1 #ifndef BT_COMPOUND_FROM_GIMPACT 2 #define BT_COMPOUND_FROM_GIMPACT 3 4 #include "BulletCollision/CollisionShapes/btCompoundShape.h" 5 #include "btGImpactShape.h" 6 #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" 7 8 struct MyCallback : public btTriangleRaycastCallback 9 { 10 int m_ignorePart; 11 int m_ignoreTriangleIndex; 12 13 14 MyCallback(const btVector3& from, const btVector3& to, int ignorePart, int ignoreTriangleIndex) 15 :btTriangleRaycastCallback(from,to), 16 m_ignorePart(ignorePart), 17 m_ignoreTriangleIndex(ignoreTriangleIndex) 18 { 19 20 } 21 virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex) 22 { 23 if (partId!=m_ignorePart || triangleIndex!=m_ignoreTriangleIndex) 24 { 25 if (hitFraction < m_hitFraction) 26 return hitFraction; 27 } 28 29 return m_hitFraction; 30 } 31 }; 32 struct MyInternalTriangleIndexCallback :public btInternalTriangleIndexCallback 33 { 34 const btGImpactMeshShape* m_gimpactShape; 35 btCompoundShape* m_colShape; 36 btScalar m_depth; 37 38 MyInternalTriangleIndexCallback (btCompoundShape* colShape, const btGImpactMeshShape* meshShape, btScalar depth) 39 :m_colShape(colShape), 40 m_gimpactShape(meshShape), 41 m_depth(depth) 42 { 43 } 44 45 virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) 46 { 47 btVector3 scale = m_gimpactShape->getLocalScaling(); 48 btVector3 v0=triangle[0]*scale; 49 btVector3 v1=triangle[1]*scale; 50 btVector3 v2=triangle[2]*scale; 51 52 btVector3 centroid = (v0+v1+v2)/3; 53 btVector3 normal = (v1-v0).cross(v2-v0); 54 normal.normalize(); 55 btVector3 rayFrom = centroid; 56 btVector3 rayTo = centroid-normal*m_depth; 57 58 MyCallback cb(rayFrom,rayTo,partId,triangleIndex); 59 60 m_gimpactShape->processAllTrianglesRay(&cb,rayFrom, rayTo); 61 if (cb.m_hitFraction<1) 62 { 63 rayTo.setInterpolate3(cb.m_from,cb.m_to,cb.m_hitFraction); 64 //rayTo = cb.m_from; 65 //rayTo = rayTo.lerp(cb.m_to,cb.m_hitFraction); 66 //gDebugDraw.drawLine(tr(centroid),tr(centroid+normal),btVector3(1,0,0)); 67 } 68 69 70 71 btBU_Simplex1to4* tet = new btBU_Simplex1to4(v0,v1,v2,rayTo); 72 btTransform ident; 73 ident.setIdentity(); 74 m_colShape->addChildShape(ident,tet); 75 } 76 }; 77 78 btCompoundShape* btCreateCompoundFromGimpactShape(const btGImpactMeshShape* gimpactMesh, btScalar depth) 79 { 80 btCompoundShape* colShape = new btCompoundShape(); 81 82 btTransform tr; 83 tr.setIdentity(); 84 85 MyInternalTriangleIndexCallback cb(colShape,gimpactMesh, depth); 86 btVector3 aabbMin,aabbMax; 87 gimpactMesh->getAabb(tr,aabbMin,aabbMax); 88 gimpactMesh->getMeshInterface()->InternalProcessAllTriangles(&cb,aabbMin,aabbMax); 89 90 return colShape; 91 } 92 93 #endif //BT_COMPOUND_FROM_GIMPACT