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

#include <Opcode.h>

Inheritance diagram for Opcode::AABBTreeCollider:
Opcode::Collider

Public Member Functions

 AABBTreeCollider ()
 
virtual ~AABBTreeCollider ()
 
bool Collide (BVTCache &cache, const Matrix4x4 *world0=null, const Matrix4x4 *world1=null)
 
bool Collide (const AABBCollisionTree *tree0, const AABBCollisionTree *tree1, const Matrix4x4 *world0=null, const Matrix4x4 *world1=null, Pair *cache=null)
 
bool Collide (const AABBNoLeafTree *tree0, const AABBNoLeafTree *tree1, const Matrix4x4 *world0=null, const Matrix4x4 *world1=null, Pair *cache=null)
 
bool Collide (const AABBQuantizedTree *tree0, const AABBQuantizedTree *tree1, const Matrix4x4 *world0=null, const Matrix4x4 *world1=null, Pair *cache=null)
 
bool Collide (const AABBQuantizedNoLeafTree *tree0, const AABBQuantizedNoLeafTree *tree1, const Matrix4x4 *world0=null, const Matrix4x4 *world1=null, Pair *cache=null)
 
inline_ void SetFullBoxBoxTest (bool flag)
 
void SetFullPrimBoxTest (bool flag)
 
inline_ udword GetNbBVBVTests () const
 
inline_ udword GetNbPrimPrimTests () const
 
inline_ udword GetNbBVPrimTests () const
 
inline_ udword GetNbPairs () const
 
inline_ const PairGetPairs () 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 *b0, const AABBCollisionNode *b1)
 
void _Collide (const AABBQuantizedNode *b0, const AABBQuantizedNode *b1, const Point &a, const Point &Pa, const Point &b, const Point &Pb)
 
void _CollideTriBox (const AABBNoLeafNode *b)
 
void _CollideBoxTri (const AABBNoLeafNode *b)
 
void _Collide (const AABBNoLeafNode *a, const AABBNoLeafNode *b)
 
void _CollideTriBox (const AABBQuantizedNoLeafNode *b)
 
void _CollideBoxTri (const AABBQuantizedNoLeafNode *b)
 
void _Collide (const AABBQuantizedNoLeafNode *a, const AABBQuantizedNoLeafNode *b)
 
void PrimTest (udword id0, udword id1)
 
inline_ void PrimTestTriIndex (udword id1)
 
inline_ void PrimTestIndexTri (udword id0)
 
inline_ bool BoxBoxOverlap (const Point &ea, const Point &ca, const Point &eb, const Point &cb)
 
inline_ bool TriBoxOverlap (const Point &center, const Point &extents)
 
inline_ bool TriTriOverlap (const Point &V0, const Point &V1, const Point &V2, const Point &U0, const Point &U1, const Point &U2)
 
void InitQuery (const Matrix4x4 *world0=null, const Matrix4x4 *world1=null)
 
bool CheckTemporalCoherence (Pair *cache)
 
inline_ bool Setup (const MeshInterface *mi0, const MeshInterface *mi1)
 
- Protected Member Functions inherited from Opcode::Collider
inline_ BOOL Setup (const BaseModel *model)
 
virtual inline_ void InitQuery ()
 

Protected Attributes

Container mPairs
 Pairs of colliding primitives. More...
 
const MeshInterfacemIMesh0
 User-defined mesh interface for object0. More...
 
const MeshInterfacemIMesh1
 User-defined mesh interface for object1. More...
 
udword mNbBVBVTests
 Number of BV-BV tests. More...
 
udword mNbPrimPrimTests
 Number of Primitive-Primitive tests. More...
 
udword mNbBVPrimTests
 Number of BV-Primitive tests. More...
 
Matrix3x3 mAR
 Absolute rotation matrix. More...
 
Matrix3x3 mR0to1
 Rotation from object0 to object1. More...
 
Matrix3x3 mR1to0
 Rotation from object1 to object0. More...
 
Point mT0to1
 Translation from object0 to object1. More...
 
Point mT1to0
 Translation from object1 to object0. More...
 
Point mCenterCoeff0
 
Point mExtentsCoeff0
 
Point mCenterCoeff1
 
Point mExtentsCoeff1
 
Point mLeafVerts [3]
 Triangle vertices. More...
 
udword mLeafIndex
 Triangle index. More...
 
bool mFullBoxBoxTest
 Perform full BV-BV tests (true) or SAT-lite tests (false) More...
 
bool mFullPrimBoxTest
 Perform full Primitive-BV tests (true) or SAT-lite tests (false) 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 70 of file Opcode.h.

Constructor & Destructor Documentation

AABBTreeCollider::AABBTreeCollider ( )

Constructor.

Definition at line 46 of file OPC_TreeCollider.cpp.

46  :
47  mIMesh0 (null),
48  mIMesh1 (null),
49  mNbBVBVTests (0),
50  mNbPrimPrimTests (0),
51  mNbBVPrimTests (0),
52  mFullBoxBoxTest (true),
53  mFullPrimBoxTest (true)
54 {
55 }
AABBTreeCollider::~AABBTreeCollider ( )
virtual

Destructor.

