2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
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.
3
17
#include "LinearMath/btScalar.h"
7
21
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
8
22
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
11
25
#include "LinearMath/btQuickprof.h"
13
27
btSimulationIslandManager::btSimulationIslandManager()
28
void btSimulationIslandManager::findUnions(btDispatcher* dispatcher)
42
void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btCollisionWorld* colWorld)
32
for (int i=0;i<dispatcher->getNumManifolds();i++)
46
btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
48
for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++)
34
const btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
35
//static objects (invmass btScalar(0.)) don't merge !
37
const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>(manifold->getBody0());
38
const btCollisionObject* colObj1 = static_cast<const btCollisionObject*>(manifold->getBody1());
50
const btBroadphasePair& collisionPair = pairPtr[i];
51
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
52
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
40
54
if (((colObj0) && ((colObj0)->mergesSimulationIslands())) &&
41
55
((colObj1) && ((colObj1)->mergesSimulationIslands())))
91
105
for (i=0;i<colWorld->getCollisionObjectArray().size();i++)
93
107
btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i];
94
if (collisionObject->mergesSimulationIslands())
108
if (!collisionObject->isStaticOrKinematicObject())
96
110
collisionObject->setIslandTag( m_unionFind.find(index) );
97
111
collisionObject->setCompanionId(-1);
136
// todo: this is random access, it can be walked 'cache friendly'!
138
void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback)
146
void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects)
145
int maxNumManifolds = dispatcher->getNumManifolds();
146
btCollisionDispatcher* colDis = (btCollisionDispatcher*)dispatcher;
147
btPersistentManifold** manifold = colDis->getInternalManifoldPointer();
148
callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, 0);
154
BEGIN_PROFILE("islandUnionFindAndHeapSort");
149
BT_PROFILE("islandUnionFindAndQuickSort");
151
m_islandmanifold.resize(0);
156
153
//we are going to sort the unionfind array, and store the element id in the size
157
154
//afterwards, we clean unionfind, to make sure no-one uses it anymore
183
180
btCollisionObject* colObj0 = collisionObjects[i];
184
181
if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
186
printf("error in island management\n");
183
// printf("error in island management\n");
189
186
assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
210
207
btCollisionObject* colObj0 = collisionObjects[i];
211
208
if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
213
printf("error in island management\n");
210
// printf("error in island management\n");
216
213
assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
231
228
btCollisionObject* colObj0 = collisionObjects[i];
232
229
if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
234
printf("error in island management\n");
231
// printf("error in island management\n");
237
234
assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
250
btAlignedObjectArray<btPersistentManifold*> islandmanifold;
252
249
int maxNumManifolds = dispatcher->getNumManifolds();
253
islandmanifold.reserve(maxNumManifolds);
251
#define SPLIT_ISLANDS 1
255
#endif //SPLIT_ISLANDS
255
258
for (i=0;i<maxNumManifolds ;i++)
257
260
btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
267
270
//kinematic objects don't merge islands, but wake up all connected objects
268
if (colObj0->isStaticOrKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
271
if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
270
273
colObj1->activate();
272
if (colObj1->isStaticOrKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
275
if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
274
277
colObj0->activate();
277
//filtering for response
280
// //filtering for response
278
281
if (dispatcher->needsResponse(colObj0,colObj1))
279
islandmanifold.push_back(manifold);
282
m_islandmanifold.push_back(manifold);
283
#endif //SPLIT_ISLANDS
283
int numManifolds = int (islandmanifold.size());
291
// todo: this is random access, it can be walked 'cache friendly'!
293
void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback)
296
buildIslands(dispatcher,collisionObjects);
298
int endIslandIndex=1;
299
int startIslandIndex;
300
int numElem = getUnionFind().getNumElements();
302
BT_PROFILE("processIslands");
304
#ifndef SPLIT_ISLANDS
305
btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer();
307
callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1);
285
309
// Sort manifolds, based on islands
286
310
// Sort the vector using predicate and std::sort
287
311
//std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);
313
int numManifolds = int (m_islandmanifold.size());
289
315
//we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
290
islandmanifold.heapSort(btPersistentManifoldSortPredicate());
316
m_islandmanifold.quickSort(btPersistentManifoldSortPredicate());
292
318
//now process all active islands (sets of manifolds for now)
299
END_PROFILE("islandUnionFindAndHeapSort");
301
btAlignedObjectArray<btCollisionObject*> islandBodies;
327
// printf("Start Islands\n");
304
329
//traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
305
330
for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
314
339
int i = getUnionFind().getElement(endIslandIndex).m_sz;
315
340
btCollisionObject* colObj0 = collisionObjects[i];
316
islandBodies.push_back(colObj0);
341
m_islandBodies.push_back(colObj0);
317
342
if (!colObj0->isActive())
318
343
islandSleeping = true;
326
351
if (startManifoldIndex<numManifolds)
328
int curIslandId = getIslandId(islandmanifold[startManifoldIndex]);
353
int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]);
329
354
if (curIslandId == islandId)
331
startManifold = &islandmanifold[startManifoldIndex];
356
startManifold = &m_islandmanifold[startManifoldIndex];
333
for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(islandmanifold[endManifoldIndex]));endManifoldIndex++)
358
for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++)
343
368
if (!islandSleeping)
345
callback->ProcessIsland(&islandBodies[0],islandBodies.size(),startManifold,numIslandManifolds, islandId);
370
callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId);
371
// printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
348
374
if (numIslandManifolds)