Показать сообщение отдельно
Старый 05.01.2009, 06:28   #2
ABTOMAT
Ференька
 
Аватар для ABTOMAT
 
Регистрация: 26.01.2007
Адрес: улица Пушкина дом Колотушкина
Сообщений: 10,741
Написано 5,461 полезных сообщений
(для 15,675 пользователей)
Ответ: Учебник по PhysX Wrapper для Blitz3D

Начало работы. Что понадобится? Первое простое приложение на ФизикСе.

Вам понадобятся:
  • Блитз3Д (Думаю, раз уж вы читаете тутор по врапперу для этого движка, то он (движок) у вас уже есть)
  • Физикс Враппер, установленный на него (можно скачать с офф сайта)
  • Какое-никакое знание Блитза, т.к. я не стану объяснять его азы, ведь статья не об этом.
  • Голова на плечах =)) (полностью на вашей совести)

Итак, качаем установщик враппера. Запускаем его, указываем путь к Блитзу. Там несложно, разберётесь. Собсно это всё. Теперь перезапускаем Блитз и можно уже писать программу.

Вот простой пример кода на Блитз3Д, который я взял за основу:

Graphics3D 800,600,32,2
SetBuffer BackBuffer()

cam = CreateCamera()
PositionEntity cam,0,10,-20

plane = CreatePlane()
EntityColor plane,64,128,128

Repeat

RenderWorld()
Flip