Definition at line 62 of file OPC_TreeCollider.cpp.

63 {
64 }

Member Function Documentation

void AABBTreeCollider::_Collide ( const AABBCollisionNode b0,
const AABBCollisionNode b1 
)
protected

Recursive collision query for normal AABB trees.

Parameters
b0[in] collision node from first tree
b1[in] collision node from second tree

Definition at line 478 of file OPC_TreeCollider.cpp.

479 {
480  // Perform BV-BV overlap test
481  if(!BoxBoxOverlap(b0->mAABB.mExtents, b0->mAABB.mCenter, b1->mAABB.mExtents, b1->mAABB.mCenter))
482  {
483  return;
484  }
485 
486  if(b0->IsLeaf())
487  {
488  if(b1->IsLeaf())
489  {
490  PrimTest(b0->GetPrimitive(), b1->GetPrimitive());
491  }
492  else
493  {
494  _Collide(b0, b1->GetNeg());
495  if(ContactFound()) return;
496  _Collide(b0, b1->GetPos());
497  }
498  }
499  else if(b1->IsLeaf())
500  {
501  _Collide(b0->GetNeg(), b1);
502  if(ContactFound()) return;
503  _Collide(b0->GetPos(), b1);
504  }
505  else
506  {
507  _Collide(b0->GetNeg(), b1->GetNeg());
508  if(ContactFound()) return;
509  _Collide(b0->GetNeg(), b1->GetPos());
510  if(ContactFound()) return;
511  _Collide(b0->GetPos(), b1->GetNeg());
512  if(ContactFound()) return;
513  _Collide(b0->GetPos(), b1->GetPos());
514  }
515 }
void AABBTreeCollider::_Collide ( const AABBQuantizedNode b0,
const AABBQuantizedNode b1,
const Point a,
const Point Pa,
const Point b,
const Point Pb 
)
protected

Recursive collision query for quantized AABB trees.

Parameters
b0[in] collision node from first tree
b1[in] collision node from second tree
a[in] extent from box A
Pa[in] center from box A
b[in] extent from box B
Pb[in] center from box B

Definition at line 753 of file OPC_TreeCollider.cpp.

754 {
755  // Perform BV-BV overlap test
756  if(!BoxBoxOverlap(a, Pa, b, Pb)) return;
757 
758  if(b0->IsLeaf() && b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); return; }
759 
760  if(b1->IsLeaf() || (!b0->IsLeaf() && (b0->GetSize() > b1->GetSize())))
761  {
762  // Dequantize box
763  const QuantizedAABB* Box = &b0->GetNeg()->mAABB;
764  const Point negPa(float(Box->mCenter[0]) * mCenterCoeff0.x, float(Box->mCenter[1]) * mCenterCoeff0.y, float(Box->mCenter[2]) * mCenterCoeff0.z);
765  const Point nega(float(Box->mExtents[0]) * mExtentsCoeff0.x, float(Box->mExtents[1]) * mExtentsCoeff0.y, float(Box->mExtents[2]) * mExtentsCoeff0.z);
766  _Collide(b0->GetNeg(), b1, nega, negPa, b, Pb);
767 
768  if(ContactFound()) return;
769 
770  // Dequantize box
771  Box = &b0->GetPos()->mAABB;
772  const Point posPa(float(Box->mCenter[0]) * mCenterCoeff0.x, float(Box->mCenter[1]) * mCenterCoeff0.y, float(Box->mCenter[2]) * mCenterCoeff0.z);
773  const Point posa(float(Box->mExtents[0]) * mExtentsCoeff0.x, float(Box->mExtents[1]) * mExtentsCoeff0.y, float(Box->mExtents[2]) * mExtentsCoeff0.z);
774  _Collide(b0->GetPos(), b1, posa, posPa, b, Pb);
775  }
776  else
777  {
778  // Dequantize box
779  const QuantizedAABB* Box = &b1->GetNeg()->mAABB;
780  const Point negPb(float(Box->mCenter[0]) * mCenterCoeff1.x, float(Box->mCenter[1]) * mCenterCoeff1.y, float(Box->mCenter[2]) * mCenterCoeff1.z);
781  const Point negb(float(Box->mExtents[0]) * mExtentsCoeff1.x, float(Box->mExtents[1]) * mExtentsCoeff1.y, float(Box->mExtents[2]) * mExtentsCoeff1.z);
782  _Collide(b0, b1->GetNeg(), a, Pa, negb, negPb);
783 
784  if(ContactFound()) return;
785 
786  // Dequantize box
787  Box = &b1->GetPos()->mAABB;
788  const Point posPb(float(Box->mCenter[0]) * mCenterCoeff1.x, float(Box->mCenter[1]) * mCenterCoeff1.y, float(Box->mCenter[2]) * mCenterCoeff1.z);
789  const Point posb(float(Box->mExtents[0]) * mExtentsCoeff1.x, float(Box->mExtents[1]) * mExtentsCoeff1.y, float(Box->mExtents[2]) * mExtentsCoeff1.z);
790  _Collide(b0, b1->GetPos(), a, Pa, posb, posPb);
791  }
792 }
void AABBTreeCollider::_Collide ( const AABBNoLeafNode a,
const AABBNoLeafNode b 
)
protected

