日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

PhysX官方教程lession101

發(fā)布時(shí)間:2023/12/13 综合教程 37 生活家
生活随笔 收集整理的這篇文章主要介紹了 PhysX官方教程lession101 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

由于國(guó)內(nèi)資料很少,所以有些沖動(dòng)將PhysX原教程給翻譯了,今天只做了一部分希望大家能夠認(rèn)同

Lesson 1-1 – 主要形狀

介紹

In this lesson, you will create an instance of the SDK, create a scene, create four actors (a ground plane, a capsule, a sphere and a box), simulate the other three actors on the plane actor, and apply global forces to the box by keyboard action during the simulation.

這是我們學(xué)習(xí)PhysX SDK 剛體的第一課。這里,你會(huì)學(xué)會(huì)創(chuàng)建一個(gè)PhysX的實(shí)例,一個(gè)場(chǎng)景,和4個(gè)角色Actor(一個(gè)地面,一個(gè)膠囊,一個(gè)球體和一個(gè)立方體(盒子))模擬其中三個(gè)角色Actor放在地面上,并且通過(guò)使用鍵盤(pán)動(dòng)作來(lái)產(chǎn)生一些力量控制這些角色。

1 Initializing the SDK and Creating a Scene初始化SDK并且創(chuàng)建一個(gè)場(chǎng)景
在每個(gè)課程中,你都需要?jiǎng)?chuàng)建一個(gè)PhysX SDK的實(shí)例來(lái)構(gòu)建你虛擬的物理世界。 這些都通過(guò)一個(gè)叫做InitNx()的方法來(lái)實(shí)現(xiàn) 。以下這些未完成的代碼是提供給你來(lái)初始化PhysX SDK 并且創(chuàng)建一個(gè)場(chǎng)景scene的。

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

}

從 main()函數(shù)開(kāi)始, 我們調(diào)用了InitNx()函數(shù)。 InitNx() makes an instance of the physics SDK InitNx()函數(shù)創(chuàng)建了Physics SDK的實(shí)例, 對(duì)應(yīng)指針名字叫做gPhysicsSDK,并且創(chuàng)建了一個(gè)場(chǎng)景scene , 對(duì)應(yīng)指針名gScene. 這大概是可以作到的最簡(jiǎn)單的PhysX 應(yīng)用了。同樣這段代碼也能正常編譯和運(yùn)行。

2 Setting Parameters for the SDK設(shè)置SDK的屬性
Now we add parameters to the SDK to flesh out our simulation.

現(xiàn)在我們來(lái)給SDK填充一些屬性來(lái)豐富我們的虛擬世界。

//設(shè)置SDK的屬性

gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01);

第一個(gè)設(shè)置的SDK的全局屬性被稱為皮膚寬度skin width 。這是一個(gè)很重要的屬性, basically a “grace-depth” the SDK allows objects to penetrate each other by基本上一個(gè) “grace-depth”SDK允許里面的物體相互穿透。 For now, we are setting it manually to 0.01 (an absolute depth of 0.01m or 1cm)因?yàn)楝F(xiàn)在,我們手動(dòng)地設(shè)置它為0.01(一個(gè)0.01米或1厘米絕對(duì)深度). If we don’t add this line, it will default to 0.025 (0.025m or 2.5cm).如果我們不寫(xiě)這一行代碼,它會(huì)采用默認(rèn)值0.025(0.025米或2.5厘米)。

// 設(shè)置一些調(diào)試可見(jiàn)的屬性

gPhysicsSDK->setParameter(NX_VISUALIZATION_SCALE, 1);

gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1);

gPhysicsSDK->setParameter(NX_VISUALIZE_ACTOR_AXES, 1);

These are debug visualization parameters we are setting for the simulation設(shè)置這些調(diào)試可見(jiàn)的屬性是為了實(shí)現(xiàn)我們需要的物理模擬效果,. We are saying when we switch to Debug Wireframe Mode, we want debug vectors to be 1 meter in length and we want to see all the collision shapes in the scene and the global poses of all the actors. 我們?cè)O(shè)置縮放比例為1m:1m,并且我們想在場(chǎng)景中看到所有的碰撞形狀,而且所有的角色都使用同一個(gè)朝向。亂七八糟的什么邊框激活模式,反正和上面圖形里面的白色條紋有關(guān)了。求高手翻譯。

3 Creating the Scene創(chuàng)建場(chǎng)景
We have adjusted all the parameters we want to the SDK and added a default material for objects to be constructed from. Now we create the scene. 我們已經(jīng)調(diào)整好了所有我們想要的SDK的屬性,并且給所有的物體增加了一個(gè)默認(rèn)的材質(zhì),現(xiàn)在我們來(lái)創(chuàng)建場(chǎng)景吧。

// 創(chuàng)建場(chǎng)景

NxSceneDesc sceneDesc;

sceneDesc.gravity = gDefaultGravity;

