官方網站:
www.nvidia.cn
github擷取c++版本physx代碼流程
第一步 新增賬號:
https://developer.nvidia.com/physx-sdk
第二步: 等待官方稽核,正常會在第二天就可以再官網添加的GitHub賬号下有社群/PhysX-3.3版本:
https://github.com/Golangltd/PhysX-3.3
社群/PhysX-3.4版本:
https://github.com/Golangltd/PhysX-3.4
AGEIA的PhysX處理器是世界上首款實體模拟處理器 (PPU), 該處理器将解除中央處理器進行實體模拟的負擔。PhysX PPU 的設計構架基于頂點的多線程操作,允許遊戲開發人員進行精确、流暢和動畫創作和運動模拟,例如毛發、布料、液體、流體等。本文介紹了如何利用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) 渲染
1ProcessCameraKeys();
2
3 SetupCamera();
4
5 if (gScene && !bPause)
6
7 {
8
9 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執行個體,并且建立我們需要的場景;是以我們需要設定以下幾個變量,并且将它們設定為全局變量
1 NxPhysicsSDK*gPhysicsSDK = NULL;//PhysX SDK執行個體對象
2
3NxScene*gScene = NULL;//場景對象
4
5NxVec3 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);
②. 建立場景
1 NxSceneDesc sceneDesc; //場景表述表對象
2
3 sceneDesc.gravity = gDefaultGravity;
4
5 sceneDesc.broadPhase = NX_BROADPHASE_COHERENT;
6
7 sceneDesc.collisionDetection = true;
8
9 gScene = gPhysicsSDK->createScene(sceneDesc);
在PhysX中,不管是建立場景還是建立各個物體角色時,都是先通過各自對應的描述器(翻譯的不是很準确)設定場景和各個物體的實體參數,用來模拟真實的世界環境和物體。建立好表述器後,通過函數createScene(NxSceneDesc)函數就可以建立需要的場景對象。
一般情況下,場景描述器的參數就是設定重力加速度sceneDesc.gravity,是否進行碰撞檢測collisionDetection, true為進行,在PhysX SDK中描述器被廣泛的應用. 描述器包括所有你建立物體的資訊broadphase-coherent是三種碰撞檢測中的一種。
1gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01);
當互相碰撞的物體的材質都很軟的時候,在現實中就會發現當發生碰撞的時候物體之間就會互相嵌入一部分,在這裡我們就可以利用實體參數NX_SKIN_WIDTH,它的預設值為0.05m,該值越大,嵌入的就越多
同時,我們可以對場景中的所有物體建立材質。建立的材質定義了碰撞和物體材料的實體屬性。比如反彈系數、靜摩擦力、滑動摩擦力等。
1 // Create the default material通過材質索引建立一個材質的對象
2
3 NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);
4
5 defaultMaterial->setRestitution(0.5);
6
7 defaultMaterial->setStaticFriction(0.5);
8
9 defaultMaterial->setDynamicFriction(0.5);
10
11
12
13建立物體,以box為例
14
15NxActor* box = CreateBox(NxVec3(5,1,0));
16
17NxActor* CreateBox(const NxVec3& pos)
18
19{
20
21 // Add a single-shape actor to the scene
22
23 NxActorDesc actorDesc;
24
25 NxBodyDesc bodyDesc;
26
27
28
29 // The actor has one shape, a box
30
31 NxBoxShapeDesc boxDesc;
32
33 boxDesc.dimensions.set(0.5,1,0.5);
34
35 actorDesc.shapes.pushBack(&boxDesc);
36
37
38
39 actorDesc.body = &bodyDesc;
40
41 actorDesc.density = 10;
42
43 actorDesc.globalPose.t = pos;
44
45 return gScene->createActor(actorDesc);
46
47}
我們建立一個角色參與者box,它的類型為NxActor*。建立該對象的時候需要設定它的描述器,然後利用函數createActor(NxActorDesc actorDesc)将該對象加入場景中。每一個對象又有和自己形狀相對應的描述器。利用它設定對象的實體參數。boxDesc該描述器描述了該盒子的長、寬、高分别為0.5,初始化的位置以及該盒子的密度。
③. 建立完所有的物體對象時,調用UpdateTime()得到從上一幀渲染到現在經過的時間
④. 當建立的場景成功,利用函數StartPhysics()開始它的第一幀模拟。
1 void StartPhysics()
2
3{
4
5 // Update the time step
6
7 NxReal deltaTime = UpdateTime();
8
9
10
11 // Start collision and dynamics for delta time since the last frame
12
13 gScene->simulate(deltaTime);
14
15 gScene->flushStream();
16
17}
18
19simulate(deltaTime)是PhysX 解決實體學的關鍵
20
21 flushStream()對時間步進行仿真
四.glutMainLoop()
程式将一直停留在glutMainLoop()中,直到使用者自己結束。當場景一旦被渲染後,在每次設定下一場景時,RenderCallback()回調函數将被調用
五.ReleaseNx()
删除場景中所有的物體對象以及場景本身
原文釋出時間為:2018-06-24
本文作者:cserli
本文來自雲栖社群合作夥伴“
Golang語言社群”,了解相關資訊可以關注“
”。