Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
63f2ad90eThis file is pinned to the selected release. Download the original to open it in your design tool.
#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;
}