aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/ode/src/collision_trimesh_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ode-0.9/ode/src/collision_trimesh_internal.h')
-rw-r--r--libraries/ode-0.9/ode/src/collision_trimesh_internal.h495
1 files changed, 495 insertions, 0 deletions
diff --git a/libraries/ode-0.9/ode/src/collision_trimesh_internal.h b/libraries/ode-0.9/ode/src/collision_trimesh_internal.h
new file mode 100644
index 0000000..bf474a2
--- /dev/null
+++ b/libraries/ode-0.9/ode/src/collision_trimesh_internal.h
@@ -0,0 +1,495 @@
1/*************************************************************************
2 * *
3 * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
4 * All rights reserved. Email: russ@q12.org Web: www.q12.org *
5 * *
6 * This library is free software; you can redistribute it and/or *
7 * modify it under the terms of EITHER: *
8 * (1) The GNU Lesser General Public License as published by the Free *
9 * Software Foundation; either version 2.1 of the License, or (at *
10 * your option) any later version. The text of the GNU Lesser *
11 * General Public License is included with this library in the *
12 * file LICENSE.TXT. *
13 * (2) The BSD-style license that is included with this library in *
14 * the file LICENSE-BSD.TXT. *
15 * *
16 * This library is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
19 * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
20 * *
21 *************************************************************************/
22
23// TriMesh code by Erwin de Vries.
24// Modified for FreeSOLID Compatibility by Rodrigo Hernandez
25
26#ifndef _ODE_COLLISION_TRIMESH_INTERNAL_H_
27#define _ODE_COLLISION_TRIMESH_INTERNAL_H_
28
29int dCollideCylinderTrimesh(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
30int dCollideTrimeshPlane(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
31
32int dCollideSTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
33int dCollideBTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
34int dCollideRTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
35int dCollideTTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
36int dCollideCCTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
37
38PURE_INLINE int dCollideRayTrimesh( dxGeom *ray, dxGeom *trimesh, int flags,
39 dContactGeom *contact, int skip )
40{
41 // Swapped case, for code that needs it (heightfield initially)
42 // The other ray-geom colliders take geoms in a swapped order to the
43 // dCollideRTL function which is annoying when using function pointers.
44 return dCollideRTL( trimesh, ray, flags, contact, skip );
45}
46
47//****************************************************************************
48// dxTriMesh class
49
50#ifdef TRIMESH_INTERNAL
51
52#include "collision_kernel.h"
53#include <ode/collision_trimesh.h>
54
55#if dTRIMESH_OPCODE
56#define BAN_OPCODE_AUTOLINK
57#include "Opcode.h"
58using namespace Opcode;
59#endif // dTRIMESH_OPCODE
60
61#if dTRIMESH_GIMPACT
62#include <GIMPACT/gimpact.h>
63#endif
64
65struct dxTriMeshData : public dBase
66{
67 /* Array of flags for which edges and verts should be used on each triangle */
68 enum UseFlags
69 {
70 kEdge0 = 0x1,
71 kEdge1 = 0x2,
72 kEdge2 = 0x4,
73 kVert0 = 0x8,
74 kVert1 = 0x10,
75 kVert2 = 0x20,
76
77 kUseAll = 0xFF,
78 };
79
80 /* Setup the UseFlags array */
81 void Preprocess();
82 /* For when app changes the vertices */
83 void UpdateData();
84
85#if dTRIMESH_OPCODE
86 Model BVTree;
87 MeshInterface Mesh;
88
89 dxTriMeshData();
90 ~dxTriMeshData();
91
92 void Build(const void* Vertices, int VertexStide, int VertexCount,
93 const void* Indices, int IndexCount, int TriStride,
94 const void* Normals,
95 bool Single);
96
97 /* aabb in model space */
98 dVector3 AABBCenter;
99 dVector3 AABBExtents;
100
101 // data for use in collision resolution
102 const void* Normals;
103 uint8* UseFlags;
104#endif // dTRIMESH_OPCODE
105
106#if dTRIMESH_GIMPACT
107 const char* m_Vertices;
108 int m_VertexStride;
109 int m_VertexCount;
110 const char* m_Indices;
111 int m_TriangleCount;
112 int m_TriStride;
113 bool m_single;
114
115 dxTriMeshData()
116 {
117 m_Vertices=NULL;
118 m_VertexStride = 12;
119 m_VertexCount = 0;
120 m_Indices = 0;
121 m_TriangleCount = 0;
122 m_TriStride = 12;
123 m_single = true;
124 }
125
126 void Build(const void* Vertices, int VertexStride, int VertexCount,
127 const void* Indices, int IndexCount, int TriStride,
128 const void* Normals,
129 bool Single)
130 {
131 dIASSERT(Vertices);
132 dIASSERT(Indices);
133 dIASSERT(VertexStride);
134 dIASSERT(TriStride);
135 dIASSERT(IndexCount);
136 m_Vertices=(const char *)Vertices;
137 m_VertexStride = VertexStride;
138 m_VertexCount = VertexCount;
139 m_Indices = (const char *)Indices;
140 m_TriangleCount = IndexCount/3;
141 m_TriStride = TriStride;
142 m_single = Single;
143 }
144
145 inline void GetVertex(unsigned int i, dVector3 Out)
146 {
147 if(m_single)
148 {
149 const float * fverts = (const float * )(m_Vertices + m_VertexStride*i);
150 Out[0] = fverts[0];
151 Out[1] = fverts[1];
152 Out[2] = fverts[2];
153 Out[3] = 1.0f;
154 }
155 else
156 {
157 const double * dverts = (const double * )(m_Vertices + m_VertexStride*i);
158 Out[0] = (float)dverts[0];
159 Out[1] = (float)dverts[1];
160 Out[2] = (float)dverts[2];
161 Out[3] = 1.0f;
162
163 }
164 }
165
166 inline void GetTriIndices(unsigned int itriangle, unsigned int triindices[3])
167 {
168 const unsigned int * ind = (const unsigned int * )(m_Indices + m_TriStride*itriangle);
169 triindices[0] = ind[0];
170 triindices[1] = ind[1];
171 triindices[2] = ind[2];
172 }
173#endif // dTRIMESH_GIMPACT
174};
175
176
177struct dxTriMesh : public dxGeom{
178 // Callbacks
179 dTriCallback* Callback;
180 dTriArrayCallback* ArrayCallback;
181 dTriRayCallback* RayCallback;
182
183 // Data types
184 dxTriMeshData* Data;
185
186 bool doSphereTC;
187 bool doBoxTC;
188 bool doCapsuleTC;
189
190 // Functions
191 dxTriMesh(dSpaceID Space, dTriMeshDataID Data);
192 ~dxTriMesh();
193
194 void ClearTCCache();
195
196 int AABBTest(dxGeom* g, dReal aabb[6]);
197 void computeAABB();
198
199#if dTRIMESH_OPCODE
200 // Instance data for last transform.
201 dMatrix4 last_trans;
202
203 // Colliders
204 static PlanesCollider _PlanesCollider;
205 static SphereCollider _SphereCollider;
206 static OBBCollider _OBBCollider;
207 static RayCollider _RayCollider;
208 static AABBTreeCollider _AABBTreeCollider;
209 static LSSCollider _LSSCollider;
210
211 // Some constants
212 static CollisionFaces Faces;
213 // Temporal coherence
214 struct SphereTC : public SphereCache{
215 dxGeom* Geom;
216 };
217 dArray<SphereTC> SphereTCCache;
218 static SphereCache defaultSphereCache;
219
220 struct BoxTC : public OBBCache{
221 dxGeom* Geom;
222 };
223 dArray<BoxTC> BoxTCCache;
224 static OBBCache defaultBoxCache;
225
226 struct CapsuleTC : public LSSCache{
227 dxGeom* Geom;
228 };
229 dArray<CapsuleTC> CapsuleTCCache;
230 static LSSCache defaultCapsuleCache;
231#endif // dTRIMESH_OPCODE
232
233#if dTRIMESH_GIMPACT
234 GIM_TRIMESH m_collision_trimesh;
235#endif // dTRIMESH_GIMPACT
236};
237
238#if 0
239#include "collision_kernel.h"
240// Fetches a contact
241inline dContactGeom* SAFECONTACT(int Flags, dContactGeom* Contacts, int Index, int Stride){
242 dIASSERT(Index >= 0 && Index < (Flags & NUMC_MASK));
243 return ((dContactGeom*)(((char*)Contacts) + (Index * Stride)));
244}
245#endif
246
247#if dTRIMESH_OPCODE
248inline void FetchTriangle(dxTriMesh* TriMesh, int Index, dVector3 Out[3]){
249 VertexPointers VP;
250 TriMesh->Data->Mesh.GetTriangle(VP, Index);
251 for (int i = 0; i < 3; i++){
252 Out[i][0] = VP.Vertex[i]->x;
253 Out[i][1] = VP.Vertex[i]->y;
254 Out[i][2] = VP.Vertex[i]->z;
255 Out[i][3] = 0;
256 }
257}
258
259inline void FetchTriangle(dxTriMesh* TriMesh, int Index, const dVector3 Position, const dMatrix3 Rotation, dVector3 Out[3]){
260 VertexPointers VP;
261 TriMesh->Data->Mesh.GetTriangle(VP, Index);
262 for (int i = 0; i < 3; i++){
263 dVector3 v;
264 v[0] = VP.Vertex[i]->x;
265 v[1] = VP.Vertex[i]->y;
266 v[2] = VP.Vertex[i]->z;
267 v[3] = 0;
268
269 dMULTIPLY0_331(Out[i], Rotation, v);
270 Out[i][0] += Position[0];
271 Out[i][1] += Position[1];
272 Out[i][2] += Position[2];
273 Out[i][3] = 0;
274 }
275}
276
277inline Matrix4x4& MakeMatrix(const dVector3 Position, const dMatrix3 Rotation, Matrix4x4& Out){
278 Out.m[0][0] = (float) Rotation[0];
279 Out.m[1][0] = (float) Rotation[1];
280 Out.m[2][0] = (float) Rotation[2];
281
282 Out.m[0][1] = (float) Rotation[4];
283 Out.m[1][1] = (float) Rotation[5];
284 Out.m[2][1] = (float) Rotation[6];
285
286 Out.m[0][2] = (float) Rotation[8];
287 Out.m[1][2] = (float) Rotation[9];
288 Out.m[2][2] = (float) Rotation[10];
289
290 Out.m[3][0] = (float) Position[0];
291 Out.m[3][1] = (float) Position[1];
292 Out.m[3][2] = (float) Position[2];
293
294 Out.m[0][3] = 0.0f;
295 Out.m[1][3] = 0.0f;
296 Out.m[2][3] = 0.0f;
297 Out.m[3][3] = 1.0f;
298
299 return Out;
300}
301
302inline Matrix4x4& MakeMatrix(dxGeom* g, Matrix4x4& Out){
303 const dVector3& Position = *(const dVector3*)dGeomGetPosition(g);
304 const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g);
305 return MakeMatrix(Position, Rotation, Out);
306}
307#endif // dTRIMESH_OPCODE
308
309#if dTRIMESH_GIMPACT
310inline void FetchTriangle(dxTriMesh* TriMesh, int Index, const dVector3 Position, const dMatrix3 Rotation, dVector3 Out[3]){
311 // why is this not implemented?
312 dAASSERT(false);
313}
314
315inline void MakeMatrix(const dVector3 Position, const dMatrix3 Rotation, mat4f m)
316{
317 m[0][0] = (float) Rotation[0];
318 m[0][1] = (float) Rotation[1];
319 m[0][2] = (float) Rotation[2];
320
321 m[1][0] = (float) Rotation[4];
322 m[1][1] = (float) Rotation[5];
323 m[1][2] = (float) Rotation[6];
324
325 m[2][0] = (float) Rotation[8];
326 m[2][1] = (float) Rotation[9];
327 m[2][2] = (float) Rotation[10];
328
329 m[0][3] = (float) Position[0];
330 m[1][3] = (float) Position[1];
331 m[2][3] = (float) Position[2];
332
333}
334
335inline void MakeMatrix(dxGeom* g, mat4f Out){
336 const dVector3& Position = *(const dVector3*)dGeomGetPosition(g);
337 const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g);
338 MakeMatrix(Position, Rotation, Out);
339}
340#endif // dTRIMESH_GIMPACT
341
342// Outputs a matrix to 3 vectors
343inline void Decompose(const dMatrix3 Matrix, dVector3 Right, dVector3 Up, dVector3 Direction){
344 Right[0] = Matrix[0 * 4 + 0];
345 Right[1] = Matrix[1 * 4 + 0];
346 Right[2] = Matrix[2 * 4 + 0];
347 Right[3] = REAL(0.0);
348 Up[0] = Matrix[0 * 4 + 1];
349 Up[1] = Matrix[1 * 4 + 1];
350 Up[2] = Matrix[2 * 4 + 1];
351 Up[3] = REAL(0.0);
352 Direction[0] = Matrix[0 * 4 + 2];
353 Direction[1] = Matrix[1 * 4 + 2];
354 Direction[2] = Matrix[2 * 4 + 2];
355 Direction[3] = REAL(0.0);
356}
357
358// Outputs a matrix to 3 vectors
359inline void Decompose(const dMatrix3 Matrix, dVector3 Vectors[3]){
360 Decompose(Matrix, Vectors[0], Vectors[1], Vectors[2]);
361}
362
363// Finds barycentric
364inline void GetPointFromBarycentric(const dVector3 dv[3], dReal u, dReal v, dVector3 Out){
365 dReal w = REAL(1.0) - u - v;
366
367 Out[0] = (dv[0][0] * w) + (dv[1][0] * u) + (dv[2][0] * v);
368 Out[1] = (dv[0][1] * w) + (dv[1][1] * u) + (dv[2][1] * v);
369 Out[2] = (dv[0][2] * w) + (dv[1][2] * u) + (dv[2][2] * v);
370 Out[3] = (dv[0][3] * w) + (dv[1][3] * u) + (dv[2][3] * v);
371}
372
373// Performs a callback
374inline bool Callback(dxTriMesh* TriMesh, dxGeom* Object, int TriIndex){
375 if (TriMesh->Callback != NULL){
376 return (TriMesh->Callback(TriMesh, Object, TriIndex)!=0);
377 }
378 else return true;
379}
380
381// Some utilities
382template<class T> const T& dcMAX(const T& x, const T& y){
383 return x > y ? x : y;
384}
385
386template<class T> const T& dcMIN(const T& x, const T& y){
387 return x < y ? x : y;
388}
389
390dReal SqrDistancePointTri( const dVector3 p, const dVector3 triOrigin,
391 const dVector3 triEdge1, const dVector3 triEdge2,
392 dReal* pfSParam = 0, dReal* pfTParam = 0 );
393
394dReal SqrDistanceSegments( const dVector3 seg1Origin, const dVector3 seg1Direction,
395 const dVector3 seg2Origin, const dVector3 seg2Direction,
396 dReal* pfSegP0 = 0, dReal* pfSegP1 = 0 );
397
398dReal SqrDistanceSegTri( const dVector3 segOrigin, const dVector3 segEnd,
399 const dVector3 triOrigin,
400 const dVector3 triEdge1, const dVector3 triEdge2,
401 dReal* t = 0, dReal* u = 0, dReal* v = 0 );
402
403inline
404void Vector3Subtract( const dVector3 left, const dVector3 right, dVector3 result )
405{
406 result[0] = left[0] - right[0];
407 result[1] = left[1] - right[1];
408 result[2] = left[2] - right[2];
409 result[3] = REAL(0.0);
410}
411
412inline
413void Vector3Add( const dVector3 left, const dVector3 right, dVector3 result )
414{
415 result[0] = left[0] + right[0];
416 result[1] = left[1] + right[1];
417 result[2] = left[2] + right[2];
418 result[3] = REAL(0.0);
419}
420
421inline
422void Vector3Negate( const dVector3 in, dVector3 out )
423{
424 out[0] = -in[0];
425 out[1] = -in[1];
426 out[2] = -in[2];
427 out[3] = REAL(0.0);
428}
429
430inline
431void Vector3Copy( const dVector3 in, dVector3 out )
432{
433 out[0] = in[0];
434 out[1] = in[1];
435 out[2] = in[2];
436 out[3] = REAL(0.0);
437}
438
439inline
440void Vector3Multiply( const dVector3 in, dReal scalar, dVector3 out )
441{
442 out[0] = in[0] * scalar;
443 out[1] = in[1] * scalar;
444 out[2] = in[2] * scalar;
445 out[3] = REAL(0.0);
446}
447
448inline
449void TransformVector3( const dVector3 in,
450 const dMatrix3 orientation, const dVector3 position,
451 dVector3 out )
452{
453 dMULTIPLY0_331( out, orientation, in );
454 out[0] += position[0];
455 out[1] += position[1];
456 out[2] += position[2];
457}
458
459//------------------------------------------------------------------------------
460/**
461 @brief Check for intersection between triangle and capsule.
462
463 @param dist [out] Shortest distance squared between the triangle and
464 the capsule segment (central axis).
465 @param t [out] t value of point on segment that's the shortest distance
466 away from the triangle, the coordinates of this point
467 can be found by (cap.seg.end - cap.seg.start) * t,
468 or cap.seg.ipol(t).
469 @param u [out] Barycentric coord on triangle.
470 @param v [out] Barycentric coord on triangle.
471 @return True if intersection exists.
472
473 The third Barycentric coord is implicit, ie. w = 1.0 - u - v
474 The Barycentric coords give the location of the point on the triangle
475 closest to the capsule (where the distance between the two shapes
476 is the shortest).
477*/
478inline
479bool IntersectCapsuleTri( const dVector3 segOrigin, const dVector3 segEnd,
480 const dReal radius, const dVector3 triOrigin,
481 const dVector3 triEdge0, const dVector3 triEdge1,
482 dReal* dist, dReal* t, dReal* u, dReal* v )
483{
484 dReal sqrDist = SqrDistanceSegTri( segOrigin, segEnd, triOrigin, triEdge0, triEdge1,
485 t, u, v );
486
487 if ( dist )
488 *dist = sqrDist;
489
490 return ( sqrDist <= (radius * radius) );
491}
492
493#endif //TRIMESH_INTERNAL
494
495#endif //_ODE_COLLISION_TRIMESH_INTERNAL_H_