CollisionShape2TriangleMesh.cpp 7.8 KB

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