2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
16 #include "btDiscreteDynamicsWorldMt.h"
19 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
20 #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
21 #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
22 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
23 #include "btSimulationIslandManagerMt.h"
24 #include "LinearMath/btTransformUtil.h"
25 #include "LinearMath/btQuickprof.h"
27 //rigidbody & constraints
28 #include "BulletDynamics/Dynamics/btRigidBody.h"
29 #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
30 #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
31 #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
32 #include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
33 #include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
34 #include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
35 #include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
36 #include "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h"
37 #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
38 #include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
40 #include "LinearMath/btIDebugDraw.h"
41 #include "BulletCollision/CollisionShapes/btSphereShape.h"
43 #include "BulletDynamics/Dynamics/btActionInterface.h"
44 #include "LinearMath/btQuickprof.h"
45 #include "LinearMath/btMotionState.h"
47 #include "LinearMath/btSerializer.h"
50 /// btConstraintSolverPoolMt
53 btConstraintSolverPoolMt::ThreadSolver* btConstraintSolverPoolMt::getAndLockThreadSolver()
57 i = btGetCurrentThreadIndex() % m_solvers.size();
58 #endif // #if BT_THREADSAFE
61 ThreadSolver& solver = m_solvers[i];
62 if (solver.mutex.tryLock())
66 // failed, try the next one
67 i = (i + 1) % m_solvers.size();
72 void btConstraintSolverPoolMt::init(btConstraintSolver** solvers, int numSolvers)
74 m_solverType = BT_SEQUENTIAL_IMPULSE_SOLVER;
75 m_solvers.resize(numSolvers);
76 for (int i = 0; i < numSolvers; ++i)
78 m_solvers[i].solver = solvers[i];
82 m_solverType = solvers[0]->getSolverType();
86 // create the solvers for me
87 btConstraintSolverPoolMt::btConstraintSolverPoolMt(int numSolvers)
89 btAlignedObjectArray<btConstraintSolver*> solvers;
90 solvers.reserve(numSolvers);
91 for (int i = 0; i < numSolvers; ++i)
93 btConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
94 solvers.push_back(solver);
96 init(&solvers[0], numSolvers);
99 // pass in fully constructed solvers (destructor will delete them)
100 btConstraintSolverPoolMt::btConstraintSolverPoolMt(btConstraintSolver** solvers, int numSolvers)
102 init(solvers, numSolvers);
105 btConstraintSolverPoolMt::~btConstraintSolverPoolMt()
107 // delete all solvers
108 for (int i = 0; i < m_solvers.size(); ++i)
110 ThreadSolver& solver = m_solvers[i];
111 delete solver.solver;
112 solver.solver = NULL;
116 ///solve a group of constraints
117 btScalar btConstraintSolverPoolMt::solveGroup(btCollisionObject** bodies,
119 btPersistentManifold** manifolds,
121 btTypedConstraint** constraints,
123 const btContactSolverInfo& info,
124 btIDebugDraw* debugDrawer,
125 btDispatcher* dispatcher)
127 ThreadSolver* ts = getAndLockThreadSolver();
128 ts->solver->solveGroup(bodies, numBodies, manifolds, numManifolds, constraints, numConstraints, info, debugDrawer, dispatcher);
133 void btConstraintSolverPoolMt::reset()
135 for (int i = 0; i < m_solvers.size(); ++i)
137 ThreadSolver& solver = m_solvers[i];
139 solver.solver->reset();
140 solver.mutex.unlock();
145 /// btDiscreteDynamicsWorldMt
148 btDiscreteDynamicsWorldMt::btDiscreteDynamicsWorldMt(btDispatcher* dispatcher,
149 btBroadphaseInterface* pairCache,
150 btConstraintSolverPoolMt* solverPool,
151 btConstraintSolver* constraintSolverMt,
152 btCollisionConfiguration* collisionConfiguration)
153 : btDiscreteDynamicsWorld(dispatcher, pairCache, solverPool, collisionConfiguration)
155 if (m_ownsIslandManager)
157 m_islandManager->~btSimulationIslandManager();
158 btAlignedFree(m_islandManager);
161 void* mem = btAlignedAlloc(sizeof(btSimulationIslandManagerMt), 16);
162 btSimulationIslandManagerMt* im = new (mem) btSimulationIslandManagerMt();
163 im->setMinimumSolverBatchSize(m_solverInfo.m_minimumSolverBatchSize);
164 m_islandManager = im;
166 m_constraintSolverMt = constraintSolverMt;
169 btDiscreteDynamicsWorldMt::~btDiscreteDynamicsWorldMt()
173 void btDiscreteDynamicsWorldMt::solveConstraints(btContactSolverInfo& solverInfo)
175 BT_PROFILE("solveConstraints");
177 m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds());
179 /// solve all the constraints for this island
180 btSimulationIslandManagerMt* im = static_cast<btSimulationIslandManagerMt*>(m_islandManager);
181 btSimulationIslandManagerMt::SolverParams solverParams;
182 solverParams.m_solverPool = m_constraintSolver;
183 solverParams.m_solverMt = m_constraintSolverMt;
184 solverParams.m_solverInfo = &solverInfo;
185 solverParams.m_debugDrawer = m_debugDrawer;
186 solverParams.m_dispatcher = getCollisionWorld()->getDispatcher();
187 im->buildAndProcessIslands(getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_constraints, solverParams);
189 m_constraintSolver->allSolved(solverInfo, m_debugDrawer);
192 struct UpdaterUnconstrainedMotion : public btIParallelForBody
195 btRigidBody** rigidBodies;
197 void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
199 for (int i = iBegin; i < iEnd; ++i)
201 btRigidBody* body = rigidBodies[i];
202 if (!body->isStaticOrKinematicObject())
204 //don't integrate/update velocities here, it happens in the constraint solver
205 body->applyDamping(timeStep);
206 body->predictIntegratedTransform(timeStep, body->getInterpolationWorldTransform());
212 void btDiscreteDynamicsWorldMt::predictUnconstraintMotion(btScalar timeStep)
214 BT_PROFILE("predictUnconstraintMotion");
215 if (m_nonStaticRigidBodies.size() > 0)
217 UpdaterUnconstrainedMotion update;
218 update.timeStep = timeStep;
219 update.rigidBodies = &m_nonStaticRigidBodies[0];
220 int grainSize = 50; // num of iterations per task for task scheduler
221 btParallelFor(0, m_nonStaticRigidBodies.size(), grainSize, update);
225 void btDiscreteDynamicsWorldMt::createPredictiveContacts(btScalar timeStep)
227 BT_PROFILE("createPredictiveContacts");
228 releasePredictiveContacts();
229 if (m_nonStaticRigidBodies.size() > 0)
231 UpdaterCreatePredictiveContacts update;
233 update.timeStep = timeStep;
234 update.rigidBodies = &m_nonStaticRigidBodies[0];
235 int grainSize = 50; // num of iterations per task for task scheduler
236 btParallelFor(0, m_nonStaticRigidBodies.size(), grainSize, update);
240 void btDiscreteDynamicsWorldMt::integrateTransforms(btScalar timeStep)
242 BT_PROFILE("integrateTransforms");
243 if (m_nonStaticRigidBodies.size() > 0)
245 UpdaterIntegrateTransforms update;
247 update.timeStep = timeStep;
248 update.rigidBodies = &m_nonStaticRigidBodies[0];
249 int grainSize = 50; // num of iterations per task for task scheduler
250 btParallelFor(0, m_nonStaticRigidBodies.size(), grainSize, update);
254 int btDiscreteDynamicsWorldMt::stepSimulation(btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep)
256 int numSubSteps = btDiscreteDynamicsWorld::stepSimulation(timeStep, maxSubSteps, fixedTimeStep);
257 if (btITaskScheduler* scheduler = btGetTaskScheduler())
259 // tell Bullet's threads to sleep, so other threads can run
260 scheduler->sleepWorkerThreadsHint();