Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Opcode::OBBCollider Class Reference

#include <Opcode.h>

Inheritance diagram for Opcode::OBBCollider:
Opcode::VolumeCollider Opcode::Collider Opcode::HybridOBBCollider

Public Member Functions

 OBBCollider ()
 
virtual ~OBBCollider ()
 
bool Collide (OBBCache &cache, const OBB &box, const Model &model, const Matrix4x4 *worldb=null, const Matrix4x4 *worldm=null)
 
inline_ void SetFullBoxBoxTest (bool flag)
 
 override (Collider) const char *ValidateSettings()
 
- Public Member Functions inherited from Opcode::VolumeCollider
 VolumeCollider ()
 
virtual ~VolumeCollider ()=0
 
inline_ udword GetNbTouchedPrimitives () const
 
inline_ const udwordGetTouchedPrimitives () const
 
inline_ udword GetNbVolumeBVTests () const
 
inline_ udword GetNbVolumePrimTests () const
 
 override (Collider) const char *ValidateSettings()
 
- Public Member Functions inherited from Opcode::Collider
 Collider ()
 
virtual ~Collider ()
 
inline_ BOOL GetContactStatus () const
 
inline_ BOOL FirstContactEnabled () const
 
inline_ BOOL TemporalCoherenceEnabled () const
 
inline_ BOOL ContactFound () const
 
inline_ BOOL TemporalHit () const
 
inline_ BOOL SkipPrimitiveTests () const
 
inline_ void SetFirstContact (bool flag)
 
inline_ void SetTemporalCoherence (bool flag)
 
inline_ void SetPrimitiveTests (bool flag)
 
virtual const char * ValidateSettings ()=0
 

Protected Member Functions

void _Collide (const AABBCollisionNode *node)
 
void _Collide (const AABBNoLeafNode *node)
 
void _Collide (const AABBQuantizedNode *node)
 
void _Collide (const AABBQuantizedNoLeafNode *node)
 
void _CollideNoPrimitiveTest (const AABBCollisionNode *node)
 
void _CollideNoPrimitiveTest (const AABBNoLeafNode *node)
 
void _CollideNoPrimitiveTest (const AABBQuantizedNode *node)
 
void _CollideNoPrimitiveTest (const AABBQuantizedNoLeafNode *node)
 
inline_ bool OBBContainsBox (const Point &bc, const Point &be)
 
inline_ bool BoxBoxOverlap (const Point &extents, const Point &center)
 
inline_ bool TriBoxOverlap ()
 
bool InitQuery (OBBCache &cache, const OBB &box, const Matrix4x4 *worldb=null, const Matrix4x4 *worldm=null)
 
- Protected Member Functions inherited from Opcode::VolumeCollider
void _Dump (const AABBCollisionNode *node)
 
void _Dump (const AABBNoLeafNode *node)
 
void _Dump (const AABBQuantizedNode *node)
 
void _Dump (const AABBQuantizedNoLeafNode *node)
 
 override (Collider) inline_ void InitQuery()
 
inline_ BOOL IsCacheValid (VolumeCache &cache)
 
- Protected Member Functions inherited from Opcode::Collider
inline_ BOOL Setup (const BaseModel *model)
 
virtual inline_ void InitQuery ()
 

Protected Attributes

Matrix3x3 mAR
 Absolute rotation matrix. More...
 
Matrix3x3 mRModelToBox
 Rotation from model space to obb space. More...
 
Matrix3x3 mRBoxToModel
 Rotation from obb space to model space. More...
 
Point mTModelToBox
 Translation from model space to obb space. More...
 
Point mTBoxToModel
 Translation from obb space to model space. More...
 
Point mBoxExtents
 
Point mB0
 
Point mB1
 
float mBBx1
 
float mBBy1
 
float mBBz1
 
float mBB_1
 
float mBB_2
 
float mBB_3
 
float mBB_4
 
float mBB_5
 
float mBB_6
 
float mBB_7
 
float mBB_8
 
float mBB_9
 
Point mLeafVerts [3]
 Triangle vertices. More...
 
bool mFullBoxBoxTest
 Perform full BV-BV tests (true) or SAT-lite tests (false) More...
 
- Protected Attributes inherited from Opcode::VolumeCollider
ContainermTouchedPrimitives
 List of touched primitives. More...
 
Point mCenterCoeff
 
Point mExtentsCoeff
 
