CR的代码文本

all for learning about the world
  订阅 订阅  :: 管理

PhysX2.8教程:Cooking

Posted on 2011-06-17 10:39  mumuliang  阅读(2456)  评论(0编辑  收藏  举报
来自:The PhysX SDK.chm/Guide/Collision Detection/Meshes/Cooking

创建三角网格,首先要把它cook成某种固定格式,在这种格式下SDK才能高效的进行冲突检测。cooking的过程可能会非常慢,因此cooking操作通常是离线的并且只做一次,完成以后,将结果数据generated stream保存成文档形式,下一次只需要载入。


使用PPU进行cook,另外有一些注意事项。详见Mesh Paging章节。

实用程序使用NxCooking库cook网格。首先要调用如下接口初始化一个NxCooking库的对象:

 

static NxCookingInterface* gCooking = NxGetCookingLib(NX_PHYSX_SDK_VERSION);
gCooking
->NxInitCooking();

然后,用一个NxTriangleMeshDesc对象描述一个网格,将其作为参数传递给函数NxCookTriangleMesh(),该函数会处理网格描述并通过用户实现的stream——NxStream是PhysX要求用户实现的一个读写操作的接口——然后stream就能将其写入文件或内存。

//Build physical model 
NxTriangleMeshDesc bunnyDesc;    
bunnyDesc.numVertices 
= BUNNY_NBVERTICES; 
bunnyDesc.numTriangles 
= BUNNY_NBFACES;
bunnyDesc.pointStrideBytes 
= sizeof(NxVec3);
bunnyDesc.triangleStrideBytes 
= 3*sizeof(NxU32);
bunnyDesc.points 
= gBunnyVertices;
bunnyDesc.triangles 
= gBunnyTriangles;
bunnyDesc.flags 
= 0
gCooking
->NxCookTriangleMesh(bunnyDesc, UserStream("c:\\cooked.bin"false));

接下来,当应用程序需要创建三角面mesh时,通过下面的函数载入stream保存的mesh数据。

bunnyTriangleMesh = gPhysicsSDK->createTriangleMesh(UserStream("c:\\tmp.bin"true));

NxCookConvexMesh()/NxCookClothMesh()NxCookTriangleMesh()用法一样一样的。

注意: cooking操作受精度影响很大,很依赖于浮点运算单元FPU的模式。跨平台的话,要保证FPU的精度和舍入方式是一致的。

上例中,没有设置flag成员。flag可以设置一些特殊标志。例如

  1. NX_MF_FLIPNORMALS – 索引列表中三个顶点的顺序反向(默认是逆时针),即法线反向
  2. NX_MF_16_BIT_INDICES – 顶点索引数据长度16bit而不是32bit
  3. NX_MF_CONVEX – 允许将mesh看做convex,并自动优化

三角面的法线没有显式的描述出来,它可以这样算出来
(v1 – v0) x (v2 – v0)
v0,v1,v2是三角形的三个顶点。逆时针顺序counter-clockwise(右手法则right handed coordinate system)还是顺时针顺序,这个算法都是一样的。


网格注意事项:
  1. 确保法线的朝向,别反了。冲突检测只能正确计算正面过来的shape。
  2. 顶点不要重复。如果俩三角形共享一个顶点,这个点只能在顶点列表中出现一次,只不过是在索引列表中索引两次。因为重复的顶点对PhysX来说,它就是两个点,这就会造成冲突检测错误。
  3. 不要用T-Joint和non-manifold edge。(因为这两个东西都会要求三角面中的共享点被看做两个点。)
  4. 一旦网格cook完成了,质量mass和inertia tensor也都计算出来了。
  5. 同一个网格中的不同三角面的材质可以不同。详见Material章节

然后就可以用mesh创建shape并Actor了。关键就是把triangle mesh shape description的meshdata设置为前面cooking后的mesh就O了。

NxTriangleMeshShapeDesc bunnyShapeDesc;
bunnyShapeDesc.meshData
= bunnyTriangleMesh;
NxBodyDesc bodyDesc;
NxActorDesc actorDesc;
actorDesc.shapes.pushBack(
&bunnyShapeDesc);
actorDesc.body
= &bodyDesc;
actorDesc.density
= 1.0f;
NxActor
* newActor = gScene->createActor(actorDesc);