00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
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
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
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
00793 bool cfgBenchmark1_Enable = cfgEnable;
00794 static const int cfgBenchmark1_Iterations = 8;
00795 static const int cfgBenchmark1_Reference = 3499;
00796
00797 bool cfgBenchmark2_Enable = cfgEnable;
00798 static const int cfgBenchmark2_Iterations = 4;
00799 static const int cfgBenchmark2_Reference = 1945;
00800
00801 bool cfgBenchmark3_Enable = cfgEnable;
00802 static const int cfgBenchmark3_Iterations = 512;
00803 static const int cfgBenchmark3_Reference = 5485;
00804
00805 bool cfgBenchmark4_Enable = cfgEnable;
00806 static const int cfgBenchmark4_Iterations = 512;
00807 static const int cfgBenchmark4_Reference = 2814;
00808
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
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
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
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
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
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
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
00845 bool cfgBenchmark12_Enable = cfgEnable;
00846 static const int cfgBenchmark12_Iterations = 32;
00847 static const int cfgBenchmark12_Reference = 3677;
00848
00849 bool cfgBenchmark13_Enable = cfgEnable;
00850 static const int cfgBenchmark13_Iterations = 1024;
00851 static const int cfgBenchmark13_Reference = 2231;
00852
00853 bool cfgBenchmark14_Enable = cfgEnable;
00854 static const int cfgBenchmark14_Iterations = 8192;
00855 static const int cfgBenchmark14_Reference = 3500;
00856
00857 bool cfgBenchmark15_Enable = cfgEnable;
00858 static const int cfgBenchmark15_Iterations = 8192;
00859 static const int cfgBenchmark15_Reference = 1151;
00860
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
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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