Recursive collision query for no-leaf AABB trees.

Parameters
a[in] collision node from first tree
b[in] collision node from second tree

Definition at line 658 of file OPC_TreeCollider.cpp.

659 {
660  // Perform BV-BV overlap test
661  if(!BoxBoxOverlap(a->mAABB.mExtents, a->mAABB.mCenter, b->mAABB.mExtents, b->mAABB.mCenter)) return;
662 
663  // Catch leaf status
664  BOOL BHasPosLeaf = b->HasPosLeaf();
665  BOOL BHasNegLeaf = b->HasNegLeaf();
666 
667  if(a->HasPosLeaf())
668  {
669  FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1)
670 
671  if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive());
672  else _CollideTriBox(b->GetPos());
673 
674  if(ContactFound()) return;
675 
676  if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive());
677  else _CollideTriBox(b->GetNeg());
678  }
679  else
680  {
681  if(BHasPosLeaf)
682  {
683  FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0)
684 
685  _CollideBoxTri(a->GetPos());
686  }
687  else _Collide(a->GetPos(), b->GetPos());
688 
689  if(ContactFound()) return;
690 
691  if(BHasNegLeaf)
692  {
693  FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0)
694 
695  _CollideBoxTri(a->GetPos());
696  }
697  else _Collide(a->GetPos(), b->GetNeg());
698  }
699 
700  if(ContactFound()) return;
701 
702  if(a->HasNegLeaf())
703  {
704  FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1)
705 
706  if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive());
707  else _CollideTriBox(b->GetPos());
708 
709  if(ContactFound()) return;
710 
711  if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive());
712  else _CollideTriBox(b->GetNeg());
713  }
714  else
715  {
716  if(BHasPosLeaf)
717  {
718  // ### That leaf has possibly already been fetched
719  FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0)
720 
721  _CollideBoxTri(a->GetNeg());
722  }
723  else _Collide(a->GetNeg(), b->GetPos());
724 
725  if(ContactFound()) return;
726 
727  if(BHasNegLeaf)
728  {
729  // ### That leaf has possibly already been fetched
730  FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0)
731 
732  _CollideBoxTri(a->GetNeg());
733  }
734  else _Collide(a->GetNeg(), b->GetNeg());
735  }
736 }
void AABBTreeCollider::_Collide ( const AABBQuantizedNoLeafNode a,
const AABBQuantizedNoLeafNode b 
)
protected

Recursive collision query for quantized no-leaf AABB trees.

Parameters
a[in] collision node from first tree
b[in] collision node from second tree

Definition at line 857 of file OPC_TreeCollider.cpp.

858 {
859  // Dequantize box A
860  const QuantizedAABB* ab = &a->mAABB;
861  const Point Pa(float(ab->mCenter[0]) * mCenterCoeff0.x, float(ab->mCenter[1]) * mCenterCoeff0.y, float(ab->mCenter[2]) * mCenterCoeff0.z);
862  const Point ea(float(ab->mExtents[0]) * mExtentsCoeff0.x, float(ab->mExtents[1]) * mExtentsCoeff0.y, float(ab->mExtents[2]) * mExtentsCoeff0.z);
863  // Dequantize box B
864  const QuantizedAABB* bb = &b->mAABB;
865  const Point Pb(float(bb->mCenter[0]) * mCenterCoeff1.x, float(bb->mCenter[1]) * mCenterCoeff1.y, float(bb->mCenter[2]) * mCenterCoeff1.z);
866  const Point eb(float(bb->mExtents[0]) * mExtentsCoeff1.x, float(bb->mExtents[1]) * mExtentsCoeff1.y, float(bb->mExtents[2]) * mExtentsCoeff1.z);
867 
868  // Perform BV-BV overlap test
869  if(!BoxBoxOverlap(ea, Pa, eb, Pb)) return;
870 
871  // Catch leaf status
872  BOOL BHasPosLeaf = b->HasPosLeaf();
873  BOOL BHasNegLeaf = b->HasNegLeaf();
874 
875  if(a->HasPosLeaf())
876  {
877  FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1)
878 
879  if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive());
880  else _CollideTriBox(b->GetPos());
881 
882  if(ContactFound()) return;
883 
884  if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive());
885  else _CollideTriBox(b->GetNeg());
886  }
887  else
888  {
889  if(BHasPosLeaf)
890  {
891  FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0)
892 
893  _CollideBoxTri(a->GetPos());
894  }
895  else _Collide(a->GetPos(), b->GetPos());
896 
897  if(ContactFound()) return;
898 
899  if(BHasNegLeaf)
900  {
901  FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0)
902 
903  _CollideBoxTri(a->GetPos());
904  }
905  else _Collide(a->GetPos(), b->GetNeg());
906  }
907 
908  if(ContactFound()) return;
909 
910  if(a->HasNegLeaf())
911  {
912  FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1)
913 
914  if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive());
915  else _CollideTriBox(b->GetPos());
916 
917  if(ContactFound()) return;
918 
919  if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive());
920  else _CollideTriBox(b->GetNeg());
921  }
922  else
923  {
924  if(BHasPosLeaf)
925  {
926  // ### That leaf has possibly already been fetched
927  FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0)
928 
929  _CollideBoxTri(a->GetNeg());
930  }
931  else _Collide(a->GetNeg(), b->GetPos());
932 
933  if(ContactFound()) return;
934 
935  if(BHasNegLeaf)
936  {
937  // ### That leaf has possibly already been fetched
938  FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0)
939 
940  _CollideBoxTri(a->GetNeg());
941  }
942  else _Collide(a->GetNeg(), b->GetNeg());
943  }
944 }
void AABBTreeCollider::_CollideBoxTri ( const AABBNoLeafNode b)
protected

