Constraints can override their own number of solver iterations (either more or less than the default) or leave it default (-1)
Bump version to 2.80
This commit is contained in:
@@ -69,6 +69,87 @@ btSoftBodySolver* fSoftBodySolver=0;
|
|||||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void SerializeDemo::keyboardCallback(unsigned char key, int x, int y)
|
||||||
|
{
|
||||||
|
btAlignedObjectArray<btRigidBody*> bodies;
|
||||||
|
if (key == 'g')
|
||||||
|
{
|
||||||
|
int numManifolds = getDynamicsWorld()->getDispatcher()->getNumManifolds();
|
||||||
|
|
||||||
|
for (int i=0;i<numManifolds;i++)
|
||||||
|
{
|
||||||
|
btPersistentManifold* manifold = getDynamicsWorld()->getDispatcher()->getManifoldByIndexInternal(i);
|
||||||
|
if (!manifold->getNumContacts())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
btScalar minDist = 1e30f;
|
||||||
|
int minIndex = -1;
|
||||||
|
for (int v=0;v<manifold->getNumContacts();v++)
|
||||||
|
{
|
||||||
|
if (minDist >manifold->getContactPoint(v).getDistance())
|
||||||
|
{
|
||||||
|
minDist = manifold->getContactPoint(v).getDistance();
|
||||||
|
minIndex = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (minDist>0.)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0();
|
||||||
|
btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1();
|
||||||
|
int tag0 = (colObj0)->getIslandTag();
|
||||||
|
int tag1 = (colObj1)->getIslandTag();
|
||||||
|
btRigidBody* body0 = btRigidBody::upcast(colObj0);
|
||||||
|
btRigidBody* body1 = btRigidBody::upcast(colObj1);
|
||||||
|
if (bodies.findLinearSearch(body0)==bodies.size())
|
||||||
|
bodies.push_back(body0);
|
||||||
|
if (bodies.findLinearSearch(body1)==bodies.size())
|
||||||
|
bodies.push_back(body1);
|
||||||
|
|
||||||
|
if (body0 && body1)
|
||||||
|
{
|
||||||
|
if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject())
|
||||||
|
{
|
||||||
|
if (body0->checkCollideWithOverride(body1))
|
||||||
|
{
|
||||||
|
{
|
||||||
|
btTransform trA,trB;
|
||||||
|
trA.setIdentity();
|
||||||
|
trB.setIdentity();
|
||||||
|
btVector3 contactPosWorld = manifold->getContactPoint(minIndex).m_positionWorldOnA;
|
||||||
|
btTransform globalFrame;
|
||||||
|
globalFrame.setIdentity();
|
||||||
|
globalFrame.setOrigin(contactPosWorld);
|
||||||
|
|
||||||
|
trA = body0->getWorldTransform().inverse()*globalFrame;
|
||||||
|
trB = body1->getWorldTransform().inverse()*globalFrame;
|
||||||
|
|
||||||
|
btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body0,*body1,trA,trB,true);
|
||||||
|
dof6->setOverrideNumSolverIterations(100);
|
||||||
|
|
||||||
|
dof6->setBreakingImpulseThreshold(35);
|
||||||
|
|
||||||
|
for (int i=0;i<6;i++)
|
||||||
|
dof6->setLimit(i,0,0);
|
||||||
|
getDynamicsWorld()->addConstraint(dof6,true);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0;i<bodies.size();i++)
|
||||||
|
{
|
||||||
|
getDynamicsWorld()->removeRigidBody(bodies[i]);
|
||||||
|
getDynamicsWorld()->addRigidBody(bodies[i]);
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
PlatformDemoApplication::keyboardCallback(key,x,y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SerializeDemo::clientMoveAndDisplay()
|
void SerializeDemo::clientMoveAndDisplay()
|
||||||
@@ -81,7 +162,6 @@ void SerializeDemo::clientMoveAndDisplay()
|
|||||||
///step the simulation
|
///step the simulation
|
||||||
if (m_dynamicsWorld)
|
if (m_dynamicsWorld)
|
||||||
{
|
{
|
||||||
|
|
||||||
m_dynamicsWorld->stepSimulation(ms / 1000000.f);
|
m_dynamicsWorld->stepSimulation(ms / 1000000.f);
|
||||||
|
|
||||||
#ifdef DESERIALIZE_SOFT_BODIES
|
#ifdef DESERIALIZE_SOFT_BODIES
|
||||||
@@ -242,9 +322,13 @@ void SerializeDemo::setupEmptyDynamicsWorld()
|
|||||||
btSoftRigidDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver,
|
btSoftRigidDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver,
|
||||||
m_collisionConfiguration, fSoftBodySolver);
|
m_collisionConfiguration, fSoftBodySolver);
|
||||||
m_dynamicsWorld = world;
|
m_dynamicsWorld = world;
|
||||||
|
|
||||||
//world->setDrawFlags(world->getDrawFlags()^fDrawFlags::Clusters);
|
//world->setDrawFlags(world->getDrawFlags()^fDrawFlags::Clusters);
|
||||||
#else
|
#else
|
||||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
|
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
|
||||||
|
//m_dynamicsWorld ->getSolverInfo().m_solverMode|=SOLVER_RANDMIZE_ORDER;
|
||||||
|
//m_dynamicsWorld->getDispatchInfo().m_enableSatConvex = true;
|
||||||
|
//m_dynamicsWorld->getSolverInfo().m_splitImpulse=true;
|
||||||
#endif //DESERIALIZE_SOFT_BODIES
|
#endif //DESERIALIZE_SOFT_BODIES
|
||||||
|
|
||||||
//btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher*)m_dynamicsWorld->getDispatcher());
|
//btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher*)m_dynamicsWorld->getDispatcher());
|
||||||
@@ -731,7 +815,7 @@ void SerializeDemo::initPhysics()
|
|||||||
|
|
||||||
body->setActivationState(ISLAND_SLEEPING);
|
body->setActivationState(ISLAND_SLEEPING);
|
||||||
|
|
||||||
m_dynamicsWorld->addRigidBody(body);
|
m_dynamicsWorld->addRigidBody(body,1,2);
|
||||||
body->setActivationState(ISLAND_SLEEPING);
|
body->setActivationState(ISLAND_SLEEPING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ class SerializeDemo : public PlatformDemoApplication
|
|||||||
|
|
||||||
void exitPhysics();
|
void exitPhysics();
|
||||||
|
|
||||||
|
virtual void keyboardCallback(unsigned char key, int x, int y);
|
||||||
|
|
||||||
virtual void clientMoveAndDisplay();
|
virtual void clientMoveAndDisplay();
|
||||||
|
|
||||||
virtual void displayCallback();
|
virtual void displayCallback();
|
||||||
|
|||||||
Binary file not shown.
@@ -145,6 +145,10 @@ namespace bParse {
|
|||||||
|
|
||||||
void dumpChunks(bDNA* dna);
|
void dumpChunks(bDNA* dna);
|
||||||
|
|
||||||
|
int getVersion() const
|
||||||
|
{
|
||||||
|
return mVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1164,6 +1164,14 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
|
|||||||
if (constraint)
|
if (constraint)
|
||||||
{
|
{
|
||||||
constraint->setDbgDrawSize(constraintData->m_dbgDrawSize);
|
constraint->setDbgDrawSize(constraintData->m_dbgDrawSize);
|
||||||
|
///those fields didn't exist and set to zero for pre-280 versions, so do a check here
|
||||||
|
if (bulletFile2->getVersion()>=280)
|
||||||
|
{
|
||||||
|
constraint->setBreakingImpulseThreshold(constraintData->m_breakingImpulseThreshold);
|
||||||
|
constraint->setEnabled(constraintData->m_isEnabled);
|
||||||
|
constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations);
|
||||||
|
}
|
||||||
|
|
||||||
if (constraintData->m_name)
|
if (constraintData->m_name)
|
||||||
{
|
{
|
||||||
char* newname = duplicateName(constraintData->m_name);
|
char* newname = duplicateName(constraintData->m_name);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ AC_PREREQ([2.54])
|
|||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
AC_INIT(
|
AC_INIT(
|
||||||
[bullet],
|
[bullet],
|
||||||
[2.79],
|
[2.80],
|
||||||
[bullet@erwincoumans.com])
|
[bullet@erwincoumans.com])
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_CONFIG_SRCDIR([configure.ac])
|
AC_CONFIG_SRCDIR([configure.ac])
|
||||||
|
|||||||
@@ -85,12 +85,13 @@ struct btTriangleInfoMap : public btInternalTriangleInfoMap
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///those fields have to be float and not btScalar for the serialization to work properly
|
||||||
struct btTriangleInfoData
|
struct btTriangleInfoData
|
||||||
{
|
{
|
||||||
int m_flags;
|
int m_flags;
|
||||||
btScalar m_edgeV0V1Angle;
|
float m_edgeV0V1Angle;
|
||||||
btScalar m_edgeV1V2Angle;
|
float m_edgeV1V2Angle;
|
||||||
btScalar m_edgeV2V0Angle;
|
float m_edgeV2V0Angle;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct btTriangleInfoMapData
|
struct btTriangleInfoMapData
|
||||||
@@ -100,11 +101,11 @@ struct btTriangleInfoMapData
|
|||||||
btTriangleInfoData *m_valueArrayPtr;
|
btTriangleInfoData *m_valueArrayPtr;
|
||||||
int *m_keyArrayPtr;
|
int *m_keyArrayPtr;
|
||||||
|
|
||||||
btScalar m_convexEpsilon;
|
float m_convexEpsilon;
|
||||||
btScalar m_planarEpsilon;
|
float m_planarEpsilon;
|
||||||
btScalar m_equalVertexThreshold;
|
float m_equalVertexThreshold;
|
||||||
btScalar m_edgeDistanceThreshold;
|
float m_edgeDistanceThreshold;
|
||||||
btScalar m_zeroAreaThreshold;
|
float m_zeroAreaThreshold;
|
||||||
|
|
||||||
int m_nextSize;
|
int m_nextSize;
|
||||||
int m_hashTableSize;
|
int m_hashTableSize;
|
||||||
|
|||||||
@@ -740,13 +740,13 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
|
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
|
||||||
{
|
{
|
||||||
BT_PROFILE("solveGroupCacheFriendlySetup");
|
BT_PROFILE("solveGroupCacheFriendlySetup");
|
||||||
(void)stackAlloc;
|
(void)stackAlloc;
|
||||||
(void)debugDrawer;
|
(void)debugDrawer;
|
||||||
|
|
||||||
|
m_maxOverrideNumSolverIterations = 0;
|
||||||
|
|
||||||
if (!(numConstraints + numManifolds))
|
if (!(numConstraints + numManifolds))
|
||||||
{
|
{
|
||||||
@@ -831,12 +831,15 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
|||||||
|
|
||||||
btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
|
btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
|
||||||
btTypedConstraint* constraint = constraints[i];
|
btTypedConstraint* constraint = constraints[i];
|
||||||
|
|
||||||
|
|
||||||
btRigidBody& rbA = constraint->getRigidBodyA();
|
btRigidBody& rbA = constraint->getRigidBodyA();
|
||||||
btRigidBody& rbB = constraint->getRigidBodyB();
|
btRigidBody& rbB = constraint->getRigidBodyB();
|
||||||
|
|
||||||
|
|
||||||
|
int overrideNumSolverIterations = constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations;
|
||||||
|
if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations)
|
||||||
|
m_maxOverrideNumSolverIterations = overrideNumSolverIterations;
|
||||||
|
|
||||||
|
|
||||||
int j;
|
int j;
|
||||||
for ( j=0;j<info1.m_numConstraintRows;j++)
|
for ( j=0;j<info1.m_numConstraintRows;j++)
|
||||||
{
|
{
|
||||||
@@ -847,6 +850,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
|||||||
currentConstraintRow[j].m_appliedPushImpulse = 0.f;
|
currentConstraintRow[j].m_appliedPushImpulse = 0.f;
|
||||||
currentConstraintRow[j].m_solverBodyA = &rbA;
|
currentConstraintRow[j].m_solverBodyA = &rbA;
|
||||||
currentConstraintRow[j].m_solverBodyB = &rbB;
|
currentConstraintRow[j].m_solverBodyB = &rbB;
|
||||||
|
currentConstraintRow[j].m_overrideNumSolverIterations = overrideNumSolverIterations;
|
||||||
}
|
}
|
||||||
|
|
||||||
rbA.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
|
rbA.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
|
||||||
@@ -1004,18 +1008,22 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
|
|||||||
m_orderNonContactConstraintPool[swapi] = tmp;
|
m_orderNonContactConstraintPool[swapi] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j=0; j<numConstraintPool; ++j) {
|
//contact/friction constraints are not solved more than
|
||||||
int tmp = m_orderTmpConstraintPool[j];
|
if (iteration< infoGlobal.m_numIterations)
|
||||||
int swapi = btRandInt2(j+1);
|
{
|
||||||
m_orderTmpConstraintPool[j] = m_orderTmpConstraintPool[swapi];
|
for (j=0; j<numConstraintPool; ++j) {
|
||||||
m_orderTmpConstraintPool[swapi] = tmp;
|
int tmp = m_orderTmpConstraintPool[j];
|
||||||
}
|
int swapi = btRandInt2(j+1);
|
||||||
|
m_orderTmpConstraintPool[j] = m_orderTmpConstraintPool[swapi];
|
||||||
|
m_orderTmpConstraintPool[swapi] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
for (j=0; j<numFrictionPool; ++j) {
|
for (j=0; j<numFrictionPool; ++j) {
|
||||||
int tmp = m_orderFrictionConstraintPool[j];
|
int tmp = m_orderFrictionConstraintPool[j];
|
||||||
int swapi = btRandInt2(j+1);
|
int swapi = btRandInt2(j+1);
|
||||||
m_orderFrictionConstraintPool[j] = m_orderFrictionConstraintPool[swapi];
|
m_orderFrictionConstraintPool[j] = m_orderFrictionConstraintPool[swapi];
|
||||||
m_orderFrictionConstraintPool[swapi] = tmp;
|
m_orderFrictionConstraintPool[swapi] = tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1026,35 +1034,40 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
|
|||||||
for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
|
for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
|
||||||
{
|
{
|
||||||
btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[m_orderNonContactConstraintPool[j]];
|
btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[m_orderNonContactConstraintPool[j]];
|
||||||
resolveSingleConstraintRowGenericSIMD(*constraint.m_solverBodyA,*constraint.m_solverBodyB,constraint);
|
if (iteration < constraint.m_overrideNumSolverIterations)
|
||||||
|
resolveSingleConstraintRowGenericSIMD(*constraint.m_solverBodyA,*constraint.m_solverBodyB,constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j=0;j<numConstraints;j++)
|
if (iteration< infoGlobal.m_numIterations)
|
||||||
{
|
{
|
||||||
constraints[j]->solveConstraintObsolete(constraints[j]->getRigidBodyA(),constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
|
for (j=0;j<numConstraints;j++)
|
||||||
}
|
|
||||||
|
|
||||||
///solve all contact constraints using SIMD, if available
|
|
||||||
int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
|
|
||||||
for (j=0;j<numPoolConstraints;j++)
|
|
||||||
{
|
|
||||||
const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
|
|
||||||
resolveSingleConstraintRowLowerLimitSIMD(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
|
|
||||||
|
|
||||||
}
|
|
||||||
///solve all friction constraints, using SIMD, if available
|
|
||||||
int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
|
|
||||||
for (j=0;j<numFrictionPoolConstraints;j++)
|
|
||||||
{
|
|
||||||
btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
|
|
||||||
btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
|
|
||||||
|
|
||||||
if (totalImpulse>btScalar(0))
|
|
||||||
{
|
{
|
||||||
solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
|
constraints[j]->solveConstraintObsolete(constraints[j]->getRigidBodyA(),constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
|
||||||
solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
|
}
|
||||||
|
|
||||||
resolveSingleConstraintRowGenericSIMD(*solveManifold.m_solverBodyA, *solveManifold.m_solverBodyB,solveManifold);
|
///solve all contact constraints using SIMD, if available
|
||||||
|
int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
|
||||||
|
for (j=0;j<numPoolConstraints;j++)
|
||||||
|
{
|
||||||
|
const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
|
||||||
|
resolveSingleConstraintRowLowerLimitSIMD(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///solve all friction constraints, using SIMD, if available
|
||||||
|
int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
|
||||||
|
for (j=0;j<numFrictionPoolConstraints;j++)
|
||||||
|
{
|
||||||
|
btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
|
||||||
|
btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
|
||||||
|
|
||||||
|
if (totalImpulse>btScalar(0))
|
||||||
|
{
|
||||||
|
solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
|
||||||
|
solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
|
||||||
|
|
||||||
|
resolveSingleConstraintRowGenericSIMD(*solveManifold.m_solverBodyA, *solveManifold.m_solverBodyB,solveManifold);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -1064,33 +1077,37 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
|
|||||||
for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
|
for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
|
||||||
{
|
{
|
||||||
btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[m_orderNonContactConstraintPool[j]];
|
btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[m_orderNonContactConstraintPool[j]];
|
||||||
resolveSingleConstraintRowGeneric(*constraint.m_solverBodyA,*constraint.m_solverBodyB,constraint);
|
if (iteration < constraint.m_overrideNumSolverIterations)
|
||||||
|
resolveSingleConstraintRowGeneric(*constraint.m_solverBodyA,*constraint.m_solverBodyB,constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j=0;j<numConstraints;j++)
|
if (iteration< infoGlobal.m_numIterations)
|
||||||
{
|
{
|
||||||
constraints[j]->solveConstraintObsolete(constraints[j]->getRigidBodyA(),constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
|
for (j=0;j<numConstraints;j++)
|
||||||
}
|
|
||||||
///solve all contact constraints
|
|
||||||
int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
|
|
||||||
for (j=0;j<numPoolConstraints;j++)
|
|
||||||
{
|
|
||||||
const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
|
|
||||||
resolveSingleConstraintRowLowerLimit(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
|
|
||||||
}
|
|
||||||
///solve all friction constraints
|
|
||||||
int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
|
|
||||||
for (j=0;j<numFrictionPoolConstraints;j++)
|
|
||||||
{
|
|
||||||
btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
|
|
||||||
btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
|
|
||||||
|
|
||||||
if (totalImpulse>btScalar(0))
|
|
||||||
{
|
{
|
||||||
solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
|
constraints[j]->solveConstraintObsolete(constraints[j]->getRigidBodyA(),constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
|
||||||
solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
|
}
|
||||||
|
///solve all contact constraints
|
||||||
|
int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
|
||||||
|
for (j=0;j<numPoolConstraints;j++)
|
||||||
|
{
|
||||||
|
const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
|
||||||
|
resolveSingleConstraintRowLowerLimit(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
|
||||||
|
}
|
||||||
|
///solve all friction constraints
|
||||||
|
int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
|
||||||
|
for (j=0;j<numFrictionPoolConstraints;j++)
|
||||||
|
{
|
||||||
|
btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
|
||||||
|
btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
|
||||||
|
|
||||||
resolveSingleConstraintRowGeneric(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
|
if (totalImpulse>btScalar(0))
|
||||||
|
{
|
||||||
|
solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
|
||||||
|
solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
|
||||||
|
|
||||||
|
resolveSingleConstraintRowGeneric(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1142,13 +1159,14 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
|
|||||||
{
|
{
|
||||||
BT_PROFILE("solveGroupCacheFriendlyIterations");
|
BT_PROFILE("solveGroupCacheFriendlyIterations");
|
||||||
|
|
||||||
|
|
||||||
//should traverse the contacts random order...
|
|
||||||
int iteration;
|
|
||||||
{
|
{
|
||||||
|
///this is a special step to resolve penetrations (just for contacts)
|
||||||
solveGroupCacheFriendlySplitImpulseIterations(bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
|
solveGroupCacheFriendlySplitImpulseIterations(bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
|
||||||
|
|
||||||
for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
|
int maxIterations = m_maxOverrideNumSolverIterations > infoGlobal.m_numIterations? m_maxOverrideNumSolverIterations : infoGlobal.m_numIterations;
|
||||||
|
|
||||||
|
for ( int iteration = 0 ; iteration< maxIterations ; iteration++)
|
||||||
|
//for ( int iteration = maxIterations-1 ; iteration >= 0;iteration--)
|
||||||
{
|
{
|
||||||
solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
|
solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ protected:
|
|||||||
btAlignedObjectArray<int> m_orderNonContactConstraintPool;
|
btAlignedObjectArray<int> m_orderNonContactConstraintPool;
|
||||||
btAlignedObjectArray<int> m_orderFrictionConstraintPool;
|
btAlignedObjectArray<int> m_orderFrictionConstraintPool;
|
||||||
btAlignedObjectArray<btTypedConstraint::btConstraintInfo1> m_tmpConstraintSizesPool;
|
btAlignedObjectArray<btTypedConstraint::btConstraintInfo1> m_tmpConstraintSizesPool;
|
||||||
|
int m_maxOverrideNumSolverIterations;
|
||||||
|
|
||||||
void setupFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyIdB,
|
void setupFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyIdB,
|
||||||
btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,
|
btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ ATTRIBUTE_ALIGNED64 (struct) btSolverConstraint
|
|||||||
btScalar m_unusedPadding0;
|
btScalar m_unusedPadding0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int m_overrideNumSolverIterations;
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
int m_frictionIndex;
|
int m_frictionIndex;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ m_userConstraintId(-1),
|
|||||||
m_breakingImpulseThreshold(SIMD_INFINITY),
|
m_breakingImpulseThreshold(SIMD_INFINITY),
|
||||||
m_isEnabled(true),
|
m_isEnabled(true),
|
||||||
m_needsFeedback(false),
|
m_needsFeedback(false),
|
||||||
|
m_overrideNumSolverIterations(-1),
|
||||||
m_rbA(rbA),
|
m_rbA(rbA),
|
||||||
m_rbB(getFixedBody()),
|
m_rbB(getFixedBody()),
|
||||||
m_appliedImpulse(btScalar(0.)),
|
m_appliedImpulse(btScalar(0.)),
|
||||||
@@ -43,6 +44,7 @@ m_userConstraintId(-1),
|
|||||||
m_breakingImpulseThreshold(SIMD_INFINITY),
|
m_breakingImpulseThreshold(SIMD_INFINITY),
|
||||||
m_isEnabled(true),
|
m_isEnabled(true),
|
||||||
m_needsFeedback(false),
|
m_needsFeedback(false),
|
||||||
|
m_overrideNumSolverIterations(-1),
|
||||||
m_rbA(rbA),
|
m_rbA(rbA),
|
||||||
m_rbB(rbB),
|
m_rbB(rbB),
|
||||||
m_appliedImpulse(btScalar(0.)),
|
m_appliedImpulse(btScalar(0.)),
|
||||||
@@ -118,6 +120,10 @@ const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* seriali
|
|||||||
|
|
||||||
tcd->m_objectType = m_objectType;
|
tcd->m_objectType = m_objectType;
|
||||||
tcd->m_needsFeedback = m_needsFeedback;
|
tcd->m_needsFeedback = m_needsFeedback;
|
||||||
|
tcd->m_overrideNumSolverIterations = m_overrideNumSolverIterations;
|
||||||
|
tcd->m_breakingImpulseThreshold = float(m_breakingImpulseThreshold);
|
||||||
|
tcd->m_isEnabled = m_isEnabled? 1: 0;
|
||||||
|
|
||||||
tcd->m_userConstraintId =m_userConstraintId;
|
tcd->m_userConstraintId =m_userConstraintId;
|
||||||
tcd->m_userConstraintType =m_userConstraintType;
|
tcd->m_userConstraintType =m_userConstraintType;
|
||||||
|
|
||||||
|
|||||||
@@ -64,10 +64,10 @@ class btTypedConstraint : public btTypedObject
|
|||||||
|
|
||||||
btScalar m_breakingImpulseThreshold;
|
btScalar m_breakingImpulseThreshold;
|
||||||
bool m_isEnabled;
|
bool m_isEnabled;
|
||||||
|
bool m_needsFeedback;
|
||||||
|
int m_overrideNumSolverIterations;
|
||||||
|
|
||||||
|
|
||||||
bool m_needsFeedback;
|
|
||||||
|
|
||||||
btTypedConstraint& operator=(btTypedConstraint& other)
|
btTypedConstraint& operator=(btTypedConstraint& other)
|
||||||
{
|
{
|
||||||
btAssert(0);
|
btAssert(0);
|
||||||
@@ -131,6 +131,18 @@ public:
|
|||||||
btScalar m_damping;
|
btScalar m_damping;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int getOverrideNumSolverIterations() const
|
||||||
|
{
|
||||||
|
return m_overrideNumSolverIterations;
|
||||||
|
}
|
||||||
|
|
||||||
|
///override the number of constraint solver iterations used to solve this constraint
|
||||||
|
///-1 will use the default number of iterations, as specified in SolverInfo.m_numIterations
|
||||||
|
void setOverrideNumSolverIterations(int overideNumIterations)
|
||||||
|
{
|
||||||
|
m_overrideNumSolverIterations = overideNumIterations;
|
||||||
|
}
|
||||||
|
|
||||||
///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 buildJacobian() {};
|
virtual void buildJacobian() {};
|
||||||
|
|
||||||
@@ -329,7 +341,10 @@ struct btTypedConstraintData
|
|||||||
float m_dbgDrawSize;
|
float m_dbgDrawSize;
|
||||||
|
|
||||||
int m_disableCollisionsBetweenLinkedBodies;
|
int m_disableCollisionsBetweenLinkedBodies;
|
||||||
char m_pad4[4];
|
int m_overrideNumSolverIterations;
|
||||||
|
|
||||||
|
float m_breakingImpulseThreshold;
|
||||||
|
int m_isEnabled;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ subject to the following restrictions:
|
|||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
|
/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
|
||||||
#define BT_BULLET_VERSION 279
|
#define BT_BULLET_VERSION 280
|
||||||
|
|
||||||
inline int btGetVersion()
|
inline int btGetVersion()
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -437,8 +437,8 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
buffer[9] = '2';
|
buffer[9] = '2';
|
||||||
buffer[10] = '7';
|
buffer[10] = '8';
|
||||||
buffer[11] = '8';
|
buffer[11] = '0';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user