Bullet Collision Detection & Physics Library
btMultiSapBroadphase.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
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:
10 
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.
14 */
15 
16 #include "btMultiSapBroadphase.h"
17 
18 #include "btSimpleBroadphase.h"
19 #include "LinearMath/btAabbUtil2.h"
20 #include "btQuantizedBvh.h"
21 
23 
25 extern int gOverlappingPairs;
26 
27 /*
28 class btMultiSapSortedOverlappingPairCache : public btSortedOverlappingPairCache
29 {
30 public:
31 
32  virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
33  {
34  return btSortedOverlappingPairCache::addOverlappingPair((btBroadphaseProxy*)proxy0->m_multiSapParentProxy,(btBroadphaseProxy*)proxy1->m_multiSapParentProxy);
35  }
36 };
37 
38 */
39 
41 :m_overlappingPairs(pairCache),
42 m_optimizedAabbTree(0),
43 m_ownsPairCache(false),
44 m_invalidPair(0)
45 {
46  if (!m_overlappingPairs)
47  {
48  m_ownsPairCache = true;
49  void* mem = btAlignedAlloc(sizeof(btSortedOverlappingPairCache),16);
51  }
52 
53  struct btMultiSapOverlapFilterCallback : public btOverlapFilterCallback
54  {
55  virtual ~btMultiSapOverlapFilterCallback()
56  {}
57  // return true when pairs need collision
58  virtual bool needBroadphaseCollision(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1) const
59  {
60  btBroadphaseProxy* multiProxy0 = (btBroadphaseProxy*)childProxy0->m_multiSapParentProxy;
61  btBroadphaseProxy* multiProxy1 = (btBroadphaseProxy*)childProxy1->m_multiSapParentProxy;
62 
63  bool collides = (multiProxy0->m_collisionFilterGroup & multiProxy1->m_collisionFilterMask) != 0;
64  collides = collides && (multiProxy1->m_collisionFilterGroup & multiProxy0->m_collisionFilterMask);
65 
66  return collides;
67  }
68  };
69 
70  void* mem = btAlignedAlloc(sizeof(btMultiSapOverlapFilterCallback),16);
71  m_filterCallback = new (mem)btMultiSapOverlapFilterCallback();
72 
74 // mem = btAlignedAlloc(sizeof(btSimpleBroadphase),16);
75 // m_simpleBroadphase = new (mem) btSimpleBroadphase(maxProxies,m_overlappingPairs);
76 }
77 
79 {
80  if (m_ownsPairCache)
81  {
84  }
85 }
86 
87 
88 void btMultiSapBroadphase::buildTree(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax)
89 {
91  m_optimizedAabbTree->setQuantizationValues(bvhAabbMin,bvhAabbMax);
93  for (int i=0;i<m_sapBroadphases.size();i++)
94  {
95  btQuantizedBvhNode node;
96  btVector3 aabbMin,aabbMax;
97  m_sapBroadphases[i]->getBroadphaseAabb(aabbMin,aabbMax);
98  m_optimizedAabbTree->quantize(&node.m_quantizedAabbMin[0],aabbMin,0);
99  m_optimizedAabbTree->quantize(&node.m_quantizedAabbMax[0],aabbMax,1);
100  int partId = 0;
101  node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | i;
102  nodes.push_back(node);
103  }
105 }
106 
107 btBroadphaseProxy* btMultiSapBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* /*ignoreMe*/)
108 {
109  //void* ignoreMe -> we could think of recursive multi-sap, if someone is interested
110 
111  void* mem = btAlignedAlloc(sizeof(btMultiSapProxy),16);
112  btMultiSapProxy* proxy = new (mem)btMultiSapProxy(aabbMin, aabbMax,shapeType,userPtr, collisionFilterGroup,collisionFilterMask);
113  m_multiSapProxies.push_back(proxy);
114 
116  setAabb(proxy,aabbMin,aabbMax,dispatcher);
117  return proxy;
118 }
119 
121 {
123  btAssert(0);
124 
125 }
126 
127 
129 {
130  void* mem = btAlignedAlloc(sizeof(btBridgeProxy),16);
131  btBridgeProxy* bridgeProxyRef = new(mem) btBridgeProxy;
132  bridgeProxyRef->m_childProxy = childProxy;
133  bridgeProxyRef->m_childBroadphase = childBroadphase;
134  parentMultiSapProxy->m_bridgeProxies.push_back(bridgeProxyRef);
135 }
136 
137 
138 bool boxIsContainedWithinBox(const btVector3& amin,const btVector3& amax,const btVector3& bmin,const btVector3& bmax);
139 bool boxIsContainedWithinBox(const btVector3& amin,const btVector3& amax,const btVector3& bmin,const btVector3& bmax)
140 {
141 return
142 amin.getX() >= bmin.getX() && amax.getX() <= bmax.getX() &&
143 amin.getY() >= bmin.getY() && amax.getY() <= bmax.getY() &&
144 amin.getZ() >= bmin.getZ() && amax.getZ() <= bmax.getZ();
145 }
146 
147 
148 
149 
150 
151 
153 {
154  btMultiSapProxy* multiProxy = static_cast<btMultiSapProxy*>(proxy);
155  aabbMin = multiProxy->m_aabbMin;
156  aabbMax = multiProxy->m_aabbMax;
157 }
158 
159 void btMultiSapBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax)
160 {
161  for (int i=0;i<m_multiSapProxies.size();i++)
162  {
163  rayCallback.process(m_multiSapProxies[i]);
164  }
165 }
166 
167 
168 //#include <stdio.h>
169 
170 void btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)
171 {
172  btMultiSapProxy* multiProxy = static_cast<btMultiSapProxy*>(proxy);
173  multiProxy->m_aabbMin = aabbMin;
174  multiProxy->m_aabbMax = aabbMax;
175 
176 
177 // bool fullyContained = false;
178 // bool alreadyInSimple = false;
179 
180 
181 
182 
183  struct MyNodeOverlapCallback : public btNodeOverlapCallback
184  {
185  btMultiSapBroadphase* m_multiSap;
186  btMultiSapProxy* m_multiProxy;
187  btDispatcher* m_dispatcher;
188 
189  MyNodeOverlapCallback(btMultiSapBroadphase* multiSap,btMultiSapProxy* multiProxy,btDispatcher* dispatcher)
190  :m_multiSap(multiSap),
191  m_multiProxy(multiProxy),
192  m_dispatcher(dispatcher)
193  {
194 
195  }
196 
197  virtual void processNode(int /*nodeSubPart*/, int broadphaseIndex)
198  {
199  btBroadphaseInterface* childBroadphase = m_multiSap->getBroadphaseArray()[broadphaseIndex];
200 
201  int containingBroadphaseIndex = -1;
202  //already found?
203  for (int i=0;i<m_multiProxy->m_bridgeProxies.size();i++)
204  {
205 
206  if (m_multiProxy->m_bridgeProxies[i]->m_childBroadphase == childBroadphase)
207  {
208  containingBroadphaseIndex = i;
209  break;
210  }
211  }
212  if (containingBroadphaseIndex<0)
213  {
214  //add it
215  btBroadphaseProxy* childProxy = childBroadphase->createProxy(m_multiProxy->m_aabbMin,m_multiProxy->m_aabbMax,m_multiProxy->m_shapeType,m_multiProxy->m_clientObject,m_multiProxy->m_collisionFilterGroup,m_multiProxy->m_collisionFilterMask, m_dispatcher,m_multiProxy);
216  m_multiSap->addToChildBroadphase(m_multiProxy,childProxy,childBroadphase);
217 
218  }
219  }
220  };
221 
222  MyNodeOverlapCallback myNodeCallback(this,multiProxy,dispatcher);
223 
224 
225 
226 
228  m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
229 
230  int i;
231 
232  for ( i=0;i<multiProxy->m_bridgeProxies.size();i++)
233  {
234  btVector3 worldAabbMin,worldAabbMax;
235  multiProxy->m_bridgeProxies[i]->m_childBroadphase->getBroadphaseAabb(worldAabbMin,worldAabbMax);
236  bool overlapsBroadphase = TestAabbAgainstAabb2(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax);
237  if (!overlapsBroadphase)
238  {
239  //remove it now
240  btBridgeProxy* bridgeProxy = multiProxy->m_bridgeProxies[i];
241 
242  btBroadphaseProxy* childProxy = bridgeProxy->m_childProxy;
243  bridgeProxy->m_childBroadphase->destroyProxy(childProxy,dispatcher);
244 
245  multiProxy->m_bridgeProxies.swap( i,multiProxy->m_bridgeProxies.size()-1);
246  multiProxy->m_bridgeProxies.pop_back();
247 
248  }
249  }
250 
251 
252  /*
253 
254  if (1)
255  {
256 
257  //find broadphase that contain this multiProxy
258  int numChildBroadphases = getBroadphaseArray().size();
259  for (int i=0;i<numChildBroadphases;i++)
260  {
261  btBroadphaseInterface* childBroadphase = getBroadphaseArray()[i];
262  btVector3 worldAabbMin,worldAabbMax;
263  childBroadphase->getBroadphaseAabb(worldAabbMin,worldAabbMax);
264  bool overlapsBroadphase = TestAabbAgainstAabb2(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax);
265 
266  // fullyContained = fullyContained || boxIsContainedWithinBox(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax);
267  int containingBroadphaseIndex = -1;
268 
269  //if already contains this
270 
271  for (int i=0;i<multiProxy->m_bridgeProxies.size();i++)
272  {
273  if (multiProxy->m_bridgeProxies[i]->m_childBroadphase == childBroadphase)
274  {
275  containingBroadphaseIndex = i;
276  }
277  alreadyInSimple = alreadyInSimple || (multiProxy->m_bridgeProxies[i]->m_childBroadphase == m_simpleBroadphase);
278  }
279 
280  if (overlapsBroadphase)
281  {
282  if (containingBroadphaseIndex<0)
283  {
284  btBroadphaseProxy* childProxy = childBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher);
285  childProxy->m_multiSapParentProxy = multiProxy;
286  addToChildBroadphase(multiProxy,childProxy,childBroadphase);
287  }
288  } else
289  {
290  if (containingBroadphaseIndex>=0)
291  {
292  //remove
293  btBridgeProxy* bridgeProxy = multiProxy->m_bridgeProxies[containingBroadphaseIndex];
294 
295  btBroadphaseProxy* childProxy = bridgeProxy->m_childProxy;
296  bridgeProxy->m_childBroadphase->destroyProxy(childProxy,dispatcher);
297 
298  multiProxy->m_bridgeProxies.swap( containingBroadphaseIndex,multiProxy->m_bridgeProxies.size()-1);
299  multiProxy->m_bridgeProxies.pop_back();
300  }
301  }
302  }
303 
304 
307  if (0)//!multiProxy->m_bridgeProxies.size())
308  {
311  btBroadphaseProxy* childProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher);
312  childProxy->m_multiSapParentProxy = multiProxy;
313  addToChildBroadphase(multiProxy,childProxy,m_simpleBroadphase);
314  }
315  }
316 
317  if (!multiProxy->m_bridgeProxies.size())
318  {
321  btBroadphaseProxy* childProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher);
322  childProxy->m_multiSapParentProxy = multiProxy;
323  addToChildBroadphase(multiProxy,childProxy,m_simpleBroadphase);
324  }
325 */
326 
327 
328  //update
329  for ( i=0;i<multiProxy->m_bridgeProxies.size();i++)
330  {
331  btBridgeProxy* bridgeProxyRef = multiProxy->m_bridgeProxies[i];
332  bridgeProxyRef->m_childBroadphase->setAabb(bridgeProxyRef->m_childProxy,aabbMin,aabbMax,dispatcher);
333  }
334 
335 }
336 bool stopUpdating=false;
337 
338 
339 
341 {
342  public:
343 
344  bool operator() ( const btBroadphasePair& a1, const btBroadphasePair& b1 ) const
345  {
350 
351  return aProxy0 > bProxy0 ||
352  (aProxy0 == bProxy0 && aProxy1 > bProxy1) ||
353  (aProxy0 == bProxy0 && aProxy1 == bProxy1 && a1.m_algorithm > b1.m_algorithm);
354  }
355 };
356 
357 
360 {
361 
362 // m_simpleBroadphase->calculateOverlappingPairs(dispatcher);
363 
364  if (!stopUpdating && getOverlappingPairCache()->hasDeferredRemoval())
365  {
366 
368 
369  // quicksort(overlappingPairArray,0,overlappingPairArray.size());
370 
371  overlappingPairArray.quickSort(btMultiSapBroadphasePairSortPredicate());
372 
373  //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
374  // overlappingPairArray.heapSort(btMultiSapBroadphasePairSortPredicate());
375 
376  overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
377  m_invalidPair = 0;
378 
379 
380  int i;
381 
382  btBroadphasePair previousPair;
383  previousPair.m_pProxy0 = 0;
384  previousPair.m_pProxy1 = 0;
385  previousPair.m_algorithm = 0;
386 
387 
388  for (i=0;i<overlappingPairArray.size();i++)
389  {
390 
391  btBroadphasePair& pair = overlappingPairArray[i];
392 
395  btMultiSapProxy* bProxy0 = previousPair.m_pProxy0 ? (btMultiSapProxy*)previousPair.m_pProxy0->m_multiSapParentProxy : 0;
396  btMultiSapProxy* bProxy1 = previousPair.m_pProxy1 ? (btMultiSapProxy*)previousPair.m_pProxy1->m_multiSapParentProxy : 0;
397 
398  bool isDuplicate = (aProxy0 == bProxy0) && (aProxy1 == bProxy1);
399 
400  previousPair = pair;
401 
402  bool needsRemoval = false;
403 
404  if (!isDuplicate)
405  {
406  bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
407 
408  if (hasOverlap)
409  {
410  needsRemoval = false;//callback->processOverlap(pair);
411  } else
412  {
413  needsRemoval = true;
414  }
415  } else
416  {
417  //remove duplicate
418  needsRemoval = true;
419  //should have no algorithm
420  btAssert(!pair.m_algorithm);
421  }
422 
423  if (needsRemoval)
424  {
425  getOverlappingPairCache()->cleanOverlappingPair(pair,dispatcher);
426 
427  // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
428  // m_overlappingPairArray.pop_back();
429  pair.m_pProxy0 = 0;
430  pair.m_pProxy1 = 0;
431  m_invalidPair++;
433  }
434 
435  }
436 
438  #define CLEAN_INVALID_PAIRS 1
439  #ifdef CLEAN_INVALID_PAIRS
440 
441  //perform a sort, to sort 'invalid' pairs to the end
442  //overlappingPairArray.heapSort(btMultiSapBroadphasePairSortPredicate());
443  overlappingPairArray.quickSort(btMultiSapBroadphasePairSortPredicate());
444 
445  overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
446  m_invalidPair = 0;
447  #endif//CLEAN_INVALID_PAIRS
448 
449  //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
450  }
451 
452 
453 }
454 
455 
457 {
458  btMultiSapProxy* multiSapProxy0 = (btMultiSapProxy*)childProxy0->m_multiSapParentProxy;
459  btMultiSapProxy* multiSapProxy1 = (btMultiSapProxy*)childProxy1->m_multiSapParentProxy;
460 
461  return TestAabbAgainstAabb2(multiSapProxy0->m_aabbMin,multiSapProxy0->m_aabbMax,
462  multiSapProxy1->m_aabbMin,multiSapProxy1->m_aabbMax);
463 
464 }
465 
466 
468 {
469 /* printf("---------------------------------\n");
470 
471  printf("btMultiSapBroadphase.h\n");
472  printf("numHandles = %d\n",m_multiSapProxies.size());
473  //find broadphase that contain this multiProxy
474  int numChildBroadphases = getBroadphaseArray().size();
475  for (int i=0;i<numChildBroadphases;i++)
476  {
477 
478  btBroadphaseInterface* childBroadphase = getBroadphaseArray()[i];
479  childBroadphase->printStats();
480 
481  }
482  */
483 
484 }
485 
487 {
488  // not yet
489 }
QuantizedNodeArray & getLeafNodeArray()
void push_back(const T &_Val)
void setQuantizationValues(const btVector3 &bvhAabbMin, const btVector3 &bvhAabbMax, btScalar quantizationMargin=btScalar(1.0))
***************************************** expert/internal use only ************************* ...
virtual void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)=0
int gOverlappingPairs
btSapBroadphaseArray m_sapBroadphases;
class btQuantizedBvh * m_optimizedAabbTree
btOverlappingPairCache * m_overlappingPairs
void buildInternal()
buildInternal is expert use only: assumes that setQuantizationValues and LeafNodeArray are initialize...
short int m_collisionFilterGroup
#define btAssert(x)
Definition: btScalar.h:101
The btMultiSapBroadphase is a research project, not recommended to use in production.
virtual void setOverlapFilterCallback(btOverlapFilterCallback *callback)=0
bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, const btVector3 &aabbMin2, const btVector3 &aabbMax2)
conservative test for overlap between two aabbs
Definition: btAabbUtil2.h:48
bool stopUpdating
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:565
The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
#define MAX_NUM_PARTS_IN_BITS
int size() const
return the number of elements in the array
virtual btBroadphasePairArray & getOverlappingPairArray()=0
virtual void resetPool(btDispatcher *dispatcher)
reset broadphase internal structures, to ensure determinism/reproducability
btOverlapFilterCallback * m_filterCallback
bool testAabbOverlap(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
virtual btBroadphaseProxy * createProxy(const btVector3 &aabbMin, const btVector3 &aabbMax, int shapeType, void *userPtr, short int collisionFilterGroup, short int collisionFilterMask, btDispatcher *dispatcher, void *multiSapProxy)=0
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
#define btAlignedFree(ptr)
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
void addToChildBroadphase(btMultiSapProxy *parentMultiSapProxy, btBroadphaseProxy *childProxy, btBroadphaseInterface *childBroadphase)
btSortedOverlappingPairCache maintains the objects with overlapping AABB Typically managed by the Bro...
virtual btOverlappingPairCache * getOverlappingPairCache()
void quantize(unsigned short *out, const btVector3 &point, int isMax) const
virtual btBroadphaseProxy * createProxy(const btVector3 &aabbMin, const btVector3 &aabbMax, int shapeType, void *userPtr, short int collisionFilterGroup, short int collisionFilterMask, btDispatcher *dispatcher, void *multiSapProxy)
btMultiSapBroadphase(int maxProxies=16384, btOverlappingPairCache *pairCache=0)
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs...
btQuantizedBvhNode is a compressed aabb node, 16 bytes.
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
btBroadphaseProxy * m_pProxy1
btCollisionAlgorithm * m_algorithm
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
virtual bool process(const btBroadphaseProxy *proxy)=0
btBroadphaseProxy * m_pProxy0
btSapBroadphaseArray m_sapBroadphases
btAlignedObjectArray< btMultiSapProxy * > m_multiSapProxies
btBroadphaseInterface * m_childBroadphase
void resize(int newsize, const T &fillData=T())
btAlignedObjectArray< btBridgeProxy * > m_bridgeProxies
array with all the entries that this proxy belongs to
virtual void getAabb(btBroadphaseProxy *proxy, btVector3 &aabbMin, btVector3 &aabbMax) const
The btQuantizedBvh class stores an AABB tree that can be quickly traversed on CPU and Cell SPU...
unsigned short int m_quantizedAabbMin[3]
bool boxIsContainedWithinBox(const btVector3 &amin, const btVector3 &amax, const btVector3 &bmin, const btVector3 &bmax)
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)=0
#define btAlignedAlloc(size, alignment)
short int m_collisionFilterMask
bool operator()(const btBroadphasePair &a1, const btBroadphasePair &b1) const
unsigned short int m_quantizedAabbMax[3]
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
virtual void rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, btBroadphaseRayCallback &rayCallback, const btVector3 &aabbMin=btVector3(0, 0, 0), const btVector3 &aabbMax=btVector3(0, 0, 0))
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:69
void buildTree(const btVector3 &bvhAabbMin, const btVector3 &bvhAabbMax)
void reportAabbOverlappingNodex(btNodeOverlapCallback *nodeCallback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
***************************************** expert/internal use only ************************* ...
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
virtual void calculateOverlappingPairs(btDispatcher *dispatcher)
calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during th...
void quickSort(const L &CompareFunc)
The btBroadphasePair class contains a pair of aabb-overlapping objects.