btDbvtBroadphase.cpp 21 KB

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