Автор: Александр Залога

Опубликовано: 03.04.2007

Изменено: 03.04.2007

Постоянная ссылка

Комментарии [0]

Введение в физический движок AGEIA PhysX


Эта статья познакомит вас с основами разработки приложений с использованием физического движка AGEIA PhysX SDK на примере урока "Ящик на плоскости" (Box on a Plane).



Страницы: 1 2 3

Эта статья познакомит вас с основами разработки приложений с использованием физического движка AGEIA PhysX SDK (Software Development Kit – набор средств для разработки ПО).

Будут рассмотрены следующие вопросы:

  1. Инициализация SDK и создание сцены
  2. Установка параметров для SDK
  3. Добавление материалов к SDK
  4. Создание сцены
  5. Создание актеров на сцене
  6. Физический цикл
  7. Рисование актеров
  8. Рисование отладочной информации
  9. Перезапуск сцены
  10. Завершение работы SDK

Для более эффективного изучения этого материала, рекомендуется скачать исходный код примера ( Lesson101_2_Domino.rar, 26 kb) и файлы ресурсов ( PhysX_resource.rar, 301 kb), необходимых для компиляции проектов. Также нужно зайти на сайт разработчика http://devsupport.ageia.com, зарегистрироваться там (совершенно бесплатно, но придется писать по-английски), и через некоторое время (1-2 дня) вам на e-mail придет письмо с паролем. После этого зайти на тот же сайт в раздел "Download", и скачать драйвер физического ускорителя (PhysX_x.xx.xx_SystemSoftware.exe) и сам SDK (PhysX_x.x.x_SDK_Core.exe) последних версий. При желании можете скачать SDK Tools, они предоставляют инструменты для работы с физическим ускорителем для программ типа Maya, 3DS Max и т.д.

Имейте ввиду, что программы, написанные на AGEIA PhysX SDK, могут запускаться там, где нет физического ускорителя AGEIA, но наличие драйверов от него – обязательное условие для успешного запуска. С начала 2007 года PhysX SDK распространяется свободно, только нужно указывать достоверную информацию о себе на их сайте и согласиться с "Лицензионным соглашением" при скачивании.

Перед чтением этой статьи рекомендую просмотреть код проекта первого урока, который можно найти здесь:

C:\Program Files\AGEIA Technologies\AGEIA PhysX SDK\v2.x.x\TrainingPrograms\ ->
                               \ProgramsChapter1_Rigid_Bodies\Lesson101_Box_on_a_Plane

Чтобы проекты примеров успешно запускались, нужно в каждом файле "LessonXXX.cpp" найти функцию "InitNx()" и в ней найти строку "sceneDesc.simType = NX_SIMULATION_HW;". Затем исправить эту строку на "sceneDesc.simType = NX_SIMULATION_SW;" (Подробнее смотрите в примере "Lesson601_Heightfields").

Базовые компоненты SDK

Все физические SDK построены на фундаментальных объектах - сам SDK; физическая среда или сцена; параметры сцены; твердые тела; материалы, которые определяют свойства поверхностей твердых тел; фигуры столкновений, из которых состоят твердые тела; сетки из треугольников, которые более точно определяют фигуры столкновения твердых тел, состоящих из соединенных точек; и пружины, соединяющие твердые тела через силы на расстоянии. Финальный компонент SDK – это установка вызова объектов, которые пользователь может назначить по запросу сцене для получения дополнительной информации. Это включает отладочные каркасы, контактную информацию об указанной контактной паре, разрушение соединений и т.д.

Если вы раньше ни когда раньше не использовали физический движок, то это будет новым для вас. Если вы уже пользовались одной из физических систем или систем столкновений, то посмотрите, как эти объекты соответствуют объектам, которые вы использовали. Если вы уже пользовались физическими SDK прежде или сейчас используете в вашей игре, отметьте, какие объекты и методы PhysX соответствуют объектами и методам в вашем текущем SDK. Для каждого важного компонента SDK посмотрите на его аналог в PhysX. Проверьте каждый объект и отметьте схожести и различия в их реализации и использовании.

1. Физический SDK
class NxPhysicsSDK - Объект физического SDK
NxPhysicsSDK::NxCreatePhysicsSDK() - Создание физического SDK

2. Сцены
class NxScene - Физическая среда
NxPhysicsSDK:createScene() - Создание физической среды

3. Параметры сцены
enum NxParameter - Глобальный параметр SDK
NxPhysicsSDK::setParameter - Изменение значений параметров

4. Твердые тела
class NxActor - Твердое тело (эктор)
NxScene::createActor() - Создание твердого тела

