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::LSSCollider Class Reference

#include <Opcode.h>

Inheritance diagram for Opcode::LSSCollider:
Opcode::VolumeCollider Opcode::Collider Opcode::HybridLSSCollider

Public Member Functions

 LSSCollider ()
 
virtual ~LSSCollider ()
 
bool Collide (LSSCache &cache, const LSS &lss, const Model &model, const Matrix4x4 *worldl=null, const Matrix4x4 *worldm=null)
 
bool Collide (LSSCache &cache, const LSS &lss, const AABBTree *tree)
 
- 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 _Collide (const AABBTreeNode *node)
 
void _CollideNoPrimitiveTest (const AABBCollisionNode *node)
 
void _CollideNoPrimitiveTest (const AABBNoLeafNode *node)
 
void _CollideNoPrimitiveTest (const AABBQuantizedNode *node)
 
void _CollideNoPrimitiveTest (const AABBQuantizedNoLeafNode *node)
 
inline_ bool LSSContainsBox (const Point &bc, const Point &be)
 
inline_ bool LSSAABBOverlap (const Point &center, const Point &extents)
 
inline_ bool LSSTriOverlap (const Point &vert0, const Point &vert1, const Point &vert2)
 
bool InitQuery (LSSCache &cache, const LSS &lss, const Matrix4x4 *worldl=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

Segment mSeg
 Segment. More...
 
float mRadius2
 LSS radius squared. 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 40 of file Opcode.h.

Constructor & Destructor Documentation

LSSCollider::LSSCollider ( )

Constructor.

Definition at line 60 of file OPC_LSSCollider.cpp.

61 {
62 // mCenter.Zero();
63 // mRadius2 = 0.0f;
64 }
LSSCollider::~LSSCollider ( )
virtual

Destructor.

Definition at line 71 of file OPC_LSSCollider.cpp.

72 {
73 }

Member Function Documentation

void LSSCollider::_Collide ( const AABBCollisionNode node)
protected

Recursive collision query for normal AABB trees.

Parameters
node[in] current collision node

Definition at line 344 of file OPC_LSSCollider.cpp.

345 {
346  // Perform LSS-AABB overlap test
347  if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return;
348 
349  TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents)
350 
351  if(node->IsLeaf())
352  {
353  LSS_PRIM(node->GetPrimitive(), OPC_CONTACT)
354  }
355  else
356  {
357  _Collide(node->GetPos());
358 
359  if(ContactFound()) return;
360 
361  _Collide(node->GetNeg());
362  }
363 }
void LSSCollider::_Collide ( const AABBNoLeafNode node)
protected

Recursive collision query for no-leaf AABB trees.

Parameters
node[in] current collision node

Definition at line 462 of file OPC_LSSCollider.cpp.

463 {
464  // Perform LSS-AABB overlap test
465  if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return;
466 
467  TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents)
468 
469  if(node->HasPosLeaf()) { LSS_PRIM(node->GetPosPrimitive(), OPC_CONTACT) }
470  else _Collide(node->GetPos());
471 
472  if(ContactFound()) return;
473 
474  if(node->HasNegLeaf()) { LSS_PRIM(node->GetNegPrimitive(), OPC_CONTACT) }
475  else _Collide(node->GetNeg());
476 }
void LSSCollider::_Collide ( const AABBQuantizedNode node)
protected

Recursive collision query for quantized AABB trees.

Parameters
node[in] current collision node

Definition at line 398 of file OPC_LSSCollider.cpp.

399 {
400  // Dequantize box
401  const QuantizedAABB& Box = node->mAABB;
402  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
403  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
404 
405  // Perform LSS-AABB overlap test
406  if(!LSSAABBOverlap(Center, Extents)) return;
407 
408  TEST_BOX_IN_LSS(Center, Extents)
409 
410  if(node->IsLeaf())
411  {
412  LSS_PRIM(node->GetPrimitive(), OPC_CONTACT)
413  }
414  else
415  {
416  _Collide(node->GetPos());
417 
418  if(ContactFound()) return;
419 
420  _Collide(node->GetNeg());
421  }
422 }
void LSSCollider::_Collide ( const AABBQuantizedNoLeafNode node)
protected

