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