5. Материалы
class NxMaterial - Внешний и внутренний материал твердого тела
NxPhysicsSDK::setMaterialAtIndex() - Регистрация материала в SDK

6. Фигуры столкновений
class NxShape - Форма столкновения в твердом теле
NxActorDesc::shapes - Список фигур, из которых состоит твердое тело

7. Сетки из треугольников (Triangle Meshes)
class NxTriangleMesh - Сетка, используемая для создания фигуры столкновения из нее
NxPhysicsSDK::createTriangleMesh() - Создание сетки из массива точек или из определенного пользователем выпуклого каркаса (convex hull)

8. Сочленения
class NxJoint - Сочленение, соединяющее два эктора - точка, определяющее различные уровни свободы вращения и премещения между ними
NxScene::createJoint() - Создание соединения, содержащего описатель соединения и два эктора

9. Пружинящие и амортизирующие элементы
class NxSpringAndDamperEffector - Пружинное соединение двух экторов, присоединенное к точкам каждого эктора
NxScene::createSpringAndDamperEffector() - Создание пружины, содержащей описатель пружины и два эктора

10. Классы, определенные пользователем
Эти вызванные пользователем классы расширяют методы для добавления к SDK дополнительных функций, написанных пользователем для вычисления в физическом ускорителе. Они описаны и объяснены в руководстве "User Defined Classes"

Это были важные объекты SDK. Давайте познакомимся с применением некоторых из них (далее идет перевод первого урока из AGEIA PhysX SDK).

Занятие 101 – Ящик на плоскости (Lesson101. Box on a Plane)

Ящик на плоскости

Вступление

Это первая лекция в главе «Твердые тела» («Rigid Bodies») из комплекта разработчика AGEIA PhysX SDK. В этой лекции вы создадите экземпляр объекта SDK, создадите сцену, двух актеров (плоскость земли и ящик), симитируете поведение ящика на плоскости и примените глобальные силы к ящику посредствам нажатия клавиш во время симуляции (процесса моделирования).

1. Инициализация SDK и создание сцены

В каждой лекции вам нужно создавать экземпляр объекта PhysX SDK для построения симуляции. Это делается в функции InitNx(). Следующий блок кода – это всё, что нужно для инициализации PhysX SDK и создания сцены:

#include "Lesson101.h"

// Physics SDK globals
NxPhysicsSDK*         gPhysicsSDK = NULL;
NxScene*              gScene = NULL;
NxVec3                gDefaultGravity(0,-9.8,0);

void InitNx()
{
    // Create the physics SDK
    gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
    if (!gPhysicsSDK)  return;

    // Create the scene
    NxSceneDesc sceneDesc;
    sceneDesc.gravity = gDefaultGravity;

    gScene = gPhysicsSDK->createScene(sceneDesc);
}

void main(int argc, char** argv)
{
    InitNx();
}

Мы вызываем InitNx() из функции main(). InitNx() создает экземпляр физики, gPhysicsSDK, и создает сцену gScene. Наверное, это простейшая программа PhysX. Теперь это можно запустить.

2. Установка параметров для SDK

Теперь мы добавим параметры к SDK, чтобы расширить нашу симуляцию.

// Set the physics parameters
gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01);

Первый параметр – это глобальный физический параметр, используемый в SDK для вычисления толщины поверхностей. Это важный параметр, по существу определяющий разрешенную глубину взаимного проникновения объектов друг в друга. Сейчас мы установим его вручную на 0.01 (абсолютная глубина 0.01 м или 1 см). Если не добавить этой строки, то останется значение по умолчанию: 0.025 (0.025 м или 2.5 см).

// Set the debug visualization parameters
gPhysicsSDK->setParameter(NX_VISUALIZATION_SCALE, 1);
gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1);
gPhysicsSDK->setParameter(NX_VISUALIZE_ACTOR_AXES, 1);

Это параметры отладочной визуализации. Здесь мы говорим, что при включении режима отображения каркасов (Debug Wireframe Mode), мы хотим видеть отладочные векторы длиной 1 метр (NX_VISUALIZATION_SCALE), видеть все сталкивающиеся тела (NX_VISUALIZE_COLLISION_SHAPES) и положения актеров в глобальных координатах (NX_VISUALIZE_ACTOR_AXES).

3. Создание сцены

Мы установили все желаемые параметры для SDK. Теперь создадим сцену:

// Create the scene
NxSceneDesc sceneDesc;
sceneDesc.gravity  = gDefaultGravity;
sceneDesc.simType  = NX_SIMULATION_HW;
 
gScene = gPhysicsSDK->createScene(sceneDesc);

