OPC_MeshInterface.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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 a mesh interface.
  11. * \file OPC_MeshInterface.h
  12. * \author Pierre Terdiman
  13. * \date November, 27, 2002
  14. */
  15. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  16. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. // Include Guard
  18. #ifndef __OPC_MESHINTERFACE_H__
  19. #define __OPC_MESHINTERFACE_H__
  20. struct VertexPointers
  21. {
  22. const Point* Vertex[3];
  23. bool BackfaceCulling(const Point& source)
  24. {
  25. const Point& p0 = *Vertex[0];
  26. const Point& p1 = *Vertex[1];
  27. const Point& p2 = *Vertex[2];
  28. // Compute normal direction
  29. Point Normal = (p2 - p1)^(p0 - p1);
  30. // Backface culling
  31. return (Normal | (source - p0)) >= 0.0f;
  32. }
  33. };
  34. struct VertexPointersEx
  35. {
  36. VertexPointers vp;
  37. dTriIndex Index[3];
  38. };
  39. typedef Point ConversionArea[3];
  40. #ifdef OPC_USE_CALLBACKS
  41. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  42. /**
  43. * User-callback, called by OPCODE to request vertices from the app.
  44. * \param triangle_index [in] face index for which the system is requesting the vertices
  45. * \param triangle [out] triangle's vertices (must be provided by the user)
  46. * \param user_data [in] user-defined data from SetCallback()
  47. */
  48. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  49. typedef void (*RequestCallback) (udword triangle_index, VertexPointers& triangle, void* user_data);
  50. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  51. /**
  52. * User-callback, called by OPCODE to request vertex indices from the app.
  53. * \param triangle_index [in] face index for which the system is requesting the vertices
  54. * \param triangle [out] triangle's vertices with indices (must be provided by the user)
  55. * \param user_data [in] user-defined data from SetExCallback()
  56. */
  57. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. typedef void (*RequestExCallback) (udword triangle_index, VertexPointersEx& triangle, void* user_data);
  59. #endif
  60. class OPCODE_API MeshInterface
  61. {
  62. public:
  63. // Constructor / Destructor
  64. MeshInterface();
  65. ~MeshInterface();
  66. // Common settings
  67. inline_ udword GetNbTriangles() const { return mNbTris; }
  68. inline_ udword GetNbVertices() const { return mNbVerts; }
  69. inline_ void SetNbTriangles(udword nb) { mNbTris = nb; }
  70. inline_ void SetNbVertices(udword nb) { mNbVerts = nb; }
  71. #ifdef OPC_USE_CALLBACKS
  72. // Callback settings
  73. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  74. /**
  75. * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index.
  76. * \param callback [in] user-defined callback
  77. * \param user_data [in] user-defined data
  78. * \return true if success
  79. */
  80. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  81. bool SetCallback(RequestCallback callback, void* user_data);
  82. inline_ void* GetUserData() const { return mUserData; }
  83. inline_ RequestCallback GetCallback() const { return mObjCallback; }
  84. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  85. /**
  86. * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index.
  87. * \param callback [in] user-defined callback
  88. * \param user_data [in] user-defined data
  89. * \return true if success
  90. */
  91. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  92. bool SetExCallback(RequestExCallback callback, void* user_data);
  93. inline_ void* GetExUserData() const { return mExUserData; }
  94. inline_ RequestExCallback GetExCallback() const { return mObjExCallback; }
  95. #else
  96. // Pointers settings
  97. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  98. /**
  99. * Pointers control: setups object pointers. Must provide access to faces and vertices for a given object.
  100. * \param tris [in] pointer to triangles
  101. * \param verts [in] pointer to vertices
  102. * \return true if success
  103. */
  104. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  105. bool SetPointers(const IndexedTriangle* tris, const Point* verts);
  106. inline_ const IndexedTriangle* GetTris() const { return mTris; }
  107. inline_ const Point* GetVerts() const { return mVerts; }
  108. #ifdef OPC_USE_STRIDE
  109. // Strides settings
  110. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  111. /**
  112. * Strides control
  113. * \param tri_stride [in] size of a triangle in bytes. The first sizeof(IndexedTriangle) bytes are used to get vertex indices.
  114. * \param vertex_stride [in] size of a vertex in bytes. The first sizeof(Point) bytes are used to get vertex position.
  115. * \return true if success
  116. */
  117. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  118. bool SetStrides(udword tri_stride=sizeof(IndexedTriangle), udword vertex_stride=sizeof(Point));
  119. inline_ udword GetTriStride() const { return mTriStride; }
  120. inline_ udword GetVertexStride() const { return mVertexStride; }
  121. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  122. /**
  123. * Single/Double control
  124. * \param value [in] Indicates if mesh data is provided as array of \c single values. If \c false, data is expected to contain \c double elements.
  125. */
  126. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  127. inline_ void SetSingle(bool value)
  128. {
  129. mFetchTriangle = (value ? &MeshInterface::FetchTriangleFromSingles : &MeshInterface::FetchTriangleFromDoubles);
  130. mFetchExTriangle = (value ? &MeshInterface::FetchExTriangleFromSingles : &MeshInterface::FetchExTriangleFromDoubles);
  131. }
  132. #else
  133. inline_ bool SetStrides(udword tri_stride=sizeof(IndexedTriangle), udword vertex_stride=sizeof(Point)) { return true; }
  134. inline_ void SetSingle(bool value) {}
  135. inline_ udword GetTriStride() const { return sizeof(IndexedTriangle); }
  136. inline_ udword GetVertexStride() const { return sizeof(Point); }
  137. #endif
  138. #endif
  139. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  140. /**
  141. * Fetches a triangle given a triangle index.
  142. * \param vp [out] required triangle's vertex pointers
  143. * \param index [in] triangle index
  144. * \param vc [in,out] storage required for data conversion (pass local variable with same scope as \a vp, as \a vp may point to this memory on return)
  145. */
  146. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  147. inline_ void GetTriangle(VertexPointers& vp, udword index, ConversionArea vc) const
  148. {
  149. #ifdef OPC_USE_CALLBACKS
  150. (mObjCallback)(index, vp, mUserData);
  151. #else
  152. #ifdef OPC_USE_STRIDE
  153. // Since there was conditional statement "if (Single)" which was unpredictable for compiler
  154. // and required both branches to be always generated what made inlining a questionable
  155. // benefit, I consider it better to introduce a forced call
  156. // but get rig of branching and dead code injection.
  157. ((*this).*mFetchTriangle)(vp, index, vc);
  158. #else
  159. const Point* Verts = GetVerts();
  160. const IndexedTriangle* T = &mTris[index];
  161. vp.Vertex[0] = &Verts[T->mVRef[0]];
  162. vp.Vertex[1] = &Verts[T->mVRef[1]];
  163. vp.Vertex[2] = &Verts[T->mVRef[2]];
  164. #endif
  165. #endif
  166. }
  167. inline_ bool GetExTriangle(VertexPointersEx& vpe, udword index, ConversionArea vc) const
  168. {
  169. #ifdef OPC_USE_CALLBACKS
  170. if (mObjExCallback) { (mObjExCallback)(index, vpe, mUserData); return true; }
  171. else { (mObjCallback)(index, vpe.vp, mUserData); return false; }
  172. #else
  173. #ifdef OPC_USE_STRIDE
  174. // Since there was conditional statement "if (Single)" which was unpredictable for compiler
  175. // and required both branches to be always generated what made inlining a questionable
  176. // benefit, I consider it better to introduce a forced call
  177. // but get rig of branching and dead code injection.
  178. ((*this).*mFetchExTriangle)(vpe, index, vc);
  179. return true;
  180. #else
  181. const Point* Verts = GetVerts();
  182. const IndexedTriangle* T = &mTris[index];
  183. dTriIndex VertIndex0 = T->mVRef[0];
  184. vpe.Index[0] = VertIndex0;
  185. vpe.vp.Vertex[0] = &Verts[VertIndex0];
  186. dTriIndex VertIndex1 = T->mVRef[1];
  187. vpe.Index[1] = VertIndex1;
  188. vpe.vp.Vertex[1] = &Verts[VertIndex1];
  189. dTriIndex VertIndex2 = T->mVRef[2];
  190. vpe.Index[2] = VertIndex2;
  191. vpe.vp.Vertex[2] = &Verts[VertIndex2];
  192. return true;
  193. #endif
  194. #endif
  195. }
  196. private:
  197. #ifndef OPC_USE_CALLBACKS
  198. #ifdef OPC_USE_STRIDE
  199. void FetchTriangleFromSingles(VertexPointers& vp, udword index, ConversionArea vc) const;
  200. void FetchTriangleFromDoubles(VertexPointers& vp, udword index, ConversionArea vc) const;
  201. void FetchExTriangleFromSingles(VertexPointersEx& vpe, udword index, ConversionArea vc) const;
  202. void FetchExTriangleFromDoubles(VertexPointersEx& vpe, udword index, ConversionArea vc) const;
  203. #endif
  204. #endif
  205. public:
  206. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  207. /**
  208. * Remaps client's mesh according to a permutation.
  209. * \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles)
  210. * \param permutation [in] list of triangle indices
  211. * \return true if success
  212. */
  213. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  214. bool RemapClient(udword nb_indices, const dTriIndex* permutation) const;
  215. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  216. /**
  217. * Checks the mesh interface is valid, i.e. things have been setup correctly.
  218. * \return true if valid
  219. */
  220. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  221. bool IsValid() const;
  222. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  223. /**
  224. * Checks the mesh itself is valid.
  225. * Currently we only look for degenerate faces.
  226. * \return number of degenerate faces
  227. */
  228. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  229. udword CheckTopology() const;
  230. private:
  231. udword mNbTris; //!< Number of triangles in the input model
  232. udword mNbVerts; //!< Number of vertices in the input model
  233. #ifdef OPC_USE_CALLBACKS
  234. // User callback
  235. void* mUserData; //!< User-defined data sent to callback
  236. RequestCallback mObjCallback; //!< Object callback
  237. void* mExUserData; //!< User-defined data sent to ex-callback
  238. RequestExCallback mObjExCallback; //!< Object ex-callback
  239. #else
  240. // User pointers
  241. #ifdef OPC_USE_STRIDE
  242. udword mTriStride; //!< Possible triangle stride in bytes [Opcode 1.3]
  243. udword mVertexStride; //!< Possible vertex stride in bytes [Opcode 1.3]
  244. typedef void (MeshInterface:: *TriangleFetchProc)(VertexPointers& vp, udword index, ConversionArea vc) const;
  245. TriangleFetchProc mFetchTriangle;
  246. typedef void (MeshInterface:: *ExTriangleFetchProc)(VertexPointersEx& vpe, udword index, ConversionArea vc) const;
  247. ExTriangleFetchProc mFetchExTriangle;
  248. #endif
  249. const IndexedTriangle* mTris; //!< Array of indexed triangles
  250. const Point* mVerts; //!< Array of vertices
  251. #endif
  252. };
  253. #endif //__OPC_MESHINTERFACE_H__