PhysX SDK物理引擎開發包使用教程

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);

 

在PhysX中,不管是創建場景還是創建各個物體角色時,都是先通過各自對應的描述器(翻譯的不是很準確)設置場景和各個物體的物理參數,用來模擬真實的世界環境和物體。建立好表述器後,通過函數createScene(NxSceneDesc)函數就可以建立需要的場景對象。一般情況下,場景描述器的參數就是設置重力加速度sceneDesc.gravity,是否進行碰撞檢測collisionDetection, true爲進行,在PhysX SDK中描述器被廣泛的應用. 描述器包括所有你創建物體的信息broadphase-coherent是三種碰撞檢測中的一種。 gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01); 當相互碰撞的物體的材質都很軟的時候,在現實中就會發現當發生碰撞的時候物體之間就會相互嵌入一部分,在這裏我們就可以利用物理參數NX_SKIN_WIDTH,它的默認值爲0.05m,該值越大,嵌入的就越多 同時,我們可以對場景中的所有物體創建材質。創建的材質定義了碰撞和物體材料的物理屬性。比如反彈係數、靜摩擦力、滑動摩擦力等。
代碼:

            // 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); }

 

我們創建一個角色參與者box,它的類型爲NxActor*。建立該對象的時候需要設置它的描述器,然後利用函數createActor(NxActorDesc actorDesc)將該對象加入場景中。每一個對象又有和自己形狀相對應的描述器。利用它設置對象的物理參數。boxDesc該描述器描述了該盒子的長、寬、高分別爲0.5,初始化的位置以及該盒子的密度。 ③. 創建完所有的物體對象時,調用UpdateTime()得到從上一幀渲染到現在經過的時間 ④. 當創建的場景成功,利用函數StartPhysics()開始它的第一幀模擬。
代碼:

            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(); }

 

simulate(deltaTime)是PhysX 解決物理學的關鍵 flushStream()對時間步進行仿真四.glutMainLoop() 程序將一直停留在glutMainLoop()中,直到用戶自己結束。當場景一旦被渲染後,在每次設置下一場景時,RenderCallback()回調函數將被調用五.ReleaseNx() 刪除場景中所有的物體對象以及場景本身
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章