udword mNbVolumeBVTests
 Number of Volume-BV tests. More...
 
udword mNbVolumePrimTests
 Number of Volume-Primitive tests. More...
 
- Protected Attributes inherited from Opcode::Collider
udword mFlags
 Bit flags. More...
 
const BaseModelmCurrentModel
 Current model for collision query (owner of touched faces) More...
 
const MeshInterfacemIMesh
 User-defined mesh interface. More...
 

Detailed Description

Definition at line 39 of file Opcode.h.

Constructor & Destructor Documentation

OBBCollider::OBBCollider ( )

Constructor.

Definition at line 63 of file OPC_OBBCollider.cpp.

63  : mFullBoxBoxTest(true)
64 {
65 }
OBBCollider::~OBBCollider ( )
virtual

Destructor.

Definition at line 72 of file OPC_OBBCollider.cpp.

73 {
74 }

Member Function Documentation

void OBBCollider::_Collide ( const AABBCollisionNode node)
protected

Recursive collision query for normal AABB trees.

Parameters
node[in] current collision node

Definition at line 412 of file OPC_OBBCollider.cpp.

413 {
414  // Perform OBB-AABB overlap test
415  if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return;
416 
417  TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents)
418 
419  if(node->IsLeaf())
420  {
421  OBB_PRIM(node->GetPrimitive(), OPC_CONTACT)
422  }
423  else
424  {
425  _Collide(node->GetPos());
426 
427  if(ContactFound()) return;
428 
429  _Collide(node->GetNeg());
430  }
431 }
void OBBCollider::_Collide ( const AABBNoLeafNode node)
protected

Recursive collision query for no-leaf AABB trees.

Parameters
node[in] current collision node

Definition at line 530 of file OPC_OBBCollider.cpp.

531 {
532  // Perform OBB-AABB overlap test
533  if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return;
534 
535  TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents)
536 
537  if(node->HasPosLeaf()) { OBB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) }
538  else _Collide(node->GetPos());
539 
540  if(ContactFound()) return;
541 
542  if(node->HasNegLeaf()) { OBB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) }
543  else _Collide(node->GetNeg());
544 }
void OBBCollider::_Collide ( const AABBQuantizedNode node)
protected

Recursive collision query for quantized AABB trees.

Parameters
node[in] current collision node

Definition at line 466 of file OPC_OBBCollider.cpp.

467 {
468  // Dequantize box
469  const QuantizedAABB& Box = node->mAABB;
470  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
471  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
472 
473  // Perform OBB-AABB overlap test
474  if(!BoxBoxOverlap(Extents, Center)) return;
475 
476  TEST_BOX_IN_OBB(Center, Extents)
477 
478  if(node->IsLeaf())
479  {
480  OBB_PRIM(node->GetPrimitive(), OPC_CONTACT)
481  }
482  else
483  {
484  _Collide(node->GetPos());
485 
486  if(ContactFound()) return;
487 
488  _Collide(node->GetNeg());
489  }
490 }
void OBBCollider::_Collide ( const AABBQuantizedNoLeafNode node)
protected

Recursive collision query for quantized no-leaf AABB trees.

Parameters
node[in] current collision node

Definition at line 574 of file OPC_OBBCollider.cpp.

575 {
576  // Dequantize box
577  const QuantizedAABB& Box = node->mAABB;
578  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
579  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
580 
581  // Perform OBB-AABB overlap test
582  if(!BoxBoxOverlap(Extents, Center)) return;
583 
584  TEST_BOX_IN_OBB(Center, Extents)
585 
586  if(node->HasPosLeaf()) { OBB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) }
587  else _Collide(node->GetPos());
588 
589  if(ContactFound()) return;
590 
591  if(node->HasNegLeaf()) { OBB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) }
592  else _Collide(node->GetNeg());
593 }
void OBBCollider::_CollideNoPrimitiveTest ( const AABBCollisionNode node)
protected

Recursive collision query for normal AABB trees, without primitive tests.

Parameters
node[in] current collision node

Definition at line 439 of file OPC_OBBCollider.cpp.

Referenced by Opcode::HybridOBBCollider::Collide().

