2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2013 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 "btMultiBodyDynamicsWorld.h"
17
#include "btMultiBodyConstraintSolver.h"
18
#include "btMultiBody.h"
19
#include "btMultiBodyLinkCollider.h"
20
#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
21
#include "LinearMath/btQuickprof.h"
22
#include "btMultiBodyConstraint.h"
27
void btMultiBodyDynamicsWorld::addMultiBody(btMultiBody* body, short group, short mask)
29
m_multiBodies.push_back(body);
33
void btMultiBodyDynamicsWorld::removeMultiBody(btMultiBody* body)
35
m_multiBodies.remove(body);
38
void btMultiBodyDynamicsWorld::calculateSimulationIslands()
40
BT_PROFILE("calculateSimulationIslands");
42
getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher());
45
//merge islands based on speculative contact manifolds too
46
for (int i=0;i<this->m_predictiveManifolds.size();i++)
48
btPersistentManifold* manifold = m_predictiveManifolds[i];
50
const btCollisionObject* colObj0 = manifold->getBody0();
51
const btCollisionObject* colObj1 = manifold->getBody1();
53
if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
54
((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
56
getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
63
int numConstraints = int(m_constraints.size());
64
for (i=0;i< numConstraints ; i++ )
66
btTypedConstraint* constraint = m_constraints[i];
67
if (constraint->isEnabled())
69
const btRigidBody* colObj0 = &constraint->getRigidBodyA();
70
const btRigidBody* colObj1 = &constraint->getRigidBodyB();
72
if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
73
((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
75
getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
81
//merge islands linked by Featherstone link colliders
82
for (int i=0;i<m_multiBodies.size();i++)
84
btMultiBody* body = m_multiBodies[i];
86
btMultiBodyLinkCollider* prev = body->getBaseCollider();
88
for (int b=0;b<body->getNumLinks();b++)
90
btMultiBodyLinkCollider* cur = body->getLink(b).m_collider;
92
if (((cur) && (!(cur)->isStaticOrKinematicObject())) &&
93
((prev) && (!(prev)->isStaticOrKinematicObject())))
95
int tagPrev = prev->getIslandTag();
96
int tagCur = cur->getIslandTag();
97
getSimulationIslandManager()->getUnionFind().unite(tagPrev, tagCur);
99
if (cur && !cur->isStaticOrKinematicObject())
106
//merge islands linked by multibody constraints
108
for (int i=0;i<this->m_multiBodyConstraints.size();i++)
110
btMultiBodyConstraint* c = m_multiBodyConstraints[i];
111
int tagA = c->getIslandIdA();
112
int tagB = c->getIslandIdB();
113
if (tagA>=0 && tagB>=0)
114
getSimulationIslandManager()->getUnionFind().unite(tagA, tagB);
118
//Store the island id in each body
119
getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld());
124
void btMultiBodyDynamicsWorld::updateActivationState(btScalar timeStep)
126
BT_PROFILE("btMultiBodyDynamicsWorld::updateActivationState");
130
for ( int i=0;i<m_multiBodies.size();i++)
132
btMultiBody* body = m_multiBodies[i];
135
body->checkMotionAndSleepIfRequired(timeStep);
136
if (!body->isAwake())
138
btMultiBodyLinkCollider* col = body->getBaseCollider();
139
if (col && col->getActivationState() == ACTIVE_TAG)
141
col->setActivationState( WANTS_DEACTIVATION);
142
col->setDeactivationTime(0.f);
144
for (int b=0;b<body->getNumLinks();b++)
146
btMultiBodyLinkCollider* col = body->getLink(b).m_collider;
147
if (col && col->getActivationState() == ACTIVE_TAG)
149
col->setActivationState( WANTS_DEACTIVATION);
150
col->setDeactivationTime(0.f);
155
btMultiBodyLinkCollider* col = body->getBaseCollider();
156
if (col && col->getActivationState() != DISABLE_DEACTIVATION)
157
col->setActivationState( ACTIVE_TAG );
159
for (int b=0;b<body->getNumLinks();b++)
161
btMultiBodyLinkCollider* col = body->getLink(b).m_collider;
162
if (col && col->getActivationState() != DISABLE_DEACTIVATION)
163
col->setActivationState( ACTIVE_TAG );
170
btDiscreteDynamicsWorld::updateActivationState(timeStep);
174
SIMD_FORCE_INLINE int btGetConstraintIslandId2(const btTypedConstraint* lhs)
178
const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
179
const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
180
islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag();
186
class btSortConstraintOnIslandPredicate2
190
bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs ) const
192
int rIslandId0,lIslandId0;
193
rIslandId0 = btGetConstraintIslandId2(rhs);
194
lIslandId0 = btGetConstraintIslandId2(lhs);
195
return lIslandId0 < rIslandId0;
201
SIMD_FORCE_INLINE int btGetMultiBodyConstraintIslandId(const btMultiBodyConstraint* lhs)
205
int islandTagA = lhs->getIslandIdA();
206
int islandTagB = lhs->getIslandIdB();
207
islandId= islandTagA>=0?islandTagA:islandTagB;
213
class btSortMultiBodyConstraintOnIslandPredicate
217
bool operator() ( const btMultiBodyConstraint* lhs, const btMultiBodyConstraint* rhs ) const
219
int rIslandId0,lIslandId0;
220
rIslandId0 = btGetMultiBodyConstraintIslandId(rhs);
221
lIslandId0 = btGetMultiBodyConstraintIslandId(lhs);
222
return lIslandId0 < rIslandId0;
226
struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback
228
btContactSolverInfo* m_solverInfo;
229
btMultiBodyConstraintSolver* m_solver;
230
btMultiBodyConstraint** m_multiBodySortedConstraints;
231
int m_numMultiBodyConstraints;
233
btTypedConstraint** m_sortedConstraints;
234
int m_numConstraints;
235
btIDebugDraw* m_debugDrawer;
236
btDispatcher* m_dispatcher;
238
btAlignedObjectArray<btCollisionObject*> m_bodies;
239
btAlignedObjectArray<btPersistentManifold*> m_manifolds;
240
btAlignedObjectArray<btTypedConstraint*> m_constraints;
241
btAlignedObjectArray<btMultiBodyConstraint*> m_multiBodyConstraints;
244
MultiBodyInplaceSolverIslandCallback( btMultiBodyConstraintSolver* solver,
245
btDispatcher* dispatcher)
248
m_multiBodySortedConstraints(NULL),
251
m_dispatcher(dispatcher)
256
MultiBodyInplaceSolverIslandCallback& operator=(MultiBodyInplaceSolverIslandCallback& other)
263
SIMD_FORCE_INLINE void setup ( btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btMultiBodyConstraint** sortedMultiBodyConstraints, int numMultiBodyConstraints, btIDebugDraw* debugDrawer)
265
btAssert(solverInfo);
266
m_solverInfo = solverInfo;
268
m_multiBodySortedConstraints = sortedMultiBodyConstraints;
269
m_numMultiBodyConstraints = numMultiBodyConstraints;
270
m_sortedConstraints = sortedConstraints;
271
m_numConstraints = numConstraints;
273
m_debugDrawer = debugDrawer;
275
m_manifolds.resize (0);
276
m_constraints.resize (0);
277
m_multiBodyConstraints.resize(0);
281
virtual void processIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId)
285
///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
286
m_solver->solveMultiBodyGroup( bodies,numBodies,manifolds, numManifolds,m_sortedConstraints, m_numConstraints, &m_multiBodySortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher);
289
//also add all non-contact constraints/joints for this island
290
btTypedConstraint** startConstraint = 0;
291
btMultiBodyConstraint** startMultiBodyConstraint = 0;
293
int numCurConstraints = 0;
294
int numCurMultiBodyConstraints = 0;
298
//find the first constraint for this island
300
for (i=0;i<m_numConstraints;i++)
302
if (btGetConstraintIslandId2(m_sortedConstraints[i]) == islandId)
304
startConstraint = &m_sortedConstraints[i];
308
//count the number of constraints in this island
309
for (;i<m_numConstraints;i++)
311
if (btGetConstraintIslandId2(m_sortedConstraints[i]) == islandId)
317
for (i=0;i<m_numMultiBodyConstraints;i++)
319
if (btGetMultiBodyConstraintIslandId(m_multiBodySortedConstraints[i]) == islandId)
322
startMultiBodyConstraint = &m_multiBodySortedConstraints[i];
326
//count the number of multi body constraints in this island
327
for (;i<m_numMultiBodyConstraints;i++)
329
if (btGetMultiBodyConstraintIslandId(m_multiBodySortedConstraints[i]) == islandId)
331
numCurMultiBodyConstraints++;
335
if (m_solverInfo->m_minimumSolverBatchSize<=1)
337
m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher);
341
for (i=0;i<numBodies;i++)
342
m_bodies.push_back(bodies[i]);
343
for (i=0;i<numManifolds;i++)
344
m_manifolds.push_back(manifolds[i]);
345
for (i=0;i<numCurConstraints;i++)
346
m_constraints.push_back(startConstraint[i]);
348
for (i=0;i<numCurMultiBodyConstraints;i++)
349
m_multiBodyConstraints.push_back(startMultiBodyConstraint[i]);
351
if ((m_constraints.size()+m_manifolds.size())>m_solverInfo->m_minimumSolverBatchSize)
353
processConstraints();
356
//printf("deferred\n");
361
void processConstraints()
364
btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0;
365
btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0;
366
btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0;
367
btMultiBodyConstraint** multiBodyConstraints = m_multiBodyConstraints.size() ? &m_multiBodyConstraints[0] : 0;
369
m_solver->solveMultiBodyGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,multiBodyConstraints, m_multiBodyConstraints.size(), *m_solverInfo,m_debugDrawer,m_dispatcher);
371
m_manifolds.resize(0);
372
m_constraints.resize(0);
373
m_multiBodyConstraints.resize(0);
380
btMultiBodyDynamicsWorld::btMultiBodyDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btMultiBodyConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
381
:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration),
382
m_multiBodyConstraintSolver(constraintSolver)
384
//split impulse is not yet supported for Featherstone hierarchies
385
getSolverInfo().m_splitImpulse = false;
386
getSolverInfo().m_solverMode |=SOLVER_USE_2_FRICTION_DIRECTIONS;
387
m_solverMultiBodyIslandCallback = new MultiBodyInplaceSolverIslandCallback(constraintSolver,dispatcher);
390
btMultiBodyDynamicsWorld::~btMultiBodyDynamicsWorld ()
392
delete m_solverMultiBodyIslandCallback;
398
void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
401
btAlignedObjectArray<btScalar> scratch_r;
402
btAlignedObjectArray<btVector3> scratch_v;
403
btAlignedObjectArray<btMatrix3x3> scratch_m;
406
BT_PROFILE("solveConstraints");
408
m_sortedConstraints.resize( m_constraints.size());
410
for (i=0;i<getNumConstraints();i++)
412
m_sortedConstraints[i] = m_constraints[i];
414
m_sortedConstraints.quickSort(btSortConstraintOnIslandPredicate2());
415
btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0;
417
m_sortedMultiBodyConstraints.resize(m_multiBodyConstraints.size());
418
for (i=0;i<m_multiBodyConstraints.size();i++)
420
m_sortedMultiBodyConstraints[i] = m_multiBodyConstraints[i];
422
m_sortedMultiBodyConstraints.quickSort(btSortMultiBodyConstraintOnIslandPredicate());
424
btMultiBodyConstraint** sortedMultiBodyConstraints = m_sortedMultiBodyConstraints.size() ? &m_sortedMultiBodyConstraints[0] : 0;
427
m_solverMultiBodyIslandCallback->setup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),sortedMultiBodyConstraints,m_sortedMultiBodyConstraints.size(), getDebugDrawer());
428
m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds());
430
/// solve all the constraints for this island
431
m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),m_solverMultiBodyIslandCallback);
435
BT_PROFILE("btMultiBody addForce and stepVelocities");
436
for (int i=0;i<this->m_multiBodies.size();i++)
438
btMultiBody* bod = m_multiBodies[i];
440
bool isSleeping = false;
442
if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING)
446
for (int b=0;b<bod->getNumLinks();b++)
448
if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState()==ISLAND_SLEEPING)
454
scratch_r.resize(bod->getNumLinks()+1);
455
scratch_v.resize(bod->getNumLinks()+1);
456
scratch_m.resize(bod->getNumLinks()+1);
458
bod->clearForcesAndTorques();
459
bod->addBaseForce(m_gravity * bod->getBaseMass());
461
for (int j = 0; j < bod->getNumLinks(); ++j)
463
bod->addLinkForce(j, m_gravity * bod->getLinkMass(j));
466
bod->stepVelocities(solverInfo.m_timeStep, scratch_r, scratch_v, scratch_m);
471
m_solverMultiBodyIslandCallback->processConstraints();
473
m_constraintSolver->allSolved(solverInfo, m_debugDrawer);
477
void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep)
479
btDiscreteDynamicsWorld::integrateTransforms(timeStep);
482
BT_PROFILE("btMultiBody stepPositions");
483
//integrate and update the Featherstone hierarchies
484
btAlignedObjectArray<btQuaternion> world_to_local;
485
btAlignedObjectArray<btVector3> local_origin;
487
for (int b=0;b<m_multiBodies.size();b++)
489
btMultiBody* bod = m_multiBodies[b];
490
bool isSleeping = false;
491
if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING)
495
for (int b=0;b<bod->getNumLinks();b++)
497
if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState()==ISLAND_SLEEPING)
504
int nLinks = bod->getNumLinks();
507
world_to_local.resize(nLinks+1);
508
local_origin.resize(nLinks+1);
510
bod->stepPositions(timeStep);
514
world_to_local[0] = bod->getWorldToBaseRot();
515
local_origin[0] = bod->getBasePos();
517
if (bod->getBaseCollider())
519
btVector3 posr = local_origin[0];
520
float pos[4]={posr.x(),posr.y(),posr.z(),1};
521
float quat[4]={-world_to_local[0].x(),-world_to_local[0].y(),-world_to_local[0].z(),world_to_local[0].w()};
525
tr.setRotation(btQuaternion(quat[0],quat[1],quat[2],quat[3]));
527
bod->getBaseCollider()->setWorldTransform(tr);
531
for (int k=0;k<bod->getNumLinks();k++)
533
const int parent = bod->getParent(k);
534
world_to_local[k+1] = bod->getParentToLocalRot(k) * world_to_local[parent+1];
535
local_origin[k+1] = local_origin[parent+1] + (quatRotate(world_to_local[k+1].inverse() , bod->getRVector(k)));
539
for (int m=0;m<bod->getNumLinks();m++)
541
btMultiBodyLinkCollider* col = bod->getLink(m).m_collider;
544
int link = col->m_link;
549
btVector3 posr = local_origin[index];
550
float pos[4]={posr.x(),posr.y(),posr.z(),1};
551
float quat[4]={-world_to_local[index].x(),-world_to_local[index].y(),-world_to_local[index].z(),world_to_local[index].w()};
555
tr.setRotation(btQuaternion(quat[0],quat[1],quat[2],quat[3]));
557
col->setWorldTransform(tr);
562
bod->clearVelocities();
570
void btMultiBodyDynamicsWorld::addMultiBodyConstraint( btMultiBodyConstraint* constraint)
572
m_multiBodyConstraints.push_back(constraint);
575
void btMultiBodyDynamicsWorld::removeMultiBodyConstraint( btMultiBodyConstraint* constraint)
577
m_multiBodyConstraints.remove(constraint);