Recursive collision of a leaf node from B and a branch from A.

Parameters
b[in] collision node from first tree

Definition at line 625 of file OPC_TreeCollider.cpp.

626 {
627  // Perform triangle-box overlap test
628  if(!TriBoxOverlap(b->mAABB.mCenter, b->mAABB.mExtents)) return;
629 
630  // Keep same triangle, deal with first child
631  if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive());
632  else _CollideBoxTri(b->GetPos());
633 
634  if(ContactFound()) return;
635 
636  // Keep same triangle, deal with second child
637  if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive());
638  else _CollideBoxTri(b->GetNeg());
639 }
void AABBTreeCollider::_CollideBoxTri ( const AABBQuantizedNoLeafNode b)
protected

Recursive collision of a leaf node from B and a quantized branch from A.

Parameters
b[in] collision node from first tree
leaf[in] leaf triangle from second tree

Definition at line 831 of file OPC_TreeCollider.cpp.

832 {
833  // Dequantize box
834  const QuantizedAABB* bb = &b->mAABB;
835  const Point Pa(float(bb->mCenter[0]) * mCenterCoeff0.x, float(bb->mCenter[1]) * mCenterCoeff0.y, float(bb->mCenter[2]) * mCenterCoeff0.z);
836  const Point ea(float(bb->mExtents[0]) * mExtentsCoeff0.x, float(bb->mExtents[1]) * mExtentsCoeff0.y, float(bb->mExtents[2]) * mExtentsCoeff0.z);
837 
838  // Perform triangle-box overlap test
839  if(!TriBoxOverlap(Pa, ea)) return;
840 
841  if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive());
842  else _CollideBoxTri(b->GetPos());
843 
844  if(ContactFound()) return;
845 
846  if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive());
847  else _CollideBoxTri(b->GetNeg());
848 }
void AABBTreeCollider::_CollideTriBox ( const AABBNoLeafNode b)
protected

Recursive collision of a leaf node from A and a branch from B.

Parameters
b[in] collision node from second tree

Definition at line 603 of file OPC_TreeCollider.cpp.

604 {
605  // Perform triangle-box overlap test
606  if(!TriBoxOverlap(b->mAABB.mCenter, b->mAABB.mExtents)) return;
607 
608  // Keep same triangle, deal with first child
609  if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive());
610  else _CollideTriBox(b->GetPos());
611 
612  if(ContactFound()) return;
613 
614  // Keep same triangle, deal with second child
615  if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive());
616  else _CollideTriBox(b->GetNeg());
617 }
void AABBTreeCollider::_CollideTriBox ( const AABBQuantizedNoLeafNode b)
protected

Recursive collision of a leaf node from A and a quantized branch from B.

Parameters
leaf[in] leaf triangle from first tree
b[in] collision node from second tree

Definition at line 805 of file OPC_TreeCollider.cpp.

806 {
807  // Dequantize box
808  const QuantizedAABB* bb = &b->mAABB;
809  const Point Pb(float(bb->mCenter[0]) * mCenterCoeff1.x, float(bb->mCenter[1]) * mCenterCoeff1.y, float(bb->mCenter[2]) * mCenterCoeff1.z);
810  const Point eb(float(bb->mExtents[0]) * mExtentsCoeff1.x, float(bb->mExtents[1]) * mExtentsCoeff1.y, float(bb->mExtents[2]) * mExtentsCoeff1.z);
811 
812  // Perform triangle-box overlap test
813  if(!TriBoxOverlap(Pb, eb)) return;
814 
815  if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive());
816  else _CollideTriBox(b->GetPos());
817 
818  if(ContactFound()) return;
819 
820  if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive());
821  else _CollideTriBox(b->GetNeg());
822 }
inline_ bool Opcode::AABBTreeCollider::BoxBoxOverlap ( const Point ea,
const Point ca,
const Point eb,
const Point cb 
)
protected
bool AABBTreeCollider::CheckTemporalCoherence ( Pair cache)
protected

Takes advantage of temporal coherence.

Parameters
cache[in] cache for a pair of previously colliding primitives
Returns
true if we can return immediately
Warning
only works for "First Contact" mode

Definition at line 278 of file OPC_TreeCollider.cpp.

279 {
280  // Checkings
281  if(!cache) return false;
282 
283  // Test previously colliding primitives first
285  {
286  PrimTest(cache->id0, cache->id1);
287  if(GetContactStatus()) return true;
288  }
289  return false;
290 }
bool AABBTreeCollider::Collide ( BVTCache cache,
const Matrix4x4 world0 = null,
const Matrix4x4 world1 = null 
)

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