sceneDesc.simType = NX_SIMULATION_SW;

gScene = gPhysicsSDK->createScene(sceneDesc);

We start out with a scene descriptor which we feed to the SDK to create our scene. 我們創(chuàng)建了一個(gè)場(chǎng)景描述符(sceneDesc),然后依賴剛才我們定義好的SDK通過(guò)這個(gè)描述符來(lái)創(chuàng)建場(chǎng)景Descriptors are widely used throughout the SDK,這個(gè)描述符將被廣泛的應(yīng)用于SDK的各個(gè)位置. They are structures that contain all the information you want your object to be created with他們包含了所有我們想要?jiǎng)?chuàng)造的物體的構(gòu)造信息. You can adjust the descriptor to taste or leave it alone and the object will be created with the descriptor’s default settings.你可以調(diào)整這個(gè)描述符去嘗試使用或者不使用這個(gè)描述符來(lái)創(chuàng)建你物體。

In the above case, we want to create a software scene with the gravity vector provided. To create a software scene, set the simulation type to NX_SIMULATION_SW .

在上面的例子中,我們想要?jiǎng)?chuàng)建一個(gè)有重力方向的場(chǎng)景,就需要把simType設(shè)置為 NX_SIMULATION_SW。

4 Adding Materials to the Scene給場(chǎng)景增加一個(gè)默認(rèn)材質(zhì)
You want to give the scene a default physical material that everything will be made of. A material defines the collision and surface properties of the object the material is assigned to, that is, how the object will bounce, slide, and roll off other objects.

我們想在這個(gè)場(chǎng)景中創(chuàng)建的任何物體都具備一個(gè)默認(rèn)的材質(zhì),一個(gè)材質(zhì)可以定義這個(gè)物體的碰撞表面屬性。就是,可以會(huì)怎樣發(fā)生反彈,怎樣滑動(dòng),怎樣滾過(guò)其他的物體。

// Create the default material創(chuàng)建一個(gè)默認(rèn)的材質(zhì)

NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);

defaultMaterial->setRestitution(0.5);

defaultMaterial->setStaticFriction(0.5);

defaultMaterial->setDynamicFriction(0.5);

This says all objects in the scene are made of a substance with average bounciness (restitution of 0.5) and average resting and sliding friction (static friction of 0.5 and dynamic friction of 0.5).

這里聲明了在這個(gè)場(chǎng)景中的所有物體均具有0.5的還原系數(shù)(彈性阻尼),0.5的動(dòng)摩擦系數(shù)和靜摩擦系數(shù)。

5 Creating the Actors in the Scene在場(chǎng)景中創(chuàng)建角色Actor
At the end of InitNx(), we add our actors, the box and the plane, to the scene.

在InitNx()函數(shù)的末尾,我們把我們的角色添加進(jìn)場(chǎng)景中,他們是一個(gè)盒子和一個(gè)面板。

// Actor globals全局角色

NxActor* groundPlane = NULL;

NxActor* box = NULL;

void InitNx()

{

// Create the objects in the scene

groundPlane = CreateGroundPlane();

gSelectedActor = CreateBox();

CreateSphere();

CreateCapsule();

}

6 Creating the Ground Plane創(chuàng)建地面面板
We will be using a ground plane in most of our simulations and we add it here.

我們將在這里添加一個(gè)很多模擬將用到的地面面板。

void InitNx()

{

...

groundPlane = CreateGroundPlane();

...

}

來(lái)看函數(shù)CreateGroundPlane().

NxActor* CreateGroundPlane()

{

// Create a plane with default descriptor

NxPlaneShapeDesc planeDesc;

NxActorDesc actorDesc;

actorDesc.shapes.pushBack(&planeDesc);

return gScene->createActor(actorDesc);

}

This is probably the simplest actor creation function. The ground plane actor is initialized with an actor descriptor. The actor descriptor is initialized with the default plane descriptor, so the ground plane passes through the origin (0,0,0) with normal along the positive y-axis (0,1,0). The plane has no rigid body assigned to it, so it is a static actor: it will not move and will push dynamic objects away from it as if it had infinite mass.

這可能是最簡(jiǎn)單的角色創(chuàng)建函數(shù)了,這個(gè)地面面板角色通過(guò)一個(gè)actor的描述符初始化,而這個(gè)actor的描述符又通過(guò)一個(gè)默認(rèn)的plane描述符初始化,因此這個(gè)地面面板會(huì)穿過(guò)原點(diǎn)(0,0,0)并且法線方向始終指向 y軸(0,1,0)。這個(gè)面板沒(méi)有注冊(cè)對(duì)應(yīng)的剛體,所以它默認(rèn)為一個(gè)靜態(tài)角色:既它不能移動(dòng),而且能夠?qū)⑺械膭?dòng)態(tài)物體推離自己,無(wú)限廣闊就像真實(shí)世界的地面一樣。

7 Creating the Box創(chuàng)建盒子
We now create our box. It is a single actor consisting of a single shape.

