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

#include <Opcode.h>

Inheritance diagram for Opcode::PlanesCollider:
Opcode::VolumeCollider Opcode::Collider Opcode::HybridPlanesCollider

Public Member Functions

 PlanesCollider ()
 
virtual ~PlanesCollider ()
 
bool Collide (PlanesCache &cache, const Plane *planes, udword nb_planes, const Model &model, const Matrix4x4 *worldm=null)
 
inline_ bool Collide (PlanesCache &cache, const OBB &box, const Model &model, const Matrix4x4 *worldb=null, const Matrix4x4 *worldm=null)
 
 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, udword clip_mask)
 
void _Collide (const AABBNoLeafNode *node, udword clip_mask)
 
void _Collide (const AABBQuantizedNode *node, udword clip_mask)
 
void _Collide (const AABBQuantizedNoLeafNode *node, udword clip_mask)
 
void _CollideNoPrimitiveTest (const AABBCollisionNode *node, udword clip_mask)
 
void _CollideNoPrimitiveTest (const AABBNoLeafNode *node, udword clip_mask)
 
void _CollideNoPrimitiveTest (const AABBQuantizedNode *node, udword clip_mask)
 
void _CollideNoPrimitiveTest (const AABBQuantizedNoLeafNode *node, udword clip_mask)
 
inline_ bool PlanesAABBOverlap (const Point &center, const Point &extents, udword &out_clip_mask, udword in_clip_mask)
 
inline_ bool PlanesTriOverlap (udword in_clip_mask)
 
bool InitQuery (PlanesCache &cache, const Plane *planes, udword nb_planes, 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

udword mNbPlanes
 
PlanemPlanes
 
VertexPointers mVP
 
- 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 31 of file Opcode.h.

Constructor & Destructor Documentation

PlanesCollider::PlanesCollider ( )

Constructor.

Definition at line 59 of file OPC_PlanesCollider.cpp.

59  :
60  mNbPlanes (0),
61  mPlanes (null)
62 {
63 }
PlanesCollider::~PlanesCollider ( )
virtual

Destructor.

Definition at line 70 of file OPC_PlanesCollider.cpp.

71 {
73 }

Member Function Documentation

void PlanesCollider::_Collide ( const AABBCollisionNode node,
udword  clip_mask 
)
protected

Recursive collision query for normal AABB trees.

Parameters
node[in] current collision node

Definition at line 277 of file OPC_PlanesCollider.cpp.

278 {
279  // Test the box against the planes. If the box is completely culled, so are its children, hence we exit.
280  udword OutClipMask;
281  if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return;
282 
284 
285  // Else the box straddles one or several planes, so we need to recurse down the tree.
286  if(node->IsLeaf())
287  {
288  PLANES_PRIM(node->GetPrimitive(), OPC_CONTACT)
289  }
290  else
291  {
292  _Collide(node->GetPos(), OutClipMask);
293 
294  if(ContactFound()) return;
295 
296  _Collide(node->GetNeg(), OutClipMask);
297  }
298 }
void PlanesCollider::_Collide ( const AABBNoLeafNode node,
udword  clip_mask 
)
protected

Recursive collision query for no-leaf AABB trees.

Parameters
node[in] current collision node

Definition at line 403 of file OPC_PlanesCollider.cpp.

404 {
405  // Test the box against the planes. If the box is completely culled, so are its children, hence we exit.
406  udword OutClipMask;
407  if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return;
408 
410 
411  // Else the box straddles one or several planes, so we need to recurse down the tree.
412  if(node->HasPosLeaf()) { PLANES_PRIM(node->GetPosPrimitive(), OPC_CONTACT) }
413  else _Collide(node->GetPos(), OutClipMask);
414 
415  if(ContactFound()) return;
416 
417  if(node->HasNegLeaf()) { PLANES_PRIM(node->GetNegPrimitive(), OPC_CONTACT) }
418  else _Collide(node->GetNeg(), OutClipMask);
419 }
void PlanesCollider::_Collide ( const AABBQuantizedNode node,
udword  clip_mask 
)
protected

Recursive collision query for quantized AABB trees.

Parameters
node[in] current collision node

Definition at line 335 of file OPC_PlanesCollider.cpp.

336 {
337  // Dequantize box
338  const QuantizedAABB& Box = node->mAABB;
339  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
340  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
341 
342  // Test the box against the planes. If the box is completely culled, so are its children, hence we exit.
343  udword OutClipMask;
344  if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return;
345 
347 
348  // Else the box straddles one or several planes, so we need to recurse down the tree.
349  if(node->IsLeaf())
350  {
351  PLANES_PRIM(node->GetPrimitive(), OPC_CONTACT)
352  }
353  else
354  {
355  _Collide(node->GetPos(), OutClipMask);
356 
357  if(ContactFound()) return;
358 
359  _Collide(node->GetNeg(), OutClipMask);
360  }
361 }
void PlanesCollider::_Collide ( const AABBQuantizedNoLeafNode node,
udword  clip_mask 
)
protected

Recursive collision query for quantized no-leaf AABB trees.

Parameters
node[in] current collision node

Definition at line 451 of file OPC_PlanesCollider.cpp.

452 {
453  // Dequantize box
454  const QuantizedAABB& Box = node->mAABB;
455  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
456  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
457 
458  // Test the box against the planes. If the box is completely culled, so are its children, hence we exit.
459  udword OutClipMask;
460  if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return;
461 
463 
464  // Else the box straddles one or several planes, so we need to recurse down the tree.
465  if(node->HasPosLeaf()) { PLANES_PRIM(node->GetPosPrimitive(), OPC_CONTACT) }
466  else _Collide(node->GetPos(), OutClipMask);
467 
468  if(ContactFound()) return;
469 
470  if(node->HasNegLeaf()) { PLANES_PRIM(node->GetNegPrimitive(), OPC_CONTACT) }
471  else _Collide(node->GetNeg(), OutClipMask);
472 }
void PlanesCollider::_CollideNoPrimitiveTest ( const AABBCollisionNode node,
udword  clip_mask 
)
protected

Recursive collision query for normal AABB trees.

Parameters
node[in] current collision node

Definition at line 306 of file OPC_PlanesCollider.cpp.

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

307 {
308  // Test the box against the planes. If the box is completely culled, so are its children, hence we exit.
309  udword OutClipMask;
310  if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return;
311 
313 
314  // Else the box straddles one or several planes, so we need to recurse down the tree.
315  if(node->IsLeaf())
316  {
317  SET_CONTACT(node->GetPrimitive(), OPC_CONTACT)
318  }
319  else
320  {
321  _CollideNoPrimitiveTest(node->GetPos(), OutClipMask);
322 
323  if(ContactFound()) return;
324 
325  _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask);
326  }
327 }
void PlanesCollider::_CollideNoPrimitiveTest ( const AABBNoLeafNode node,
udword  clip_mask 
)
protected

