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:
@@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user