btDbvtBroadphase.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. /*
  2. Bullet Continuous Collision Detection and Physics Library
  3. Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
  4. This software is provided 'as-is', without any express or implied warranty.
  5. In no event will the authors be held liable for any damages arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it freely,
  8. subject to the following restrictions:
  9. 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.
  10. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  11. 3. This notice may not be removed or altered from any source distribution.
  12. */
  13. ///btDbvtBroadphase implementation by Nathanael Presson
  14. #include "btDbvtBroadphase.h"
  15. #include "LinearMath/btThreads.h"
  16. btScalar gDbvtMargin = btScalar(0.05);
  17. //
  18. // Profiling
  19. //
  20. #if DBVT_BP_PROFILE || DBVT_BP_ENABLE_BENCHMARK
  21. #include <stdio.h>
  22. #endif
  23. #if DBVT_BP_PROFILE
  24. struct ProfileScope
  25. {
  26. __forceinline ProfileScope(btClock& clock, unsigned long& value) : m_clock(&clock), m_value(&value), m_base(clock.getTimeMicroseconds())
  27. {
  28. }
  29. __forceinline ~ProfileScope()
  30. {
  31. (*m_value) += m_clock->getTimeMicroseconds() - m_base;
  32. }
  33. btClock* m_clock;
  34. unsigned long* m_value;
  35. unsigned long m_base;
  36. };
  37. #define SPC(_value_) ProfileScope spc_scope(m_clock, _value_)
  38. #else
  39. #define SPC(_value_)
  40. #endif
  41. //
  42. // Helpers
  43. //
  44. //
  45. template <typename T>
  46. static inline void listappend(T* item, T*& list)
  47. {
  48. item->links[0] = 0;
  49. item->links[1] = list;
  50. if (list) list->links[0] = item;
  51. list = item;
  52. }
  53. //
  54. template <typename T>
  55. static inline void listremove(T* item, T*& list)
  56. {
  57. if (item->links[0])
  58. item->links[0]->links[1] = item->links[1];
  59. else
  60. list = item->links[1];
  61. if (item->links[1]) item->links[1]->links[0] = item->links[0];
  62. }
  63. //
  64. template <typename T>
  65. static inline int listcount(T* root)
  66. {
  67. int n = 0;
  68. while (root)
  69. {
  70. ++n;
  71. root = root->links[1];
  72. }
  73. return (n);
  74. }
  75. //
  76. template <typename T>
  77. static inline void clear(T& value)
  78. {
  79. static const struct ZeroDummy : T
  80. {
  81. } zerodummy;
  82. value = zerodummy;
  83. }
  84. //
  85. // Colliders
  86. //
  87. /* Tree collider */
  88. struct btDbvtTreeCollider : btDbvt::ICollide
  89. {
  90. btDbvtBroadphase* pbp;
  91. btDbvtProxy* proxy;
  92. btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}
  93. void Process(const btDbvtNode* na, const btDbvtNode* nb)
  94. {
  95. if (na != nb)
  96. {
  97. btDbvtProxy* pa = (btDbvtProxy*)na->data;
  98. btDbvtProxy* pb = (btDbvtProxy*)nb->data;
  99. #if DBVT_BP_SORTPAIRS
  100. if (pa->m_uniqueId > pb->m_uniqueId)
  101. btSwap(pa, pb);
  102. #endif
  103. pbp->m_paircache->addOverlappingPair(pa, pb);
  104. ++pbp->m_newpairs;
  105. }
  106. }
  107. void Process(const btDbvtNode* n)
  108. {
  109. Process(n, proxy->leaf);
  110. }
  111. };
  112. //
  113. // btDbvtBroadphase
  114. //
  115. //
  116. btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache)
  117. {
  118. m_deferedcollide = false;
  119. m_needcleanup = true;
  120. m_releasepaircache = (paircache != 0) ? false : true;
  121. m_prediction = 0;
  122. m_stageCurrent = 0;
  123. m_fixedleft = 0;
  124. m_fupdates = 1;
  125. m_dupdates = 0;
  126. m_cupdates = 10;
  127. m_newpairs = 1;
  128. m_updates_call = 0;
  129. m_updates_done = 0;
  130. m_updates_ratio = 0;
  131. m_paircache = paircache ? paircache : new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache), 16)) btHashedOverlappingPairCache();
  132. m_gid = 0;
  133. m_pid = 0;
  134. m_cid = 0;
  135. for (int i = 0; i <= STAGECOUNT; ++i)
  136. {
  137. m_stageRoots[i] = 0;
  138. }
  139. #if BT_THREADSAFE
  140. m_rayTestStacks.resize(BT_MAX_THREAD_COUNT);
  141. #else
  142. m_rayTestStacks.resize(1);
  143. #endif
  144. #if DBVT_BP_PROFILE
  145. clear(m_profiling);
  146. #endif
  147. }
  148. //
  149. btDbvtBroadphase::~btDbvtBroadphase()
  150. {
  151. if (m_releasepaircache)
  152. {
  153. m_paircache->~btOverlappingPairCache();
  154. btAlignedFree(m_paircache);
  155. }
  156. }
  157. //
  158. btBroadphaseProxy* btDbvtBroadphase::createProxy(const btVector3& aabbMin,
  159. const btVector3& aabbMax,
  160. int /*shapeType*/,
  161. void* userPtr,
  162. int collisionFilterGroup,
  163. int collisionFilterMask,
  164. btDispatcher* /*dispatcher*/)
  165. {
  166. btDbvtProxy* proxy = new (btAlignedAlloc(sizeof(btDbvtProxy), 16)) btDbvtProxy(aabbMin, aabbMax, userPtr,
  167. collisionFilterGroup,
  168. collisionFilterMask);
  169. btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin, aabbMax);
  170. //bproxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
  171. proxy->stage = m_stageCurrent;
  172. proxy->m_uniqueId = ++m_gid;
  173. proxy->leaf = m_sets[0].insert(aabb, proxy);
  174. listappend(proxy, m_stageRoots[m_stageCurrent]);
  175. if (!m_deferedcollide)
  176. {
  177. btDbvtTreeCollider collider(this);
  178. collider.proxy = proxy;
  179. m_sets[0].collideTV(m_sets[0].m_root, aabb, collider);
  180. m_sets[1].collideTV(m_sets[1].m_root, aabb, collider);
  181. }
  182. return (proxy);
  183. }
  184. //
  185. void btDbvtBroadphase::destroyProxy(btBroadphaseProxy* absproxy,
  186. btDispatcher* dispatcher)
  187. {
  188. btDbvtProxy* proxy = (btDbvtProxy*)absproxy;
  189. if (proxy->stage == STAGECOUNT)
  190. m_sets[1].remove(proxy->leaf);
  191. else
  192. m_sets[0].remove(proxy->leaf);
  193. listremove(proxy, m_stageRoots[proxy->stage]);
  194. m_paircache->removeOverlappingPairsContainingProxy(proxy, dispatcher);
  195. btAlignedFree(proxy);
  196. m_needcleanup = true;
  197. }
  198. void btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy, btVector3& aabbMin, btVector3& aabbMax) const
  199. {
  200. btDbvtProxy* proxy = (btDbvtProxy*)absproxy;
  201. aabbMin = proxy->m_aabbMin;
  202. aabbMax = proxy->m_aabbMax;
  203. }
  204. struct BroadphaseRayTester : btDbvt::ICollide
  205. {
  206. btBroadphaseRayCallback& m_rayCallback;
  207. BroadphaseRayTester(btBroadphaseRayCallback& orgCallback)
  208. : m_rayCallback(orgCallback)
  209. {
  210. }
  211. void Process(const btDbvtNode* leaf)
  212. {
  213. btDbvtProxy* proxy = (btDbvtProxy*)leaf->data;
  214. m_rayCallback.process(proxy);
  215. }
  216. };
  217. void btDbvtBroadphase::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin, const btVector3& aabbMax)
  218. {
  219. BroadphaseRayTester callback(rayCallback);
  220. btAlignedObjectArray<const btDbvtNode*>* stack = &m_rayTestStacks[0];
  221. #if BT_THREADSAFE
  222. // for this function to be threadsafe, each thread must have a separate copy
  223. // of this stack. This could be thread-local static to avoid dynamic allocations,
  224. // instead of just a local.
  225. int threadIndex = btGetCurrentThreadIndex();
  226. btAlignedObjectArray<const btDbvtNode*> localStack;
  227. //todo(erwincoumans, "why do we get tsan issue here?")
  228. if (0)//threadIndex < m_rayTestStacks.size())
  229. //if (threadIndex < m_rayTestStacks.size())
  230. {
  231. // use per-thread preallocated stack if possible to avoid dynamic allocations
  232. stack = &m_rayTestStacks[threadIndex];
  233. }
  234. else
  235. {
  236. stack = &localStack;
  237. }
  238. #endif
  239. m_sets[0].rayTestInternal(m_sets[0].m_root,
  240. rayFrom,
  241. rayTo,
  242. rayCallback.m_rayDirectionInverse,
  243. rayCallback.m_signs,
  244. rayCallback.m_lambda_max,
  245. aabbMin,
  246. aabbMax,
  247. *stack,
  248. callback);
  249. m_sets[1].rayTestInternal(m_sets[1].m_root,
  250. rayFrom,
  251. rayTo,
  252. rayCallback.m_rayDirectionInverse,
  253. rayCallback.m_signs,
  254. rayCallback.m_lambda_max,
  255. aabbMin,
  256. aabbMax,
  257. *stack,
  258. callback);
  259. }
  260. struct BroadphaseAabbTester : btDbvt::ICollide
  261. {
  262. btBroadphaseAabbCallback& m_aabbCallback;
  263. BroadphaseAabbTester(btBroadphaseAabbCallback& orgCallback)
  264. : m_aabbCallback(orgCallback)
  265. {
  266. }
  267. void Process(const btDbvtNode* leaf)
  268. {
  269. btDbvtProxy* proxy = (btDbvtProxy*)leaf->data;
  270. m_aabbCallback.process(proxy);
  271. }
  272. };
  273. void btDbvtBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& aabbCallback)
  274. {
  275. BroadphaseAabbTester callback(aabbCallback);
  276. const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds = btDbvtVolume::FromMM(aabbMin, aabbMax);
  277. //process all children, that overlap with the given AABB bounds
  278. m_sets[0].collideTV(m_sets[0].m_root, bounds, callback);
  279. m_sets[1].collideTV(m_sets[1].m_root, bounds, callback);
  280. }
  281. //
  282. void btDbvtBroadphase::setAabb(btBroadphaseProxy* absproxy,
  283. const btVector3& aabbMin,
  284. const btVector3& aabbMax,
  285. btDispatcher* /*dispatcher*/)
  286. {
  287. btDbvtProxy* proxy = (btDbvtProxy*)absproxy;
  288. ATTRIBUTE_ALIGNED16(btDbvtVolume)
  289. aabb = btDbvtVolume::FromMM(aabbMin, aabbMax);
  290. #if DBVT_BP_PREVENTFALSEUPDATE
  291. if (NotEqual(aabb, proxy->leaf->volume))
  292. #endif
  293. {
  294. bool docollide = false;
  295. if (proxy->stage == STAGECOUNT)
  296. { /* fixed -> dynamic set */
  297. m_sets[1].remove(proxy->leaf);
  298. proxy->leaf = m_sets[0].insert(aabb, proxy);
  299. docollide = true;
  300. }
  301. else
  302. { /* dynamic set */
  303. ++m_updates_call;
  304. if (Intersect(proxy->leaf->volume, aabb))
  305. { /* Moving */
  306. const btVector3 delta = aabbMin - proxy->m_aabbMin;
  307. btVector3 velocity(((proxy->m_aabbMax - proxy->m_aabbMin) / 2) * m_prediction);
  308. if (delta[0] < 0) velocity[0] = -velocity[0];
  309. if (delta[1] < 0) velocity[1] = -velocity[1];
  310. if (delta[2] < 0) velocity[2] = -velocity[2];
  311. if (
  312. m_sets[0].update(proxy->leaf, aabb, velocity, gDbvtMargin)
  313. )
  314. {
  315. ++m_updates_done;
  316. docollide = true;
  317. }
  318. }
  319. else
  320. { /* Teleporting */
  321. m_sets[0].update(proxy->leaf, aabb);
  322. ++m_updates_done;
  323. docollide = true;
  324. }
  325. }
  326. listremove(proxy, m_stageRoots[proxy->stage]);
  327. proxy->m_aabbMin = aabbMin;
  328. proxy->m_aabbMax = aabbMax;
  329. proxy->stage = m_stageCurrent;
  330. listappend(proxy, m_stageRoots[m_stageCurrent]);
  331. if (docollide)
  332. {
  333. m_needcleanup = true;
  334. if (!m_deferedcollide)
  335. {
  336. btDbvtTreeCollider collider(this);
  337. m_sets[1].collideTTpersistentStack(m_sets[1].m_root, proxy->leaf, collider);
  338. m_sets[0].collideTTpersistentStack(m_sets[0].m_root, proxy->leaf, collider);
  339. }
  340. }
  341. }
  342. }
  343. //
  344. void btDbvtBroadphase::setAabbForceUpdate(btBroadphaseProxy* absproxy,
  345. const btVector3& aabbMin,
  346. const btVector3& aabbMax,
  347. btDispatcher* /*dispatcher*/)
  348. {
  349. btDbvtProxy* proxy = (btDbvtProxy*)absproxy;
  350. ATTRIBUTE_ALIGNED16(btDbvtVolume)
  351. aabb = btDbvtVolume::FromMM(aabbMin, aabbMax);
  352. bool docollide = false;
  353. if (proxy->stage == STAGECOUNT)
  354. { /* fixed -> dynamic set */
  355. m_sets[1].remove(proxy->leaf);
  356. proxy->leaf = m_sets[0].insert(aabb, proxy);
  357. docollide = true;
  358. }
  359. else
  360. { /* dynamic set */
  361. ++m_updates_call;
  362. /* Teleporting */
  363. m_sets[0].update(proxy->leaf, aabb);
  364. ++m_updates_done;
  365. docollide = true;
  366. }
  367. listremove(proxy, m_stageRoots[proxy->stage]);
  368. proxy->m_aabbMin = aabbMin;
  369. proxy->m_aabbMax = aabbMax;
  370. proxy->stage = m_stageCurrent;
  371. listappend(proxy, m_stageRoots[m_stageCurrent]);
  372. if (docollide)
  373. {
  374. m_needcleanup = true;
  375. if (!m_deferedcollide)
  376. {
  377. btDbvtTreeCollider collider(this);
  378. m_sets[1].collideTTpersistentStack(m_sets[1].m_root, proxy->leaf, collider);
  379. m_sets[0].collideTTpersistentStack(m_sets[0].m_root, proxy->leaf, collider);
  380. }
  381. }
  382. }
  383. //
  384. void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
  385. {
  386. collide(dispatcher);
  387. #if DBVT_BP_PROFILE
  388. if (0 == (m_pid % DBVT_BP_PROFILING_RATE))
  389. {
  390. printf("fixed(%u) dynamics(%u) pairs(%u)\r\n", m_sets[1].m_leaves, m_sets[0].m_leaves, m_paircache->getNumOverlappingPairs());
  391. unsigned int total = m_profiling.m_total;
  392. if (total <= 0) total = 1;
  393. printf("ddcollide: %u%% (%uus)\r\n", (50 + m_profiling.m_ddcollide * 100) / total, m_profiling.m_ddcollide / DBVT_BP_PROFILING_RATE);
  394. printf("fdcollide: %u%% (%uus)\r\n", (50 + m_profiling.m_fdcollide * 100) / total, m_profiling.m_fdcollide / DBVT_BP_PROFILING_RATE);
  395. printf("cleanup: %u%% (%uus)\r\n", (50 + m_profiling.m_cleanup * 100) / total, m_profiling.m_cleanup / DBVT_BP_PROFILING_RATE);
  396. printf("total: %uus\r\n", total / DBVT_BP_PROFILING_RATE);
  397. const unsigned long sum = m_profiling.m_ddcollide +
  398. m_profiling.m_fdcollide +
  399. m_profiling.m_cleanup;
  400. printf("leaked: %u%% (%uus)\r\n", 100 - ((50 + sum * 100) / total), (total - sum) / DBVT_BP_PROFILING_RATE);
  401. 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));
  402. clear(m_profiling);
  403. m_clock.reset();
  404. }
  405. #endif
  406. performDeferredRemoval(dispatcher);
  407. }
  408. void btDbvtBroadphase::performDeferredRemoval(btDispatcher* dispatcher)
  409. {
  410. if (m_paircache->hasDeferredRemoval())
  411. {
  412. btBroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray();
  413. //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
  414. overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
  415. int invalidPair = 0;
  416. int i;
  417. btBroadphasePair previousPair;
  418. previousPair.m_pProxy0 = 0;
  419. previousPair.m_pProxy1 = 0;
  420. previousPair.m_algorithm = 0;
  421. for (i = 0; i < overlappingPairArray.size(); i++)
  422. {
  423. btBroadphasePair& pair = overlappingPairArray[i];
  424. bool isDuplicate = (pair == previousPair);
  425. previousPair = pair;
  426. bool needsRemoval = false;
  427. if (!isDuplicate)
  428. {
  429. //important to perform AABB check that is consistent with the broadphase
  430. btDbvtProxy* pa = (btDbvtProxy*)pair.m_pProxy0;
  431. btDbvtProxy* pb = (btDbvtProxy*)pair.m_pProxy1;
  432. bool hasOverlap = Intersect(pa->leaf->volume, pb->leaf->volume);
  433. if (hasOverlap)
  434. {
  435. needsRemoval = false;
  436. }
  437. else
  438. {
  439. needsRemoval = true;
  440. }
  441. }
  442. else
  443. {
  444. //remove duplicate
  445. needsRemoval = true;
  446. //should have no algorithm
  447. btAssert(!pair.m_algorithm);
  448. }
  449. if (needsRemoval)
  450. {
  451. m_paircache->cleanOverlappingPair(pair, dispatcher);
  452. pair.m_pProxy0 = 0;
  453. pair.m_pProxy1 = 0;
  454. invalidPair++;
  455. }
  456. }
  457. //perform a sort, to sort 'invalid' pairs to the end
  458. overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
  459. overlappingPairArray.resize(overlappingPairArray.size() - invalidPair);
  460. }
  461. }
  462. //
  463. void btDbvtBroadphase::collide(btDispatcher* dispatcher)
  464. {
  465. /*printf("---------------------------------------------------------\n");
  466. printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves);
  467. printf("m_sets[1].m_leaves=%d\n",m_sets[1].m_leaves);
  468. printf("numPairs = %d\n",getOverlappingPairCache()->getNumOverlappingPairs());
  469. {
  470. int i;
  471. for (i=0;i<getOverlappingPairCache()->getNumOverlappingPairs();i++)
  472. {
  473. printf("pair[%d]=(%d,%d),",i,getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy0->getUid(),
  474. getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy1->getUid());
  475. }
  476. printf("\n");
  477. }
  478. */
  479. SPC(m_profiling.m_total);
  480. /* optimize */
  481. m_sets[0].optimizeIncremental(1 + (m_sets[0].m_leaves * m_dupdates) / 100);
  482. if (m_fixedleft)
  483. {
  484. const int count = 1 + (m_sets[1].m_leaves * m_fupdates) / 100;
  485. m_sets[1].optimizeIncremental(1 + (m_sets[1].m_leaves * m_fupdates) / 100);
  486. m_fixedleft = btMax<int>(0, m_fixedleft - count);
  487. }
  488. /* dynamic -> fixed set */
  489. m_stageCurrent = (m_stageCurrent + 1) % STAGECOUNT;
  490. btDbvtProxy* current = m_stageRoots[m_stageCurrent];
  491. if (current)
  492. {
  493. #if DBVT_BP_ACCURATESLEEPING
  494. btDbvtTreeCollider collider(this);
  495. #endif
  496. do
  497. {
  498. btDbvtProxy* next = current->links[1];
  499. listremove(current, m_stageRoots[current->stage]);
  500. listappend(current, m_stageRoots[STAGECOUNT]);
  501. #if DBVT_BP_ACCURATESLEEPING
  502. m_paircache->removeOverlappingPairsContainingProxy(current, dispatcher);
  503. collider.proxy = current;
  504. btDbvt::collideTV(m_sets[0].m_root, current->aabb, collider);
  505. btDbvt::collideTV(m_sets[1].m_root, current->aabb, collider);
  506. #endif
  507. m_sets[0].remove(current->leaf);
  508. ATTRIBUTE_ALIGNED16(btDbvtVolume)
  509. curAabb = btDbvtVolume::FromMM(current->m_aabbMin, current->m_aabbMax);
  510. current->leaf = m_sets[1].insert(curAabb, current);
  511. current->stage = STAGECOUNT;
  512. current = next;
  513. } while (current);
  514. m_fixedleft = m_sets[1].m_leaves;
  515. m_needcleanup = true;
  516. }
  517. /* collide dynamics */
  518. {
  519. btDbvtTreeCollider collider(this);
  520. if (m_deferedcollide)
  521. {
  522. SPC(m_profiling.m_fdcollide);
  523. m_sets[0].collideTTpersistentStack(m_sets[0].m_root, m_sets[1].m_root, collider);
  524. }
  525. if (m_deferedcollide)
  526. {
  527. SPC(m_profiling.m_ddcollide);
  528. m_sets[0].collideTTpersistentStack(m_sets[0].m_root, m_sets[0].m_root, collider);
  529. }
  530. }
  531. /* clean up */
  532. if (m_needcleanup)
  533. {
  534. SPC(m_profiling.m_cleanup);
  535. btBroadphasePairArray& pairs = m_paircache->getOverlappingPairArray();
  536. if (pairs.size() > 0)
  537. {
  538. int ni = btMin(pairs.size(), btMax<int>(m_newpairs, (pairs.size() * m_cupdates) / 100));
  539. for (int i = 0; i < ni; ++i)
  540. {
  541. btBroadphasePair& p = pairs[(m_cid + i) % pairs.size()];
  542. btDbvtProxy* pa = (btDbvtProxy*)p.m_pProxy0;
  543. btDbvtProxy* pb = (btDbvtProxy*)p.m_pProxy1;
  544. if (!Intersect(pa->leaf->volume, pb->leaf->volume))
  545. {
  546. #if DBVT_BP_SORTPAIRS
  547. if (pa->m_uniqueId > pb->m_uniqueId)
  548. btSwap(pa, pb);
  549. #endif
  550. m_paircache->removeOverlappingPair(pa, pb, dispatcher);
  551. --ni;
  552. --i;
  553. }
  554. }
  555. if (pairs.size() > 0)
  556. m_cid = (m_cid + ni) % pairs.size();
  557. else
  558. m_cid = 0;
  559. }
  560. }
  561. ++m_pid;
  562. m_newpairs = 1;
  563. m_needcleanup = false;
  564. if (m_updates_call > 0)
  565. {
  566. m_updates_ratio = m_updates_done / (btScalar)m_updates_call;
  567. }
  568. else
  569. {
  570. m_updates_ratio = 0;
  571. }
  572. m_updates_done /= 2;
  573. m_updates_call /= 2;
  574. }
  575. //
  576. void btDbvtBroadphase::optimize()
  577. {
  578. m_sets[0].optimizeTopDown();
  579. m_sets[1].optimizeTopDown();
  580. }
  581. //
  582. btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache()
  583. {
  584. return (m_paircache);
  585. }
  586. //
  587. const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const
  588. {
  589. return (m_paircache);
  590. }
  591. //
  592. void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin, btVector3& aabbMax) const
  593. {
  594. ATTRIBUTE_ALIGNED16(btDbvtVolume)
  595. bounds;
  596. if (!m_sets[0].empty())
  597. if (!m_sets[1].empty())
  598. Merge(m_sets[0].m_root->volume,
  599. m_sets[1].m_root->volume, bounds);
  600. else
  601. bounds = m_sets[0].m_root->volume;
  602. else if (!m_sets[1].empty())
  603. bounds = m_sets[1].m_root->volume;
  604. else
  605. bounds = btDbvtVolume::FromCR(btVector3(0, 0, 0), 0);
  606. aabbMin = bounds.Mins();
  607. aabbMax = bounds.Maxs();
  608. }
  609. void btDbvtBroadphase::resetPool(btDispatcher* dispatcher)
  610. {
  611. int totalObjects = m_sets[0].m_leaves + m_sets[1].m_leaves;
  612. if (!totalObjects)
  613. {
  614. //reset internal dynamic tree data structures
  615. m_sets[0].clear();
  616. m_sets[1].clear();
  617. m_deferedcollide = false;
  618. m_needcleanup = true;
  619. m_stageCurrent = 0;
  620. m_fixedleft = 0;
  621. m_fupdates = 1;
  622. m_dupdates = 0;
  623. m_cupdates = 10;
  624. m_newpairs = 1;
  625. m_updates_call = 0;
  626. m_updates_done = 0;
  627. m_updates_ratio = 0;
  628. m_gid = 0;
  629. m_pid = 0;
  630. m_cid = 0;
  631. for (int i = 0; i <= STAGECOUNT; ++i)
  632. {
  633. m_stageRoots[i] = 0;
  634. }
  635. }
  636. }
  637. //
  638. void btDbvtBroadphase::printStats()
  639. {
  640. }
  641. //
  642. #if DBVT_BP_ENABLE_BENCHMARK
  643. struct btBroadphaseBenchmark
  644. {
  645. struct Experiment
  646. {
  647. const char* name;
  648. int object_count;
  649. int update_count;
  650. int spawn_count;
  651. int iterations;
  652. btScalar speed;
  653. btScalar amplitude;
  654. };
  655. struct Object
  656. {
  657. btVector3 center;
  658. btVector3 extents;
  659. btBroadphaseProxy* proxy;
  660. btScalar time;
  661. void update(btScalar speed, btScalar amplitude, btBroadphaseInterface* pbi)
  662. {
  663. time += speed;
  664. center[0] = btCos(time * (btScalar)2.17) * amplitude +
  665. btSin(time) * amplitude / 2;
  666. center[1] = btCos(time * (btScalar)1.38) * amplitude +
  667. btSin(time) * amplitude;
  668. center[2] = btSin(time * (btScalar)0.777) * amplitude;
  669. pbi->setAabb(proxy, center - extents, center + extents, 0);
  670. }
  671. };
  672. static int UnsignedRand(int range = RAND_MAX - 1) { return (rand() % (range + 1)); }
  673. static btScalar UnitRand() { return (UnsignedRand(16384) / (btScalar)16384); }
  674. static void OutputTime(const char* name, btClock& c, unsigned count = 0)
  675. {
  676. const unsigned long us = c.getTimeMicroseconds();
  677. const unsigned long ms = (us + 500) / 1000;
  678. const btScalar sec = us / (btScalar)(1000 * 1000);
  679. if (count > 0)
  680. printf("%s : %u us (%u ms), %.2f/s\r\n", name, us, ms, count / sec);
  681. else
  682. printf("%s : %u us (%u ms)\r\n", name, us, ms);
  683. }
  684. };
  685. void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi)
  686. {
  687. static const btBroadphaseBenchmark::Experiment experiments[] =
  688. {
  689. {"1024o.10%", 1024, 10, 0, 8192, (btScalar)0.005, (btScalar)100},
  690. /*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100},
  691. {"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/
  692. };
  693. static const int nexperiments = sizeof(experiments) / sizeof(experiments[0]);
  694. btAlignedObjectArray<btBroadphaseBenchmark::Object*> objects;
  695. btClock wallclock;
  696. /* Begin */
  697. for (int iexp = 0; iexp < nexperiments; ++iexp)
  698. {
  699. const btBroadphaseBenchmark::Experiment& experiment = experiments[iexp];
  700. const int object_count = experiment.object_count;
  701. const int update_count = (object_count * experiment.update_count) / 100;
  702. const int spawn_count = (object_count * experiment.spawn_count) / 100;
  703. const btScalar speed = experiment.speed;
  704. const btScalar amplitude = experiment.amplitude;
  705. printf("Experiment #%u '%s':\r\n", iexp, experiment.name);
  706. printf("\tObjects: %u\r\n", object_count);
  707. printf("\tUpdate: %u\r\n", update_count);
  708. printf("\tSpawn: %u\r\n", spawn_count);
  709. printf("\tSpeed: %f\r\n", speed);
  710. printf("\tAmplitude: %f\r\n", amplitude);
  711. srand(180673);
  712. /* Create objects */
  713. wallclock.reset();
  714. objects.reserve(object_count);
  715. for (int i = 0; i < object_count; ++i)
  716. {
  717. btBroadphaseBenchmark::Object* po = new btBroadphaseBenchmark::Object();
  718. po->center[0] = btBroadphaseBenchmark::UnitRand() * 50;
  719. po->center[1] = btBroadphaseBenchmark::UnitRand() * 50;
  720. po->center[2] = btBroadphaseBenchmark::UnitRand() * 50;
  721. po->extents[0] = btBroadphaseBenchmark::UnitRand() * 2 + 2;
  722. po->extents[1] = btBroadphaseBenchmark::UnitRand() * 2 + 2;
  723. po->extents[2] = btBroadphaseBenchmark::UnitRand() * 2 + 2;
  724. po->time = btBroadphaseBenchmark::UnitRand() * 2000;
  725. po->proxy = pbi->createProxy(po->center - po->extents, po->center + po->extents, 0, po, 1, 1, 0, 0);
  726. objects.push_back(po);
  727. }
  728. btBroadphaseBenchmark::OutputTime("\tInitialization", wallclock);
  729. /* First update */
  730. wallclock.reset();
  731. for (int i = 0; i < objects.size(); ++i)
  732. {
  733. objects[i]->update(speed, amplitude, pbi);
  734. }
  735. btBroadphaseBenchmark::OutputTime("\tFirst update", wallclock);
  736. /* Updates */
  737. wallclock.reset();
  738. for (int i = 0; i < experiment.iterations; ++i)
  739. {
  740. for (int j = 0; j < update_count; ++j)
  741. {
  742. objects[j]->update(speed, amplitude, pbi);
  743. }
  744. pbi->calculateOverlappingPairs(0);
  745. }
  746. btBroadphaseBenchmark::OutputTime("\tUpdate", wallclock, experiment.iterations);
  747. /* Clean up */
  748. wallclock.reset();
  749. for (int i = 0; i < objects.size(); ++i)
  750. {
  751. pbi->destroyProxy(objects[i]->proxy, 0);
  752. delete objects[i];
  753. }
  754. objects.resize(0);
  755. btBroadphaseBenchmark::OutputTime("\tRelease", wallclock);
  756. }
  757. }
  758. #else
  759. void btDbvtBroadphase::benchmark(btBroadphaseInterface*)
  760. {
  761. }
  762. #endif
  763. #if DBVT_BP_PROFILE
  764. #undef SPC
  765. #endif