現(xiàn)在我們來(lái)創(chuàng)建我們的立方體,一個(gè)由單一的簡(jiǎn)單圖形構(gòu)成的單一的角色。

void InitNx()

{

...

box = CreateBox();

...

}

以下為CreateBox() 函數(shù)的內(nèi)容:

NxActor* CreateBox()

{

// Set the box starting height to 3.5m so box starts off falling onto the ground賦值一個(gè)real型的數(shù)據(jù)startHeight =3.5米

NxReal boxStartHeight = 3.5;

// Add a single-shape actor to the scene在場(chǎng)景中添加一個(gè)簡(jiǎn)單圖形的角色

NxActorDesc actorDesc;

NxBodyDesc bodyDesc;

// The actor has one shape, a box, 1m on a side這個(gè)角色有一個(gè)圖形,一個(gè)立方體,棱長(zhǎng)為1

NxBoxShapeDesc boxDesc;

boxDesc.dimensions.set(0.5,0.5,0.5);

actorDesc.shapes.pushBack(&boxDesc);

actorDesc.body = &bodyDesc;

actorDesc.density = 10.0f;

actorDesc.globalPose.t = NxVec3(0,boxStartHeight,0);

assert(actorDesc.isValid());

NxActor *pActor = gScene->createActor(actorDesc);

assert(pActor);

// //create actor with no shapes創(chuàng)建一個(gè)沒(méi)有圖形的角色

//NxShape* const *shape = pActor->getShapes();

//NxBoxShape *boxShape = shape[0]->isBox();

//assert(boxShape);

//pActor->releaseShape(*boxShape);

return pActor;

}

We are creating an actor in the scene called “box”. To create the actor we need to pass an actor descriptor defining the actor to NxScene::createActor(). We give actorDesc a single shape descriptor, boxDesc. boxDesc describes a box that is one meter on a side. We set its dimensions using half the length, width, and height of the box with boxDesc.dimensions.set(0.5, 0.5, 0.5). Then we attach a body to the actor, bodyDesc, give the actor a density of 10, and set its global position to (0,boxStartHeight,0), meaning the center of the box will be at boxStartHeight = 3.5 meters above the ground at the beginning of the simulation.

我們?cè)趫?chǎng)景中創(chuàng)建了一個(gè)叫做“box”的角色,創(chuàng)建這個(gè)角色的方法Scene::createActor()需要通過(guò)一個(gè)角色描述符來(lái)定義角色信息。我們給這個(gè)角色描述符actorDesc一個(gè)簡(jiǎn)單形狀描述符,boxDesc。boxDesc描述了一個(gè)棱長(zhǎng)為1米的立方體,然后我們使用boxDesc.dimensions.set(0.5,0.5,0.5)方法使這個(gè)立方體的尺寸定制為0.5倍的長(zhǎng)寬高。然后我們將一個(gè)體綁定到這個(gè)actor上,bodyDesc,設(shè)置角色密度為10/米立方,并且定義這個(gè)角色的全局位置為(0,boxStartHeight,0),意味著當(dāng)程序開(kāi)始運(yùn)行時(shí),這個(gè)立方體的中心點(diǎn)會(huì)處于高為3.5米的空中。

Our actor consists of a single shape, a box 1m on a side, centered at (0, boxStartHeight,0), and having a density 10. When we call NxScene::createActor(), the rigid body we attached to the actor, bodyDesc, will be computed given the box shape and density we have constructed the actor with.

我們的角色由一個(gè)簡(jiǎn)單的形狀構(gòu)成,一個(gè)棱長(zhǎng)為1米的立方體,中心點(diǎn)位于(0,3.5 ,0)的位置上,并且密度為10,當(dāng)我們調(diào)用這個(gè)NxSceneActor()時(shí),這個(gè)剛體bodyDesc被綁定到這個(gè)角色上,將會(huì)計(jì)算出我們所構(gòu)造出的這個(gè)立方體的形狀以及密度。

8 Initializing the HUD初始化HUD
We create a heads-up-display object that displays whether or not the scene is running in hardware, whether or not the scene is paused, as well as additional information as needed by the tutorial.

這里我們將創(chuàng)建一個(gè)前臺(tái)展示系統(tǒng)來(lái)展示我們所運(yùn)行在PhysX中的角色。(這段我瞎翻譯的不要當(dāng)真)

若有高手請(qǐng)幫忙翻譯。不勝感激

// HUD globals全局的HUD

HUD hud;

// Simulation globals

bool bHardwareScene = false;

bool bPause = false;

void InitNx()

{

// Initialize HUD

bHardwareScene = (gScene->getSimType() == NX_SIMULATION_HW);

hud.Update(bHardwareScene, bPause, "");

}

The HUD class and its member variables and functions are defined in HUD.cpp and HUD.h.

這個(gè)HUD類以及它的成員變量和方法被定義在HUD.cpp和HUD.h中。

