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 | /** |
---|
11 | * Contains a mesh interface. |
---|
12 | * \file OPC_MeshInterface.h |
---|
13 | * \author Pierre Terdiman |
---|
14 | * \date November, 27, 2002 |
---|
15 | */ |
---|
16 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
17 | |
---|
18 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
19 | // Include Guard |
---|
20 | #ifndef __OPC_MESHINTERFACE_H__ |
---|
21 | #define __OPC_MESHINTERFACE_H__ |
---|
22 | |
---|
23 | struct VertexPointers |
---|
24 | { |
---|
25 | const Point* Vertex[3]; |
---|
26 | |
---|
27 | bool BackfaceCulling(const Point& source) |
---|
28 | { |
---|
29 | const Point& p0 = *Vertex[0]; |
---|
30 | const Point& p1 = *Vertex[1]; |
---|
31 | const Point& p2 = *Vertex[2]; |
---|
32 | |
---|
33 | // Compute normal direction |
---|
34 | Point Normal = (p2 - p1)^(p0 - p1); |
---|
35 | |
---|
36 | // Backface culling |
---|
37 | return (Normal | (source - p0)) >= 0.0f; |
---|
38 | } |
---|
39 | }; |
---|
40 | |
---|
41 | #ifdef OPC_USE_CALLBACKS |
---|
42 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
43 | /** |
---|
44 | * User-callback, called by OPCODE to request vertices from the app. |
---|
45 | * \param triangle_index [in] face index for which the system is requesting the vertices |
---|
46 | * \param triangle [out] triangle's vertices (must be provided by the user) |
---|
47 | * \param user_data [in] user-defined data from SetCallback() |
---|
48 | */ |
---|
49 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
50 | typedef void (*RequestCallback) (udword triangle_index, VertexPointers& triangle, void* user_data); |
---|
51 | #endif |
---|
52 | |
---|
53 | class OPCODE_API MeshInterface |
---|
54 | { |
---|
55 | public: |
---|
56 | // Constructor / Destructor |
---|
57 | MeshInterface(); |
---|
58 | ~MeshInterface(); |
---|
59 | // Common settings |
---|
60 | inline_ udword GetNbTriangles() const { return mNbTris; } |
---|
61 | inline_ udword GetNbVertices() const { return mNbVerts; } |
---|
62 | inline_ void SetNbTriangles(udword nb) { mNbTris = nb; } |
---|
63 | inline_ void SetNbVertices(udword nb) { mNbVerts = nb; } |
---|
64 | |
---|
65 | #ifdef OPC_USE_CALLBACKS |
---|
66 | // Callback settings |
---|
67 | |
---|
68 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
69 | /** |
---|
70 | * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index. |
---|
71 | * \param callback [in] user-defined callback |
---|
72 | * \param user_data [in] user-defined data |
---|
73 | * \return true if success |
---|
74 | */ |
---|
75 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
76 | bool SetCallback(RequestCallback callback, void* user_data); |
---|
77 | inline_ void* GetUserData() const { return mUserData; } |
---|
78 | inline_ RequestCallback GetCallback() const { return mObjCallback; } |
---|
79 | #else |
---|
80 | // Pointers settings |
---|
81 | |
---|
82 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
83 | /** |
---|
84 | * Pointers control: setups object pointers. Must provide access to faces and vertices for a given object. |
---|
85 | * \param tris [in] pointer to triangles |
---|
86 | * \param verts [in] pointer to vertices |
---|
87 | * \return true if success |
---|
88 | */ |
---|
89 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
90 | bool SetPointers(const IndexedTriangle* tris, const Point* verts); |
---|
91 | inline_ const IndexedTriangle* GetTris() const { return mTris; } |
---|
92 | inline_ const Point* GetVerts() const { return mVerts; } |
---|
93 | |
---|
94 | #ifdef OPC_USE_STRIDE |
---|
95 | // Strides settings |
---|
96 | |
---|
97 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
98 | /** |
---|
99 | * Strides control |
---|
100 | * \param tri_stride [in] size of a triangle in bytes. The first sizeof(IndexedTriangle) bytes are used to get vertex indices. |
---|
101 | * \param vertex_stride [in] size of a vertex in bytes. The first sizeof(Point) bytes are used to get vertex position. |
---|
102 | * \return true if success |
---|
103 | */ |
---|
104 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
105 | bool SetStrides(udword tri_stride=sizeof(IndexedTriangle), udword vertex_stride=sizeof(Point)); |
---|
106 | inline_ udword GetTriStride() const { return mTriStride; } |
---|
107 | inline_ udword GetVertexStride() const { return mVertexStride; } |
---|
108 | #endif |
---|
109 | #endif |
---|
110 | |
---|
111 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
112 | /** |
---|
113 | * Fetches a triangle given a triangle index. |
---|
114 | * \param vp [out] required triangle's vertex pointers |
---|
115 | * \param index [in] triangle index |
---|
116 | */ |
---|
117 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
118 | inline_ void GetTriangle(VertexPointers& vp, udword index) const |
---|
119 | { |
---|
120 | #ifdef OPC_USE_CALLBACKS |
---|
121 | (mObjCallback)(index, vp, mUserData); |
---|
122 | #else |
---|
123 | #ifdef OPC_USE_STRIDE |
---|
124 | const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + index * mTriStride); |
---|
125 | |
---|
126 | if (Single){ |
---|
127 | vp.Vertex[0] = (const Point*)(((ubyte*)mVerts) + T->mVRef[0] * mVertexStride); |
---|
128 | vp.Vertex[1] = (const Point*)(((ubyte*)mVerts) + T->mVRef[1] * mVertexStride); |
---|
129 | vp.Vertex[2] = (const Point*)(((ubyte*)mVerts) + T->mVRef[2] * mVertexStride); |
---|
130 | } |
---|
131 | else{ |
---|
132 | for (int i = 0; i < 3; i++){ |
---|
133 | const double* v = (const double*)(((ubyte*)mVerts) + T->mVRef[i] * mVertexStride); |
---|
134 | |
---|
135 | VertexCache[i].x = (float)v[0]; |
---|
136 | VertexCache[i].y = (float)v[1]; |
---|
137 | VertexCache[i].z = (float)v[2]; |
---|
138 | vp.Vertex[i] = &VertexCache[i]; |
---|
139 | } |
---|
140 | } |
---|
141 | #else |
---|
142 | const IndexedTriangle* T = &mTris[index]; |
---|
143 | vp.Vertex[0] = &mVerts[T->mVRef[0]]; |
---|
144 | vp.Vertex[1] = &mVerts[T->mVRef[1]]; |
---|
145 | vp.Vertex[2] = &mVerts[T->mVRef[2]]; |
---|
146 | #endif |
---|
147 | #endif |
---|
148 | } |
---|
149 | |
---|
150 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
151 | /** |
---|
152 | * Remaps client's mesh according to a permutation. |
---|
153 | * \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles) |
---|
154 | * \param permutation [in] list of triangle indices |
---|
155 | * \return true if success |
---|
156 | */ |
---|
157 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
158 | bool RemapClient(udword nb_indices, const udword* permutation) const; |
---|
159 | |
---|
160 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
161 | /** |
---|
162 | * Checks the mesh interface is valid, i.e. things have been setup correctly. |
---|
163 | * \return true if valid |
---|
164 | */ |
---|
165 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
166 | bool IsValid() const; |
---|
167 | |
---|
168 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
169 | /** |
---|
170 | * Checks the mesh itself is valid. |
---|
171 | * Currently we only look for degenerate faces. |
---|
172 | * \return number of degenerate faces |
---|
173 | */ |
---|
174 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
175 | udword CheckTopology() const; |
---|
176 | private: |
---|
177 | |
---|
178 | udword mNbTris; //!< Number of triangles in the input model |
---|
179 | udword mNbVerts; //!< Number of vertices in the input model |
---|
180 | #ifdef OPC_USE_CALLBACKS |
---|
181 | // User callback |
---|
182 | void* mUserData; //!< User-defined data sent to callback |
---|
183 | RequestCallback mObjCallback; //!< Object callback |
---|
184 | #else |
---|
185 | // User pointers |
---|
186 | const IndexedTriangle* mTris; //!< Array of indexed triangles |
---|
187 | const Point* mVerts; //!< Array of vertices |
---|
188 | #ifdef OPC_USE_STRIDE |
---|
189 | udword mTriStride; //!< Possible triangle stride in bytes [Opcode 1.3] |
---|
190 | udword mVertexStride; //!< Possible vertex stride in bytes [Opcode 1.3] |
---|
191 | #endif |
---|
192 | public: |
---|
193 | bool Single; //!< Use single or double precision vertices |
---|
194 | private: |
---|
195 | static Point VertexCache[3]; |
---|
196 | #endif |
---|
197 | }; |
---|
198 | |
---|
199 | #endif //__OPC_MESHINTERFACE_H__ |
---|