Recursive collision query for quantized no-leaf AABB trees.

Parameters
node[in] current collision node

Definition at line 506 of file OPC_LSSCollider.cpp.

507 {
508  // Dequantize box
509  const QuantizedAABB& Box = node->mAABB;
510  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
511  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
512 
513  // Perform LSS-AABB overlap test
514  if(!LSSAABBOverlap(Center, Extents)) return;
515 
516  TEST_BOX_IN_LSS(Center, Extents)
517 
518  if(node->HasPosLeaf()) { LSS_PRIM(node->GetPosPrimitive(), OPC_CONTACT) }
519  else _Collide(node->GetPos());
520 
521  if(ContactFound()) return;
522 
523  if(node->HasNegLeaf()) { LSS_PRIM(node->GetNegPrimitive(), OPC_CONTACT) }
524  else _Collide(node->GetNeg());
525 }
void LSSCollider::_Collide ( const AABBTreeNode node)
protected

Recursive collision query for vanilla AABB trees.

Parameters
node[in] current collision node

Definition at line 560 of file OPC_LSSCollider.cpp.

561 {
562  // Perform LSS-AABB overlap test
563  Point Center, Extents;
564  node->GetAABB()->GetCenter(Center);
565  node->GetAABB()->GetExtents(Extents);
566  if(!LSSAABBOverlap(Center, Extents)) return;
567 
568  if(node->IsLeaf() || LSSContainsBox(Center, Extents))
569  {
570  mFlags |= OPC_CONTACT;
572  }
573  else
574  {
575  _Collide(node->GetPos());
576  _Collide(node->GetNeg());
577  }
578 }
void LSSCollider::_CollideNoPrimitiveTest ( const AABBCollisionNode node)
protected

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

Parameters
node[in] current collision node

Definition at line 371 of file OPC_LSSCollider.cpp.

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

372 {
373  // Perform LSS-AABB overlap test
374  if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return;
375 
376  TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents)
377 
378  if(node->IsLeaf())
379  {
380  SET_CONTACT(node->GetPrimitive(), OPC_CONTACT)
381  }
382  else
383  {
384  _CollideNoPrimitiveTest(node->GetPos());
385 
386  if(ContactFound()) return;
387 
388  _CollideNoPrimitiveTest(node->GetNeg());
389  }
390 }
void LSSCollider::_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 484 of file OPC_LSSCollider.cpp.

485 {
486  // Perform LSS-AABB overlap test
487  if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return;
488 
489  TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents)
490 
491  if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) }
492  else _CollideNoPrimitiveTest(node->GetPos());
493 
494  if(ContactFound()) return;
495 
496  if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) }
497  else _CollideNoPrimitiveTest(node->GetNeg());
498 }
void LSSCollider::_CollideNoPrimitiveTest ( const AABBQuantizedNode node)
protected

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

Parameters
node[in] current collision node

Definition at line 430 of file OPC_LSSCollider.cpp.

431 {
432  // Dequantize box
433  const QuantizedAABB& Box = node->mAABB;
434  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
435  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
436 
437  // Perform LSS-AABB overlap test
438  if(!LSSAABBOverlap(Center, Extents)) return;
439 
440  TEST_BOX_IN_LSS(Center, Extents)
441 
442  if(node->IsLeaf())
443  {
444  SET_CONTACT(node->GetPrimitive(), OPC_CONTACT)
445  }
446  else
447  {
448  _CollideNoPrimitiveTest(node->GetPos());
449 
450  if(ContactFound()) return;
451 
452  _CollideNoPrimitiveTest(node->GetNeg());
453  }
454 }
void LSSCollider::_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 533 of file OPC_LSSCollider.cpp.