9 Updating the Time更新時(shí)間流
Next we call UpdateTime().

接下來(lái)我們調(diào)用UpdateTime()函數(shù)

UpdateTime.h

NxReal UpdateTime()

{

NxReal deltaTime;

#ifndef LINUX

static __int64 gTime,gLastTime;

__int64 freq;

QueryPerformanceCounter((LARGE_INTEGER *)&gTime); // Get current count

QueryPerformanceFrequency((LARGE_INTEGER *)&freq); // Get processor freq

deltaTime = (double)(gTime - gLastTime)/(double)freq;

gLastTime = gTime;

#else

struct timeval tv;

static struct timeval lasttv = { 0 , 0 };

if (lasttv.tv_usec == 0 && lasttv.tv_sec == 0)

gettimeofday(&lasttv, NULL);

gettimeofday(&tv, NULL);

deltaTime = (tv.tv_usec - lasttv.tv_usec)/1000000.f

+ (tv.tv_sec - lasttv.tv_sec);

lasttv = tv;

#endif

return deltaTime;

}

Lesson101.h

void InitNx()

{

...

// Get the current time

UpdateTime();

...

}

This sets gTime to the current time. Every frame we call UpdateTime() to get deltaTime, the amount of time that has passed since we last rendered the scene and therefore the amount of time we need to advance the simulation to render the current scene.

這里設(shè)置gTime來(lái)控制時(shí)間流,每一禎我們都調(diào)用UpdateTime()方法來(lái)獲取deltaTime——從我們最后一次渲染場(chǎng)景到現(xiàn)在的時(shí)間到當(dāng)前時(shí)間的時(shí)間段,因此這個(gè)我們需要在當(dāng)前渲染的活動(dòng)場(chǎng)景中增加這個(gè)加上這個(gè)時(shí)間段。

10 Starting the First Frame of the Simulation開(kāi)始模擬第一禎
Finally, we call StartPhysics() to start the first frame of the simulation.

最后,我們來(lái)調(diào)用StartPhysics()方法來(lái)啟動(dòng)這個(gè)模擬程序的第一禎。

void InitNx()

{

...

// Start the first frame of the simulation啟動(dòng),若存在場(chǎng)景則調(diào)用StartPhysics()

if (gScene) StartPhysics();

}

void StartPhysics()

{

// Update the time step更新時(shí)間

gDeltaTime = UpdateTime();

// Start collision and dynamics for delta time since the last frame從最后一禎的時(shí)間開(kāi)始模擬這個(gè)時(shí)間段的物理碰撞和破壞。

gScene->simulate(gDeltaTime);

gScene->flushStream();

}

11 Getting the Results of the Simulation獲取模擬的結(jié)果集
We have initialized the SDK and created our scene with InitNx(). Now we call glutMainLoop() from main().

我們已經(jīng)初始化了SDK并且使用InitNx()創(chuàng)建了場(chǎng)景,現(xiàn)在讓我們來(lái)從Main調(diào)用glutMainLoop()

int main(int argc, char** argv)

{

PrintControls();

InitGlut(argc, argv);

InitNx();

glutMainLoop();

ReleaseNx();

return 0;

}

The program will stay in glutMainLoop() until the user ends the simulation. After a scene is rendered, the RenderCallback() callback function gets called where we set up the next scene. At the beginning of RenderCallback(), we call NxScene::fetchResults() from GetPhysicsResults() to get the results of our physics simulation since our last call to NxScene::simulate() from StartPhysics().

這個(gè)程序?qū)⒁恢碧幱趃lutMainLoop()這個(gè)循環(huán)函數(shù)中,直到用戶終止這個(gè)模擬。當(dāng)一個(gè)場(chǎng)景渲染完畢后,我們需要渲染動(dòng)態(tài)場(chǎng)景的下一個(gè)狀況,RenderCallback()回調(diào)函數(shù)獲取調(diào)用。在RenderCallback()方法前端,我們調(diào)用GetPhysicsResult()函數(shù),使用Scene::fetchResults獲取結(jié)果集。處理輸入流后再繼續(xù)進(jìn)行物理模擬(這個(gè)大長(zhǎng)句讓我頭上星光閃閃了,以自己的理解翻譯了,肯定不是原意,求高手)

void RenderCallback()

{

...

if (gScene && !bPause)//如果存在場(chǎng)景,且沒(méi)有處于暫停狀態(tài)

{

GetPhysicsResults();//獲取物理模擬結(jié)果集

ProcessInputs();//處理輸入

StartPhysics();//開(kāi)始物理模擬

}

}

void GetPhysicsResults()

{

// Get results from gScene->simulate(deltaTime)通過(guò)gScene->simulate(delta Time)方法來(lái)獲取結(jié)果集。

while (!gScene->fetchResults(NX_RIGID_BODY_FINISHED, false));

}

