Cosmetic: Premake script fixed to avoid adding outest.cpp to the project being generated
[ode.git] / OPCODE / OPC_MeshInterface.h
blobc40494811d7114887e978c4ec62dd4954711f947
1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 /*
3 * OPCODE - Optimized Collision Detection
4 * Copyright (C) 2001 Pierre Terdiman
5 * Homepage: http://www.codercorner.com/Opcode.htm
6 */
7 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10 /**
11 * Contains a mesh interface.
12 * \file OPC_MeshInterface.h
13 * \author Pierre Terdiman
14 * \date November, 27, 2002
16 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 // Include Guard
20 #ifndef __OPC_MESHINTERFACE_H__
21 #define __OPC_MESHINTERFACE_H__
23 struct VertexPointers
25 const Point* Vertex[3];
27 bool BackfaceCulling(const Point& source)
29 const Point& p0 = *Vertex[0];
30 const Point& p1 = *Vertex[1];
31 const Point& p2 = *Vertex[2];
33 // Compute normal direction
34 Point Normal = (p2 - p1)^(p0 - p1);
36 // Backface culling
37 return (Normal | (source - p0)) >= 0.0f;
41 struct VertexPointersEx
43 VertexPointers vp;
44 dTriIndex Index[3];
47 typedef Point ConversionArea[3];
49 #ifdef OPC_USE_CALLBACKS
50 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
51 /**
52 * User-callback, called by OPCODE to request vertices 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 (must be provided by the user)
55 * \param user_data [in] user-defined data from SetCallback()
57 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
58 typedef void (*RequestCallback) (udword triangle_index, VertexPointers& triangle, void* user_data);
60 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
61 /**
62 * User-callback, called by OPCODE to request vertex indices from the app.
63 * \param triangle_index [in] face index for which the system is requesting the vertices
64 * \param triangle [out] triangle's vertices with indices (must be provided by the user)
65 * \param user_data [in] user-defined data from SetExCallback()
67 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
68 typedef void (*RequestExCallback) (udword triangle_index, VertexPointersEx& triangle, void* user_data);
69 #endif
71 class OPCODE_API MeshInterface
73 public:
74 // Constructor / Destructor
75 MeshInterface();
76 ~MeshInterface();
77 // Common settings
78 inline_ udword GetNbTriangles() const { return mNbTris; }
79 inline_ udword GetNbVertices() const { return mNbVerts; }
80 inline_ void SetNbTriangles(udword nb) { mNbTris = nb; }
81 inline_ void SetNbVertices(udword nb) { mNbVerts = nb; }
83 #ifdef OPC_USE_CALLBACKS
84 // Callback settings
86 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
87 /**
88 * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index.
89 * \param callback [in] user-defined callback
90 * \param user_data [in] user-defined data
91 * \return true if success
93 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
94 bool SetCallback(RequestCallback callback, void* user_data);
95 inline_ void* GetUserData() const { return mUserData; }
96 inline_ RequestCallback GetCallback() const { return mObjCallback; }
98 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
99 /**
100 * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index.
101 * \param callback [in] user-defined callback
102 * \param user_data [in] user-defined data
103 * \return true if success
105 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
106 bool SetExCallback(RequestExCallback callback, void* user_data);
107 inline_ void* GetExUserData() const { return mExUserData; }
108 inline_ RequestExCallback GetExCallback() const { return mObjExCallback; }
109 #else
110 // Pointers settings
112 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
114 * Pointers control: setups object pointers. Must provide access to faces and vertices for a given object.
115 * \param tris [in] pointer to triangles
116 * \param verts [in] pointer to vertices
117 * \return true if success
119 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
120 bool SetPointers(const IndexedTriangle* tris, const Point* verts);
121 inline_ const IndexedTriangle* GetTris() const { return mTris; }
122 inline_ const Point* GetVerts() const { return mVerts; }
124 #ifdef OPC_USE_STRIDE
125 // Strides settings
127 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
129 * Strides control
130 * \param tri_stride [in] size of a triangle in bytes. The first sizeof(IndexedTriangle) bytes are used to get vertex indices.
131 * \param vertex_stride [in] size of a vertex in bytes. The first sizeof(Point) bytes are used to get vertex position.
132 * \return true if success
134 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
135 bool SetStrides(udword tri_stride=sizeof(IndexedTriangle), udword vertex_stride=sizeof(Point));
136 inline_ udword GetTriStride() const { return mTriStride; }
137 inline_ udword GetVertexStride() const { return mVertexStride; }
139 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
141 * Single/Double control
142 * \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.
144 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
145 inline_ void SetSingle(bool value)
147 mFetchTriangle = (value ? &MeshInterface::FetchTriangleFromSingles : &MeshInterface::FetchTriangleFromDoubles);
148 mFetchExTriangle = (value ? &MeshInterface::FetchExTriangleFromSingles : &MeshInterface::FetchExTriangleFromDoubles);
151 #else
152 inline_ bool SetStrides(udword tri_stride=sizeof(IndexedTriangle), udword vertex_stride=sizeof(Point)) { return true; }
153 inline_ void SetSingle(bool value) {}
154 inline_ udword GetTriStride() const { return sizeof(IndexedTriangle); }
155 inline_ udword GetVertexStride() const { return sizeof(Point); }
156 #endif
157 #endif
159 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
161 * Fetches a triangle given a triangle index.
162 * \param vp [out] required triangle's vertex pointers
163 * \param index [in] triangle index
164 * \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)
166 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
167 inline_ void GetTriangle(VertexPointers& vp, udword index, ConversionArea vc) const
169 #ifdef OPC_USE_CALLBACKS
170 (mObjCallback)(index, vp, mUserData);
171 #else
172 #ifdef OPC_USE_STRIDE
173 // Since there was conditional statement "if (Single)" which was unpredictable for compiler
174 // and required both branches to be always generated what made inlining a questionable
175 // benefit, I consider it better to introduce a forced call
176 // but get rig of branching and dead code injection.
177 ((*this).*mFetchTriangle)(vp, index, vc);
178 #else
179 const Point* Verts = GetVerts();
180 const IndexedTriangle* T = &mTris[index];
181 vp.Vertex[0] = &Verts[T->mVRef[0]];
182 vp.Vertex[1] = &Verts[T->mVRef[1]];
183 vp.Vertex[2] = &Verts[T->mVRef[2]];
184 #endif
185 #endif
188 inline_ bool GetExTriangle(VertexPointersEx& vpe, udword index, ConversionArea vc) const
190 #ifdef OPC_USE_CALLBACKS
191 if (mObjExCallback) { (mObjExCallback)(index, vpe, mUserData); return true; }
192 else { (mObjCallback)(index, vpe.vp, mUserData); return false; }
193 #else
194 #ifdef OPC_USE_STRIDE
195 // Since there was conditional statement "if (Single)" which was unpredictable for compiler
196 // and required both branches to be always generated what made inlining a questionable
197 // benefit, I consider it better to introduce a forced call
198 // but get rig of branching and dead code injection.
199 ((*this).*mFetchExTriangle)(vpe, index, vc);
200 return true;
201 #else
202 const Point* Verts = GetVerts();
203 const IndexedTriangle* T = &mTris[index];
204 dTriIndex VertIndex0 = T->mVRef[0];
205 vpe.Index[0] = VertIndex0;
206 vpe.vp.Vertex[0] = &Verts[VertIndex0];
207 dTriIndex VertIndex1 = T->mVRef[1];
208 vpe.Index[1] = VertIndex1;
209 vpe.vp.Vertex[1] = &Verts[VertIndex1];
210 dTriIndex VertIndex2 = T->mVRef[2];
211 vpe.Index[2] = VertIndex2;
212 vpe.vp.Vertex[2] = &Verts[VertIndex2];
213 return true;
214 #endif
215 #endif
218 private:
219 #ifndef OPC_USE_CALLBACKS
220 #ifdef OPC_USE_STRIDE
221 void FetchTriangleFromSingles(VertexPointers& vp, udword index, ConversionArea vc) const;
222 void FetchTriangleFromDoubles(VertexPointers& vp, udword index, ConversionArea vc) const;
223 void FetchExTriangleFromSingles(VertexPointersEx& vpe, udword index, ConversionArea vc) const;
224 void FetchExTriangleFromDoubles(VertexPointersEx& vpe, udword index, ConversionArea vc) const;
225 #endif
226 #endif
228 public:
229 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
231 * Remaps client's mesh according to a permutation.
232 * \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles)
233 * \param permutation [in] list of triangle indices
234 * \return true if success
236 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
237 bool RemapClient(udword nb_indices, const dTriIndex* permutation) const;
239 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
241 * Checks the mesh interface is valid, i.e. things have been setup correctly.
242 * \return true if valid
244 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
245 bool IsValid() const;
247 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
249 * Checks the mesh itself is valid.
250 * Currently we only look for degenerate faces.
251 * \return number of degenerate faces
253 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
254 udword CheckTopology() const;
255 private:
257 udword mNbTris; //!< Number of triangles in the input model
258 udword mNbVerts; //!< Number of vertices in the input model
259 #ifdef OPC_USE_CALLBACKS
260 // User callback
261 void* mUserData; //!< User-defined data sent to callback
262 RequestCallback mObjCallback; //!< Object callback
263 void* mExUserData; //!< User-defined data sent to ex-callback
264 RequestExCallback mObjExCallback; //!< Object ex-callback
265 #else
266 // User pointers
267 #ifdef OPC_USE_STRIDE
268 udword mTriStride; //!< Possible triangle stride in bytes [Opcode 1.3]
269 udword mVertexStride; //!< Possible vertex stride in bytes [Opcode 1.3]
270 typedef void (MeshInterface:: *TriangleFetchProc)(VertexPointers& vp, udword index, ConversionArea vc) const;
271 TriangleFetchProc mFetchTriangle;
272 typedef void (MeshInterface:: *ExTriangleFetchProc)(VertexPointersEx& vpe, udword index, ConversionArea vc) const;
273 ExTriangleFetchProc mFetchExTriangle;
274 #endif
275 const IndexedTriangle* mTris; //!< Array of indexed triangles
276 const Point* mVerts; //!< Array of vertices
277 #endif
280 #endif //__OPC_MESHINTERFACE_H__