AGEIA的PhysX处理器是世界上首款物理模拟处理器 (PPU), 该处理器将解除中央处理器进行物理模拟的负担。PhysX PPU 的设计构架基于顶点的多线程操作,允许游戏开发人员进行精确、流畅和动画创作和运动模拟,例如毛发、布料、液体、流体等。
目前 AGEIA 的PhysX处理器是世界上第一款也是唯一一款专注于物理算法处理器的产品. 利用PhysX SDK物理引擎开发包来实现我们仿真的效果时,一般需要以下几个步骤:(1) PrintControls(); (2) InitGlut(argc, argv); (3) InitNx(); (4) glutMainLoop(); (5) ReleaseNx(); 其中最为主要的函数是InitNx(),也既是初始化PhysX,创建一个PhysX SDK实例以及建立我们的场景。
下面具体分析各个函数的作用。
一.PrintControls(); 显而易见,利用该函数的目的是在告诉玩家该如何进行操作。操作的按键可根据自己的喜好进行设置。
二.InitGlut(argc, argv); PhysX是OpenGL上开发的,所以在初始化PhysX实例之前,必须建立一个OpenGL的框架。
①. glutInit(&argc, argv) 用来初始化GLUT,并且处理任意的命令行变量
②. glutInitWindowSize(int width, int size) 指定了窗口以像素为单位的尺寸
③. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH) 建立一个带有双缓存、RGB颜色模型和很大缓存的窗口 ④. glutCreateWindow(char* string) 创建一个具有OpenGL创建的窗口,string为该窗口的窗口名
⑤. glutSetWindow()
⑥. glutDisplayFunc(RenderCallback) 渲染 ProcessCameraKeys(); SetupCamera(); if (gScene && !bPause) { GetPhysicsResults(); ProcessInputs();根据选择的对象,给该对象施加前后、上下、左右不同方向的力,然后调用对象的方法addForce,产生不同的物理效果 StartPhysics(); } // Display scene RenderActors(bShadows); 调用函数DrawActor(NxActor* actor)将场景中的物体渲染出来,实在是在DrawActor(NxActor* actor)函数中根据物体形状调用不同形状的绘画函数将物体渲染出来的。在渲染的过程中,利用显示列表绘制不同形状的物体.
在PhysX中,物体形状分为以下几种:NX_SHAPE_PLANE(面板状), NX_SHAPE_BOX(盒子状), NX_SHAPE_ SPHERE(球形状), NX_SHAPE_CAPSULE(胶囊状), NX_SHAPE_CONVEX(凸多边形状), NX_SHAPE_MESH(网状状)。
当bShadows为true时,渲染物体的阴影;为false时就不绘制 DrawForce(box, gForceVec, NxVec3(1,1,0)); 将物体受力的受力方向渲染出来
⑦. glutReshapeFunc(ReshapeCallback) 设置窗口
⑧. glutIdleFunc(IdleCallback);
⑨. glutKeyboardFunc(KeyboardCallback);
⑩. glutKeyboardUpFunc(KeyboardUpCallback);
⑪. glutSpecialFunc(SpecialCallback); 在此,调用ResetNx(),重新渲染
⑫. glutMouseFunc(MouseCallback);
⑬. glutMotionFunc(MotionCallback);
⑭. MotionCallback(0,0);
三.InitNx() 因为我们需要初始化PhysX SDK实例,并且建立我们需要的场景;所以我们需要设置以下几个变量,并且将它们设置为全局变量 NxPhysicsSDK*gPhysicsSDK = NULL;//PhysX SDK实例对象 NxScene*gScene = NULL;//场景对象 NxVec3 gDefaultGravity(0,-9.8,0); ***注意:坐标系的方向指向,在PhysX、OpenGL以及3DMax都有一些不一样,当运行里面的demo的时候就可以体会到。它们的坐标系分别如下: 下面就在InitNx()中开始初始化实例以及建立场景.
代码: |
①. 实例化 physics SDK gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION); 初始化完Physics SDK后,只是简单的一个实例。可以通过设置实例的物理参数来充实我们的模拟效果. gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01); ②. 创建场景 NxSceneDesc sceneDesc; //场景表述表对象 sceneDesc.gravity = gDefaultGravity; sceneDesc.broadPhase = NX_BROADPHASE_COHERENT; sceneDesc.collisionDetection = true; gScene = gPhysicsSDK->createScene(sceneDesc);
|
代码: |
// Create the default material通过材质索引创建一个材质的对象 NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0); defaultMaterial->setRestitution(0.5); defaultMaterial->setStaticFriction(0.5); defaultMaterial->setDynamicFriction(0.5); 创建物体,以box为例 NxActor* box = CreateBox(NxVec3(5,1,0)); NxActor* CreateBox(const NxVec3& pos) { // Add a single-shape actor to the scene NxActorDesc actorDesc; NxBodyDesc bodyDesc; // The actor has one shape, a box NxBoxShapeDesc boxDesc; boxDesc.dimensions.set(0.5,1,0.5); actorDesc.shapes.pushBack(&boxDesc); actorDesc.body = &bodyDesc; actorDesc.density = 10; actorDesc.globalPose.t = pos; return gScene->createActor(actorDesc); }
|
代码: |
void StartPhysics() { // Update the time step NxReal deltaTime = UpdateTime(); // Start collision and dynamics for delta time since the last frame gScene->simulate(deltaTime); gScene->flushStream(); }
|