We call NxScene::fetchResults(NX_RIGID_BODY_FINISHED, false) to close out the simulation started on the last call to NxScene::simulate(). The “NX_RIGID_BODY_FINISHED” parameter specifies that we want to close out the simulation of rigid bodies for this time step. The “false” parameter specifies that the call is non-blocking. We will not block waiting for the rigid body simulation to finish. If we put “true” here, instead:

我們使用NxScene::fetchResults(NX_RIGID_BODY_FINISHED,false)來(lái)處理從最后一次調(diào)用 NxScene::simulate() 的模擬。如果這里我們不等待所有剛體物理模擬完成,在這里我們選擇“true”,代碼應(yīng)替換為:

void GetPhysicsResults()

{

// Get results from gScene->simulate(deltaTime)

gScene->fetchResults(NX_RIGID_BODY_FINISHED, true);

}

...the NxScene::fetchResults() call will not return at all until the simulation is finished. With our call, we continually query to see if the simulation is finished and don't break out of the loop until the funciton returns true. We could use this space to execute additional code in case the physics for the frame is not yet finished.

除非所有的模擬完成,NxScene::fetchResults()不會(huì)返回任何內(nèi)容。程序會(huì)不斷的查詢這個(gè)模擬過(guò)程是否完成,并且一直等待這個(gè)應(yīng)答為“true”時(shí)才跳出循環(huán)。我們可以用這段禎空閑時(shí)間來(lái)執(zhí)行一些附加的代碼(不影響PhysX主循環(huán)的情況下)。

void GetPhysicsResults()

{

// Get results from gScene->simulate(deltaTime)

while (!gScene->fetchResults(NX_RIGID_BODY_FINISHED, false))

{

// Execute additional code here for rendering, AI, etc., 在這里執(zhí)行附加代碼,可以用于渲染,或者人工智能,或者其它

// while waiting for the rigid body simulation to finish在這個(gè)循環(huán)等待這段時(shí)間的物理運(yùn)算結(jié)束。

...

}

}

12 Processing Inputs to the Simulation處理輸入數(shù)據(jù)
We then call ProcessInputs() to collect all physics inputs to the new scene and set up any callbacks for the new scene. Here we apply forces to the box, set the position of the box, and set up callbacks, namely the user debug renderer, for the next simulation step.

接下來(lái)我們調(diào)用ProcessInputs()來(lái)收集所有服務(wù)于新場(chǎng)景(應(yīng)為場(chǎng)景新?tīng)顟B(tài))的物理輸入數(shù)據(jù)和任何回調(diào)數(shù)據(jù)。在這里我們?cè)O(shè)置了一個(gè)作用于box的力,設(shè)置box的位置,和組織回調(diào)內(nèi)容,即用戶的調(diào)試渲染器,為下一個(gè)模擬步驟準(zhǔn)備。

void RenderCallback()

{

...

if (gScene && !bPause)

{

GetPhysicsResults();

ProcessInputs();

StartPhysics();

}

}

...

void ProcessInputs()

{

ProcessForceKeys();

// Show debug wireframes

if (bDebugWireframeMode)

{

if (gScene) gDebugRenderer.renderData(*gScene->getDebugRenderable());

}

}

1. Selecting Actors選擇角色

Press ‘r’ to call SelectNextActor to select other actor. The selected actor is rendered in wireframe mode. The actor with NX_TRIGGER_ENABLE flag and static actor can’t be selected.

按下‘r’鍵來(lái)調(diào)用SelectNextActor()選擇下一個(gè)角色。這個(gè)被選擇的角色會(huì)被渲染成邊框激活模式。擁有觸發(fā)器可用(NX _TRIGGER_ENABLE)標(biāo)示的角色和靜態(tài)的角色(例如GroundPlane) 不會(huì)被選擇到。

void SelectNextActor()

{

NxU32 nbActors = gScene->getNbActors();

NxActor** actors = gScene->getActors();

for(NxU32 i = 0; i < nbActors; i++)

{

if (actors[i] == gSelectedActor)

{

NxU32 j = 1;

gSelectedActor = actors[(i+j)%nbActors];

while (!IsSelectable(gSelectedActor))

{

j++;

gSelectedActor = actors[(i+j)%nbActors];

}

break;

}

}

}

2. Applying Forces to the Actors對(duì)選擇的角色施加作用力

Our first call is to ProcessForceKeys(), where we call ApplyForceToActor() on our actor.

我們第一次調(diào)用ProcessForceKeys(),哪里我們對(duì)actor調(diào)用ApplyForceToActor()函數(shù)。

// Force globals全局作用力變量

NxVec3 gForceVec(0,0,0);//方向

NxReal gForceStrength = 20000;//力量

bool bForceMode = true;//???

// Keyboard globals鍵盤(pán)全局編號(hào)

#define MAX_KEYS 256

bool gKeys[MAX_KEYS];//256的鍵盤(pán)誒。其實(shí)是ASIC碼了