440 {
441  // Perform OBB-AABB overlap test
442  if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return;
443 
444  TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents)
445 
446  if(node->IsLeaf())
447  {
448  SET_CONTACT(node->GetPrimitive(), OPC_CONTACT)
449  }
450  else
451  {
452  _CollideNoPrimitiveTest(node->GetPos());
453 
454  if(ContactFound()) return;
455 
456  _CollideNoPrimitiveTest(node->GetNeg());
457  }
458 }
void OBBCollider::_CollideNoPrimitiveTest ( const AABBNoLeafNode node)
protected

Recursive collision query for no-leaf AABB trees, without primitive tests.

Parameters
node[in] current collision node

Definition at line 552 of file OPC_OBBCollider.cpp.

553 {
554  // Perform OBB-AABB overlap test
555  if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return;
556 
557  TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents)
558 
559  if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) }
560  else _CollideNoPrimitiveTest(node->GetPos());
561 
562  if(ContactFound()) return;
563 
564  if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) }
565  else _CollideNoPrimitiveTest(node->GetNeg());
566 }
void OBBCollider::_CollideNoPrimitiveTest ( const AABBQuantizedNode node)
protected

Recursive collision query for quantized AABB trees, without primitive tests.

Parameters
node[in] current collision node

Definition at line 498 of file OPC_OBBCollider.cpp.

499 {
500  // Dequantize box
501  const QuantizedAABB& Box = node->mAABB;
502  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
503  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
504 
505  // Perform OBB-AABB overlap test
506  if(!BoxBoxOverlap(Extents, Center)) return;
507 
508  TEST_BOX_IN_OBB(Center, Extents)
509 
510  if(node->IsLeaf())
511  {
512  SET_CONTACT(node->GetPrimitive(), OPC_CONTACT)
513  }
514  else
515  {
516  _CollideNoPrimitiveTest(node->GetPos());
517 
518  if(ContactFound()) return;
519 
520  _CollideNoPrimitiveTest(node->GetNeg());
521  }
522 }
void OBBCollider::_CollideNoPrimitiveTest ( const AABBQuantizedNoLeafNode node)
protected

Recursive collision query for quantized no-leaf AABB trees, without primitive tests.

Parameters
node[in] current collision node

Definition at line 601 of file OPC_OBBCollider.cpp.

602 {
603  // Dequantize box
604  const QuantizedAABB& Box = node->mAABB;
605  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
606  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
607 
608  // Perform OBB-AABB overlap test
609  if(!BoxBoxOverlap(Extents, Center)) return;
610 
611  TEST_BOX_IN_OBB(Center, Extents)
612 
613  if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) }
614  else _CollideNoPrimitiveTest(node->GetPos());
615 
616  if(ContactFound()) return;
617 
618  if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) }
619  else _CollideNoPrimitiveTest(node->GetNeg());
620 }
inline_ bool Opcode::OBBCollider::BoxBoxOverlap ( const Point extents,
const Point center 
)
protected
bool OBBCollider::Collide ( OBBCache cache,
const OBB box,
const Model model,
const Matrix4x4 worldb = null,
const Matrix4x4 worldm = null 
)

Generic collision query for generic OPCODE models. After the call, access the results:

Parameters
cache[in/out] a box cache
box[in] collision OBB in local space
model[in] Opcode model to collide with
worldb[in] OBB's world matrix, or null
worldm[in] model's world matrix, or null
Returns
true if success
Warning
SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.

Definition at line 105 of file OPC_OBBCollider.cpp.

106 {
107  // Checkings
108  if(!Setup(&model)) return false;
109 
110  // Init collision query
111  if(InitQuery(cache, box, worldb, worldm)) return true;
112 
113  if(!model.HasLeafNodes())
114  {
115  if(model.IsQuantized())
116  {
117  const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree();
118 
119  // Setup dequantization coeffs
120  mCenterCoeff = Tree->mCenterCoeff;
122 
123  // Perform collision query
124  if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
125  else _Collide(Tree->GetNodes());
126  }
127  else
128  {
129  const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree();
130 
131  // Perform collision query
132  if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
133  else _Collide(Tree->GetNodes());
134  }
135  }
136  else
137  {
138  if(model.IsQuantized())
139  {
140  const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree();
141 
142  // Setup dequantization coeffs
143  mCenterCoeff = Tree->mCenterCoeff;
145 
146  // Perform collision query
147  if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
148  else _Collide(Tree->GetNodes());
149  }
150  else
151  {
152  const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree();
153 
154  // Perform collision query
155  if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
156  else _Collide(Tree->GetNodes());
157  }
158  }
159 
160  return true;
161 }
bool OBBCollider::InitQuery ( OBBCache cache,
const OBB box,
const Matrix4x4 worldb = null,
const Matrix4x4 worldm = null 
)
protected