534 {
535  // Dequantize box
536  const QuantizedAABB& Box = node->mAABB;
537  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
538  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
539 
540  // Perform LSS-AABB overlap test
541  if(!LSSAABBOverlap(Center, Extents)) return;
542 
543  TEST_BOX_IN_LSS(Center, Extents)
544 
545  if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) }
546  else _CollideNoPrimitiveTest(node->GetPos());
547 
548  if(ContactFound()) return;
549 
550  if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) }
551  else _CollideNoPrimitiveTest(node->GetNeg());
552 }
bool LSSCollider::Collide ( LSSCache cache,
const LSS lss,
const Model model,
const Matrix4x4 worldl = null,
const Matrix4x4 worldm = null 
)

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

Parameters
cache[in/out] an lss cache
lss[in] collision lss in local space
model[in] Opcode model to collide with
worldl[in] lss 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 91 of file OPC_LSSCollider.cpp.

92 {
93  // Checkings
94  if(!Setup(&model)) return false;
95 
96  // Init collision query
97  if(InitQuery(cache, lss, worldl, worldm)) return true;
98 
99  if(!model.HasLeafNodes())
100  {
101  if(model.IsQuantized())
102  {
103  const AABBQuantizedNoLeafTree* Tree = (const AABBQuantizedNoLeafTree*)model.GetTree();
104 
105  // Setup dequantization coeffs
106  mCenterCoeff = Tree->mCenterCoeff;
108 
109  // Perform collision query
110  if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
111  else _Collide(Tree->GetNodes());
112  }
113  else
114  {
115  const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree();
116 
117  // Perform collision query
118  if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
119  else _Collide(Tree->GetNodes());
120  }
121  }
122  else
123  {
124  if(model.IsQuantized())
125  {
126  const AABBQuantizedTree* Tree = (const AABBQuantizedTree*)model.GetTree();
127 
128  // Setup dequantization coeffs
129  mCenterCoeff = Tree->mCenterCoeff;
131 
132  // Perform collision query
133  if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
134  else _Collide(Tree->GetNodes());
135  }
136  else
137  {
138  const AABBCollisionTree* Tree = (const AABBCollisionTree*)model.GetTree();
139 
140  // Perform collision query
141  if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
142  else _Collide(Tree->GetNodes());
143  }
144  }
145 
146  return true;
147 }
bool LSSCollider::Collide ( LSSCache cache,
const LSS lss,
const AABBTree tree 
)

Collision query for vanilla AABB trees.

Parameters
cache[in/out] an lss cache
lss[in] collision lss in world space
tree[in] AABB tree
Returns
true if success

Definition at line 296 of file OPC_LSSCollider.cpp.

297 {
298  // This is typically called for a scene tree, full of -AABBs-, not full of triangles.
299  // So we don't really have "primitives" to deal with. Hence it doesn't work with
300  // "FirstContact" + "TemporalCoherence".
302 
303  // Checkings
304  if(!tree) return false;
305 
306  // Init collision query
307  if(InitQuery(cache, lss)) return true;
308 
309  // Perform collision query
310  _Collide(tree);
311 
312  return true;
313 }
bool LSSCollider::InitQuery ( LSSCache cache,
const LSS lss,
const Matrix4x4 worldl = null,
const Matrix4x4 worldm = null 
)
protected

Initializes a collision query :

  • reset stats & contact status
  • setup matrices
  • check temporal coherence
Parameters
cache[in/out] an lss cache
lss[in] lss in local space
worldl[in] lss 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 164 of file OPC_LSSCollider.cpp.

