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 ///btDbvtBroadphase implementation by Nathanael Presson
18 #include "btDbvtBroadphase.h"
19 #include "LinearMath/btThreads.h"
20 btScalar gDbvtMargin = btScalar(0.05);
25 #if DBVT_BP_PROFILE || DBVT_BP_ENABLE_BENCHMARK
32 __forceinline ProfileScope(btClock& clock, unsigned long& value) : m_clock(&clock), m_value(&value), m_base(clock.getTimeMicroseconds())
35 __forceinline ~ProfileScope()
37 (*m_value) += m_clock->getTimeMicroseconds() - m_base;
40 unsigned long* m_value;
43 #define SPC(_value_) ProfileScope spc_scope(m_clock, _value_)
54 static inline void listappend(T* item, T*& list)
57 item->links[1] = list;
58 if (list) list->links[0] = item;
64 static inline void listremove(T* item, T*& list)
67 item->links[0]->links[1] = item->links[1];
69 list = item->links[1];
70 if (item->links[1]) item->links[1]->links[0] = item->links[0];
75 static inline int listcount(T* root)
81 root = root->links[1];
88 static inline void clear(T& value)
90 static const struct ZeroDummy : T
101 struct btDbvtTreeCollider : btDbvt::ICollide
103 btDbvtBroadphase* pbp;
105 btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}
106 void Process(const btDbvtNode* na, const btDbvtNode* nb)
110 btDbvtProxy* pa = (btDbvtProxy*)na->data;
111 btDbvtProxy* pb = (btDbvtProxy*)nb->data;
112 #if DBVT_BP_SORTPAIRS
113 if (pa->m_uniqueId > pb->m_uniqueId)
116 pbp->m_paircache->addOverlappingPair(pa, pb);
120 void Process(const btDbvtNode* n)
122 Process(n, proxy->leaf);
131 btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache)
133 m_deferedcollide = false;
134 m_needcleanup = true;
135 m_releasepaircache = (paircache != 0) ? false : true;
146 m_paircache = paircache ? paircache : new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache), 16)) btHashedOverlappingPairCache();
150 for (int i = 0; i <= STAGECOUNT; ++i)
155 m_rayTestStacks.resize(BT_MAX_THREAD_COUNT);
157 m_rayTestStacks.resize(1);
165 btDbvtBroadphase::~btDbvtBroadphase()
167 if (m_releasepaircache)
169 m_paircache->~btOverlappingPairCache();
170 btAlignedFree(m_paircache);
175 btBroadphaseProxy* btDbvtBroadphase::createProxy(const btVector3& aabbMin,
176 const btVector3& aabbMax,
179 int collisionFilterGroup,
180 int collisionFilterMask,
181 btDispatcher* /*dispatcher*/)
183 btDbvtProxy* proxy = new (btAlignedAlloc(sizeof(btDbvtProxy), 16)) btDbvtProxy(aabbMin, aabbMax, userPtr,
184 collisionFilterGroup,
185 collisionFilterMask);
187 btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin, aabbMax);
189 //bproxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
190 proxy->stage = m_stageCurrent;
191 proxy->m_uniqueId = ++m_gid;
192 proxy->leaf = m_sets[0].insert(aabb, proxy);
193 listappend(proxy, m_stageRoots[m_stageCurrent]);
194 if (!m_deferedcollide)
196 btDbvtTreeCollider collider(this);
197 collider.proxy = proxy;
198 m_sets[0].collideTV(m_sets[0].m_root, aabb, collider);
199 m_sets[1].collideTV(m_sets[1].m_root, aabb, collider);
205 void btDbvtBroadphase::destroyProxy(btBroadphaseProxy* absproxy,
206 btDispatcher* dispatcher)
208 btDbvtProxy* proxy = (btDbvtProxy*)absproxy;
209 if (proxy->stage == STAGECOUNT)
210 m_sets[1].remove(proxy->leaf);
212 m_sets[0].remove(proxy->leaf);
213 listremove(proxy, m_stageRoots[proxy->stage]);
214 m_paircache->removeOverlappingPairsContainingProxy(proxy, dispatcher);
215 btAlignedFree(proxy);
216 m_needcleanup = true;
219 void btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy, btVector3& aabbMin, btVector3& aabbMax) const
221 btDbvtProxy* proxy = (btDbvtProxy*)absproxy;
222 aabbMin = proxy->m_aabbMin;
223 aabbMax = proxy->m_aabbMax;
226 struct BroadphaseRayTester : btDbvt::ICollide
228 btBroadphaseRayCallback& m_rayCallback;
229 BroadphaseRayTester(btBroadphaseRayCallback& orgCallback)
230 : m_rayCallback(orgCallback)
233 void Process(const btDbvtNode* leaf)
235 btDbvtProxy* proxy = (btDbvtProxy*)leaf->data;
236 m_rayCallback.process(proxy);
240 void btDbvtBroadphase::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin, const btVector3& aabbMax)
242 BroadphaseRayTester callback(rayCallback);
243 btAlignedObjectArray<const btDbvtNode*>* stack = &m_rayTestStacks[0];
245 // for this function to be threadsafe, each thread must have a separate copy
246 // of this stack. This could be thread-local static to avoid dynamic allocations,
247 // instead of just a local.
248 int threadIndex = btGetCurrentThreadIndex();
249 btAlignedObjectArray<const btDbvtNode*> localStack;
250 //todo(erwincoumans, "why do we get tsan issue here?")
251 if (0)//threadIndex < m_rayTestStacks.size())
252 //if (threadIndex < m_rayTestStacks.size())
254 // use per-thread preallocated stack if possible to avoid dynamic allocations
255 stack = &m_rayTestStacks[threadIndex];
263 m_sets[0].rayTestInternal(m_sets[0].m_root,
266 rayCallback.m_rayDirectionInverse,
268 rayCallback.m_lambda_max,
274 m_sets[1].rayTestInternal(m_sets[1].m_root,
277 rayCallback.m_rayDirectionInverse,
279 rayCallback.m_lambda_max,
286 struct BroadphaseAabbTester : btDbvt::ICollide
288 btBroadphaseAabbCallback& m_aabbCallback;
289 BroadphaseAabbTester(btBroadphaseAabbCallback& orgCallback)
290 : m_aabbCallback(orgCallback)
293 void Process(const btDbvtNode* leaf)
295 btDbvtProxy* proxy = (btDbvtProxy*)leaf->data;
296 m_aabbCallback.process(proxy);
300 void btDbvtBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& aabbCallback)
302 BroadphaseAabbTester callback(aabbCallback);
304 const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds = btDbvtVolume::FromMM(aabbMin, aabbMax);
305 //process all children, that overlap with the given AABB bounds
306 m_sets[0].collideTV(m_sets[0].m_root, bounds, callback);
307 m_sets[1].collideTV(m_sets[1].m_root, bounds, callback);
311 void btDbvtBroadphase::setAabb(btBroadphaseProxy* absproxy,
312 const btVector3& aabbMin,
313 const btVector3& aabbMax,
314 btDispatcher* /*dispatcher*/)
316 btDbvtProxy* proxy = (btDbvtProxy*)absproxy;
317 ATTRIBUTE_ALIGNED16(btDbvtVolume)
318 aabb = btDbvtVolume::FromMM(aabbMin, aabbMax);
319 #if DBVT_BP_PREVENTFALSEUPDATE
320 if (NotEqual(aabb, proxy->leaf->volume))
323 bool docollide = false;
324 if (proxy->stage == STAGECOUNT)
325 { /* fixed -> dynamic set */
326 m_sets[1].remove(proxy->leaf);
327 proxy->leaf = m_sets[0].insert(aabb, proxy);
333 if (Intersect(proxy->leaf->volume, aabb))
336 const btVector3 delta = aabbMin - proxy->m_aabbMin;
337 btVector3 velocity(((proxy->m_aabbMax - proxy->m_aabbMin) / 2) * m_prediction);
338 if (delta[0] < 0) velocity[0] = -velocity[0];
339 if (delta[1] < 0) velocity[1] = -velocity[1];
340 if (delta[2] < 0) velocity[2] = -velocity[2];
342 m_sets[0].update(proxy->leaf, aabb, velocity, gDbvtMargin)
352 m_sets[0].update(proxy->leaf, aabb);
357 listremove(proxy, m_stageRoots[proxy->stage]);
358 proxy->m_aabbMin = aabbMin;
359 proxy->m_aabbMax = aabbMax;
360 proxy->stage = m_stageCurrent;
361 listappend(proxy, m_stageRoots[m_stageCurrent]);
364 m_needcleanup = true;
365 if (!m_deferedcollide)
367 btDbvtTreeCollider collider(this);
368 m_sets[1].collideTTpersistentStack(m_sets[1].m_root, proxy->leaf, collider);
369 m_sets[0].collideTTpersistentStack(m_sets[0].m_root, proxy->leaf, collider);
376 void btDbvtBroadphase::setAabbForceUpdate(btBroadphaseProxy* absproxy,
377 const btVector3& aabbMin,
378 const btVector3& aabbMax,
379 btDispatcher* /*dispatcher*/)
381 btDbvtProxy* proxy = (btDbvtProxy*)absproxy;
382 ATTRIBUTE_ALIGNED16(btDbvtVolume)
383 aabb = btDbvtVolume::FromMM(aabbMin, aabbMax);
384 bool docollide = false;
385 if (proxy->stage == STAGECOUNT)
386 { /* fixed -> dynamic set */
387 m_sets[1].remove(proxy->leaf);
388 proxy->leaf = m_sets[0].insert(aabb, proxy);
395 m_sets[0].update(proxy->leaf, aabb);
399 listremove(proxy, m_stageRoots[proxy->stage]);
400 proxy->m_aabbMin = aabbMin;
401 proxy->m_aabbMax = aabbMax;
402 proxy->stage = m_stageCurrent;
403 listappend(proxy, m_stageRoots[m_stageCurrent]);
406 m_needcleanup = true;
407 if (!m_deferedcollide)
409 btDbvtTreeCollider collider(this);
410 m_sets[1].collideTTpersistentStack(m_sets[1].m_root, proxy->leaf, collider);
411 m_sets[0].collideTTpersistentStack(m_sets[0].m_root, proxy->leaf, collider);
417 void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
421 if (0 == (m_pid % DBVT_BP_PROFILING_RATE))
423 printf("fixed(%u) dynamics(%u) pairs(%u)\r\n", m_sets[1].m_leaves, m_sets[0].m_leaves, m_paircache->getNumOverlappingPairs());
424 unsigned int total = m_profiling.m_total;
425 if (total <= 0) total = 1;
426 printf("ddcollide: %u%% (%uus)\r\n", (50 + m_profiling.m_ddcollide * 100) / total, m_profiling.m_ddcollide / DBVT_BP_PROFILING_RATE);
427 printf("fdcollide: %u%% (%uus)\r\n", (50 + m_profiling.m_fdcollide * 100) / total, m_profiling.m_fdcollide / DBVT_BP_PROFILING_RATE);
428 printf("cleanup: %u%% (%uus)\r\n", (50 + m_profiling.m_cleanup * 100) / total, m_profiling.m_cleanup / DBVT_BP_PROFILING_RATE);
429 printf("total: %uus\r\n", total / DBVT_BP_PROFILING_RATE);
430 const unsigned long sum = m_profiling.m_ddcollide +
431 m_profiling.m_fdcollide +
432 m_profiling.m_cleanup;
433 printf("leaked: %u%% (%uus)\r\n", 100 - ((50 + sum * 100) / total), (total - sum) / DBVT_BP_PROFILING_RATE);
434 printf("job counts: %u%%\r\n", (m_profiling.m_jobcount * 100) / ((m_sets[0].m_leaves + m_sets[1].m_leaves) * DBVT_BP_PROFILING_RATE));
440 performDeferredRemoval(dispatcher);
443 void btDbvtBroadphase::performDeferredRemoval(btDispatcher* dispatcher)
445 if (m_paircache->hasDeferredRemoval())
447 btBroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray();
449 //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
450 overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
456 btBroadphasePair previousPair;
457 previousPair.m_pProxy0 = 0;
458 previousPair.m_pProxy1 = 0;
459 previousPair.m_algorithm = 0;
461 for (i = 0; i < overlappingPairArray.size(); i++)
463 btBroadphasePair& pair = overlappingPairArray[i];
465 bool isDuplicate = (pair == previousPair);
469 bool needsRemoval = false;
473 //important to perform AABB check that is consistent with the broadphase
474 btDbvtProxy* pa = (btDbvtProxy*)pair.m_pProxy0;
475 btDbvtProxy* pb = (btDbvtProxy*)pair.m_pProxy1;
476 bool hasOverlap = Intersect(pa->leaf->volume, pb->leaf->volume);
480 needsRemoval = false;
491 //should have no algorithm
492 btAssert(!pair.m_algorithm);
497 m_paircache->cleanOverlappingPair(pair, dispatcher);
505 //perform a sort, to sort 'invalid' pairs to the end
506 overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
507 overlappingPairArray.resize(overlappingPairArray.size() - invalidPair);
512 void btDbvtBroadphase::collide(btDispatcher* dispatcher)
514 /*printf("---------------------------------------------------------\n");
515 printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves);
516 printf("m_sets[1].m_leaves=%d\n",m_sets[1].m_leaves);
517 printf("numPairs = %d\n",getOverlappingPairCache()->getNumOverlappingPairs());
520 for (i=0;i<getOverlappingPairCache()->getNumOverlappingPairs();i++)
522 printf("pair[%d]=(%d,%d),",i,getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy0->getUid(),
523 getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy1->getUid());
529 SPC(m_profiling.m_total);
531 m_sets[0].optimizeIncremental(1 + (m_sets[0].m_leaves * m_dupdates) / 100);
534 const int count = 1 + (m_sets[1].m_leaves * m_fupdates) / 100;
535 m_sets[1].optimizeIncremental(1 + (m_sets[1].m_leaves * m_fupdates) / 100);
536 m_fixedleft = btMax<int>(0, m_fixedleft - count);
538 /* dynamic -> fixed set */
539 m_stageCurrent = (m_stageCurrent + 1) % STAGECOUNT;
540 btDbvtProxy* current = m_stageRoots[m_stageCurrent];
543 #if DBVT_BP_ACCURATESLEEPING
544 btDbvtTreeCollider collider(this);
548 btDbvtProxy* next = current->links[1];
549 listremove(current, m_stageRoots[current->stage]);
550 listappend(current, m_stageRoots[STAGECOUNT]);
551 #if DBVT_BP_ACCURATESLEEPING
552 m_paircache->removeOverlappingPairsContainingProxy(current, dispatcher);
553 collider.proxy = current;
554 btDbvt::collideTV(m_sets[0].m_root, current->aabb, collider);
555 btDbvt::collideTV(m_sets[1].m_root, current->aabb, collider);
557 m_sets[0].remove(current->leaf);
558 ATTRIBUTE_ALIGNED16(btDbvtVolume)
559 curAabb = btDbvtVolume::FromMM(current->m_aabbMin, current->m_aabbMax);
560 current->leaf = m_sets[1].insert(curAabb, current);
561 current->stage = STAGECOUNT;
564 m_fixedleft = m_sets[1].m_leaves;
565 m_needcleanup = true;
567 /* collide dynamics */
569 btDbvtTreeCollider collider(this);
570 if (m_deferedcollide)
572 SPC(m_profiling.m_fdcollide);
573 m_sets[0].collideTTpersistentStack(m_sets[0].m_root, m_sets[1].m_root, collider);
575 if (m_deferedcollide)
577 SPC(m_profiling.m_ddcollide);
578 m_sets[0].collideTTpersistentStack(m_sets[0].m_root, m_sets[0].m_root, collider);
584 SPC(m_profiling.m_cleanup);
585 btBroadphasePairArray& pairs = m_paircache->getOverlappingPairArray();
586 if (pairs.size() > 0)
588 int ni = btMin(pairs.size(), btMax<int>(m_newpairs, (pairs.size() * m_cupdates) / 100));
589 for (int i = 0; i < ni; ++i)
591 btBroadphasePair& p = pairs[(m_cid + i) % pairs.size()];
592 btDbvtProxy* pa = (btDbvtProxy*)p.m_pProxy0;
593 btDbvtProxy* pb = (btDbvtProxy*)p.m_pProxy1;
594 if (!Intersect(pa->leaf->volume, pb->leaf->volume))
596 #if DBVT_BP_SORTPAIRS
597 if (pa->m_uniqueId > pb->m_uniqueId)
600 m_paircache->removeOverlappingPair(pa, pb, dispatcher);
605 if (pairs.size() > 0)
606 m_cid = (m_cid + ni) % pairs.size();
613 m_needcleanup = false;
614 if (m_updates_call > 0)
616 m_updates_ratio = m_updates_done / (btScalar)m_updates_call;
627 void btDbvtBroadphase::optimize()
629 m_sets[0].optimizeTopDown();
630 m_sets[1].optimizeTopDown();
634 btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache()
636 return (m_paircache);
640 const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const
642 return (m_paircache);
646 void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin, btVector3& aabbMax) const
648 ATTRIBUTE_ALIGNED16(btDbvtVolume)
651 if (!m_sets[0].empty())
652 if (!m_sets[1].empty())
653 Merge(m_sets[0].m_root->volume,
654 m_sets[1].m_root->volume, bounds);
656 bounds = m_sets[0].m_root->volume;
657 else if (!m_sets[1].empty())
658 bounds = m_sets[1].m_root->volume;
660 bounds = btDbvtVolume::FromCR(btVector3(0, 0, 0), 0);
661 aabbMin = bounds.Mins();
662 aabbMax = bounds.Maxs();
665 void btDbvtBroadphase::resetPool(btDispatcher* dispatcher)
667 int totalObjects = m_sets[0].m_leaves + m_sets[1].m_leaves;
670 //reset internal dynamic tree data structures
674 m_deferedcollide = false;
675 m_needcleanup = true;
689 for (int i = 0; i <= STAGECOUNT; ++i)
697 void btDbvtBroadphase::printStats()
702 #if DBVT_BP_ENABLE_BENCHMARK
704 struct btBroadphaseBenchmark
720 btBroadphaseProxy* proxy;
722 void update(btScalar speed, btScalar amplitude, btBroadphaseInterface* pbi)
725 center[0] = btCos(time * (btScalar)2.17) * amplitude +
726 btSin(time) * amplitude / 2;
727 center[1] = btCos(time * (btScalar)1.38) * amplitude +
728 btSin(time) * amplitude;
729 center[2] = btSin(time * (btScalar)0.777) * amplitude;
730 pbi->setAabb(proxy, center - extents, center + extents, 0);
733 static int UnsignedRand(int range = RAND_MAX - 1) { return (rand() % (range + 1)); }
734 static btScalar UnitRand() { return (UnsignedRand(16384) / (btScalar)16384); }
735 static void OutputTime(const char* name, btClock& c, unsigned count = 0)
737 const unsigned long us = c.getTimeMicroseconds();
738 const unsigned long ms = (us + 500) / 1000;
739 const btScalar sec = us / (btScalar)(1000 * 1000);
741 printf("%s : %u us (%u ms), %.2f/s\r\n", name, us, ms, count / sec);
743 printf("%s : %u us (%u ms)\r\n", name, us, ms);
747 void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi)
749 static const btBroadphaseBenchmark::Experiment experiments[] =
751 {"1024o.10%", 1024, 10, 0, 8192, (btScalar)0.005, (btScalar)100},
752 /*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100},
753 {"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/
755 static const int nexperiments = sizeof(experiments) / sizeof(experiments[0]);
756 btAlignedObjectArray<btBroadphaseBenchmark::Object*> objects;
759 for (int iexp = 0; iexp < nexperiments; ++iexp)
761 const btBroadphaseBenchmark::Experiment& experiment = experiments[iexp];
762 const int object_count = experiment.object_count;
763 const int update_count = (object_count * experiment.update_count) / 100;
764 const int spawn_count = (object_count * experiment.spawn_count) / 100;
765 const btScalar speed = experiment.speed;
766 const btScalar amplitude = experiment.amplitude;
767 printf("Experiment #%u '%s':\r\n", iexp, experiment.name);
768 printf("\tObjects: %u\r\n", object_count);
769 printf("\tUpdate: %u\r\n", update_count);
770 printf("\tSpawn: %u\r\n", spawn_count);
771 printf("\tSpeed: %f\r\n", speed);
772 printf("\tAmplitude: %f\r\n", amplitude);
776 objects.reserve(object_count);
777 for (int i = 0; i < object_count; ++i)
779 btBroadphaseBenchmark::Object* po = new btBroadphaseBenchmark::Object();
780 po->center[0] = btBroadphaseBenchmark::UnitRand() * 50;
781 po->center[1] = btBroadphaseBenchmark::UnitRand() * 50;
782 po->center[2] = btBroadphaseBenchmark::UnitRand() * 50;
783 po->extents[0] = btBroadphaseBenchmark::UnitRand() * 2 + 2;
784 po->extents[1] = btBroadphaseBenchmark::UnitRand() * 2 + 2;
785 po->extents[2] = btBroadphaseBenchmark::UnitRand() * 2 + 2;
786 po->time = btBroadphaseBenchmark::UnitRand() * 2000;
787 po->proxy = pbi->createProxy(po->center - po->extents, po->center + po->extents, 0, po, 1, 1, 0, 0);
788 objects.push_back(po);
790 btBroadphaseBenchmark::OutputTime("\tInitialization", wallclock);
793 for (int i = 0; i < objects.size(); ++i)
795 objects[i]->update(speed, amplitude, pbi);
797 btBroadphaseBenchmark::OutputTime("\tFirst update", wallclock);
800 for (int i = 0; i < experiment.iterations; ++i)
802 for (int j = 0; j < update_count; ++j)
804 objects[j]->update(speed, amplitude, pbi);
806 pbi->calculateOverlappingPairs(0);
808 btBroadphaseBenchmark::OutputTime("\tUpdate", wallclock, experiment.iterations);
811 for (int i = 0; i < objects.size(); ++i)
813 pbi->destroyProxy(objects[i]->proxy, 0);
817 btBroadphaseBenchmark::OutputTime("\tRelease", wallclock);
821 void btDbvtBroadphase::benchmark(btBroadphaseInterface*)