Initializes a collision query :

  • reset stats & contact status
  • setup matrices
  • check temporal coherence
Parameters
cache[in/out] a box cache
box[in] obb in local space
worldb[in] obb's world matrix, or null
worldm[in] model's world matrix, or null
Returns
TRUE if we can return immediately
Warning
SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.

Definition at line 178 of file OPC_OBBCollider.cpp.

179 {
180  // 1) Call the base method
182 
183  // 2) Compute obb in world space
184  mBoxExtents = box.mExtents;
185 
186  Matrix4x4 WorldB;
187 
188  if(worldb)
189  {
190  WorldB = Matrix4x4( box.mRot * Matrix3x3(*worldb) );
191  WorldB.SetTrans(box.mCenter * *worldb);
192  }
193  else
194  {
195  WorldB = box.mRot;
196  WorldB.SetTrans(box.mCenter);
197  }
198 
199  // Setup matrices
200  Matrix4x4 InvWorldB;
201  InvertPRMatrix(InvWorldB, WorldB);
202 
203  if(worldm)
204  {
205  Matrix4x4 InvWorldM;
206  InvertPRMatrix(InvWorldM, *worldm);
207 
208  Matrix4x4 WorldBtoM = WorldB * InvWorldM;
209  Matrix4x4 WorldMtoB = *worldm * InvWorldB;
210 
211  mRModelToBox = WorldMtoB; WorldMtoB.GetTrans(mTModelToBox);
212  mRBoxToModel = WorldBtoM; WorldBtoM.GetTrans(mTBoxToModel);
213  }
214  else
215  {
216  mRModelToBox = InvWorldB; InvWorldB.GetTrans(mTModelToBox);
217  mRBoxToModel = WorldB; WorldB.GetTrans(mTBoxToModel);
218  }
219 
220  // 3) Setup destination pointer
222 
223  // 4) Special case: 1-triangle meshes [Opcode 1.3]
225  {
226  if(!SkipPrimitiveTests())
227  {
228  // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0.
230 
231  // Perform overlap test between the unique triangle and the box (and set contact status if needed)
233 
234  // Return immediately regardless of status
235  return TRUE;
236  }
237  }
238 
239  // 5) Check temporal coherence:
241  {
242  // Here we use temporal coherence
243  // => check results from previous frame before performing the collision query
244  if(FirstContactEnabled())
245  {
246  // We're only interested in the first contact found => test the unique previously touched face
248  {
249  // Get index of previously touched face = the first entry in the array
250  udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0);
251 
252  // Then reset the array:
253  // - if the overlap test below is successful, the index we'll get added back anyway
254  // - if it isn't, then the array should be reset anyway for the normal query
256 
257  // Perform overlap test between the cached triangle and the box (and set contact status if needed)
258  OBB_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT)
259 
260  // Return immediately if possible
261  if(GetContactStatus()) return TRUE;
262  }
263  // else no face has been touched during previous query
264  // => we'll have to perform a normal query
265  }
266  else
267  {
268  // ### rewrite this
270 
271  // We're interested in all contacts =>test the new real box N(ew) against the previous fat box P(revious):
272  if(IsCacheValid(cache) && TestBox.IsInside(cache.FatBox))
273  {
274  // - if N is included in P, return previous list
275  // => we simply leave the list (mTouchedFaces) unchanged
276 
277  // Set contact status if needed
279 
280  // In any case we don't need to do a query
281  return TRUE;
282  }
283  else
284  {
285  // - else do the query using a fat N
286 
287  // Reset cache since we'll about to perform a real query
289 
290  // Make a fat box so that coherence will work for subsequent frames
291  TestBox.mExtents *= cache.FatCoeff;
292  mBoxExtents *= cache.FatCoeff;
293 
294  // Update cache with query data (signature for cached faces)
295  cache.FatBox = TestBox;
296  }
297  }
298  }
299  else
300  {
301  // Here we don't use temporal coherence => do a normal query
303  }
304 
305  // Now we can precompute box-box data
306 
307  // Precompute absolute box-to-model rotation matrix
308  for(udword i=0;i<3;i++)
309  {
310  for(udword j=0;j<3;j++)
311  {
312  // Epsilon value prevents floating-point inaccuracies (strategy borrowed from RAPID)
313  mAR.m[i][j] = 1e-6f + fabsf(mRBoxToModel.m[i][j]);
314  }
315  }
316 
317  // Precompute bounds for box-in-box test
320 
321  // Precompute box-box data - Courtesy of Erwin de Vries
322  mBBx1 = mBoxExtents.x*mAR.m[0][0] + mBoxExtents.y*mAR.m[1][0] + mBoxExtents.z*mAR.m[2][0];
323  mBBy1 = mBoxExtents.x*mAR.m[0][1] + mBoxExtents.y*mAR.m[1][1] + mBoxExtents.z*mAR.m[2][1];
324  mBBz1 = mBoxExtents.x*mAR.m[0][2] + mBoxExtents.y*mAR.m[1][2] + mBoxExtents.z*mAR.m[2][2];
325 
326  mBB_1 = mBoxExtents.y*mAR.m[2][0] + mBoxExtents.z*mAR.m[1][0];
327  mBB_2 = mBoxExtents.x*mAR.m[2][0] + mBoxExtents.z*mAR.m[0][0];
328  mBB_3 = mBoxExtents.x*mAR.m[1][0] + mBoxExtents.y*mAR.m[0][0];
329  mBB_4 = mBoxExtents.y*mAR.m[2][1] + mBoxExtents.z*mAR.m[1][1];
330  mBB_5 = mBoxExtents.x*mAR.m[2][1] + mBoxExtents.z*mAR.m[0][1];
331  mBB_6 = mBoxExtents.x*mAR.m[1][1] + mBoxExtents.y*mAR.m[0][1];
332  mBB_7 = mBoxExtents.y*mAR.m[2][2] + mBoxExtents.z*mAR.m[1][2];
333  mBB_8 = mBoxExtents.x*mAR.m[2][2] + mBoxExtents.z*mAR.m[0][2];
334  mBB_9 = mBoxExtents.x*mAR.m[1][2] + mBoxExtents.y*mAR.m[0][2];
335 
336  return FALSE;
337 }
inline_ bool OBBCollider::OBBContainsBox ( const Point bc,
const Point be 
)
protected

