123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #include "btFractureBody.h"
- #include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
- #include "BulletCollision/CollisionShapes/btCompoundShape.h"
- #include "BulletDynamics/Dynamics/btDynamicsWorld.h"
- void btFractureBody::recomputeConnectivity(btCollisionWorld* world)
- {
- m_connections.clear();
- //@todo use the AABB tree to avoid N^2 checks
- if (getCollisionShape()->isCompound())
- {
- btCompoundShape* compound = (btCompoundShape*)getCollisionShape();
- for (int i=0;i<compound->getNumChildShapes();i++)
- {
- for (int j=i+1;j<compound->getNumChildShapes();j++)
- {
- struct MyContactResultCallback : public btCollisionWorld::ContactResultCallback
- {
- bool m_connected;
- btScalar m_margin;
- MyContactResultCallback() :m_connected(false),m_margin(0.05)
- {
- }
- virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
- {
- if (cp.getDistance()<=m_margin)
- m_connected = true;
- return 1.f;
- }
- };
- MyContactResultCallback result;
- btCollisionObject obA;
- obA.setWorldTransform(compound->getChildTransform(i));
- obA.setCollisionShape(compound->getChildShape(i));
- btCollisionObject obB;
- obB.setWorldTransform(compound->getChildTransform(j));
- obB.setCollisionShape(compound->getChildShape(j));
- world->contactPairTest(&obA,&obB,result);
- if (result.m_connected)
- {
- btConnection tmp;
- tmp.m_childIndex0 = i;
- tmp.m_childIndex1 = j;
- tmp.m_childShape0 = compound->getChildShape(i);
- tmp.m_childShape1 = compound->getChildShape(j);
- tmp.m_strength = 1.f;//??
- m_connections.push_back(tmp);
- }
- }
- }
- }
-
- }
- btCompoundShape* btFractureBody::shiftTransformDistributeMass(btCompoundShape* boxCompound,btScalar mass,btTransform& shift)
- {
- btVector3 principalInertia;
- btScalar* masses = new btScalar[boxCompound->getNumChildShapes()];
- for (int j=0;j<boxCompound->getNumChildShapes();j++)
- {
- //evenly distribute mass
- masses[j]=mass/boxCompound->getNumChildShapes();
- }
- return shiftTransform(boxCompound,masses,shift,principalInertia);
- }
- btCompoundShape* btFractureBody::shiftTransform(btCompoundShape* boxCompound,btScalar* masses,btTransform& shift, btVector3& principalInertia)
- {
- btTransform principal;
- boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia);
- ///create a new compound with world transform/center of mass properly aligned with the principal axis
- ///non-recursive compound shapes perform better
-
- #ifdef USE_RECURSIVE_COMPOUND
- btCompoundShape* newCompound = new btCompoundShape();
- newCompound->addChildShape(principal.inverse(),boxCompound);
- newBoxCompound = newCompound;
- //m_collisionShapes.push_back(newCompound);
- //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
- //btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia);
- #else
- #ifdef CHANGE_COMPOUND_INPLACE
- newBoxCompound = boxCompound;
- for (int i=0;i<boxCompound->getNumChildShapes();i++)
- {
- btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
- ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
- boxCompound->updateChildTransform(i,newChildTransform);
- }
- bool isDynamic = (mass != 0.f);
- btVector3 localInertia(0,0,0);
- if (isDynamic)
- boxCompound->calculateLocalInertia(mass,localInertia);
-
- #else
- ///creation is faster using a new compound to store the shifted children
- btCompoundShape* newBoxCompound = new btCompoundShape();
- for (int i=0;i<boxCompound->getNumChildShapes();i++)
- {
- btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
- ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
- newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i));
- }
- #endif
- #endif//USE_RECURSIVE_COMPOUND
- shift = principal;
- return newBoxCompound;
- }
|