Bullet Collision Detection & Physics Library: btSimulationIslandManagerMt.cpp Source File

Bullet Collision Detection & Physics Library

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

btSimulationIslandManagerMt.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#include "LinearMath/btScalar.h"
17#include "LinearMath/btThreads.h"
18#include "btSimulationIslandManagerMt.h"
19#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
20#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
21#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
22#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
23#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
24#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.h" // for s_minimumContactManifoldsForBatching
25
26//#include <stdio.h>
27#include "LinearMath/btQuickprof.h"
28
29 SIMD_FORCE_INLINE int calcBatchCost(int bodies, int manifolds, int constraints)
30{
31 // rough estimate of the cost of a batch, used for merging
32 int batchCost = bodies + 8 * manifolds + 4 * constraints;
33 return batchCost;
34}
35
36 SIMD_FORCE_INLINE int calcBatchCost(const btSimulationIslandManagerMt::Island* island)
37{
38 return calcBatchCost(island->bodyArray.size(), island->manifoldArray.size(), island->constraintArray.size());
39}
40
41btSimulationIslandManagerMt::btSimulationIslandManagerMt()
42{
43 m_minimumSolverBatchSize = calcBatchCost(0, 128, 0);
44 m_batchIslandMinBodyCount = 32;
45 m_islandDispatch = parallelIslandDispatch;
46 m_batchIsland = NULL;
47}
48
49btSimulationIslandManagerMt::~btSimulationIslandManagerMt()
50{
51 for (int i = 0; i < m_allocatedIslands.size(); ++i)
52 {
53 delete m_allocatedIslands[i];
54 }
55 m_allocatedIslands.resize(0);
56 m_activeIslands.resize(0);
57 m_freeIslands.resize(0);
58}
59
60 inline int getIslandId(const btPersistentManifold* lhs)
61{
62 const btCollisionObject* rcolObj0 = static_cast<const btCollisionObject*>(lhs->getBody0());
63 const btCollisionObject* rcolObj1 = static_cast<const btCollisionObject*>(lhs->getBody1());
64 int islandId = rcolObj0->getIslandTag() >= 0 ? rcolObj0->getIslandTag() : rcolObj1->getIslandTag();
65 return islandId;
66}
67
68 SIMD_FORCE_INLINE int btGetConstraintIslandId1(const btTypedConstraint* lhs)
69{
70 const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
71 const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
72 int islandId = rcolObj0.getIslandTag() >= 0 ? rcolObj0.getIslandTag() : rcolObj1.getIslandTag();
73 return islandId;
74}
75
77 class IslandBatchSizeSortPredicate
78{
79public:
80 bool operator()(const btSimulationIslandManagerMt::Island* lhs, const btSimulationIslandManagerMt::Island* rhs) const
81 {
82 int lCost = calcBatchCost(lhs);
83 int rCost = calcBatchCost(rhs);
84 return lCost > rCost;
85 }
86};
87
88 class IslandBodyCapacitySortPredicate
89{
90public:
91 bool operator()(const btSimulationIslandManagerMt::Island* lhs, const btSimulationIslandManagerMt::Island* rhs) const
92 {
93 return lhs->bodyArray.capacity() > rhs->bodyArray.capacity();
94 }
95};
96
97 void btSimulationIslandManagerMt::Island::append(const Island& other)
98{
99 // append bodies
100 for (int i = 0; i < other.bodyArray.size(); ++i)
101 {
102 bodyArray.push_back(other.bodyArray[i]);
103 }
104 // append manifolds
105 for (int i = 0; i < other.manifoldArray.size(); ++i)
106 {
107 manifoldArray.push_back(other.manifoldArray[i]);
108 }
109 // append constraints
110 for (int i = 0; i < other.constraintArray.size(); ++i)
111 {
112 constraintArray.push_back(other.constraintArray[i]);
113 }
114}
115
116 bool btIsBodyInIsland(const btSimulationIslandManagerMt::Island& island, const btCollisionObject* obj)
117{
118 for (int i = 0; i < island.bodyArray.size(); ++i)
119 {
120 if (island.bodyArray[i] == obj)
121 {
122 return true;
123 }
124 }
125 return false;
126}
127
128 void btSimulationIslandManagerMt::initIslandPools()
129{
130 // reset island pools
131 int numElem = getUnionFind().getNumElements();
132 m_lookupIslandFromId.resize(numElem);
133 for (int i = 0; i < m_lookupIslandFromId.size(); ++i)
134 {
135 m_lookupIslandFromId[i] = NULL;
136 }
137 m_activeIslands.resize(0);
138 m_freeIslands.resize(0);
139 // check whether allocated islands are sorted by body capacity (largest to smallest)
140 int lastCapacity = 0;
141 bool isSorted = true;
142 for (int i = 0; i < m_allocatedIslands.size(); ++i)
143 {
144 Island* island = m_allocatedIslands[i];
145 int cap = island->bodyArray.capacity();
146 if (cap > lastCapacity)
147 {
148 isSorted = false;
149 break;
150 }
151 lastCapacity = cap;
152 }
153 if (!isSorted)
154 {
155 m_allocatedIslands.quickSort(IslandBodyCapacitySortPredicate());
156 }
157
158 m_batchIsland = NULL;
159 // mark all islands free (but avoid deallocation)
160 for (int i = 0; i < m_allocatedIslands.size(); ++i)
161 {
162 Island* island = m_allocatedIslands[i];
163 island->bodyArray.resize(0);
164 island->manifoldArray.resize(0);
165 island->constraintArray.resize(0);
166 island->id = -1;
167 island->isSleeping = true;
168 m_freeIslands.push_back(island);
169 }
170}
171
172 btSimulationIslandManagerMt::Island* btSimulationIslandManagerMt::getIsland(int id)
173{
174 btAssert(id >= 0);
175 btAssert(id < m_lookupIslandFromId.size());
176 Island* island = m_lookupIslandFromId[id];
177 if (island == NULL)
178 {
179 // search for existing island
180 for (int i = 0; i < m_activeIslands.size(); ++i)
181 {
182 if (m_activeIslands[i]->id == id)
183 {
184 island = m_activeIslands[i];
185 break;
186 }
187 }
188 m_lookupIslandFromId[id] = island;
189 }
190 return island;
191}
192
193 btSimulationIslandManagerMt::Island* btSimulationIslandManagerMt::allocateIsland(int id, int numBodies)
194{
195 Island* island = NULL;
196 int allocSize = numBodies;
197 if (numBodies < m_batchIslandMinBodyCount)
198 {
199 if (m_batchIsland)
200 {
201 island = m_batchIsland;
202 m_lookupIslandFromId[id] = island;
203 // if we've made a large enough batch,
204 if (island->bodyArray.size() + numBodies >= m_batchIslandMinBodyCount)
205 {
206 // next time start a new batch
207 m_batchIsland = NULL;
208 }
209 return island;
210 }
211 else
212 {
213 // need to allocate a batch island
214 allocSize = m_batchIslandMinBodyCount * 2;
215 }
216 }
217 btAlignedObjectArray<Island*>& freeIslands = m_freeIslands;
218
219 // search for free island
220 if (freeIslands.size() > 0)
221 {
222 // try to reuse a previously allocated island
223 int iFound = freeIslands.size();
224 // linear search for smallest island that can hold our bodies
225 for (int i = freeIslands.size() - 1; i >= 0; --i)
226 {
227 if (freeIslands[i]->bodyArray.capacity() >= allocSize)
228 {
229 iFound = i;
230 island = freeIslands[i];
231 island->id = id;
232 break;
233 }
234 }
235 // if found, shrink array while maintaining ordering
236 if (island)
237 {
238 int iDest = iFound;
239 int iSrc = iDest + 1;
240 while (iSrc < freeIslands.size())
241 {
242 freeIslands[iDest++] = freeIslands[iSrc++];
243 }
244 freeIslands.pop_back();
245 }
246 }
247 if (island == NULL)
248 {
249 // no free island found, allocate
250 island = new Island(); // TODO: change this to use the pool allocator
251 island->id = id;
252 island->bodyArray.reserve(allocSize);
253 m_allocatedIslands.push_back(island);
254 }
255 m_lookupIslandFromId[id] = island;
256 if (numBodies < m_batchIslandMinBodyCount)
257 {
258 m_batchIsland = island;
259 }
260 m_activeIslands.push_back(island);
261 return island;
262}
263
264 void btSimulationIslandManagerMt::buildIslands(btDispatcher* dispatcher, btCollisionWorld* collisionWorld)
265{
266 BT_PROFILE("buildIslands");
267
268 btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
269
270 //we are going to sort the unionfind array, and store the element id in the size
271 //afterwards, we clean unionfind, to make sure no-one uses it anymore
272
273 getUnionFind().sortIslands();
274 int numElem = getUnionFind().getNumElements();
275
276 int endIslandIndex = 1;
277 int startIslandIndex;
278
279 //update the sleeping state for bodies, if all are sleeping
280 for (startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex)
281 {
282 int islandId = getUnionFind().getElement(startIslandIndex).m_id;
283 for (endIslandIndex = startIslandIndex + 1; (endIslandIndex < numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId); endIslandIndex++)
284 {
285 }
286
287 //int numSleeping = 0;
288
289 bool allSleeping = true;
290
291 int idx;
292 for (idx = startIslandIndex; idx < endIslandIndex; idx++)
293 {
294 int i = getUnionFind().getElement(idx).m_sz;
295
296 btCollisionObject* colObj0 = collisionObjects[i];
297 if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
298 {
299 // printf("error in island management\n");
300 }
301
302 btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
303 if (colObj0->getIslandTag() == islandId)
304 {
305 if (colObj0->getActivationState() == ACTIVE_TAG ||
306 colObj0->getActivationState() == DISABLE_DEACTIVATION)
307 {
308 allSleeping = false;
309 break;
310 }
311 }
312 }
313
314 if (allSleeping)
315 {
316 int idx;
317 for (idx = startIslandIndex; idx < endIslandIndex; idx++)
318 {
319 int i = getUnionFind().getElement(idx).m_sz;
320 btCollisionObject* colObj0 = collisionObjects[i];
321 if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
322 {
323 // printf("error in island management\n");
324 }
325
326 btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
327
328 if (colObj0->getIslandTag() == islandId)
329 {
330 colObj0->setActivationState(ISLAND_SLEEPING);
331 }
332 }
333 }
334 else
335 {
336 int idx;
337 for (idx = startIslandIndex; idx < endIslandIndex; idx++)
338 {
339 int i = getUnionFind().getElement(idx).m_sz;
340
341 btCollisionObject* colObj0 = collisionObjects[i];
342 if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
343 {
344 // printf("error in island management\n");
345 }
346
347 btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
348
349 if (colObj0->getIslandTag() == islandId)
350 {
351 if (colObj0->getActivationState() == ISLAND_SLEEPING)
352 {
353 colObj0->setActivationState(WANTS_DEACTIVATION);
354 colObj0->setDeactivationTime(0.f);
355 }
356 }
357 }
358 }
359 }
360}
361
362 void btSimulationIslandManagerMt::addBodiesToIslands(btCollisionWorld* collisionWorld)
363{
364 btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
365 int endIslandIndex = 1;
366 int startIslandIndex;
367 int numElem = getUnionFind().getNumElements();
368
369 // create explicit islands and add bodies to each
370 for (startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex)
371 {
372 int islandId = getUnionFind().getElement(startIslandIndex).m_id;
373
374 // find end index
375 for (endIslandIndex = startIslandIndex; (endIslandIndex < numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId); endIslandIndex++)
376 {
377 }
378 // check if island is sleeping
379 bool islandSleeping = true;
380 for (int iElem = startIslandIndex; iElem < endIslandIndex; iElem++)
381 {
382 int i = getUnionFind().getElement(iElem).m_sz;
383 btCollisionObject* colObj = collisionObjects[i];
384 if (colObj->isActive())
385 {
386 islandSleeping = false;
387 }
388 }
389 if (!islandSleeping)
390 {
391 // want to count the number of bodies before allocating the island to optimize memory usage of the Island structures
392 int numBodies = endIslandIndex - startIslandIndex;
393 Island* island = allocateIsland(islandId, numBodies);
394 island->isSleeping = false;
395
396 // add bodies to island
397 for (int iElem = startIslandIndex; iElem < endIslandIndex; iElem++)
398 {
399 int i = getUnionFind().getElement(iElem).m_sz;
400 btCollisionObject* colObj = collisionObjects[i];
401 island->bodyArray.push_back(colObj);
402 }
403 }
404 }
405}
406
407 void btSimulationIslandManagerMt::addManifoldsToIslands(btDispatcher* dispatcher)
408{
409 // walk all the manifolds, activating bodies touched by kinematic objects, and add each manifold to its Island
410 int maxNumManifolds = dispatcher->getNumManifolds();
411 for (int i = 0; i < maxNumManifolds; i++)
412 {
413 btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
414
415 const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>(manifold->getBody0());
416 const btCollisionObject* colObj1 = static_cast<const btCollisionObject*>(manifold->getBody1());
417
419 if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) ||
420 ((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING))
421 {
422 //kinematic objects don't merge islands, but wake up all connected objects
423 if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
424 {
425 if (colObj0->hasContactResponse())
426 colObj1->activate();
427 }
428 if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
429 {
430 if (colObj1->hasContactResponse())
431 colObj0->activate();
432 }
433 //filtering for response
434 if (dispatcher->needsResponse(colObj0, colObj1))
435 {
436 // scatter manifolds into various islands
437 int islandId = getIslandId(manifold);
438 // if island not sleeping,
439 if (Island* island = getIsland(islandId))
440 {
441 island->manifoldArray.push_back(manifold);
442 }
443 }
444 }
445 }
446}
447
448 void btSimulationIslandManagerMt::addConstraintsToIslands(btAlignedObjectArray<btTypedConstraint*>& constraints)
449{
450 // walk constraints
451 for (int i = 0; i < constraints.size(); i++)
452 {
453 // scatter constraints into various islands
454 btTypedConstraint* constraint = constraints[i];
455 if (constraint->isEnabled())
456 {
457 int islandId = btGetConstraintIslandId1(constraint);
458 // if island is not sleeping,
459 if (Island* island = getIsland(islandId))
460 {
461 island->constraintArray.push_back(constraint);
462 }
463 }
464 }
465}
466
467 void btSimulationIslandManagerMt::mergeIslands()
468{
469 // sort islands in order of decreasing batch size
470 m_activeIslands.quickSort(IslandBatchSizeSortPredicate());
471
472 // merge small islands to satisfy minimum batch size
473 // find first small batch island
474 int destIslandIndex = m_activeIslands.size();
475 for (int i = 0; i < m_activeIslands.size(); ++i)
476 {
477 Island* island = m_activeIslands[i];
478 int batchSize = calcBatchCost(island);
479 if (batchSize < m_minimumSolverBatchSize)
480 {
481 destIslandIndex = i;
482 break;
483 }
484 }
485 int lastIndex = m_activeIslands.size() - 1;
486 while (destIslandIndex < lastIndex)
487 {
488 // merge islands from the back of the list
489 Island* island = m_activeIslands[destIslandIndex];
490 int numBodies = island->bodyArray.size();
491 int numManifolds = island->manifoldArray.size();
492 int numConstraints = island->constraintArray.size();
493 int firstIndex = lastIndex;
494 // figure out how many islands we want to merge and find out how many bodies, manifolds and constraints we will have
495 while (true)
496 {
497 Island* src = m_activeIslands[firstIndex];
498 numBodies += src->bodyArray.size();
499 numManifolds += src->manifoldArray.size();
500 numConstraints += src->constraintArray.size();
501 int batchCost = calcBatchCost(numBodies, numManifolds, numConstraints);
502 if (batchCost >= m_minimumSolverBatchSize)
503 {
504 break;
505 }
506 if (firstIndex - 1 == destIslandIndex)
507 {
508 break;
509 }
510 firstIndex--;
511 }
512 // reserve space for these pointers to minimize reallocation
513 island->bodyArray.reserve(numBodies);
514 island->manifoldArray.reserve(numManifolds);
515 island->constraintArray.reserve(numConstraints);
516 // merge islands
517 for (int i = firstIndex; i <= lastIndex; ++i)
518 {
519 island->append(*m_activeIslands[i]);
520 }
521 // shrink array to exclude the islands that were merged from
522 m_activeIslands.resize(firstIndex);
523 lastIndex = firstIndex - 1;
524 destIslandIndex++;
525 }
526}
527
528 void btSimulationIslandManagerMt::solveIsland(btConstraintSolver* solver, Island& island, const SolverParams& solverParams)
529{
530 btPersistentManifold** manifolds = island.manifoldArray.size() ? &island.manifoldArray[0] : NULL;
531 btTypedConstraint** constraintsPtr = island.constraintArray.size() ? &island.constraintArray[0] : NULL;
532 solver->solveGroup(&island.bodyArray[0],
533 island.bodyArray.size(),
534 manifolds,
535 island.manifoldArray.size(),
536 constraintsPtr,
537 island.constraintArray.size(),
538 *solverParams.m_solverInfo,
539 solverParams.m_debugDrawer,
540 solverParams.m_dispatcher);
541}
542
543 void btSimulationIslandManagerMt::serialIslandDispatch(btAlignedObjectArray<Island*>* islandsPtr, const SolverParams& solverParams)
544{
545 BT_PROFILE("serialIslandDispatch");
546 // serial dispatch
547 btAlignedObjectArray<Island*>& islands = *islandsPtr;
548 btConstraintSolver* solver = solverParams.m_solverMt ? solverParams.m_solverMt : solverParams.m_solverPool;
549 for (int i = 0; i < islands.size(); ++i)
550 {
551 solveIsland(solver, *islands[i], solverParams);
552 }
553}
554
555 struct UpdateIslandDispatcher : public btIParallelForBody
556{
557 btAlignedObjectArray<btSimulationIslandManagerMt::Island*>& m_islandsPtr;
558 const btSimulationIslandManagerMt::SolverParams& m_solverParams;
559
560 UpdateIslandDispatcher(btAlignedObjectArray<btSimulationIslandManagerMt::Island*>& islandsPtr, const btSimulationIslandManagerMt::SolverParams& solverParams)
561 : m_islandsPtr(islandsPtr), m_solverParams(solverParams)
562 {
563 }
564
565 void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
566 {
567 btConstraintSolver* solver = m_solverParams.m_solverPool;
568 for (int i = iBegin; i < iEnd; ++i)
569 {
570 btSimulationIslandManagerMt::Island* island = m_islandsPtr[i];
571 btSimulationIslandManagerMt::solveIsland(solver, *island, m_solverParams);
572 }
573 }
574};
575
576 void btSimulationIslandManagerMt::parallelIslandDispatch(btAlignedObjectArray<Island*>* islandsPtr, const SolverParams& solverParams)
577{
578 BT_PROFILE("parallelIslandDispatch");
579 //
580 // if there are islands with many contacts, it may be faster to submit these
581 // large islands *serially* to a single parallel constraint solver, and then later
582 // submit the remaining smaller islands in parallel to multiple sequential solvers.
583 //
584 // Some task schedulers do not deal well with nested parallelFor loops. One implementation
585 // of OpenMP was actually slower than doing everything single-threaded. Intel TBB
586 // on the other hand, seems to do a pretty respectable job with it.
587 //
588 // When solving islands in parallel, the worst case performance happens when there
589 // is one very large island and then perhaps a smattering of very small
590 // islands -- one worker thread takes the large island and the remaining workers
591 // tear through the smaller islands and then sit idle waiting for the first worker
592 // to finish. Solving islands in parallel works best when there are numerous small
593 // islands, roughly equal in size.
594 //
595 // By contrast, the other approach -- the parallel constraint solver -- is only
596 // able to deliver a worthwhile speedup when the island is large. For smaller islands,
597 // it is difficult to extract a useful amount of parallelism -- the overhead of grouping
598 // the constraints into batches and sending the batches to worker threads can nullify
599 // any gains from parallelism.
600 //
601
602 UpdateIslandDispatcher dispatcher(*islandsPtr, solverParams);
603 // We take advantage of the fact the islands are sorted in order of decreasing size
604 int iBegin = 0;
605 if (solverParams.m_solverMt)
606 {
607 while (iBegin < islandsPtr->size())
608 {
609 btSimulationIslandManagerMt::Island* island = (*islandsPtr)[iBegin];
610 if (island->manifoldArray.size() < btSequentialImpulseConstraintSolverMt::s_minimumContactManifoldsForBatching)
611 {
612 // OK to submit the rest of the array in parallel
613 break;
614 }
615 // serial dispatch to parallel solver for large islands (if any)
616 solveIsland(solverParams.m_solverMt, *island, solverParams);
617 ++iBegin;
618 }
619 }
620 // parallel dispatch to sequential solvers for rest
621 btParallelFor(iBegin, islandsPtr->size(), 1, dispatcher);
622}
623
625 void btSimulationIslandManagerMt::buildAndProcessIslands(btDispatcher* dispatcher,
626 btCollisionWorld* collisionWorld,
627 btAlignedObjectArray<btTypedConstraint*>& constraints,
628 const SolverParams& solverParams)
629{
630 BT_PROFILE("buildAndProcessIslands");
631 btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
632
633 buildIslands(dispatcher, collisionWorld);
634
635 if (!getSplitIslands())
636 {
637 btPersistentManifold** manifolds = dispatcher->getInternalManifoldPointer();
638 int maxNumManifolds = dispatcher->getNumManifolds();
639
640 for (int i = 0; i < maxNumManifolds; i++)
641 {
642 btPersistentManifold* manifold = manifolds[i];
643
644 const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>(manifold->getBody0());
645 const btCollisionObject* colObj1 = static_cast<const btCollisionObject*>(manifold->getBody1());
646
648 if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) ||
649 ((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING))
650 {
651 //kinematic objects don't merge islands, but wake up all connected objects
652 if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
653 {
654 if (colObj0->hasContactResponse())
655 colObj1->activate();
656 }
657 if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
658 {
659 if (colObj1->hasContactResponse())
660 colObj0->activate();
661 }
662 }
663 }
664 btTypedConstraint** constraintsPtr = constraints.size() ? &constraints[0] : NULL;
665 btConstraintSolver* solver = solverParams.m_solverMt ? solverParams.m_solverMt : solverParams.m_solverPool;
666 solver->solveGroup(&collisionObjects[0],
667 collisionObjects.size(),
668 manifolds,
669 maxNumManifolds,
670 constraintsPtr,
671 constraints.size(),
672 *solverParams.m_solverInfo,
673 solverParams.m_debugDrawer,
674 solverParams.m_dispatcher);
675 }
676 else
677 {
678 initIslandPools();
679
680 //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
681 addBodiesToIslands(collisionWorld);
682 addManifoldsToIslands(dispatcher);
683 addConstraintsToIslands(constraints);
684
685 // m_activeIslands array should now contain all non-sleeping Islands, and each Island should
686 // have all the necessary bodies, manifolds and constraints.
687
688 // if we want to merge islands with small batch counts,
689 if (m_minimumSolverBatchSize > 1)
690 {
691 mergeIslands();
692 }
693 // dispatch islands to solver
694 m_islandDispatch(&m_activeIslands, solverParams);
695 }
696}
getElement
static void getElement(int arrayLen, const char *cur, const char *old, char *oldPtr, char *curData)
Definition: bFile.cpp:817
btCollisionObject.h
ACTIVE_TAG
#define ACTIVE_TAG
Definition: btCollisionObject.h:22
DISABLE_DEACTIVATION
#define DISABLE_DEACTIVATION
Definition: btCollisionObject.h:25
WANTS_DEACTIVATION
#define WANTS_DEACTIVATION
Definition: btCollisionObject.h:24
ISLAND_SLEEPING
#define ISLAND_SLEEPING
Definition: btCollisionObject.h:23
btCollisionWorld.h
size
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
btDispatcher.h
btPersistentManifold.h
btQuickprof.h
BT_PROFILE
#define BT_PROFILE(name)
Definition: btQuickprof.h:198
btScalar.h
SIMD_FORCE_INLINE
#define SIMD_FORCE_INLINE
Definition: btScalar.h:98
btAssert
#define btAssert(x)
Definition: btScalar.h:153
btSequentialImpulseConstraintSolverMt.h
btGetConstraintIslandId1
int btGetConstraintIslandId1(const btTypedConstraint *lhs)
Definition: btSimulationIslandManagerMt.cpp:68
btIsBodyInIsland
bool btIsBodyInIsland(const btSimulationIslandManagerMt::Island &island, const btCollisionObject *obj)
Definition: btSimulationIslandManagerMt.cpp:116
getIslandId
int getIslandId(const btPersistentManifold *lhs)
Definition: btSimulationIslandManagerMt.cpp:60
calcBatchCost
int calcBatchCost(int bodies, int manifolds, int constraints)
Definition: btSimulationIslandManagerMt.cpp:29
btSimulationIslandManagerMt.h
getIslandId
int getIslandId(const btPersistentManifold *lhs)
Definition: btSimulationIslandManager.cpp:167
btParallelFor
void btParallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody &body)
Definition: btThreads.cpp:412
btThreads.h
BT_OVERRIDE
#define BT_OVERRIDE
Definition: btThreads.h:26
btTypedConstraint.h
IslandBatchSizeSortPredicate
function object that routes calls to operator<
Definition: btSimulationIslandManagerMt.cpp:78
IslandBatchSizeSortPredicate::operator()
bool operator()(const btSimulationIslandManagerMt::Island *lhs, const btSimulationIslandManagerMt::Island *rhs) const
Definition: btSimulationIslandManagerMt.cpp:80
IslandBodyCapacitySortPredicate
Definition: btSimulationIslandManagerMt.cpp:89
IslandBodyCapacitySortPredicate::operator()
bool operator()(const btSimulationIslandManagerMt::Island *lhs, const btSimulationIslandManagerMt::Island *rhs) const
Definition: btSimulationIslandManagerMt.cpp:91
btAlignedObjectArray
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
Definition: btAlignedObjectArray.h:46
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:142
btAlignedObjectArray::resize
void resize(int newsize, const T &fillData=T())
Definition: btAlignedObjectArray.h:203
btAlignedObjectArray::quickSort
void quickSort(const L &CompareFunc)
Definition: btAlignedObjectArray.h:341
btAlignedObjectArray::push_back
void push_back(const T &_Val)
Definition: btAlignedObjectArray.h:257
btAlignedObjectArray::capacity
int capacity() const
return the pre-allocated (reserved) elements, this is at least as large as the total number of elemen...
Definition: btAlignedObjectArray.h:275
btAlignedObjectArray::reserve
void reserve(int _Count)
Definition: btAlignedObjectArray.h:280
btAlignedObjectArray::pop_back
void pop_back()
Definition: btAlignedObjectArray.h:185
btCollisionObject
btCollisionObject can be used to manage collision detection objects.
Definition: btCollisionObject.h:51
btCollisionObject::hasContactResponse
bool hasContactResponse() const
Definition: btCollisionObject.h:212
btCollisionObject::isActive
bool isActive() const
Definition: btCollisionObject.h:306
btCollisionObject::activate
void activate(bool forceActivation=false) const
Definition: btCollisionObject.cpp:72
btCollisionObject::setActivationState
void setActivationState(int newState) const
Definition: btCollisionObject.cpp:61
btCollisionObject::isKinematicObject
bool isKinematicObject() const
Definition: btCollisionObject.h:202
btCollisionObject::getIslandTag
int getIslandTag() const
Definition: btCollisionObject.h:448
btCollisionObject::setDeactivationTime
void setDeactivationTime(btScalar time)
Definition: btCollisionObject.h:293
btCollisionObject::getActivationState
int getActivationState() const
Definition: btCollisionObject.h:289
btCollisionWorld
CollisionWorld is interface and container for the collision detection.
Definition: btCollisionWorld.h:86
btCollisionWorld::getCollisionObjectArray
btCollisionObjectArray & getCollisionObjectArray()
Definition: btCollisionWorld.h:476
btConstraintSolver
Definition: btConstraintSolver.h:42
btConstraintSolver::solveGroup
virtual btScalar solveGroup(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifold, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &info, class btIDebugDraw *debugDrawer, btDispatcher *dispatcher)=0
solve a group of constraints
btDispatcher
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:77
btDispatcher::getNumManifolds
virtual int getNumManifolds() const =0
btDispatcher::getManifoldByIndexInternal
virtual btPersistentManifold * getManifoldByIndexInternal(int index)=0
btDispatcher::needsResponse
virtual bool needsResponse(const btCollisionObject *body0, const btCollisionObject *body1)=0
btDispatcher::getInternalManifoldPointer
virtual btPersistentManifold ** getInternalManifoldPointer()=0
btIParallelForBody
Definition: btThreads.h:102
btPersistentManifold
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
Definition: btPersistentManifold.h:65
btPersistentManifold::getBody0
const btCollisionObject * getBody0() const
Definition: btPersistentManifold.h:105
btPersistentManifold::getBody1
const btCollisionObject * getBody1() const
Definition: btPersistentManifold.h:106
btSequentialImpulseConstraintSolverMt::s_minimumContactManifoldsForBatching
static int s_minimumContactManifoldsForBatching
Definition: btSequentialImpulseConstraintSolverMt.h:89
btSimulationIslandManagerMt::m_allocatedIslands
btAlignedObjectArray< Island * > m_allocatedIslands
Definition: btSimulationIslandManagerMt.h:65
btSimulationIslandManagerMt::addBodiesToIslands
virtual void addBodiesToIslands(btCollisionWorld *collisionWorld)
Definition: btSimulationIslandManagerMt.cpp:362
btSimulationIslandManagerMt::m_batchIsland
Island * m_batchIsland
Definition: btSimulationIslandManagerMt.h:69
btSimulationIslandManagerMt::buildAndProcessIslands
virtual void buildAndProcessIslands(btDispatcher *dispatcher, btCollisionWorld *collisionWorld, btAlignedObjectArray< btTypedConstraint * > &constraints, const SolverParams &solverParams)
Definition: btSimulationIslandManagerMt.cpp:625
btSimulationIslandManagerMt::initIslandPools
virtual void initIslandPools()
Definition: btSimulationIslandManagerMt.cpp:128
btSimulationIslandManagerMt::getIsland
Island * getIsland(int id)
Definition: btSimulationIslandManagerMt.cpp:172
btSimulationIslandManagerMt::m_batchIslandMinBodyCount
int m_batchIslandMinBodyCount
Definition: btSimulationIslandManagerMt.h:71
btSimulationIslandManagerMt::allocateIsland
virtual Island * allocateIsland(int id, int numBodies)
Definition: btSimulationIslandManagerMt.cpp:193
btSimulationIslandManagerMt::m_freeIslands
btAlignedObjectArray< Island * > m_freeIslands
Definition: btSimulationIslandManagerMt.h:67
btSimulationIslandManagerMt::~btSimulationIslandManagerMt
virtual ~btSimulationIslandManagerMt()
Definition: btSimulationIslandManagerMt.cpp:49
btSimulationIslandManagerMt::m_lookupIslandFromId
btAlignedObjectArray< Island * > m_lookupIslandFromId
Definition: btSimulationIslandManagerMt.h:68
btSimulationIslandManagerMt::addManifoldsToIslands
virtual void addManifoldsToIslands(btDispatcher *dispatcher)
Definition: btSimulationIslandManagerMt.cpp:407
btSimulationIslandManagerMt::m_minimumSolverBatchSize
int m_minimumSolverBatchSize
Definition: btSimulationIslandManagerMt.h:70
btSimulationIslandManagerMt::addConstraintsToIslands
virtual void addConstraintsToIslands(btAlignedObjectArray< btTypedConstraint * > &constraints)
Definition: btSimulationIslandManagerMt.cpp:448
btSimulationIslandManagerMt::m_islandDispatch
IslandDispatchFunc m_islandDispatch
Definition: btSimulationIslandManagerMt.h:72
btSimulationIslandManagerMt::m_activeIslands
btAlignedObjectArray< Island * > m_activeIslands
Definition: btSimulationIslandManagerMt.h:66
btSimulationIslandManagerMt::parallelIslandDispatch
static void parallelIslandDispatch(btAlignedObjectArray< Island * > *islandsPtr, const SolverParams &solverParams)
Definition: btSimulationIslandManagerMt.cpp:576
btSimulationIslandManagerMt::solveIsland
static void solveIsland(btConstraintSolver *solver, Island &island, const SolverParams &solverParams)
Definition: btSimulationIslandManagerMt.cpp:528
btSimulationIslandManagerMt::serialIslandDispatch
static void serialIslandDispatch(btAlignedObjectArray< Island * > *islandsPtr, const SolverParams &solverParams)
Definition: btSimulationIslandManagerMt.cpp:543
btSimulationIslandManagerMt::btSimulationIslandManagerMt
btSimulationIslandManagerMt()
Definition: btSimulationIslandManagerMt.cpp:41
btSimulationIslandManagerMt::mergeIslands
virtual void mergeIslands()
Definition: btSimulationIslandManagerMt.cpp:467
btSimulationIslandManagerMt::buildIslands
virtual void buildIslands(btDispatcher *dispatcher, btCollisionWorld *colWorld)
Definition: btSimulationIslandManagerMt.cpp:264
btSimulationIslandManager::getUnionFind
btUnionFind & getUnionFind()
Definition: btSimulationIslandManager.h:45
btSimulationIslandManager::getSplitIslands
bool getSplitIslands()
Definition: btSimulationIslandManager.h:65
btTypedConstraint
TypedConstraint is the baseclass for Bullet constraints and vehicles.
Definition: btTypedConstraint.h:76
btTypedConstraint::isEnabled
bool isEnabled() const
Definition: btTypedConstraint.h:201
btTypedConstraint::getRigidBodyA
const btRigidBody & getRigidBodyA() const
Definition: btTypedConstraint.h:214
btTypedConstraint::getRigidBodyB
const btRigidBody & getRigidBodyB() const
Definition: btTypedConstraint.h:218
btUnionFind::getNumElements
int getNumElements() const
Definition: btUnionFind.h:50
btUnionFind::getElement
btElement & getElement(int index)
Definition: btUnionFind.h:59
btUnionFind::sortIslands
void sortIslands()
this is a special operation, destroying the content of btUnionFind.
Definition: btUnionFind.cpp:58
UpdateIslandDispatcher
Definition: btSimulationIslandManagerMt.cpp:556
UpdateIslandDispatcher::UpdateIslandDispatcher
UpdateIslandDispatcher(btAlignedObjectArray< btSimulationIslandManagerMt::Island * > &islandsPtr, const btSimulationIslandManagerMt::SolverParams &solverParams)
Definition: btSimulationIslandManagerMt.cpp:560
UpdateIslandDispatcher::forLoop
void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
Definition: btSimulationIslandManagerMt.cpp:565
UpdateIslandDispatcher::m_islandsPtr
btAlignedObjectArray< btSimulationIslandManagerMt::Island * > & m_islandsPtr
Definition: btSimulationIslandManagerMt.cpp:557
UpdateIslandDispatcher::m_solverParams
const btSimulationIslandManagerMt::SolverParams & m_solverParams
Definition: btSimulationIslandManagerMt.cpp:558
btElement::m_id
int m_id
Definition: btUnionFind.h:28
btElement::m_sz
int m_sz
Definition: btUnionFind.h:29
btSimulationIslandManagerMt::Island
Definition: btSimulationIslandManagerMt.h:39
btSimulationIslandManagerMt::Island::isSleeping
bool isSleeping
Definition: btSimulationIslandManagerMt.h:46
btSimulationIslandManagerMt::Island::constraintArray
btAlignedObjectArray< btTypedConstraint * > constraintArray
Definition: btSimulationIslandManagerMt.h:44
btSimulationIslandManagerMt::Island::append
void append(const Island &other)
Definition: btSimulationIslandManagerMt.cpp:97
btSimulationIslandManagerMt::Island::id
int id
Definition: btSimulationIslandManagerMt.h:45
btSimulationIslandManagerMt::Island::bodyArray
btAlignedObjectArray< btCollisionObject * > bodyArray
Definition: btSimulationIslandManagerMt.h:42
btSimulationIslandManagerMt::Island::manifoldArray
btAlignedObjectArray< btPersistentManifold * > manifoldArray
Definition: btSimulationIslandManagerMt.h:43
btSimulationIslandManagerMt::SolverParams
Definition: btSimulationIslandManagerMt.h:51
btSimulationIslandManagerMt::SolverParams::m_solverInfo
btContactSolverInfo * m_solverInfo
Definition: btSimulationIslandManagerMt.h:54
btSimulationIslandManagerMt::SolverParams::m_dispatcher
btDispatcher * m_dispatcher
Definition: btSimulationIslandManagerMt.h:56
btSimulationIslandManagerMt::SolverParams::m_solverPool
btConstraintSolver * m_solverPool
Definition: btSimulationIslandManagerMt.h:52
btSimulationIslandManagerMt::SolverParams::m_solverMt
btConstraintSolver * m_solverMt
Definition: btSimulationIslandManagerMt.h:53
btSimulationIslandManagerMt::SolverParams::m_debugDrawer
btIDebugDraw * m_debugDrawer
Definition: btSimulationIslandManagerMt.h:55