Checks the OBB completely contains the box. In which case we can end the query sooner.

Parameters
bc[in] box center
be[in] box extents
Returns
true if the OBB contains the whole box

Definition at line 347 of file OPC_OBBCollider.cpp.

348 {
349  // I assume if all 8 box vertices are inside the OBB, so does the whole box.
350  // Sounds ok but maybe there's a better way?
351 /*
352 #define TEST_PT(a,b,c) \
353  p.x=a; p.y=b; p.z=c; p+=bc; \
354  f = p.x * mRModelToBox.m[0][0] + p.y * mRModelToBox.m[1][0] + p.z * mRModelToBox.m[2][0]; if(f>mB0.x || f<mB1.x) return FALSE;\
355  f = p.x * mRModelToBox.m[0][1] + p.y * mRModelToBox.m[1][1] + p.z * mRModelToBox.m[2][1]; if(f>mB0.y || f<mB1.y) return FALSE;\
356  f = p.x * mRModelToBox.m[0][2] + p.y * mRModelToBox.m[1][2] + p.z * mRModelToBox.m[2][2]; if(f>mB0.z || f<mB1.z) return FALSE;
357 
358  Point p;
359  float f;
360 
361  TEST_PT(be.x, be.y, be.z)
362  TEST_PT(-be.x, be.y, be.z)
363  TEST_PT(be.x, -be.y, be.z)
364  TEST_PT(-be.x, -be.y, be.z)
365  TEST_PT(be.x, be.y, -be.z)
366  TEST_PT(-be.x, be.y, -be.z)
367  TEST_PT(be.x, -be.y, -be.z)
368  TEST_PT(-be.x, -be.y, -be.z)
369 
370  return TRUE;
371 */
372 
373  // Yes there is:
374  // - compute model-box's AABB in OBB space
375  // - test AABB-in-AABB
376  float NCx = bc.x * mRModelToBox.m[0][0] + bc.y * mRModelToBox.m[1][0] + bc.z * mRModelToBox.m[2][0];
377  float NEx = fabsf(mRModelToBox.m[0][0] * be.x) + fabsf(mRModelToBox.m[1][0] * be.y) + fabsf(mRModelToBox.m[2][0] * be.z);
378 
379  if(mB0.x < NCx+NEx) return FALSE;
380  if(mB1.x > NCx-NEx) return FALSE;
381 
382  float NCy = bc.x * mRModelToBox.m[0][1] + bc.y * mRModelToBox.m[1][1] + bc.z * mRModelToBox.m[2][1];
383  float NEy = fabsf(mRModelToBox.m[0][1] * be.x) + fabsf(mRModelToBox.m[1][1] * be.y) + fabsf(mRModelToBox.m[2][1] * be.z);
384 
385  if(mB0.y < NCy+NEy) return FALSE;
386  if(mB1.y > NCy-NEy) return FALSE;
387 
388  float NCz = bc.x * mRModelToBox.m[0][2] + bc.y * mRModelToBox.m[1][2] + bc.z * mRModelToBox.m[2][2];
389  float NEz = fabsf(mRModelToBox.m[0][2] * be.x) + fabsf(mRModelToBox.m[1][2] * be.y) + fabsf(mRModelToBox.m[2][2] * be.z);
390 
391  if(mB0.z < NCz+NEz) return FALSE;
392  if(mB1.z > NCz-NEz) return FALSE;
393 
394  return TRUE;
395 }
Opcode::OBBCollider::override ( Collider  ) const

Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider.

