研究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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章