aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/OPCODE/OPC_MeshInterface.cpp
diff options
context:
space:
mode:
authordan miller2007-10-19 05:24:38 +0000
committerdan miller2007-10-19 05:24:38 +0000
commitf205de7847da7ae1c10212d82e7042d0100b4ce0 (patch)
tree9acc9608a6880502aaeda43af52c33e278e95b9c /libraries/ode-0.9/OPCODE/OPC_MeshInterface.cpp
parenttrying to fix my screwup part deux (diff)
downloadopensim-SC_OLD-f205de7847da7ae1c10212d82e7042d0100b4ce0.zip
opensim-SC_OLD-f205de7847da7ae1c10212d82e7042d0100b4ce0.tar.gz
opensim-SC_OLD-f205de7847da7ae1c10212d82e7042d0100b4ce0.tar.bz2
opensim-SC_OLD-f205de7847da7ae1c10212d82e7042d0100b4ce0.tar.xz
from the start... checking in ode-0.9
Diffstat (limited to 'libraries/ode-0.9/OPCODE/OPC_MeshInterface.cpp')
-rw-r--r--libraries/ode-0.9/OPCODE/OPC_MeshInterface.cpp303
1 files changed, 303 insertions, 0 deletions
diff --git a/libraries/ode-0.9/OPCODE/OPC_MeshInterface.cpp b/libraries/ode-0.9/OPCODE/OPC_MeshInterface.cpp
new file mode 100644
index 0000000..b962764
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/OPC_MeshInterface.cpp
@@ -0,0 +1,303 @@
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.cpp
13 * \author Pierre Terdiman
14 * \date November, 27, 2002
15 */
16///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17
18///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19/**
20 * This structure holds 3 vertex-pointers. It's mainly used by collision callbacks so that the app doesn't have
21 * to return 3 vertices to OPCODE (36 bytes) but only 3 pointers (12 bytes). It seems better but I never profiled
22 * the alternative.
23 *
24 * \class VertexPointers
25 * \author Pierre Terdiman
26 * \version 1.3
27 * \date March, 20, 2001
28*/
29///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30
31///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32/**
33 * This class is an interface between us and user-defined meshes. Meshes can be defined in a lot of ways, and here we
34 * try to support most of them.
35 *
36 * Basically you have two options:
37 * - callbacks, if OPC_USE_CALLBACKS is defined in OPC_Settings.h.
38 * - else pointers.
39 *
40 * If using pointers, you can also use strides or not. Strides are used when OPC_USE_STRIDE is defined.
41 *
42 *
43 * CALLBACKS:
44 *
45 * Using callbacks is the most generic way to feed OPCODE with your meshes. Indeed, you just have to give
46 * access to three vertices at the end of the day. It's up to you to fetch them from your database, using
47 * whatever method you want. Hence your meshes can lie in system memory or AGP, be indexed or not, use 16
48 * or 32-bits indices, you can decompress them on-the-fly if needed, etc. On the other hand, a callback is
49 * called each time OPCODE needs access to a particular triangle, so there might be a slight overhead.
50 *
51 * To make things clear: geometry & topology are NOT stored in the collision system,
52 * in order to save some ram. So, when the system needs them to perform accurate intersection
53 * tests, you're requested to provide the triangle-vertices corresponding to a given face index.
54 *
55 * Ex:
56 *
57 * \code
58 * static void ColCallback(udword triangle_index, VertexPointers& triangle, udword user_data)
59 * {
60 * // Get back Mesh0 or Mesh1 (you also can use 2 different callbacks)
61 * Mesh* MyMesh = (Mesh*)user_data;
62 * // Get correct triangle in the app-controlled database
63 * const Triangle* Tri = MyMesh->GetTriangle(triangle_index);
64 * // Setup pointers to vertices for the collision system
65 * triangle.Vertex[0] = MyMesh->GetVertex(Tri->mVRef[0]);
66 * triangle.Vertex[1] = MyMesh->GetVertex(Tri->mVRef[1]);
67 * triangle.Vertex[2] = MyMesh->GetVertex(Tri->mVRef[2]);
68 * }
69 *
70 * // Setup callbacks
71 * MeshInterface0->SetCallback(ColCallback, udword(Mesh0));
72 * MeshInterface1->SetCallback(ColCallback, udword(Mesh1));
73 * \endcode
74 *
75 * Of course, you should make this callback as fast as possible. And you're also not supposed
76 * to modify the geometry *after* the collision trees have been built. The alternative was to
77 * store the geometry & topology in the collision system as well (as in RAPID) but we have found
78 * this approach to waste a lot of ram in many cases.
79 *
80 *
81 * POINTERS:
82 *
83 * If you're internally using the following canonical structures:
84 * - a vertex made of three 32-bits floating point values
85 * - a triangle made of three 32-bits integer vertex references
86 * ...then you may want to use pointers instead of callbacks. This is the same, except OPCODE will directly
87 * use provided pointers to access the topology and geometry, without using a callback. It might be faster,
88 * but probably not as safe. Pointers have been introduced in OPCODE 1.2.
89 *
90 * Ex:
91 *
92 * \code
93 * // Setup pointers
94 * MeshInterface0->SetPointers(Mesh0->GetFaces(), Mesh0->GetVerts());
95 * MeshInterface1->SetPointers(Mesh1->GetFaces(), Mesh1->GetVerts());
96 * \endcode
97 *
98 *
99 * STRIDES:
100 *
101 * If your vertices are D3D-like entities interleaving a position, a normal and/or texture coordinates
102 * (i.e. if your vertices are FVFs), you might want to use a vertex stride to skip extra data OPCODE
103 * doesn't need. Using a stride shouldn't be notably slower than not using it, but it might increase
104 * cache misses. Please also note that you *shouldn't* read from AGP or video-memory buffers !
105 *
106 *
107 * In any case, compilation flags are here to select callbacks/pointers/strides at compile time, so
108 * choose what's best for your application. All of this has been wrapped into this MeshInterface.
109 *
110 * \class MeshInterface
111 * \author Pierre Terdiman
112 * \version 1.3
113 * \date November, 27, 2002
114*/
115///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
116
117///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
118// Precompiled Header
119#include "Stdafx.h"
120
121using namespace Opcode;
122
123Point MeshInterface::VertexCache[3];
124
125///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
126/**
127 * Constructor.
128 */
129///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
130MeshInterface::MeshInterface() :
131#ifdef OPC_USE_CALLBACKS
132 mUserData (null),
133 mObjCallback (null),
134#else
135 mTris (null),
136 mVerts (null),
137 #ifdef OPC_USE_STRIDE
138 mTriStride (sizeof(IndexedTriangle)),
139 mVertexStride (sizeof(Point)),
140 #endif
141#endif
142 mNbTris (0),
143 mNbVerts (0),
144
145 Single(true)
146{
147}
148
149///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
150/**
151 * Destructor.
152 */
153///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
154MeshInterface::~MeshInterface()
155{
156}
157
158///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
159/**
160 * Checks the mesh interface is valid, i.e. things have been setup correctly.
161 * \return true if valid
162 */
163///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
164bool MeshInterface::IsValid() const
165{
166 if(!mNbTris || !mNbVerts) return false;
167#ifdef OPC_USE_CALLBACKS
168 if(!mObjCallback) return false;
169#else
170 if(!mTris || !mVerts) return false;
171#endif
172 return true;
173}
174
175///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
176/**
177 * Checks the mesh itself is valid.
178 * Currently we only look for degenerate faces.
179 * \return number of degenerate faces
180 */
181///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
182udword MeshInterface::CheckTopology() const
183{
184 // Check topology. If the model contains degenerate faces, collision report can be wrong in some cases.
185 // e.g. it happens with the standard MAX teapot. So clean your meshes first... If you don't have a mesh cleaner
186 // you can try this: www.codercorner.com/Consolidation.zip
187
188 udword NbDegenerate = 0;
189
190 VertexPointers VP;
191
192 // Using callbacks, we don't have access to vertex indices. Nevertheless we still can check for
193 // redundant vertex pointers, which cover all possibilities (callbacks/pointers/strides).
194 for(udword i=0;i<mNbTris;i++)
195 {
196 GetTriangle(VP, i);
197
198 if( (VP.Vertex[0]==VP.Vertex[1])
199 || (VP.Vertex[1]==VP.Vertex[2])
200 || (VP.Vertex[2]==VP.Vertex[0])) NbDegenerate++;
201 }
202
203 return NbDegenerate;
204}
205
206#ifdef OPC_USE_CALLBACKS
207///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
208/**
209 * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index.
210 * \param callback [in] user-defined callback
211 * \param user_data [in] user-defined data
212 * \return true if success
213 */
214///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
215bool MeshInterface::SetCallback(RequestCallback callback, void* user_data)
216{
217 if(!callback) return SetIceError("MeshInterface::SetCallback: callback pointer is null");
218
219 mObjCallback = callback;
220 mUserData = user_data;
221 return true;
222}
223#else
224///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
225/**
226 * Pointers control: setups object pointers. Must provide access to faces and vertices for a given object.
227 * \param tris [in] pointer to triangles
228 * \param verts [in] pointer to vertices
229 * \return true if success
230 */
231///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
232bool MeshInterface::SetPointers(const IndexedTriangle* tris, const Point* verts)
233{
234 if(!tris || !verts) return SetIceError("MeshInterface::SetPointers: pointer is null", null);
235
236 mTris = tris;
237 mVerts = verts;
238 return true;
239}
240#ifdef OPC_USE_STRIDE
241///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
242/**
243 * Strides control
244 * \param tri_stride [in] size of a triangle in bytes. The first sizeof(IndexedTriangle) bytes are used to get vertex indices.
245 * \param vertex_stride [in] size of a vertex in bytes. The first sizeof(Point) bytes are used to get vertex position.
246 * \return true if success
247 */
248///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
249bool MeshInterface::SetStrides(udword tri_stride, udword vertex_stride)
250{
251 if(tri_stride<sizeof(IndexedTriangle)) return SetIceError("MeshInterface::SetStrides: invalid triangle stride", null);
252 if(vertex_stride<sizeof(Point)) return SetIceError("MeshInterface::SetStrides: invalid vertex stride", null);
253
254 mTriStride = tri_stride;
255 mVertexStride = vertex_stride;
256 return true;
257}
258#endif
259#endif
260
261///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
262/**
263 * Remaps client's mesh according to a permutation.
264 * \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles)
265 * \param permutation [in] list of triangle indices
266 * \return true if success
267 */
268///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
269bool MeshInterface::RemapClient(udword nb_indices, const udword* permutation) const
270{
271 // Checkings
272 if(!nb_indices || !permutation) return false;
273 if(nb_indices!=mNbTris) return false;
274
275#ifdef OPC_USE_CALLBACKS
276 // We can't really do that using callbacks
277 return false;
278#else
279 IndexedTriangle* Tmp = new IndexedTriangle[mNbTris];
280 CHECKALLOC(Tmp);
281
282 #ifdef OPC_USE_STRIDE
283 udword Stride = mTriStride;
284 #else
285 udword Stride = sizeof(IndexedTriangle);
286 #endif
287
288 for(udword i=0;i<mNbTris;i++)
289 {
290 const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + i * Stride);
291 Tmp[i] = *T;
292 }
293
294 for(udword i=0;i<mNbTris;i++)
295 {
296 IndexedTriangle* T = (IndexedTriangle*)(((ubyte*)mTris) + i * Stride);
297 *T = Tmp[permutation[i]];
298 }
299
300 DELETEARRAY(Tmp);
301#endif
302 return true;
303}