bullet3/examples/FractureDemo/btFractureBody.cpp
erwincoumans ab8f16961e Code-style consistency improvement:
Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files.
make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type.
This commit contains no other changes aside from adding and applying clang-format-all.sh
2018-09-23 14:17:31 -07:00

123 lines
4.1 KiB
C++

#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;
}