Parameters
cache[in] collision cache for model pointers and a colliding pair of primitives
world0[in] world matrix for first object, or null
world1[in] world matrix for second object, or null
Returns
true if success
Warning
SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.

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

Parameters
cache[in] collision cache for model pointers and a colliding pair of primitives
world0[in] world matrix for first object
world1[in] world matrix for second object
Returns
true if success
Warning
SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.

Definition at line 92 of file OPC_TreeCollider.cpp.

93 {
94  // Checkings
95  if(!cache.Model0 || !cache.Model1) return false;
96  if(cache.Model0->HasLeafNodes()!=cache.Model1->HasLeafNodes()) return false;
97  if(cache.Model0->IsQuantized()!=cache.Model1->IsQuantized()) return false;
98 
99  /*
100 
101  Rules:
102  - perform hull test
103  - when hulls collide, disable hull test
104  - if meshes overlap, reset countdown
105  - if countdown reaches 0, enable hull test
106 
107  */
108 
109 #ifdef __MESHMERIZER_H__
110  // Handle hulls
111  if(cache.HullTest)
112  {
113  if(cache.Model0->GetHull() && cache.Model1->GetHull())
114  {
115  struct Local
116  {
117  static Point* SVCallback(const Point& sv, udword& previndex, udword user_data)
118  {
119  CollisionHull* Hull = (CollisionHull*)user_data;
120  previndex = Hull->ComputeSupportingVertex(sv, previndex);
121  return (Point*)&Hull->GetVerts()[previndex];
122  }
123  };
124 
125  bool Collide;
126 
127  if(0)
128  {
129  static GJKEngine GJK;
130  static bool GJKInitDone=false;
131  if(!GJKInitDone)
132  {
133  GJK.Enable(GJK_BACKUP_PROCEDURE);
134  GJK.Enable(GJK_DEGENERATE);
135  GJK.Enable(GJK_HILLCLIMBING);
136  GJKInitDone = true;
137  }
138  GJK.SetCallbackObj0(Local::SVCallback);
139  GJK.SetCallbackObj1(Local::SVCallback);
140  GJK.SetUserData0(udword(cache.Model0->GetHull()));
141  GJK.SetUserData1(udword(cache.Model1->GetHull()));
142  Collide = GJK.Collide(*world0, *world1, &cache.SepVector);
143  }
144  else
145  {
146  static SVEngine SVE;
147  SVE.SetCallbackObj0(Local::SVCallback);
148  SVE.SetCallbackObj1(Local::SVCallback);
149  SVE.SetUserData0(udword(cache.Model0->GetHull()));
150  SVE.SetUserData1(udword(cache.Model1->GetHull()));
151  Collide = SVE.Collide(*world0, *world1, &cache.SepVector);
152  }
153 
154  if(!Collide)
155  {
156  // Reset stats & contact status
157  mFlags &= ~OPC_CONTACT;
158  mNbBVBVTests = 0;
159  mNbPrimPrimTests = 0;
160  mNbBVPrimTests = 0;
161  mPairs.Reset();
162  return true;
163  }
164  }
165  }
166 
167  // Here, hulls collide
168  cache.HullTest = false;
169 #endif // __MESHMERIZER_H__
170 
171  // Checkings
172  if(!Setup(cache.Model0->GetMeshInterface(), cache.Model1->GetMeshInterface())) return false;
173 
174  // Simple double-dispatch
175  bool Status;
176  if(!cache.Model0->HasLeafNodes())
177  {
178  if(cache.Model0->IsQuantized())
179  {
182  Status = Collide(T0, T1, world0, world1, &cache);
183  }
184  else
185  {
186  const AABBNoLeafTree* T0 = (const AABBNoLeafTree*)cache.Model0->GetTree();
187  const AABBNoLeafTree* T1 = (const AABBNoLeafTree*)cache.Model1->GetTree();
188  Status = Collide(T0, T1, world0, world1, &cache);
189  }
190  }
191  else
192  {
193  if(cache.Model0->IsQuantized())
194  {
195  const AABBQuantizedTree* T0 = (const AABBQuantizedTree*)cache.Model0->GetTree();
196  const AABBQuantizedTree* T1 = (const AABBQuantizedTree*)cache.Model1->GetTree();
197  Status = Collide(T0, T1, world0, world1, &cache);
198  }
199  else
200  {
201  const AABBCollisionTree* T0 = (const AABBCollisionTree*)cache.Model0->GetTree();
202  const AABBCollisionTree* T1 = (const AABBCollisionTree*)cache.Model1->GetTree();
203  Status = Collide(T0, T1, world0, world1, &cache);
204  }
205  }
206 
207 #ifdef __MESHMERIZER_H__
208  if(Status)
209  {
210  // Reset counter as long as overlap occurs
211  if(GetContactStatus()) cache.ResetCountDown();
212 
213  // Enable hull test again when counter reaches zero
214  cache.CountDown--;
215  if(!cache.CountDown)
216  {
217  cache.ResetCountDown();
218  cache.HullTest = true;
219  }
220  }
221 #endif
222  return Status;
223 }
bool AABBTreeCollider::Collide ( const AABBCollisionTree tree0,
const AABBCollisionTree tree1,
const Matrix4x4 world0 = null,
const Matrix4x4 world1 = null,
Pair cache = null 
)

