Changed: Python bindings integer type size corrections to match platform pointer...
[ode.git] / OPCODE / OPC_AABBCollider.cpp
bloba19231176c7c5964d4b8dc5a991272ebbfa0568b
1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 /*
3 * OPCODE - Optimized Collision Detection
4 * Copyright (C) 2001 Pierre Terdiman
5 * Homepage: http://www.codercorner.com/Opcode.htm
6 */
7 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10 /**
11 * Contains code for an AABB collider.
12 * \file OPC_AABBCollider.cpp
13 * \author Pierre Terdiman
14 * \date January, 1st, 2002
16 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 /**
20 * Contains an AABB-vs-tree collider.
22 * \class AABBCollider
23 * \author Pierre Terdiman
24 * \version 1.3
25 * \date January, 1st, 2002
27 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30 // Precompiled Header
31 #include "Stdafx.h"
33 using namespace Opcode;
35 #include "OPC_BoxBoxOverlap.h"
36 #include "OPC_TriBoxOverlap.h"
38 #define SET_CONTACT(prim_index, flag) \
39 /* Set contact status */ \
40 mFlags |= flag; \
41 mTouchedPrimitives->Add(udword(prim_index));
43 //! AABB-triangle test
44 #define AABB_PRIM(prim_index, flag) \
45 /* Request vertices from the app */ \
46 VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \
47 mLeafVerts[0] = *VP.Vertex[0]; \
48 mLeafVerts[1] = *VP.Vertex[1]; \
49 mLeafVerts[2] = *VP.Vertex[2]; \
50 /* Perform triangle-box overlap test */ \
51 if(TriBoxOverlap()) \
52 { \
53 SET_CONTACT(prim_index, flag) \
56 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
57 /**
58 * Constructor.
60 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
61 AABBCollider::AABBCollider()
65 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66 /**
67 * Destructor.
69 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
70 AABBCollider::~AABBCollider()
74 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
75 /**
76 * Generic collision query for generic OPCODE models. After the call, access the results:
77 * - with GetContactStatus()
78 * - with GetNbTouchedPrimitives()
79 * - with GetTouchedPrimitives()
81 * \param cache [in/out] a box cache
82 * \param box [in] collision AABB in world space
83 * \param model [in] Opcode model to collide with
84 * \return true if success
85 * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
87 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
88 bool AABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const Model& model)
90 // Checkings
91 if(!Setup(&model)) return false;
93 // Init collision query
94 if(InitQuery(cache, box)) return true;
96 if(!model.HasLeafNodes())
98 if(model.IsQuantized())
100 const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree());
102 // Setup dequantization coeffs
103 mCenterCoeff = Tree->mCenterCoeff;
104 mExtentsCoeff = Tree->mExtentsCoeff;
106 // Perform collision query
107 if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
108 else _Collide(Tree->GetNodes());
110 else
112 const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree());
114 // Perform collision query
115 if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
116 else _Collide(Tree->GetNodes());
119 else
121 if(model.IsQuantized())
123 const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree());
125 // Setup dequantization coeffs
126 mCenterCoeff = Tree->mCenterCoeff;
127 mExtentsCoeff = Tree->mExtentsCoeff;
129 // Perform collision query
130 if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
131 else _Collide(Tree->GetNodes());
133 else
135 const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree());
137 // Perform collision query
138 if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
139 else _Collide(Tree->GetNodes());
142 return true;
145 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
147 * Initializes a collision query :
148 * - reset stats & contact status
149 * - check temporal coherence
151 * \param cache [in/out] a box cache
152 * \param box [in] AABB in world space
153 * \return TRUE if we can return immediately
155 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
156 BOOL AABBCollider::InitQuery(AABBCache& cache, const CollisionAABB& box)
158 // 1) Call the base method
159 VolumeCollider::InitQuery();
161 // 2) Keep track of the query box
162 mBox = box;
164 // 3) Setup destination pointer
165 mTouchedPrimitives = &cache.TouchedPrimitives;
167 // 4) Special case: 1-triangle meshes [Opcode 1.3]
168 if(mCurrentModel && mCurrentModel->HasSingleNode())
170 if(!SkipPrimitiveTests())
172 // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0.
173 mTouchedPrimitives->Reset();
175 // Perform overlap test between the unique triangle and the box (and set contact status if needed)
176 AABB_PRIM(udword(0), OPC_CONTACT)
178 // Return immediately regardless of status
179 return TRUE;
183 // 5) Check temporal coherence :
184 if(TemporalCoherenceEnabled())
186 // Here we use temporal coherence
187 // => check results from previous frame before performing the collision query
188 if(FirstContactEnabled())
190 // We're only interested in the first contact found => test the unique previously touched face
191 if(mTouchedPrimitives->GetNbEntries())
193 // Get index of previously touched face = the first entry in the array
194 udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0);
196 // Then reset the array:
197 // - if the overlap test below is successful, the index we'll get added back anyway
198 // - if it isn't, then the array should be reset anyway for the normal query
199 mTouchedPrimitives->Reset();
201 // Perform overlap test between the cached triangle and the box (and set contact status if needed)
202 AABB_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT)
204 // Return immediately if possible
205 if(GetContactStatus()) return TRUE;
207 // else no face has been touched during previous query
208 // => we'll have to perform a normal query
210 else
212 // We're interested in all contacts =>test the new real box N(ew) against the previous fat box P(revious):
213 if(IsCacheValid(cache) && mBox.IsInside(cache.FatBox))
215 // - if N is included in P, return previous list
216 // => we simply leave the list (mTouchedFaces) unchanged
218 // Set contact status if needed
219 if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT;
221 // In any case we don't need to do a query
222 return TRUE;
224 else
226 // - else do the query using a fat N
228 // Reset cache since we'll about to perform a real query
229 mTouchedPrimitives->Reset();
231 // Make a fat box so that coherence will work for subsequent frames
232 mBox.mExtents *= cache.FatCoeff;
234 // Update cache with query data (signature for cached faces)
235 cache.FatBox = mBox;
239 else
241 // Here we don't use temporal coherence => do a normal query
242 mTouchedPrimitives->Reset();
245 // 5) Precompute min & max bounds if needed
246 mMin = box.mCenter - box.mExtents;
247 mMax = box.mCenter + box.mExtents;
249 return FALSE;
252 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
254 * Collision query for vanilla AABB trees.
255 * \param cache [in/out] a box cache
256 * \param box [in] collision AABB in world space
257 * \param tree [in] AABB tree
258 * \return true if success
260 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
261 bool AABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const AABBTree* tree)
263 // This is typically called for a scene tree, full of -AABBs-, not full of triangles.
264 // So we don't really have "primitives" to deal with. Hence it doesn't work with
265 // "FirstContact" + "TemporalCoherence".
266 ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) );
268 // Checkings
269 if(!tree) return false;
271 // Init collision query
272 if(InitQuery(cache, box)) return true;
274 // Perform collision query
275 _Collide(tree);
277 return true;
280 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
282 * Checks the AABB completely contains the box. In which case we can end the query sooner.
283 * \param bc [in] box center
284 * \param be [in] box extents
285 * \return true if the AABB contains the whole box
287 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
288 inline_ BOOL AABBCollider::AABBContainsBox(const Point& bc, const Point& be)
290 if(mMin.x > bc.x - be.x) return FALSE;
291 if(mMin.y > bc.y - be.y) return FALSE;
292 if(mMin.z > bc.z - be.z) return FALSE;
294 if(mMax.x < bc.x + be.x) return FALSE;
295 if(mMax.y < bc.y + be.y) return FALSE;
296 if(mMax.z < bc.z + be.z) return FALSE;
298 return TRUE;
301 #define TEST_BOX_IN_AABB(center, extents) \
302 if(AABBContainsBox(center, extents)) \
304 /* Set contact status */ \
305 mFlags |= OPC_CONTACT; \
306 _Dump(node); \
307 return; \
310 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
312 * Recursive collision query for normal AABB trees.
313 * \param node [in] current collision node
315 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
316 void AABBCollider::_Collide(const AABBCollisionNode* node)
318 // Perform AABB-AABB overlap test
319 if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return;
321 TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents)
323 if(node->IsLeaf())
325 AABB_PRIM(node->GetPrimitive(), OPC_CONTACT)
327 else
329 _Collide(node->GetPos());
331 if(ContactFound()) return;
333 _Collide(node->GetNeg());
337 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
339 * Recursive collision query for normal AABB trees, without primitive tests.
340 * \param node [in] current collision node
342 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
343 void AABBCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node)
345 // Perform AABB-AABB overlap test
346 if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return;
348 TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents)
350 if(node->IsLeaf())
352 SET_CONTACT(node->GetPrimitive(), OPC_CONTACT)
354 else
356 _CollideNoPrimitiveTest(node->GetPos());
358 if(ContactFound()) return;
360 _CollideNoPrimitiveTest(node->GetNeg());
364 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
366 * Recursive collision query for quantized AABB trees.
367 * \param node [in] current collision node
369 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
370 void AABBCollider::_Collide(const AABBQuantizedNode* node)
372 // Dequantize box
373 const QuantizedAABB& Box = node->mAABB;
374 const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
375 const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
377 // Perform AABB-AABB overlap test
378 if(!AABBAABBOverlap(Extents, Center)) return;
380 TEST_BOX_IN_AABB(Center, Extents)
382 if(node->IsLeaf())
384 AABB_PRIM(node->GetPrimitive(), OPC_CONTACT)
386 else
388 _Collide(node->GetPos());
390 if(ContactFound()) return;
392 _Collide(node->GetNeg());
396 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
398 * Recursive collision query for quantized AABB trees, without primitive tests.
399 * \param node [in] current collision node
401 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
402 void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node)
404 // Dequantize box
405 const QuantizedAABB& Box = node->mAABB;
406 const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
407 const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
409 // Perform AABB-AABB overlap test
410 if(!AABBAABBOverlap(Extents, Center)) return;
412 TEST_BOX_IN_AABB(Center, Extents)
414 if(node->IsLeaf())
416 SET_CONTACT(node->GetPrimitive(), OPC_CONTACT)
418 else
420 _CollideNoPrimitiveTest(node->GetPos());
422 if(ContactFound()) return;
424 _CollideNoPrimitiveTest(node->GetNeg());
428 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
430 * Recursive collision query for no-leaf AABB trees.
431 * \param node [in] current collision node
433 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
434 void AABBCollider::_Collide(const AABBNoLeafNode* node)
436 // Perform AABB-AABB overlap test
437 if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return;
439 TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents)
441 if(node->HasPosLeaf()) { AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) }
442 else _Collide(node->GetPos());
444 if(ContactFound()) return;
446 if(node->HasNegLeaf()) { AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) }
447 else _Collide(node->GetNeg());
450 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
452 * Recursive collision query for no-leaf AABB trees, without primitive tests.
453 * \param node [in] current collision node
455 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
456 void AABBCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node)
458 // Perform AABB-AABB overlap test
459 if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return;
461 TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents)
463 if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) }
464 else _CollideNoPrimitiveTest(node->GetPos());
466 if(ContactFound()) return;
468 if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) }
469 else _CollideNoPrimitiveTest(node->GetNeg());
472 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
474 * Recursive collision query for quantized no-leaf AABB trees.
475 * \param node [in] current collision node
477 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
478 void AABBCollider::_Collide(const AABBQuantizedNoLeafNode* node)
480 // Dequantize box
481 const QuantizedAABB& Box = node->mAABB;
482 const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
483 const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
485 // Perform AABB-AABB overlap test
486 if(!AABBAABBOverlap(Extents, Center)) return;
488 TEST_BOX_IN_AABB(Center, Extents)
490 if(node->HasPosLeaf()) { AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) }
491 else _Collide(node->GetPos());
493 if(ContactFound()) return;
495 if(node->HasNegLeaf()) { AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) }
496 else _Collide(node->GetNeg());
499 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
501 * Recursive collision query for quantized no-leaf AABB trees, without primitive tests.
502 * \param node [in] current collision node
504 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
505 void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node)
507 // Dequantize box
508 const QuantizedAABB& Box = node->mAABB;
509 const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
510 const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
512 // Perform AABB-AABB overlap test
513 if(!AABBAABBOverlap(Extents, Center)) return;
515 TEST_BOX_IN_AABB(Center, Extents)
517 if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) }
518 else _CollideNoPrimitiveTest(node->GetPos());
520 if(ContactFound()) return;
522 if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) }
523 else _CollideNoPrimitiveTest(node->GetNeg());
526 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
528 * Recursive collision query for vanilla AABB trees.
529 * \param node [in] current collision node
531 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
532 void AABBCollider::_Collide(const AABBTreeNode* node)
534 // Perform AABB-AABB overlap test
535 Point Center, Extents;
536 node->GetAABB()->GetCenter(Center);
537 node->GetAABB()->GetExtents(Extents);
538 if(!AABBAABBOverlap(Center, Extents)) return;
540 if(node->IsLeaf() || AABBContainsBox(Center, Extents))
542 mFlags |= OPC_CONTACT;
543 mTouchedPrimitives->Add(node->GetPrimitives(), node->GetNbPrimitives());
545 else
547 _Collide(node->GetPos());
548 _Collide(node->GetNeg());
555 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
557 * Constructor.
559 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
560 HybridAABBCollider::HybridAABBCollider()
564 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
566 * Destructor.
568 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
569 HybridAABBCollider::~HybridAABBCollider()
573 bool HybridAABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const HybridModel& model)
575 // We don't want primitive tests here!
576 mFlags |= OPC_NO_PRIMITIVE_TESTS;
578 // Checkings
579 if(!Setup(&model)) return false;
581 // Init collision query
582 if(InitQuery(cache, box)) return true;
584 // Special case for 1-leaf trees
585 if(mCurrentModel && mCurrentModel->HasSingleNode())
587 // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles
588 udword Nb = mIMesh->GetNbTriangles();
590 // Loop through all triangles
591 for(udword i=0;i<Nb;i++)
593 AABB_PRIM(i, OPC_CONTACT)
595 return true;
598 // Override destination array since we're only going to get leaf boxes here
599 mTouchedBoxes.Reset();
600 mTouchedPrimitives = &mTouchedBoxes;
602 // Now, do the actual query against leaf boxes
603 if(!model.HasLeafNodes())
605 if(model.IsQuantized())
607 const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree());
609 // Setup dequantization coeffs
610 mCenterCoeff = Tree->mCenterCoeff;
611 mExtentsCoeff = Tree->mExtentsCoeff;
613 // Perform collision query - we don't want primitive tests here!
614 _CollideNoPrimitiveTest(Tree->GetNodes());
616 else
618 const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree());
620 // Perform collision query - we don't want primitive tests here!
621 _CollideNoPrimitiveTest(Tree->GetNodes());
624 else
626 if(model.IsQuantized())
628 const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree());
630 // Setup dequantization coeffs
631 mCenterCoeff = Tree->mCenterCoeff;
632 mExtentsCoeff = Tree->mExtentsCoeff;
634 // Perform collision query - we don't want primitive tests here!
635 _CollideNoPrimitiveTest(Tree->GetNodes());
637 else
639 const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree());
641 // Perform collision query - we don't want primitive tests here!
642 _CollideNoPrimitiveTest(Tree->GetNodes());
646 // We only have a list of boxes so far
647 if(GetContactStatus())
649 // Reset contact status, since it currently only reflects collisions with leaf boxes
650 Collider::InitQuery();
652 // Change dest container so that we can use built-in overlap tests and get collided primitives
653 cache.TouchedPrimitives.Reset();
654 mTouchedPrimitives = &cache.TouchedPrimitives;
656 // Read touched leaf boxes
657 udword Nb = mTouchedBoxes.GetNbEntries();
658 const udword* Touched = mTouchedBoxes.GetEntries();
660 const LeafTriangles* LT = model.GetLeafTriangles();
661 const udword* Indices = model.GetIndices();
663 // Loop through touched leaves
664 while(Nb--)
666 const LeafTriangles& CurrentLeaf = LT[*Touched++];
668 // Each leaf box has a set of triangles
669 udword NbTris = CurrentLeaf.GetNbTriangles();
670 if(Indices)
672 const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()];
674 // Loop through triangles and test each of them
675 while(NbTris--)
677 udword TriangleIndex = *T++;
678 AABB_PRIM(TriangleIndex, OPC_CONTACT)
681 else
683 udword BaseIndex = CurrentLeaf.GetTriangleIndex();
685 // Loop through triangles and test each of them
686 while(NbTris--)
688 udword TriangleIndex = BaseIndex++;
689 AABB_PRIM(TriangleIndex, OPC_CONTACT)
695 return true;