OPC_Model.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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 OPCODE models.
  11. * \file OPC_Model.cpp
  12. * \author Pierre Terdiman
  13. * \date March, 20, 2001
  14. */
  15. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  16. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. /**
  18. * The main collision wrapper, for all trees. Supported trees are:
  19. * - Normal trees (2*N-1 nodes, full size)
  20. * - No-leaf trees (N-1 nodes, full size)
  21. * - Quantized trees (2*N-1 nodes, half size)
  22. * - Quantized no-leaf trees (N-1 nodes, half size)
  23. *
  24. * Usage:
  25. *
  26. * 1) Create a static mesh interface using callbacks or pointers. (see OPC_MeshInterface.cpp).
  27. * Keep it around in your app, since a pointer to this interface is saved internally and
  28. * used until you release the collision structures.
  29. *
  30. * 2) Build a Model using a creation structure:
  31. *
  32. * \code
  33. * Model Sample;
  34. *
  35. * OPCODECREATE OPCC;
  36. * OPCC.IMesh = ...;
  37. * OPCC.Rules = ...;
  38. * OPCC.NoLeaf = ...;
  39. * OPCC.Quantized = ...;
  40. * OPCC.KeepOriginal = ...;
  41. * bool Status = Sample.Build(OPCC);
  42. * \endcode
  43. *
  44. * 3) Create a tree collider and set it up:
  45. *
  46. * \code
  47. * AABBTreeCollider TC;
  48. * TC.SetFirstContact(...);
  49. * TC.SetFullBoxBoxTest(...);
  50. * TC.SetFullPrimBoxTest(...);
  51. * TC.SetTemporalCoherence(...);
  52. * \endcode
  53. *
  54. * 4) Perform a collision query
  55. *
  56. * \code
  57. * // Setup cache
  58. * static BVTCache ColCache;
  59. * ColCache.Model0 = &Model0;
  60. * ColCache.Model1 = &Model1;
  61. *
  62. * // Collision query
  63. * bool IsOk = TC.Collide(ColCache, World0, World1);
  64. *
  65. * // Get collision status => if true, objects overlap
  66. * BOOL Status = TC.GetContactStatus();
  67. *
  68. * // Number of colliding pairs and list of pairs
  69. * udword NbPairs = TC.GetNbPairs();
  70. * const Pair* p = TC.GetPairs()
  71. * \endcode
  72. *
  73. * 5) Stats
  74. *
  75. * \code
  76. * Model0.GetUsedBytes() = number of bytes used for this collision tree
  77. * TC.GetNbBVBVTests() = number of BV-BV overlap tests performed during last query
  78. * TC.GetNbPrimPrimTests() = number of Triangle-Triangle overlap tests performed during last query
  79. * TC.GetNbBVPrimTests() = number of Triangle-BV overlap tests performed during last query
  80. * \endcode
  81. *
  82. * \class Model
  83. * \author Pierre Terdiman
  84. * \version 1.3
  85. * \date March, 20, 2001
  86. */
  87. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  88. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  89. // Precompiled Header
  90. #include "Stdafx.h"
  91. using namespace Opcode;
  92. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  93. /**
  94. * Constructor.
  95. */
  96. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  97. Model::Model()
  98. {
  99. #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
  100. mHull = null;
  101. #endif // __MESHMERIZER_H__
  102. }
  103. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. /**
  105. * Destructor.
  106. */
  107. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  108. Model::~Model()
  109. {
  110. Release();
  111. }
  112. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  113. /**
  114. * Releases the model.
  115. */
  116. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  117. void Model::Release()
  118. {
  119. ReleaseBase();
  120. #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
  121. DELETESINGLE(mHull);
  122. #endif // __MESHMERIZER_H__
  123. }
  124. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  125. /**
  126. * Builds a collision model.
  127. * \param create [in] model creation structure
  128. * \return true if success
  129. */
  130. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  131. bool Model::Build(const OPCODECREATE& create)
  132. {
  133. // 1) Checkings
  134. if(!create.mIMesh || !create.mIMesh->IsValid()) return false;
  135. // For this model, we only support complete trees
  136. if(create.mSettings.mLimit!=1) return SetIceError("OPCODE WARNING: supports complete trees only! Use mLimit = 1.\n", null);
  137. // Look for degenerate faces.
  138. //udword NbDegenerate = create.mIMesh->CheckTopology();
  139. //if(NbDegenerate) Log("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate);
  140. // We continue nonetheless....
  141. Release(); // Make sure previous tree has been discarded [Opcode 1.3, thanks Adam]
  142. // 1-1) Setup mesh interface automatically [Opcode 1.3]
  143. SetMeshInterface(create.mIMesh);
  144. // Special case for 1-triangle meshes [Opcode 1.3]
  145. udword NbTris = create.mIMesh->GetNbTriangles();
  146. if(NbTris==1)
  147. {
  148. // We don't need to actually create a tree here, since we'll only have a single triangle to deal with anyway.
  149. // It's a waste to use a "model" for this but at least it will work.
  150. mModelCode |= OPC_SINGLE_NODE;
  151. return true;
  152. }
  153. // 2) Build a generic AABB Tree.
  154. mSource = new AABBTree;
  155. CHECKALLOC(mSource);
  156. // 2-1) Setup a builder. Our primitives here are triangles from input mesh,
  157. // so we use an AABBTreeOfTrianglesBuilder.....
  158. {
  159. AABBTreeOfTrianglesBuilder TB;
  160. TB.mIMesh = create.mIMesh;
  161. TB.mSettings = create.mSettings;
  162. TB.mNbPrimitives = NbTris;
  163. if(!mSource->Build(&TB)) return false;
  164. }
  165. // 3) Create an optimized tree according to user-settings
  166. if(!CreateTree(create.mNoLeaf, create.mQuantized)) return false;
  167. // 3-2) Create optimized tree
  168. if(!mTree->Build(mSource)) return false;
  169. // 3-3) Delete generic tree if needed
  170. if(!create.mKeepOriginal) DELETESINGLE(mSource);
  171. #ifdef __MESHMERIZER_H__
  172. // 4) Convex hull
  173. if(create.mCollisionHull)
  174. {
  175. // Create hull
  176. mHull = new CollisionHull;
  177. CHECKALLOC(mHull);
  178. CONVEXHULLCREATE CHC;
  179. // ### doesn't work with strides
  180. CHC.NbVerts = create.mIMesh->GetNbVertices();
  181. CHC.Vertices = create.mIMesh->GetVerts();
  182. CHC.UnifyNormals = true;
  183. CHC.ReduceVertices = true;
  184. CHC.WordFaces = false;
  185. mHull->Compute(CHC);
  186. }
  187. #endif // __MESHMERIZER_H__
  188. return true;
  189. }
  190. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  191. /**
  192. * Gets the number of bytes used by the tree.
  193. * \return amount of bytes used
  194. */
  195. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  196. udword Model::GetUsedBytes() const
  197. {
  198. if(!mTree) return 0;
  199. return mTree->GetUsedBytes();
  200. }