disable constraints when they exceed a breaking threshold, control it with new methods in btTypedConstraint: get/setBreakingImpulseThreshold and get/setEnabled
Disabled constraints are not removed from the world and they use negligible CPU cycles
This commit is contained in:
@@ -13,7 +13,6 @@ subject to the following restrictions:
|
|||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define TEST_SERIALIZATION 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -29,12 +28,6 @@ subject to the following restrictions:
|
|||||||
#include "GL_ShapeDrawer.h"
|
#include "GL_ShapeDrawer.h"
|
||||||
#include "GlutStuff.h"
|
#include "GlutStuff.h"
|
||||||
|
|
||||||
#ifdef TEST_SERIALIZATION
|
|
||||||
#include "LinearMath/btSerializer.h"
|
|
||||||
#include "btBulletFile.h"
|
|
||||||
#include "btBulletWorldImporter.h"
|
|
||||||
#endif //TEST_SERIALIZATION
|
|
||||||
|
|
||||||
|
|
||||||
const int numObjects = 3;
|
const int numObjects = 3;
|
||||||
|
|
||||||
@@ -121,6 +114,30 @@ void ConstraintDemo::initPhysics()
|
|||||||
trans.setOrigin(btVector3(0,20,0));
|
trans.setOrigin(btVector3(0,20,0));
|
||||||
|
|
||||||
float mass = 1.f;
|
float mass = 1.f;
|
||||||
|
|
||||||
|
|
||||||
|
#if ENABLE_ALL_DEMOS
|
||||||
|
//point to point constraint with a breaking threshold
|
||||||
|
{
|
||||||
|
trans.setIdentity();
|
||||||
|
trans.setOrigin(btVector3(1,30,-5));
|
||||||
|
localCreateRigidBody( mass,trans,shape);
|
||||||
|
trans.setOrigin(btVector3(0,0,-5));
|
||||||
|
|
||||||
|
btRigidBody* body0 = localCreateRigidBody( mass,trans,shape);
|
||||||
|
trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0));
|
||||||
|
mass = 1.f;
|
||||||
|
btRigidBody* body1 = 0;//localCreateRigidBody( mass,trans,shape);
|
||||||
|
btVector3 pivotInA(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,0);
|
||||||
|
btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA);
|
||||||
|
m_dynamicsWorld->addConstraint(p2p);
|
||||||
|
p2p ->setBreakingImpulseThreshold(10.2);
|
||||||
|
p2p->setDbgDrawSize(btScalar(5.f));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if ENABLE_ALL_DEMOS
|
#if ENABLE_ALL_DEMOS
|
||||||
//point to point constraint (ball socket)
|
//point to point constraint (ball socket)
|
||||||
{
|
{
|
||||||
@@ -141,7 +158,7 @@ void ConstraintDemo::initPhysics()
|
|||||||
(body1->getCenterOfMassTransform().getBasis().inverse()*(body1->getCenterOfMassTransform().getBasis() * axisInA)) :
|
(body1->getCenterOfMassTransform().getBasis().inverse()*(body1->getCenterOfMassTransform().getBasis() * axisInA)) :
|
||||||
body0->getCenterOfMassTransform().getBasis() * axisInA;
|
body0->getCenterOfMassTransform().getBasis() * axisInA;
|
||||||
|
|
||||||
//#define P2P
|
#define P2P
|
||||||
#ifdef P2P
|
#ifdef P2P
|
||||||
btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA);
|
btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA);
|
||||||
//btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,*body1,pivotInA,pivotInB);
|
//btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,*body1,pivotInA,pivotInB);
|
||||||
@@ -518,27 +535,6 @@ void ConstraintDemo::initPhysics()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef TEST_SERIALIZATION
|
|
||||||
|
|
||||||
int maxSerializeBufferSize = 1024*1024*5;
|
|
||||||
|
|
||||||
btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize);
|
|
||||||
m_dynamicsWorld->serialize(serializer);
|
|
||||||
|
|
||||||
FILE* f2 = fopen("testFile.bullet","wb");
|
|
||||||
fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2);
|
|
||||||
fclose(f2);
|
|
||||||
|
|
||||||
|
|
||||||
exitPhysics();
|
|
||||||
|
|
||||||
setupEmptyDynamicsWorld();
|
|
||||||
|
|
||||||
btBulletWorldImporter* fileLoader = new btBulletWorldImporter(m_dynamicsWorld);
|
|
||||||
|
|
||||||
fileLoader->loadFile("testFile.bullet");
|
|
||||||
|
|
||||||
#endif //TEST_SERIALIZATION
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1345,6 +1345,11 @@ void DemoApplication::clientResetScene()
|
|||||||
|
|
||||||
if (m_dynamicsWorld)
|
if (m_dynamicsWorld)
|
||||||
{
|
{
|
||||||
|
int numConstraints = m_dynamicsWorld->getNumConstraints();
|
||||||
|
for (i=0;i<numConstraints;i++)
|
||||||
|
{
|
||||||
|
m_dynamicsWorld->getConstraint(0)->setEnabled(true);
|
||||||
|
}
|
||||||
numObjects = m_dynamicsWorld->getNumCollisionObjects();
|
numObjects = m_dynamicsWorld->getNumCollisionObjects();
|
||||||
|
|
||||||
///create a copy of the array, not a reference!
|
///create a copy of the array, not a reference!
|
||||||
|
|||||||
@@ -805,7 +805,14 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
|||||||
for (i=0;i<numConstraints;i++)
|
for (i=0;i<numConstraints;i++)
|
||||||
{
|
{
|
||||||
btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
|
btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
|
||||||
constraints[i]->getInfo1(&info1);
|
if (constraints[i]->isEnabled())
|
||||||
|
{
|
||||||
|
constraints[i]->getInfo1(&info1);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
info1.m_numConstraintRows = 0;
|
||||||
|
info1.nub = 0;
|
||||||
|
}
|
||||||
totalNumRows += info1.m_numConstraintRows;
|
totalNumRows += info1.m_numConstraintRows;
|
||||||
}
|
}
|
||||||
m_tmpSolverNonContactConstraintPool.resize(totalNumRows);
|
m_tmpSolverNonContactConstraintPool.resize(totalNumRows);
|
||||||
@@ -826,7 +833,6 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
|||||||
btTypedConstraint* constraint = constraints[i];
|
btTypedConstraint* constraint = constraints[i];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
btRigidBody& rbA = constraint->getRigidBodyA();
|
btRigidBody& rbA = constraint->getRigidBodyA();
|
||||||
btRigidBody& rbB = constraint->getRigidBodyB();
|
btRigidBody& rbB = constraint->getRigidBodyB();
|
||||||
|
|
||||||
@@ -835,8 +841,8 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
|||||||
for ( j=0;j<info1.m_numConstraintRows;j++)
|
for ( j=0;j<info1.m_numConstraintRows;j++)
|
||||||
{
|
{
|
||||||
memset(¤tConstraintRow[j],0,sizeof(btSolverConstraint));
|
memset(¤tConstraintRow[j],0,sizeof(btSolverConstraint));
|
||||||
currentConstraintRow[j].m_lowerLimit = -FLT_MAX;
|
currentConstraintRow[j].m_lowerLimit = -SIMD_INFINITY;
|
||||||
currentConstraintRow[j].m_upperLimit = FLT_MAX;
|
currentConstraintRow[j].m_upperLimit = SIMD_INFINITY;
|
||||||
currentConstraintRow[j].m_appliedImpulse = 0.f;
|
currentConstraintRow[j].m_appliedImpulse = 0.f;
|
||||||
currentConstraintRow[j].m_appliedPushImpulse = 0.f;
|
currentConstraintRow[j].m_appliedPushImpulse = 0.f;
|
||||||
currentConstraintRow[j].m_solverBodyA = &rbA;
|
currentConstraintRow[j].m_solverBodyA = &rbA;
|
||||||
@@ -869,6 +875,18 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
|||||||
info2.m_numIterations = infoGlobal.m_numIterations;
|
info2.m_numIterations = infoGlobal.m_numIterations;
|
||||||
constraints[i]->getInfo2(&info2);
|
constraints[i]->getInfo2(&info2);
|
||||||
|
|
||||||
|
if (currentConstraintRow->m_upperLimit>constraints[i]->getBreakingImpulseThreshold())
|
||||||
|
{
|
||||||
|
currentConstraintRow->m_upperLimit = constraints[i]->getBreakingImpulseThreshold();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentConstraintRow->m_lowerLimit<-constraints[i]->getBreakingImpulseThreshold())
|
||||||
|
{
|
||||||
|
currentConstraintRow->m_lowerLimit = -constraints[i]->getBreakingImpulseThreshold();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///finalize the constraint setup
|
///finalize the constraint setup
|
||||||
for ( j=0;j<info1.m_numConstraintRows;j++)
|
for ( j=0;j<info1.m_numConstraintRows;j++)
|
||||||
{
|
{
|
||||||
@@ -1153,9 +1171,11 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCo
|
|||||||
{
|
{
|
||||||
const btSolverConstraint& solverConstr = m_tmpSolverNonContactConstraintPool[j];
|
const btSolverConstraint& solverConstr = m_tmpSolverNonContactConstraintPool[j];
|
||||||
btTypedConstraint* constr = (btTypedConstraint*)solverConstr.m_originalContactPoint;
|
btTypedConstraint* constr = (btTypedConstraint*)solverConstr.m_originalContactPoint;
|
||||||
btScalar sum = constr->internalGetAppliedImpulse();
|
constr->internalSetAppliedImpulse(solverConstr.m_appliedImpulse);
|
||||||
sum += solverConstr.m_appliedImpulse;
|
if (solverConstr.m_appliedImpulse>constr->getBreakingImpulseThreshold())
|
||||||
constr->internalSetAppliedImpulse(sum);
|
{
|
||||||
|
constr->setEnabled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ m_needsFeedback(false),
|
|||||||
m_rbA(rbA),
|
m_rbA(rbA),
|
||||||
m_rbB(getFixedBody()),
|
m_rbB(getFixedBody()),
|
||||||
m_appliedImpulse(btScalar(0.)),
|
m_appliedImpulse(btScalar(0.)),
|
||||||
m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
|
m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE),
|
||||||
|
m_breakingImpulseThreshold(SIMD_INFINITY),
|
||||||
|
m_isEnabled(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +44,9 @@ m_needsFeedback(false),
|
|||||||
m_rbA(rbA),
|
m_rbA(rbA),
|
||||||
m_rbB(rbB),
|
m_rbB(rbB),
|
||||||
m_appliedImpulse(btScalar(0.)),
|
m_appliedImpulse(btScalar(0.)),
|
||||||
m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
|
m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE),
|
||||||
|
m_breakingImpulseThreshold(SIMD_INFINITY),
|
||||||
|
m_isEnabled(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ class btTypedConstraint : public btTypedObject
|
|||||||
void* m_userConstraintPtr;
|
void* m_userConstraintPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
btScalar m_breakingImpulseThreshold;
|
||||||
|
bool m_isEnabled;
|
||||||
|
|
||||||
|
|
||||||
bool m_needsFeedback;
|
bool m_needsFeedback;
|
||||||
|
|
||||||
btTypedConstraint& operator=(btTypedConstraint& other)
|
btTypedConstraint& operator=(btTypedConstraint& other)
|
||||||
@@ -155,6 +159,28 @@ public:
|
|||||||
return m_appliedImpulse;
|
return m_appliedImpulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
btScalar getBreakingImpulseThreshold() const
|
||||||
|
{
|
||||||
|
return m_breakingImpulseThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBreakingImpulseThreshold(btScalar threshold)
|
||||||
|
{
|
||||||
|
m_breakingImpulseThreshold = threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEnabled() const
|
||||||
|
{
|
||||||
|
return m_isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
m_isEnabled=enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///internal method used by the constraint solver, don't use them directly
|
///internal method used by the constraint solver, don't use them directly
|
||||||
virtual void solveConstraintObsolete(btRigidBody& /*bodyA*/,btRigidBody& /*bodyB*/,btScalar /*timeStep*/) {};
|
virtual void solveConstraintObsolete(btRigidBody& /*bodyA*/,btRigidBody& /*bodyB*/,btScalar /*timeStep*/) {};
|
||||||
|
|
||||||
|
|||||||
@@ -1165,11 +1165,8 @@ btScalar btParallelConstraintSolver::solveGroup(btCollisionObject** bodies1,int
|
|||||||
if (info1.m_numConstraintRows)
|
if (info1.m_numConstraintRows)
|
||||||
{
|
{
|
||||||
btAssert(currentRow<totalNumRows);
|
btAssert(currentRow<totalNumRows);
|
||||||
|
|
||||||
btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
|
|
||||||
btTypedConstraint* constraint = constraints[i];
|
btTypedConstraint* constraint = constraints[i];
|
||||||
|
btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
|
||||||
|
|
||||||
|
|
||||||
btRigidBody& rbA = constraint->getRigidBodyA();
|
btRigidBody& rbA = constraint->getRigidBodyA();
|
||||||
btRigidBody& rbB = constraint->getRigidBodyB();
|
btRigidBody& rbB = constraint->getRigidBodyB();
|
||||||
@@ -1212,6 +1209,7 @@ btScalar btParallelConstraintSolver::solveGroup(btCollisionObject** bodies1,int
|
|||||||
info2.m_numIterations = infoGlobal.m_numIterations;
|
info2.m_numIterations = infoGlobal.m_numIterations;
|
||||||
constraints[i]->getInfo2(&info2);
|
constraints[i]->getInfo2(&info2);
|
||||||
|
|
||||||
|
|
||||||
int idA = constraint->getRigidBodyA().getCompanionId();
|
int idA = constraint->getRigidBodyA().getCompanionId();
|
||||||
int idB = constraint->getRigidBodyB().getCompanionId();
|
int idB = constraint->getRigidBodyB().getCompanionId();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user