天天看點

PhysX SDK實體引擎開發包使用及擷取c++源碼教程

官方網站:

www.nvidia.cn

PhysX SDK實體引擎開發包使用及擷取c++源碼教程

github擷取c++版本physx代碼流程

第一步 新增賬號:

https://developer.nvidia.com/physx-sdk

PhysX SDK實體引擎開發包使用及擷取c++源碼教程
第二步:
PhysX SDK實體引擎開發包使用及擷取c++源碼教程
等待官方稽核,正常會在第二天就可以再官網添加的GitHub賬号下有
PhysX SDK實體引擎開發包使用及擷取c++源碼教程

社群/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的時候就可以體會到。它們的坐标系分别如下:

PhysX SDK實體引擎開發包使用及擷取c++源碼教程

下面就在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語言社群

”,了解相關資訊可以關注“

”。

繼續閱讀