diff options
Diffstat (limited to 'thirdparty/bullet/BulletCollision/Gimpact/btCompoundFromGimpact.h')
-rw-r--r-- | thirdparty/bullet/BulletCollision/Gimpact/btCompoundFromGimpact.h | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/thirdparty/bullet/BulletCollision/Gimpact/btCompoundFromGimpact.h b/thirdparty/bullet/BulletCollision/Gimpact/btCompoundFromGimpact.h new file mode 100644 index 0000000000..19f7ecddd0 --- /dev/null +++ b/thirdparty/bullet/BulletCollision/Gimpact/btCompoundFromGimpact.h @@ -0,0 +1,109 @@ +#ifndef BT_COMPOUND_FROM_GIMPACT +#define BT_COMPOUND_FROM_GIMPACT + +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "btGImpactShape.h" +#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" + +ATTRIBUTE_ALIGNED16(class) btCompoundFromGimpactShape : public btCompoundShape +{ +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + virtual ~btCompoundFromGimpactShape() + { + /*delete all the btBU_Simplex1to4 ChildShapes*/ + for (int i = 0; i < m_children.size(); i++) + { + delete m_children[i].m_childShape; + } + } + +}; + +struct MyCallback : public btTriangleRaycastCallback + { + int m_ignorePart; + int m_ignoreTriangleIndex; + + + MyCallback(const btVector3& from, const btVector3& to, int ignorePart, int ignoreTriangleIndex) + :btTriangleRaycastCallback(from,to), + m_ignorePart(ignorePart), + m_ignoreTriangleIndex(ignoreTriangleIndex) + { + + } + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex) + { + if (partId!=m_ignorePart || triangleIndex!=m_ignoreTriangleIndex) + { + if (hitFraction < m_hitFraction) + return hitFraction; + } + + return m_hitFraction; + } + }; + struct MyInternalTriangleIndexCallback :public btInternalTriangleIndexCallback + { + const btGImpactMeshShape* m_gimpactShape; + btCompoundShape* m_colShape; + btScalar m_depth; + + MyInternalTriangleIndexCallback (btCompoundShape* colShape, const btGImpactMeshShape* meshShape, btScalar depth) + :m_colShape(colShape), + m_gimpactShape(meshShape), + m_depth(depth) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + btVector3 scale = m_gimpactShape->getLocalScaling(); + btVector3 v0=triangle[0]*scale; + btVector3 v1=triangle[1]*scale; + btVector3 v2=triangle[2]*scale; + + btVector3 centroid = (v0+v1+v2)/3; + btVector3 normal = (v1-v0).cross(v2-v0); + normal.normalize(); + btVector3 rayFrom = centroid; + btVector3 rayTo = centroid-normal*m_depth; + + MyCallback cb(rayFrom,rayTo,partId,triangleIndex); + + m_gimpactShape->processAllTrianglesRay(&cb,rayFrom, rayTo); + if (cb.m_hitFraction<1) + { + rayTo.setInterpolate3(cb.m_from,cb.m_to,cb.m_hitFraction); + //rayTo = cb.m_from; + //rayTo = rayTo.lerp(cb.m_to,cb.m_hitFraction); + //gDebugDraw.drawLine(tr(centroid),tr(centroid+normal),btVector3(1,0,0)); + } + + + + btBU_Simplex1to4* tet = new btBU_Simplex1to4(v0,v1,v2,rayTo); + btTransform ident; + ident.setIdentity(); + m_colShape->addChildShape(ident,tet); + } + }; + +btCompoundShape* btCreateCompoundFromGimpactShape(const btGImpactMeshShape* gimpactMesh, btScalar depth) +{ + btCompoundShape* colShape = new btCompoundFromGimpactShape(); + + btTransform tr; + tr.setIdentity(); + + MyInternalTriangleIndexCallback cb(colShape,gimpactMesh, depth); + btVector3 aabbMin,aabbMax; + gimpactMesh->getAabb(tr,aabbMin,aabbMax); + gimpactMesh->getMeshInterface()->InternalProcessAllTriangles(&cb,aabbMin,aabbMax); + + return colShape; +} + +#endif //BT_COMPOUND_FROM_GIMPACT |