CollisionShape2TriangleMesh.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include "CollisionShape2TriangleMesh.h"
  2. #include "btBulletCollisionCommon.h"
  3. #include "BulletCollision/CollisionShapes/btShapeHull.h"//to create a tesselation of a generic btConvexShape
  4. void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTransform& parentTransform, btAlignedObjectArray<btVector3>& vertexPositions, btAlignedObjectArray<btVector3>& vertexNormals, btAlignedObjectArray<int>& indicesOut)
  5. {
  6. //todo: support all collision shape types
  7. switch (collisionShape->getShapeType())
  8. {
  9. case SOFTBODY_SHAPE_PROXYTYPE:
  10. {
  11. //skip the soft body collision shape for now
  12. break;
  13. }
  14. case STATIC_PLANE_PROXYTYPE:
  15. {
  16. //draw a box, oriented along the plane normal
  17. const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(collisionShape);
  18. btScalar planeConst = staticPlaneShape->getPlaneConstant();
  19. const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
  20. btVector3 planeOrigin = planeNormal * planeConst;
  21. btVector3 vec0,vec1;
  22. btPlaneSpace1(planeNormal,vec0,vec1);
  23. btScalar vecLen = 100.f;
  24. btVector3 verts[4];
  25. verts[0] = planeOrigin + vec0*vecLen + vec1*vecLen;
  26. verts[1] = planeOrigin - vec0*vecLen + vec1*vecLen;
  27. verts[2] = planeOrigin - vec0*vecLen - vec1*vecLen;
  28. verts[3] = planeOrigin + vec0*vecLen - vec1*vecLen;
  29. int startIndex = vertexPositions.size();
  30. indicesOut.push_back(startIndex+0);
  31. indicesOut.push_back(startIndex+1);
  32. indicesOut.push_back(startIndex+2);
  33. indicesOut.push_back(startIndex+0);
  34. indicesOut.push_back(startIndex+2);
  35. indicesOut.push_back(startIndex+3);
  36. btVector3 triNormal = parentTransform.getBasis()*planeNormal;
  37. for (int i=0;i<4;i++)
  38. {
  39. btVector3 vtxPos;
  40. btVector3 pos =parentTransform*verts[i];
  41. vertexPositions.push_back(pos);
  42. vertexNormals.push_back(triNormal);
  43. }
  44. break;
  45. }
  46. case TRIANGLE_MESH_SHAPE_PROXYTYPE:
  47. {
  48. btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*) collisionShape;
  49. btVector3 trimeshScaling = trimesh->getLocalScaling();
  50. btStridingMeshInterface* meshInterface = trimesh->getMeshInterface();
  51. btAlignedObjectArray<btVector3> vertices;
  52. btAlignedObjectArray<int> indices;
  53. for (int partId=0;partId<meshInterface->getNumSubParts();partId++)
  54. {
  55. const unsigned char *vertexbase = 0;
  56. int numverts = 0;
  57. PHY_ScalarType type = PHY_INTEGER;
  58. int stride = 0;
  59. const unsigned char *indexbase = 0;
  60. int indexstride = 0;
  61. int numfaces = 0;
  62. PHY_ScalarType indicestype = PHY_INTEGER;
  63. //PHY_ScalarType indexType=0;
  64. btVector3 triangleVerts[3];
  65. meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
  66. btVector3 aabbMin,aabbMax;
  67. for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
  68. {
  69. unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
  70. for (int j=2;j>=0;j--)
  71. {
  72. int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
  73. if (type == PHY_FLOAT)
  74. {
  75. float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
  76. triangleVerts[j] = btVector3(
  77. graphicsbase[0]*trimeshScaling.getX(),
  78. graphicsbase[1]*trimeshScaling.getY(),
  79. graphicsbase[2]*trimeshScaling.getZ());
  80. }
  81. else
  82. {
  83. double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
  84. triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*trimeshScaling.getX()),
  85. btScalar(graphicsbase[1]*trimeshScaling.getY()),
  86. btScalar(graphicsbase[2]*trimeshScaling.getZ()));
  87. }
  88. }
  89. indices.push_back(vertices.size());
  90. vertices.push_back(triangleVerts[0]);
  91. indices.push_back(vertices.size());
  92. vertices.push_back(triangleVerts[1]);
  93. indices.push_back(vertices.size());
  94. vertices.push_back(triangleVerts[2]);
  95. btVector3 triNormal = (triangleVerts[1]-triangleVerts[0]).cross(triangleVerts[2]-triangleVerts[0]);
  96. triNormal.normalize();
  97. for (int v=0;v<3;v++)
  98. {
  99. btVector3 pos =parentTransform*triangleVerts[v];
  100. indicesOut.push_back(vertexPositions.size());
  101. vertexPositions.push_back(pos);
  102. vertexNormals.push_back(triNormal);
  103. }
  104. }
  105. }
  106. break;
  107. }
  108. default:
  109. {
  110. if (collisionShape->isConvex())
  111. {
  112. btConvexShape* convex = (btConvexShape*)collisionShape;
  113. {
  114. btShapeHull* hull = new btShapeHull(convex);
  115. hull->buildHull(0.0);
  116. {
  117. //int strideInBytes = 9*sizeof(float);
  118. //int numVertices = hull->numVertices();
  119. //int numIndices =hull->numIndices();
  120. for (int t=0;t<hull->numTriangles();t++)
  121. {
  122. btVector3 triNormal;
  123. int index0 = hull->getIndexPointer()[t*3+0];
  124. int index1 = hull->getIndexPointer()[t*3+1];
  125. int index2 = hull->getIndexPointer()[t*3+2];
  126. btVector3 pos0 =parentTransform*hull->getVertexPointer()[index0];
  127. btVector3 pos1 =parentTransform*hull->getVertexPointer()[index1];
  128. btVector3 pos2 =parentTransform*hull->getVertexPointer()[index2];
  129. triNormal = (pos1-pos0).cross(pos2-pos0);
  130. triNormal.normalize();
  131. for (int v=0;v<3;v++)
  132. {
  133. int index = hull->getIndexPointer()[t*3+v];
  134. btVector3 pos =parentTransform*hull->getVertexPointer()[index];
  135. indicesOut.push_back(vertexPositions.size());
  136. vertexPositions.push_back(pos);
  137. vertexNormals.push_back(triNormal);
  138. }
  139. }
  140. }
  141. delete hull;
  142. }
  143. } else
  144. {
  145. if (collisionShape->isCompound())
  146. {
  147. btCompoundShape* compound = (btCompoundShape*) collisionShape;
  148. for (int i=0;i<compound->getNumChildShapes();i++)
  149. {
  150. btTransform childWorldTrans = parentTransform * compound->getChildTransform(i);
  151. CollisionShape2TriangleMesh(compound->getChildShape(i),childWorldTrans,vertexPositions,vertexNormals,indicesOut);
  152. }
  153. } else
  154. {
  155. btAssert(0);
  156. }
  157. }
  158. }
  159. };
  160. }