Blender V2.61 - r43446

btDbvt.h

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2007 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 #ifndef BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
00018 #define BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
00019 
00020 #include "LinearMath/btAlignedObjectArray.h"
00021 #include "LinearMath/btVector3.h"
00022 #include "LinearMath/btTransform.h"
00023 #include "LinearMath/btAabbUtil2.h"
00024 
00025 //
00026 // Compile time configuration
00027 //
00028 
00029 
00030 // Implementation profiles
00031 #define DBVT_IMPL_GENERIC       0   // Generic implementation   
00032 #define DBVT_IMPL_SSE           1   // SSE
00033 
00034 // Template implementation of ICollide
00035 #ifdef _WIN32
00036 #if (defined (_MSC_VER) && _MSC_VER >= 1400)
00037 #define DBVT_USE_TEMPLATE       1
00038 #else
00039 #define DBVT_USE_TEMPLATE       0
00040 #endif
00041 #else
00042 #define DBVT_USE_TEMPLATE       0
00043 #endif
00044 
00045 // Use only intrinsics instead of inline asm
00046 #define DBVT_USE_INTRINSIC_SSE  1
00047 
00048 // Using memmov for collideOCL
00049 #define DBVT_USE_MEMMOVE        1
00050 
00051 // Enable benchmarking code
00052 #define DBVT_ENABLE_BENCHMARK   0
00053 
00054 // Inlining
00055 #define DBVT_INLINE             SIMD_FORCE_INLINE
00056 
00057 // Specific methods implementation
00058 
00059 //SSE gives errors on a MSVC 7.1
00060 #if defined (BT_USE_SSE) && defined (_WIN32)
00061 #define DBVT_SELECT_IMPL        DBVT_IMPL_SSE
00062 #define DBVT_MERGE_IMPL         DBVT_IMPL_SSE
00063 #define DBVT_INT0_IMPL          DBVT_IMPL_SSE
00064 #else
00065 #define DBVT_SELECT_IMPL        DBVT_IMPL_GENERIC
00066 #define DBVT_MERGE_IMPL         DBVT_IMPL_GENERIC
00067 #define DBVT_INT0_IMPL          DBVT_IMPL_GENERIC
00068 #endif
00069 
00070 #if (DBVT_SELECT_IMPL==DBVT_IMPL_SSE)|| \
00071     (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)||  \
00072     (DBVT_INT0_IMPL==DBVT_IMPL_SSE)
00073 #include <emmintrin.h>
00074 #endif
00075 
00076 //
00077 // Auto config and checks
00078 //
00079 
00080 #if DBVT_USE_TEMPLATE
00081 #define DBVT_VIRTUAL
00082 #define DBVT_VIRTUAL_DTOR(a)
00083 #define DBVT_PREFIX                 template <typename T>
00084 #define DBVT_IPOLICY                T& policy
00085 #define DBVT_CHECKTYPE              static const ICollide&  typechecker=*(T*)1;(void)typechecker;
00086 #else
00087 #define DBVT_VIRTUAL_DTOR(a)        virtual ~a() {}
00088 #define DBVT_VIRTUAL                virtual
00089 #define DBVT_PREFIX
00090 #define DBVT_IPOLICY                ICollide& policy
00091 #define DBVT_CHECKTYPE
00092 #endif
00093 
00094 #if DBVT_USE_MEMMOVE
00095 #if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
00096 #include <memory.h>
00097 #endif
00098 #include <string.h>
00099 #endif
00100 
00101 #ifndef DBVT_USE_TEMPLATE
00102 #error "DBVT_USE_TEMPLATE undefined"
00103 #endif
00104 
00105 #ifndef DBVT_USE_MEMMOVE
00106 #error "DBVT_USE_MEMMOVE undefined"
00107 #endif
00108 
00109 #ifndef DBVT_ENABLE_BENCHMARK
00110 #error "DBVT_ENABLE_BENCHMARK undefined"
00111 #endif
00112 
00113 #ifndef DBVT_SELECT_IMPL
00114 #error "DBVT_SELECT_IMPL undefined"
00115 #endif
00116 
00117 #ifndef DBVT_MERGE_IMPL
00118 #error "DBVT_MERGE_IMPL undefined"
00119 #endif
00120 
00121 #ifndef DBVT_INT0_IMPL
00122 #error "DBVT_INT0_IMPL undefined"
00123 #endif
00124 
00125 //
00126 // Defaults volumes
00127 //
00128 
00129 /* btDbvtAabbMm         */ 
00130 struct  btDbvtAabbMm
00131 {
00132     DBVT_INLINE btVector3           Center() const  { return((mi+mx)/2); }
00133     DBVT_INLINE btVector3           Lengths() const { return(mx-mi); }
00134     DBVT_INLINE btVector3           Extents() const { return((mx-mi)/2); }
00135     DBVT_INLINE const btVector3&    Mins() const    { return(mi); }
00136     DBVT_INLINE const btVector3&    Maxs() const    { return(mx); }
00137     static inline btDbvtAabbMm      FromCE(const btVector3& c,const btVector3& e);
00138     static inline btDbvtAabbMm      FromCR(const btVector3& c,btScalar r);
00139     static inline btDbvtAabbMm      FromMM(const btVector3& mi,const btVector3& mx);
00140     static inline btDbvtAabbMm      FromPoints(const btVector3* pts,int n);
00141     static inline btDbvtAabbMm      FromPoints(const btVector3** ppts,int n);
00142     DBVT_INLINE void                Expand(const btVector3& e);
00143     DBVT_INLINE void                SignedExpand(const btVector3& e);
00144     DBVT_INLINE bool                Contain(const btDbvtAabbMm& a) const;
00145     DBVT_INLINE int                 Classify(const btVector3& n,btScalar o,int s) const;
00146     DBVT_INLINE btScalar            ProjectMinimum(const btVector3& v,unsigned signs) const;
00147     DBVT_INLINE friend bool         Intersect(  const btDbvtAabbMm& a,
00148         const btDbvtAabbMm& b);
00149     
00150     DBVT_INLINE friend bool         Intersect(  const btDbvtAabbMm& a,
00151         const btVector3& b);
00152 
00153     DBVT_INLINE friend btScalar     Proximity(  const btDbvtAabbMm& a,
00154         const btDbvtAabbMm& b);
00155     DBVT_INLINE friend int          Select(     const btDbvtAabbMm& o,
00156         const btDbvtAabbMm& a,
00157         const btDbvtAabbMm& b);
00158     DBVT_INLINE friend void         Merge(      const btDbvtAabbMm& a,
00159         const btDbvtAabbMm& b,
00160         btDbvtAabbMm& r);
00161     DBVT_INLINE friend bool         NotEqual(   const btDbvtAabbMm& a,
00162         const btDbvtAabbMm& b);
00163 private:
00164     DBVT_INLINE void                AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
00165 private:
00166     btVector3   mi,mx;
00167 };
00168 
00169 // Types    
00170 typedef btDbvtAabbMm    btDbvtVolume;
00171 
00172 /* btDbvtNode               */ 
00173 struct  btDbvtNode
00174 {
00175     btDbvtVolume    volume;
00176     btDbvtNode*     parent;
00177     DBVT_INLINE bool    isleaf() const      { return(childs[1]==0); }
00178     DBVT_INLINE bool    isinternal() const  { return(!isleaf()); }
00179     union
00180     {
00181         btDbvtNode* childs[2];
00182         void*   data;
00183         int     dataAsInt;
00184     };
00185 };
00186 
00190 struct  btDbvt
00191 {
00192     /* Stack element    */ 
00193     struct  sStkNN
00194     {
00195         const btDbvtNode*   a;
00196         const btDbvtNode*   b;
00197         sStkNN() {}
00198         sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {}
00199     };
00200     struct  sStkNP
00201     {
00202         const btDbvtNode*   node;
00203         int         mask;
00204         sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {}
00205     };
00206     struct  sStkNPS
00207     {
00208         const btDbvtNode*   node;
00209         int         mask;
00210         btScalar    value;
00211         sStkNPS() {}
00212         sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {}
00213     };
00214     struct  sStkCLN
00215     {
00216         const btDbvtNode*   node;
00217         btDbvtNode*     parent;
00218         sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {}
00219     };
00220     // Policies/Interfaces
00221 
00222     /* ICollide */ 
00223     struct  ICollide
00224     {       
00225         DBVT_VIRTUAL_DTOR(ICollide)
00226             DBVT_VIRTUAL void   Process(const btDbvtNode*,const btDbvtNode*)        {}
00227         DBVT_VIRTUAL void   Process(const btDbvtNode*)                  {}
00228         DBVT_VIRTUAL void   Process(const btDbvtNode* n,btScalar)           { Process(n); }
00229         DBVT_VIRTUAL bool   Descent(const btDbvtNode*)                  { return(true); }
00230         DBVT_VIRTUAL bool   AllLeaves(const btDbvtNode*)                    { return(true); }
00231     };
00232     /* IWriter  */ 
00233     struct  IWriter
00234     {
00235         virtual ~IWriter() {}
00236         virtual void        Prepare(const btDbvtNode* root,int numnodes)=0;
00237         virtual void        WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0;
00238         virtual void        WriteLeaf(const btDbvtNode*,int index,int parent)=0;
00239     };
00240     /* IClone   */ 
00241     struct  IClone
00242     {
00243         virtual ~IClone()   {}
00244         virtual void        CloneLeaf(btDbvtNode*) {}
00245     };
00246 
00247     // Constants
00248     enum    {
00249         SIMPLE_STACKSIZE    =   64,
00250         DOUBLE_STACKSIZE    =   SIMPLE_STACKSIZE*2
00251     };
00252 
00253     // Fields
00254     btDbvtNode*     m_root;
00255     btDbvtNode*     m_free;
00256     int             m_lkhd;
00257     int             m_leaves;
00258     unsigned        m_opath;
00259 
00260     
00261     btAlignedObjectArray<sStkNN>    m_stkStack;
00262 
00263 
00264     // Methods
00265     btDbvt();
00266     ~btDbvt();
00267     void            clear();
00268     bool            empty() const { return(0==m_root); }
00269     void            optimizeBottomUp();
00270     void            optimizeTopDown(int bu_treshold=128);
00271     void            optimizeIncremental(int passes);
00272     btDbvtNode*     insert(const btDbvtVolume& box,void* data);
00273     void            update(btDbvtNode* leaf,int lookahead=-1);
00274     void            update(btDbvtNode* leaf,btDbvtVolume& volume);
00275     bool            update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin);
00276     bool            update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity);
00277     bool            update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin);  
00278     void            remove(btDbvtNode* leaf);
00279     void            write(IWriter* iwriter) const;
00280     void            clone(btDbvt& dest,IClone* iclone=0) const;
00281     static int      maxdepth(const btDbvtNode* node);
00282     static int      countLeaves(const btDbvtNode* node);
00283     static void     extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves);
00284 #if DBVT_ENABLE_BENCHMARK
00285     static void     benchmark();
00286 #else
00287     static void     benchmark(){}
00288 #endif
00289     // DBVT_IPOLICY must support ICollide policy/interface
00290     DBVT_PREFIX
00291         static void     enumNodes(  const btDbvtNode* root,
00292         DBVT_IPOLICY);
00293     DBVT_PREFIX
00294         static void     enumLeaves( const btDbvtNode* root,
00295         DBVT_IPOLICY);
00296     DBVT_PREFIX
00297         void        collideTT(  const btDbvtNode* root0,
00298         const btDbvtNode* root1,
00299         DBVT_IPOLICY);
00300 
00301     DBVT_PREFIX
00302         void        collideTTpersistentStack(   const btDbvtNode* root0,
00303           const btDbvtNode* root1,
00304           DBVT_IPOLICY);
00305 #if 0
00306     DBVT_PREFIX
00307         void        collideTT(  const btDbvtNode* root0,
00308         const btDbvtNode* root1,
00309         const btTransform& xform,
00310         DBVT_IPOLICY);
00311     DBVT_PREFIX
00312         void        collideTT(  const btDbvtNode* root0,
00313         const btTransform& xform0,
00314         const btDbvtNode* root1,
00315         const btTransform& xform1,
00316         DBVT_IPOLICY);
00317 #endif
00318 
00319     DBVT_PREFIX
00320         void        collideTV(  const btDbvtNode* root,
00321         const btDbvtVolume& volume,
00322         DBVT_IPOLICY);
00325     DBVT_PREFIX
00326         static void     rayTest(    const btDbvtNode* root,
00327         const btVector3& rayFrom,
00328         const btVector3& rayTo,
00329         DBVT_IPOLICY);
00332     DBVT_PREFIX
00333         void        rayTestInternal(    const btDbvtNode* root,
00334                                 const btVector3& rayFrom,
00335                                 const btVector3& rayTo,
00336                                 const btVector3& rayDirectionInverse,
00337                                 unsigned int signs[3],
00338                                 btScalar lambda_max,
00339                                 const btVector3& aabbMin,
00340                                 const btVector3& aabbMax,
00341                                 DBVT_IPOLICY) const;
00342 
00343     DBVT_PREFIX
00344         static void     collideKDOP(const btDbvtNode* root,
00345         const btVector3* normals,
00346         const btScalar* offsets,
00347         int count,
00348         DBVT_IPOLICY);
00349     DBVT_PREFIX
00350         static void     collideOCL( const btDbvtNode* root,
00351         const btVector3* normals,
00352         const btScalar* offsets,
00353         const btVector3& sortaxis,
00354         int count,                              
00355         DBVT_IPOLICY,
00356         bool fullsort=true);
00357     DBVT_PREFIX
00358         static void     collideTU(  const btDbvtNode* root,
00359         DBVT_IPOLICY);
00360     // Helpers  
00361     static DBVT_INLINE int  nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h)
00362     {
00363         int m=0;
00364         while(l<h)
00365         {
00366             m=(l+h)>>1;
00367             if(a[i[m]].value>=v) l=m+1; else h=m;
00368         }
00369         return(h);
00370     }
00371     static DBVT_INLINE int  allocate(   btAlignedObjectArray<int>& ifree,
00372         btAlignedObjectArray<sStkNPS>& stock,
00373         const sStkNPS& value)
00374     {
00375         int i;
00376         if(ifree.size()>0)
00377         { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }
00378         else
00379         { i=stock.size();stock.push_back(value); }
00380         return(i); 
00381     }
00382     //
00383 private:
00384     btDbvt(const btDbvt&)   {}  
00385 };
00386 
00387 //
00388 // Inline's
00389 //
00390 
00391 //
00392 inline btDbvtAabbMm         btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e)
00393 {
00394     btDbvtAabbMm box;
00395     box.mi=c-e;box.mx=c+e;
00396     return(box);
00397 }
00398 
00399 //
00400 inline btDbvtAabbMm         btDbvtAabbMm::FromCR(const btVector3& c,btScalar r)
00401 {
00402     return(FromCE(c,btVector3(r,r,r)));
00403 }
00404 
00405 //
00406 inline btDbvtAabbMm         btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx)
00407 {
00408     btDbvtAabbMm box;
00409     box.mi=mi;box.mx=mx;
00410     return(box);
00411 }
00412 
00413 //
00414 inline btDbvtAabbMm         btDbvtAabbMm::FromPoints(const btVector3* pts,int n)
00415 {
00416     btDbvtAabbMm box;
00417     box.mi=box.mx=pts[0];
00418     for(int i=1;i<n;++i)
00419     {
00420         box.mi.setMin(pts[i]);
00421         box.mx.setMax(pts[i]);
00422     }
00423     return(box);
00424 }
00425 
00426 //
00427 inline btDbvtAabbMm         btDbvtAabbMm::FromPoints(const btVector3** ppts,int n)
00428 {
00429     btDbvtAabbMm box;
00430     box.mi=box.mx=*ppts[0];
00431     for(int i=1;i<n;++i)
00432     {
00433         box.mi.setMin(*ppts[i]);
00434         box.mx.setMax(*ppts[i]);
00435     }
00436     return(box);
00437 }
00438 
00439 //
00440 DBVT_INLINE void        btDbvtAabbMm::Expand(const btVector3& e)
00441 {
00442     mi-=e;mx+=e;
00443 }
00444 
00445 //
00446 DBVT_INLINE void        btDbvtAabbMm::SignedExpand(const btVector3& e)
00447 {
00448     if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]);
00449     if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]);
00450     if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]);
00451 }
00452 
00453 //
00454 DBVT_INLINE bool        btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const
00455 {
00456     return( (mi.x()<=a.mi.x())&&
00457         (mi.y()<=a.mi.y())&&
00458         (mi.z()<=a.mi.z())&&
00459         (mx.x()>=a.mx.x())&&
00460         (mx.y()>=a.mx.y())&&
00461         (mx.z()>=a.mx.z()));
00462 }
00463 
00464 //
00465 DBVT_INLINE int     btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const
00466 {
00467     btVector3           pi,px;
00468     switch(s)
00469     {
00470     case    (0+0+0):    px=btVector3(mi.x(),mi.y(),mi.z());
00471         pi=btVector3(mx.x(),mx.y(),mx.z());break;
00472     case    (1+0+0):    px=btVector3(mx.x(),mi.y(),mi.z());
00473         pi=btVector3(mi.x(),mx.y(),mx.z());break;
00474     case    (0+2+0):    px=btVector3(mi.x(),mx.y(),mi.z());
00475         pi=btVector3(mx.x(),mi.y(),mx.z());break;
00476     case    (1+2+0):    px=btVector3(mx.x(),mx.y(),mi.z());
00477         pi=btVector3(mi.x(),mi.y(),mx.z());break;
00478     case    (0+0+4):    px=btVector3(mi.x(),mi.y(),mx.z());
00479         pi=btVector3(mx.x(),mx.y(),mi.z());break;
00480     case    (1+0+4):    px=btVector3(mx.x(),mi.y(),mx.z());
00481         pi=btVector3(mi.x(),mx.y(),mi.z());break;
00482     case    (0+2+4):    px=btVector3(mi.x(),mx.y(),mx.z());
00483         pi=btVector3(mx.x(),mi.y(),mi.z());break;
00484     case    (1+2+4):    px=btVector3(mx.x(),mx.y(),mx.z());
00485         pi=btVector3(mi.x(),mi.y(),mi.z());break;
00486     }
00487     if((btDot(n,px)+o)<0)       return(-1);
00488     if((btDot(n,pi)+o)>=0)  return(+1);
00489     return(0);
00490 }
00491 
00492 //
00493 DBVT_INLINE btScalar    btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const
00494 {
00495     const btVector3*    b[]={&mx,&mi};
00496     const btVector3     p(  b[(signs>>0)&1]->x(),
00497         b[(signs>>1)&1]->y(),
00498         b[(signs>>2)&1]->z());
00499     return(btDot(p,v));
00500 }
00501 
00502 //
00503 DBVT_INLINE void        btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const
00504 {
00505     for(int i=0;i<3;++i)
00506     {
00507         if(d[i]<0)
00508         { smi+=mx[i]*d[i];smx+=mi[i]*d[i]; }
00509         else
00510         { smi+=mi[i]*d[i];smx+=mx[i]*d[i]; }
00511     }
00512 }
00513 
00514 //
00515 DBVT_INLINE bool        Intersect(  const btDbvtAabbMm& a,
00516                                   const btDbvtAabbMm& b)
00517 {
00518 #if DBVT_INT0_IMPL == DBVT_IMPL_SSE
00519     const __m128    rt(_mm_or_ps(   _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
00520         _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
00521     const __int32*  pu((const __int32*)&rt);
00522     return((pu[0]|pu[1]|pu[2])==0);
00523 #else
00524     return( (a.mi.x()<=b.mx.x())&&
00525         (a.mx.x()>=b.mi.x())&&
00526         (a.mi.y()<=b.mx.y())&&
00527         (a.mx.y()>=b.mi.y())&&
00528         (a.mi.z()<=b.mx.z())&&      
00529         (a.mx.z()>=b.mi.z()));
00530 #endif
00531 }
00532 
00533 
00534 
00535 //
00536 DBVT_INLINE bool        Intersect(  const btDbvtAabbMm& a,
00537                                   const btVector3& b)
00538 {
00539     return( (b.x()>=a.mi.x())&&
00540         (b.y()>=a.mi.y())&&
00541         (b.z()>=a.mi.z())&&
00542         (b.x()<=a.mx.x())&&
00543         (b.y()<=a.mx.y())&&
00544         (b.z()<=a.mx.z()));
00545 }
00546 
00547 
00548 
00549 
00550 
00552 
00553 
00554 //
00555 DBVT_INLINE btScalar    Proximity(  const btDbvtAabbMm& a,
00556                                   const btDbvtAabbMm& b)
00557 {
00558     const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx);
00559     return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
00560 }
00561 
00562 
00563 
00564 //
00565 DBVT_INLINE int         Select( const btDbvtAabbMm& o,
00566                                const btDbvtAabbMm& a,
00567                                const btDbvtAabbMm& b)
00568 {
00569 #if DBVT_SELECT_IMPL == DBVT_IMPL_SSE
00570     static ATTRIBUTE_ALIGNED16(const unsigned __int32)  mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
00572 #if DBVT_USE_INTRINSIC_SSE
00573 
00574     union btSSEUnion 
00575     {
00576        __m128       ssereg;
00577        float        floats[4];
00578        int          ints[4];
00579     };
00580 
00581     __m128  omi(_mm_load_ps(o.mi));
00582     omi=_mm_add_ps(omi,_mm_load_ps(o.mx));
00583     __m128  ami(_mm_load_ps(a.mi));
00584     ami=_mm_add_ps(ami,_mm_load_ps(a.mx));
00585     ami=_mm_sub_ps(ami,omi);
00586     ami=_mm_and_ps(ami,_mm_load_ps((const float*)mask));
00587     __m128  bmi(_mm_load_ps(b.mi));
00588     bmi=_mm_add_ps(bmi,_mm_load_ps(b.mx));
00589     bmi=_mm_sub_ps(bmi,omi);
00590     bmi=_mm_and_ps(bmi,_mm_load_ps((const float*)mask));
00591     __m128  t0(_mm_movehl_ps(ami,ami));
00592     ami=_mm_add_ps(ami,t0);
00593     ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1));
00594     __m128 t1(_mm_movehl_ps(bmi,bmi));
00595     bmi=_mm_add_ps(bmi,t1);
00596     bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1));
00597     
00598     btSSEUnion tmp;
00599     tmp.ssereg = _mm_cmple_ss(bmi,ami);
00600     return tmp.ints[0]&1;
00601 
00602 #else
00603     ATTRIBUTE_ALIGNED16(__int32 r[1]);
00604     __asm
00605     {
00606         mov     eax,o
00607             mov     ecx,a
00608             mov     edx,b
00609             movaps  xmm0,[eax]
00610         movaps  xmm5,mask
00611             addps   xmm0,[eax+16]   
00612         movaps  xmm1,[ecx]
00613         movaps  xmm2,[edx]
00614         addps   xmm1,[ecx+16]
00615         addps   xmm2,[edx+16]
00616         subps   xmm1,xmm0
00617             subps   xmm2,xmm0
00618             andps   xmm1,xmm5
00619             andps   xmm2,xmm5
00620             movhlps xmm3,xmm1
00621             movhlps xmm4,xmm2
00622             addps   xmm1,xmm3
00623             addps   xmm2,xmm4
00624             pshufd  xmm3,xmm1,1
00625             pshufd  xmm4,xmm2,1
00626             addss   xmm1,xmm3
00627             addss   xmm2,xmm4
00628             cmpless xmm2,xmm1
00629             movss   r,xmm2
00630     }
00631     return(r[0]&1);
00632 #endif
00633 #else
00634     return(Proximity(o,a)<Proximity(o,b)?0:1);
00635 #endif
00636 }
00637 
00638 //
00639 DBVT_INLINE void        Merge(  const btDbvtAabbMm& a,
00640                               const btDbvtAabbMm& b,
00641                               btDbvtAabbMm& r)
00642 {
00643 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
00644     __m128  ami(_mm_load_ps(a.mi));
00645     __m128  amx(_mm_load_ps(a.mx));
00646     __m128  bmi(_mm_load_ps(b.mi));
00647     __m128  bmx(_mm_load_ps(b.mx));
00648     ami=_mm_min_ps(ami,bmi);
00649     amx=_mm_max_ps(amx,bmx);
00650     _mm_store_ps(r.mi,ami);
00651     _mm_store_ps(r.mx,amx);
00652 #else
00653     for(int i=0;i<3;++i)
00654     {
00655         if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i];
00656         if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i];
00657     }
00658 #endif
00659 }
00660 
00661 //
00662 DBVT_INLINE bool        NotEqual(   const btDbvtAabbMm& a,
00663                                  const btDbvtAabbMm& b)
00664 {
00665     return( (a.mi.x()!=b.mi.x())||
00666         (a.mi.y()!=b.mi.y())||
00667         (a.mi.z()!=b.mi.z())||
00668         (a.mx.x()!=b.mx.x())||
00669         (a.mx.y()!=b.mx.y())||
00670         (a.mx.z()!=b.mx.z()));
00671 }
00672 
00673 //
00674 // Inline's
00675 //
00676 
00677 //
00678 DBVT_PREFIX
00679 inline void     btDbvt::enumNodes(  const btDbvtNode* root,
00680                                   DBVT_IPOLICY)
00681 {
00682     DBVT_CHECKTYPE
00683         policy.Process(root);
00684     if(root->isinternal())
00685     {
00686         enumNodes(root->childs[0],policy);
00687         enumNodes(root->childs[1],policy);
00688     }
00689 }
00690 
00691 //
00692 DBVT_PREFIX
00693 inline void     btDbvt::enumLeaves( const btDbvtNode* root,
00694                                    DBVT_IPOLICY)
00695 {
00696     DBVT_CHECKTYPE
00697         if(root->isinternal())
00698         {
00699             enumLeaves(root->childs[0],policy);
00700             enumLeaves(root->childs[1],policy);
00701         }
00702         else
00703         {
00704             policy.Process(root);
00705         }
00706 }
00707 
00708 //
00709 DBVT_PREFIX
00710 inline void     btDbvt::collideTT(  const btDbvtNode* root0,
00711                                   const btDbvtNode* root1,
00712                                   DBVT_IPOLICY)
00713 {
00714     DBVT_CHECKTYPE
00715         if(root0&&root1)
00716         {
00717             int                             depth=1;
00718             int                             treshold=DOUBLE_STACKSIZE-4;
00719             btAlignedObjectArray<sStkNN>    stkStack;
00720             stkStack.resize(DOUBLE_STACKSIZE);
00721             stkStack[0]=sStkNN(root0,root1);
00722             do  {       
00723                 sStkNN  p=stkStack[--depth];
00724                 if(depth>treshold)
00725                 {
00726                     stkStack.resize(stkStack.size()*2);
00727                     treshold=stkStack.size()-4;
00728                 }
00729                 if(p.a==p.b)
00730                 {
00731                     if(p.a->isinternal())
00732                     {
00733                         stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
00734                         stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
00735                         stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
00736                     }
00737                 }
00738                 else if(Intersect(p.a->volume,p.b->volume))
00739                 {
00740                     if(p.a->isinternal())
00741                     {
00742                         if(p.b->isinternal())
00743                         {
00744                             stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
00745                             stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
00746                             stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
00747                             stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
00748                         }
00749                         else
00750                         {
00751                             stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
00752                             stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
00753                         }
00754                     }
00755                     else
00756                     {
00757                         if(p.b->isinternal())
00758                         {
00759                             stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
00760                             stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
00761                         }
00762                         else
00763                         {
00764                             policy.Process(p.a,p.b);
00765                         }
00766                     }
00767                 }
00768             } while(depth);
00769         }
00770 }
00771 
00772 
00773 
00774 DBVT_PREFIX
00775 inline void     btDbvt::collideTTpersistentStack(   const btDbvtNode* root0,
00776                                   const btDbvtNode* root1,
00777                                   DBVT_IPOLICY)
00778 {
00779     DBVT_CHECKTYPE
00780         if(root0&&root1)
00781         {
00782             int                             depth=1;
00783             int                             treshold=DOUBLE_STACKSIZE-4;
00784             
00785             m_stkStack.resize(DOUBLE_STACKSIZE);
00786             m_stkStack[0]=sStkNN(root0,root1);
00787             do  {       
00788                 sStkNN  p=m_stkStack[--depth];
00789                 if(depth>treshold)
00790                 {
00791                     m_stkStack.resize(m_stkStack.size()*2);
00792                     treshold=m_stkStack.size()-4;
00793                 }
00794                 if(p.a==p.b)
00795                 {
00796                     if(p.a->isinternal())
00797                     {
00798                         m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
00799                         m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
00800                         m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
00801                     }
00802                 }
00803                 else if(Intersect(p.a->volume,p.b->volume))
00804                 {
00805                     if(p.a->isinternal())
00806                     {
00807                         if(p.b->isinternal())
00808                         {
00809                             m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
00810                             m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
00811                             m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
00812                             m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
00813                         }
00814                         else
00815                         {
00816                             m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
00817                             m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
00818                         }
00819                     }
00820                     else
00821                     {
00822                         if(p.b->isinternal())
00823                         {
00824                             m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
00825                             m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
00826                         }
00827                         else
00828                         {
00829                             policy.Process(p.a,p.b);
00830                         }
00831                     }
00832                 }
00833             } while(depth);
00834         }
00835 }
00836 
00837 #if 0
00838 //
00839 DBVT_PREFIX
00840 inline void     btDbvt::collideTT(  const btDbvtNode* root0,
00841                                   const btDbvtNode* root1,
00842                                   const btTransform& xform,
00843                                   DBVT_IPOLICY)
00844 {
00845     DBVT_CHECKTYPE
00846         if(root0&&root1)
00847         {
00848             int                             depth=1;
00849             int                             treshold=DOUBLE_STACKSIZE-4;
00850             btAlignedObjectArray<sStkNN>    stkStack;
00851             stkStack.resize(DOUBLE_STACKSIZE);
00852             stkStack[0]=sStkNN(root0,root1);
00853             do  {
00854                 sStkNN  p=stkStack[--depth];
00855                 if(Intersect(p.a->volume,p.b->volume,xform))
00856                 {
00857                     if(depth>treshold)
00858                     {
00859                         stkStack.resize(stkStack.size()*2);
00860                         treshold=stkStack.size()-4;
00861                     }
00862                     if(p.a->isinternal())
00863                     {
00864                         if(p.b->isinternal())
00865                         {                   
00866                             stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
00867                             stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
00868                             stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
00869                             stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
00870                         }
00871                         else
00872                         {
00873                             stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
00874                             stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
00875                         }
00876                     }
00877                     else
00878                     {
00879                         if(p.b->isinternal())
00880                         {
00881                             stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
00882                             stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
00883                         }
00884                         else
00885                         {
00886                             policy.Process(p.a,p.b);
00887                         }
00888                     }
00889                 }
00890             } while(depth);
00891         }
00892 }
00893 //
00894 DBVT_PREFIX
00895 inline void     btDbvt::collideTT(  const btDbvtNode* root0,
00896                                   const btTransform& xform0,
00897                                   const btDbvtNode* root1,
00898                                   const btTransform& xform1,
00899                                   DBVT_IPOLICY)
00900 {
00901     const btTransform   xform=xform0.inverse()*xform1;
00902     collideTT(root0,root1,xform,policy);
00903 }
00904 #endif 
00905 
00906 //
00907 DBVT_PREFIX
00908 inline void     btDbvt::collideTV(  const btDbvtNode* root,
00909                                   const btDbvtVolume& vol,
00910                                   DBVT_IPOLICY)
00911 {
00912     DBVT_CHECKTYPE
00913         if(root)
00914         {
00915             ATTRIBUTE_ALIGNED16(btDbvtVolume)       volume(vol);
00916             btAlignedObjectArray<const btDbvtNode*> stack;
00917             stack.resize(0);
00918             stack.reserve(SIMPLE_STACKSIZE);
00919             stack.push_back(root);
00920             do  {
00921                 const btDbvtNode*   n=stack[stack.size()-1];
00922                 stack.pop_back();
00923                 if(Intersect(n->volume,volume))
00924                 {
00925                     if(n->isinternal())
00926                     {
00927                         stack.push_back(n->childs[0]);
00928                         stack.push_back(n->childs[1]);
00929                     }
00930                     else
00931                     {
00932                         policy.Process(n);
00933                     }
00934                 }
00935             } while(stack.size()>0);
00936         }
00937 }
00938 
00939 DBVT_PREFIX
00940 inline void     btDbvt::rayTestInternal(    const btDbvtNode* root,
00941                                 const btVector3& rayFrom,
00942                                 const btVector3& rayTo,
00943                                 const btVector3& rayDirectionInverse,
00944                                 unsigned int signs[3],
00945                                 btScalar lambda_max,
00946                                 const btVector3& aabbMin,
00947                                 const btVector3& aabbMax,
00948                                 DBVT_IPOLICY) const
00949 {
00950         (void) rayTo;
00951     DBVT_CHECKTYPE
00952     if(root)
00953     {
00954         btVector3 resultNormal;
00955 
00956         int                             depth=1;
00957         int                             treshold=DOUBLE_STACKSIZE-2;
00958         btAlignedObjectArray<const btDbvtNode*> stack;
00959         stack.resize(DOUBLE_STACKSIZE);
00960         stack[0]=root;
00961         btVector3 bounds[2];
00962         do  
00963         {
00964             const btDbvtNode*   node=stack[--depth];
00965             bounds[0] = node->volume.Mins()-aabbMax;
00966             bounds[1] = node->volume.Maxs()-aabbMin;
00967             btScalar tmin=1.f,lambda_min=0.f;
00968             unsigned int result1=false;
00969             result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
00970             if(result1)
00971             {
00972                 if(node->isinternal())
00973                 {
00974                     if(depth>treshold)
00975                     {
00976                         stack.resize(stack.size()*2);
00977                         treshold=stack.size()-2;
00978                     }
00979                     stack[depth++]=node->childs[0];
00980                     stack[depth++]=node->childs[1];
00981                 }
00982                 else
00983                 {
00984                     policy.Process(node);
00985                 }
00986             }
00987         } while(depth);
00988     }
00989 }
00990 
00991 //
00992 DBVT_PREFIX
00993 inline void     btDbvt::rayTest(    const btDbvtNode* root,
00994                                 const btVector3& rayFrom,
00995                                 const btVector3& rayTo,
00996                                 DBVT_IPOLICY)
00997 {
00998     DBVT_CHECKTYPE
00999         if(root)
01000         {
01001             btVector3 rayDir = (rayTo-rayFrom);
01002             rayDir.normalize ();
01003 
01005             btVector3 rayDirectionInverse;
01006             rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
01007             rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
01008             rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
01009             unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
01010 
01011             btScalar lambda_max = rayDir.dot(rayTo-rayFrom);
01012 
01013             btVector3 resultNormal;
01014 
01015             btAlignedObjectArray<const btDbvtNode*> stack;
01016 
01017             int                             depth=1;
01018             int                             treshold=DOUBLE_STACKSIZE-2;
01019 
01020             stack.resize(DOUBLE_STACKSIZE);
01021             stack[0]=root;
01022             btVector3 bounds[2];
01023             do  {
01024                 const btDbvtNode*   node=stack[--depth];
01025 
01026                 bounds[0] = node->volume.Mins();
01027                 bounds[1] = node->volume.Maxs();
01028                 
01029                 btScalar tmin=1.f,lambda_min=0.f;
01030                 unsigned int result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
01031 
01032 #ifdef COMPARE_BTRAY_AABB2
01033                 btScalar param=1.f;
01034                 bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal);
01035                 btAssert(result1 == result2);
01036 #endif //TEST_BTRAY_AABB2
01037 
01038                 if(result1)
01039                 {
01040                     if(node->isinternal())
01041                     {
01042                         if(depth>treshold)
01043                         {
01044                             stack.resize(stack.size()*2);
01045                             treshold=stack.size()-2;
01046                         }
01047                         stack[depth++]=node->childs[0];
01048                         stack[depth++]=node->childs[1];
01049                     }
01050                     else
01051                     {
01052                         policy.Process(node);
01053                     }
01054                 }
01055             } while(depth);
01056 
01057         }
01058 }
01059 
01060 //
01061 DBVT_PREFIX
01062 inline void     btDbvt::collideKDOP(const btDbvtNode* root,
01063                                     const btVector3* normals,
01064                                     const btScalar* offsets,
01065                                     int count,
01066                                     DBVT_IPOLICY)
01067 {
01068     DBVT_CHECKTYPE
01069         if(root)
01070         {
01071             const int                       inside=(1<<count)-1;
01072             btAlignedObjectArray<sStkNP>    stack;
01073             int                             signs[sizeof(unsigned)*8];
01074             btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
01075             for(int i=0;i<count;++i)
01076             {
01077                 signs[i]=   ((normals[i].x()>=0)?1:0)+
01078                     ((normals[i].y()>=0)?2:0)+
01079                     ((normals[i].z()>=0)?4:0);
01080             }
01081             stack.reserve(SIMPLE_STACKSIZE);
01082             stack.push_back(sStkNP(root,0));
01083             do  {
01084                 sStkNP  se=stack[stack.size()-1];
01085                 bool    out=false;
01086                 stack.pop_back();
01087                 for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
01088                 {
01089                     if(0==(se.mask&j))
01090                     {
01091                         const int   side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
01092                         switch(side)
01093                         {
01094                         case    -1: out=true;break;
01095                         case    +1: se.mask|=j;break;
01096                         }
01097                     }
01098                 }
01099                 if(!out)
01100                 {
01101                     if((se.mask!=inside)&&(se.node->isinternal()))
01102                     {
01103                         stack.push_back(sStkNP(se.node->childs[0],se.mask));
01104                         stack.push_back(sStkNP(se.node->childs[1],se.mask));
01105                     }
01106                     else
01107                     {
01108                         if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);
01109                     }
01110                 }
01111             } while(stack.size());
01112         }
01113 }
01114 
01115 //
01116 DBVT_PREFIX
01117 inline void     btDbvt::collideOCL( const btDbvtNode* root,
01118                                    const btVector3* normals,
01119                                    const btScalar* offsets,
01120                                    const btVector3& sortaxis,
01121                                    int count,
01122                                    DBVT_IPOLICY,
01123                                    bool fsort)
01124 {
01125     DBVT_CHECKTYPE
01126         if(root)
01127         {
01128             const unsigned                  srtsgns=(sortaxis[0]>=0?1:0)+
01129                 (sortaxis[1]>=0?2:0)+
01130                 (sortaxis[2]>=0?4:0);
01131             const int                       inside=(1<<count)-1;
01132             btAlignedObjectArray<sStkNPS>   stock;
01133             btAlignedObjectArray<int>       ifree;
01134             btAlignedObjectArray<int>       stack;
01135             int                             signs[sizeof(unsigned)*8];
01136             btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
01137             for(int i=0;i<count;++i)
01138             {
01139                 signs[i]=   ((normals[i].x()>=0)?1:0)+
01140                     ((normals[i].y()>=0)?2:0)+
01141                     ((normals[i].z()>=0)?4:0);
01142             }
01143             stock.reserve(SIMPLE_STACKSIZE);
01144             stack.reserve(SIMPLE_STACKSIZE);
01145             ifree.reserve(SIMPLE_STACKSIZE);
01146             stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns))));
01147             do  {
01148                 const int   id=stack[stack.size()-1];
01149                 sStkNPS     se=stock[id];
01150                 stack.pop_back();ifree.push_back(id);
01151                 if(se.mask!=inside)
01152                 {
01153                     bool    out=false;
01154                     for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
01155                     {
01156                         if(0==(se.mask&j))
01157                         {
01158                             const int   side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
01159                             switch(side)
01160                             {
01161                             case    -1: out=true;break;
01162                             case    +1: se.mask|=j;break;
01163                             }
01164                         }
01165                     }
01166                     if(out) continue;
01167                 }
01168                 if(policy.Descent(se.node))
01169                 {
01170                     if(se.node->isinternal())
01171                     {
01172                         const btDbvtNode* pns[]={   se.node->childs[0],se.node->childs[1]};
01173                         sStkNPS     nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)),
01174                             sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))};
01175                         const int   q=nes[0].value<nes[1].value?1:0;                
01176                         int         j=stack.size();
01177                         if(fsort&&(j>0))
01178                         {
01179                             /* Insert 0 */ 
01180                             j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
01181                             stack.push_back(0);
01182 #if DBVT_USE_MEMMOVE
01183                             memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
01184 #else
01185                             for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
01186 #endif
01187                             stack[j]=allocate(ifree,stock,nes[q]);
01188                             /* Insert 1 */ 
01189                             j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size());
01190                             stack.push_back(0);
01191 #if DBVT_USE_MEMMOVE
01192                             memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
01193 #else
01194                             for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
01195 #endif
01196                             stack[j]=allocate(ifree,stock,nes[1-q]);
01197                         }
01198                         else
01199                         {
01200                             stack.push_back(allocate(ifree,stock,nes[q]));
01201                             stack.push_back(allocate(ifree,stock,nes[1-q]));
01202                         }
01203                     }
01204                     else
01205                     {
01206                         policy.Process(se.node,se.value);
01207                     }
01208                 }
01209             } while(stack.size());
01210         }
01211 }
01212 
01213 //
01214 DBVT_PREFIX
01215 inline void     btDbvt::collideTU(  const btDbvtNode* root,
01216                                   DBVT_IPOLICY)
01217 {
01218     DBVT_CHECKTYPE
01219         if(root)
01220         {
01221             btAlignedObjectArray<const btDbvtNode*> stack;
01222             stack.reserve(SIMPLE_STACKSIZE);
01223             stack.push_back(root);
01224             do  {
01225                 const btDbvtNode*   n=stack[stack.size()-1];
01226                 stack.pop_back();
01227                 if(policy.Descent(n))
01228                 {
01229                     if(n->isinternal())
01230                     { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
01231                     else
01232                     { policy.Process(n); }
01233                 }
01234             } while(stack.size()>0);
01235         }
01236 }
01237 
01238 //
01239 // PP Cleanup
01240 //
01241 
01242 #undef DBVT_USE_MEMMOVE
01243 #undef DBVT_USE_TEMPLATE
01244 #undef DBVT_VIRTUAL_DTOR
01245 #undef DBVT_VIRTUAL
01246 #undef DBVT_PREFIX
01247 #undef DBVT_IPOLICY
01248 #undef DBVT_CHECKTYPE
01249 #undef DBVT_IMPL_GENERIC
01250 #undef DBVT_IMPL_SSE
01251 #undef DBVT_USE_INTRINSIC_SSE
01252 #undef DBVT_SELECT_IMPL
01253 #undef DBVT_MERGE_IMPL
01254 #undef DBVT_INT0_IMPL
01255 
01256 #endif