source: trunk/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.h @ 1640

Last change on this file since 1640 was 1640, checked in by sam, 9 years ago

core: fix shitloads of compiler warnings in the Bullet source code.

  • Property svn:keywords set to Id
File size: 31.4 KB
Line 
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2007 Erwin Coumans  http://continuousphysics.com/Bullet/
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15///btDbvt implementation by Nathanael Presson
16
17#ifndef BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
18#define BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
19
20#include "LinearMath/btAlignedObjectArray.h"
21#include "LinearMath/btVector3.h"
22#include "LinearMath/btTransform.h"
23#include "LinearMath/btAabbUtil2.h"
24
25//
26// Compile time configuration
27//
28
29
30// Implementation profiles
31#define DBVT_IMPL_GENERIC               0       // Generic implementation       
32#define DBVT_IMPL_SSE                   1       // SSE
33
34// Template implementation of ICollide
35#ifdef _WIN32
36#if (defined (_MSC_VER) && _MSC_VER >= 1400)
37#define DBVT_USE_TEMPLATE               1
38#else
39#define DBVT_USE_TEMPLATE               0
40#endif
41#else
42#define DBVT_USE_TEMPLATE               0
43#endif
44
45// Use only intrinsics instead of inline asm
46#define DBVT_USE_INTRINSIC_SSE  1
47
48// Using memmov for collideOCL
49#define DBVT_USE_MEMMOVE                1
50
51// Enable benchmarking code
52#define DBVT_ENABLE_BENCHMARK   0
53
54// Inlining
55#define DBVT_INLINE                             SIMD_FORCE_INLINE
56
57// Specific methods implementation
58
59//SSE gives errors on a MSVC 7.1
60#if defined (BT_USE_SSE) && defined (_WIN32)
61#define DBVT_SELECT_IMPL                DBVT_IMPL_SSE
62#define DBVT_MERGE_IMPL                 DBVT_IMPL_SSE
63#define DBVT_INT0_IMPL                  DBVT_IMPL_SSE
64#else
65#define DBVT_SELECT_IMPL                DBVT_IMPL_GENERIC
66#define DBVT_MERGE_IMPL                 DBVT_IMPL_GENERIC
67#define DBVT_INT0_IMPL                  DBVT_IMPL_GENERIC
68#endif
69
70#if     (DBVT_SELECT_IMPL==DBVT_IMPL_SSE)||     \
71        (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)||      \
72        (DBVT_INT0_IMPL==DBVT_IMPL_SSE)
73#include <emmintrin.h>
74#endif
75
76//
77// Auto config and checks
78//
79
80#if DBVT_USE_TEMPLATE
81#define DBVT_VIRTUAL
82#define DBVT_VIRTUAL_DTOR(a)
83#define DBVT_PREFIX                                     template <typename T>
84#define DBVT_IPOLICY                            T& policy
85#define DBVT_CHECKTYPE                          static const ICollide&  typechecker=*(T*)1;(void)typechecker;
86#else
87#define DBVT_VIRTUAL_DTOR(a)            virtual ~a() {}
88#define DBVT_VIRTUAL                            virtual
89#define DBVT_PREFIX
90#define DBVT_IPOLICY                            ICollide& policy
91#define DBVT_CHECKTYPE
92#endif
93
94#if DBVT_USE_MEMMOVE
95// LOL BEGIN
96#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) && !defined(__native_client__)
97// LOL END
98#include <memory.h>
99#endif
100#include <string.h>
101#endif
102
103#ifndef DBVT_USE_TEMPLATE
104#error "DBVT_USE_TEMPLATE undefined"
105#endif
106
107#ifndef DBVT_USE_MEMMOVE
108#error "DBVT_USE_MEMMOVE undefined"
109#endif
110
111#ifndef DBVT_ENABLE_BENCHMARK
112#error "DBVT_ENABLE_BENCHMARK undefined"
113#endif
114
115#ifndef DBVT_SELECT_IMPL
116#error "DBVT_SELECT_IMPL undefined"
117#endif
118
119#ifndef DBVT_MERGE_IMPL
120#error "DBVT_MERGE_IMPL undefined"
121#endif
122
123#ifndef DBVT_INT0_IMPL
124#error "DBVT_INT0_IMPL undefined"
125#endif
126
127//
128// Defaults volumes
129//
130
131/* btDbvtAabbMm                 */
132struct  btDbvtAabbMm
133{
134        DBVT_INLINE btVector3                   Center() const  { return((mi+mx)/2); }
135        DBVT_INLINE btVector3                   Lengths() const { return(mx-mi); }
136        DBVT_INLINE btVector3                   Extents() const { return((mx-mi)/2); }
137        DBVT_INLINE const btVector3&    Mins() const    { return(mi); }
138        DBVT_INLINE const btVector3&    Maxs() const    { return(mx); }
139        static inline btDbvtAabbMm              FromCE(const btVector3& c,const btVector3& e);
140        static inline btDbvtAabbMm              FromCR(const btVector3& c,btScalar r);
141        static inline btDbvtAabbMm              FromMM(const btVector3& mi,const btVector3& mx);
142        static inline btDbvtAabbMm              FromPoints(const btVector3* pts,int n);
143        static inline btDbvtAabbMm              FromPoints(const btVector3** ppts,int n);
144        DBVT_INLINE void                                Expand(const btVector3& e);
145        DBVT_INLINE void                                SignedExpand(const btVector3& e);
146        DBVT_INLINE bool                                Contain(const btDbvtAabbMm& a) const;
147        DBVT_INLINE int                                 Classify(const btVector3& n,btScalar o,int s) const;
148        DBVT_INLINE btScalar                    ProjectMinimum(const btVector3& v,unsigned signs) const;
149        DBVT_INLINE friend bool                 Intersect(      const btDbvtAabbMm& a,
150                const btDbvtAabbMm& b);
151       
152        DBVT_INLINE friend bool                 Intersect(      const btDbvtAabbMm& a,
153                const btVector3& b);
154
155        DBVT_INLINE friend btScalar             Proximity(      const btDbvtAabbMm& a,
156                const btDbvtAabbMm& b);
157        DBVT_INLINE friend int                  Select(         const btDbvtAabbMm& o,
158                const btDbvtAabbMm& a,
159                const btDbvtAabbMm& b);
160        DBVT_INLINE friend void                 Merge(          const btDbvtAabbMm& a,
161                const btDbvtAabbMm& b,
162                btDbvtAabbMm& r);
163        DBVT_INLINE friend bool                 NotEqual(       const btDbvtAabbMm& a,
164                const btDbvtAabbMm& b);
165private:
166        DBVT_INLINE void                                AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
167private:
168        btVector3       mi,mx;
169};
170
171// Types       
172typedef btDbvtAabbMm    btDbvtVolume;
173
174/* btDbvtNode                           */
175struct  btDbvtNode
176{
177        btDbvtVolume    volume;
178        btDbvtNode*             parent;
179        DBVT_INLINE bool        isleaf() const          { return(childs[1]==0); }
180        DBVT_INLINE bool        isinternal() const      { return(!isleaf()); }
181        union
182        {
183                btDbvtNode*     childs[2];
184                void*   data;
185                int             dataAsInt;
186        };
187};
188
189///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree).
190///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes.
191///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure.
192struct  btDbvt
193{
194        /* Stack element        */
195        struct  sStkNN
196        {
197                const btDbvtNode*       a;
198                const btDbvtNode*       b;
199                sStkNN() {}
200                sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {}
201        };
202        struct  sStkNP
203        {
204                const btDbvtNode*       node;
205                int                     mask;
206                sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {}
207        };
208        struct  sStkNPS
209        {
210                const btDbvtNode*       node;
211                int                     mask;
212                btScalar        value;
213                sStkNPS() {}
214                sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {}
215        };
216        struct  sStkCLN
217        {
218                const btDbvtNode*       node;
219                btDbvtNode*             parent;
220                sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {}
221        };
222        // Policies/Interfaces
223
224        /* ICollide     */
225        struct  ICollide
226        {               
227                DBVT_VIRTUAL_DTOR(ICollide)
228                        DBVT_VIRTUAL void       Process(const btDbvtNode*,const btDbvtNode*)            {}
229                DBVT_VIRTUAL void       Process(const btDbvtNode*)                                      {}
230                DBVT_VIRTUAL void       Process(const btDbvtNode* n,btScalar)                   { Process(n); }
231                DBVT_VIRTUAL bool       Descent(const btDbvtNode*)                                      { return(true); }
232                DBVT_VIRTUAL bool       AllLeaves(const btDbvtNode*)                                    { return(true); }
233        };
234        /* IWriter      */
235        struct  IWriter
236        {
237                virtual ~IWriter() {}
238                virtual void            Prepare(const btDbvtNode* root,int numnodes)=0;
239                virtual void            WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0;
240                virtual void            WriteLeaf(const btDbvtNode*,int index,int parent)=0;
241        };
242        /* IClone       */
243        struct  IClone
244        {
245                virtual ~IClone()       {}
246                virtual void            CloneLeaf(btDbvtNode*) {}
247        };
248
249        // Constants
250        enum    {
251                SIMPLE_STACKSIZE        =       64,
252                DOUBLE_STACKSIZE        =       SIMPLE_STACKSIZE*2
253        };
254
255        // Fields
256        btDbvtNode*             m_root;
257        btDbvtNode*             m_free;
258        int                             m_lkhd;
259        int                             m_leaves;
260        unsigned                m_opath;
261
262       
263        btAlignedObjectArray<sStkNN>    m_stkStack;
264        mutable btAlignedObjectArray<const btDbvtNode*> m_rayTestStack;
265
266
267        // Methods
268        btDbvt();
269        ~btDbvt();
270        void                    clear();
271        bool                    empty() const { return(0==m_root); }
272        void                    optimizeBottomUp();
273        void                    optimizeTopDown(int bu_treshold=128);
274        void                    optimizeIncremental(int passes);
275        btDbvtNode*             insert(const btDbvtVolume& box,void* data);
276        void                    update(btDbvtNode* leaf,int lookahead=-1);
277        void                    update(btDbvtNode* leaf,btDbvtVolume& volume);
278        bool                    update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin);
279        bool                    update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity);
280        bool                    update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin); 
281        void                    remove(btDbvtNode* leaf);
282        void                    write(IWriter* iwriter) const;
283        void                    clone(btDbvt& dest,IClone* iclone=0) const;
284        static int              maxdepth(const btDbvtNode* node);
285        static int              countLeaves(const btDbvtNode* node);
286        static void             extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves);
287#if DBVT_ENABLE_BENCHMARK
288        static void             benchmark();
289#else
290        static void             benchmark(){}
291#endif
292        // DBVT_IPOLICY must support ICollide policy/interface
293        DBVT_PREFIX
294                static void             enumNodes(      const btDbvtNode* root,
295                DBVT_IPOLICY);
296        DBVT_PREFIX
297                static void             enumLeaves(     const btDbvtNode* root,
298                DBVT_IPOLICY);
299        DBVT_PREFIX
300                void            collideTT(      const btDbvtNode* root0,
301                const btDbvtNode* root1,
302                DBVT_IPOLICY);
303
304        DBVT_PREFIX
305                void            collideTTpersistentStack(       const btDbvtNode* root0,
306                  const btDbvtNode* root1,
307                  DBVT_IPOLICY);
308#if 0
309        DBVT_PREFIX
310                void            collideTT(      const btDbvtNode* root0,
311                const btDbvtNode* root1,
312                const btTransform& xform,
313                DBVT_IPOLICY);
314        DBVT_PREFIX
315                void            collideTT(      const btDbvtNode* root0,
316                const btTransform& xform0,
317                const btDbvtNode* root1,
318                const btTransform& xform1,
319                DBVT_IPOLICY);
320#endif
321
322        DBVT_PREFIX
323                void            collideTV(      const btDbvtNode* root,
324                const btDbvtVolume& volume,
325                DBVT_IPOLICY);
326        ///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc)
327        ///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time
328        DBVT_PREFIX
329                static void             rayTest(        const btDbvtNode* root,
330                const btVector3& rayFrom,
331                const btVector3& rayTo,
332                DBVT_IPOLICY);
333        ///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections
334        ///rayTestInternal is used by btDbvtBroadphase to accelerate world ray casts
335        DBVT_PREFIX
336                void            rayTestInternal(        const btDbvtNode* root,
337                                                                const btVector3& rayFrom,
338                                                                const btVector3& rayTo,
339                                                                const btVector3& rayDirectionInverse,
340                                                                unsigned int signs[3],
341                                                                btScalar lambda_max,
342                                                                const btVector3& aabbMin,
343                                                                const btVector3& aabbMax,
344                                                                DBVT_IPOLICY) const;
345
346        DBVT_PREFIX
347                static void             collideKDOP(const btDbvtNode* root,
348                const btVector3* normals,
349                const btScalar* offsets,
350                int count,
351                DBVT_IPOLICY);
352        DBVT_PREFIX
353                static void             collideOCL(     const btDbvtNode* root,
354                const btVector3* normals,
355                const btScalar* offsets,
356                const btVector3& sortaxis,
357                int count,                                                             
358                DBVT_IPOLICY,
359                bool fullsort=true);
360        DBVT_PREFIX
361                static void             collideTU(      const btDbvtNode* root,
362                DBVT_IPOLICY);
363        // Helpers     
364        static DBVT_INLINE int  nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h)
365        {
366                int     m=0;
367                while(l<h)
368                {
369                        m=(l+h)>>1;
370                        if(a[i[m]].value>=v) l=m+1; else h=m;
371                }
372                return(h);
373        }
374        static DBVT_INLINE int  allocate(       btAlignedObjectArray<int>& ifree,
375                btAlignedObjectArray<sStkNPS>& stock,
376                const sStkNPS& value)
377        {
378                int     i;
379                if(ifree.size()>0)
380                { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }
381                else
382                { i=stock.size();stock.push_back(value); }
383                return(i);
384        }
385        //
386private:
387        btDbvt(const btDbvt&)   {}     
388};
389
390//
391// Inline's
392//
393
394//
395inline btDbvtAabbMm                     btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e)
396{
397        btDbvtAabbMm box;
398        box.mi=c-e;box.mx=c+e;
399        return(box);
400}
401
402//
403inline btDbvtAabbMm                     btDbvtAabbMm::FromCR(const btVector3& c,btScalar r)
404{
405        return(FromCE(c,btVector3(r,r,r)));
406}
407
408//
409inline btDbvtAabbMm                     btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx)
410{
411        btDbvtAabbMm box;
412        box.mi=mi;box.mx=mx;
413        return(box);
414}
415
416//
417inline btDbvtAabbMm                     btDbvtAabbMm::FromPoints(const btVector3* pts,int n)
418{
419        btDbvtAabbMm box;
420        box.mi=box.mx=pts[0];
421        for(int i=1;i<n;++i)
422        {
423                box.mi.setMin(pts[i]);
424                box.mx.setMax(pts[i]);
425        }
426        return(box);
427}
428
429//
430inline btDbvtAabbMm                     btDbvtAabbMm::FromPoints(const btVector3** ppts,int n)
431{
432        btDbvtAabbMm box;
433        box.mi=box.mx=*ppts[0];
434        for(int i=1;i<n;++i)
435        {
436                box.mi.setMin(*ppts[i]);
437                box.mx.setMax(*ppts[i]);
438        }
439        return(box);
440}
441
442//
443DBVT_INLINE void                btDbvtAabbMm::Expand(const btVector3& e)
444{
445        mi-=e;mx+=e;
446}
447
448//
449DBVT_INLINE void                btDbvtAabbMm::SignedExpand(const btVector3& e)
450{
451        if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]);
452        if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]);
453        if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]);
454}
455
456//
457DBVT_INLINE bool                btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const
458{
459        return( (mi.x()<=a.mi.x())&&
460                (mi.y()<=a.mi.y())&&
461                (mi.z()<=a.mi.z())&&
462                (mx.x()>=a.mx.x())&&
463                (mx.y()>=a.mx.y())&&
464                (mx.z()>=a.mx.z()));
465}
466
467//
468DBVT_INLINE int         btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const
469{
470        btVector3                       pi,px;
471        switch(s)
472        {
473        case    (0+0+0):        px=btVector3(mi.x(),mi.y(),mi.z());
474                pi=btVector3(mx.x(),mx.y(),mx.z());break;
475        case    (1+0+0):        px=btVector3(mx.x(),mi.y(),mi.z());
476                pi=btVector3(mi.x(),mx.y(),mx.z());break;
477        case    (0+2+0):        px=btVector3(mi.x(),mx.y(),mi.z());
478                pi=btVector3(mx.x(),mi.y(),mx.z());break;
479        case    (1+2+0):        px=btVector3(mx.x(),mx.y(),mi.z());
480                pi=btVector3(mi.x(),mi.y(),mx.z());break;
481        case    (0+0+4):        px=btVector3(mi.x(),mi.y(),mx.z());
482                pi=btVector3(mx.x(),mx.y(),mi.z());break;
483        case    (1+0+4):        px=btVector3(mx.x(),mi.y(),mx.z());
484                pi=btVector3(mi.x(),mx.y(),mi.z());break;
485        case    (0+2+4):        px=btVector3(mi.x(),mx.y(),mx.z());
486                pi=btVector3(mx.x(),mi.y(),mi.z());break;
487        case    (1+2+4):        px=btVector3(mx.x(),mx.y(),mx.z());
488                pi=btVector3(mi.x(),mi.y(),mi.z());break;
489        }
490        if((btDot(n,px)+o)<0)           return(-1);
491        if((btDot(n,pi)+o)>=0)  return(+1);
492        return(0);
493}
494
495//
496DBVT_INLINE btScalar    btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const
497{
498        const btVector3*        b[]={&mx,&mi};
499        const btVector3         p(      b[(signs>>0)&1]->x(),
500                b[(signs>>1)&1]->y(),
501                b[(signs>>2)&1]->z());
502        return(btDot(p,v));
503}
504
505//
506DBVT_INLINE void                btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const
507{
508        for(int i=0;i<3;++i)
509        {
510                if(d[i]<0)
511                { smi+=mx[i]*d[i];smx+=mi[i]*d[i]; }
512                else
513                { smi+=mi[i]*d[i];smx+=mx[i]*d[i]; }
514        }
515}
516
517//
518DBVT_INLINE bool                Intersect(      const btDbvtAabbMm& a,
519                                                                  const btDbvtAabbMm& b)
520{
521#if     DBVT_INT0_IMPL == DBVT_IMPL_SSE
522        const __m128    rt(_mm_or_ps(   _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
523                _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
524        const __int32*  pu((const __int32*)&rt);
525        return((pu[0]|pu[1]|pu[2])==0);
526#else
527        return( (a.mi.x()<=b.mx.x())&&
528                (a.mx.x()>=b.mi.x())&&
529                (a.mi.y()<=b.mx.y())&&
530                (a.mx.y()>=b.mi.y())&&
531                (a.mi.z()<=b.mx.z())&&         
532                (a.mx.z()>=b.mi.z()));
533#endif
534}
535
536
537
538//
539DBVT_INLINE bool                Intersect(      const btDbvtAabbMm& a,
540                                                                  const btVector3& b)
541{
542        return( (b.x()>=a.mi.x())&&
543                (b.y()>=a.mi.y())&&
544                (b.z()>=a.mi.z())&&
545                (b.x()<=a.mx.x())&&
546                (b.y()<=a.mx.y())&&
547                (b.z()<=a.mx.z()));
548}
549
550
551
552
553
554//////////////////////////////////////
555
556
557//
558DBVT_INLINE btScalar    Proximity(      const btDbvtAabbMm& a,
559                                                                  const btDbvtAabbMm& b)
560{
561        const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx);
562        return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
563}
564
565
566
567//
568DBVT_INLINE int                 Select( const btDbvtAabbMm& o,
569                                                           const btDbvtAabbMm& a,
570                                                           const btDbvtAabbMm& b)
571{
572#if     DBVT_SELECT_IMPL == DBVT_IMPL_SSE
573        static ATTRIBUTE_ALIGNED16(const unsigned __int32)      mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
574        ///@todo: the intrinsic version is 11% slower
575#if DBVT_USE_INTRINSIC_SSE
576
577        union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory
578        {
579           __m128               ssereg;
580           float                floats[4];
581           int                  ints[4];
582        };
583
584        __m128  omi(_mm_load_ps(o.mi));
585        omi=_mm_add_ps(omi,_mm_load_ps(o.mx));
586        __m128  ami(_mm_load_ps(a.mi));
587        ami=_mm_add_ps(ami,_mm_load_ps(a.mx));
588        ami=_mm_sub_ps(ami,omi);
589        ami=_mm_and_ps(ami,_mm_load_ps((const float*)mask));
590        __m128  bmi(_mm_load_ps(b.mi));
591        bmi=_mm_add_ps(bmi,_mm_load_ps(b.mx));
592        bmi=_mm_sub_ps(bmi,omi);
593        bmi=_mm_and_ps(bmi,_mm_load_ps((const float*)mask));
594        __m128  t0(_mm_movehl_ps(ami,ami));
595        ami=_mm_add_ps(ami,t0);
596        ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1));
597        __m128 t1(_mm_movehl_ps(bmi,bmi));
598        bmi=_mm_add_ps(bmi,t1);
599        bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1));
600       
601        btSSEUnion tmp;
602        tmp.ssereg = _mm_cmple_ss(bmi,ami);
603        return tmp.ints[0]&1;
604
605#else
606        ATTRIBUTE_ALIGNED16(__int32     r[1]);
607        __asm
608        {
609                mov             eax,o
610                        mov             ecx,a
611                        mov             edx,b
612                        movaps  xmm0,[eax]
613                movaps  xmm5,mask
614                        addps   xmm0,[eax+16]   
615                movaps  xmm1,[ecx]
616                movaps  xmm2,[edx]
617                addps   xmm1,[ecx+16]
618                addps   xmm2,[edx+16]
619                subps   xmm1,xmm0
620                        subps   xmm2,xmm0
621                        andps   xmm1,xmm5
622                        andps   xmm2,xmm5
623                        movhlps xmm3,xmm1
624                        movhlps xmm4,xmm2
625                        addps   xmm1,xmm3
626                        addps   xmm2,xmm4
627                        pshufd  xmm3,xmm1,1
628                        pshufd  xmm4,xmm2,1
629                        addss   xmm1,xmm3
630                        addss   xmm2,xmm4
631                        cmpless xmm2,xmm1
632                        movss   r,xmm2
633        }
634        return(r[0]&1);
635#endif
636#else
637        return(Proximity(o,a)<Proximity(o,b)?0:1);
638#endif
639}
640
641//
642DBVT_INLINE void                Merge(  const btDbvtAabbMm& a,
643                                                          const btDbvtAabbMm& b,
644                                                          btDbvtAabbMm& r)
645{
646#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
647        __m128  ami(_mm_load_ps(a.mi));
648        __m128  amx(_mm_load_ps(a.mx));
649        __m128  bmi(_mm_load_ps(b.mi));
650        __m128  bmx(_mm_load_ps(b.mx));
651        ami=_mm_min_ps(ami,bmi);
652        amx=_mm_max_ps(amx,bmx);
653        _mm_store_ps(r.mi,ami);
654        _mm_store_ps(r.mx,amx);
655#else
656        for(int i=0;i<3;++i)
657        {
658                if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i];
659                if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i];
660        }
661#endif
662}
663
664//
665DBVT_INLINE bool                NotEqual(       const btDbvtAabbMm& a,
666                                                                 const btDbvtAabbMm& b)
667{
668        return( (a.mi.x()!=b.mi.x())||
669                (a.mi.y()!=b.mi.y())||
670                (a.mi.z()!=b.mi.z())||
671                (a.mx.x()!=b.mx.x())||
672                (a.mx.y()!=b.mx.y())||
673                (a.mx.z()!=b.mx.z()));
674}
675
676//
677// Inline's
678//
679
680//
681DBVT_PREFIX
682inline void             btDbvt::enumNodes(      const btDbvtNode* root,
683                                                                  DBVT_IPOLICY)
684{
685        DBVT_CHECKTYPE
686                policy.Process(root);
687        if(root->isinternal())
688        {
689                enumNodes(root->childs[0],policy);
690                enumNodes(root->childs[1],policy);
691        }
692}
693
694//
695DBVT_PREFIX
696inline void             btDbvt::enumLeaves(     const btDbvtNode* root,
697                                                                   DBVT_IPOLICY)
698{
699        DBVT_CHECKTYPE
700                if(root->isinternal())
701                {
702                        enumLeaves(root->childs[0],policy);
703                        enumLeaves(root->childs[1],policy);
704                }
705                else
706                {
707                        policy.Process(root);
708                }
709}
710
711//
712DBVT_PREFIX
713inline void             btDbvt::collideTT(      const btDbvtNode* root0,
714                                                                  const btDbvtNode* root1,
715                                                                  DBVT_IPOLICY)
716{
717        DBVT_CHECKTYPE
718                if(root0&&root1)
719                {
720                        int                                                             depth=1;
721                        int                                                             treshold=DOUBLE_STACKSIZE-4;
722                        btAlignedObjectArray<sStkNN>    stkStack;
723                        stkStack.resize(DOUBLE_STACKSIZE);
724                        stkStack[0]=sStkNN(root0,root1);
725                        do      {               
726                                sStkNN  p=stkStack[--depth];
727                                if(depth>treshold)
728                                {
729                                        stkStack.resize(stkStack.size()*2);
730                                        treshold=stkStack.size()-4;
731                                }
732                                if(p.a==p.b)
733                                {
734                                        if(p.a->isinternal())
735                                        {
736                                                stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
737                                                stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
738                                                stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
739                                        }
740                                }
741                                else if(Intersect(p.a->volume,p.b->volume))
742                                {
743                                        if(p.a->isinternal())
744                                        {
745                                                if(p.b->isinternal())
746                                                {
747                                                        stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
748                                                        stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
749                                                        stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
750                                                        stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
751                                                }
752                                                else
753                                                {
754                                                        stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
755                                                        stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
756                                                }
757                                        }
758                                        else
759                                        {
760                                                if(p.b->isinternal())
761                                                {
762                                                        stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
763                                                        stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
764                                                }
765                                                else
766                                                {
767                                                        policy.Process(p.a,p.b);
768                                                }
769                                        }
770                                }
771                        } while(depth);
772                }
773}
774
775
776
777DBVT_PREFIX
778inline void             btDbvt::collideTTpersistentStack(       const btDbvtNode* root0,
779                                                                  const btDbvtNode* root1,
780                                                                  DBVT_IPOLICY)
781{
782        DBVT_CHECKTYPE
783                if(root0&&root1)
784                {
785                        int                                                             depth=1;
786                        int                                                             treshold=DOUBLE_STACKSIZE-4;
787                       
788                        m_stkStack.resize(DOUBLE_STACKSIZE);
789                        m_stkStack[0]=sStkNN(root0,root1);
790                        do      {               
791                                sStkNN  p=m_stkStack[--depth];
792                                if(depth>treshold)
793                                {
794                                        m_stkStack.resize(m_stkStack.size()*2);
795                                        treshold=m_stkStack.size()-4;
796                                }
797                                if(p.a==p.b)
798                                {
799                                        if(p.a->isinternal())
800                                        {
801                                                m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
802                                                m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
803                                                m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
804                                        }
805                                }
806                                else if(Intersect(p.a->volume,p.b->volume))
807                                {
808                                        if(p.a->isinternal())
809                                        {
810                                                if(p.b->isinternal())
811                                                {
812                                                        m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
813                                                        m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
814                                                        m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
815                                                        m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
816                                                }
817                                                else
818                                                {
819                                                        m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
820                                                        m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
821                                                }
822                                        }
823                                        else
824                                        {
825                                                if(p.b->isinternal())
826                                                {
827                                                        m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
828                                                        m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
829                                                }
830                                                else
831                                                {
832                                                        policy.Process(p.a,p.b);
833                                                }
834                                        }
835                                }
836                        } while(depth);
837                }
838}
839
840#if 0
841//
842DBVT_PREFIX
843inline void             btDbvt::collideTT(      const btDbvtNode* root0,
844                                                                  const btDbvtNode* root1,
845                                                                  const btTransform& xform,
846                                                                  DBVT_IPOLICY)
847{
848        DBVT_CHECKTYPE
849                if(root0&&root1)
850                {
851                        int                                                             depth=1;
852                        int                                                             treshold=DOUBLE_STACKSIZE-4;
853                        btAlignedObjectArray<sStkNN>    stkStack;
854                        stkStack.resize(DOUBLE_STACKSIZE);
855                        stkStack[0]=sStkNN(root0,root1);
856                        do      {
857                                sStkNN  p=stkStack[--depth];
858                                if(Intersect(p.a->volume,p.b->volume,xform))
859                                {
860                                        if(depth>treshold)
861                                        {
862                                                stkStack.resize(stkStack.size()*2);
863                                                treshold=stkStack.size()-4;
864                                        }
865                                        if(p.a->isinternal())
866                                        {
867                                                if(p.b->isinternal())
868                                                {                                       
869                                                        stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
870                                                        stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
871                                                        stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
872                                                        stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
873                                                }
874                                                else
875                                                {
876                                                        stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
877                                                        stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
878                                                }
879                                        }
880                                        else
881                                        {
882                                                if(p.b->isinternal())
883                                                {
884                                                        stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
885                                                        stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
886                                                }
887                                                else
888                                                {
889                                                        policy.Process(p.a,p.b);
890                                                }
891                                        }
892                                }
893                        } while(depth);
894                }
895}
896//
897DBVT_PREFIX
898inline void             btDbvt::collideTT(      const btDbvtNode* root0,
899                                                                  const btTransform& xform0,
900                                                                  const btDbvtNode* root1,
901                                                                  const btTransform& xform1,
902                                                                  DBVT_IPOLICY)
903{
904        const btTransform       xform=xform0.inverse()*xform1;
905        collideTT(root0,root1,xform,policy);
906}
907#endif
908
909//
910DBVT_PREFIX
911inline void             btDbvt::collideTV(      const btDbvtNode* root,
912                                                                  const btDbvtVolume& vol,
913                                                                  DBVT_IPOLICY)
914{
915        DBVT_CHECKTYPE
916                if(root)
917                {
918                        ATTRIBUTE_ALIGNED16(btDbvtVolume)               volume(vol);
919                        btAlignedObjectArray<const btDbvtNode*> stack;
920                        stack.resize(0);
921                        stack.reserve(SIMPLE_STACKSIZE);
922                        stack.push_back(root);
923                        do      {
924                                const btDbvtNode*       n=stack[stack.size()-1];
925                                stack.pop_back();
926                                if(Intersect(n->volume,volume))
927                                {
928                                        if(n->isinternal())
929                                        {
930                                                stack.push_back(n->childs[0]);
931                                                stack.push_back(n->childs[1]);
932                                        }
933                                        else
934                                        {
935                                                policy.Process(n);
936                                        }
937                                }
938                        } while(stack.size()>0);
939                }
940}
941
942DBVT_PREFIX
943inline void             btDbvt::rayTestInternal(        const btDbvtNode* root,
944                                                                const btVector3& rayFrom,
945                                                                const btVector3& rayTo,
946                                                                const btVector3& rayDirectionInverse,
947                                                                unsigned int signs[3],
948                                                                btScalar lambda_max,
949                                                                const btVector3& aabbMin,
950                                                                const btVector3& aabbMax,
951                                                                DBVT_IPOLICY) const
952{
953        (void) rayTo;
954        DBVT_CHECKTYPE
955        if(root)
956        {
957                btVector3 resultNormal;
958
959                int                                                             depth=1;
960                int                                                             treshold=DOUBLE_STACKSIZE-2;
961                btAlignedObjectArray<const btDbvtNode*>&        stack = m_rayTestStack;
962                stack.resize(DOUBLE_STACKSIZE);
963                stack[0]=root;
964                btVector3 bounds[2];
965                do     
966                {
967                        const btDbvtNode*       node=stack[--depth];
968                        bounds[0] = node->volume.Mins()-aabbMax;
969                        bounds[1] = node->volume.Maxs()-aabbMin;
970                        btScalar tmin=1.f,lambda_min=0.f;
971                        unsigned int result1=false;
972                        result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
973                        if(result1)
974                        {
975                                if(node->isinternal())
976                                {
977                                        if(depth>treshold)
978                                        {
979                                                stack.resize(stack.size()*2);
980                                                treshold=stack.size()-2;
981                                        }
982                                        stack[depth++]=node->childs[0];
983                                        stack[depth++]=node->childs[1];
984                                }
985                                else
986                                {
987                                        policy.Process(node);
988                                }
989                        }
990                } while(depth);
991        }
992}
993
994//
995DBVT_PREFIX
996inline void             btDbvt::rayTest(        const btDbvtNode* root,
997                                                                const btVector3& rayFrom,
998                                                                const btVector3& rayTo,
999                                                                DBVT_IPOLICY)
1000{
1001        DBVT_CHECKTYPE
1002                if(root)
1003                {
1004                        btVector3 rayDir = (rayTo-rayFrom);
1005                        rayDir.normalize ();
1006
1007                        ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
1008                        btVector3 rayDirectionInverse;
1009                        rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
1010                        rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
1011                        rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
1012                        unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
1013
1014                        btScalar lambda_max = rayDir.dot(rayTo-rayFrom);
1015
1016                        btVector3 resultNormal;
1017
1018                        btAlignedObjectArray<const btDbvtNode*> stack;
1019
1020                        int                                                             depth=1;
1021                        int                                                             treshold=DOUBLE_STACKSIZE-2;
1022
1023                        stack.resize(DOUBLE_STACKSIZE);
1024                        stack[0]=root;
1025                        btVector3 bounds[2];
1026                        do      {
1027                                const btDbvtNode*       node=stack[--depth];
1028
1029                                bounds[0] = node->volume.Mins();
1030                                bounds[1] = node->volume.Maxs();
1031                               
1032                                btScalar tmin=1.f,lambda_min=0.f;
1033                                unsigned int result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
1034
1035#ifdef COMPARE_BTRAY_AABB2
1036                                btScalar param=1.f;
1037                                bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal);
1038                                btAssert(result1 == result2);
1039#endif //TEST_BTRAY_AABB2
1040
1041                                if(result1)
1042                                {
1043                                        if(node->isinternal())
1044                                        {
1045                                                if(depth>treshold)
1046                                                {
1047                                                        stack.resize(stack.size()*2);
1048                                                        treshold=stack.size()-2;
1049                                                }
1050                                                stack[depth++]=node->childs[0];
1051                                                stack[depth++]=node->childs[1];
1052                                        }
1053                                        else
1054                                        {
1055                                                policy.Process(node);
1056                                        }
1057                                }
1058                        } while(depth);
1059
1060                }
1061}
1062
1063//
1064DBVT_PREFIX
1065inline void             btDbvt::collideKDOP(const btDbvtNode* root,
1066                                                                        const btVector3* normals,
1067                                                                        const btScalar* offsets,
1068                                                                        int count,
1069                                                                        DBVT_IPOLICY)
1070{
1071        DBVT_CHECKTYPE
1072                if(root)
1073                {
1074                        const int                                               inside=(1<<count)-1;
1075                        btAlignedObjectArray<sStkNP>    stack;
1076                        int                                                             signs[sizeof(unsigned)*8];
1077                        btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
1078                        for(int i=0;i<count;++i)
1079                        {
1080                                signs[i]=       ((normals[i].x()>=0)?1:0)+
1081                                        ((normals[i].y()>=0)?2:0)+
1082                                        ((normals[i].z()>=0)?4:0);
1083                        }
1084                        stack.reserve(SIMPLE_STACKSIZE);
1085                        stack.push_back(sStkNP(root,0));
1086                        do      {
1087                                sStkNP  se=stack[stack.size()-1];
1088                                bool    out=false;
1089                                stack.pop_back();
1090                                for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
1091                                {
1092                                        if(0==(se.mask&j))
1093                                        {
1094                                                const int       side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
1095                                                switch(side)
1096                                                {
1097                                                case    -1:     out=true;break;
1098                                                case    +1:     se.mask|=j;break;
1099                                                }
1100                                        }
1101                                }
1102                                if(!out)
1103                                {
1104                                        if((se.mask!=inside)&&(se.node->isinternal()))
1105                                        {
1106                                                stack.push_back(sStkNP(se.node->childs[0],se.mask));
1107                                                stack.push_back(sStkNP(se.node->childs[1],se.mask));
1108                                        }
1109                                        else
1110                                        {
1111                                                if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);
1112                                        }
1113                                }
1114                        } while(stack.size());
1115                }
1116}
1117
1118//
1119DBVT_PREFIX
1120inline void             btDbvt::collideOCL(     const btDbvtNode* root,
1121                                                                   const btVector3* normals,
1122                                                                   const btScalar* offsets,
1123                                                                   const btVector3& sortaxis,
1124                                                                   int count,
1125                                                                   DBVT_IPOLICY,
1126                                                                   bool fsort)
1127{
1128        DBVT_CHECKTYPE
1129                if(root)
1130                {
1131                        const unsigned                                  srtsgns=(sortaxis[0]>=0?1:0)+
1132                                (sortaxis[1]>=0?2:0)+
1133                                (sortaxis[2]>=0?4:0);
1134                        const int                                               inside=(1<<count)-1;
1135                        btAlignedObjectArray<sStkNPS>   stock;
1136                        btAlignedObjectArray<int>               ifree;
1137                        btAlignedObjectArray<int>               stack;
1138                        int                                                             signs[sizeof(unsigned)*8];
1139                        btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
1140                        for(int i=0;i<count;++i)
1141                        {
1142                                signs[i]=       ((normals[i].x()>=0)?1:0)+
1143                                        ((normals[i].y()>=0)?2:0)+
1144                                        ((normals[i].z()>=0)?4:0);
1145                        }
1146                        stock.reserve(SIMPLE_STACKSIZE);
1147                        stack.reserve(SIMPLE_STACKSIZE);
1148                        ifree.reserve(SIMPLE_STACKSIZE);
1149                        stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns))));
1150                        do      {
1151                                const int       id=stack[stack.size()-1];
1152                                sStkNPS         se=stock[id];
1153                                stack.pop_back();ifree.push_back(id);
1154                                if(se.mask!=inside)
1155                                {
1156                                        bool    out=false;
1157                                        for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
1158                                        {
1159                                                if(0==(se.mask&j))
1160                                                {
1161                                                        const int       side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
1162                                                        switch(side)
1163                                                        {
1164                                                        case    -1:     out=true;break;
1165                                                        case    +1:     se.mask|=j;break;
1166                                                        }
1167                                                }
1168                                        }
1169                                        if(out) continue;
1170                                }
1171                                if(policy.Descent(se.node))
1172                                {
1173                                        if(se.node->isinternal())
1174                                        {
1175                                                const btDbvtNode* pns[]={       se.node->childs[0],se.node->childs[1]};
1176                                                sStkNPS         nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)),
1177                                                        sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))};
1178                                                const int       q=nes[0].value<nes[1].value?1:0;                               
1179                                                int                     j=stack.size();
1180                                                if(fsort&&(j>0))
1181                                                {
1182                                                        /* Insert 0     */
1183                                                        j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
1184                                                        stack.push_back(0);
1185#if DBVT_USE_MEMMOVE
1186                                                        memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
1187#else
1188                                                        for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
1189#endif
1190                                                        stack[j]=allocate(ifree,stock,nes[q]);
1191                                                        /* Insert 1     */
1192                                                        j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size());
1193                                                        stack.push_back(0);
1194#if DBVT_USE_MEMMOVE
1195                                                        memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
1196#else
1197                                                        for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
1198#endif
1199                                                        stack[j]=allocate(ifree,stock,nes[1-q]);
1200                                                }
1201                                                else
1202                                                {
1203                                                        stack.push_back(allocate(ifree,stock,nes[q]));
1204                                                        stack.push_back(allocate(ifree,stock,nes[1-q]));
1205                                                }
1206                                        }
1207                                        else
1208                                        {
1209                                                policy.Process(se.node,se.value);
1210                                        }
1211                                }
1212                        } while(stack.size());
1213                }
1214}
1215
1216//
1217DBVT_PREFIX
1218inline void             btDbvt::collideTU(      const btDbvtNode* root,
1219                                                                  DBVT_IPOLICY)
1220{
1221        DBVT_CHECKTYPE
1222                if(root)
1223                {
1224                        btAlignedObjectArray<const btDbvtNode*> stack;
1225                        stack.reserve(SIMPLE_STACKSIZE);
1226                        stack.push_back(root);
1227                        do      {
1228                                const btDbvtNode*       n=stack[stack.size()-1];
1229                                stack.pop_back();
1230                                if(policy.Descent(n))
1231                                {
1232                                        if(n->isinternal())
1233                                        { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
1234                                        else
1235                                        { policy.Process(n); }
1236                                }
1237                        } while(stack.size()>0);
1238                }
1239}
1240
1241//
1242// PP Cleanup
1243//
1244
1245#undef DBVT_USE_MEMMOVE
1246#undef DBVT_USE_TEMPLATE
1247#undef DBVT_VIRTUAL_DTOR
1248#undef DBVT_VIRTUAL
1249#undef DBVT_PREFIX
1250#undef DBVT_IPOLICY
1251#undef DBVT_CHECKTYPE
1252#undef DBVT_IMPL_GENERIC
1253#undef DBVT_IMPL_SSE
1254#undef DBVT_USE_INTRINSIC_SSE
1255#undef DBVT_SELECT_IMPL
1256#undef DBVT_MERGE_IMPL
1257#undef DBVT_INT0_IMPL
1258
1259#endif
Note: See TracBrowser for help on using the repository browser.