Recursive collision query for no-leaf AABB trees.

Parameters
node[in] current collision node

Definition at line 427 of file OPC_PlanesCollider.cpp.

428 {
429  // Test the box against the planes. If the box is completely culled, so are its children, hence we exit.
430  udword OutClipMask;
431  if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return;
432 
434 
435  // Else the box straddles one or several planes, so we need to recurse down the tree.
436  if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) }
437  else _CollideNoPrimitiveTest(node->GetPos(), OutClipMask);
438 
439  if(ContactFound()) return;
440 
441  if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) }
442  else _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask);
443 }
void PlanesCollider::_CollideNoPrimitiveTest ( const AABBQuantizedNode node,
udword  clip_mask 
)
protected

Recursive collision query for quantized AABB trees.

Parameters
node[in] current collision node

Definition at line 369 of file OPC_PlanesCollider.cpp.

370 {
371  // Dequantize box
372  const QuantizedAABB& Box = node->mAABB;
373  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
374  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
375 
376  // Test the box against the planes. If the box is completely culled, so are its children, hence we exit.
377  udword OutClipMask;
378  if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return;
379 
381 
382  // Else the box straddles one or several planes, so we need to recurse down the tree.
383  if(node->IsLeaf())
384  {
385  SET_CONTACT(node->GetPrimitive(), OPC_CONTACT)
386  }
387  else
388  {
389  _CollideNoPrimitiveTest(node->GetPos(), OutClipMask);
390 
391  if(ContactFound()) return;
392 
393  _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask);
394  }
395 }
void PlanesCollider::_CollideNoPrimitiveTest ( const AABBQuantizedNoLeafNode node,
udword  clip_mask 
)
protected

Recursive collision query for quantized no-leaf AABB trees.

Parameters
node[in] current collision node

Definition at line 480 of file OPC_PlanesCollider.cpp.