Returns
null if everything is ok, else a string describing the problem
inline_ void Opcode::OBBCollider::SetFullBoxBoxTest ( bool  flag)
inline

Settings: select between full box-box tests or "SAT-lite" tests (where Class III axes are discarded)

Parameters
flag[in] true for full tests, false for coarse tests

Definition at line 72 of file Opcode.h.

inline_ bool Opcode::OBBCollider::TriBoxOverlap ( )
protected

Member Data Documentation

Matrix3x3 Opcode::OBBCollider::mAR
protected

Absolute rotation matrix.

Definition at line 86 of file Opcode.h.

Point Opcode::OBBCollider::mB0
protected
  • mTModelToBox + mBoxExtents

Definition at line 93 of file Opcode.h.

Point Opcode::OBBCollider::mB1
protected
  • mTModelToBox - mBoxExtents

Definition at line 94 of file Opcode.h.

float Opcode::OBBCollider::mBB_1
protected

Definition at line 100 of file Opcode.h.

float Opcode::OBBCollider::mBB_2
protected

Definition at line 101 of file Opcode.h.

float Opcode::OBBCollider::mBB_3
protected

Definition at line 102 of file Opcode.h.

float Opcode::OBBCollider::mBB_4
protected

Definition at line 103 of file Opcode.h.

float Opcode::OBBCollider::mBB_5
protected

Definition at line 104 of file Opcode.h.

float Opcode::OBBCollider::mBB_6
protected

Definition at line 105 of file Opcode.h.

float Opcode::OBBCollider::mBB_7
protected

Definition at line 106 of file Opcode.h.

float Opcode::OBBCollider::mBB_8
protected

Definition at line 107 of file Opcode.h.

float Opcode::OBBCollider::mBB_9
protected

Definition at line 108 of file Opcode.h.

float Opcode::OBBCollider::mBBx1
protected

Definition at line 96 of file Opcode.h.

float Opcode::OBBCollider::mBBy1
protected

Definition at line 97 of file Opcode.h.

float Opcode::OBBCollider::mBBz1
protected

Definition at line 98 of file Opcode.h.

Point Opcode::OBBCollider::mBoxExtents
protected

Definition at line 92 of file Opcode.h.

bool Opcode::OBBCollider::mFullBoxBoxTest
protected

Perform full BV-BV tests (true) or SAT-lite tests (false)

Definition at line 113 of file Opcode.h.

Point Opcode::OBBCollider::mLeafVerts[3]
protected

Triangle vertices.

Definition at line 111 of file Opcode.h.

Matrix3x3 Opcode::OBBCollider::mRBoxToModel
protected

Rotation from obb space to model space.

Definition at line 88 of file Opcode.h.

Matrix3x3 Opcode::OBBCollider::mRModelToBox
protected

Rotation from model space to obb space.

Definition at line 87 of file Opcode.h.

Point Opcode::OBBCollider::mTBoxToModel
protected

Translation from obb space to model space.

Definition at line 90 of file Opcode.h.

Point Opcode::OBBCollider::mTModelToBox
protected

Translation from model space to obb space.

Definition at line 89 of file Opcode.h.


The documentation for this class was generated from the following files: