Blender V2.61 - r43446

btDbvt.cpp

Go to the documentation of this file.
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