diff --git a/src/BulletCollision/Gimpact/btCompoundFromGimpact.h b/src/BulletCollision/Gimpact/btCompoundFromGimpact.h new file mode 100644 index 000000000..9e66285c1 --- /dev/null +++ b/src/BulletCollision/Gimpact/btCompoundFromGimpact.h @@ -0,0 +1,93 @@ +#ifndef BT_COMPOUND_FROM_GIMPACT +#define BT_COMPOUND_FROM_GIMPACT + +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "btGImpactShape.h" +#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" + +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 btCompoundShape(); + + 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 \ No newline at end of file diff --git a/src/BulletCollision/Gimpact/btGImpactShape.cpp b/src/BulletCollision/Gimpact/btGImpactShape.cpp index cceace55e..ac8efdf38 100644 --- a/src/BulletCollision/Gimpact/btGImpactShape.cpp +++ b/src/BulletCollision/Gimpact/btGImpactShape.cpp @@ -25,6 +25,7 @@ subject to the following restrictions: #define CALC_EXACT_INERTIA 1 + void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const { lockChildShapes(); @@ -144,6 +145,31 @@ void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayT { } +void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const +{ + lockChildShapes(); + + btAlignedObjectArray collided; + btVector3 rayDir(rayTo - rayFrom); + rayDir.normalize(); + m_box_set.rayQuery(rayDir, rayFrom, collided); + + if(collided.size()==0) + { + unlockChildShapes(); + return; + } + + int part = (int)getPart(); + btPrimitiveTriangle triangle; + int i = collided.size(); + while(i--) + { + getPrimitiveTriangle(collided[i],triangle); + callback->processTriangle(triangle.m_vertices,part,collided[i]); + } + unlockChildShapes(); +} void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const { @@ -182,6 +208,15 @@ void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const } } +void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const +{ + int i = m_mesh_parts.size(); + while(i--) + { + m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo); + } +} + ///fills the dataBuffer and returns the struct name (and 0 on failure) const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const diff --git a/src/BulletCollision/Gimpact/btGImpactShape.h b/src/BulletCollision/Gimpact/btGImpactShape.h index 775d08377..3d1f48d47 100644 --- a/src/BulletCollision/Gimpact/btGImpactShape.h +++ b/src/BulletCollision/Gimpact/btGImpactShape.h @@ -51,6 +51,7 @@ enum eGIMPACT_SHAPE_TYPE }; + //! Helper class for tetrahedrons class btTetrahedronShapeEx:public btBU_Simplex1to4 { @@ -288,6 +289,15 @@ public: (void) callback; (void) aabbMin; (void) aabbMax; } + //! Function for retrieve triangles. + /*! + It gives the triangles in local space + */ + virtual void processAllTrianglesRay(btTriangleCallback* /*callback*/,const btVector3& /*rayFrom*/, const btVector3& /*rayTo*/) const + { + + } + //!@} }; @@ -639,7 +649,7 @@ public: { if(indicestype == PHY_SHORT) { - unsigned short * s_indices = (unsigned short *)(indexbase + face_index*indexstride); + unsigned short* s_indices = (unsigned short *)(indexbase + face_index * indexstride); i0 = s_indices[0]; i1 = s_indices[1]; i2 = s_indices[2]; @@ -885,6 +895,7 @@ public: } virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + virtual void processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const; }; @@ -1141,6 +1152,8 @@ public: */ virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + virtual void processAllTrianglesRay (btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure)