OPC_TreeCollider.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. /*
  3. * OPCODE - Optimized Collision Detection
  4. * Copyright (C) 2001 Pierre Terdiman
  5. * Homepage: http://www.codercorner.com/Opcode.htm
  6. */
  7. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. /**
  10. * Contains code for a tree collider.
  11. * \file OPC_TreeCollider.h
  12. * \author Pierre Terdiman
  13. * \date March, 20, 2001
  14. */
  15. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  16. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. // Include Guard
  18. #ifndef __OPC_TREECOLLIDER_H__
  19. #define __OPC_TREECOLLIDER_H__
  20. //! This structure holds cached information used by the algorithm.
  21. //! Two model pointers and two colliding primitives are cached. Model pointers are assigned
  22. //! to their respective meshes, and the pair of colliding primitives is used for temporal
  23. //! coherence. That is, in case temporal coherence is enabled, those two primitives are
  24. //! tested for overlap before everything else. If they still collide, we're done before
  25. //! even entering the recursive collision code.
  26. struct OPCODE_API BVTCache : Pair
  27. {
  28. //! Constructor
  29. inline_ BVTCache()
  30. {
  31. ResetCache();
  32. ResetCountDown();
  33. }
  34. void ResetCache()
  35. {
  36. Model0 = null;
  37. Model1 = null;
  38. id0 = 0;
  39. id1 = 1;
  40. #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
  41. HullTest = true;
  42. SepVector.pid = 0;
  43. SepVector.qid = 0;
  44. SepVector.SV = Point(1.0f, 0.0f, 0.0f);
  45. #endif // __MESHMERIZER_H__
  46. }
  47. inline_ void ResetCountDown()
  48. {
  49. #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
  50. CountDown = 50;
  51. #endif // __MESHMERIZER_H__
  52. }
  53. const Model* Model0; //!< Model for first object
  54. const Model* Model1; //!< Model for second object
  55. #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
  56. SVCache SepVector;
  57. udword CountDown;
  58. bool HullTest;
  59. #endif // __MESHMERIZER_H__
  60. };
  61. class OPCODE_API AABBTreeCollider : public Collider
  62. {
  63. public:
  64. // Constructor / Destructor
  65. AABBTreeCollider();
  66. virtual ~AABBTreeCollider();
  67. // Generic collision query
  68. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. /**
  70. * Generic collision query for generic OPCODE models. After the call, access the results with:
  71. * - GetContactStatus()
  72. * - GetNbPairs()
  73. * - GetPairs()
  74. *
  75. * \param cache [in] collision cache for model pointers and a colliding pair of primitives
  76. * \param world0 [in] world matrix for first object, or null
  77. * \param world1 [in] world matrix for second object, or null
  78. * \return true if success
  79. * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
  80. */
  81. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  82. bool Collide(BVTCache& cache, const Matrix4x4* world0=null, const Matrix4x4* world1=null);
  83. // Collision queries
  84. bool Collide(const AABBCollisionTree* tree0, const AABBCollisionTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null);
  85. bool Collide(const AABBNoLeafTree* tree0, const AABBNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null);
  86. bool Collide(const AABBQuantizedTree* tree0, const AABBQuantizedTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null);
  87. bool Collide(const AABBQuantizedNoLeafTree* tree0, const AABBQuantizedNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null);
  88. // Settings
  89. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  90. /**
  91. * Settings: selects between full box-box tests or "SAT-lite" tests (where Class III axes are discarded)
  92. * \param flag [in] true for full tests, false for coarse tests
  93. * \see SetFullPrimBoxTest(bool flag)
  94. */
  95. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  96. inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; }
  97. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  98. /**
  99. * Settings: selects between full triangle-box tests or "SAT-lite" tests (where Class III axes are discarded)
  100. * \param flag [in] true for full tests, false for coarse tests
  101. * \see SetFullBoxBoxTest(bool flag)
  102. */
  103. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. inline_ void SetFullPrimBoxTest(bool flag) { mFullPrimBoxTest = flag; }
  105. // Stats
  106. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  107. /**
  108. * Stats: gets the number of BV-BV overlap tests after a collision query.
  109. * \see GetNbPrimPrimTests()
  110. * \see GetNbBVPrimTests()
  111. * \return the number of BV-BV tests performed during last query
  112. */
  113. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  114. inline_ udword GetNbBVBVTests() const { return mNbBVBVTests; }
  115. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  116. /**
  117. * Stats: gets the number of Triangle-Triangle overlap tests after a collision query.
  118. * \see GetNbBVBVTests()
  119. * \see GetNbBVPrimTests()
  120. * \return the number of Triangle-Triangle tests performed during last query
  121. */
  122. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  123. inline_ udword GetNbPrimPrimTests() const { return mNbPrimPrimTests; }
  124. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  125. /**
  126. * Stats: gets the number of BV-Triangle overlap tests after a collision query.
  127. * \see GetNbBVBVTests()
  128. * \see GetNbPrimPrimTests()
  129. * \return the number of BV-Triangle tests performed during last query
  130. */
  131. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  132. inline_ udword GetNbBVPrimTests() const { return mNbBVPrimTests; }
  133. // Data access
  134. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  135. /**
  136. * Gets the number of contacts after a collision query.
  137. * \see GetContactStatus()
  138. * \see GetPairs()
  139. * \return the number of contacts / colliding pairs.
  140. */
  141. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  142. inline_ udword GetNbPairs() const { return mPairs.GetNbEntries()>>1; }
  143. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  144. /**
  145. * Gets the pairs of colliding triangles after a collision query.
  146. * \see GetContactStatus()
  147. * \see GetNbPairs()
  148. * \return the list of colliding pairs (triangle indices)
  149. */
  150. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  151. inline_ const Pair* GetPairs() const { return (const Pair*)mPairs.GetEntries(); }
  152. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  153. /**
  154. * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider.
  155. * \return null if everything is ok, else a string describing the problem
  156. */
  157. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  158. override(Collider) const char* ValidateSettings();
  159. protected:
  160. // Colliding pairs
  161. OPC_Container mPairs; //!< Pairs of colliding primitives
  162. // User mesh interfaces
  163. const MeshInterface* mIMesh0; //!< User-defined mesh interface for object0
  164. const MeshInterface* mIMesh1; //!< User-defined mesh interface for object1
  165. // Stats
  166. udword mNbBVBVTests; //!< Number of BV-BV tests
  167. udword mNbPrimPrimTests; //!< Number of Primitive-Primitive tests
  168. udword mNbBVPrimTests; //!< Number of BV-Primitive tests
  169. // Precomputed data
  170. Matrix3x3 mAR; //!< Absolute rotation matrix
  171. Matrix3x3 mR0to1; //!< Rotation from object0 to object1
  172. Matrix3x3 mR1to0; //!< Rotation from object1 to object0
  173. Point mT0to1; //!< Translation from object0 to object1
  174. Point mT1to0; //!< Translation from object1 to object0
  175. // Dequantization coeffs
  176. Point mCenterCoeff0;
  177. Point mExtentsCoeff0;
  178. Point mCenterCoeff1;
  179. Point mExtentsCoeff1;
  180. // Leaf description
  181. Point mLeafVerts[3]; //!< Triangle vertices
  182. udword mLeafIndex; //!< Triangle index
  183. // Settings
  184. bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false)
  185. bool mFullPrimBoxTest; //!< Perform full Primitive-BV tests (true) or SAT-lite tests (false)
  186. // Internal methods
  187. // Standard AABB trees
  188. void _Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1);
  189. // Quantized AABB trees
  190. void _Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const Point& a, const Point& Pa, const Point& b, const Point& Pb);
  191. // No-leaf AABB trees
  192. void _CollideTriBox(const AABBNoLeafNode* b);
  193. void _CollideBoxTri(const AABBNoLeafNode* b);
  194. void _Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b);
  195. // Quantized no-leaf AABB trees
  196. void _CollideTriBox(const AABBQuantizedNoLeafNode* b);
  197. void _CollideBoxTri(const AABBQuantizedNoLeafNode* b);
  198. void _Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b);
  199. // Overlap tests
  200. void PrimTest(udword id0, udword id1);
  201. inline_ void PrimTestTriIndex(udword id1);
  202. inline_ void PrimTestIndexTri(udword id0);
  203. inline_ BOOL BoxBoxOverlap(const Point& ea, const Point& ca, const Point& eb, const Point& cb);
  204. inline_ BOOL TriBoxOverlap(const Point& center, const Point& extents);
  205. inline_ BOOL TriTriOverlap(const Point& V0, const Point& V1, const Point& V2, const Point& U0, const Point& U1, const Point& U2);
  206. // Init methods
  207. void InitQuery(const Matrix4x4* world0=null, const Matrix4x4* world1=null);
  208. bool CheckTemporalCoherence(Pair* cache);
  209. inline_ BOOL Setup(const MeshInterface* mi0, const MeshInterface* mi1)
  210. {
  211. mIMesh0 = mi0;
  212. mIMesh1 = mi1;
  213. if(!mIMesh0 || !mIMesh1) return FALSE;
  214. return TRUE;
  215. }
  216. };
  217. #endif // __OPC_TREECOLLIDER_H__