Add a minimum solver 'batch' size to avoid solving many small (independent) islands separately

Default size is 128 . Disable feature by using dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 1;
This commit is contained in:
erwin.coumans
2010-02-06 22:21:44 +00:00
parent a9556d0fd5
commit 7782952d6b
2 changed files with 45 additions and 5 deletions

View File

@@ -52,6 +52,7 @@ struct btContactSolverInfoData
int m_solverMode;
int m_restingContactRestitutionThreshold;
int m_minimumSolverBatchSize;
};
@@ -79,6 +80,7 @@ struct btContactSolverInfo : public btContactSolverInfoData
m_warmstartingFactor=btScalar(0.85);
m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD;// | SOLVER_RANDMIZE_ORDER;
m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution
m_minimumSolverBatchSize = 128; //try to combine islands until the amount of constraints reaches this limit
}
};

View File

@@ -548,7 +548,6 @@ class btSortConstraintOnIslandPredicate
void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
{
BT_PROFILE("solveConstraints");
@@ -564,6 +563,11 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
btStackAlloc* m_stackAlloc;
btDispatcher* m_dispatcher;
btAlignedObjectArray<btCollisionObject*> m_bodies;
btAlignedObjectArray<btPersistentManifold*> m_manifolds;
btAlignedObjectArray<btTypedConstraint*> m_constraints;
InplaceSolverIslandCallback(
btContactSolverInfo& solverInfo,
btConstraintSolver* solver,
@@ -583,6 +587,7 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
}
InplaceSolverIslandCallback& operator=(InplaceSolverIslandCallback& other)
{
btAssert(0);
@@ -623,17 +628,48 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
}
}
if (m_solverInfo.m_minimumSolverBatchSize<=1)
{
///only call solveGroup if there is some work: avoid virtual function call, its overhead can be excessive
if (numManifolds + numCurConstraints)
{
m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
}
} else
{
for (i=0;i<numBodies;i++)
m_bodies.push_back(bodies[i]);
for (i=0;i<numManifolds;i++)
m_manifolds.push_back(manifolds[i]);
for (i=0;i<numCurConstraints;i++)
m_constraints.push_back(startConstraint[i]);
if ((m_constraints.size()+m_manifolds.size())>m_solverInfo.m_minimumSolverBatchSize)
{
processConstraints();
} else
{
//printf("deferred\n");
}
}
}
}
void processConstraints()
{
if (m_manifolds.size() + m_constraints.size()>0)
{
m_solver->solveGroup( &m_bodies[0],m_bodies.size(), &m_manifolds[0], m_manifolds.size(), &m_constraints[0], m_constraints.size() ,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
}
m_bodies.resize(0);
m_manifolds.resize(0);
m_constraints.resize(0);
}
};
//sorted version of all btTypedConstraint, based on islandId
btAlignedObjectArray<btTypedConstraint*> sortedConstraints;
sortedConstraints.resize( m_constraints.size());
@@ -658,6 +694,8 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
/// solve all the constraints for this island
m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),&solverCallback);
solverCallback.processConstraints();
m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc);
}