OPC_TreeCollider.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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. #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
  48. inline_ void ResetCountDown()
  49. {
  50. CountDown = 50;
  51. }
  52. #else
  53. void ResetCountDown(){};
  54. #endif // __MESHMERIZER_H__
  55. const Model* Model0; //!< Model for first object
  56. const Model* Model1; //!< Model for second object
  57. #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
  58. SVCache SepVector;
  59. udword CountDown;
  60. bool HullTest;
  61. #endif // __MESHMERIZER_H__
  62. };
  63. class OPCODE_API AABBTreeCollider : public Collider
  64. {
  65. public:
  66. // Constructor / Destructor
  67. AABBTreeCollider();
  68. virtual ~AABBTreeCollider();
  69. // Generic collision query
  70. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  71. /**
  72. * Generic collision query for generic OPCODE models. After the call, access the results with:
  73. * - GetContactStatus()
  74. * - GetNbPairs()
  75. * - GetPairs()
  76. *
  77. * \param cache [in] collision cache for model pointers and a colliding pair of primitives
  78. * \param world0 [in] world matrix for first object, or null
  79. * \param world1 [in] world matrix for second object, or null
  80. * \return true if success
  81. * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
  82. */
  83. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  84. bool Collide(BVTCache& cache, const Matrix4x4* world0=null, const Matrix4x4* world1=null);
  85. // Collision queries
  86. bool Collide(const AABBCollisionTree* tree0, const AABBCollisionTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null);
  87. bool Collide(const AABBNoLeafTree* tree0, const AABBNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null);
  88. bool Collide(const AABBQuantizedTree* tree0, const AABBQuantizedTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null);
  89. bool Collide(const AABBQuantizedNoLeafTree* tree0, const AABBQuantizedNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null);
  90. // Settings
  91. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  92. /**
  93. * Settings: selects between full box-box tests or "SAT-lite" tests (where Class III axes are discarded)
  94. * \param flag [in] true for full tests, false for coarse tests
  95. * \see SetFullPrimBoxTest(bool flag)
  96. */
  97. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  98. inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; }
  99. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  100. /**
  101. * Settings: selects between full triangle-box tests or "SAT-lite" tests (where Class III axes are discarded)
  102. * \param flag [in] true for full tests, false for coarse tests
  103. * \see SetFullBoxBoxTest(bool flag)
  104. */
  105. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  106. inline_ void SetFullPrimBoxTest(bool flag) { mFullPrimBoxTest = flag; }
  107. // Stats
  108. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  109. /**
  110. * Stats: gets the number of BV-BV overlap tests after a collision query.
  111. * \see GetNbPrimPrimTests()
  112. * \see GetNbBVPrimTests()
  113. * \return the number of BV-BV tests performed during last query
  114. */
  115. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  116. inline_ udword GetNbBVBVTests() const { return mNbBVBVTests; }
  117. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  118. /**
  119. * Stats: gets the number of Triangle-Triangle overlap tests after a collision query.
  120. * \see GetNbBVBVTests()
  121. * \see GetNbBVPrimTests()
  122. * \return the number of Triangle-Triangle tests performed during last query
  123. */
  124. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  125. inline_ udword GetNbPrimPrimTests() const { return mNbPrimPrimTests; }
  126. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  127. /**
  128. * Stats: gets the number of BV-Triangle overlap tests after a collision query.
  129. * \see GetNbBVBVTests()
  130. * \see GetNbPrimPrimTests()
  131. * \return the number of BV-Triangle tests performed during last query
  132. */
  133. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  134. inline_ udword GetNbBVPrimTests() const { return mNbBVPrimTests; }
  135. // Data access
  136. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  137. /**
  138. * Gets the number of contacts after a collision query.
  139. * \see GetContactStatus()
  140. * \see GetPairs()
  141. * \return the number of contacts / colliding pairs.
  142. */
  143. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  144. inline_ udword GetNbPairs() const { return mPairs.GetNbEntries()>>1; }
  145. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  146. /**
  147. * Gets the pairs of colliding triangles after a collision query.
  148. * \see GetContactStatus()
  149. * \see GetNbPairs()
  150. * \return the list of colliding pairs (triangle indices)
  151. */
  152. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  153. inline_ const Pair* GetPairs() const { return (const Pair*)mPairs.GetEntries(); }
  154. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  155. /**
  156. * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider.
  157. * \return null if everything is ok, else a string describing the problem
  158. */
  159. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  160. override(Collider) const char* ValidateSettings();
  161. protected:
  162. // Colliding pairs
  163. Container mPairs; //!< Pairs of colliding primitives
  164. // User mesh interfaces
  165. const MeshInterface* mIMesh0; //!< User-defined mesh interface for object0
  166. const MeshInterface* mIMesh1; //!< User-defined mesh interface for object1
  167. // Stats
  168. udword mNbBVBVTests; //!< Number of BV-BV tests
  169. udword mNbPrimPrimTests; //!< Number of Primitive-Primitive tests
  170. udword mNbBVPrimTests; //!< Number of BV-Primitive tests
  171. // Precomputed data
  172. Matrix3x3 mAR; //!< Absolute rotation matrix
  173. Matrix3x3 mR0to1; //!< Rotation from object0 to object1
  174. Matrix3x3 mR1to0; //!< Rotation from object1 to object0
  175. Point mT0to1; //!< Translation from object0 to object1
  176. Point mT1to0; //!< Translation from object1 to object0
  177. // Dequantization coeffs
  178. Point mCenterCoeff0;
  179. Point mExtentsCoeff0;
  180. Point mCenterCoeff1;
  181. Point mExtentsCoeff1;
  182. // Leaf description
  183. Point mLeafVerts[3]; //!< Triangle vertices
  184. udword mLeafIndex; //!< Triangle index
  185. // Settings
  186. bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false)
  187. bool mFullPrimBoxTest; //!< Perform full Primitive-BV tests (true) or SAT-lite tests (false)
  188. // Internal methods
  189. // Standard AABB trees
  190. void _Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1);
  191. // Quantized AABB trees
  192. void _Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const Point& a, const Point& Pa, const Point& b, const Point& Pb);
  193. // No-leaf AABB trees
  194. void _CollideTriBox(const AABBNoLeafNode* b);
  195. void _CollideBoxTri(const AABBNoLeafNode* b);
  196. void _Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b);
  197. // Quantized no-leaf AABB trees
  198. void _CollideTriBox(const AABBQuantizedNoLeafNode* b);
  199. void _CollideBoxTri(const AABBQuantizedNoLeafNode* b);
  200. void _Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b);
  201. // Overlap tests
  202. void PrimTest(udword id0, udword id1);
  203. inline_ void PrimTestTriIndex(udword id1);
  204. inline_ void PrimTestIndexTri(udword id0);
  205. inline_ BOOL BoxBoxOverlap(const Point& ea, const Point& ca, const Point& eb, const Point& cb);
  206. inline_ BOOL TriBoxOverlap(const Point& center, const Point& extents);
  207. inline_ BOOL TriTriOverlap(const Point& V0, const Point& V1, const Point& V2, const Point& U0, const Point& U1, const Point& U2);
  208. // Init methods
  209. void InitQuery(const Matrix4x4* world0=null, const Matrix4x4* world1=null);
  210. bool CheckTemporalCoherence(Pair* cache);
  211. inline_ BOOL Setup(const MeshInterface* mi0, const MeshInterface* mi1)
  212. {
  213. mIMesh0 = mi0;
  214. mIMesh1 = mi1;
  215. if(!mIMesh0 || !mIMesh1) return FALSE;
  216. return TRUE;
  217. }
  218. };
  219. #endif // __OPC_TREECOLLIDER_H__