Bullet Collision Detection & Physics Library: btDbvt.h Source File

Bullet Collision Detection & Physics Library

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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