Changeset 1972 for code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
- Timestamp:
- Oct 20, 2008, 5:40:38 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
r1963 r1972 27 27 #if DBVT_BP_PROFILE 28 28 struct ProfileScope 29 {29 { 30 30 __forceinline ProfileScope(btClock& clock,unsigned long& value) : 31 m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())32 {33 }31 m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds()) 32 { 33 } 34 34 __forceinline ~ProfileScope() 35 {35 { 36 36 (*m_value)+=m_clock->getTimeMicroseconds()-m_base; 37 }37 } 38 38 btClock* m_clock; 39 39 unsigned long* m_value; 40 40 unsigned long m_base; 41 };41 }; 42 42 #define SPC(_value_) ProfileScope spc_scope(m_clock,_value_) 43 43 #else … … 53 53 static inline void listappend(T* item,T*& list) 54 54 { 55 56 57 58 55 item->links[0]=0; 56 item->links[1]=list; 57 if(list) list->links[0]=item; 58 list=item; 59 59 } 60 60 … … 63 63 static inline void listremove(T* item,T*& list) 64 64 { 65 66 65 if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1]; 66 if(item->links[1]) item->links[1]->links[0]=item->links[0]; 67 67 } 68 68 … … 71 71 static inline int listcount(T* root) 72 72 { 73 74 75 73 int n=0; 74 while(root) { ++n;root=root->links[1]; } 75 return(n); 76 76 } 77 77 … … 80 80 static inline void clear(T& value) 81 81 { 82 83 82 static const struct ZeroDummy : T {} zerodummy; 83 value=zerodummy; 84 84 } 85 85 … … 91 91 struct btDbvtTreeCollider : btDbvt::ICollide 92 92 { 93 94 95 btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}96 97 { 98 99 { 100 101 102 #if DBVT_BP_SORTPAIRS103 104 #endif105 106 107 } 108 } 109 110 { 111 93 btDbvtBroadphase* pbp; 94 btDbvtProxy* proxy; 95 btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {} 96 void Process(const btDbvtNode* na,const btDbvtNode* nb) 97 { 98 if(na!=nb) 99 { 100 btDbvtProxy* pa=(btDbvtProxy*)na->data; 101 btDbvtProxy* pb=(btDbvtProxy*)nb->data; 102 #if DBVT_BP_SORTPAIRS 103 if(pa>pb) btSwap(pa,pb); 104 #endif 105 pbp->m_paircache->addOverlappingPair(pa,pb); 106 ++pbp->m_newpairs; 107 } 108 } 109 void Process(const btDbvtNode* n) 110 { 111 Process(n,proxy->leaf); 112 112 } 113 113 }; … … 120 120 btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache) 121 121 { 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 paircache :137 new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();138 139 140 141 142 { 143 122 m_deferedcollide = false; 123 m_needcleanup = true; 124 m_releasepaircache = (paircache!=0)?false:true; 125 m_prediction = 1/(btScalar)2; 126 m_stageCurrent = 0; 127 m_fixedleft = 0; 128 m_fupdates = 1; 129 m_dupdates = 0; 130 m_cupdates = 10; 131 m_newpairs = 1; 132 m_updates_call = 0; 133 m_updates_done = 0; 134 m_updates_ratio = 0; 135 m_paircache = paircache? 136 paircache : 137 new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache(); 138 m_gid = 0; 139 m_pid = 0; 140 m_cid = 0; 141 for(int i=0;i<=STAGECOUNT;++i) 142 { 143 m_stageRoots[i]=0; 144 144 } 145 145 #if DBVT_BP_PROFILE 146 146 clear(m_profiling); 147 147 #endif 148 148 } … … 151 151 btDbvtBroadphase::~btDbvtBroadphase() 152 152 { 153 154 155 156 157 153 if(m_releasepaircache) 154 { 155 m_paircache->~btOverlappingPairCache(); 156 btAlignedFree(m_paircache); 157 } 158 158 } 159 159 160 160 // 161 161 btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin, 162 const btVector3& aabbMax, 163 int /*shapeType*/, 164 void* userPtr, 165 short int collisionFilterGroup, 166 short int collisionFilterMask, 167 btDispatcher* /*dispatcher*/, 168 void* /*multiSapProxy*/) 169 { 170 btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( aabbMin,aabbMax,userPtr, 171 collisionFilterGroup, 172 collisionFilterMask); 173 174 btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); 175 176 //bproxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); 177 proxy->stage = m_stageCurrent; 178 proxy->m_uniqueId = ++m_gid; 179 proxy->leaf = m_sets[0].insert(aabb,proxy); 180 listappend(proxy,m_stageRoots[m_stageCurrent]); 181 if(!m_deferedcollide) 182 { 183 btDbvtTreeCollider collider(this); 184 collider.proxy=proxy; 185 btDbvt::collideTV(m_sets[0].m_root,aabb,collider); 186 btDbvt::collideTV(m_sets[1].m_root,aabb,collider); 187 } 188 return(proxy); 162 const btVector3& aabbMax, 163 int /*shapeType*/, 164 void* userPtr, 165 short int collisionFilterGroup, 166 short int collisionFilterMask, 167 btDispatcher* /*dispatcher*/, 168 void* /*multiSapProxy*/) 169 { 170 btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( userPtr, 171 collisionFilterGroup, 172 collisionFilterMask); 173 proxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); 174 proxy->stage = m_stageCurrent; 175 proxy->m_uniqueId = ++m_gid; 176 proxy->leaf = m_sets[0].insert(proxy->aabb,proxy); 177 listappend(proxy,m_stageRoots[m_stageCurrent]); 178 if(!m_deferedcollide) 179 { 180 btDbvtTreeCollider collider(this); 181 collider.proxy=proxy; 182 btDbvt::collideTV(m_sets[0].m_root,proxy->aabb,collider); 183 btDbvt::collideTV(m_sets[1].m_root,proxy->aabb,collider); 184 } 185 return(proxy); 189 186 } 190 187 191 188 // 192 189 void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy, 193 btDispatcher* dispatcher) 194 { 195 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 190 btDispatcher* dispatcher) 191 { 192 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 193 if(proxy->stage==STAGECOUNT) 194 m_sets[1].remove(proxy->leaf); 195 else 196 m_sets[0].remove(proxy->leaf); 197 listremove(proxy,m_stageRoots[proxy->stage]); 198 m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher); 199 btAlignedFree(proxy); 200 m_needcleanup=true; 201 } 202 203 // 204 void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, 205 const btVector3& aabbMin, 206 const btVector3& aabbMax, 207 btDispatcher* /*dispatcher*/) 208 { 209 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 210 ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); 211 #if DBVT_BP_PREVENTFALSEUPDATE 212 if(NotEqual(aabb,proxy->leaf->volume)) 213 #endif 214 { 215 bool docollide=false; 196 216 if(proxy->stage==STAGECOUNT) 217 {/* fixed -> dynamic set */ 197 218 m_sets[1].remove(proxy->leaf); 198 else 199 m_sets[0].remove(proxy->leaf); 200 listremove(proxy,m_stageRoots[proxy->stage]); 201 m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher); 202 btAlignedFree(proxy); 203 m_needcleanup=true; 204 } 205 206 void btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy,btVector3& aabbMin, btVector3& aabbMax ) const 207 { 208 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 209 aabbMin = proxy->m_aabbMin; 210 aabbMax = proxy->m_aabbMax; 211 } 212 213 void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback) 214 { 215 216 struct BroadphaseRayTester : btDbvt::ICollide 217 { 218 btBroadphaseRayCallback& m_rayCallback; 219 BroadphaseRayTester(btBroadphaseRayCallback& orgCallback) 220 :m_rayCallback(orgCallback) 221 { 222 } 223 void Process(const btDbvtNode* leaf) 224 { 225 btDbvtProxy* proxy=(btDbvtProxy*)leaf->data; 226 m_rayCallback.process(proxy); 227 } 228 }; 229 230 BroadphaseRayTester callback(rayCallback); 231 232 m_sets[0].rayTest( m_sets[0].m_root, 233 rayFrom, 234 rayTo, 235 callback); 236 237 m_sets[1].rayTest( m_sets[1].m_root, 238 rayFrom, 239 rayTo, 240 callback); 241 242 } 243 244 // 245 void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, 246 const btVector3& aabbMin, 247 const btVector3& aabbMax, 248 btDispatcher* /*dispatcher*/) 249 { 250 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 251 ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); 252 #if DBVT_BP_PREVENTFALSEUPDATE 253 if(NotEqual(aabb,proxy->leaf->volume)) 254 #endif 255 { 256 bool docollide=false; 257 if(proxy->stage==STAGECOUNT) 258 {/* fixed -> dynamic set */ 259 m_sets[1].remove(proxy->leaf); 260 proxy->leaf=m_sets[0].insert(aabb,proxy); 261 docollide=true; 219 proxy->leaf=m_sets[0].insert(aabb,proxy); 220 docollide=true; 262 221 } 263 222 else 264 223 {/* dynamic set */ 265 266 224 ++m_updates_call; 225 if(Intersect(proxy->leaf->volume,aabb)) 267 226 {/* Moving */ 268 269 const btVector3 delta=aabbMin-proxy->m_aabbMin; 270 btVector3 velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction); 271 if(delta[0]<0) velocity[0]=-velocity[0]; 272 if(delta[1]<0) velocity[1]=-velocity[1]; 273 if(delta[2]<0) velocity[2]=-velocity[2]; 274 if ( 275 #ifdef DBVT_BP_MARGIN 276 m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN) 277 #else 278 m_sets[0].update(proxy->leaf,aabb,velocity) 279 #endif 280 ) 227 const btVector3 delta=aabbMin-proxy->aabb.Mins(); 228 btVector3 velocity(aabb.Extents()*m_prediction); 229 if(delta[0]<0) velocity[0]=-velocity[0]; 230 if(delta[1]<0) velocity[1]=-velocity[1]; 231 if(delta[2]<0) velocity[2]=-velocity[2]; 232 if ( 233 #ifdef DBVT_BP_MARGIN 234 m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN) 235 #else 236 m_sets[0].update(proxy->leaf,aabb,velocity) 237 #endif 238 ) 281 239 { 282 283 240 ++m_updates_done; 241 docollide=true; 284 242 } 285 243 } 286 244 else 287 245 {/* Teleporting */ 288 289 290 246 m_sets[0].update(proxy->leaf,aabb); 247 ++m_updates_done; 248 docollide=true; 291 249 } 292 250 } 293 listremove(proxy,m_stageRoots[proxy->stage]); 294 proxy->m_aabbMin = aabbMin; 295 proxy->m_aabbMax = aabbMax; 296 proxy->stage = m_stageCurrent; 297 listappend(proxy,m_stageRoots[m_stageCurrent]); 298 if(docollide) 299 { 300 m_needcleanup=true; 301 if(!m_deferedcollide) 251 listremove(proxy,m_stageRoots[proxy->stage]); 252 proxy->aabb = aabb; 253 proxy->stage = m_stageCurrent; 254 listappend(proxy,m_stageRoots[m_stageCurrent]); 255 if(docollide) 256 { 257 m_needcleanup=true; 258 if(!m_deferedcollide) 302 259 { 303 304 305 260 btDbvtTreeCollider collider(this); 261 btDbvt::collideTT(m_sets[1].m_root,proxy->leaf,collider); 262 btDbvt::collideTT(m_sets[0].m_root,proxy->leaf,collider); 306 263 } 307 264 } … … 312 269 void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) 313 270 { 314 271 collide(dispatcher); 315 272 #if DBVT_BP_PROFILE 316 273 if(0==(m_pid%DBVT_BP_PROFILING_RATE)) 317 274 { 318 319 320 321 322 323 324 325 326 m_profiling.m_fdcollide+327 m_profiling.m_cleanup;328 329 330 331 275 printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs()); 276 unsigned int total=m_profiling.m_total; 277 if(total<=0) total=1; 278 printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE); 279 printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE); 280 printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE); 281 printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE); 282 const unsigned long sum=m_profiling.m_ddcollide+ 283 m_profiling.m_fdcollide+ 284 m_profiling.m_cleanup; 285 printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE); 286 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)); 287 clear(m_profiling); 288 m_clock.reset(); 332 289 } 333 290 #endif … … 337 294 void btDbvtBroadphase::collide(btDispatcher* dispatcher) 338 295 { 339 SPC(m_profiling.m_total); 340 /* optimize */ 341 m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); 342 if(m_fixedleft) 343 { 344 const int count=1+(m_sets[1].m_leaves*m_fupdates)/100; 345 m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100); 346 m_fixedleft=btMax<int>(0,m_fixedleft-count); 347 } 348 /* dynamic -> fixed set */ 349 m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; 350 btDbvtProxy* current=m_stageRoots[m_stageCurrent]; 351 if(current) 352 { 353 btDbvtTreeCollider collider(this); 354 do { 355 btDbvtProxy* next=current->links[1]; 356 listremove(current,m_stageRoots[current->stage]); 357 listappend(current,m_stageRoots[STAGECOUNT]); 358 #if DBVT_BP_ACCURATESLEEPING 359 m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher); 360 collider.proxy=current; 361 btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider); 362 btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider); 363 #endif 364 m_sets[0].remove(current->leaf); 365 ATTRIBUTE_ALIGNED16(btDbvtVolume) curAabb=btDbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax); 366 current->leaf = m_sets[1].insert(curAabb,current); 367 current->stage = STAGECOUNT; 368 current = next; 296 SPC(m_profiling.m_total); 297 /* optimize */ 298 m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); 299 if(m_fixedleft) 300 { 301 const int count=1+(m_sets[1].m_leaves*m_fupdates)/100; 302 m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100); 303 m_fixedleft=btMax<int>(0,m_fixedleft-count); 304 } 305 /* dynamic -> fixed set */ 306 m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; 307 btDbvtProxy* current=m_stageRoots[m_stageCurrent]; 308 if(current) 309 { 310 btDbvtTreeCollider collider(this); 311 do { 312 btDbvtProxy* next=current->links[1]; 313 listremove(current,m_stageRoots[current->stage]); 314 listappend(current,m_stageRoots[STAGECOUNT]); 315 #if DBVT_BP_ACCURATESLEEPING 316 m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher); 317 collider.proxy=current; 318 btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider); 319 btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider); 320 #endif 321 m_sets[0].remove(current->leaf); 322 current->leaf = m_sets[1].insert(current->aabb,current); 323 current->stage = STAGECOUNT; 324 current = next; 369 325 } while(current); 370 371 372 } 373 374 { 375 376 377 { 378 379 380 } 381 382 { 383 384 385 } 386 } 387 388 389 { 390 391 392 393 { 394 395 396 326 m_fixedleft=m_sets[1].m_leaves; 327 m_needcleanup=true; 328 } 329 /* collide dynamics */ 330 { 331 btDbvtTreeCollider collider(this); 332 if(m_deferedcollide) 333 { 334 SPC(m_profiling.m_fdcollide); 335 btDbvt::collideTT(m_sets[0].m_root,m_sets[1].m_root,collider); 336 } 337 if(m_deferedcollide) 338 { 339 SPC(m_profiling.m_ddcollide); 340 btDbvt::collideTT(m_sets[0].m_root,m_sets[0].m_root,collider); 341 } 342 } 343 /* clean up */ 344 if(m_needcleanup) 345 { 346 SPC(m_profiling.m_cleanup); 347 btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); 348 if(pairs.size()>0) 349 { 350 const int ci=pairs.size(); 351 int ni=btMin(ci,btMax<int>(m_newpairs,(ci*m_cupdates)/100)); 352 for(int i=0;i<ni;++i) 397 353 { 398 399 400 401 354 btBroadphasePair& p=pairs[(m_cid+i)%ci]; 355 btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0; 356 btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1; 357 if(!Intersect(pa->leaf->volume,pb->leaf->volume)) 402 358 { 403 #if DBVT_BP_SORTPAIRS404 405 #endif406 407 359 #if DBVT_BP_SORTPAIRS 360 if(pa>pb) btSwap(pa,pb); 361 #endif 362 m_paircache->removeOverlappingPair(pa,pb,dispatcher); 363 --ni;--i; 408 364 } 409 365 } 410 411 } 412 } 413 414 415 416 366 if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0; 367 } 368 } 369 ++m_pid; 370 m_newpairs=1; 371 m_needcleanup=false; 372 if(m_updates_call>0) 417 373 { m_updates_ratio=m_updates_done/(btScalar)m_updates_call; } 418 374 else 419 375 { m_updates_ratio=0; } 420 421 376 m_updates_done/=2; 377 m_updates_call/=2; 422 378 } 423 379 … … 425 381 void btDbvtBroadphase::optimize() 426 382 { 427 428 383 m_sets[0].optimizeTopDown(); 384 m_sets[1].optimizeTopDown(); 429 385 } 430 386 … … 432 388 btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() 433 389 { 434 390 return(m_paircache); 435 391 } 436 392 … … 438 394 const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const 439 395 { 440 396 return(m_paircache); 441 397 } 442 398 … … 447 403 ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds; 448 404 449 450 451 m_sets[1].m_root->volume,bounds);452 else453 bounds=m_sets[0].m_root->volume;454 455 else456 bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0);457 458 405 if(!m_sets[0].empty()) 406 if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume, 407 m_sets[1].m_root->volume,bounds); 408 else 409 bounds=m_sets[0].m_root->volume; 410 else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume; 411 else 412 bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0); 413 aabbMin=bounds.Mins(); 414 aabbMax=bounds.Maxs(); 459 415 } 460 416 … … 467 423 468 424 struct btBroadphaseBenchmark 469 {425 { 470 426 struct Experiment 471 {427 { 472 428 const char* name; 473 429 int object_count; … … 477 433 btScalar speed; 478 434 btScalar amplitude; 479 };435 }; 480 436 struct Object 481 {437 { 482 438 btVector3 center; 483 439 btVector3 extents; … … 485 441 btScalar time; 486 442 void update(btScalar speed,btScalar amplitude,btBroadphaseInterface* pbi) 487 {443 { 488 444 time += speed; 489 445 center[0] = btCos(time*(btScalar)2.17)*amplitude+ 490 btSin(time)*amplitude/2;446 btSin(time)*amplitude/2; 491 447 center[1] = btCos(time*(btScalar)1.38)*amplitude+ 492 btSin(time)*amplitude;448 btSin(time)*amplitude; 493 449 center[2] = btSin(time*(btScalar)0.777)*amplitude; 494 450 pbi->setAabb(proxy,center-extents,center+extents,0); 495 }496 };451 } 452 }; 497 453 static int UnsignedRand(int range=RAND_MAX-1) { return(rand()%(range+1)); } 498 454 static btScalar UnitRand() { return(UnsignedRand(16384)/(btScalar)16384); } 499 455 static void OutputTime(const char* name,btClock& c,unsigned count=0) 500 {456 { 501 457 const unsigned long us=c.getTimeMicroseconds(); 502 458 const unsigned long ms=(us+500)/1000; … … 504 460 if(count>0) 505 461 printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec); 506 else462 else 507 463 printf("%s : %u us (%u ms)\r\n",name,us,ms); 508 }509 };464 } 465 }; 510 466 511 467 void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi) 512 468 { 513 514 { 515 516 517 469 static const btBroadphaseBenchmark::Experiment experiments[]= 470 { 471 {"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100}, 472 /*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100}, 473 {"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/ 518 474 }; 519 520 521 522 523 524 { 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 { 543 544 545 546 547 548 549 550 551 552 553 } 554 555 556 557 558 { 559 560 } 561 562 563 564 565 { 566 475 static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]); 476 btAlignedObjectArray<btBroadphaseBenchmark::Object*> objects; 477 btClock wallclock; 478 /* Begin */ 479 for(int iexp=0;iexp<nexperiments;++iexp) 480 { 481 const btBroadphaseBenchmark::Experiment& experiment=experiments[iexp]; 482 const int object_count=experiment.object_count; 483 const int update_count=(object_count*experiment.update_count)/100; 484 const int spawn_count=(object_count*experiment.spawn_count)/100; 485 const btScalar speed=experiment.speed; 486 const btScalar amplitude=experiment.amplitude; 487 printf("Experiment #%u '%s':\r\n",iexp,experiment.name); 488 printf("\tObjects: %u\r\n",object_count); 489 printf("\tUpdate: %u\r\n",update_count); 490 printf("\tSpawn: %u\r\n",spawn_count); 491 printf("\tSpeed: %f\r\n",speed); 492 printf("\tAmplitude: %f\r\n",amplitude); 493 srand(180673); 494 /* Create objects */ 495 wallclock.reset(); 496 objects.reserve(object_count); 497 for(int i=0;i<object_count;++i) 498 { 499 btBroadphaseBenchmark::Object* po=new btBroadphaseBenchmark::Object(); 500 po->center[0]=btBroadphaseBenchmark::UnitRand()*50; 501 po->center[1]=btBroadphaseBenchmark::UnitRand()*50; 502 po->center[2]=btBroadphaseBenchmark::UnitRand()*50; 503 po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2; 504 po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2; 505 po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2; 506 po->time=btBroadphaseBenchmark::UnitRand()*2000; 507 po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0); 508 objects.push_back(po); 509 } 510 btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock); 511 /* First update */ 512 wallclock.reset(); 513 for(int i=0;i<objects.size();++i) 514 { 515 objects[i]->update(speed,amplitude,pbi); 516 } 517 btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock); 518 /* Updates */ 519 wallclock.reset(); 520 for(int i=0;i<experiment.iterations;++i) 521 { 522 for(int j=0;j<update_count;++j) 567 523 { 568 524 objects[j]->update(speed,amplitude,pbi); 569 525 } 570 571 } 572 573 574 575 576 { 577 578 579 } 580 581 526 pbi->calculateOverlappingPairs(0); 527 } 528 btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations); 529 /* Clean up */ 530 wallclock.reset(); 531 for(int i=0;i<objects.size();++i) 532 { 533 pbi->destroyProxy(objects[i]->proxy,0); 534 delete objects[i]; 535 } 536 objects.resize(0); 537 btBroadphaseBenchmark::OutputTime("\tRelease",wallclock); 582 538 } 583 539
Note: See TracChangeset
for help on using the changeset viewer.