void ProcessForceKeys()

{

// Process force keys處理鍵盤(pán)鍵

for (int i = 0; i < MAX_KEYS; i++)

{

if (!gKeys[i]) { continue; }

switch (i)

{

// Force controls控制

case 'j': {gForceVec = ApplyForceToActor(gSelectedActor, NxVec3(1,0,0), gForceStrength); break; }//如果為j碼時(shí),給gSelectedActor一個(gè)方向?yàn)椋?,0,0),大小為20000牛的 作用力,執(zhí)行完成后跳出循環(huán)。

}

}

}

...

void ProcessInputs()

{

ProcessForceKeys();

...

}

ApplyForceToActor() calls NxActor::addForce() to add forces to the box through keyboard input.

NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength)

{

NxVec3 forceVec = forceStrength*forceDir*gDeltaTime;

actor->addForce(forceVec);

return forceVec;

}

Every time we hit “j”, we call box->addForce(NxVec3(gForceStrength,0,0)) and a force of gForceStrength = 20000 is applied continuously to the box at its center along the positive x-axis each frame. Note, when running the simulation, you start out facing down the positive z-axis of the scene marked in blue. The positive y-axis is in green going up and the positive x-axis is in red going to the left. All axes in the SDK are set up and rendered in this manner. “j” now imparts a force that pushes the box to the left. The force is shown as a yellow arrow. Note using the “umijkl” buttons, the force is constant, applied at the center of the box, and always faces along the global x, y, or z-axis.

每當(dāng)我們點(diǎn)擊‘j’,我們都調(diào)用box->addForce(NxVec3(gFoceStrength,0,0))方法,即每一禎都會(huì)有一個(gè)沿x軸正方向大小為20000牛的作用力持續(xù)作用在這個(gè)立方體上,時(shí)間應(yīng)該是gDeltaTime,即禎與禎的間隔時(shí)間。(功效還是很大的1秒可以產(chǎn)生20000焦耳的能量吧2W瓦。。。)。注釋:。。。

今天先翻譯到此,要下班了。明天把最困難的第一章翻譯完,然后把這段時(shí)間的學(xué)習(xí)筆記奉上,包括Ogre,Havok以及PhysX。

3. Resetting the Position of the Actors

Next we call NxActor::setGlobalPosition() to set the position of the box in ProcessKeys().

// Keyboard globals

#define MAX_KEYS 256

bool gKeys[MAX_KEYS];

void ProcessKeys()

{

// Process keys

for (int i = 0; i < MAX_KEYS; i++)

{

if (!gKeys[i]) { continue; }

switch (i)

{

// Return box to (0,5,0)

case 't': { gSelectedActor->setGlobalPosition(NxVec3(0,5,0)); break; }

}

}

}

Every time we hit “t”, we call NxActor::setGlobalPosition(NxVec3(0,5,0)) on our box actor. This places the actor at a position 5 units above the origin.

As with adding forces, we need to do this in between the NxScene::fetchResults() call in GetPhysicsResults() and the NxScene::simulate() call in StartPhysics()). It is an input to the physics scene which we need to perform while the scene is not being calculated by the hardware.

4. Debugging the Objects

After processing possible calls to add forces to and set the position of the box, we call the following code.

void ProcessInputs()

{

// Show debug wireframes

if (bDebugWireframeMode)

{

if (gScene) gDebugRenderer.renderData(*gScene->getDebugRenderable());

}

}

Hitting “b” in the demo toggles these wireframes on and off. The call gDebugRenderer.renderData() renders wireframes in the scene that we set up to visualize in InitNx() in order to see the collision shapes and actor axes in the scene. You can see the DebugRenderer::renderData() function in DebugRenderer.cpp.

void DebugRenderer::renderData(const NxDebugRenderable& data) const

{

glLineWidth(1.0f);

glPushMatrix();

glDisable(GL_LIGHTING);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

// Render points

NxU32 NbPoints = data.getNbPoints();

if(NbPoints)

{

...

}

// Render lines

NxU32 NbLines = data.getNbLines();

if(NbLines)

{

...

}

// Render triangles

NxU32 NbTris = data.getNbTriangles();

if(NbTris)

{

...

}

// Reset the color

glColor3f(1,1,1);

glEnable(GL_LIGHTING);

glPopMatrix();

}

Note that drawing these debug wireframes is for debug mode only. The drawing is not optimal because it is not done in parallel with the physics simulation, i.e., the physics simulation is idle when you do the debug rendering.

For more information on the Debug Renderer, see “Lesson 301: Debug Renderer”.

13 Starting the Simulation
Finally, we call StartPhysics() to start the next frame of the simulation.

void RenderCallback()

{

...

if (gScene && !bPause)

{

...

StartPhysics();

}

}

...

void StartPhysics()

{

// Update the time step

gDeltaTime = UpdateTime();

// Start collision and dynamics for delta time since the last frame

gScene->simulate(gDeltaTime);

gScene->flushStream();

}