Collision query for normal AABB trees.

Parameters
tree0[in] AABB tree from first object
tree1[in] AABB tree from second object
world0[in] world matrix for first object
world1[in] world matrix for second object
cache[in/out] cache for a pair of previously colliding primitives
Returns
true if success
Warning
SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.

Definition at line 311 of file OPC_TreeCollider.cpp.

312 {
313  // Init collision query
314  InitQuery(world0, world1);
315 
316  // Check previous state
317  if(CheckTemporalCoherence(cache)) return true;
318 
319  // Perform collision query
320  _Collide(tree0->GetNodes(), tree1->GetNodes());
321 
323 
324  return true;
325 }
bool AABBTreeCollider::Collide ( const AABBNoLeafTree tree0,
const AABBNoLeafTree tree1,
const Matrix4x4 world0 = null,
const Matrix4x4 world1 = null,
Pair cache = null 
)

Collision query for no-leaf AABB trees.

Parameters
tree0[in] AABB tree from first object
tree1[in] AABB tree from second object
world0[in] world matrix for first object
world1[in] world matrix for second object
cache[in/out] cache for a pair of previously colliding primitives
Returns
true if success
Warning
SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.

Definition at line 339 of file OPC_TreeCollider.cpp.

340 {
341  // Init collision query
342  InitQuery(world0, world1);
343 
344  // Check previous state
345  if(CheckTemporalCoherence(cache)) return true;
346 
347  // Perform collision query
348  _Collide(tree0->GetNodes(), tree1->GetNodes());
349 
351 
352  return true;
353 }
bool AABBTreeCollider::Collide ( const AABBQuantizedTree tree0,
const AABBQuantizedTree tree1,
const Matrix4x4 world0 = null,
const Matrix4x4 world1 = null,
Pair cache = null 
)

Collision query for quantized AABB trees.

Parameters
tree0[in] AABB tree from first object
tree1[in] AABB tree from second object
world0[in] world matrix for first object
world1[in] world matrix for second object
cache[in/out] cache for a pair of previously colliding primitives
Returns
true if success
Warning
SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.

Definition at line 367 of file OPC_TreeCollider.cpp.

368 {
369  // Init collision query
370  InitQuery(world0, world1);
371 
372  // Check previous state
373  if(CheckTemporalCoherence(cache)) return true;
374 
375  // Setup dequantization coeffs
376  mCenterCoeff0 = tree0->mCenterCoeff;
377  mExtentsCoeff0 = tree0->mExtentsCoeff;
378  mCenterCoeff1 = tree1->mCenterCoeff;
379  mExtentsCoeff1 = tree1->mExtentsCoeff;
380 
381  // Dequantize box A
382  const AABBQuantizedNode* N0 = tree0->GetNodes();
383  const Point a(float(N0->mAABB.mExtents[0]) * mExtentsCoeff0.x, float(N0->mAABB.mExtents[1]) * mExtentsCoeff0.y, float(N0->mAABB.mExtents[2]) * mExtentsCoeff0.z);
384  const Point Pa(float(N0->mAABB.mCenter[0]) * mCenterCoeff0.x, float(N0->mAABB.mCenter[1]) * mCenterCoeff0.y, float(N0->mAABB.mCenter[2]) * mCenterCoeff0.z);
385  // Dequantize box B
386  const AABBQuantizedNode* N1 = tree1->GetNodes();
387  const Point b(float(N1->mAABB.mExtents[0]) * mExtentsCoeff1.x, float(N1->mAABB.mExtents[1]) * mExtentsCoeff1.y, float(N1->mAABB.mExtents[2]) * mExtentsCoeff1.z);
388  const Point Pb(float(N1->mAABB.mCenter[0]) * mCenterCoeff1.x, float(N1->mAABB.mCenter[1]) * mCenterCoeff1.y, float(N1->mAABB.mCenter[2]) * mCenterCoeff1.z);
389 
390  // Perform collision query
391  _Collide(N0, N1, a, Pa, b, Pb);
392 
394 
395  return true;
396 }
bool AABBTreeCollider::Collide ( const AABBQuantizedNoLeafTree tree0,
const AABBQuantizedNoLeafTree tree1,
const Matrix4x4 world0 = null,
const Matrix4x4 world1 = null,
Pair cache = null 
)

Collision query for quantized no-leaf AABB trees.

Parameters
tree0[in] AABB tree from first object
tree1[in] AABB tree from second object
world0[in] world matrix for first object
world1[in] world matrix for second object
cache[in/out] cache for a pair of previously colliding primitives
Returns
true if success
Warning
SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.

Definition at line 410 of file OPC_TreeCollider.cpp.

