2 #include "btFractureBody.h"
\r
3 #include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
\r
4 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
\r
5 #include "BulletDynamics/Dynamics/btDynamicsWorld.h"
\r
9 void btFractureBody::recomputeConnectivity(btCollisionWorld* world)
\r
11 m_connections.clear();
\r
12 //@todo use the AABB tree to avoid N^2 checks
\r
14 if (getCollisionShape()->isCompound())
\r
16 btCompoundShape* compound = (btCompoundShape*)getCollisionShape();
\r
17 for (int i=0;i<compound->getNumChildShapes();i++)
\r
19 for (int j=i+1;j<compound->getNumChildShapes();j++)
\r
22 struct MyContactResultCallback : public btCollisionWorld::ContactResultCallback
\r
25 MyContactResultCallback() :m_connected(false)
\r
28 virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
\r
30 if (cp.getDistance()<=0)
\r
36 MyContactResultCallback result;
\r
38 btCollisionObject obA;
\r
39 obA.setWorldTransform(compound->getChildTransform(i));
\r
40 obA.setCollisionShape(compound->getChildShape(i));
\r
41 btCollisionObject obB;
\r
42 obB.setWorldTransform(compound->getChildTransform(j));
\r
43 obB.setCollisionShape(compound->getChildShape(j));
\r
44 world->contactPairTest(&obA,&obB,result);
\r
45 if (result.m_connected)
\r
48 tmp.m_childIndex0 = i;
\r
49 tmp.m_childIndex1 = j;
\r
50 tmp.m_childShape0 = compound->getChildShape(i);
\r
51 tmp.m_childShape1 = compound->getChildShape(j);
\r
52 tmp.m_strength = 1.f;//??
\r
53 m_connections.push_back(tmp);
\r
62 btCompoundShape* btFractureBody::shiftTransformDistributeMass(btCompoundShape* boxCompound,btScalar mass,btTransform& shift)
\r
65 btVector3 principalInertia;
\r
67 btScalar* masses = new btScalar[boxCompound->getNumChildShapes()];
\r
68 for (int j=0;j<boxCompound->getNumChildShapes();j++)
\r
70 //evenly distribute mass
\r
71 masses[j]=mass/boxCompound->getNumChildShapes();
\r
74 return shiftTransform(boxCompound,masses,shift,principalInertia);
\r
79 btCompoundShape* btFractureBody::shiftTransform(btCompoundShape* boxCompound,btScalar* masses,btTransform& shift, btVector3& principalInertia)
\r
81 btTransform principal;
\r
83 boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia);
\r
86 ///create a new compound with world transform/center of mass properly aligned with the principal axis
\r
88 ///non-recursive compound shapes perform better
\r
90 #ifdef USE_RECURSIVE_COMPOUND
\r
92 btCompoundShape* newCompound = new btCompoundShape();
\r
93 newCompound->addChildShape(principal.inverse(),boxCompound);
\r
94 newBoxCompound = newCompound;
\r
95 //m_collisionShapes.push_back(newCompound);
\r
97 //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
\r
98 //btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia);
\r
101 #ifdef CHANGE_COMPOUND_INPLACE
\r
102 newBoxCompound = boxCompound;
\r
103 for (int i=0;i<boxCompound->getNumChildShapes();i++)
\r
105 btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
\r
106 ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
\r
107 boxCompound->updateChildTransform(i,newChildTransform);
\r
109 bool isDynamic = (mass != 0.f);
\r
110 btVector3 localInertia(0,0,0);
\r
112 boxCompound->calculateLocalInertia(mass,localInertia);
\r
115 ///creation is faster using a new compound to store the shifted children
\r
116 btCompoundShape* newBoxCompound = new btCompoundShape();
\r
117 for (int i=0;i<boxCompound->getNumChildShapes();i++)
\r
119 btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
\r
120 ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
\r
121 newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i));
\r
128 #endif//USE_RECURSIVE_COMPOUND
\r
131 return newBoxCompound;
\r