165 {
166  // 1) Call the base method
168 
169  // 2) Compute LSS in model space:
170  // - Precompute R^2
171  mRadius2 = lss.mRadius * lss.mRadius;
172  // - Compute segment
173  mSeg.mP0 = lss.mP0;
174  mSeg.mP1 = lss.mP1;
175  // -> to world space
176  if(worldl)
177  {
178  mSeg.mP0 *= *worldl;
179  mSeg.mP1 *= *worldl;
180  }
181  // -> to model space
182  if(worldm)
183  {
184  // Invert model matrix
185  Matrix4x4 InvWorldM;
186  InvertPRMatrix(InvWorldM, *worldm);
187 
188  mSeg.mP0 *= InvWorldM;
189  mSeg.mP1 *= InvWorldM;
190  }
191 
192  // 3) Setup destination pointer
194 
195  // 4) Special case: 1-triangle meshes [Opcode 1.3]
197  {
198  if(!SkipPrimitiveTests())
199  {
200  // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0.
202 
203  // Perform overlap test between the unique triangle and the LSS (and set contact status if needed)
205 
206  // Return immediately regardless of status
207  return TRUE;
208  }
209  }
210 
211  // 5) Check temporal coherence :
213  {
214  // Here we use temporal coherence
215  // => check results from previous frame before performing the collision query
216  if(FirstContactEnabled())
217  {
218  // We're only interested in the first contact found => test the unique previously touched face
220  {
221  // Get index of previously touched face = the first entry in the array
222  udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0);
223 
224  // Then reset the array:
225  // - if the overlap test below is successful, the index we'll get added back anyway
226  // - if it isn't, then the array should be reset anyway for the normal query
228 
229  // Perform overlap test between the cached triangle and the LSS (and set contact status if needed)
230  LSS_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT)
231 
232  // Return immediately if possible
233  if(GetContactStatus()) return TRUE;
234  }
235  // else no face has been touched during previous query
236  // => we'll have to perform a normal query
237  }
238  else
239  {
240  // We're interested in all contacts =>test the new real LSS N(ew) against the previous fat LSS P(revious):
241 
242  // ### rewrite this
243 
244  LSS Test(mSeg, lss.mRadius); // in model space
245  LSS Previous(cache.Previous, sqrtf(cache.Previous.mRadius));
246 
247 // if(cache.Previous.Contains(Test))
248  if(IsCacheValid(cache) && Previous.Contains(Test))
249  {
250  // - if N is included in P, return previous list
251  // => we simply leave the list (mTouchedFaces) unchanged
252 
253  // Set contact status if needed
255 
256  // In any case we don't need to do a query
257  return TRUE;
258  }
259  else
260  {
261  // - else do the query using a fat N
262 
263  // Reset cache since we'll about to perform a real query
265 
266  // Make a fat sphere so that coherence will work for subsequent frames
267  mRadius2 *= cache.FatCoeff;
268 // mRadius2 = (lss.mRadius * cache.FatCoeff)*(lss.mRadius * cache.FatCoeff);
269 
270 
271  // Update cache with query data (signature for cached faces)
272  cache.Previous.mP0 = mSeg.mP0;
273  cache.Previous.mP1 = mSeg.mP1;
274  cache.Previous.mRadius = mRadius2;
275  }
276  }
277  }
278  else
279  {
280  // Here we don't use temporal coherence => do a normal query
282  }
283 
284  return FALSE;
285 }
inline_ bool Opcode::LSSCollider::LSSAABBOverlap ( const Point center,
const Point extents 
)
protected
inline_ bool LSSCollider::LSSContainsBox ( const Point bc,
const Point be 
)
protected

Checks the LSS 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 LSS contains the whole box

Definition at line 323 of file OPC_LSSCollider.cpp.

324 {
325  // Not implemented
326  return FALSE;
327 }
inline_ bool Opcode::LSSCollider::LSSTriOverlap ( const Point vert0,
const Point vert1,
const Point vert2 
)
protected

Member Data Documentation

float Opcode::LSSCollider::mRadius2
protected

LSS radius squared.

Definition at line 69 of file Opcode.h.

Segment Opcode::LSSCollider::mSeg
protected

Segment.

Definition at line 68 of file Opcode.h.


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