StartPhysics() calls UpdateTime(), which gets deltaTime, the time step since the last scene. We call NxScene::simulate(deltaTime) and NxScene::flushStream() to run the simulation for the time step.

NxScene::simulate() is point of entry to the PhysX physics solver and the heart of the simulation. The SDK simulates the scene we have constructed for deltaTime. All computation for the simulation takes place on the hardware and gets retrieved by the next call to NxScene::fetchResults() which we call from GetPhysicsResults().

14 Drawing the Objects
After we call GetPhysicsResults(), ProcessInputs(), and StartPhysics()in RenderCallback(), we draw the objects in the scene from gCameraPos (0,5,-15) facing gCameraForward (0,0,1), so 5 meters above and 15 meters behind the origin along the z-axis, and facing the origin along positive z. We draw the actors and their shadows on the ground plane with the following code.

void RenderActors(bool shadows)

{

// Render all the actors in the scene

NxU32 nbActors = gScene->getNbActors();

NxActor** actors = gScene->getActors();

while (nbActors--)

{

NxActor* actor = *actors++;

DrawActor(actor);

// Handle shadows

if (shadows)

{

DrawActorShadow(actor);

}

}

}

void RenderCallback()

{

RenderActors(bShadows);

}

DrawActor() and DrawActorShadow() loop through all the shapes in the actor, drawing each shape and its shadow. The code for drawing the different types of shapes is in DrawShapes.cpp. You can look at it, but it’s not important for the lesson right now, just know this is where the actors get drawn.

15 Drawing the Forces
The force that gets applied to the box is returned to gForceVec. In RenderCallback(), we call DrawForce() to draw an arrow representing the force applied to the box.

void ProcessForceKeys ()

{

// Process force keys

for (int i = 0; i < MAX_KEYS; i++)

{

if (!gKeys[i]) { continue; }

switch (i)

{

// Force controls

case 'i': {gForceVec = ApplyForceToActor(gSelectedActor, NxVec3(0,0,1), gForceStrength); break; }

case 'k': {gForceVec = ApplyForceToActor(gSelectedActor, NxVec3(0,0,-1), gForceStrength); break; }

case 'j': {gForceVec = ApplyForceToActor(gSelectedActor, NxVec3(1,0,0), gForceStrength); break; }

case 'l': {gForceVec = ApplyForceToActor(gSelectedActor, NxVec3(-1,0,0), gForceStrength); break; }

case 'u': {gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,1,0), gForceStrength); break; }

case 'm': {gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,-1,0), gForceStrength); break; }

}

}

}

...

void ProcessInputs()

{

ProcessForceKeys();

}

...

void DrawForce(NxActor* actor, NxVec3& forceVec, const NxVec3& color)

{

// Draw only if the force is large enough

NxReal force = forceVec.magnitude();

if (force < 0.1f) return;

forceVec = 3*forceVec/force;

NxVec3 pos = actor->getCMassGlobalPosition();

DrawArrow(pos, pos + forceVec, color);

}

...

void RenderCallback()

{

...

if (gScene && !bPause)

{

...

ProcessInputs();

...

}

...

DrawForce(box, gForceVec, NxVec3(1,1,0));

gForceVec = NxVec3(0,0,0);

}

This code draws a yellow arrow originating from the center of mass of the box and extending 3 meters in the direction of the axis-aligned force.

16 Resetting the Scene and Shutting Down
Run the simulation for a while and hit F10. You will notice the box appears back in its starting position, falling to the ground as before. Hitting F10 resets the scene, calling ResetNx() which calls ReleaseNx() to shut down the SDK and then InitNx() to start it up again.

// Physics SDK globals

NxPhysicsSDK* gPhysicsSDK = NULL;

NxScene* gScene = NULL;

void SpecialCallback(int key, int x, int y)

{

switch (key)

{

// Reset PhysX

case GLUT_KEY_F10: ResetNx(); return;

}

}

void ReleaseNx()

{

if (gScene)

{

GetPhysicsResults(); // Make sure to fetchResults() before shutting down

gPhysicsSDK->releaseScene(*gScene);

}

if (gPhysicsSDK) gPhysicsSDK->release();

}

void ResetNx()

{

ReleaseNx();

InitNx();

}

ReleaseNx() calls GetPhysicsResults() which calls NxScene::fetchResults(), which waits for the card to finish processing the scene. It then calls NxPhysicsSDK::releaseScene() which deletes all the objects in the scene and then deletes the scene itself. It then calls NxPhysicsSDK::release() which shuts down the SDK.

ReleaseNx() is also called after glutMainLoop() to shut down the SDK before exiting.

17 Major Application Functions
The major functions of interest in the application are:

RenderCallback()

Calls GetPhysicsResults(), ProcessInputs(), and StartPhysics() each frame to simulate the scene. Places the camera with SetupCamera(). Draws the actors in the scene with RenderActors(). Draws the user supplied force to objects in the scene with DrawForce().

GetPhysicsResults()

Calls NxScene::fetchResults() to retrieve the results of the last frame of simulation.

ProcessInputs()

Gets keyboard input from ProcessForceKeys(). Calls NxDebugRenderer::renderData() to draw debug wireframes on the actors.

StartPhysics()

Calls UpdateTime() to get gDeltaTime, the time since the last frame of the scene was rendered. Calls NxScene::simulate(gDeltaTime) and NxScene::flushStream() to run the simulation for gDeltaTime.

InitNx()

Initializes the PhysX SDK with NxCreatePhysicsSDK(). Adds simulation-wide parameters with NxPhysicsSDK::setParameter(). Adds new materials to the SDK by calling NxScene::getMaterialFromIndex() and adjusting the material properties using NxMaterial::setRestitution(), ::setStaticFriction(), and ::setDynamicFriction(). Creates the scene with NxPhysicsSDK::createScene(). Constructs the actors in the scene with CreateGroundPlane() and CreateBox(), both of which call NxScene::createActor(). Sets the current time with UpdateTime(). Begins the simulation with StartPhysics().

gDebugRenderer.renderData()

Renders wireframes to visualize debug wireframes on the actors such as collision shapes and actor axes.

ReleaseNx()

Calls GetPhysicsResults() to close out the simulation. Calls NxPhysicsSDK::releaseScene() to shut down the scene and NxPhysicsSDK::release() to shut down the SDK.

18 Conclusion and Playing Around
You have completed a basic application using the PhysX SDK. Congratulations! You have taken your first step into a larger world. Experiment as much as you can with your creation. Use the “umijkl” keys to push the box around the plane and use the “qzwasd” keys to follow it around with the camera.

There is a lot of information in this lesson and it is fairly comprehensive as it covers an entire working application with everything from initializing the SDK, initializing the scene, creating an actor, applying forces to the actor through keyboard inputs, drawing the actor, running the simulation, drawing forces applied to the actor, and drawing debug wireframes for the objects. Don’t panic if there are some things you don’t understand right now. Everything will become more apparent with practice as you continue to use the SDK.

In future lessons, we will use the same framework as this lesson and introduce one or two new features per lesson until we have covered all the features in the SDK.

19 Related Classes, Functions, and Parameters
NxCreatePhysicsSDK()

NxPhysicsSDK

createScene()

setParameter()

visualize()

releaseScene()

release()

NxMaterial

setRestitution()

setStaticFriction()

setDynamicFriction()

NxSceneDesc

gravity

simType

NxScene

getMaterialFromIndex()

createActor()

simulate()

flushStream()

fetchResults()

NxPlaneShapeDesc

NxBoxShapeDesc

Dimensions

NxSphereShapeDesc

radius

NxCapsuleShapeDesc

radius

height

NxBodyDesc

NxActorDesc

shapes

body

density

globalPose

NxActor

setGlobalPosition()

getCMassGlobalPosition()

addForce()

NxDebugRenderable

getNbPoints()

getPoints()

getNbLines()

getLines()

getNbTriangles()

getTriangles()

NxDebugPoint

color

p

NxDebugLine

color

p0

p1

NxDebugTriangle

color

p0

p1

p2

NxParameter

NX_SKIN_WIDTH

NX_VISUALIZE_COLLISION_SHAPES

NX_VISUALIZE_ACTOR_AXES

NxSimulationStatus

NX_RIGID_BODY_FINISHED

21 Relationship between localPose and globalPose
In CreateBox, CreateSphere and CreateCapsule functions, there are two variables: localPose and globalPose need to be noted. See the following snippet:

NxCapsuleShapeDesc capsuleDesc;

capsuleDesc.radius = 0.55f;

capsuleDesc.height = 0.75f;

capsuleDesc.localPose.t = NxVec3(0, 0, 0);

//Rotate capsule shape

NxQuat quat(45, NxVec3(0, 0, 1));

NxMat33 m33(quat);

capsuleDesc.localPose.M = m33;

actorDesc.shapes.pushBack(&capsuleDesc);

actorDesc.body = &bodyDesc;

actorDesc.density = 10.0f;

actorDesc.globalPose.t =NxVec3(6.0f,capsuleStartHeight,0);

Here, globalPose is the coordinate in world coordinate System; localPose is the coordinate based on globalPose. See the below illustration:

Y Y’

Z

Z’

localPose

X’

globalPose

X World Coordinate System

本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/sine199/archive/2009/11/26/4879937.aspx

再分享一下我老師大神的人工智能教程吧。零基礎(chǔ)!通俗易懂!風(fēng)趣幽默!還帶黃段子!希望你也加入到我們?nèi)斯ぶ悄艿年?duì)伍中來(lái)!https://blog.csdn.net/jiangjunshow

總結(jié)

以上是生活随笔為你收集整理的PhysX官方教程lession101的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。