Blender V2.61 - r43446
|
00001 /* 00002 Bullet Continuous Collision Detection and Physics Library 00003 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ 00004 00005 This software is provided 'as-is', without any express or implied warranty. 00006 In no event will the authors be held liable for any damages arising from the use of this software. 00007 Permission is granted to anyone to use this software for any purpose, 00008 including commercial applications, and to alter it and redistribute it freely, 00009 subject to the following restrictions: 00010 00011 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. 00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00013 3. This notice may not be removed or altered from any source distribution. 00014 */ 00016 00017 #include "btDbvt.h" 00018 00019 // 00020 typedef btAlignedObjectArray<btDbvtNode*> tNodeArray; 00021 typedef btAlignedObjectArray<const btDbvtNode*> tConstNodeArray; 00022 00023 // 00024 struct btDbvtNodeEnumerator : btDbvt::ICollide 00025 { 00026 tConstNodeArray nodes; 00027 void Process(const btDbvtNode* n) { nodes.push_back(n); } 00028 }; 00029 00030 // 00031 static DBVT_INLINE int indexof(const btDbvtNode* node) 00032 { 00033 return(node->parent->childs[1]==node); 00034 } 00035 00036 // 00037 static DBVT_INLINE btDbvtVolume merge( const btDbvtVolume& a, 00038 const btDbvtVolume& b) 00039 { 00040 #if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE) 00041 ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]); 00042 btDbvtVolume& res=*(btDbvtVolume*)locals; 00043 #else 00044 btDbvtVolume res; 00045 #endif 00046 Merge(a,b,res); 00047 return(res); 00048 } 00049 00050 // volume+edge lengths 00051 static DBVT_INLINE btScalar size(const btDbvtVolume& a) 00052 { 00053 const btVector3 edges=a.Lengths(); 00054 return( edges.x()*edges.y()*edges.z()+ 00055 edges.x()+edges.y()+edges.z()); 00056 } 00057 00058 // 00059 static void getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth) 00060 { 00061 if(node->isinternal()) 00062 { 00063 getmaxdepth(node->childs[0],depth+1,maxdepth); 00064 getmaxdepth(node->childs[1],depth+1,maxdepth); 00065 } else maxdepth=btMax(maxdepth,depth); 00066 } 00067 00068 // 00069 static DBVT_INLINE void deletenode( btDbvt* pdbvt, 00070 btDbvtNode* node) 00071 { 00072 btAlignedFree(pdbvt->m_free); 00073 pdbvt->m_free=node; 00074 } 00075 00076 // 00077 static void recursedeletenode( btDbvt* pdbvt, 00078 btDbvtNode* node) 00079 { 00080 if(!node->isleaf()) 00081 { 00082 recursedeletenode(pdbvt,node->childs[0]); 00083 recursedeletenode(pdbvt,node->childs[1]); 00084 } 00085 if(node==pdbvt->m_root) pdbvt->m_root=0; 00086 deletenode(pdbvt,node); 00087 } 00088 00089 // 00090 static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, 00091 btDbvtNode* parent, 00092 void* data) 00093 { 00094 btDbvtNode* node; 00095 if(pdbvt->m_free) 00096 { node=pdbvt->m_free;pdbvt->m_free=0; } 00097 else 00098 { node=new(btAlignedAlloc(sizeof(btDbvtNode),16)) btDbvtNode(); } 00099 node->parent = parent; 00100 node->data = data; 00101 node->childs[1] = 0; 00102 return(node); 00103 } 00104 00105 // 00106 static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, 00107 btDbvtNode* parent, 00108 const btDbvtVolume& volume, 00109 void* data) 00110 { 00111 btDbvtNode* node=createnode(pdbvt,parent,data); 00112 node->volume=volume; 00113 return(node); 00114 } 00115 00116 // 00117 static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, 00118 btDbvtNode* parent, 00119 const btDbvtVolume& volume0, 00120 const btDbvtVolume& volume1, 00121 void* data) 00122 { 00123 btDbvtNode* node=createnode(pdbvt,parent,data); 00124 Merge(volume0,volume1,node->volume); 00125 return(node); 00126 } 00127 00128 // 00129 static void insertleaf( btDbvt* pdbvt, 00130 btDbvtNode* root, 00131 btDbvtNode* leaf) 00132 { 00133 if(!pdbvt->m_root) 00134 { 00135 pdbvt->m_root = leaf; 00136 leaf->parent = 0; 00137 } 00138 else 00139 { 00140 if(!root->isleaf()) 00141 { 00142 do { 00143 root=root->childs[Select( leaf->volume, 00144 root->childs[0]->volume, 00145 root->childs[1]->volume)]; 00146 } while(!root->isleaf()); 00147 } 00148 btDbvtNode* prev=root->parent; 00149 btDbvtNode* node=createnode(pdbvt,prev,leaf->volume,root->volume,0); 00150 if(prev) 00151 { 00152 prev->childs[indexof(root)] = node; 00153 node->childs[0] = root;root->parent=node; 00154 node->childs[1] = leaf;leaf->parent=node; 00155 do { 00156 if(!prev->volume.Contain(node->volume)) 00157 Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); 00158 else 00159 break; 00160 node=prev; 00161 } while(0!=(prev=node->parent)); 00162 } 00163 else 00164 { 00165 node->childs[0] = root;root->parent=node; 00166 node->childs[1] = leaf;leaf->parent=node; 00167 pdbvt->m_root = node; 00168 } 00169 } 00170 } 00171 00172 // 00173 static btDbvtNode* removeleaf( btDbvt* pdbvt, 00174 btDbvtNode* leaf) 00175 { 00176 if(leaf==pdbvt->m_root) 00177 { 00178 pdbvt->m_root=0; 00179 return(0); 00180 } 00181 else 00182 { 00183 btDbvtNode* parent=leaf->parent; 00184 btDbvtNode* prev=parent->parent; 00185 btDbvtNode* sibling=parent->childs[1-indexof(leaf)]; 00186 if(prev) 00187 { 00188 prev->childs[indexof(parent)]=sibling; 00189 sibling->parent=prev; 00190 deletenode(pdbvt,parent); 00191 while(prev) 00192 { 00193 const btDbvtVolume pb=prev->volume; 00194 Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); 00195 if(NotEqual(pb,prev->volume)) 00196 { 00197 prev=prev->parent; 00198 } else break; 00199 } 00200 return(prev?prev:pdbvt->m_root); 00201 } 00202 else 00203 { 00204 pdbvt->m_root=sibling; 00205 sibling->parent=0; 00206 deletenode(pdbvt,parent); 00207 return(pdbvt->m_root); 00208 } 00209 } 00210 } 00211 00212 // 00213 static void fetchleaves(btDbvt* pdbvt, 00214 btDbvtNode* root, 00215 tNodeArray& leaves, 00216 int depth=-1) 00217 { 00218 if(root->isinternal()&&depth) 00219 { 00220 fetchleaves(pdbvt,root->childs[0],leaves,depth-1); 00221 fetchleaves(pdbvt,root->childs[1],leaves,depth-1); 00222 deletenode(pdbvt,root); 00223 } 00224 else 00225 { 00226 leaves.push_back(root); 00227 } 00228 } 00229 00230 // 00231 static void split( const tNodeArray& leaves, 00232 tNodeArray& left, 00233 tNodeArray& right, 00234 const btVector3& org, 00235 const btVector3& axis) 00236 { 00237 left.resize(0); 00238 right.resize(0); 00239 for(int i=0,ni=leaves.size();i<ni;++i) 00240 { 00241 if(btDot(axis,leaves[i]->volume.Center()-org)<0) 00242 left.push_back(leaves[i]); 00243 else 00244 right.push_back(leaves[i]); 00245 } 00246 } 00247 00248 // 00249 static btDbvtVolume bounds( const tNodeArray& leaves) 00250 { 00251 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE 00252 ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]); 00253 btDbvtVolume& volume=*(btDbvtVolume*)locals; 00254 volume=leaves[0]->volume; 00255 #else 00256 btDbvtVolume volume=leaves[0]->volume; 00257 #endif 00258 for(int i=1,ni=leaves.size();i<ni;++i) 00259 { 00260 Merge(volume,leaves[i]->volume,volume); 00261 } 00262 return(volume); 00263 } 00264 00265 // 00266 static void bottomup( btDbvt* pdbvt, 00267 tNodeArray& leaves) 00268 { 00269 while(leaves.size()>1) 00270 { 00271 btScalar minsize=SIMD_INFINITY; 00272 int minidx[2]={-1,-1}; 00273 for(int i=0;i<leaves.size();++i) 00274 { 00275 for(int j=i+1;j<leaves.size();++j) 00276 { 00277 const btScalar sz=size(merge(leaves[i]->volume,leaves[j]->volume)); 00278 if(sz<minsize) 00279 { 00280 minsize = sz; 00281 minidx[0] = i; 00282 minidx[1] = j; 00283 } 00284 } 00285 } 00286 btDbvtNode* n[] = {leaves[minidx[0]],leaves[minidx[1]]}; 00287 btDbvtNode* p = createnode(pdbvt,0,n[0]->volume,n[1]->volume,0); 00288 p->childs[0] = n[0]; 00289 p->childs[1] = n[1]; 00290 n[0]->parent = p; 00291 n[1]->parent = p; 00292 leaves[minidx[0]] = p; 00293 leaves.swap(minidx[1],leaves.size()-1); 00294 leaves.pop_back(); 00295 } 00296 } 00297 00298 // 00299 static btDbvtNode* topdown(btDbvt* pdbvt, 00300 tNodeArray& leaves, 00301 int bu_treshold) 00302 { 00303 static const btVector3 axis[]={btVector3(1,0,0), 00304 btVector3(0,1,0), 00305 btVector3(0,0,1)}; 00306 if(leaves.size()>1) 00307 { 00308 if(leaves.size()>bu_treshold) 00309 { 00310 const btDbvtVolume vol=bounds(leaves); 00311 const btVector3 org=vol.Center(); 00312 tNodeArray sets[2]; 00313 int bestaxis=-1; 00314 int bestmidp=leaves.size(); 00315 int splitcount[3][2]={{0,0},{0,0},{0,0}}; 00316 int i; 00317 for( i=0;i<leaves.size();++i) 00318 { 00319 const btVector3 x=leaves[i]->volume.Center()-org; 00320 for(int j=0;j<3;++j) 00321 { 00322 ++splitcount[j][btDot(x,axis[j])>0?1:0]; 00323 } 00324 } 00325 for( i=0;i<3;++i) 00326 { 00327 if((splitcount[i][0]>0)&&(splitcount[i][1]>0)) 00328 { 00329 const int midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1])); 00330 if(midp<bestmidp) 00331 { 00332 bestaxis=i; 00333 bestmidp=midp; 00334 } 00335 } 00336 } 00337 if(bestaxis>=0) 00338 { 00339 sets[0].reserve(splitcount[bestaxis][0]); 00340 sets[1].reserve(splitcount[bestaxis][1]); 00341 split(leaves,sets[0],sets[1],org,axis[bestaxis]); 00342 } 00343 else 00344 { 00345 sets[0].reserve(leaves.size()/2+1); 00346 sets[1].reserve(leaves.size()/2); 00347 for(int i=0,ni=leaves.size();i<ni;++i) 00348 { 00349 sets[i&1].push_back(leaves[i]); 00350 } 00351 } 00352 btDbvtNode* node=createnode(pdbvt,0,vol,0); 00353 node->childs[0]=topdown(pdbvt,sets[0],bu_treshold); 00354 node->childs[1]=topdown(pdbvt,sets[1],bu_treshold); 00355 node->childs[0]->parent=node; 00356 node->childs[1]->parent=node; 00357 return(node); 00358 } 00359 else 00360 { 00361 bottomup(pdbvt,leaves); 00362 return(leaves[0]); 00363 } 00364 } 00365 return(leaves[0]); 00366 } 00367 00368 // 00369 static DBVT_INLINE btDbvtNode* sort(btDbvtNode* n,btDbvtNode*& r) 00370 { 00371 btDbvtNode* p=n->parent; 00372 btAssert(n->isinternal()); 00373 if(p>n) 00374 { 00375 const int i=indexof(n); 00376 const int j=1-i; 00377 btDbvtNode* s=p->childs[j]; 00378 btDbvtNode* q=p->parent; 00379 btAssert(n==p->childs[i]); 00380 if(q) q->childs[indexof(p)]=n; else r=n; 00381 s->parent=n; 00382 p->parent=n; 00383 n->parent=q; 00384 p->childs[0]=n->childs[0]; 00385 p->childs[1]=n->childs[1]; 00386 n->childs[0]->parent=p; 00387 n->childs[1]->parent=p; 00388 n->childs[i]=p; 00389 n->childs[j]=s; 00390 btSwap(p->volume,n->volume); 00391 return(p); 00392 } 00393 return(n); 00394 } 00395 00396 #if 0 00397 static DBVT_INLINE btDbvtNode* walkup(btDbvtNode* n,int count) 00398 { 00399 while(n&&(count--)) n=n->parent; 00400 return(n); 00401 } 00402 #endif 00403 00404 // 00405 // Api 00406 // 00407 00408 // 00409 btDbvt::btDbvt() 00410 { 00411 m_root = 0; 00412 m_free = 0; 00413 m_lkhd = -1; 00414 m_leaves = 0; 00415 m_opath = 0; 00416 } 00417 00418 // 00419 btDbvt::~btDbvt() 00420 { 00421 clear(); 00422 } 00423 00424 // 00425 void btDbvt::clear() 00426 { 00427 if(m_root) 00428 recursedeletenode(this,m_root); 00429 btAlignedFree(m_free); 00430 m_free=0; 00431 m_lkhd = -1; 00432 m_stkStack.clear(); 00433 m_opath = 0; 00434 00435 } 00436 00437 // 00438 void btDbvt::optimizeBottomUp() 00439 { 00440 if(m_root) 00441 { 00442 tNodeArray leaves; 00443 leaves.reserve(m_leaves); 00444 fetchleaves(this,m_root,leaves); 00445 bottomup(this,leaves); 00446 m_root=leaves[0]; 00447 } 00448 } 00449 00450 // 00451 void btDbvt::optimizeTopDown(int bu_treshold) 00452 { 00453 if(m_root) 00454 { 00455 tNodeArray leaves; 00456 leaves.reserve(m_leaves); 00457 fetchleaves(this,m_root,leaves); 00458 m_root=topdown(this,leaves,bu_treshold); 00459 } 00460 } 00461 00462 // 00463 void btDbvt::optimizeIncremental(int passes) 00464 { 00465 if(passes<0) passes=m_leaves; 00466 if(m_root&&(passes>0)) 00467 { 00468 do { 00469 btDbvtNode* node=m_root; 00470 unsigned bit=0; 00471 while(node->isinternal()) 00472 { 00473 node=sort(node,m_root)->childs[(m_opath>>bit)&1]; 00474 bit=(bit+1)&(sizeof(unsigned)*8-1); 00475 } 00476 update(node); 00477 ++m_opath; 00478 } while(--passes); 00479 } 00480 } 00481 00482 // 00483 btDbvtNode* btDbvt::insert(const btDbvtVolume& volume,void* data) 00484 { 00485 btDbvtNode* leaf=createnode(this,0,volume,data); 00486 insertleaf(this,m_root,leaf); 00487 ++m_leaves; 00488 return(leaf); 00489 } 00490 00491 // 00492 void btDbvt::update(btDbvtNode* leaf,int lookahead) 00493 { 00494 btDbvtNode* root=removeleaf(this,leaf); 00495 if(root) 00496 { 00497 if(lookahead>=0) 00498 { 00499 for(int i=0;(i<lookahead)&&root->parent;++i) 00500 { 00501 root=root->parent; 00502 } 00503 } else root=m_root; 00504 } 00505 insertleaf(this,root,leaf); 00506 } 00507 00508 // 00509 void btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume) 00510 { 00511 btDbvtNode* root=removeleaf(this,leaf); 00512 if(root) 00513 { 00514 if(m_lkhd>=0) 00515 { 00516 for(int i=0;(i<m_lkhd)&&root->parent;++i) 00517 { 00518 root=root->parent; 00519 } 00520 } else root=m_root; 00521 } 00522 leaf->volume=volume; 00523 insertleaf(this,root,leaf); 00524 } 00525 00526 // 00527 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin) 00528 { 00529 if(leaf->volume.Contain(volume)) return(false); 00530 volume.Expand(btVector3(margin,margin,margin)); 00531 volume.SignedExpand(velocity); 00532 update(leaf,volume); 00533 return(true); 00534 } 00535 00536 // 00537 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity) 00538 { 00539 if(leaf->volume.Contain(volume)) return(false); 00540 volume.SignedExpand(velocity); 00541 update(leaf,volume); 00542 return(true); 00543 } 00544 00545 // 00546 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin) 00547 { 00548 if(leaf->volume.Contain(volume)) return(false); 00549 volume.Expand(btVector3(margin,margin,margin)); 00550 update(leaf,volume); 00551 return(true); 00552 } 00553 00554 // 00555 void btDbvt::remove(btDbvtNode* leaf) 00556 { 00557 removeleaf(this,leaf); 00558 deletenode(this,leaf); 00559 --m_leaves; 00560 } 00561 00562 // 00563 void btDbvt::write(IWriter* iwriter) const 00564 { 00565 btDbvtNodeEnumerator nodes; 00566 nodes.nodes.reserve(m_leaves*2); 00567 enumNodes(m_root,nodes); 00568 iwriter->Prepare(m_root,nodes.nodes.size()); 00569 for(int i=0;i<nodes.nodes.size();++i) 00570 { 00571 const btDbvtNode* n=nodes.nodes[i]; 00572 int p=-1; 00573 if(n->parent) p=nodes.nodes.findLinearSearch(n->parent); 00574 if(n->isinternal()) 00575 { 00576 const int c0=nodes.nodes.findLinearSearch(n->childs[0]); 00577 const int c1=nodes.nodes.findLinearSearch(n->childs[1]); 00578 iwriter->WriteNode(n,i,p,c0,c1); 00579 } 00580 else 00581 { 00582 iwriter->WriteLeaf(n,i,p); 00583 } 00584 } 00585 } 00586 00587 // 00588 void btDbvt::clone(btDbvt& dest,IClone* iclone) const 00589 { 00590 dest.clear(); 00591 if(m_root!=0) 00592 { 00593 btAlignedObjectArray<sStkCLN> stack; 00594 stack.reserve(m_leaves); 00595 stack.push_back(sStkCLN(m_root,0)); 00596 do { 00597 const int i=stack.size()-1; 00598 const sStkCLN e=stack[i]; 00599 btDbvtNode* n=createnode(&dest,e.parent,e.node->volume,e.node->data); 00600 stack.pop_back(); 00601 if(e.parent!=0) 00602 e.parent->childs[i&1]=n; 00603 else 00604 dest.m_root=n; 00605 if(e.node->isinternal()) 00606 { 00607 stack.push_back(sStkCLN(e.node->childs[0],n)); 00608 stack.push_back(sStkCLN(e.node->childs[1],n)); 00609 } 00610 else 00611 { 00612 iclone->CloneLeaf(n); 00613 } 00614 } while(stack.size()>0); 00615 } 00616 } 00617 00618 // 00619 int btDbvt::maxdepth(const btDbvtNode* node) 00620 { 00621 int depth=0; 00622 if(node) getmaxdepth(node,1,depth); 00623 return(depth); 00624 } 00625 00626 // 00627 int btDbvt::countLeaves(const btDbvtNode* node) 00628 { 00629 if(node->isinternal()) 00630 return(countLeaves(node->childs[0])+countLeaves(node->childs[1])); 00631 else 00632 return(1); 00633 } 00634 00635 // 00636 void btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves) 00637 { 00638 if(node->isinternal()) 00639 { 00640 extractLeaves(node->childs[0],leaves); 00641 extractLeaves(node->childs[1],leaves); 00642 } 00643 else 00644 { 00645 leaves.push_back(node); 00646 } 00647 } 00648 00649 // 00650 #if DBVT_ENABLE_BENCHMARK 00651 00652 #include <stdio.h> 00653 #include <stdlib.h> 00654 #include "LinearMath/btQuickProf.h" 00655 00656 /* 00657 q6600,2.4ghz 00658 00659 /Ox /Ob2 /Oi /Ot /I "." /I "..\.." /I "..\..\src" /D "NDEBUG" /D "_LIB" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "WIN32" 00660 /GF /FD /MT /GS- /Gy /arch:SSE2 /Zc:wchar_t- /Fp"..\..\out\release8\build\libbulletcollision\libbulletcollision.pch" 00661 /Fo"..\..\out\release8\build\libbulletcollision\\" 00662 /Fd"..\..\out\release8\build\libbulletcollision\bulletcollision.pdb" 00663 /W3 /nologo /c /Wp64 /Zi /errorReport:prompt 00664 00665 Benchmarking dbvt... 00666 World scale: 100.000000 00667 Extents base: 1.000000 00668 Extents range: 4.000000 00669 Leaves: 8192 00670 sizeof(btDbvtVolume): 32 bytes 00671 sizeof(btDbvtNode): 44 bytes 00672 [1] btDbvtVolume intersections: 3499 ms (-1%) 00673 [2] btDbvtVolume merges: 1934 ms (0%) 00674 [3] btDbvt::collideTT: 5485 ms (-21%) 00675 [4] btDbvt::collideTT self: 2814 ms (-20%) 00676 [5] btDbvt::collideTT xform: 7379 ms (-1%) 00677 [6] btDbvt::collideTT xform,self: 7270 ms (-2%) 00678 [7] btDbvt::rayTest: 6314 ms (0%),(332143 r/s) 00679 [8] insert/remove: 2093 ms (0%),(1001983 ir/s) 00680 [9] updates (teleport): 1879 ms (-3%),(1116100 u/s) 00681 [10] updates (jitter): 1244 ms (-4%),(1685813 u/s) 00682 [11] optimize (incremental): 2514 ms (0%),(1668000 o/s) 00683 [12] btDbvtVolume notequal: 3659 ms (0%) 00684 [13] culling(OCL+fullsort): 2218 ms (0%),(461 t/s) 00685 [14] culling(OCL+qsort): 3688 ms (5%),(2221 t/s) 00686 [15] culling(KDOP+qsort): 1139 ms (-1%),(7192 t/s) 00687 [16] insert/remove batch(256): 5092 ms (0%),(823704 bir/s) 00688 [17] btDbvtVolume select: 3419 ms (0%) 00689 */ 00690 00691 struct btDbvtBenchmark 00692 { 00693 struct NilPolicy : btDbvt::ICollide 00694 { 00695 NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true) {} 00696 void Process(const btDbvtNode*,const btDbvtNode*) { ++m_pcount; } 00697 void Process(const btDbvtNode*) { ++m_pcount; } 00698 void Process(const btDbvtNode*,btScalar depth) 00699 { 00700 ++m_pcount; 00701 if(m_checksort) 00702 { if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); } 00703 } 00704 int m_pcount; 00705 btScalar m_depth; 00706 bool m_checksort; 00707 }; 00708 struct P14 : btDbvt::ICollide 00709 { 00710 struct Node 00711 { 00712 const btDbvtNode* leaf; 00713 btScalar depth; 00714 }; 00715 void Process(const btDbvtNode* leaf,btScalar depth) 00716 { 00717 Node n; 00718 n.leaf = leaf; 00719 n.depth = depth; 00720 } 00721 static int sortfnc(const Node& a,const Node& b) 00722 { 00723 if(a.depth<b.depth) return(+1); 00724 if(a.depth>b.depth) return(-1); 00725 return(0); 00726 } 00727 btAlignedObjectArray<Node> m_nodes; 00728 }; 00729 struct P15 : btDbvt::ICollide 00730 { 00731 struct Node 00732 { 00733 const btDbvtNode* leaf; 00734 btScalar depth; 00735 }; 00736 void Process(const btDbvtNode* leaf) 00737 { 00738 Node n; 00739 n.leaf = leaf; 00740 n.depth = dot(leaf->volume.Center(),m_axis); 00741 } 00742 static int sortfnc(const Node& a,const Node& b) 00743 { 00744 if(a.depth<b.depth) return(+1); 00745 if(a.depth>b.depth) return(-1); 00746 return(0); 00747 } 00748 btAlignedObjectArray<Node> m_nodes; 00749 btVector3 m_axis; 00750 }; 00751 static btScalar RandUnit() 00752 { 00753 return(rand()/(btScalar)RAND_MAX); 00754 } 00755 static btVector3 RandVector3() 00756 { 00757 return(btVector3(RandUnit(),RandUnit(),RandUnit())); 00758 } 00759 static btVector3 RandVector3(btScalar cs) 00760 { 00761 return(RandVector3()*cs-btVector3(cs,cs,cs)/2); 00762 } 00763 static btDbvtVolume RandVolume(btScalar cs,btScalar eb,btScalar es) 00764 { 00765 return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es)); 00766 } 00767 static btTransform RandTransform(btScalar cs) 00768 { 00769 btTransform t; 00770 t.setOrigin(RandVector3(cs)); 00771 t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized()); 00772 return(t); 00773 } 00774 static void RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt) 00775 { 00776 dbvt.clear(); 00777 for(int i=0;i<leaves;++i) 00778 { 00779 dbvt.insert(RandVolume(cs,eb,es),0); 00780 } 00781 } 00782 }; 00783 00784 void btDbvt::benchmark() 00785 { 00786 static const btScalar cfgVolumeCenterScale = 100; 00787 static const btScalar cfgVolumeExentsBase = 1; 00788 static const btScalar cfgVolumeExentsScale = 4; 00789 static const int cfgLeaves = 8192; 00790 static const bool cfgEnable = true; 00791 00792 //[1] btDbvtVolume intersections 00793 bool cfgBenchmark1_Enable = cfgEnable; 00794 static const int cfgBenchmark1_Iterations = 8; 00795 static const int cfgBenchmark1_Reference = 3499; 00796 //[2] btDbvtVolume merges 00797 bool cfgBenchmark2_Enable = cfgEnable; 00798 static const int cfgBenchmark2_Iterations = 4; 00799 static const int cfgBenchmark2_Reference = 1945; 00800 //[3] btDbvt::collideTT 00801 bool cfgBenchmark3_Enable = cfgEnable; 00802 static const int cfgBenchmark3_Iterations = 512; 00803 static const int cfgBenchmark3_Reference = 5485; 00804 //[4] btDbvt::collideTT self 00805 bool cfgBenchmark4_Enable = cfgEnable; 00806 static const int cfgBenchmark4_Iterations = 512; 00807 static const int cfgBenchmark4_Reference = 2814; 00808 //[5] btDbvt::collideTT xform 00809 bool cfgBenchmark5_Enable = cfgEnable; 00810 static const int cfgBenchmark5_Iterations = 512; 00811 static const btScalar cfgBenchmark5_OffsetScale = 2; 00812 static const int cfgBenchmark5_Reference = 7379; 00813 //[6] btDbvt::collideTT xform,self 00814 bool cfgBenchmark6_Enable = cfgEnable; 00815 static const int cfgBenchmark6_Iterations = 512; 00816 static const btScalar cfgBenchmark6_OffsetScale = 2; 00817 static const int cfgBenchmark6_Reference = 7270; 00818 //[7] btDbvt::rayTest 00819 bool cfgBenchmark7_Enable = cfgEnable; 00820 static const int cfgBenchmark7_Passes = 32; 00821 static const int cfgBenchmark7_Iterations = 65536; 00822 static const int cfgBenchmark7_Reference = 6307; 00823 //[8] insert/remove 00824 bool cfgBenchmark8_Enable = cfgEnable; 00825 static const int cfgBenchmark8_Passes = 32; 00826 static const int cfgBenchmark8_Iterations = 65536; 00827 static const int cfgBenchmark8_Reference = 2105; 00828 //[9] updates (teleport) 00829 bool cfgBenchmark9_Enable = cfgEnable; 00830 static const int cfgBenchmark9_Passes = 32; 00831 static const int cfgBenchmark9_Iterations = 65536; 00832 static const int cfgBenchmark9_Reference = 1879; 00833 //[10] updates (jitter) 00834 bool cfgBenchmark10_Enable = cfgEnable; 00835 static const btScalar cfgBenchmark10_Scale = cfgVolumeCenterScale/10000; 00836 static const int cfgBenchmark10_Passes = 32; 00837 static const int cfgBenchmark10_Iterations = 65536; 00838 static const int cfgBenchmark10_Reference = 1244; 00839 //[11] optimize (incremental) 00840 bool cfgBenchmark11_Enable = cfgEnable; 00841 static const int cfgBenchmark11_Passes = 64; 00842 static const int cfgBenchmark11_Iterations = 65536; 00843 static const int cfgBenchmark11_Reference = 2510; 00844 //[12] btDbvtVolume notequal 00845 bool cfgBenchmark12_Enable = cfgEnable; 00846 static const int cfgBenchmark12_Iterations = 32; 00847 static const int cfgBenchmark12_Reference = 3677; 00848 //[13] culling(OCL+fullsort) 00849 bool cfgBenchmark13_Enable = cfgEnable; 00850 static const int cfgBenchmark13_Iterations = 1024; 00851 static const int cfgBenchmark13_Reference = 2231; 00852 //[14] culling(OCL+qsort) 00853 bool cfgBenchmark14_Enable = cfgEnable; 00854 static const int cfgBenchmark14_Iterations = 8192; 00855 static const int cfgBenchmark14_Reference = 3500; 00856 //[15] culling(KDOP+qsort) 00857 bool cfgBenchmark15_Enable = cfgEnable; 00858 static const int cfgBenchmark15_Iterations = 8192; 00859 static const int cfgBenchmark15_Reference = 1151; 00860 //[16] insert/remove batch 00861 bool cfgBenchmark16_Enable = cfgEnable; 00862 static const int cfgBenchmark16_BatchCount = 256; 00863 static const int cfgBenchmark16_Passes = 16384; 00864 static const int cfgBenchmark16_Reference = 5138; 00865 //[17] select 00866 bool cfgBenchmark17_Enable = cfgEnable; 00867 static const int cfgBenchmark17_Iterations = 4; 00868 static const int cfgBenchmark17_Reference = 3390; 00869 00870 btClock wallclock; 00871 printf("Benchmarking dbvt...\r\n"); 00872 printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale); 00873 printf("\tExtents base: %f\r\n",cfgVolumeExentsBase); 00874 printf("\tExtents range: %f\r\n",cfgVolumeExentsScale); 00875 printf("\tLeaves: %u\r\n",cfgLeaves); 00876 printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume)); 00877 printf("\tsizeof(btDbvtNode): %u bytes\r\n",sizeof(btDbvtNode)); 00878 if(cfgBenchmark1_Enable) 00879 {// Benchmark 1 00880 srand(380843); 00881 btAlignedObjectArray<btDbvtVolume> volumes; 00882 btAlignedObjectArray<bool> results; 00883 volumes.resize(cfgLeaves); 00884 results.resize(cfgLeaves); 00885 for(int i=0;i<cfgLeaves;++i) 00886 { 00887 volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); 00888 } 00889 printf("[1] btDbvtVolume intersections: "); 00890 wallclock.reset(); 00891 for(int i=0;i<cfgBenchmark1_Iterations;++i) 00892 { 00893 for(int j=0;j<cfgLeaves;++j) 00894 { 00895 for(int k=0;k<cfgLeaves;++k) 00896 { 00897 results[k]=Intersect(volumes[j],volumes[k]); 00898 } 00899 } 00900 } 00901 const int time=(int)wallclock.getTimeMilliseconds(); 00902 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time); 00903 } 00904 if(cfgBenchmark2_Enable) 00905 {// Benchmark 2 00906 srand(380843); 00907 btAlignedObjectArray<btDbvtVolume> volumes; 00908 btAlignedObjectArray<btDbvtVolume> results; 00909 volumes.resize(cfgLeaves); 00910 results.resize(cfgLeaves); 00911 for(int i=0;i<cfgLeaves;++i) 00912 { 00913 volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); 00914 } 00915 printf("[2] btDbvtVolume merges: "); 00916 wallclock.reset(); 00917 for(int i=0;i<cfgBenchmark2_Iterations;++i) 00918 { 00919 for(int j=0;j<cfgLeaves;++j) 00920 { 00921 for(int k=0;k<cfgLeaves;++k) 00922 { 00923 Merge(volumes[j],volumes[k],results[k]); 00924 } 00925 } 00926 } 00927 const int time=(int)wallclock.getTimeMilliseconds(); 00928 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time); 00929 } 00930 if(cfgBenchmark3_Enable) 00931 {// Benchmark 3 00932 srand(380843); 00933 btDbvt dbvt[2]; 00934 btDbvtBenchmark::NilPolicy policy; 00935 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]); 00936 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]); 00937 dbvt[0].optimizeTopDown(); 00938 dbvt[1].optimizeTopDown(); 00939 printf("[3] btDbvt::collideTT: "); 00940 wallclock.reset(); 00941 for(int i=0;i<cfgBenchmark3_Iterations;++i) 00942 { 00943 btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy); 00944 } 00945 const int time=(int)wallclock.getTimeMilliseconds(); 00946 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time); 00947 } 00948 if(cfgBenchmark4_Enable) 00949 {// Benchmark 4 00950 srand(380843); 00951 btDbvt dbvt; 00952 btDbvtBenchmark::NilPolicy policy; 00953 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 00954 dbvt.optimizeTopDown(); 00955 printf("[4] btDbvt::collideTT self: "); 00956 wallclock.reset(); 00957 for(int i=0;i<cfgBenchmark4_Iterations;++i) 00958 { 00959 btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy); 00960 } 00961 const int time=(int)wallclock.getTimeMilliseconds(); 00962 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time); 00963 } 00964 if(cfgBenchmark5_Enable) 00965 {// Benchmark 5 00966 srand(380843); 00967 btDbvt dbvt[2]; 00968 btAlignedObjectArray<btTransform> transforms; 00969 btDbvtBenchmark::NilPolicy policy; 00970 transforms.resize(cfgBenchmark5_Iterations); 00971 for(int i=0;i<transforms.size();++i) 00972 { 00973 transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale); 00974 } 00975 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]); 00976 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]); 00977 dbvt[0].optimizeTopDown(); 00978 dbvt[1].optimizeTopDown(); 00979 printf("[5] btDbvt::collideTT xform: "); 00980 wallclock.reset(); 00981 for(int i=0;i<cfgBenchmark5_Iterations;++i) 00982 { 00983 btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy); 00984 } 00985 const int time=(int)wallclock.getTimeMilliseconds(); 00986 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time); 00987 } 00988 if(cfgBenchmark6_Enable) 00989 {// Benchmark 6 00990 srand(380843); 00991 btDbvt dbvt; 00992 btAlignedObjectArray<btTransform> transforms; 00993 btDbvtBenchmark::NilPolicy policy; 00994 transforms.resize(cfgBenchmark6_Iterations); 00995 for(int i=0;i<transforms.size();++i) 00996 { 00997 transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale); 00998 } 00999 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 01000 dbvt.optimizeTopDown(); 01001 printf("[6] btDbvt::collideTT xform,self: "); 01002 wallclock.reset(); 01003 for(int i=0;i<cfgBenchmark6_Iterations;++i) 01004 { 01005 btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy); 01006 } 01007 const int time=(int)wallclock.getTimeMilliseconds(); 01008 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time); 01009 } 01010 if(cfgBenchmark7_Enable) 01011 {// Benchmark 7 01012 srand(380843); 01013 btDbvt dbvt; 01014 btAlignedObjectArray<btVector3> rayorg; 01015 btAlignedObjectArray<btVector3> raydir; 01016 btDbvtBenchmark::NilPolicy policy; 01017 rayorg.resize(cfgBenchmark7_Iterations); 01018 raydir.resize(cfgBenchmark7_Iterations); 01019 for(int i=0;i<rayorg.size();++i) 01020 { 01021 rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2); 01022 raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2); 01023 } 01024 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 01025 dbvt.optimizeTopDown(); 01026 printf("[7] btDbvt::rayTest: "); 01027 wallclock.reset(); 01028 for(int i=0;i<cfgBenchmark7_Passes;++i) 01029 { 01030 for(int j=0;j<cfgBenchmark7_Iterations;++j) 01031 { 01032 btDbvt::rayTest(dbvt.m_root,rayorg[j],rayorg[j]+raydir[j],policy); 01033 } 01034 } 01035 const int time=(int)wallclock.getTimeMilliseconds(); 01036 unsigned rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations; 01037 printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time); 01038 } 01039 if(cfgBenchmark8_Enable) 01040 {// Benchmark 8 01041 srand(380843); 01042 btDbvt dbvt; 01043 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 01044 dbvt.optimizeTopDown(); 01045 printf("[8] insert/remove: "); 01046 wallclock.reset(); 01047 for(int i=0;i<cfgBenchmark8_Passes;++i) 01048 { 01049 for(int j=0;j<cfgBenchmark8_Iterations;++j) 01050 { 01051 dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0)); 01052 } 01053 } 01054 const int time=(int)wallclock.getTimeMilliseconds(); 01055 const int ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations; 01056 printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time); 01057 } 01058 if(cfgBenchmark9_Enable) 01059 {// Benchmark 9 01060 srand(380843); 01061 btDbvt dbvt; 01062 btAlignedObjectArray<const btDbvtNode*> leaves; 01063 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 01064 dbvt.optimizeTopDown(); 01065 dbvt.extractLeaves(dbvt.m_root,leaves); 01066 printf("[9] updates (teleport): "); 01067 wallclock.reset(); 01068 for(int i=0;i<cfgBenchmark9_Passes;++i) 01069 { 01070 for(int j=0;j<cfgBenchmark9_Iterations;++j) 01071 { 01072 dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]), 01073 btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale)); 01074 } 01075 } 01076 const int time=(int)wallclock.getTimeMilliseconds(); 01077 const int up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations; 01078 printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time); 01079 } 01080 if(cfgBenchmark10_Enable) 01081 {// Benchmark 10 01082 srand(380843); 01083 btDbvt dbvt; 01084 btAlignedObjectArray<const btDbvtNode*> leaves; 01085 btAlignedObjectArray<btVector3> vectors; 01086 vectors.resize(cfgBenchmark10_Iterations); 01087 for(int i=0;i<vectors.size();++i) 01088 { 01089 vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale; 01090 } 01091 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 01092 dbvt.optimizeTopDown(); 01093 dbvt.extractLeaves(dbvt.m_root,leaves); 01094 printf("[10] updates (jitter): "); 01095 wallclock.reset(); 01096 01097 for(int i=0;i<cfgBenchmark10_Passes;++i) 01098 { 01099 for(int j=0;j<cfgBenchmark10_Iterations;++j) 01100 { 01101 const btVector3& d=vectors[j]; 01102 btDbvtNode* l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]); 01103 btDbvtVolume v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d); 01104 dbvt.update(l,v); 01105 } 01106 } 01107 const int time=(int)wallclock.getTimeMilliseconds(); 01108 const int up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations; 01109 printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time); 01110 } 01111 if(cfgBenchmark11_Enable) 01112 {// Benchmark 11 01113 srand(380843); 01114 btDbvt dbvt; 01115 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 01116 dbvt.optimizeTopDown(); 01117 printf("[11] optimize (incremental): "); 01118 wallclock.reset(); 01119 for(int i=0;i<cfgBenchmark11_Passes;++i) 01120 { 01121 dbvt.optimizeIncremental(cfgBenchmark11_Iterations); 01122 } 01123 const int time=(int)wallclock.getTimeMilliseconds(); 01124 const int op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations; 01125 printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000); 01126 } 01127 if(cfgBenchmark12_Enable) 01128 {// Benchmark 12 01129 srand(380843); 01130 btAlignedObjectArray<btDbvtVolume> volumes; 01131 btAlignedObjectArray<bool> results; 01132 volumes.resize(cfgLeaves); 01133 results.resize(cfgLeaves); 01134 for(int i=0;i<cfgLeaves;++i) 01135 { 01136 volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); 01137 } 01138 printf("[12] btDbvtVolume notequal: "); 01139 wallclock.reset(); 01140 for(int i=0;i<cfgBenchmark12_Iterations;++i) 01141 { 01142 for(int j=0;j<cfgLeaves;++j) 01143 { 01144 for(int k=0;k<cfgLeaves;++k) 01145 { 01146 results[k]=NotEqual(volumes[j],volumes[k]); 01147 } 01148 } 01149 } 01150 const int time=(int)wallclock.getTimeMilliseconds(); 01151 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time); 01152 } 01153 if(cfgBenchmark13_Enable) 01154 {// Benchmark 13 01155 srand(380843); 01156 btDbvt dbvt; 01157 btAlignedObjectArray<btVector3> vectors; 01158 btDbvtBenchmark::NilPolicy policy; 01159 vectors.resize(cfgBenchmark13_Iterations); 01160 for(int i=0;i<vectors.size();++i) 01161 { 01162 vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized(); 01163 } 01164 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 01165 dbvt.optimizeTopDown(); 01166 printf("[13] culling(OCL+fullsort): "); 01167 wallclock.reset(); 01168 for(int i=0;i<cfgBenchmark13_Iterations;++i) 01169 { 01170 static const btScalar offset=0; 01171 policy.m_depth=-SIMD_INFINITY; 01172 dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy); 01173 } 01174 const int time=(int)wallclock.getTimeMilliseconds(); 01175 const int t=cfgBenchmark13_Iterations; 01176 printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time); 01177 } 01178 if(cfgBenchmark14_Enable) 01179 {// Benchmark 14 01180 srand(380843); 01181 btDbvt dbvt; 01182 btAlignedObjectArray<btVector3> vectors; 01183 btDbvtBenchmark::P14 policy; 01184 vectors.resize(cfgBenchmark14_Iterations); 01185 for(int i=0;i<vectors.size();++i) 01186 { 01187 vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized(); 01188 } 01189 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 01190 dbvt.optimizeTopDown(); 01191 policy.m_nodes.reserve(cfgLeaves); 01192 printf("[14] culling(OCL+qsort): "); 01193 wallclock.reset(); 01194 for(int i=0;i<cfgBenchmark14_Iterations;++i) 01195 { 01196 static const btScalar offset=0; 01197 policy.m_nodes.resize(0); 01198 dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false); 01199 policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc); 01200 } 01201 const int time=(int)wallclock.getTimeMilliseconds(); 01202 const int t=cfgBenchmark14_Iterations; 01203 printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time); 01204 } 01205 if(cfgBenchmark15_Enable) 01206 {// Benchmark 15 01207 srand(380843); 01208 btDbvt dbvt; 01209 btAlignedObjectArray<btVector3> vectors; 01210 btDbvtBenchmark::P15 policy; 01211 vectors.resize(cfgBenchmark15_Iterations); 01212 for(int i=0;i<vectors.size();++i) 01213 { 01214 vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized(); 01215 } 01216 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 01217 dbvt.optimizeTopDown(); 01218 policy.m_nodes.reserve(cfgLeaves); 01219 printf("[15] culling(KDOP+qsort): "); 01220 wallclock.reset(); 01221 for(int i=0;i<cfgBenchmark15_Iterations;++i) 01222 { 01223 static const btScalar offset=0; 01224 policy.m_nodes.resize(0); 01225 policy.m_axis=vectors[i]; 01226 dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy); 01227 policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc); 01228 } 01229 const int time=(int)wallclock.getTimeMilliseconds(); 01230 const int t=cfgBenchmark15_Iterations; 01231 printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time); 01232 } 01233 if(cfgBenchmark16_Enable) 01234 {// Benchmark 16 01235 srand(380843); 01236 btDbvt dbvt; 01237 btAlignedObjectArray<btDbvtNode*> batch; 01238 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 01239 dbvt.optimizeTopDown(); 01240 batch.reserve(cfgBenchmark16_BatchCount); 01241 printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount); 01242 wallclock.reset(); 01243 for(int i=0;i<cfgBenchmark16_Passes;++i) 01244 { 01245 for(int j=0;j<cfgBenchmark16_BatchCount;++j) 01246 { 01247 batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0)); 01248 } 01249 for(int j=0;j<cfgBenchmark16_BatchCount;++j) 01250 { 01251 dbvt.remove(batch[j]); 01252 } 01253 batch.resize(0); 01254 } 01255 const int time=(int)wallclock.getTimeMilliseconds(); 01256 const int ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount; 01257 printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time)); 01258 } 01259 if(cfgBenchmark17_Enable) 01260 {// Benchmark 17 01261 srand(380843); 01262 btAlignedObjectArray<btDbvtVolume> volumes; 01263 btAlignedObjectArray<int> results; 01264 btAlignedObjectArray<int> indices; 01265 volumes.resize(cfgLeaves); 01266 results.resize(cfgLeaves); 01267 indices.resize(cfgLeaves); 01268 for(int i=0;i<cfgLeaves;++i) 01269 { 01270 indices[i]=i; 01271 volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); 01272 } 01273 for(int i=0;i<cfgLeaves;++i) 01274 { 01275 btSwap(indices[i],indices[rand()%cfgLeaves]); 01276 } 01277 printf("[17] btDbvtVolume select: "); 01278 wallclock.reset(); 01279 for(int i=0;i<cfgBenchmark17_Iterations;++i) 01280 { 01281 for(int j=0;j<cfgLeaves;++j) 01282 { 01283 for(int k=0;k<cfgLeaves;++k) 01284 { 01285 const int idx=indices[k]; 01286 results[idx]=Select(volumes[idx],volumes[j],volumes[k]); 01287 } 01288 } 01289 } 01290 const int time=(int)wallclock.getTimeMilliseconds(); 01291 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time); 01292 } 01293 printf("\r\n\r\n"); 01294 } 01295 #endif