mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-15 06:00:12 +00:00
69e5454d18
Use statically linked freeglut, instead of dynamic glut for the obsolete Bullet 2.x demos Add the 'reset' method to b3GpuDynamicsWorld, and use it in the BasicGpuDemo (pretty slow in debug mode, use release mode) Don't crash in btCollisionWorld, if there is no collision dispatcher
140 lines
4.1 KiB
C++
140 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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|