Показать сообщение отдельно
Старый 06.01.2009, 05:25   #3
ABTOMAT
Ференька
 
Аватар для ABTOMAT
 
Регистрация: 26.01.2007
Адрес: улица Пушкина дом Колотушкина
Сообщений: 10,741
Написано 5,461 полезных сообщений
(для 15,675 пользователей)
Сообщение Другие примитивы.

Другие примитивы.
Итак, вчера я рассказал как создавать кубики. Но кроме них в ФизикСе есть ещё и другие примитивы. Думаю, будет полезно с ними кратко познакомиться.
Первым будет цилиндр:
pxBodyCreateCylinder%(radius#, height#, nbEdge%, mass#)
Итак, эта функция создаёт физическое тело-цидиндр. Функция очень похожа на pxBodyCreateCube, только тут вместо масштаба по осям нужно указывать радиус цилиндра radius#, высоту цилиндра height# и количество граней цилиндра nbEdge%. Следует заметить, что . Масса цилиндра mass# указывается точно так же, как и для куба.
Теперь давайте изменим пример PhysXExample2.zip чтобы он создавал не только кубики, но и цилиндры, причём случайно. Я изменил код создания куба таким образом:
Function CreatepxCube(x#,y#,z#)    
    pxC.pxCube = New pxCube
    fig = Rand(1,2)
    Select fig
        Case 1 ; куб
            pxC\mesh = CreateCube()
            pxC\body = pxBodyCreateCube(1,1,1,1)
        Case 2 ; цилиндр
            pxC\mesh = CreateCube()
            pxC\body = pxBodyCreateCylinder(1, 3, 8, 1)
    End Select
    pxBodySetPosition pxC\body,x,y,z
End Function
Как видите, сначала случайным образом выбирается переменная fig.
Если она равна единице, то создаётся куб, как бы это делали раньше, а если двойке - то физическим телом будет цилиндр. Как вы можете видеть, для него я выбрал радиус 1, высоту 3, 8 граней и массу 1.
Но модель по-прежнему куб. Непорядок. Куб с физической моделью цилиндра - это жестоко. Пускай будет блитзевский цилиндр с 8 гранями:
pxC\mesh = CreateCylinder(8)
Но так как я указал физической модели высоту 3, то и у модельки тоже надо изменить высоту до трёх (напомню, что при создании она равна 1). Сделаем это при помощи простого масштабирования:
ScaleEntity pxC\mesh,1,3,1
Ну вот! Теперь если поклацать по пробелу, то мы увидим созданные не только кубики, но и цилиндрики:

Для порядку я решил переименовать тип из pxCube в pxBody т.к. обзывать цилиндр кубом не очень корректно. Делать это необязательно, но это сделает код более понятным. Теперь функции и тип выглядят таким образом:
Type pxBody
    Field mesh
    Field body
End Type

Function UpdatepxBodies()
    For pxB.pxBody = Each pxBody
        pxBodySetEntity pxB\mesh, pxB\body
    Next
End Function

Function CreatepxBody(x#,y#,z#)    
    pxB.pxBody = New pxBody
    fig = Rand(1,2)
    Select fig
        Case 1 ; куб
            pxB\mesh = CreateCube()
            pxB\body = pxBodyCreateCube(1,1,1,1)
        Case 2 ; цилиндр
            pxB\mesh = CreateCylinder(8)
            ScaleEntity pxb\mesh,1,3,1
            pxB\body = pxBodyCreateCylinder(1, 3, 8, 1)
    End Select
    pxBodySetPosition pxB\body,x,y,z
End Function
Надеюсь, вы уже догадались, что в этом случае нужно поменять название ф-ии и при создании при обновлении в цикле:
If KeyHit(57) Then CreatepxBody(0,10,0)
UpdatepxBodies()
Запускаем, чтобы на всякий случай убедиться, что всё работает.
Полный код примера вы найдёте в аттаче "PhysXExample3.zip"

Продолжаем тему примитивов. На очереди у нас сфер. Ну, тут всё предельно просто:
pxBodyCreateSphere(radius#, mass#)
radius - радиус сферы, mass - масса. Тут и понимать нечего. В визуальном плане ей соответствует блитзевская сфера, создаваемая командой CreateSphere(). Давайте попробуем в наш пример встроить и сферу:
Function CreatepxBody(x#,y#,z#)    
    pxB.pxBody = New pxBody
    fig = Rand(1,3)
    Select fig
        Case 1 ; куб
            pxB\mesh = CreateCube()
            pxB\body = pxBodyCreateCube(1,1,1,1)
        Case 2 ; цилиндр
            pxB\mesh = CreateCylinder(8)
            ScaleEntity pxb\mesh,1,3,1
            pxB\body = pxBodyCreateCylinder(1, 3, 8, 1)
        Case 3 ; сфера
            pxB\mesh = CreateSphere(8)
            pxB\body = pxBodyCreateSphere(1,1)
    End Select
    pxBodySetPosition pxB\body,x,y,z
End Function
Как видите, я добавил третий случай (когда fig = 3). Если это происходит, создаётся физическая сфера радиусом 1 и массой 1 да соответствующая ей модель-сфера.
Запускаем, давим на пробел - теперь у нас ещё и шарики появляются.

Но есть у сферы одна важная особенность, делающая её отличной от других примитивов. Если помните, при создании физического цилиндра мы указывали количество его граней. То есть в предыдущем примере получился никакой не цилиндр, а 8-угольная призма. Это происходит потому, что каждый объект в ФизикСе (да и во многих других движках) имеет конечное количество точек. Чем больше точек, тем более округлую поверзность можн осмоделлировать, но тем больше будут затраты на расчёт физики. В-общем, тут полная аналогия с полигональной графикой: чем больеш треугольников - тем круглее и точнее поверхность, но тем больеш нагрузка на видеокарту. Так вот, физ.сфера является исключением из этого правила! Она действительно математически является сферой (т.е. идеально круглой). Насколько мне известно, для таких объектов в Физиксе обработка происходит по несколько другим алгоритмам. За счёт того, что сферу можно легко описать лишь её радиусом, вычисления получаются во много раз быстрее, чем если то же самое делать из точек и треугольников, как цилиндр. Поэтому запомните: если вам нужно создать физический объект, имеющий шарообразную форму или близкую к ней, используйте физический примитив-сферу: это ускорит расчёт физики, чем если сферу моделировать как другие тела.

Теперь перейдём к капсуле.
Думаю, сначала надо рассказать, что же такое капсула. Она предстваляет из себя примерно такую штуку:

По сути, это цилиндр с закруглёнными краями. Чем-то напоминает пилюлю. Создаётся вот такой командой:
pxBodyCreateCapsule%(height#,radius#,mass#)
Параметр height указывает высоту цилиндрической части капсулы, radius - радиус капсулы, mass - масса.
Глядите на схему, чтобы лучше понять.
Попробуем у нас создавать капсулу высотой 3, радиусом 1 и массой 1:
pxB\body = pxBodyCreateCapsule(3,1,1)
Теперь надо бы создать для капсулы визуальную модель. Так как в Блитзе нету примитива-капсулы, то нужна для удобства собственная функция создания меша капсулы. Вот моя попытка изобрести такую функцию:
Function CreateCapsule(height#,radius# )
    cyl = CreateCylinder()
    ScaleMesh cyl, radius, height-radius*1.5, radius
    
    sph = CreateSphere()
    ScaleEntity sph, radius,radius,radius
    PositionMesh sph, 0,height/2,0
    AddMesh sph, cyl
    
    PositionMesh sph, 0,-height,0
    AddMesh sph, cyl

    FreeEntity sph
    Return cyl
End Function
Конечно, можно оптимизировать её (например, попытаться удалить части сфер, которые попадают внутрь цилиндра, или убрать "шапки" цилиндров, но это долго, геморно и к PhysX'у непосредственно не относится. А для учебных целей нам вполне хватит и такой функции. Итак, теперь функция CreatepxBody выглядит так:
Function CreatepxBody(x#,y#,z#)    
    pxB.pxBody = New pxBody
    fig = Rand(1,4)
    Select fig
        Case 1 ; куб
            pxB\mesh = CreateCube()
            pxB\body = pxBodyCreateCube(1,1,1,1)
        Case 2 ; цилиндр
            pxB\mesh = CreateCylinder(8)
            ScaleEntity pxb\mesh,1,3,1
            pxB\body = pxBodyCreateCylinder(1, 3, 8, 1)
        Case 3 ; сфера
            pxB\mesh = CreateSphere(8)
            pxB\body = pxBodyCreateSphere(1,1)
        Case 4 ; капсула
            pxB\mesh = CreateCapsule(3,1)
            pxB\body = pxBodyCreateCapsule(3,1,1)
    End Select
    pxBodySetPosition pxB\body,x,y,z
End Function
Теперь появляются ещё и капсулы. Понаблюдайте за ихним поведением.
А теперь - внимание! - капсула, подобно сфере, тоже является исключением из правил и рассчитывается иными алгоритмами. Потому не имеет угловатостей и рассчитывается быстрее того же цилиндра с приемлемым количеством сегментов. Помните об этом.

Полный код примера вы найдёте в аттаче "PhysXExample4.zip"

Что-то уже поздновато
Думаю, на сегодня всё. Завтра я расскажу о хуллах и тримешах.
Продолжайте экспериментировать.
Вложения
Тип файла: zip PhysXExample3.zip (571 байт, 2002 просмотров)
Тип файла: zip PhysXExample4.zip (727 байт, 2016 просмотров)
__________________
Мои проекты:
Анальное Рабство
Зелёный Слоник
Дмитрий Маслов*
Различие**
Клюква**

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


Последний раз редактировалось ABTOMAT, 07.01.2009 в 01:40.
(Offline)
 
Ответить с цитированием
Эти 32 пользователя(ей) сказали Спасибо 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), Dzirt (08.04.2009), EvilChaotic (28.08.2009), h1dd3n (26.01.2009), HolyDel (17.01.2009), Hurrit (16.05.2010), Максим (09.01.2009), is.SarCasm (20.02.2010), Main Cry (23.04.2009), m_512 (13.02.2009), Nex (07.01.2009), PackegerX (03.02.2010), robox (23.08.2009), rr333 (11.02.2009), SashaRX (06.01.2009), Sashka007 (06.01.2009), SBJoker (06.01.2009), Slavik (18.06.2009), strayhnd (30.06.2010), viper86 (08.02.2009), vlactelin (05.09.2011), WhiteBlack (27.07.2010), ІГРОГРАЙКО (02.07.2009)