110 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #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
 |