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
26 MyContactResultCallback() :m_connected(false),m_margin(0.05)
\r
29 virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
\r
31 if (cp.getDistance()<=m_margin)
\r
37 MyContactResultCallback result;
\r
39 btCollisionObject obA;
\r
40 obA.setWorldTransform(compound->getChildTransform(i));
\r
41 obA.setCollisionShape(compound->getChildShape(i));
\r
42 btCollisionObject obB;
\r
43 obB.setWorldTransform(compound->getChildTransform(j));
\r
44 obB.setCollisionShape(compound->getChildShape(j));
\r
45 world->contactPairTest(&obA,&obB,result);
\r
46 if (result.m_connected)
\r
49 tmp.m_childIndex0 = i;
\r
50 tmp.m_childIndex1 = j;
\r
51 tmp.m_childShape0 = compound->getChildShape(i);
\r
52 tmp.m_childShape1 = compound->getChildShape(j);
\r
53 tmp.m_strength = 1.f;//??
\r
54 m_connections.push_back(tmp);
\r
63 btCompoundShape* btFractureBody::shiftTransformDistributeMass(btCompoundShape* boxCompound,btScalar mass,btTransform& shift)
\r
66 btVector3 principalInertia;
\r
68 btScalar* masses = new btScalar[boxCompound->getNumChildShapes()];
\r
69 for (int j=0;j<boxCompound->getNumChildShapes();j++)
\r
71 //evenly distribute mass
\r
72 masses[j]=mass/boxCompound->getNumChildShapes();
\r
75 return shiftTransform(boxCompound,masses,shift,principalInertia);
\r
80 btCompoundShape* btFractureBody::shiftTransform(btCompoundShape* boxCompound,btScalar* masses,btTransform& shift, btVector3& principalInertia)
\r
82 btTransform principal;
\r
84 boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia);
\r
87 ///create a new compound with world transform/center of mass properly aligned with the principal axis
\r
89 ///non-recursive compound shapes perform better
\r
91 #ifdef USE_RECURSIVE_COMPOUND
\r
93 btCompoundShape* newCompound = new btCompoundShape();
\r
94 newCompound->addChildShape(principal.inverse(),boxCompound);
\r
95 newBoxCompound = newCompound;
\r
96 //m_collisionShapes.push_back(newCompound);
\r
98 //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
\r
99 //btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia);
\r
102 #ifdef CHANGE_COMPOUND_INPLACE
\r
103 newBoxCompound = boxCompound;
\r
104 for (int i=0;i<boxCompound->getNumChildShapes();i++)
\r
106 btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
\r
107 ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
\r
108 boxCompound->updateChildTransform(i,newChildTransform);
\r
110 bool isDynamic = (mass != 0.f);
\r
111 btVector3 localInertia(0,0,0);
\r
113 boxCompound->calculateLocalInertia(mass,localInertia);
\r
116 ///creation is faster using a new compound to store the shifted children
\r
117 btCompoundShape* newBoxCompound = new btCompoundShape();
\r
118 for (int i=0;i<boxCompound->getNumChildShapes();i++)
\r
120 btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
\r
121 ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
\r
122 newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i));
\r
129 #endif//USE_RECURSIVE_COMPOUND
\r
132 return newBoxCompound;
\r