diff options
Diffstat (limited to 'Opcode/OPC_TreeCollider.h')
-rw-r--r-- | Opcode/OPC_TreeCollider.h | 488 |
1 files changed, 244 insertions, 244 deletions
diff --git a/Opcode/OPC_TreeCollider.h b/Opcode/OPC_TreeCollider.h index ce58ff8..ec0e517 100644 --- a/Opcode/OPC_TreeCollider.h +++ b/Opcode/OPC_TreeCollider.h @@ -1,244 +1,244 @@ -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-/*
- * OPCODE - Optimized Collision Detection
- * Copyright (C) 2001 Pierre Terdiman
- * Homepage: http://www.codercorner.com/Opcode.htm
- */
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Contains code for a tree collider.
- * \file OPC_TreeCollider.h
- * \author Pierre Terdiman
- * \date March, 20, 2001
- */
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Include Guard
-#ifndef __OPC_TREECOLLIDER_H__
-#define __OPC_TREECOLLIDER_H__
-
- //! This structure holds cached information used by the algorithm.
- //! Two model pointers and two colliding primitives are cached. Model pointers are assigned
- //! to their respective meshes, and the pair of colliding primitives is used for temporal
- //! coherence. That is, in case temporal coherence is enabled, those two primitives are
- //! tested for overlap before everything else. If they still collide, we're done before
- //! even entering the recursive collision code.
- struct OPCODE_API BVTCache : Pair
- {
- //! Constructor
- inline_ BVTCache()
- {
- ResetCache();
- ResetCountDown();
- }
-
- void ResetCache()
- {
- Model0 = null;
- Model1 = null;
- id0 = 0;
- id1 = 1;
-#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
- HullTest = true;
- SepVector.pid = 0;
- SepVector.qid = 0;
- SepVector.SV = IcePoint(1.0f, 0.0f, 0.0f);
-#endif // __MESHMERIZER_H__
- }
-
- inline_ void ResetCountDown()
- {
-#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
- CountDown = 50;
-#endif // __MESHMERIZER_H__
- }
-
- const Model* Model0; //!< Model for first object
- const Model* Model1; //!< Model for second object
-
-#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
- SVCache SepVector;
- udword CountDown;
- bool HullTest;
-#endif // __MESHMERIZER_H__
- };
-
- class OPCODE_API AABBTreeCollider : public Collider
- {
- public:
- // Constructor / Destructor
- AABBTreeCollider();
- virtual ~AABBTreeCollider();
- // Generic collision query
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /**
- * Generic collision query for generic OPCODE models. After the call, access the results with:
- * - GetContactStatus()
- * - GetNbPairs()
- * - GetPairs()
- *
- * \param cache [in] collision cache for model pointers and a colliding pair of primitives
- * \param world0 [in] world matrix for first object, or null
- * \param world1 [in] world matrix for second object, or null
- * \return true if success
- * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- bool Collide(BVTCache& cache, const Matrix4x4* world0=null, const Matrix4x4* world1=null);
-
- // Collision queries
- 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);
- // Settings
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /**
- * Settings: selects between full box-box tests or "SAT-lite" tests (where Class III axes are discarded)
- * \param flag [in] true for full tests, false for coarse tests
- * \see SetFullPrimBoxTest(bool flag)
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /**
- * Settings: selects between full triangle-box tests or "SAT-lite" tests (where Class III axes are discarded)
- * \param flag [in] true for full tests, false for coarse tests
- * \see SetFullBoxBoxTest(bool flag)
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- inline_ void SetFullPrimBoxTest(bool flag) { mFullPrimBoxTest = flag; }
-
- // Stats
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /**
- * Stats: gets the number of BV-BV overlap tests after a collision query.
- * \see GetNbPrimPrimTests()
- * \see GetNbBVPrimTests()
- * \return the number of BV-BV tests performed during last query
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- inline_ udword GetNbBVBVTests() const { return mNbBVBVTests; }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /**
- * Stats: gets the number of Triangle-Triangle overlap tests after a collision query.
- * \see GetNbBVBVTests()
- * \see GetNbBVPrimTests()
- * \return the number of Triangle-Triangle tests performed during last query
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- inline_ udword GetNbPrimPrimTests() const { return mNbPrimPrimTests; }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /**
- * Stats: gets the number of BV-Triangle overlap tests after a collision query.
- * \see GetNbBVBVTests()
- * \see GetNbPrimPrimTests()
- * \return the number of BV-Triangle tests performed during last query
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- inline_ udword GetNbBVPrimTests() const { return mNbBVPrimTests; }
-
- // Data access
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /**
- * Gets the number of contacts after a collision query.
- * \see GetContactStatus()
- * \see GetPairs()
- * \return the number of contacts / colliding pairs.
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- inline_ udword GetNbPairs() const { return mPairs.GetNbEntries()>>1; }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /**
- * Gets the pairs of colliding triangles after a collision query.
- * \see GetContactStatus()
- * \see GetNbPairs()
- * \return the list of colliding pairs (triangle indices)
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- inline_ const Pair* GetPairs() const { return (const Pair*)mPairs.GetEntries(); }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /**
- * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider.
- * \return null if everything is ok, else a string describing the problem
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- override(Collider) const char* ValidateSettings();
-
- protected:
- // Colliding pairs
- Container mPairs; //!< Pairs of colliding primitives
- // User mesh interfaces
- const MeshInterface* mIMesh0; //!< User-defined mesh interface for object0
- const MeshInterface* mIMesh1; //!< User-defined mesh interface for object1
- // Stats
- udword mNbBVBVTests; //!< Number of BV-BV tests
- udword mNbPrimPrimTests; //!< Number of Primitive-Primitive tests
- udword mNbBVPrimTests; //!< Number of BV-Primitive tests
- // Precomputed data
- Matrix3x3 mAR; //!< Absolute rotation matrix
- Matrix3x3 mR0to1; //!< Rotation from object0 to object1
- Matrix3x3 mR1to0; //!< Rotation from object1 to object0
- IcePoint mT0to1; //!< Translation from object0 to object1
- IcePoint mT1to0; //!< Translation from object1 to object0
- // Dequantization coeffs
- IcePoint mCenterCoeff0;
- IcePoint mExtentsCoeff0;
- IcePoint mCenterCoeff1;
- IcePoint mExtentsCoeff1;
- // Leaf description
- IcePoint mLeafVerts[3]; //!< Triangle vertices
- udword mLeafIndex; //!< Triangle index
- // Settings
- bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false)
- bool mFullPrimBoxTest; //!< Perform full Primitive-BV tests (true) or SAT-lite tests (false)
- // Internal methods
-
- // Standard AABB trees
- void _Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1);
- // Quantized AABB trees
- void _Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const IcePoint& a, const IcePoint& Pa, const IcePoint& b, const IcePoint& Pb);
- // No-leaf AABB trees
- void _CollideTriBox(const AABBNoLeafNode* b);
- void _CollideBoxTri(const AABBNoLeafNode* b);
- void _Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b);
- // Quantized no-leaf AABB trees
- void _CollideTriBox(const AABBQuantizedNoLeafNode* b);
- void _CollideBoxTri(const AABBQuantizedNoLeafNode* b);
- void _Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b);
- // Overlap tests
- void PrimTest(udword id0, udword id1);
- inline_ void PrimTestTriIndex(udword id1);
- inline_ void PrimTestIndexTri(udword id0);
-
- inline_ BOOL BoxBoxOverlap(const IcePoint& ea, const IcePoint& ca, const IcePoint& eb, const IcePoint& cb);
- inline_ BOOL TriBoxOverlap(const IcePoint& center, const IcePoint& extents);
- inline_ BOOL TriTriOverlap(const IcePoint& V0, const IcePoint& V1, const IcePoint& V2, const IcePoint& U0, const IcePoint& U1, const IcePoint& U2);
- // Init methods
- void InitQuery(const Matrix4x4* world0=null, const Matrix4x4* world1=null);
- bool CheckTemporalCoherence(Pair* cache);
-
- inline_ BOOL Setup(const MeshInterface* mi0, const MeshInterface* mi1)
- {
- mIMesh0 = mi0;
- mIMesh1 = mi1;
-
- if(!mIMesh0 || !mIMesh1) return FALSE;
-
- return TRUE;
- }
- };
-
-#endif // __OPC_TREECOLLIDER_H__
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a tree collider. + * \file OPC_TreeCollider.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_TREECOLLIDER_H__ +#define __OPC_TREECOLLIDER_H__ + + //! This structure holds cached information used by the algorithm. + //! Two model pointers and two colliding primitives are cached. Model pointers are assigned + //! to their respective meshes, and the pair of colliding primitives is used for temporal + //! coherence. That is, in case temporal coherence is enabled, those two primitives are + //! tested for overlap before everything else. If they still collide, we're done before + //! even entering the recursive collision code. + struct OPCODE_API BVTCache : Pair + { + //! Constructor + inline_ BVTCache() + { + ResetCache(); + ResetCountDown(); + } + + void ResetCache() + { + Model0 = null; + Model1 = null; + id0 = 0; + id1 = 1; +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + HullTest = true; + SepVector.pid = 0; + SepVector.qid = 0; + SepVector.SV = IcePoint(1.0f, 0.0f, 0.0f); +#endif // __MESHMERIZER_H__ + } + + inline_ void ResetCountDown() + { +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + CountDown = 50; +#endif // __MESHMERIZER_H__ + } + + const Model* Model0; //!< Model for first object + const Model* Model1; //!< Model for second object + +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + SVCache SepVector; + udword CountDown; + bool HullTest; +#endif // __MESHMERIZER_H__ + }; + + class OPCODE_API AABBTreeCollider : public Collider + { + public: + // Constructor / Destructor + AABBTreeCollider(); + virtual ~AABBTreeCollider(); + // Generic collision query + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results with: + * - GetContactStatus() + * - GetNbPairs() + * - GetPairs() + * + * \param cache [in] collision cache for model pointers and a colliding pair of primitives + * \param world0 [in] world matrix for first object, or null + * \param world1 [in] world matrix for second object, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(BVTCache& cache, const Matrix4x4* world0=null, const Matrix4x4* world1=null); + + // Collision queries + 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); + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: selects between full box-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + * \see SetFullPrimBoxTest(bool flag) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: selects between full triangle-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + * \see SetFullBoxBoxTest(bool flag) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullPrimBoxTest(bool flag) { mFullPrimBoxTest = flag; } + + // Stats + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of BV-BV overlap tests after a collision query. + * \see GetNbPrimPrimTests() + * \see GetNbBVPrimTests() + * \return the number of BV-BV tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbBVBVTests() const { return mNbBVBVTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Triangle-Triangle overlap tests after a collision query. + * \see GetNbBVBVTests() + * \see GetNbBVPrimTests() + * \return the number of Triangle-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbPrimPrimTests() const { return mNbPrimPrimTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of BV-Triangle overlap tests after a collision query. + * \see GetNbBVBVTests() + * \see GetNbPrimPrimTests() + * \return the number of BV-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbBVPrimTests() const { return mNbBVPrimTests; } + + // Data access + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of contacts after a collision query. + * \see GetContactStatus() + * \see GetPairs() + * \return the number of contacts / colliding pairs. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbPairs() const { return mPairs.GetNbEntries()>>1; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the pairs of colliding triangles after a collision query. + * \see GetContactStatus() + * \see GetNbPairs() + * \return the list of colliding pairs (triangle indices) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const Pair* GetPairs() const { return (const Pair*)mPairs.GetEntries(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Colliding pairs + Container mPairs; //!< Pairs of colliding primitives + // User mesh interfaces + const MeshInterface* mIMesh0; //!< User-defined mesh interface for object0 + const MeshInterface* mIMesh1; //!< User-defined mesh interface for object1 + // Stats + udword mNbBVBVTests; //!< Number of BV-BV tests + udword mNbPrimPrimTests; //!< Number of Primitive-Primitive tests + udword mNbBVPrimTests; //!< Number of BV-Primitive tests + // Precomputed data + Matrix3x3 mAR; //!< Absolute rotation matrix + Matrix3x3 mR0to1; //!< Rotation from object0 to object1 + Matrix3x3 mR1to0; //!< Rotation from object1 to object0 + IcePoint mT0to1; //!< Translation from object0 to object1 + IcePoint mT1to0; //!< Translation from object1 to object0 + // Dequantization coeffs + IcePoint mCenterCoeff0; + IcePoint mExtentsCoeff0; + IcePoint mCenterCoeff1; + IcePoint mExtentsCoeff1; + // Leaf description + IcePoint mLeafVerts[3]; //!< Triangle vertices + udword mLeafIndex; //!< Triangle index + // Settings + bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false) + bool mFullPrimBoxTest; //!< Perform full Primitive-BV tests (true) or SAT-lite tests (false) + // Internal methods + + // Standard AABB trees + void _Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1); + // Quantized AABB trees + void _Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const IcePoint& a, const IcePoint& Pa, const IcePoint& b, const IcePoint& Pb); + // No-leaf AABB trees + void _CollideTriBox(const AABBNoLeafNode* b); + void _CollideBoxTri(const AABBNoLeafNode* b); + void _Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b); + // Quantized no-leaf AABB trees + void _CollideTriBox(const AABBQuantizedNoLeafNode* b); + void _CollideBoxTri(const AABBQuantizedNoLeafNode* b); + void _Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b); + // Overlap tests + void PrimTest(udword id0, udword id1); + inline_ void PrimTestTriIndex(udword id1); + inline_ void PrimTestIndexTri(udword id0); + + inline_ BOOL BoxBoxOverlap(const IcePoint& ea, const IcePoint& ca, const IcePoint& eb, const IcePoint& cb); + inline_ BOOL TriBoxOverlap(const IcePoint& center, const IcePoint& extents); + inline_ BOOL TriTriOverlap(const IcePoint& V0, const IcePoint& V1, const IcePoint& V2, const IcePoint& U0, const IcePoint& U1, const IcePoint& U2); + // Init methods + void InitQuery(const Matrix4x4* world0=null, const Matrix4x4* world1=null); + bool CheckTemporalCoherence(Pair* cache); + + inline_ BOOL Setup(const MeshInterface* mi0, const MeshInterface* mi1) + { + mIMesh0 = mi0; + mIMesh1 = mi1; + + if(!mIMesh0 || !mIMesh1) return FALSE; + + return TRUE; + } + }; + +#endif // __OPC_TREECOLLIDER_H__ |