411 {
412  // Init collision query
413  InitQuery(world0, world1);
414 
415  // Check previous state
416  if(CheckTemporalCoherence(cache)) return true;
417 
418  // Setup dequantization coeffs
419  mCenterCoeff0 = tree0->mCenterCoeff;
420  mExtentsCoeff0 = tree0->mExtentsCoeff;
421  mCenterCoeff1 = tree1->mCenterCoeff;
422  mExtentsCoeff1 = tree1->mExtentsCoeff;
423 
424  // Perform collision query
425  _Collide(tree0->GetNodes(), tree1->GetNodes());
426 
428 
429  return true;
430 }
inline_ udword Opcode::AABBTreeCollider::GetNbBVBVTests ( ) const
inline

Stats: gets the number of BV-BV overlap tests after a collision query.

See Also
GetNbPrimPrimTests()
GetNbBVPrimTests()
Returns
the number of BV-BV tests performed during last query

Definition at line 129 of file Opcode.h.

inline_ udword Opcode::AABBTreeCollider::GetNbBVPrimTests ( ) const
inline

Stats: gets the number of BV-Triangle overlap tests after a collision query.

See Also
GetNbBVBVTests()
GetNbPrimPrimTests()
Returns
the number of BV-Triangle tests performed during last query

Definition at line 149 of file Opcode.h.

inline_ udword Opcode::AABBTreeCollider::GetNbPairs ( ) const
inline

Gets the number of contacts after a collision query.

See Also
GetContactStatus()
GetPairs()
Returns
the number of contacts / colliding pairs.

Definition at line 161 of file Opcode.h.

inline_ udword Opcode::AABBTreeCollider::GetNbPrimPrimTests ( ) const
inline

Stats: gets the number of Triangle-Triangle overlap tests after a collision query.

See Also
GetNbBVBVTests()
GetNbBVPrimTests()
Returns
the number of Triangle-Triangle tests performed during last query

Definition at line 139 of file Opcode.h.

inline_ const Pair* Opcode::AABBTreeCollider::GetPairs ( ) const
inline

Gets the pairs of colliding triangles after a collision query.

See Also
GetContactStatus()
GetNbPairs()
Returns
the list of colliding pairs (triangle indices)

Definition at line 171 of file Opcode.h.

void AABBTreeCollider::InitQuery ( const Matrix4x4 world0 = null,
const Matrix4x4 world1 = null 
)
protected

Initializes a collision query :

  • reset stats & contact status
  • setup matrices
Parameters
world0[in] world matrix for first object
world1[in] world matrix for second object
Warning
SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.

Definition at line 236 of file OPC_TreeCollider.cpp.

237 {
238  // Reset stats & contact status
240  mNbBVBVTests = 0;
241  mNbPrimPrimTests = 0;
242  mNbBVPrimTests = 0;
243  mPairs.Reset();
244 
245  // Setup matrices
246  Matrix4x4 InvWorld0, InvWorld1;
247  if(world0) InvertPRMatrix(InvWorld0, *world0);
248  else InvWorld0.Identity();
249 
250  if(world1) InvertPRMatrix(InvWorld1, *world1);
251  else InvWorld1.Identity();
252 
253  Matrix4x4 World0to1 = world0 ? (*world0 * InvWorld1) : InvWorld1;
254  Matrix4x4 World1to0 = world1 ? (*world1 * InvWorld0) : InvWorld0;
255 
256  mR0to1 = World0to1; World0to1.GetTrans(mT0to1);
257  mR1to0 = World1to0; World1to0.GetTrans(mT1to0);
258 
259  // Precompute absolute 1-to-0 rotation matrix
260  for(udword i=0;i<3;i++)
261  {
262  for(udword j=0;j<3;j++)
263  {
264  // Epsilon value prevents floating-point inaccuracies (strategy borrowed from RAPID)
265  mAR.m[i][j] = 1e-6f + fabsf(mR1to0.m[i][j]);
266  }
267  }
268 }
Opcode::AABBTreeCollider::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
void AABBTreeCollider::PrimTest ( udword  id0,
udword  id1 
)
protected

Leaf-leaf test for two primitive indices.

Parameters
id0[in] index from first leaf-triangle
id1[in] index from second leaf-triangle

Definition at line 529 of file OPC_TreeCollider.cpp.

530 {
531  // Request vertices from the app
532  VertexPointers VP0;
533  VertexPointers VP1;
534  mIMesh0->GetTriangle(VP0, id0);
535  mIMesh1->GetTriangle(VP1, id1);
536 
537  // Transform from space 1 to space 0
538  Point u0,u1,u2;
539  TransformPoint(u0, *VP1.Vertex[0], mR1to0, mT1to0);
540  TransformPoint(u1, *VP1.Vertex[1], mR1to0, mT1to0);
541  TransformPoint(u2, *VP1.Vertex[2], mR1to0, mT1to0);
542 
543  // Perform triangle-triangle overlap test
544  if(TriTriOverlap(*VP0.Vertex[0], *VP0.Vertex[1], *VP0.Vertex[2], u0, u1, u2))
545  {
546  // Keep track of colliding pairs
547  mPairs.Add(id0).Add(id1);
548  // Set contact status
549  mFlags |= OPC_CONTACT;
550  }
551 }
inline_ void AABBTreeCollider::PrimTestIndexTri ( udword  id0)
protected