481 {
482  // Dequantize box
483  const QuantizedAABB& Box = node->mAABB;
484  const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z);
485  const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z);
486 
487  // Test the box against the planes. If the box is completely culled, so are its children, hence we exit.
488  udword OutClipMask;
489  if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return;
490 
492 
493  // Else the box straddles one or several planes, so we need to recurse down the tree.
494  if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) }
495  else _CollideNoPrimitiveTest(node->GetPos(), OutClipMask);
496 
497  if(ContactFound()) return;
498 
499  if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) }
500  else _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask);
501 }
bool PlanesCollider::Collide ( PlanesCache cache,
const Plane planes,
udword  nb_planes,
const Model model,
const Matrix4x4 worldm = null 
)

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

Parameters
cache[in/out] a planes cache
planes[in] list of planes in world space
nb_planes[in] number of planes
model[in] Opcode model to collide with
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 104 of file OPC_PlanesCollider.cpp.

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

Definition at line 57 of file Opcode.h.

bool PlanesCollider::InitQuery ( PlanesCache cache,
const Plane planes,
udword  nb_planes,
const Matrix4x4 worldm = null 
)
protected

Initializes a collision query :

  • reset stats & contact status
  • compute planes in model space
  • check temporal coherence
Parameters
cache[in/out] a planes cache
planes[in] list of planes
nb_planes[in] number of planes
worldm[in] model's world matrix, or null
Returns
TRUE if we can return immediately
Warning
SCALE NOT SUPPORTED. The matrix must contain rotation & translation parts only.

Definition at line 178 of file OPC_PlanesCollider.cpp.

179 {
180  // 1) Call the base method
182 
183  // 2) Compute planes in model space
184  if(nb_planes>mNbPlanes)
185  {
187  mPlanes = new Plane[nb_planes];
188  }
189  mNbPlanes = nb_planes;
190 
191  if(worldm)
192  {
193  Matrix4x4 InvWorldM;
194  InvertPRMatrix(InvWorldM, *worldm);
195 
196 // for(udword i=0;i<nb_planes;i++) mPlanes[i] = planes[i] * InvWorldM;
197  for(udword i=0;i<nb_planes;i++) TransformPlane(mPlanes[i], planes[i], InvWorldM);
198  }
199  else CopyMemory(mPlanes, planes, nb_planes*sizeof(Plane));
200 
201  // 3) Setup destination pointer
203 
204  // 4) Special case: 1-triangle meshes [Opcode 1.3]
206  {
207  if(!SkipPrimitiveTests())
208  {
209  // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0.
211 
212  // Perform overlap test between the unique triangle and the planes (and set contact status if needed)
213  udword clip_mask = (1<<mNbPlanes)-1;
215 
216  // Return immediately regardless of status
217  return TRUE;
218  }
219  }
220 
221  // 4) Check temporal coherence:
223  {
224  // Here we use temporal coherence
225  // => check results from previous frame before performing the collision query
226  if(FirstContactEnabled())
227  {
228  // We're only interested in the first contact found => test the unique previously touched face
230  {
231  // Get index of previously touched face = the first entry in the array
232  udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0);
233 
234  // Then reset the array:
235  // - if the overlap test below is successful, the index we'll get added back anyway
236  // - if it isn't, then the array should be reset anyway for the normal query
238 
239  // Perform overlap test between the cached triangle and the planes (and set contact status if needed)
240  udword clip_mask = (1<<mNbPlanes)-1;
241  PLANES_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT)
242 
243  // Return immediately if possible
244  if(GetContactStatus()) return TRUE;
245  }
246  // else no face has been touched during previous query
247  // => we'll have to perform a normal query
248  }
249  else mTouchedPrimitives->Reset();
250  }
251  else
252  {
253  // Here we don't use temporal coherence => do a normal query
255  }
256 
257  return FALSE;
258 }
Opcode::PlanesCollider::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_ bool Opcode::PlanesCollider::PlanesAABBOverlap ( const Point center,
const Point extents,
udword out_clip_mask,
udword  in_clip_mask 
)
protected
inline_ bool Opcode::PlanesCollider::PlanesTriOverlap ( udword  in_clip_mask)
protected

Member Data Documentation

udword Opcode::PlanesCollider::mNbPlanes
protected

Definition at line 90 of file Opcode.h.

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

Plane* Opcode::PlanesCollider::mPlanes
protected

Definition at line 91 of file Opcode.h.

VertexPointers Opcode::PlanesCollider::mVP
protected

Definition at line 93 of file Opcode.h.


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