Until KeyHit(1)
End
Он создаёт камеру, зеленоватую плоскость и рисует это всё. Теперь надо подключить к проекту Физикс. Делается это при помощи команды:
pxCreateWorld(plane%, key$)
Собственно, она и говорит Блитзу, что отныне в проекте используется Физикс. В функцию надо передать параметр plane%, отвечающий за создание физической плоскости. Может принимать значения 1 или 0. Соответственно 1 - создать плоскость, а 0 - не создавать. Кроме этого, нужно передать параметр key$ - это ключ продукта, чтобы либа не надоедала сообщениями "This is demo version!". На пока вполне сгодится и демо-версия. Если у вас нет ключа - просто передайте пустую строку.
Эту команду надо вставить после инициализации графического 3Д-режима aka Graphics3D (как видите, я создал физ. плоскость и не стал передавать ключ):
pxCreateWorld(1,"")
Далее - нам понадобится обновлять физику каждый цикл. Делать это нужно перед рендером. Нам поможет команда:
pxRenderPhysic(time#, sinc%)
Она собственно и обновляет физику. В блитзе есть похожая команда UpdateWorld, которая обновляет каждый цикл коллизии и анимацию, так что использование схоже. Итак, у функции 2 параметра. Первый параметр time отвечает за скорость обновления физики. Чем меньше это число, тем быстре будут двигаться физические тела и быстрее происходить вообще все процессы в физическом мире. Пока что поставим сюда 60, это, я думаю, оптимальное значение для начала. Второй параметр sinc может принимать значения 0 или 1 и указывает, надо ли включать встроенную в синхронизацию. Пока что она работает не вполне корректно, так что лучше её отключить, а если она понадобится, то её можно сделать и своими силами. Итак, эту команду надо использовать перед рендером сцены:
pxRenderPhysic(60,0)
Ну чтож, мы подключили PhysX и прописали обновление физики. Но не хватает главного - физических объектов! Тут я сделаю опять небольшое лирическое отступление. В физических движках всё происходит отдельно от трёхмерного движка. То есть если у нас есть куб-трёхмерная модель и куб-физическое тело, то, когда мы обновляем физику, тело будет падать, кататься и вести себя по физическим законам. модель же ни с места не сдвинетя от этого самого обновления физики при помощи команды pxRenderPhysic. Привязать модель к телу на манер EntityParent тоже нельзя. Поэтоум надо вручную устанавливать модель в координаты и в поворот тела. Поначалу это кажется непривычным, но со временем вы поймёте, что это на самом деле удобно.
Итак, давайте создадим кубик. Обычный, блитзевский, при помощи всем нам хорошо известной команды CreateCube():
Cube = CreateCube()
Теперь надо создать для него физическое тело при помощи команды:
pxBodyCreateCube%( dx#, dy#, dz#, mass#)
По сути, пользоватья ей нужно так же, как и простым блитзевским CreateCube(). Но тут всё сложнее. Так как, к сожалению, масштабировать физические объекты в реальном времени нельзя, это надо делать при их создании. Поэтому первые три аргумента этой функции dx, dy, dz указывают масштабирование создаваемого физического тела-куба по осям X,Y,Z соответственно. Думаю, нам пока что хватит и обычного кубика размерами 1х1х1, поэтому мы укажет в этих параметрах единицы. Но кроме этого каждый физический объект должен иметь массу, именно за неё отвечает четвёртый аргумент mass. Думаю, масса 1 будет вполне достаточной. Физический куб, как и блитзевский, создаётся в координатах 0,0,0 с поворотом по осям 0,0,0.

На заметку
Если выставить массу 0, то объект уже не будет динамическим, а будет статическим. Об этом я расскажу позже, но пока просто имейте ввиду. Для динамических тел нам понадобится масса, отличная от нуля.


Итак, пишем код создания тела прямо после кода создания модели куба:
Body = pxBodyCreateCube(1,1,1,1)
Так, теперь у нас есть ещё и тело для куба. Но оно лежит в точке 0,0,0. Думаю, его надо приподнять повыше. Тут нам поможет команда:
pxBodySetPosition (body%, pos_x#, pos_y#, pos_z#)
Функция, по сути, аналогична Блитзевской PositionEntity, только в неё надо пихать первым аргументом body то тело, которое мы желаем переместить. В следующие три аргумента pos_x, pos_y, pos_z передаём новые координат для тела. Давайте поднимем тело куба на 10 единиц над землёй:
pxBodySetPosition Body,0,10,0
Ну вот, теперь ему есть откуда падать) Но тот куб, который мы увидим на экране всё ещё неподвижен как я писал выше, его надо вручную устанавливать в позицию и поворот соответствующего тела. К счастью, уже есть удобная команда, выполняющая это действие:
pxBodySetEntity (entity%, body%)
Первый параметр - это тело, которое нужно устанавить в позицию и поворот соответствующего тела, body - соответствующее тело. Вызывать такую функцию нужно каждый раз после обновления физики, но до вывода на экран. Т.е. между pxRenderPhysic и RenderWorld. Давайте применим её к нашему кубу и его телу:
pxBodySetEntity(Cube,Body)
Всё! Теперь можно запускать программу и наблюдать адение нашего кубика!
Да, чего-то здесь не хватает. Похоже, неплохо бы добавить освещение:
light = CreateLight()
Ну вот, теперь совсем другой вид! Собственно, у меня получилось вот что:

Полный код примера вы найдёте в аттаче "PhysXExample1.zip"
Мда, с одним кубиком не очень-то впечатляет. Давайте насоздаём их много. Используем для этого типы. Буду краток, есчли вы не очень хорошо разбираетесь в типах, то советую почитать вот этот перевод от товарища Импера:
http://forum.boolean.name/showthread.php?t=10
(я сам по нему когда-то учился )

Так, значится. Создадим тип для кубика:

Type pxCube
	Field mesh
	Field body
End Type
Всё, в-общем-то, дорлжно быть ясно: в типе хранится модель и тело объекта. Больше нам пока ничего не надо.

Теперь напишем функцию обновления каждого кубика:

Function UpdatepxCubes()
	For pxC.pxCube = Each pxCube
		pxBodySetEntity pxC\mesh, pxC\body
	Next
End Function
Здесь перебирается каждый объект типа pxCube и модель позиционируется в координаты тела. Как вы уже догадались, использовать её надо аналогично pxBodySetEntity (т.е. между обновлением физики и рендером):
UpdatepxCubes()
Теперь можно написать и функцию создания. Это, в принципе, то же самое, что было описано выше для одного кубика, но теперь всё это упорядочено в типы:
Function CreatepxCube(x#,y#,z#)
	pxC.pxCube = New pxCube
	pxC\mesh = CreateCube()
	pxC\body = pxBodyCreateCube(1,1,1,1)
	pxBodySetPosition pxC\body,x,y,z
End Function
Создаётся объект pxCube, для него создаются модель и тело, а затем тело выставляется в переданные в функцию координаты.
Ну, раз мы упорядочили всё в типы, то можно удалить наш старый кубик.
Стираем этот код:
Cube = CreateCube()
Body = pxBodyCreateCube(1,1,1,1)
pxBodySetPosition Body,0,10,0
и этот:
pxBodySetEntity(Cube,Body)
Давайте создавать кубики по нажатию пробела в точке 0,10,0. Теперь это совсем несложно:
If KeyHit(57) Then CreatepxCube(0,10,0)
Всё! Можно запускать. Запустили и тарабаним по пробелу. Вот что вышло у меня:

Да, этот результат намного интереснее!
Полный код примера вы найдёте в аттаче "PhysXExample2.zip"

Ну что ж, я описал базовые знания об этом враппере. Думаю, они окажутся вам полезными и вы прочитаете продолжение, которое я вскоре напишу. Однако не бойтесь экспериментировать и читать хелп самостоятельно. Ладно, уже скоро полшестого утра по Москве, пойду спать.
Вложения
Тип файла: zip PhysXExample1.zip (362 байт, 2195 просмотров)
Тип файла: zip PhysXExample2.zip (475 байт, 2197 просмотров)
__________________
Мои проекты:
Анальное Рабство
Зелёный Слоник
Дмитрий Маслов*
Различие**
Клюква**

* — в стадии разработки
** — в стадии проектирования
Для проектов в стадии проектирования приведены кодовые имена


Последний раз редактировалось ABTOMAT, 05.01.2009 в 14:18.
(Offline)
 
Ответить с цитированием
Эти 37 пользователя(ей) сказали Спасибо ABTOMAT за это полезное сообщение:
3dr1aN (09.01.2009), ACTIVATOR (20.01.2009), Alex_Noc (09.01.2009), Andvrok (21.10.2009), baton4ik (01.02.2010), Blender (17.01.2010), Brain (15.01.2010), DeadElf (27.07.2010), den (27.07.2010), Diablomania (14.08.2009), Dream (05.01.2009), Dzirt (08.04.2009), EvilChaotic (28.08.2009), FireOwl (27.09.2009), FrankH (17.08.2009), h1dd3n (31.01.2009), HolyDel (05.01.2009), Hurrit (16.05.2010), Максим (09.01.2009), is.SarCasm (20.02.2010), krlmisha (01.06.2011), Main Cry (23.04.2009), m_512 (13.02.2009), Nex (07.01.2009), PackegerX (03.02.2010), robox (23.08.2009), SashaRX (06.01.2009), Slavik (17.06.2009), soneek (31.03.2009), strayhnd (30.06.2010), Tadeus (05.01.2009), tormoz (05.01.2009), viper86 (08.02.2009), vlactelin (05.09.2011), WhiteBlack (27.07.2010), Данил (05.01.2009), ІГРОГРАЙКО (02.07.2009)