Leaf-leaf test for a previously fetched triangle from tree B (in A's space) and a new leaf from A.

Parameters
id0[in] leaf-triangle index from tree A

Definition at line 581 of file OPC_TreeCollider.cpp.

582 {
583  // Request vertices from the app
584  VertexPointers VP;
585  mIMesh0->GetTriangle(VP, id0);
586 
587  // Perform triangle-triangle overlap test
588  if(TriTriOverlap(mLeafVerts[0], mLeafVerts[1], mLeafVerts[2], *VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2]))
589  {
590  // Keep track of colliding pairs
591  mPairs.Add(id0).Add(mLeafIndex);
592  // Set contact status
593  mFlags |= OPC_CONTACT;
594  }
595 }
inline_ void AABBTreeCollider::PrimTestTriIndex ( udword  id1)
protected

Leaf-leaf test for a previously fetched triangle from tree A (in B's space) and a new leaf from B.

Parameters
id1[in] leaf-triangle index from tree B

Definition at line 559 of file OPC_TreeCollider.cpp.

560 {
561  // Request vertices from the app
562  VertexPointers VP;
563  mIMesh1->GetTriangle(VP, id1);
564 
565  // Perform triangle-triangle overlap test
566  if(TriTriOverlap(mLeafVerts[0], mLeafVerts[1], mLeafVerts[2], *VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2]))
567  {
568  // Keep track of colliding pairs
569  mPairs.Add(mLeafIndex).Add(id1);
570  // Set contact status
571  mFlags |= OPC_CONTACT;
572  }
573 }
inline_ void Opcode::AABBTreeCollider::SetFullBoxBoxTest ( bool  flag)
inline

Settings: selects 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
See Also
SetFullPrimBoxTest(bool flag)

Definition at line 108 of file Opcode.h.

void Opcode::AABBTreeCollider::SetFullPrimBoxTest ( bool  flag)
inline

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

Parameters
flag[in] true for full tests, false for coarse tests
See Also
SetFullBoxBoxTest(bool flag)

Definition at line 117 of file Opcode.h.

inline_ bool Opcode::AABBTreeCollider::Setup ( const MeshInterface mi0,
const MeshInterface mi1 
)
inlineprotected

Definition at line 234 of file Opcode.h.

inline_ bool Opcode::AABBTreeCollider::TriBoxOverlap ( const Point center,
const Point extents 
)
protected
inline_ bool Opcode::AABBTreeCollider::TriTriOverlap ( const Point V0,
const Point V1,
const Point V2,
const Point U0,
const Point U1,
const Point U2 
)
protected

Member Data Documentation

Matrix3x3 Opcode::AABBTreeCollider::mAR
protected

Absolute rotation matrix.

Definition at line 192 of file Opcode.h.

Point Opcode::AABBTreeCollider::mCenterCoeff0
protected

Definition at line 198 of file Opcode.h.

Point Opcode::AABBTreeCollider::mCenterCoeff1
protected

Definition at line 200 of file Opcode.h.

Point Opcode::AABBTreeCollider::mExtentsCoeff0
protected

Definition at line 199 of file Opcode.h.

Point Opcode::AABBTreeCollider::mExtentsCoeff1
protected

Definition at line 201 of file Opcode.h.

bool Opcode::AABBTreeCollider::mFullBoxBoxTest
protected

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

Definition at line 206 of file Opcode.h.

bool Opcode::AABBTreeCollider::mFullPrimBoxTest
protected

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

Definition at line 207 of file Opcode.h.

const MeshInterface* Opcode::AABBTreeCollider::mIMesh0
protected

User-defined mesh interface for object0.

Definition at line 185 of file Opcode.h.

const MeshInterface* Opcode::AABBTreeCollider::mIMesh1
protected

User-defined mesh interface for object1.

Definition at line 186 of file Opcode.h.

udword Opcode::AABBTreeCollider::mLeafIndex
protected

Triangle index.

Definition at line 204 of file Opcode.h.

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

Triangle vertices.

Definition at line 203 of file Opcode.h.

udword Opcode::AABBTreeCollider::mNbBVBVTests
protected

Number of BV-BV tests.

Definition at line 188 of file Opcode.h.

udword Opcode::AABBTreeCollider::mNbBVPrimTests
protected

Number of BV-Primitive tests.

Definition at line 190 of file Opcode.h.

udword Opcode::AABBTreeCollider::mNbPrimPrimTests
protected

Number of Primitive-Primitive tests.

Definition at line 189 of file Opcode.h.

Container Opcode::AABBTreeCollider::mPairs
protected

Pairs of colliding primitives.

Definition at line 183 of file Opcode.h.

Matrix3x3 Opcode::AABBTreeCollider::mR0to1
protected

Rotation from object0 to object1.

Definition at line 193 of file Opcode.h.

Matrix3x3 Opcode::AABBTreeCollider::mR1to0
protected

Rotation from object1 to object0.

Definition at line 194 of file Opcode.h.

Point Opcode::AABBTreeCollider::mT0to1
protected

Translation from object0 to object1.

Definition at line 195 of file Opcode.h.

Point Opcode::AABBTreeCollider::mT1to0
protected

Translation from object1 to object0.

Definition at line 196 of file Opcode.h.


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