研究physx的一些进展(NxTriangleMesh)

 

physx有很多用户类需要自己写,很麻烦,比如NxStream,NxUserAllocator,不过他带的例子中有现成了,拿来用好了 :)
physx的plane类型和character不能进行碰撞,这点非常奇怪,网上问了很多人,都不得要领,在他的官方论坛上问,也没有回应,好在他的NxtriangleMesh支持和character的碰撞。
physx除了对固定形状的碰撞判定外,还支持任意形状物体的判定,不过效率不知道如何,我也没有做过专门的测试,等以后有机会在做吧。
使用ogre的mesh的顶点数据导入physx,其实方法很简单,physx中有一个NxTriangleMeshDesc专门用于处理mesh数据。
physx感兴趣的数据只有2个,vertex和index,所以,mesh我们只需要得到这2种数据就可以了,没有什么难度,直接看代码吧
NxTriangleMesh *BuildNxTriangleMesh( MeshPtr mesh )
{
 unsigned short submeshNum = mesh->getNumSubMeshes();
 SubMesh *ghm_submesh = mesh->getSubMesh( 0 );    //还没想好sub mesh的问题,以后再说
 //read vertex buffer
 Ogre::VertexBufferBinding::VertexBufferBindingMap ghm_VBBM = ghm_submesh->vertexData->vertexBufferBinding->getBindings();
 int iPositonIndex = -1;
 //find position buffer
 for ( int i = 0; i < ghm_submesh->vertexData->vertexDeclaration->getElementCount(); i++)
 {
  const VertexElement *ghm_VE = ghm_submesh->vertexData->vertexDeclaration->getElement( i );
  if ( ghm_VE->getSemantic() == VES_POSITION )  //we are just interested in position
  {
   //bingo,get it
   iPositonIndex = i;
   break;
  }
 }
 if ( iPositonIndex == -1 )    //can't find position buffer
  return false;
 Ogre::VertexBufferBinding::VertexBufferBindingMap::iterator vbbm_interator = ghm_VBBM.find( iPositonIndex );
 size_t vertexbuffersize = vbbm_interator->second->getNumVertices() * vbbm_interator->second->getVertexSize(); //buffer size
 BYTE *VertexBuffer = new BYTE[vertexbuffersize];              //build buffer
 vbbm_interator->second->readData( 0, vertexbuffersize, VertexBuffer );        //read data
 //read index buffer
 size_t indexbuffersize = ghm_submesh->indexData->indexBuffer->getNumIndexes() * ghm_submesh->indexData->indexBuffer->getIndexSize();  //buffer size
 BYTE *IndexBuffer = new BYTE[indexbuffersize];                       //build buffer
 ghm_submesh->indexData->indexBuffer->readData( 0, indexbuffersize, IndexBuffer );             //read data
 
 // Build physical model
 NxTriangleMeshDesc terrainDesc;
 terrainDesc.numVertices     = vbbm_interator->second->getNumVertices();
 terrainDesc.numTriangles    = ghm_submesh->indexData->indexBuffer->getNumIndexes() / 3;
 terrainDesc.pointStrideBytes   = sizeof(NxVec3);
 if(ghm_submesh->indexData->indexBuffer->getType() == Ogre::HardwareIndexBuffer::IT_16BIT )
 {
  terrainDesc.triangleStrideBytes   = 3*sizeof(NxU16);
 }
 else
 {
  terrainDesc.triangleStrideBytes   = 3*sizeof(NxU32);
 }
 terrainDesc.points      = VertexBuffer;
 terrainDesc.triangles     = IndexBuffer;
 terrainDesc.flags      = NX_MF_16_BIT_INDICES | NX_MF_HARDWARE_MESH ;
 terrainDesc.heightFieldVerticalAxis  = NX_Y;
 terrainDesc.heightFieldVerticalExtent = -1000.0f;
 NxTriangleMeshShapeDesc terrainShapeDesc;
 MemoryWriteBuffer writeBuffer;
 bool rt = m_CookingInterface->NxCookTriangleMesh( terrainDesc,writeBuffer );
 return m_PhysicsSDK->createTriangleMesh(MemoryReadBuffer(writeBuffer.data));
}
一般来说用作碰撞的物体,不会含有多个sub mesh所以我直接读0,这个函数返回一个NxTriangleMesh的指针,通过赋给NxTriangleMeshShapeDesc的meshdata就可以了。
 
关于碰撞:一个character可以在一个mesh内部,或者上部,这个mesh可以是不缝合的mesh,另外注意skinwidth的设置,如果过小,碰撞会检测不到。
发布了21 篇原创文章 · 获赞 3 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章