Мы создаем описатель сцены, который мы передаем SDK для создания нашей сцены. Описатели (descriptors) широко используются во всем SDK. Это структуры, содержащие всю информацию о вашем объекте, с которой он будет создан. Вы можете приспособить описатель к своему стилю или оставить его без изменений, и объекты будут создаваться с описателями, установленными по умолчанию.

В начале укажем, что мы хотим создать аппаратно-зависимую сцену (hardware scene) с готовым вектором гравитации. Чтобы создать аппаратно-независимую сцену (software scene), установите тип симуляции NX_SIMULATION_SW; если предполагаете запускать эту программу на компьютерах с установленным физическим ускорителем от AGEIA, то установите NX_SIMULATION_HW.

4. Добавление материалов к сцене

Вы хотите установить для сцены физический материал, который будет использоваться по умолчанию. Материал, из которого состоят поверхности, определяет параметры столкновений и свойства этих поверхностей: как объекты будут отскакивать, скользить и скатываться с других объектов.

// Create the default material
NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);
defaultMaterial->setRestitution(0.5);
defaultMaterial->setStaticFriction(0.5);
defaultMaterial->setDynamicFriction(0.5);

Это говорит, что все объекты на сцене будут состоять из субстанций со средней упругостью restitution=0.5 (восстановление, возвращение), средним трением покоя static friction=0.5 (статическое трение) и средним трением скольжения dynamic friction=0.5 (динамическое трение).

5. Создание актеров на сцене

В конце функции InitNx() мы добавляем на сцену наших актеров - плоскость и ящик.

// Actor globals
NxActor* groundPlane = NULL;
NxActor* box = NULL;
...
void InitNx()
{
...
    // Create the objects in the scene
    groundPlane = CreateGroundPlane();
    box = CreateBox();
...
}

6. Создание плоскости земли

Мы будем использовать плоскость земли в большинстве наших процессов моделирования. Она добавляется так:

void InitNx()
{
...
    groundPlane = CreateGroundPlane();
...
}

// Look at the function CreateGroundPlane()

NxActor* CreateGroundPlane()
{
    // Create a plane with default descriptor
    NxPlaneShapeDesc planeDesc;
    NxActorDesc actorDesc;
    actorDesc.shapes.pushBack(&planeDesc);
    return gScene->createActor(actorDesc);
}

Это вероятно простейшая функция создания актера. Плоскость земли инициализируется через описатель актера. Описатель актера инициализирует стандартный описатель плоскости, так что земля расположена в начале координат (0,0,0) с нормальной ориентацией вдоль положительного направление оси Y (0,1,0). Плоскость не ассоциирована с твердым телом, так как это статический объект: она не может двигаться, и может отталкивать динамические объекты от себя, как если бы она имела бесконечную массу.

7. Создание ящика

Сейчас мы создадим наш ящик. Это будет актер, состоящий из одной фигуры.

void InitNx()
{
    ...
    box = CreateBox();
    ...
}

// The CreateBox() function is as follows.

NxActor* CreateBox()
{
    // Set the box starting height to 3.5m so box starts off falling onto the ground
    NxReal boxStartHeight = 3.5;

    // Add a single-shape actor to the scene
    NxActorDesc actorDesc;
    NxBodyDesc bodyDesc;

    // The actor has one shape, a box, 1m on a side
    NxBoxShapeDesc boxDesc;
    boxDesc.dimensions.set(0.5,0.5,0.5);
    actorDesc.shapes.pushBack(&boxDesc);

    actorDesc.body = &bodyDesc;
    actorDesc.density = 10;
    actorDesc.globalPose.t = NxVec3(0,boxStartHeight,0);
    return gScene->createActor(actorDesc);   
}

Мы создаем актера на сцене, назвав его «box». Чтобы создать актера, необходимо перейти к описателю актера, создаваемому через NxScene::createActor(). Мы передаем в actorDesc описатель одной формы – boxDesc – описатель ящика со сторонами 1 м. Устанавливаем размеры, используя половину длины, ширины и высоты ящика через boxDesc.dimensions.set(0.5, 0.5, 0.5). Затем мы присоединяем это тело, bodyDesc, к актеру, устанавливаем плотность = 10, и устанавливаем позицию в глобальных координатах (0,boxStartHeight,0), имея ввиду, что центр ящика в начале симуляции будет находится на высоте boxStartHeight = 3.5 м. над поверхностью земли.

Наш актер состоит из одной формы, ящика со стороной 1 м., с центром в координатах (0, boxStartHeight,0) и имеет плотность 10. Когда мы вызываем NxScene::createActor(), мы присоединяем твердое тело, bodyDesc, к актеру, установив перед этим форму ящика и плотность.

Страницы: 1 2 3