aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/OPCODE/Ice
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceAABB.cpp405
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceAABB.h505
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceAxes.h54
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceBoundingSphere.h142
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp345
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceContainer.h212
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceFPU.h337
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceHPoint.cpp70
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceHPoint.h160
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.cpp548
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.h72
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceLSS.h75
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.cpp48
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.h496
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.cpp135
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.h455
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceMemoryMacros.h109
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceOBB.cpp323
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceOBB.h177
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IcePairs.h45
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IcePlane.cpp45
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IcePlane.h113
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp193
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IcePoint.h528
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IcePreprocessor.h132
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceRandom.cpp35
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceRandom.h42
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceRay.cpp84
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceRay.h98
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.cpp520
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.h65
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceSegment.cpp57
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceSegment.h55
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceTriList.h61
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceTriangle.cpp286
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceTriangle.h68
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceTypes.h171
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceUtils.cpp39
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceUtils.h256
39 files changed, 7561 insertions, 0 deletions
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceAABB.cpp b/libraries/ode-0.9/OPCODE/Ice/IceAABB.cpp
new file mode 100644
index 0000000..d62b0ed
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceAABB.cpp
@@ -0,0 +1,405 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains AABB-related code.
4 * \file IceAABB.cpp
5 * \author Pierre Terdiman
6 * \date January, 29, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * AABB class.
13 * \class AABB
14 * \author Pierre Terdiman
15 * \version 1.0
16 */
17///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18
19///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20// Precompiled Header
21#include "Stdafx.h"
22
23using namespace IceMaths;
24
25///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26/**
27 * Computes the sum of two AABBs.
28 * \param aabb [in] the other AABB
29 * \return Self-Reference
30 */
31///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32AABB& AABB::Add(const AABB& aabb)
33{
34 // Compute new min & max values
35 Point Min; GetMin(Min);
36 Point Tmp; aabb.GetMin(Tmp);
37 Min.Min(Tmp);
38
39 Point Max; GetMax(Max);
40 aabb.GetMax(Tmp);
41 Max.Max(Tmp);
42
43 // Update this
44 SetMinMax(Min, Max);
45 return *this;
46}
47
48///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
49/**
50 * Makes a cube from the AABB.
51 * \param cube [out] the cube AABB
52 * \return cube edge length
53 */
54///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
55float AABB::MakeCube(AABB& cube) const
56{
57 Point Ext; GetExtents(Ext);
58 float Max = Ext.Max();
59
60 Point Cnt; GetCenter(Cnt);
61 cube.SetCenterExtents(Cnt, Point(Max, Max, Max));
62 return Max;
63}
64
65///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66/**
67 * Makes a sphere from the AABB.
68 * \param sphere [out] sphere containing the AABB
69 */
70///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
71void AABB::MakeSphere(Sphere& sphere) const
72{
73 GetExtents(sphere.mCenter);
74 sphere.mRadius = sphere.mCenter.Magnitude() * 1.00001f; // To make sure sphere::Contains(*this) succeeds
75 GetCenter(sphere.mCenter);
76}
77
78///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
79/**
80 * Checks a box is inside another box.
81 * \param box [in] the other AABB
82 * \return true if current box is inside input box
83 */
84///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
85bool AABB::IsInside(const AABB& box) const
86{
87 if(box.GetMin(0)>GetMin(0)) return false;
88 if(box.GetMin(1)>GetMin(1)) return false;
89 if(box.GetMin(2)>GetMin(2)) return false;
90 if(box.GetMax(0)<GetMax(0)) return false;
91 if(box.GetMax(1)<GetMax(1)) return false;
92 if(box.GetMax(2)<GetMax(2)) return false;
93 return true;
94}
95
96///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
97/**
98 * Computes the AABB planes.
99 * \param planes [out] 6 planes surrounding the box
100 * \return true if success
101 */
102///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
103bool AABB::ComputePlanes(Plane* planes) const
104{
105 // Checkings
106 if(!planes) return false;
107
108 Point Center, Extents;
109 GetCenter(Center);
110 GetExtents(Extents);
111
112 // Writes normals
113 planes[0].n = Point(1.0f, 0.0f, 0.0f);
114 planes[1].n = Point(-1.0f, 0.0f, 0.0f);
115 planes[2].n = Point(0.0f, 1.0f, 0.0f);
116 planes[3].n = Point(0.0f, -1.0f, 0.0f);
117 planes[4].n = Point(0.0f, 0.0f, 1.0f);
118 planes[5].n = Point(0.0f, 0.0f, -1.0f);
119
120 // Compute a point on each plane
121 Point p0 = Point(Center.x+Extents.x, Center.y, Center.z);
122 Point p1 = Point(Center.x-Extents.x, Center.y, Center.z);
123 Point p2 = Point(Center.x, Center.y+Extents.y, Center.z);
124 Point p3 = Point(Center.x, Center.y-Extents.y, Center.z);
125 Point p4 = Point(Center.x, Center.y, Center.z+Extents.z);
126 Point p5 = Point(Center.x, Center.y, Center.z-Extents.z);
127
128 // Compute d
129 planes[0].d = -(planes[0].n|p0);
130 planes[1].d = -(planes[1].n|p1);
131 planes[2].d = -(planes[2].n|p2);
132 planes[3].d = -(planes[3].n|p3);
133 planes[4].d = -(planes[4].n|p4);
134 planes[5].d = -(planes[5].n|p5);
135
136 return true;
137}
138
139///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
140/**
141 * Computes the aabb points.
142 * \param pts [out] 8 box points
143 * \return true if success
144 */
145///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
146bool AABB::ComputePoints(Point* pts) const
147{
148 // Checkings
149 if(!pts) return false;
150
151 // Get box corners
152 Point min; GetMin(min);
153 Point max; GetMax(max);
154
155 // 7+------+6 0 = ---
156 // /| /| 1 = +--
157 // / | / | 2 = ++-
158 // / 4+---/--+5 3 = -+-
159 // 3+------+2 / y z 4 = --+
160 // | / | / | / 5 = +-+
161 // |/ |/ |/ 6 = +++
162 // 0+------+1 *---x 7 = -++
163
164 // Generate 8 corners of the bbox
165 pts[0] = Point(min.x, min.y, min.z);
166 pts[1] = Point(max.x, min.y, min.z);
167 pts[2] = Point(max.x, max.y, min.z);
168 pts[3] = Point(min.x, max.y, min.z);
169 pts[4] = Point(min.x, min.y, max.z);
170 pts[5] = Point(max.x, min.y, max.z);
171 pts[6] = Point(max.x, max.y, max.z);
172 pts[7] = Point(min.x, max.y, max.z);
173
174 return true;
175}
176
177///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
178/**
179 * Gets vertex normals.
180 * \param pts [out] 8 box points
181 * \return true if success
182 */
183///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
184const Point* AABB::GetVertexNormals() const
185{
186 static float VertexNormals[] =
187 {
188 -INVSQRT3, -INVSQRT3, -INVSQRT3,
189 INVSQRT3, -INVSQRT3, -INVSQRT3,
190 INVSQRT3, INVSQRT3, -INVSQRT3,
191 -INVSQRT3, INVSQRT3, -INVSQRT3,
192 -INVSQRT3, -INVSQRT3, INVSQRT3,
193 INVSQRT3, -INVSQRT3, INVSQRT3,
194 INVSQRT3, INVSQRT3, INVSQRT3,
195 -INVSQRT3, INVSQRT3, INVSQRT3
196 };
197 return (const Point*)VertexNormals;
198}
199
200///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
201/**
202 * Returns edges.
203 * \return 24 indices (12 edges) indexing the list returned by ComputePoints()
204 */
205///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
206const udword* AABB::GetEdges() const
207{
208 static udword Indices[] = {
209 0, 1, 1, 2, 2, 3, 3, 0,
210 7, 6, 6, 5, 5, 4, 4, 7,
211 1, 5, 6, 2,
212 3, 7, 4, 0
213 };
214 return Indices;
215}
216
217///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
218/**
219 * Returns edge normals.
220 * \return edge normals in local space
221 */
222///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
223const Point* AABB::GetEdgeNormals() const
224{
225 static float EdgeNormals[] =
226 {
227 0, -INVSQRT2, -INVSQRT2, // 0-1
228 INVSQRT2, 0, -INVSQRT2, // 1-2
229 0, INVSQRT2, -INVSQRT2, // 2-3
230 -INVSQRT2, 0, -INVSQRT2, // 3-0
231
232 0, INVSQRT2, INVSQRT2, // 7-6
233 INVSQRT2, 0, INVSQRT2, // 6-5
234 0, -INVSQRT2, INVSQRT2, // 5-4
235 -INVSQRT2, 0, INVSQRT2, // 4-7
236
237 INVSQRT2, -INVSQRT2, 0, // 1-5
238 INVSQRT2, INVSQRT2, 0, // 6-2
239 -INVSQRT2, INVSQRT2, 0, // 3-7
240 -INVSQRT2, -INVSQRT2, 0 // 4-0
241 };
242 return (const Point*)EdgeNormals;
243}
244
245// ===========================================================================
246// (C) 1996-98 Vienna University of Technology
247// ===========================================================================
248// NAME: bboxarea
249// TYPE: c++ code
250// PROJECT: Bounding Box Area
251// CONTENT: Computes area of 2D projection of 3D oriented bounding box
252// VERSION: 1.0
253// ===========================================================================
254// AUTHORS: ds Dieter Schmalstieg
255// ep Erik Pojar
256// ===========================================================================
257// HISTORY:
258//
259// 19-sep-99 15:23:03 ds last modification
260// 01-dec-98 15:23:03 ep created
261// ===========================================================================
262
263//----------------------------------------------------------------------------
264// SAMPLE CODE STARTS HERE
265//----------------------------------------------------------------------------
266
267// NOTE: This sample program requires OPEN INVENTOR!
268
269//indexlist: this table stores the 64 possible cases of classification of
270//the eyepoint with respect to the 6 defining planes of the bbox (2^6=64)
271//only 26 (3^3-1, where 1 is "inside" cube) of these cases are valid.
272//the first 6 numbers in each row are the indices of the bbox vertices that
273//form the outline of which we want to compute the area (counterclockwise
274//ordering), the 7th entry means the number of vertices in the outline.
275//there are 6 cases with a single face and and a 4-vertex outline, and
276//20 cases with 2 or 3 faces and a 6-vertex outline. a value of 0 indicates
277//an invalid case.
278
279
280// Original list was made of 7 items, I added an 8th element:
281// - to padd on a cache line
282// - to repeat the first entry to avoid modulos
283//
284// I also replaced original ints with sbytes.
285
286static const sbyte gIndexList[64][8] =
287{
288 {-1,-1,-1,-1,-1,-1,-1, 0}, // 0 inside
289 { 0, 4, 7, 3, 0,-1,-1, 4}, // 1 left
290 { 1, 2, 6, 5, 1,-1,-1, 4}, // 2 right
291 {-1,-1,-1,-1,-1,-1,-1, 0}, // 3 -
292 { 0, 1, 5, 4, 0,-1,-1, 4}, // 4 bottom
293 { 0, 1, 5, 4, 7, 3, 0, 6}, // 5 bottom, left
294 { 0, 1, 2, 6, 5, 4, 0, 6}, // 6 bottom, right
295 {-1,-1,-1,-1,-1,-1,-1, 0}, // 7 -
296 { 2, 3, 7, 6, 2,-1,-1, 4}, // 8 top
297 { 0, 4, 7, 6, 2, 3, 0, 6}, // 9 top, left
298 { 1, 2, 3, 7, 6, 5, 1, 6}, //10 top, right
299 {-1,-1,-1,-1,-1,-1,-1, 0}, //11 -
300 {-1,-1,-1,-1,-1,-1,-1, 0}, //12 -
301 {-1,-1,-1,-1,-1,-1,-1, 0}, //13 -
302 {-1,-1,-1,-1,-1,-1,-1, 0}, //14 -
303 {-1,-1,-1,-1,-1,-1,-1, 0}, //15 -
304 { 0, 3, 2, 1, 0,-1,-1, 4}, //16 front
305 { 0, 4, 7, 3, 2, 1, 0, 6}, //17 front, left
306 { 0, 3, 2, 6, 5, 1, 0, 6}, //18 front, right
307 {-1,-1,-1,-1,-1,-1,-1, 0}, //19 -
308 { 0, 3, 2, 1, 5, 4, 0, 6}, //20 front, bottom
309 { 1, 5, 4, 7, 3, 2, 1, 6}, //21 front, bottom, left
310 { 0, 3, 2, 6, 5, 4, 0, 6}, //22 front, bottom, right
311 {-1,-1,-1,-1,-1,-1,-1, 0}, //23 -
312 { 0, 3, 7, 6, 2, 1, 0, 6}, //24 front, top
313 { 0, 4, 7, 6, 2, 1, 0, 6}, //25 front, top, left
314 { 0, 3, 7, 6, 5, 1, 0, 6}, //26 front, top, right
315 {-1,-1,-1,-1,-1,-1,-1, 0}, //27 -
316 {-1,-1,-1,-1,-1,-1,-1, 0}, //28 -
317 {-1,-1,-1,-1,-1,-1,-1, 0}, //29 -
318 {-1,-1,-1,-1,-1,-1,-1, 0}, //30 -
319 {-1,-1,-1,-1,-1,-1,-1, 0}, //31 -
320 { 4, 5, 6, 7, 4,-1,-1, 4}, //32 back
321 { 0, 4, 5, 6, 7, 3, 0, 6}, //33 back, left
322 { 1, 2, 6, 7, 4, 5, 1, 6}, //34 back, right
323 {-1,-1,-1,-1,-1,-1,-1, 0}, //35 -
324 { 0, 1, 5, 6, 7, 4, 0, 6}, //36 back, bottom
325 { 0, 1, 5, 6, 7, 3, 0, 6}, //37 back, bottom, left
326 { 0, 1, 2, 6, 7, 4, 0, 6}, //38 back, bottom, right
327 {-1,-1,-1,-1,-1,-1,-1, 0}, //39 -
328 { 2, 3, 7, 4, 5, 6, 2, 6}, //40 back, top
329 { 0, 4, 5, 6, 2, 3, 0, 6}, //41 back, top, left
330 { 1, 2, 3, 7, 4, 5, 1, 6}, //42 back, top, right
331 {-1,-1,-1,-1,-1,-1,-1, 0}, //43 invalid
332 {-1,-1,-1,-1,-1,-1,-1, 0}, //44 invalid
333 {-1,-1,-1,-1,-1,-1,-1, 0}, //45 invalid
334 {-1,-1,-1,-1,-1,-1,-1, 0}, //46 invalid
335 {-1,-1,-1,-1,-1,-1,-1, 0}, //47 invalid
336 {-1,-1,-1,-1,-1,-1,-1, 0}, //48 invalid
337 {-1,-1,-1,-1,-1,-1,-1, 0}, //49 invalid
338 {-1,-1,-1,-1,-1,-1,-1, 0}, //50 invalid
339 {-1,-1,-1,-1,-1,-1,-1, 0}, //51 invalid
340 {-1,-1,-1,-1,-1,-1,-1, 0}, //52 invalid
341 {-1,-1,-1,-1,-1,-1,-1, 0}, //53 invalid
342 {-1,-1,-1,-1,-1,-1,-1, 0}, //54 invalid
343 {-1,-1,-1,-1,-1,-1,-1, 0}, //55 invalid
344 {-1,-1,-1,-1,-1,-1,-1, 0}, //56 invalid
345 {-1,-1,-1,-1,-1,-1,-1, 0}, //57 invalid
346 {-1,-1,-1,-1,-1,-1,-1, 0}, //58 invalid
347 {-1,-1,-1,-1,-1,-1,-1, 0}, //59 invalid
348 {-1,-1,-1,-1,-1,-1,-1, 0}, //60 invalid
349 {-1,-1,-1,-1,-1,-1,-1, 0}, //61 invalid
350 {-1,-1,-1,-1,-1,-1,-1, 0}, //62 invalid
351 {-1,-1,-1,-1,-1,-1,-1, 0} //63 invalid
352};
353
354const sbyte* AABB::ComputeOutline(const Point& local_eye, sdword& num) const
355{
356 // Get box corners
357 Point min; GetMin(min);
358 Point max; GetMax(max);
359
360 // Compute 6-bit code to classify eye with respect to the 6 defining planes of the bbox
361 int pos = ((local_eye.x < min.x) ? 1 : 0) // 1 = left
362 + ((local_eye.x > max.x) ? 2 : 0) // 2 = right
363 + ((local_eye.y < min.y) ? 4 : 0) // 4 = bottom
364 + ((local_eye.y > max.y) ? 8 : 0) // 8 = top
365 + ((local_eye.z < min.z) ? 16 : 0) // 16 = front
366 + ((local_eye.z > max.z) ? 32 : 0); // 32 = back
367
368 // Look up number of vertices in outline
369 num = (sdword)gIndexList[pos][7];
370 // Zero indicates invalid case
371 if(!num) return null;
372
373 return &gIndexList[pos][0];
374}
375
376// calculateBoxArea: computes the screen-projected 2D area of an oriented 3D bounding box
377
378//const Point& eye, //eye point (in bbox object coordinates)
379//const AABB& box, //3d bbox
380//const Matrix4x4& mat, //free transformation for bbox
381//float width, float height, int& num)
382float AABB::ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const
383{
384 const sbyte* Outline = ComputeOutline(eye, num);
385 if(!Outline) return -1.0f;
386
387 // Compute box vertices
388 Point vertexBox[8], dst[8];
389 ComputePoints(vertexBox);
390
391 // Transform all outline corners into 2D screen space
392 for(sdword i=0;i<num;i++)
393 {
394 HPoint Projected;
395 vertexBox[Outline[i]].ProjectToScreen(width, height, mat, Projected);
396 dst[i] = Projected;
397 }
398
399 float Sum = (dst[num-1][0] - dst[0][0]) * (dst[num-1][1] + dst[0][1]);
400
401 for(int i=0; i<num-1; i++)
402 Sum += (dst[i][0] - dst[i+1][0]) * (dst[i][1] + dst[i+1][1]);
403
404 return Sum * 0.5f; //return computed value corrected by 0.5
405}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceAABB.h b/libraries/ode-0.9/OPCODE/Ice/IceAABB.h
new file mode 100644
index 0000000..f71d7e9
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceAABB.h
@@ -0,0 +1,505 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains AABB-related code. (axis-aligned bounding box)
4 * \file IceAABB.h
5 * \author Pierre Terdiman
6 * \date January, 13, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEAABB_H__
13#define __ICEAABB_H__
14
15 // Forward declarations
16 class Sphere;
17
18//! Declarations of type-independent methods (most of them implemented in the .cpp)
19#define AABB_COMMON_METHODS \
20 AABB& Add(const AABB& aabb); \
21 float MakeCube(AABB& cube) const; \
22 void MakeSphere(Sphere& sphere) const; \
23 const sbyte* ComputeOutline(const Point& local_eye, sdword& num) const; \
24 float ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const; \
25 bool IsInside(const AABB& box) const; \
26 bool ComputePlanes(Plane* planes) const; \
27 bool ComputePoints(Point* pts) const; \
28 const Point* GetVertexNormals() const; \
29 const udword* GetEdges() const; \
30 const Point* GetEdgeNormals() const; \
31 inline_ BOOL ContainsPoint(const Point& p) const \
32 { \
33 if(p.x > GetMax(0) || p.x < GetMin(0)) return FALSE; \
34 if(p.y > GetMax(1) || p.y < GetMin(1)) return FALSE; \
35 if(p.z > GetMax(2) || p.z < GetMin(2)) return FALSE; \
36 return TRUE; \
37 }
38
39 enum AABBType
40 {
41 AABB_RENDER = 0, //!< AABB used for rendering. Not visible == not rendered.
42 AABB_UPDATE = 1, //!< AABB used for dynamic updates. Not visible == not updated.
43
44 AABB_FORCE_DWORD = 0x7fffffff,
45 };
46
47#ifdef USE_MINMAX
48
49 struct ICEMATHS_API ShadowAABB
50 {
51 Point mMin;
52 Point mMax;
53 };
54
55 class ICEMATHS_API AABB
56 {
57 public:
58 //! Constructor
59 inline_ AABB() {}
60 //! Destructor
61 inline_ ~AABB() {}
62
63 //! Type-independent methods
64 AABB_COMMON_METHODS;
65
66 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
67 /**
68 * Setups an AABB from min & max vectors.
69 * \param min [in] the min point
70 * \param max [in] the max point
71 */
72 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
73 void SetMinMax(const Point& min, const Point& max) { mMin = min; mMax = max; }
74
75 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
76 /**
77 * Setups an AABB from center & extents vectors.
78 * \param c [in] the center point
79 * \param e [in] the extents vector
80 */
81 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
82 void SetCenterExtents(const Point& c, const Point& e) { mMin = c - e; mMax = c + e; }
83
84 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
85 /**
86 * Setups an empty AABB.
87 */
88 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
89 void SetEmpty() { Point p(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); mMin = -p; mMax = p;}
90
91 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
92 /**
93 * Setups a point AABB.
94 */
95 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
96 void SetPoint(const Point& pt) { mMin = mMax = pt; }
97
98 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
99 /**
100 * Gets the size of the AABB. The size is defined as the longest extent.
101 * \return the size of the AABB
102 */
103 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
104 float GetSize() const { Point e; GetExtents(e); return e.Max(); }
105
106 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
107 /**
108 * Extends the AABB.
109 * \param p [in] the next point
110 */
111 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
112 void Extend(const Point& p)
113 {
114 if(p.x > mMax.x) mMax.x = p.x;
115 if(p.x < mMin.x) mMin.x = p.x;
116
117 if(p.y > mMax.y) mMax.y = p.y;
118 if(p.y < mMin.y) mMin.y = p.y;
119
120 if(p.z > mMax.z) mMax.z = p.z;
121 if(p.z < mMin.z) mMin.z = p.z;
122 }
123 // Data access
124
125 //! Get min point of the box
126 inline_ void GetMin(Point& min) const { min = mMin; }
127 //! Get max point of the box
128 inline_ void GetMax(Point& max) const { max = mMax; }
129
130 //! Get component of the box's min point along a given axis
131 inline_ float GetMin(udword axis) const { return mMin[axis]; }
132 //! Get component of the box's max point along a given axis
133 inline_ float GetMax(udword axis) const { return mMax[axis]; }
134
135 //! Get box center
136 inline_ void GetCenter(Point& center) const { center = (mMax + mMin)*0.5f; }
137 //! Get box extents
138 inline_ void GetExtents(Point& extents) const { extents = (mMax - mMin)*0.5f; }
139
140 //! Get component of the box's center along a given axis
141 inline_ float GetCenter(udword axis) const { return (mMax[axis] + mMin[axis])*0.5f; }
142 //! Get component of the box's extents along a given axis
143 inline_ float GetExtents(udword axis) const { return (mMax[axis] - mMin[axis])*0.5f; }
144
145 //! Get box diagonal
146 inline_ void GetDiagonal(Point& diagonal) const { diagonal = mMax - mMin; }
147 inline_ float GetWidth() const { return mMax.x - mMin.x; }
148 inline_ float GetHeight() const { return mMax.y - mMin.y; }
149 inline_ float GetDepth() const { return mMax.z - mMin.z; }
150
151 //! Volume
152 inline_ float GetVolume() const { return GetWidth() * GetHeight() * GetDepth(); }
153
154 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
155 /**
156 * Computes the intersection between two AABBs.
157 * \param a [in] the other AABB
158 * \return true on intersection
159 */
160 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
161 inline_ BOOL Intersect(const AABB& a) const
162 {
163 if(mMax.x < a.mMin.x
164 || a.mMax.x < mMin.x
165 || mMax.y < a.mMin.y
166 || a.mMax.y < mMin.y
167 || mMax.z < a.mMin.z
168 || a.mMax.z < mMin.z) return FALSE;
169
170 return TRUE;
171 }
172
173 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
174 /**
175 * Computes the 1D-intersection between two AABBs, on a given axis.
176 * \param a [in] the other AABB
177 * \param axis [in] the axis (0, 1, 2)
178 * \return true on intersection
179 */
180 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
181 inline_ BOOL Intersect(const AABB& a, udword axis) const
182 {
183 if(mMax[axis] < a.mMin[axis] || a.mMax[axis] < mMin[axis]) return FALSE;
184 return TRUE;
185 }
186
187 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
188 /**
189 * Recomputes the AABB after an arbitrary transform by a 4x4 matrix.
190 * Original code by Charles Bloom on the GD-Algorithm list. (I slightly modified it)
191 * \param mtx [in] the transform matrix
192 * \param aabb [out] the transformed AABB [can be *this]
193 */
194 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
195 inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const
196 {
197 // The three edges transformed: you can efficiently transform an X-only vector
198 // by just getting the "X" column of the matrix
199 Point vx,vy,vz;
200 mtx.GetRow(0, vx); vx *= (mMax.x - mMin.x);
201 mtx.GetRow(1, vy); vy *= (mMax.y - mMin.y);
202 mtx.GetRow(2, vz); vz *= (mMax.z - mMin.z);
203
204 // Transform the min point
205 aabb.mMin = aabb.mMax = mMin * mtx;
206
207 // Take the transformed min & axes and find new extents
208 // Using CPU code in the right place is faster...
209 if(IS_NEGATIVE_FLOAT(vx.x)) aabb.mMin.x += vx.x; else aabb.mMax.x += vx.x;
210 if(IS_NEGATIVE_FLOAT(vx.y)) aabb.mMin.y += vx.y; else aabb.mMax.y += vx.y;
211 if(IS_NEGATIVE_FLOAT(vx.z)) aabb.mMin.z += vx.z; else aabb.mMax.z += vx.z;
212 if(IS_NEGATIVE_FLOAT(vy.x)) aabb.mMin.x += vy.x; else aabb.mMax.x += vy.x;
213 if(IS_NEGATIVE_FLOAT(vy.y)) aabb.mMin.y += vy.y; else aabb.mMax.y += vy.y;
214 if(IS_NEGATIVE_FLOAT(vy.z)) aabb.mMin.z += vy.z; else aabb.mMax.z += vy.z;
215 if(IS_NEGATIVE_FLOAT(vz.x)) aabb.mMin.x += vz.x; else aabb.mMax.x += vz.x;
216 if(IS_NEGATIVE_FLOAT(vz.y)) aabb.mMin.y += vz.y; else aabb.mMax.y += vz.y;
217 if(IS_NEGATIVE_FLOAT(vz.z)) aabb.mMin.z += vz.z; else aabb.mMax.z += vz.z;
218 }
219
220 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
221 /**
222 * Checks the AABB is valid.
223 * \return true if the box is valid
224 */
225 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
226 inline_ BOOL IsValid() const
227 {
228 // Consistency condition for (Min, Max) boxes: min < max
229 if(mMin.x > mMax.x) return FALSE;
230 if(mMin.y > mMax.y) return FALSE;
231 if(mMin.z > mMax.z) return FALSE;
232 return TRUE;
233 }
234
235 //! Operator for AABB *= float. Scales the extents, keeps same center.
236 inline_ AABB& operator*=(float s)
237 {
238 Point Center; GetCenter(Center);
239 Point Extents; GetExtents(Extents);
240 SetCenterExtents(Center, Extents * s);
241 return *this;
242 }
243
244 //! Operator for AABB /= float. Scales the extents, keeps same center.
245 inline_ AABB& operator/=(float s)
246 {
247 Point Center; GetCenter(Center);
248 Point Extents; GetExtents(Extents);
249 SetCenterExtents(Center, Extents / s);
250 return *this;
251 }
252
253 //! Operator for AABB += Point. Translates the box.
254 inline_ AABB& operator+=(const Point& trans)
255 {
256 mMin+=trans;
257 mMax+=trans;
258 return *this;
259 }
260 private:
261 Point mMin; //!< Min point
262 Point mMax; //!< Max point
263 };
264
265#else
266
267 class ICEMATHS_API AABB
268 {
269 public:
270 //! Constructor
271 inline_ AABB() {}
272 //! Destructor
273 inline_ ~AABB() {}
274
275 //! Type-independent methods
276 AABB_COMMON_METHODS;
277
278 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
279 /**
280 * Setups an AABB from min & max vectors.
281 * \param min [in] the min point
282 * \param max [in] the max point
283 */
284 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
285 void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; }
286
287 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
288 /**
289 * Setups an AABB from center & extents vectors.
290 * \param c [in] the center point
291 * \param e [in] the extents vector
292 */
293 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
294 void SetCenterExtents(const Point& c, const Point& e) { mCenter = c; mExtents = e; }
295
296 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
297 /**
298 * Setups an empty AABB.
299 */
300 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
301 void SetEmpty() { mCenter.Zero(); mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);}
302
303 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
304 /**
305 * Setups a point AABB.
306 */
307 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
308 void SetPoint(const Point& pt) { mCenter = pt; mExtents.Zero(); }
309
310 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
311 /**
312 * Gets the size of the AABB. The size is defined as the longest extent.
313 * \return the size of the AABB
314 */
315 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
316 float GetSize() const { return mExtents.Max(); }
317
318 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
319 /**
320 * Extends the AABB.
321 * \param p [in] the next point
322 */
323 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
324 void Extend(const Point& p)
325 {
326 Point Max = mCenter + mExtents;
327 Point Min = mCenter - mExtents;
328
329 if(p.x > Max.x) Max.x = p.x;
330 if(p.x < Min.x) Min.x = p.x;
331
332 if(p.y > Max.y) Max.y = p.y;
333 if(p.y < Min.y) Min.y = p.y;
334
335 if(p.z > Max.z) Max.z = p.z;
336 if(p.z < Min.z) Min.z = p.z;
337
338 SetMinMax(Min, Max);
339 }
340 // Data access
341
342 //! Get min point of the box
343 inline_ void GetMin(Point& min) const { min = mCenter - mExtents; }
344 //! Get max point of the box
345 inline_ void GetMax(Point& max) const { max = mCenter + mExtents; }
346
347 //! Get component of the box's min point along a given axis
348 inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; }
349 //! Get component of the box's max point along a given axis
350 inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; }
351
352 //! Get box center
353 inline_ void GetCenter(Point& center) const { center = mCenter; }
354 //! Get box extents
355 inline_ void GetExtents(Point& extents) const { extents = mExtents; }
356
357 //! Get component of the box's center along a given axis
358 inline_ float GetCenter(udword axis) const { return mCenter[axis]; }
359 //! Get component of the box's extents along a given axis
360 inline_ float GetExtents(udword axis) const { return mExtents[axis]; }
361
362 //! Get box diagonal
363 inline_ void GetDiagonal(Point& diagonal) const { diagonal = mExtents * 2.0f; }
364 inline_ float GetWidth() const { return mExtents.x * 2.0f; }
365 inline_ float GetHeight() const { return mExtents.y * 2.0f; }
366 inline_ float GetDepth() const { return mExtents.z * 2.0f; }
367
368 //! Volume
369 inline_ float GetVolume() const { return mExtents.x * mExtents.y * mExtents.z * 8.0f; }
370
371 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
372 /**
373 * Computes the intersection between two AABBs.
374 * \param a [in] the other AABB
375 * \return true on intersection
376 */
377 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
378 inline_ BOOL Intersect(const AABB& a) const
379 {
380 float tx = mCenter.x - a.mCenter.x; float ex = a.mExtents.x + mExtents.x; if(AIR(tx) > IR(ex)) return FALSE;
381 float ty = mCenter.y - a.mCenter.y; float ey = a.mExtents.y + mExtents.y; if(AIR(ty) > IR(ey)) return FALSE;
382 float tz = mCenter.z - a.mCenter.z; float ez = a.mExtents.z + mExtents.z; if(AIR(tz) > IR(ez)) return FALSE;
383 return TRUE;
384 }
385
386 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
387 /**
388 * The standard intersection method from Gamasutra. Just here to check its speed against the one above.
389 * \param a [in] the other AABB
390 * \return true on intersection
391 */
392 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
393 inline_ bool GomezIntersect(const AABB& a)
394 {
395 Point T = mCenter - a.mCenter; // Vector from A to B
396 return ((fabsf(T.x) <= (a.mExtents.x + mExtents.x))
397 && (fabsf(T.y) <= (a.mExtents.y + mExtents.y))
398 && (fabsf(T.z) <= (a.mExtents.z + mExtents.z)));
399 }
400
401 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
402 /**
403 * Computes the 1D-intersection between two AABBs, on a given axis.
404 * \param a [in] the other AABB
405 * \param axis [in] the axis (0, 1, 2)
406 * \return true on intersection
407 */
408 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
409 inline_ BOOL Intersect(const AABB& a, udword axis) const
410 {
411 float t = mCenter[axis] - a.mCenter[axis];
412 float e = a.mExtents[axis] + mExtents[axis];
413 if(AIR(t) > IR(e)) return FALSE;
414 return TRUE;
415 }
416
417 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
418 /**
419 * Recomputes the AABB after an arbitrary transform by a 4x4 matrix.
420 * \param mtx [in] the transform matrix
421 * \param aabb [out] the transformed AABB [can be *this]
422 */
423 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
424 inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const
425 {
426 // Compute new center
427 aabb.mCenter = mCenter * mtx;
428
429 // Compute new extents. FPU code & CPU code have been interleaved for improved performance.
430 Point Ex(mtx.m[0][0] * mExtents.x, mtx.m[0][1] * mExtents.x, mtx.m[0][2] * mExtents.x);
431 IR(Ex.x)&=0x7fffffff; IR(Ex.y)&=0x7fffffff; IR(Ex.z)&=0x7fffffff;
432
433 Point Ey(mtx.m[1][0] * mExtents.y, mtx.m[1][1] * mExtents.y, mtx.m[1][2] * mExtents.y);
434 IR(Ey.x)&=0x7fffffff; IR(Ey.y)&=0x7fffffff; IR(Ey.z)&=0x7fffffff;
435
436 Point Ez(mtx.m[2][0] * mExtents.z, mtx.m[2][1] * mExtents.z, mtx.m[2][2] * mExtents.z);
437 IR(Ez.x)&=0x7fffffff; IR(Ez.y)&=0x7fffffff; IR(Ez.z)&=0x7fffffff;
438
439 aabb.mExtents.x = Ex.x + Ey.x + Ez.x;
440 aabb.mExtents.y = Ex.y + Ey.y + Ez.y;
441 aabb.mExtents.z = Ex.z + Ey.z + Ez.z;
442 }
443
444 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
445 /**
446 * Checks the AABB is valid.
447 * \return true if the box is valid
448 */
449 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
450 inline_ BOOL IsValid() const
451 {
452 // Consistency condition for (Center, Extents) boxes: Extents >= 0
453 if(IS_NEGATIVE_FLOAT(mExtents.x)) return FALSE;
454 if(IS_NEGATIVE_FLOAT(mExtents.y)) return FALSE;
455 if(IS_NEGATIVE_FLOAT(mExtents.z)) return FALSE;
456 return TRUE;
457 }
458
459 //! Operator for AABB *= float. Scales the extents, keeps same center.
460 inline_ AABB& operator*=(float s) { mExtents*=s; return *this; }
461
462 //! Operator for AABB /= float. Scales the extents, keeps same center.
463 inline_ AABB& operator/=(float s) { mExtents/=s; return *this; }
464
465 //! Operator for AABB += Point. Translates the box.
466 inline_ AABB& operator+=(const Point& trans)
467 {
468 mCenter+=trans;
469 return *this;
470 }
471 private:
472 Point mCenter; //!< AABB Center
473 Point mExtents; //!< x, y and z extents
474 };
475
476#endif
477
478 inline_ void ComputeMinMax(const Point& p, Point& min, Point& max)
479 {
480 if(p.x > max.x) max.x = p.x;
481 if(p.x < min.x) min.x = p.x;
482
483 if(p.y > max.y) max.y = p.y;
484 if(p.y < min.y) min.y = p.y;
485
486 if(p.z > max.z) max.z = p.z;
487 if(p.z < min.z) min.z = p.z;
488 }
489
490 inline_ void ComputeAABB(AABB& aabb, const Point* list, udword nb_pts)
491 {
492 if(list)
493 {
494 Point Maxi(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);
495 Point Mini(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT);
496 while(nb_pts--)
497 {
498// _prefetch(list+1); // off by one ?
499 ComputeMinMax(*list++, Mini, Maxi);
500 }
501 aabb.SetMinMax(Mini, Maxi);
502 }
503 }
504
505#endif // __ICEAABB_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceAxes.h b/libraries/ode-0.9/OPCODE/Ice/IceAxes.h
new file mode 100644
index 0000000..8af57e1
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceAxes.h
@@ -0,0 +1,54 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains axes definition.
4 * \file IceAxes.h
5 * \author Pierre Terdiman
6 * \date January, 29, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEAXES_H__
13#define __ICEAXES_H__
14
15 enum PointComponent
16 {
17 X = 0,
18 Y = 1,
19 Z = 2,
20 W = 3,
21
22 FORCE_DWORD = 0x7fffffff
23 };
24
25 enum AxisOrder
26 {
27 AXES_XYZ = (X)|(Y<<2)|(Z<<4),
28 AXES_XZY = (X)|(Z<<2)|(Y<<4),
29 AXES_YXZ = (Y)|(X<<2)|(Z<<4),
30 AXES_YZX = (Y)|(Z<<2)|(X<<4),
31 AXES_ZXY = (Z)|(X<<2)|(Y<<4),
32 AXES_ZYX = (Z)|(Y<<2)|(X<<4),
33
34 AXES_FORCE_DWORD = 0x7fffffff
35 };
36
37 class ICEMATHS_API Axes
38 {
39 public:
40
41 inline_ Axes(AxisOrder order)
42 {
43 mAxis0 = (order ) & 3;
44 mAxis1 = (order>>2) & 3;
45 mAxis2 = (order>>4) & 3;
46 }
47 inline_ ~Axes() {}
48
49 udword mAxis0;
50 udword mAxis1;
51 udword mAxis2;
52 };
53
54#endif // __ICEAXES_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceBoundingSphere.h b/libraries/ode-0.9/OPCODE/Ice/IceBoundingSphere.h
new file mode 100644
index 0000000..945d38c
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceBoundingSphere.h
@@ -0,0 +1,142 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code to compute the minimal bounding sphere.
4 * \file IceBoundingSphere.h
5 * \author Pierre Terdiman
6 * \date January, 29, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEBOUNDINGSPHERE_H__
13#define __ICEBOUNDINGSPHERE_H__
14
15 enum BSphereMethod
16 {
17 BS_NONE,
18 BS_GEMS,
19 BS_MINIBALL,
20
21 BS_FORCE_DWORD = 0x7fffffff
22 };
23
24 class ICEMATHS_API Sphere
25 {
26 public:
27 //! Constructor
28 inline_ Sphere() {}
29 //! Constructor
30 inline_ Sphere(const Point& center, float radius) : mCenter(center), mRadius(radius) {}
31 //! Constructor
32 Sphere(udword nb_verts, const Point* verts);
33 //! Copy constructor
34 inline_ Sphere(const Sphere& sphere) : mCenter(sphere.mCenter), mRadius(sphere.mRadius) {}
35 //! Destructor
36 inline_ ~Sphere() {}
37
38 BSphereMethod Compute(udword nb_verts, const Point* verts);
39 bool FastCompute(udword nb_verts, const Point* verts);
40
41 // Access methods
42 inline_ const Point& GetCenter() const { return mCenter; }
43 inline_ float GetRadius() const { return mRadius; }
44
45 inline_ const Point& Center() const { return mCenter; }
46 inline_ float Radius() const { return mRadius; }
47
48 inline_ Sphere& Set(const Point& center, float radius) { mCenter = center; mRadius = radius; return *this; }
49 inline_ Sphere& SetCenter(const Point& center) { mCenter = center; return *this; }
50 inline_ Sphere& SetRadius(float radius) { mRadius = radius; return *this; }
51
52 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
53 /**
54 * Tests if a point is contained within the sphere.
55 * \param p [in] the point to test
56 * \return true if inside the sphere
57 */
58 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
59 inline_ bool Contains(const Point& p) const
60 {
61 return mCenter.SquareDistance(p) <= mRadius*mRadius;
62 }
63
64 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
65 /**
66 * Tests if a sphere is contained within the sphere.
67 * \param sphere [in] the sphere to test
68 * \return true if inside the sphere
69 */
70 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
71 inline_ bool Contains(const Sphere& sphere) const
72 {
73 // If our radius is the smallest, we can't possibly contain the other sphere
74 if(mRadius < sphere.mRadius) return false;
75 // So r is always positive or null now
76 float r = mRadius - sphere.mRadius;
77 return mCenter.SquareDistance(sphere.mCenter) <= r*r;
78 }
79
80 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 /**
82 * Tests if a box is contained within the sphere.
83 * \param aabb [in] the box to test
84 * \return true if inside the sphere
85 */
86 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
87 inline_ BOOL Contains(const AABB& aabb) const
88 {
89 // I assume if all 8 box vertices are inside the sphere, so does the whole box.
90 // Sounds ok but maybe there's a better way?
91 float R2 = mRadius * mRadius;
92#ifdef USE_MIN_MAX
93 const Point& Max = ((ShadowAABB&)&aabb).mMax;
94 const Point& Min = ((ShadowAABB&)&aabb).mMin;
95#else
96 Point Max; aabb.GetMax(Max);
97 Point Min; aabb.GetMin(Min);
98#endif
99 Point p;
100 p.x=Max.x; p.y=Max.y; p.z=Max.z; if(mCenter.SquareDistance(p)>=R2) return FALSE;
101 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
102 p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE;
103 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
104 p.x=Max.x; p.y=Max.y; p.z=Min.z; if(mCenter.SquareDistance(p)>=R2) return FALSE;
105 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
106 p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE;
107 p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE;
108
109 return TRUE;
110 }
111
112 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
113 /**
114 * Tests if the sphere intersects another sphere
115 * \param sphere [in] the other sphere
116 * \return true if spheres overlap
117 */
118 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
119 inline_ bool Intersect(const Sphere& sphere) const
120 {
121 float r = mRadius + sphere.mRadius;
122 return mCenter.SquareDistance(sphere.mCenter) <= r*r;
123 }
124
125 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
126 /**
127 * Checks the sphere is valid.
128 * \return true if the box is valid
129 */
130 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
131 inline_ BOOL IsValid() const
132 {
133 // Consistency condition for spheres: Radius >= 0.0f
134 if(mRadius < 0.0f) return FALSE;
135 return TRUE;
136 }
137 public:
138 Point mCenter; //!< Sphere center
139 float mRadius; //!< Sphere radius
140 };
141
142#endif // __ICEBOUNDINGSPHERE_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp b/libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp
new file mode 100644
index 0000000..8a4a570
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp
@@ -0,0 +1,345 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains a simple container class.
4 * \file IceContainer.cpp
5 * \author Pierre Terdiman
6 * \date February, 5, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * Contains a list of 32-bits values.
13 * Use this class when you need to store an unknown number of values. The list is automatically
14 * resized and can contains 32-bits entities (dwords or floats)
15 *
16 * \class Container
17 * \author Pierre Terdiman
18 * \version 1.0
19 * \date 08.15.98
20*/
21///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
22
23///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24// Precompiled Header
25#include "Stdafx.h"
26
27using namespace IceCore;
28
29// Static members
30#ifdef CONTAINER_STATS
31udword Container::mNbContainers = 0;
32udword Container::mUsedRam = 0;
33#endif
34
35///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36/**
37 * Constructor. No entries allocated there.
38 */
39///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
40Container::Container() : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
41{
42#ifdef CONTAINER_STATS
43 mNbContainers++;
44 mUsedRam+=sizeof(Container);
45#endif
46}
47
48///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
49/**
50 * Constructor. Also allocates a given number of entries.
51 */
52///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
53Container::Container(udword size, float growth_factor) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(growth_factor)
54{
55#ifdef CONTAINER_STATS
56 mNbContainers++;
57 mUsedRam+=sizeof(Container);
58#endif
59 SetSize(size);
60}
61
62///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
63/**
64 * Copy constructor.
65 */
66///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
67Container::Container(const Container& object) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
68{
69#ifdef CONTAINER_STATS
70 mNbContainers++;
71 mUsedRam+=sizeof(Container);
72#endif
73 *this = object;
74}
75
76///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
77/**
78 * Destructor. Frees everything and leaves.
79 */
80///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81Container::~Container()
82{
83 Empty();
84#ifdef CONTAINER_STATS
85 mNbContainers--;
86 mUsedRam-=GetUsedRam();
87#endif
88}
89
90///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91/**
92 * Clears the container. All stored values are deleted, and it frees used ram.
93 * \see Reset()
94 * \return Self-Reference
95 */
96///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
97Container& Container::Empty()
98{
99#ifdef CONTAINER_STATS
100 mUsedRam-=mMaxNbEntries*sizeof(udword);
101#endif
102 DELETEARRAY(mEntries);
103 mCurNbEntries = mMaxNbEntries = 0;
104 return *this;
105}
106
107///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
108/**
109 * Resizes the container.
110 * \param needed [in] assume the container can be added at least "needed" values
111 * \return true if success.
112 */
113///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
114bool Container::Resize(udword needed)
115{
116#ifdef CONTAINER_STATS
117 // Subtract previous amount of bytes
118 mUsedRam-=mMaxNbEntries*sizeof(udword);
119#endif
120
121 // Get more entries
122 mMaxNbEntries = mMaxNbEntries ? udword(float(mMaxNbEntries)*mGrowthFactor) : 2; // Default nb Entries = 2
123 if(mMaxNbEntries<mCurNbEntries + needed) mMaxNbEntries = mCurNbEntries + needed;
124
125 // Get some bytes for new entries
126 udword* NewEntries = new udword[mMaxNbEntries];
127 CHECKALLOC(NewEntries);
128
129#ifdef CONTAINER_STATS
130 // Add current amount of bytes
131 mUsedRam+=mMaxNbEntries*sizeof(udword);
132#endif
133
134 // Copy old data if needed
135 if(mCurNbEntries) CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
136
137 // Delete old data
138 DELETEARRAY(mEntries);
139
140 // Assign new pointer
141 mEntries = NewEntries;
142
143 return true;
144}
145
146///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
147/**
148 * Sets the initial size of the container. If it already contains something, it's discarded.
149 * \param nb [in] Number of entries
150 * \return true if success
151 */
152///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
153bool Container::SetSize(udword nb)
154{
155 // Make sure it's empty
156 Empty();
157
158 // Checkings
159 if(!nb) return false;
160
161 // Initialize for nb entries
162 mMaxNbEntries = nb;
163
164 // Get some bytes for new entries
165 mEntries = new udword[mMaxNbEntries];
166 CHECKALLOC(mEntries);
167
168#ifdef CONTAINER_STATS
169 // Add current amount of bytes
170 mUsedRam+=mMaxNbEntries*sizeof(udword);
171#endif
172 return true;
173}
174
175///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
176/**
177 * Refits the container and get rid of unused bytes.
178 * \return true if success
179 */
180///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
181bool Container::Refit()
182{
183#ifdef CONTAINER_STATS
184 // Subtract previous amount of bytes
185 mUsedRam-=mMaxNbEntries*sizeof(udword);
186#endif
187
188 // Get just enough entries
189 mMaxNbEntries = mCurNbEntries;
190 if(!mMaxNbEntries) return false;
191
192 // Get just enough bytes
193 udword* NewEntries = new udword[mMaxNbEntries];
194 CHECKALLOC(NewEntries);
195
196#ifdef CONTAINER_STATS
197 // Add current amount of bytes
198 mUsedRam+=mMaxNbEntries*sizeof(udword);
199#endif
200
201 // Copy old data
202 CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
203
204 // Delete old data
205 DELETEARRAY(mEntries);
206
207 // Assign new pointer
208 mEntries = NewEntries;
209
210 return true;
211}
212
213///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
214/**
215 * Checks whether the container already contains a given value.
216 * \param entry [in] the value to look for in the container
217 * \param location [out] a possible pointer to store the entry location
218 * \see Add(udword entry)
219 * \see Add(float entry)
220 * \see Empty()
221 * \return true if the value has been found in the container, else false.
222 */
223///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
224bool Container::Contains(udword entry, udword* location) const
225{
226 // Look for the entry
227 for(udword i=0;i<mCurNbEntries;i++)
228 {
229 if(mEntries[i]==entry)
230 {
231 if(location) *location = i;
232 return true;
233 }
234 }
235 return false;
236}
237
238///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
239/**
240 * Deletes an entry. If the container contains such an entry, it's removed.
241 * \param entry [in] the value to delete.
242 * \return true if the value has been found in the container, else false.
243 * \warning This method is arbitrary slow (O(n)) and should be used carefully. Insertion order is not preserved.
244 */
245///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
246bool Container::Delete(udword entry)
247{
248 // Look for the entry
249 for(udword i=0;i<mCurNbEntries;i++)
250 {
251 if(mEntries[i]==entry)
252 {
253 // Entry has been found at index i. The strategy is to copy the last current entry at index i, and decrement the current number of entries.
254 DeleteIndex(i);
255 return true;
256 }
257 }
258 return false;
259}
260
261///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
262/**
263 * Deletes an entry, preserving the insertion order. If the container contains such an entry, it's removed.
264 * \param entry [in] the value to delete.
265 * \return true if the value has been found in the container, else false.
266 * \warning This method is arbitrary slow (O(n)) and should be used carefully.
267 */
268///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
269bool Container::DeleteKeepingOrder(udword entry)
270{
271 // Look for the entry
272 for(udword i=0;i<mCurNbEntries;i++)
273 {
274 if(mEntries[i]==entry)
275 {
276 // Entry has been found at index i.
277 // Shift entries to preserve order. You really should use a linked list instead.
278 mCurNbEntries--;
279 for(udword j=i;j<mCurNbEntries;j++)
280 {
281 mEntries[j] = mEntries[j+1];
282 }
283 return true;
284 }
285 }
286 return false;
287}
288
289///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
290/**
291 * Gets the next entry, starting from input one.
292 * \param entry [in/out] On input, the entry to look for. On output, the next entry
293 * \param find_mode [in] wrap/clamp
294 * \return Self-Reference
295 */
296///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
297Container& Container::FindNext(udword& entry, FindMode find_mode)
298{
299 udword Location;
300 if(Contains(entry, &Location))
301 {
302 Location++;
303 if(Location==mCurNbEntries) Location = find_mode==FIND_WRAP ? 0 : mCurNbEntries-1;
304 entry = mEntries[Location];
305 }
306 return *this;
307}
308
309///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
310/**
311 * Gets the previous entry, starting from input one.
312 * \param entry [in/out] On input, the entry to look for. On output, the previous entry
313 * \param find_mode [in] wrap/clamp
314 * \return Self-Reference
315 */
316///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
317Container& Container::FindPrev(udword& entry, FindMode find_mode)
318{
319 udword Location;
320 if(Contains(entry, &Location))
321 {
322 Location--;
323 if(Location==0xffffffff) Location = find_mode==FIND_WRAP ? mCurNbEntries-1 : 0;
324 entry = mEntries[Location];
325 }
326 return *this;
327}
328
329///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
330/**
331 * Gets the ram used by the container.
332 * \return the ram used in bytes.
333 */
334///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
335udword Container::GetUsedRam() const
336{
337 return sizeof(Container) + mMaxNbEntries * sizeof(udword);
338}
339
340/*void Container::operator=(const Container& object)
341{
342 SetSize(object.GetNbEntries());
343 CopyMemory(mEntries, object.GetEntries(), mMaxNbEntries*sizeof(udword));
344 mCurNbEntries = mMaxNbEntries;
345}*/
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceContainer.h b/libraries/ode-0.9/OPCODE/Ice/IceContainer.h
new file mode 100644
index 0000000..d726c2a
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceContainer.h
@@ -0,0 +1,212 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains a simple container class.
4 * \file IceContainer.h
5 * \author Pierre Terdiman
6 * \date February, 5, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICECONTAINER_H__
13#define __ICECONTAINER_H__
14
15 #define CONTAINER_STATS
16
17 enum FindMode
18 {
19 FIND_CLAMP,
20 FIND_WRAP,
21
22 FIND_FORCE_DWORD = 0x7fffffff
23 };
24
25 class ICECORE_API Container
26 {
27 public:
28 // Constructor / Destructor
29 Container();
30 Container(const Container& object);
31 Container(udword size, float growth_factor);
32 ~Container();
33 // Management
34 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
35 /**
36 * A O(1) method to add a value in the container. The container is automatically resized if needed.
37 * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
38 * costs a lot more than the call overhead...
39 *
40 * \param entry [in] a udword to store in the container
41 * \see Add(float entry)
42 * \see Empty()
43 * \see Contains(udword entry)
44 * \return Self-Reference
45 */
46 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
47 inline_ Container& Add(udword entry)
48 {
49 // Resize if needed
50 if(mCurNbEntries==mMaxNbEntries) Resize();
51
52 // Add new entry
53 mEntries[mCurNbEntries++] = entry;
54 return *this;
55 }
56
57 inline_ Container& Add(const udword* entries, udword nb)
58 {
59 // Resize if needed
60 if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
61
62 // Add new entry
63 CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword));
64 mCurNbEntries+=nb;
65 return *this;
66 }
67
68 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
69 /**
70 * A O(1) method to add a value in the container. The container is automatically resized if needed.
71 * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
72 * costs a lot more than the call overhead...
73 *
74 * \param entry [in] a float to store in the container
75 * \see Add(udword entry)
76 * \see Empty()
77 * \see Contains(udword entry)
78 * \return Self-Reference
79 */
80 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 inline_ Container& Add(float entry)
82 {
83 // Resize if needed
84 if(mCurNbEntries==mMaxNbEntries) Resize();
85
86 // Add new entry
87 mEntries[mCurNbEntries++] = IR(entry);
88 return *this;
89 }
90
91 inline_ Container& Add(const float* entries, udword nb)
92 {
93 // Resize if needed
94 if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
95
96 // Add new entry
97 CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float));
98 mCurNbEntries+=nb;
99 return *this;
100 }
101
102 //! Add unique [slow]
103 inline_ Container& AddUnique(udword entry)
104 {
105 if(!Contains(entry)) Add(entry);
106 return *this;
107 }
108
109 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
110 /**
111 * Clears the container. All stored values are deleted, and it frees used ram.
112 * \see Reset()
113 * \return Self-Reference
114 */
115 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
116 Container& Empty();
117
118 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
119 /**
120 * Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again.
121 * That's a kind of temporal coherence.
122 * \see Empty()
123 */
124 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
125 inline_ void Reset()
126 {
127 // Avoid the write if possible
128 // ### CMOV
129 if(mCurNbEntries) mCurNbEntries = 0;
130 }
131
132 // HANDLE WITH CARE
133 inline_ void ForceSize(udword size)
134 {
135 mCurNbEntries = size;
136 }
137
138 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
139 /**
140 * Sets the initial size of the container. If it already contains something, it's discarded.
141 * \param nb [in] Number of entries
142 * \return true if success
143 */
144 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
145 bool SetSize(udword nb);
146
147 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
148 /**
149 * Refits the container and get rid of unused bytes.
150 * \return true if success
151 */
152 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
153 bool Refit();
154
155 // Checks whether the container already contains a given value.
156 bool Contains(udword entry, udword* location=null) const;
157 // Deletes an entry - doesn't preserve insertion order.
158 bool Delete(udword entry);
159 // Deletes an entry - does preserve insertion order.
160 bool DeleteKeepingOrder(udword entry);
161 //! Deletes the very last entry.
162 inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; }
163 //! Deletes the entry whose index is given
164 inline_ void DeleteIndex(udword index) { mEntries[index] = mEntries[--mCurNbEntries]; }
165
166 // Helpers
167 Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP);
168 Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP);
169 // Data access.
170 inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries.
171 inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry
172 inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries.
173
174 inline_ udword GetFirst() const { return mEntries[0]; }
175 inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; }
176
177 // Growth control
178 inline_ float GetGrowthFactor() const { return mGrowthFactor; } //!< Returns the growth factor
179 inline_ void SetGrowthFactor(float growth) { mGrowthFactor = growth; } //!< Sets the growth factor
180 inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full
181 inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty
182
183 //! Read-access as an array
184 inline_ udword operator[](udword i) const { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
185 //! Write-access as an array
186 inline_ udword& operator[](udword i) { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
187
188 // Stats
189 udword GetUsedRam() const;
190
191 //! Operator for "Container A = Container B"
192 //void operator = (const Container& object);
193
194#ifdef CONTAINER_STATS
195 inline_ udword GetNbContainers() const { return mNbContainers; }
196 inline_ udword GetTotalBytes() const { return mUsedRam; }
197 private:
198
199 static udword mNbContainers; //!< Number of containers around
200 static udword mUsedRam; //!< Amount of bytes used by containers in the system
201#endif
202 private:
203 // Resizing
204 bool Resize(udword needed=1);
205 // Data
206 udword mMaxNbEntries; //!< Maximum possible number of entries
207 udword mCurNbEntries; //!< Current number of entries
208 udword* mEntries; //!< List of entries
209 float mGrowthFactor; //!< Resize: new number of entries = old number * mGrowthFactor
210 };
211
212#endif // __ICECONTAINER_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceFPU.h b/libraries/ode-0.9/OPCODE/Ice/IceFPU.h
new file mode 100644
index 0000000..0cae4cb
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceFPU.h
@@ -0,0 +1,337 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains FPU related code.
4 * \file IceFPU.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEFPU_H__
13#define __ICEFPU_H__
14
15 #define SIGN_BITMASK 0x80000000
16
17 //! Integer representation of a floating-point value.
18 #define IR(x) ((udword&)(x))
19
20 //! Signed integer representation of a floating-point value.
21 #define SIR(x) ((sdword&)(x))
22
23 //! Absolute integer representation of a floating-point value
24 #define AIR(x) (IR(x)&0x7fffffff)
25
26 //! Floating-point representation of an integer value.
27 #define FR(x) ((float&)(x))
28
29 //! Integer-based comparison of a floating point value.
30 //! Don't use it blindly, it can be faster or slower than the FPU comparison, depends on the context.
31 #define IS_NEGATIVE_FLOAT(x) (IR(x)&0x80000000)
32
33 //! Fast fabs for floating-point values. It just clears the sign bit.
34 //! Don't use it blindy, it can be faster or slower than the FPU comparison, depends on the context.
35 inline_ float FastFabs(float x)
36 {
37 udword FloatBits = IR(x)&0x7fffffff;
38 return FR(FloatBits);
39 }
40
41 //! Fast square root for floating-point values.
42 inline_ float FastSqrt(float square)
43 {
44#ifdef _MSC_VER
45 float retval;
46
47 __asm {
48 mov eax, square
49 sub eax, 0x3F800000
50 sar eax, 1
51 add eax, 0x3F800000
52 mov [retval], eax
53 }
54 return retval;
55#else
56 return sqrt(square);
57#endif
58 }
59
60 //! Saturates positive to zero.
61 inline_ float fsat(float f)
62 {
63 udword y = (udword&)f & ~((sdword&)f >>31);
64 return (float&)y;
65 }
66
67 //! Computes 1.0f / sqrtf(x).
68 inline_ float frsqrt(float f)
69 {
70 float x = f * 0.5f;
71 udword y = 0x5f3759df - ((udword&)f >> 1);
72 // Iteration...
73 (float&)y = (float&)y * ( 1.5f - ( x * (float&)y * (float&)y ) );
74 // Result
75 return (float&)y;
76 }
77
78 //! Computes 1.0f / sqrtf(x). Comes from NVIDIA.
79 inline_ float InvSqrt(const float& x)
80 {
81 udword tmp = (udword(IEEE_1_0 << 1) + IEEE_1_0 - *(udword*)&x) >> 1;
82 float y = *(float*)&tmp;
83 return y * (1.47f - 0.47f * x * y * y);
84 }
85
86 //! Computes 1.0f / sqrtf(x). Comes from Quake3. Looks like the first one I had above.
87 //! See http://www.magic-software.com/3DGEDInvSqrt.html
88 inline_ float RSqrt(float number)
89 {
90 long i;
91 float x2, y;
92 const float threehalfs = 1.5f;
93
94 x2 = number * 0.5f;
95 y = number;
96 i = * (long *) &y;
97 i = 0x5f3759df - (i >> 1);
98 y = * (float *) &i;
99 y = y * (threehalfs - (x2 * y * y));
100
101 return y;
102 }
103
104 //! TO BE DOCUMENTED
105 inline_ float fsqrt(float f)
106 {
107 udword y = ( ( (sdword&)f - 0x3f800000 ) >> 1 ) + 0x3f800000;
108 // Iteration...?
109 // (float&)y = (3.0f - ((float&)y * (float&)y) / f) * (float&)y * 0.5f;
110 // Result
111 return (float&)y;
112 }
113
114 //! Returns the float ranged espilon value.
115 inline_ float fepsilon(float f)
116 {
117 udword b = (udword&)f & 0xff800000;
118 udword a = b | 0x00000001;
119 (float&)a -= (float&)b;
120 // Result
121 return (float&)a;
122 }
123
124 //! Is the float valid ?
125 inline_ bool IsNAN(float value) { return (IR(value)&0x7f800000) == 0x7f800000; }
126 inline_ bool IsIndeterminate(float value) { return IR(value) == 0xffc00000; }
127 inline_ bool IsPlusInf(float value) { return IR(value) == 0x7f800000; }
128 inline_ bool IsMinusInf(float value) { return IR(value) == 0xff800000; }
129
130 inline_ bool IsValidFloat(float value)
131 {
132 if(IsNAN(value)) return false;
133 if(IsIndeterminate(value)) return false;
134 if(IsPlusInf(value)) return false;
135 if(IsMinusInf(value)) return false;
136 return true;
137 }
138
139 #define CHECK_VALID_FLOAT(x) ASSERT(IsValidFloat(x));
140
141/*
142 //! FPU precision setting function.
143 inline_ void SetFPU()
144 {
145 // This function evaluates whether the floating-point
146 // control word is set to single precision/round to nearest/
147 // exceptions disabled. If these conditions don't hold, the
148 // function changes the control word to set them and returns
149 // TRUE, putting the old control word value in the passback
150 // location pointed to by pwOldCW.
151 {
152 uword wTemp, wSave;
153
154 __asm fstcw wSave
155 if (wSave & 0x300 || // Not single mode
156 0x3f != (wSave & 0x3f) || // Exceptions enabled
157 wSave & 0xC00) // Not round to nearest mode
158 {
159 __asm
160 {
161 mov ax, wSave
162 and ax, not 300h ;; single mode
163 or ax, 3fh ;; disable all exceptions
164 and ax, not 0xC00 ;; round to nearest mode
165 mov wTemp, ax
166 fldcw wTemp
167 }
168 }
169 }
170 }
171*/
172 //! This function computes the slowest possible floating-point value (you can also directly use FLT_EPSILON)
173 inline_ float ComputeFloatEpsilon()
174 {
175 float f = 1.0f;
176 ((udword&)f)^=1;
177 return f - 1.0f; // You can check it's the same as FLT_EPSILON
178 }
179
180 inline_ bool IsFloatZero(float x, float epsilon=1e-6f)
181 {
182 return x*x < epsilon;
183 }
184
185 #define FCOMI_ST0 _asm _emit 0xdb _asm _emit 0xf0
186 #define FCOMIP_ST0 _asm _emit 0xdf _asm _emit 0xf0
187 #define FCMOVB_ST0 _asm _emit 0xda _asm _emit 0xc0
188 #define FCMOVNB_ST0 _asm _emit 0xdb _asm _emit 0xc0
189
190 #define FCOMI_ST1 _asm _emit 0xdb _asm _emit 0xf1
191 #define FCOMIP_ST1 _asm _emit 0xdf _asm _emit 0xf1
192 #define FCMOVB_ST1 _asm _emit 0xda _asm _emit 0xc1
193 #define FCMOVNB_ST1 _asm _emit 0xdb _asm _emit 0xc1
194
195 #define FCOMI_ST2 _asm _emit 0xdb _asm _emit 0xf2
196 #define FCOMIP_ST2 _asm _emit 0xdf _asm _emit 0xf2
197 #define FCMOVB_ST2 _asm _emit 0xda _asm _emit 0xc2
198 #define FCMOVNB_ST2 _asm _emit 0xdb _asm _emit 0xc2
199
200 #define FCOMI_ST3 _asm _emit 0xdb _asm _emit 0xf3
201 #define FCOMIP_ST3 _asm _emit 0xdf _asm _emit 0xf3
202 #define FCMOVB_ST3 _asm _emit 0xda _asm _emit 0xc3
203 #define FCMOVNB_ST3 _asm _emit 0xdb _asm _emit 0xc3
204
205 #define FCOMI_ST4 _asm _emit 0xdb _asm _emit 0xf4
206 #define FCOMIP_ST4 _asm _emit 0xdf _asm _emit 0xf4
207 #define FCMOVB_ST4 _asm _emit 0xda _asm _emit 0xc4
208 #define FCMOVNB_ST4 _asm _emit 0xdb _asm _emit 0xc4
209
210 #define FCOMI_ST5 _asm _emit 0xdb _asm _emit 0xf5
211 #define FCOMIP_ST5 _asm _emit 0xdf _asm _emit 0xf5
212 #define FCMOVB_ST5 _asm _emit 0xda _asm _emit 0xc5
213 #define FCMOVNB_ST5 _asm _emit 0xdb _asm _emit 0xc5
214
215 #define FCOMI_ST6 _asm _emit 0xdb _asm _emit 0xf6
216 #define FCOMIP_ST6 _asm _emit 0xdf _asm _emit 0xf6
217 #define FCMOVB_ST6 _asm _emit 0xda _asm _emit 0xc6
218 #define FCMOVNB_ST6 _asm _emit 0xdb _asm _emit 0xc6
219
220 #define FCOMI_ST7 _asm _emit 0xdb _asm _emit 0xf7
221 #define FCOMIP_ST7 _asm _emit 0xdf _asm _emit 0xf7
222 #define FCMOVB_ST7 _asm _emit 0xda _asm _emit 0xc7
223 #define FCMOVNB_ST7 _asm _emit 0xdb _asm _emit 0xc7
224
225 //! A global function to find MAX(a,b) using FCOMI/FCMOV
226 inline_ float FCMax2(float a, float b)
227 {
228#ifdef _MSC_VER
229 float Res;
230 _asm fld [a]
231 _asm fld [b]
232 FCOMI_ST1
233 FCMOVB_ST1
234 _asm fstp [Res]
235 _asm fcomp
236 return Res;
237#else
238 return (a > b) ? a : b;
239#endif
240 }
241
242 //! A global function to find MIN(a,b) using FCOMI/FCMOV
243 inline_ float FCMin2(float a, float b)
244 {
245#ifdef _MSC_VER
246 float Res;
247 _asm fld [a]
248 _asm fld [b]
249 FCOMI_ST1
250 FCMOVNB_ST1
251 _asm fstp [Res]
252 _asm fcomp
253 return Res;
254#else
255 return (a < b) ? a : b;
256#endif
257 }
258
259 //! A global function to find MAX(a,b,c) using FCOMI/FCMOV
260 inline_ float FCMax3(float a, float b, float c)
261 {
262#ifdef _MSC_VER
263 float Res;
264 _asm fld [a]
265 _asm fld [b]
266 _asm fld [c]
267 FCOMI_ST1
268 FCMOVB_ST1
269 FCOMI_ST2
270 FCMOVB_ST2
271 _asm fstp [Res]
272 _asm fcompp
273 return Res;
274#else
275 return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
276#endif
277 }
278
279 //! A global function to find MIN(a,b,c) using FCOMI/FCMOV
280 inline_ float FCMin3(float a, float b, float c)
281 {
282#ifdef _MSC_VER
283 float Res;
284 _asm fld [a]
285 _asm fld [b]
286 _asm fld [c]
287 FCOMI_ST1
288 FCMOVNB_ST1
289 FCOMI_ST2
290 FCMOVNB_ST2
291 _asm fstp [Res]
292 _asm fcompp
293 return Res;
294#else
295 return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c);
296#endif
297 }
298
299 inline_ int ConvertToSortable(float f)
300 {
301 int& Fi = (int&)f;
302 int Fmask = (Fi>>31);
303 Fi ^= Fmask;
304 Fmask &= ~(1<<31);
305 Fi -= Fmask;
306 return Fi;
307 }
308
309 enum FPUMode
310 {
311 FPU_FLOOR = 0,
312 FPU_CEIL = 1,
313 FPU_BEST = 2,
314
315 FPU_FORCE_DWORD = 0x7fffffff
316 };
317
318 FUNCTION ICECORE_API FPUMode GetFPUMode();
319 FUNCTION ICECORE_API void SaveFPU();
320 FUNCTION ICECORE_API void RestoreFPU();
321 FUNCTION ICECORE_API void SetFPUFloorMode();
322 FUNCTION ICECORE_API void SetFPUCeilMode();
323 FUNCTION ICECORE_API void SetFPUBestMode();
324
325 FUNCTION ICECORE_API void SetFPUPrecision24();
326 FUNCTION ICECORE_API void SetFPUPrecision53();
327 FUNCTION ICECORE_API void SetFPUPrecision64();
328 FUNCTION ICECORE_API void SetFPURoundingChop();
329 FUNCTION ICECORE_API void SetFPURoundingUp();
330 FUNCTION ICECORE_API void SetFPURoundingDown();
331 FUNCTION ICECORE_API void SetFPURoundingNear();
332
333 FUNCTION ICECORE_API int intChop(const float& f);
334 FUNCTION ICECORE_API int intFloor(const float& f);
335 FUNCTION ICECORE_API int intCeil(const float& f);
336
337#endif // __ICEFPU_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceHPoint.cpp b/libraries/ode-0.9/OPCODE/Ice/IceHPoint.cpp
new file mode 100644
index 0000000..f806a0c
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceHPoint.cpp
@@ -0,0 +1,70 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for homogeneous points.
4 * \file IceHPoint.cpp
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * Homogeneous point.
13 *
14 * Use it:
15 * - for clipping in homogeneous space (standard way)
16 * - to differentiate between points (w=1) and vectors (w=0).
17 * - in some cases you can also use it instead of Point for padding reasons.
18 *
19 * \class HPoint
20 * \author Pierre Terdiman
21 * \version 1.0
22 * \warning No cross-product in 4D.
23 * \warning HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4
24 */
25///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26
27///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28// Precompiled Header
29#include "Stdafx.h"
30
31using namespace IceMaths;
32
33///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
34// Point Mul = HPoint * Matrix3x3;
35///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36Point HPoint::operator*(const Matrix3x3& mat) const
37{
38 return Point(
39 x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0],
40 x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1],
41 x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] );
42}
43
44///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
45// HPoint Mul = HPoint * Matrix4x4;
46///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
47HPoint HPoint::operator*(const Matrix4x4& mat) const
48{
49 return HPoint(
50 x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0],
51 x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1],
52 x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2],
53 x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3]);
54}
55
56///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
57// HPoint *= Matrix4x4
58///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
59HPoint& HPoint::operator*=(const Matrix4x4& mat)
60{
61 float xp = x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0];
62 float yp = x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1];
63 float zp = x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2];
64 float wp = x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3];
65
66 x = xp; y = yp; z = zp; w = wp;
67
68 return *this;
69}
70
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceHPoint.h b/libraries/ode-0.9/OPCODE/Ice/IceHPoint.h
new file mode 100644
index 0000000..a3770cd
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceHPoint.h
@@ -0,0 +1,160 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for homogeneous points.
4 * \file IceHPoint.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEHPOINT_H__
13#define __ICEHPOINT_H__
14
15 class ICEMATHS_API HPoint : public Point
16 {
17 public:
18
19 //! Empty constructor
20 inline_ HPoint() {}
21 //! Constructor from floats
22 inline_ HPoint(float xx, float yy, float zz, float ww=0.0f) : Point(xx, yy, zz), w(ww) {}
23 //! Constructor from array
24 inline_ HPoint(const float f[4]) : Point(f), w(f[3]) {}
25 //! Constructor from a Point
26 inline_ HPoint(const Point& p, float ww=0.0f) : Point(p), w(ww) {}
27 //! Destructor
28 inline_ ~HPoint() {}
29
30 //! Clear the point
31 inline_ HPoint& Zero() { x = y = z = w = 0.0f; return *this; }
32
33 //! Assignment from values
34 inline_ HPoint& Set(float xx, float yy, float zz, float ww ) { x = xx; y = yy; z = zz; w = ww; return *this; }
35 //! Assignment from array
36 inline_ HPoint& Set(const float f[4]) { x = f[X]; y = f[Y]; z = f[Z]; w = f[W]; return *this; }
37 //! Assignment from another h-point
38 inline_ HPoint& Set(const HPoint& src) { x = src.x; y = src.y; z = src.z; w = src.w; return *this; }
39
40 //! Add a vector
41 inline_ HPoint& Add(float xx, float yy, float zz, float ww ) { x += xx; y += yy; z += zz; w += ww; return *this; }
42 //! Add a vector
43 inline_ HPoint& Add(const float f[4]) { x += f[X]; y += f[Y]; z += f[Z]; w += f[W]; return *this; }
44
45 //! Subtract a vector
46 inline_ HPoint& Sub(float xx, float yy, float zz, float ww ) { x -= xx; y -= yy; z -= zz; w -= ww; return *this; }
47 //! Subtract a vector
48 inline_ HPoint& Sub(const float f[4]) { x -= f[X]; y -= f[Y]; z -= f[Z]; w -= f[W]; return *this; }
49
50 //! Multiplies by a scalar
51 inline_ HPoint& Mul(float s) { x *= s; y *= s; z *= s; w *= s; return *this; }
52
53 //! Returns MIN(x, y, z, w);
54 float Min() const { return MIN(x, MIN(y, MIN(z, w))); }
55 //! Returns MAX(x, y, z, w);
56 float Max() const { return MAX(x, MAX(y, MAX(z, w))); }
57 //! Sets each element to be componentwise minimum
58 HPoint& Min(const HPoint& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); w = MIN(w, p.w); return *this; }
59 //! Sets each element to be componentwise maximum
60 HPoint& Max(const HPoint& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); w = MAX(w, p.w); return *this; }
61
62 //! Computes square magnitude
63 inline_ float SquareMagnitude() const { return x*x + y*y + z*z + w*w; }
64 //! Computes magnitude
65 inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z + w*w); }
66
67 //! Normalize the vector
68 inline_ HPoint& Normalize()
69 {
70 float M = Magnitude();
71 if(M)
72 {
73 M = 1.0f / M;
74 x *= M;
75 y *= M;
76 z *= M;
77 w *= M;
78 }
79 return *this;
80 }
81
82 // Arithmetic operators
83 //! Operator for HPoint Negate = - HPoint;
84 inline_ HPoint operator-() const { return HPoint(-x, -y, -z, -w); }
85
86 //! Operator for HPoint Plus = HPoint + HPoint;
87 inline_ HPoint operator+(const HPoint& p) const { return HPoint(x + p.x, y + p.y, z + p.z, w + p.w); }
88 //! Operator for HPoint Minus = HPoint - HPoint;
89 inline_ HPoint operator-(const HPoint& p) const { return HPoint(x - p.x, y - p.y, z - p.z, w - p.w); }
90
91 //! Operator for HPoint Mul = HPoint * HPoint;
92 inline_ HPoint operator*(const HPoint& p) const { return HPoint(x * p.x, y * p.y, z * p.z, w * p.w); }
93 //! Operator for HPoint Scale = HPoint * float;
94 inline_ HPoint operator*(float s) const { return HPoint(x * s, y * s, z * s, w * s); }
95 //! Operator for HPoint Scale = float * HPoint;
96 inline_ friend HPoint operator*(float s, const HPoint& p) { return HPoint(s * p.x, s * p.y, s * p.z, s * p.w); }
97
98 //! Operator for HPoint Div = HPoint / HPoint;
99 inline_ HPoint operator/(const HPoint& p) const { return HPoint(x / p.x, y / p.y, z / p.z, w / p.w); }
100 //! Operator for HPoint Scale = HPoint / float;
101 inline_ HPoint operator/(float s) const { s = 1.0f / s; return HPoint(x * s, y * s, z * s, w * s); }
102 //! Operator for HPoint Scale = float / HPoint;
103 inline_ friend HPoint operator/(float s, const HPoint& p) { return HPoint(s / p.x, s / p.y, s / p.z, s / p.w); }
104
105 //! Operator for float DotProd = HPoint | HPoint;
106 inline_ float operator|(const HPoint& p) const { return x*p.x + y*p.y + z*p.z + w*p.w; }
107 // No cross-product in 4D
108
109 //! Operator for HPoint += HPoint;
110 inline_ HPoint& operator+=(const HPoint& p) { x += p.x; y += p.y; z += p.z; w += p.w; return *this; }
111 //! Operator for HPoint += float;
112 inline_ HPoint& operator+=(float s) { x += s; y += s; z += s; w += s; return *this; }
113
114 //! Operator for HPoint -= HPoint;
115 inline_ HPoint& operator-=(const HPoint& p) { x -= p.x; y -= p.y; z -= p.z; w -= p.w; return *this; }
116 //! Operator for HPoint -= float;
117 inline_ HPoint& operator-=(float s) { x -= s; y -= s; z -= s; w -= s; return *this; }
118
119 //! Operator for HPoint *= HPoint;
120 inline_ HPoint& operator*=(const HPoint& p) { x *= p.x; y *= p.y; z *= p.z; w *= p.w; return *this; }
121 //! Operator for HPoint *= float;
122 inline_ HPoint& operator*=(float s) { x*=s; y*=s; z*=s; w*=s; return *this; }
123
124 //! Operator for HPoint /= HPoint;
125 inline_ HPoint& operator/=(const HPoint& p) { x /= p.x; y /= p.y; z /= p.z; w /= p.w; return *this; }
126 //! Operator for HPoint /= float;
127 inline_ HPoint& operator/=(float s) { s = 1.0f / s; x*=s; y*=s; z*=s; w*=s; return *this; }
128
129 // Arithmetic operators
130
131 //! Operator for Point Mul = HPoint * Matrix3x3;
132 Point operator*(const Matrix3x3& mat) const;
133 //! Operator for HPoint Mul = HPoint * Matrix4x4;
134 HPoint operator*(const Matrix4x4& mat) const;
135
136 // HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4
137 //! Operator for HPoint *= Matrix4x4
138 HPoint& operator*=(const Matrix4x4& mat);
139
140 // Logical operators
141
142 //! Operator for "if(HPoint==HPoint)"
143 inline_ bool operator==(const HPoint& p) const { return ( (x==p.x)&&(y==p.y)&&(z==p.z)&&(w==p.w)); }
144 //! Operator for "if(HPoint!=HPoint)"
145 inline_ bool operator!=(const HPoint& p) const { return ( (x!=p.x)||(y!=p.y)||(z!=p.z)||(w!=p.w)); }
146
147 // Cast operators
148
149 //! Cast a HPoint to a Point. w is discarded.
150#ifdef _MSC_VER
151 inline_ operator Point() const { return Point(x, y, z); }
152 // gcc complains that conversion to a base class will never use a type conversion operator
153#endif
154
155 public:
156 float w;
157 };
158
159#endif // __ICEHPOINT_H__
160
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.cpp b/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.cpp
new file mode 100644
index 0000000..db279c4
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.cpp
@@ -0,0 +1,548 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains a handy indexed triangle class.
4 * \file IceIndexedTriangle.cpp
5 * \author Pierre Terdiman
6 * \date January, 17, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Precompiled Header
12#include "Stdafx.h"
13
14using namespace IceMaths;
15
16///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17/**
18 * Contains an indexed triangle class.
19 *
20 * \class Triangle
21 * \author Pierre Terdiman
22 * \version 1.0
23 * \date 08.15.98
24*/
25///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26
27///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28/**
29 * Flips the winding order.
30 */
31///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32void IndexedTriangle::Flip()
33{
34 Swap(mVRef[1], mVRef[2]);
35}
36
37///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
38/**
39 * Computes the triangle area.
40 * \param verts [in] the list of indexed vertices
41 * \return the area
42 */
43///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
44float IndexedTriangle::Area(const Point* verts) const
45{
46 if(!verts) return 0.0f;
47 const Point& p0 = verts[0];
48 const Point& p1 = verts[1];
49 const Point& p2 = verts[2];
50 return ((p0-p1)^(p0-p2)).Magnitude() * 0.5f;
51}
52
53///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54/**
55 * Computes the triangle perimeter.
56 * \param verts [in] the list of indexed vertices
57 * \return the perimeter
58 */
59///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60float IndexedTriangle::Perimeter(const Point* verts) const
61{
62 if(!verts) return 0.0f;
63 const Point& p0 = verts[0];
64 const Point& p1 = verts[1];
65 const Point& p2 = verts[2];
66 return p0.Distance(p1)
67 + p0.Distance(p2)
68 + p1.Distance(p2);
69}
70
71///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
72/**
73 * Computes the triangle compacity.
74 * \param verts [in] the list of indexed vertices
75 * \return the compacity
76 */
77///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
78float IndexedTriangle::Compacity(const Point* verts) const
79{
80 if(!verts) return 0.0f;
81 float P = Perimeter(verts);
82 if(P==0.0f) return 0.0f;
83 return (4.0f*PI*Area(verts)/(P*P));
84}
85
86///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
87/**
88 * Computes the triangle normal.
89 * \param verts [in] the list of indexed vertices
90 * \param normal [out] the computed normal
91 */
92///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93void IndexedTriangle::Normal(const Point* verts, Point& normal) const
94{
95 if(!verts) return;
96
97 const Point& p0 = verts[mVRef[0]];
98 const Point& p1 = verts[mVRef[1]];
99 const Point& p2 = verts[mVRef[2]];
100 normal = ((p2-p1)^(p0-p1)).Normalize();
101}
102
103///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
104/**
105 * Computes the triangle denormalized normal.
106 * \param verts [in] the list of indexed vertices
107 * \param normal [out] the computed normal
108 */
109///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
110void IndexedTriangle::DenormalizedNormal(const Point* verts, Point& normal) const
111{
112 if(!verts) return;
113
114 const Point& p0 = verts[mVRef[0]];
115 const Point& p1 = verts[mVRef[1]];
116 const Point& p2 = verts[mVRef[2]];
117 normal = ((p2-p1)^(p0-p1));
118}
119
120///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
121/**
122 * Computes the triangle center.
123 * \param verts [in] the list of indexed vertices
124 * \param center [out] the computed center
125 */
126///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
127void IndexedTriangle::Center(const Point* verts, Point& center) const
128{
129 if(!verts) return;
130
131 const Point& p0 = verts[mVRef[0]];
132 const Point& p1 = verts[mVRef[1]];
133 const Point& p2 = verts[mVRef[2]];
134 center = (p0+p1+p2)*INV3;
135}
136
137///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
138/**
139 * Computes the centered normal
140 * \param verts [in] the list of indexed vertices
141 * \param normal [out] the computed centered normal
142 */
143///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
144void IndexedTriangle::CenteredNormal(const Point* verts, Point& normal) const
145{
146 if(!verts) return;
147
148 const Point& p0 = verts[mVRef[0]];
149 const Point& p1 = verts[mVRef[1]];
150 const Point& p2 = verts[mVRef[2]];
151 Point Center = (p0+p1+p2)*INV3;
152 normal = Center + ((p2-p1)^(p0-p1)).Normalize();
153}
154
155///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
156/**
157 * Computes a random point within the triangle.
158 * \param verts [in] the list of indexed vertices
159 * \param normal [out] the computed centered normal
160 */
161///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
162void IndexedTriangle::RandomPoint(const Point* verts, Point& random) const
163{
164 if(!verts) return;
165
166 // Random barycentric coords
167 float Alpha = UnitRandomFloat();
168 float Beta = UnitRandomFloat();
169 float Gamma = UnitRandomFloat();
170 float OneOverTotal = 1.0f / (Alpha + Beta + Gamma);
171 Alpha *= OneOverTotal;
172 Beta *= OneOverTotal;
173 Gamma *= OneOverTotal;
174
175 const Point& p0 = verts[mVRef[0]];
176 const Point& p1 = verts[mVRef[1]];
177 const Point& p2 = verts[mVRef[2]];
178 random = Alpha*p0 + Beta*p1 + Gamma*p2;
179}
180
181///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
182/**
183 * Computes backface culling.
184 * \param verts [in] the list of indexed vertices
185 * \param source [in] source point (in local space) from which culling must be computed
186 * \return true if the triangle is visible from the source point
187 */
188///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
189bool IndexedTriangle::IsVisible(const Point* verts, const Point& source) const
190{
191 // Checkings
192 if(!verts) return false;
193
194 const Point& p0 = verts[mVRef[0]];
195 const Point& p1 = verts[mVRef[1]];
196 const Point& p2 = verts[mVRef[2]];
197
198 // Compute denormalized normal
199 Point Normal = (p2 - p1)^(p0 - p1);
200
201 // Backface culling
202 return (Normal | source) >= 0.0f;
203
204// Same as:
205// Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]);
206// return PL.Distance(source) > PL.d;
207}
208
209///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
210/**
211 * Computes backface culling.
212 * \param verts [in] the list of indexed vertices
213 * \param source [in] source point (in local space) from which culling must be computed
214 * \return true if the triangle is visible from the source point
215 */
216///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
217bool IndexedTriangle::BackfaceCulling(const Point* verts, const Point& source) const
218{
219 // Checkings
220 if(!verts) return false;
221
222 const Point& p0 = verts[mVRef[0]];
223 const Point& p1 = verts[mVRef[1]];
224 const Point& p2 = verts[mVRef[2]];
225
226 // Compute base
227// Point Base = (p0 + p1 + p2)*INV3;
228
229 // Compute denormalized normal
230 Point Normal = (p2 - p1)^(p0 - p1);
231
232 // Backface culling
233// return (Normal | (source - Base)) >= 0.0f;
234 return (Normal | (source - p0)) >= 0.0f;
235
236// Same as: (but a bit faster)
237// Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]);
238// return PL.Distance(source)>0.0f;
239}
240
241///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
242/**
243 * Computes the occlusion potential of the triangle.
244 * \param verts [in] the list of indexed vertices
245 * \param source [in] source point (in local space) from which occlusion potential must be computed
246 * \return the occlusion potential
247 */
248///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
249float IndexedTriangle::ComputeOcclusionPotential(const Point* verts, const Point& view) const
250{
251 if(!verts) return 0.0f;
252 // Occlusion potential: -(A * (N|V) / d^2)
253 // A = polygon area
254 // N = polygon normal
255 // V = view vector
256 // d = distance viewpoint-center of polygon
257
258 float A = Area(verts);
259 Point N; Normal(verts, N);
260 Point C; Center(verts, C);
261 float d = view.Distance(C);
262 return -(A*(N|view))/(d*d);
263}
264
265///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
266/**
267 * Replaces a vertex reference with another one.
268 * \param oldref [in] the vertex reference to replace
269 * \param newref [in] the new vertex reference
270 * \return true if success, else false if the input vertex reference doesn't belong to the triangle
271 */
272///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
273bool IndexedTriangle::ReplaceVertex(udword oldref, udword newref)
274{
275 if(mVRef[0]==oldref) { mVRef[0] = newref; return true; }
276 else if(mVRef[1]==oldref) { mVRef[1] = newref; return true; }
277 else if(mVRef[2]==oldref) { mVRef[2] = newref; return true; }
278 return false;
279}
280
281///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
282/**
283 * Checks whether the triangle is degenerate or not. A degenerate triangle has two common vertex references. This is a zero-area triangle.
284 * \return true if the triangle is degenerate
285 */
286///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
287bool IndexedTriangle::IsDegenerate() const
288{
289 if(mVRef[0]==mVRef[1]) return true;
290 if(mVRef[1]==mVRef[2]) return true;
291 if(mVRef[2]==mVRef[0]) return true;
292 return false;
293}
294
295///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
296/**
297 * Checks whether the input vertex reference belongs to the triangle or not.
298 * \param ref [in] the vertex reference to look for
299 * \return true if the triangle contains the vertex reference
300 */
301///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
302bool IndexedTriangle::HasVertex(udword ref) const
303{
304 if(mVRef[0]==ref) return true;
305 if(mVRef[1]==ref) return true;
306 if(mVRef[2]==ref) return true;
307 return false;
308}
309
310///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
311/**
312 * Checks whether the input vertex reference belongs to the triangle or not.
313 * \param ref [in] the vertex reference to look for
314 * \param index [out] the corresponding index in the triangle
315 * \return true if the triangle contains the vertex reference
316 */
317///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
318bool IndexedTriangle::HasVertex(udword ref, udword* index) const
319{
320 if(mVRef[0]==ref) { *index = 0; return true; }
321 if(mVRef[1]==ref) { *index = 1; return true; }
322 if(mVRef[2]==ref) { *index = 2; return true; }
323 return false;
324}
325
326///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
327/**
328 * Finds an edge in a tri, given two vertex references.
329 * \param vref0 [in] the edge's first vertex reference
330 * \param vref1 [in] the edge's second vertex reference
331 * \return the edge number between 0 and 2, or 0xff if input refs are wrong.
332 */
333///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
334ubyte IndexedTriangle::FindEdge(udword vref0, udword vref1) const
335{
336 if(mVRef[0]==vref0 && mVRef[1]==vref1) return 0;
337 else if(mVRef[0]==vref1 && mVRef[1]==vref0) return 0;
338 else if(mVRef[0]==vref0 && mVRef[2]==vref1) return 1;
339 else if(mVRef[0]==vref1 && mVRef[2]==vref0) return 1;
340 else if(mVRef[1]==vref0 && mVRef[2]==vref1) return 2;
341 else if(mVRef[1]==vref1 && mVRef[2]==vref0) return 2;
342 return 0xff;
343}
344
345///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
346/**
347 * Gets the last reference given the first two.
348 * \param vref0 [in] the first vertex reference
349 * \param vref1 [in] the second vertex reference
350 * \return the last reference, or INVALID_ID if input refs are wrong.
351 */
352///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
353udword IndexedTriangle::OppositeVertex(udword vref0, udword vref1) const
354{
355 if(mVRef[0]==vref0 && mVRef[1]==vref1) return mVRef[2];
356 else if(mVRef[0]==vref1 && mVRef[1]==vref0) return mVRef[2];
357 else if(mVRef[0]==vref0 && mVRef[2]==vref1) return mVRef[1];
358 else if(mVRef[0]==vref1 && mVRef[2]==vref0) return mVRef[1];
359 else if(mVRef[1]==vref0 && mVRef[2]==vref1) return mVRef[0];
360 else if(mVRef[1]==vref1 && mVRef[2]==vref0) return mVRef[0];
361 return INVALID_ID;
362}
363
364///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
365/**
366 * Gets the three sorted vertex references according to an edge number.
367 * edgenb = 0 => edge 0-1, returns references 0, 1, 2
368 * edgenb = 1 => edge 0-2, returns references 0, 2, 1
369 * edgenb = 2 => edge 1-2, returns references 1, 2, 0
370 *
371 * \param edgenb [in] the edge number, 0, 1 or 2
372 * \param vref0 [out] the returned first vertex reference
373 * \param vref1 [out] the returned second vertex reference
374 * \param vref2 [out] the returned third vertex reference
375 */
376///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
377void IndexedTriangle::GetVRefs(ubyte edgenb, udword& vref0, udword& vref1, udword& vref2) const
378{
379 if(edgenb==0)
380 {
381 vref0 = mVRef[0];
382 vref1 = mVRef[1];
383 vref2 = mVRef[2];
384 }
385 else if(edgenb==1)
386 {
387 vref0 = mVRef[0];
388 vref1 = mVRef[2];
389 vref2 = mVRef[1];
390 }
391 else if(edgenb==2)
392 {
393 vref0 = mVRef[1];
394 vref1 = mVRef[2];
395 vref2 = mVRef[0];
396 }
397}
398
399///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
400/**
401 * Computes the triangle's smallest edge length.
402 * \param verts [in] the list of indexed vertices
403 * \return the smallest edge length
404 */
405///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
406float IndexedTriangle::MinEdgeLength(const Point* verts) const
407{
408 if(!verts) return 0.0f;
409
410 float Min = MAX_FLOAT;
411 float Length01 = verts[0].Distance(verts[1]);
412 float Length02 = verts[0].Distance(verts[2]);
413 float Length12 = verts[1].Distance(verts[2]);
414 if(Length01 < Min) Min = Length01;
415 if(Length02 < Min) Min = Length02;
416 if(Length12 < Min) Min = Length12;
417 return Min;
418}
419
420///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
421/**
422 * Computes the triangle's largest edge length.
423 * \param verts [in] the list of indexed vertices
424 * \return the largest edge length
425 */
426///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
427float IndexedTriangle::MaxEdgeLength(const Point* verts) const
428{
429 if(!verts) return 0.0f;
430
431 float Max = MIN_FLOAT;
432 float Length01 = verts[0].Distance(verts[1]);
433 float Length02 = verts[0].Distance(verts[2]);
434 float Length12 = verts[1].Distance(verts[2]);
435 if(Length01 > Max) Max = Length01;
436 if(Length02 > Max) Max = Length02;
437 if(Length12 > Max) Max = Length12;
438 return Max;
439}
440
441///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
442/**
443 * Computes a point on the triangle according to the stabbing information.
444 * \param verts [in] the list of indexed vertices
445 * \param u,v [in] point's barycentric coordinates
446 * \param pt [out] point on triangle
447 * \param nearvtx [out] index of nearest vertex
448 */
449///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
450void IndexedTriangle::ComputePoint(const Point* verts, float u, float v, Point& pt, udword* nearvtx) const
451{
452 // Checkings
453 if(!verts) return;
454
455 // Get face in local or global space
456 const Point& p0 = verts[mVRef[0]];
457 const Point& p1 = verts[mVRef[1]];
458 const Point& p2 = verts[mVRef[2]];
459
460 // Compute point coordinates
461 pt = (1.0f - u - v)*p0 + u*p1 + v*p2;
462
463 // Compute nearest vertex if needed
464 if(nearvtx)
465 {
466 // Compute distance vector
467 Point d(p0.SquareDistance(pt), // Distance^2 from vertex 0 to point on the face
468 p1.SquareDistance(pt), // Distance^2 from vertex 1 to point on the face
469 p2.SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face
470
471 // Get smallest distance
472 *nearvtx = mVRef[d.SmallestAxis()];
473 }
474}
475
476 //**************************************
477 // Angle between two vectors (in radians)
478 // we use this formula
479 // uv = |u||v| cos(u,v)
480 // u ^ v = w
481 // |w| = |u||v| |sin(u,v)|
482 //**************************************
483 float Angle(const Point& u, const Point& v)
484 {
485 float NormU = u.Magnitude(); // |u|
486 float NormV = v.Magnitude(); // |v|
487 float Product = NormU*NormV; // |u||v|
488 if(Product==0.0f) return 0.0f;
489 float OneOverProduct = 1.0f / Product;
490
491 // Cosinus
492 float Cosinus = (u|v) * OneOverProduct;
493
494 // Sinus
495 Point w = u^v;
496 float NormW = w.Magnitude();
497
498 float AbsSinus = NormW * OneOverProduct;
499
500 // Remove degeneracy
501 if(AbsSinus > 1.0f) AbsSinus = 1.0f;
502 if(AbsSinus < -1.0f) AbsSinus = -1.0f;
503
504 if(Cosinus>=0.0f) return asinf(AbsSinus);
505 else return (PI-asinf(AbsSinus));
506 }
507
508///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
509/**
510 * Computes the angle between two triangles.
511 * \param tri [in] the other triangle
512 * \param verts [in] the list of indexed vertices
513 * \return the angle in radians
514 */
515///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
516float IndexedTriangle::Angle(const IndexedTriangle& tri, const Point* verts) const
517{
518 // Checkings
519 if(!verts) return 0.0f;
520
521 // Compute face normals
522 Point n0, n1;
523 Normal(verts, n0);
524 tri.Normal(verts, n1);
525
526 // Compute angle
527 float dp = n0|n1;
528 if(dp>1.0f) return 0.0f;
529 if(dp<-1.0f) return PI;
530 return acosf(dp);
531
532// return ::Angle(n0,n1);
533}
534
535///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
536/**
537 * Checks a triangle is the same as another one.
538 * \param tri [in] the other triangle
539 * \return true if same triangle
540 */
541///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
542bool IndexedTriangle::Equal(const IndexedTriangle& tri) const
543{
544 // Test all vertex references
545 return (HasVertex(tri.mVRef[0]) &&
546 HasVertex(tri.mVRef[1]) &&
547 HasVertex(tri.mVRef[2]));
548}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.h b/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.h
new file mode 100644
index 0000000..b34c485
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.h
@@ -0,0 +1,72 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains a handy indexed triangle class.
4 * \file IceIndexedTriangle.h
5 * \author Pierre Terdiman
6 * \date January, 17, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEINDEXEDTRIANGLE_H__
13#define __ICEINDEXEDTRIANGLE_H__
14
15 // Forward declarations
16#ifdef _MSC_VER
17 enum CubeIndex;
18#else
19 typedef int CubeIndex;
20#endif
21
22 // An indexed triangle class.
23 class ICEMATHS_API IndexedTriangle
24 {
25 public:
26 //! Constructor
27 inline_ IndexedTriangle() {}
28 //! Constructor
29 inline_ IndexedTriangle(udword r0, udword r1, udword r2) { mVRef[0]=r0; mVRef[1]=r1; mVRef[2]=r2; }
30 //! Copy constructor
31 inline_ IndexedTriangle(const IndexedTriangle& triangle)
32 {
33 mVRef[0] = triangle.mVRef[0];
34 mVRef[1] = triangle.mVRef[1];
35 mVRef[2] = triangle.mVRef[2];
36 }
37 //! Destructor
38 inline_ ~IndexedTriangle() {}
39 //! Vertex-references
40 udword mVRef[3];
41
42 // Methods
43 void Flip();
44 float Area(const Point* verts) const;
45 float Perimeter(const Point* verts) const;
46 float Compacity(const Point* verts) const;
47 void Normal(const Point* verts, Point& normal) const;
48 void DenormalizedNormal(const Point* verts, Point& normal) const;
49 void Center(const Point* verts, Point& center) const;
50 void CenteredNormal(const Point* verts, Point& normal) const;
51 void RandomPoint(const Point* verts, Point& random) const;
52 bool IsVisible(const Point* verts, const Point& source) const;
53 bool BackfaceCulling(const Point* verts, const Point& source) const;
54 float ComputeOcclusionPotential(const Point* verts, const Point& view) const;
55 bool ReplaceVertex(udword oldref, udword newref);
56 bool IsDegenerate() const;
57 bool HasVertex(udword ref) const;
58 bool HasVertex(udword ref, udword* index) const;
59 ubyte FindEdge(udword vref0, udword vref1) const;
60 udword OppositeVertex(udword vref0, udword vref1) const;
61 inline_ udword OppositeVertex(ubyte edgenb) const { return mVRef[2-edgenb]; }
62 void GetVRefs(ubyte edgenb, udword& vref0, udword& vref1, udword& vref2) const;
63 float MinEdgeLength(const Point* verts) const;
64 float MaxEdgeLength(const Point* verts) const;
65 void ComputePoint(const Point* verts, float u, float v, Point& pt, udword* nearvtx=null) const;
66 float Angle(const IndexedTriangle& tri, const Point* verts) const;
67 inline_ Plane PlaneEquation(const Point* verts) const { return Plane(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); }
68 bool Equal(const IndexedTriangle& tri) const;
69 CubeIndex ComputeCubeIndex(const Point* verts) const;
70 };
71
72#endif // __ICEINDEXEDTRIANGLE_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceLSS.h b/libraries/ode-0.9/OPCODE/Ice/IceLSS.h
new file mode 100644
index 0000000..bd260c1
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceLSS.h
@@ -0,0 +1,75 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for line-swept spheres.
4 * \file IceLSS.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICELSS_H__
13#define __ICELSS_H__
14
15 class ICEMATHS_API LSS : public Segment
16 {
17 public:
18 //! Constructor
19 inline_ LSS() {}
20 //! Constructor
21 inline_ LSS(const Segment& seg, float radius) : Segment(seg), mRadius(radius) {}
22 //! Destructor
23 inline_ ~LSS() {}
24
25 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26 /**
27 * Computes an OBB surrounding the LSS.
28 * \param box [out] the OBB
29 */
30 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 void ComputeOBB(OBB& box);
32
33 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
34 /**
35 * Tests if a point is contained within the LSS.
36 * \param pt [in] the point to test
37 * \return true if inside the LSS
38 * \warning point and LSS must be in same space
39 */
40 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
41 inline_ bool Contains(const Point& pt) const { return SquareDistance(pt) <= mRadius*mRadius; }
42
43 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
44 /**
45 * Tests if a sphere is contained within the LSS.
46 * \param sphere [in] the sphere to test
47 * \return true if inside the LSS
48 * \warning sphere and LSS must be in same space
49 */
50 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
51 inline_ bool Contains(const Sphere& sphere)
52 {
53 float d = mRadius - sphere.mRadius;
54 if(d>=0.0f) return SquareDistance(sphere.mCenter) <= d*d;
55 else return false;
56 }
57
58 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
59 /**
60 * Tests if an LSS is contained within the LSS.
61 * \param lss [in] the LSS to test
62 * \return true if inside the LSS
63 * \warning both LSS must be in same space
64 */
65 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66 inline_ bool Contains(const LSS& lss)
67 {
68 // We check the LSS contains the two spheres at the start and end of the sweep
69 return Contains(Sphere(lss.mP0, lss.mRadius)) && Contains(Sphere(lss.mP0, lss.mRadius));
70 }
71
72 float mRadius; //!< Sphere radius
73 };
74
75#endif // __ICELSS_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.cpp b/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.cpp
new file mode 100644
index 0000000..af56d3e
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.cpp
@@ -0,0 +1,48 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for 3x3 matrices.
4 * \file IceMatrix3x3.cpp
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * 3x3 matrix.
13 * DirectX-compliant, ie row-column order, ie m[Row][Col].
14 * Same as:
15 * m11 m12 m13 first row.
16 * m21 m22 m23 second row.
17 * m31 m32 m33 third row.
18 * Stored in memory as m11 m12 m13 m21...
19 *
20 * Multiplication rules:
21 *
22 * [x'y'z'] = [xyz][M]
23 *
24 * x' = x*m11 + y*m21 + z*m31
25 * y' = x*m12 + y*m22 + z*m32
26 * z' = x*m13 + y*m23 + z*m33
27 *
28 * \class Matrix3x3
29 * \author Pierre Terdiman
30 * \version 1.0
31 */
32///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
33
34///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
35// Precompiled Header
36#include "Stdafx.h"
37
38using namespace IceMaths;
39
40// Cast operator
41Matrix3x3::operator Matrix4x4() const
42{
43 return Matrix4x4(
44 m[0][0], m[0][1], m[0][2], 0.0f,
45 m[1][0], m[1][1], m[1][2], 0.0f,
46 m[2][0], m[2][1], m[2][2], 0.0f,
47 0.0f, 0.0f, 0.0f, 1.0f);
48}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.h b/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.h
new file mode 100644
index 0000000..a30680d
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.h
@@ -0,0 +1,496 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for 3x3 matrices.
4 * \file IceMatrix3x3.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEMATRIX3X3_H__
13#define __ICEMATRIX3X3_H__
14
15 // Forward declarations
16 class Quat;
17
18 #define MATRIX3X3_EPSILON (1.0e-7f)
19
20 class ICEMATHS_API Matrix3x3
21 {
22 public:
23 //! Empty constructor
24 inline_ Matrix3x3() {}
25 //! Constructor from 9 values
26 inline_ Matrix3x3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22)
27 {
28 m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
29 m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
30 m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
31 }
32 //! Copy constructor
33 inline_ Matrix3x3(const Matrix3x3& mat) { CopyMemory(m, &mat.m, 9*sizeof(float)); }
34 //! Destructor
35 inline_ ~Matrix3x3() {}
36
37 //! Assign values
38 inline_ void Set(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22)
39 {
40 m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
41 m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
42 m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
43 }
44
45 //! Sets the scale from a Point. The point is put on the diagonal.
46 inline_ void SetScale(const Point& p) { m[0][0] = p.x; m[1][1] = p.y; m[2][2] = p.z; }
47
48 //! Sets the scale from floats. Values are put on the diagonal.
49 inline_ void SetScale(float sx, float sy, float sz) { m[0][0] = sx; m[1][1] = sy; m[2][2] = sz; }
50
51 //! Scales from a Point. Each row is multiplied by a component.
52 inline_ void Scale(const Point& p)
53 {
54 m[0][0] *= p.x; m[0][1] *= p.x; m[0][2] *= p.x;
55 m[1][0] *= p.y; m[1][1] *= p.y; m[1][2] *= p.y;
56 m[2][0] *= p.z; m[2][1] *= p.z; m[2][2] *= p.z;
57 }
58
59 //! Scales from floats. Each row is multiplied by a value.
60 inline_ void Scale(float sx, float sy, float sz)
61 {
62 m[0][0] *= sx; m[0][1] *= sx; m[0][2] *= sx;
63 m[1][0] *= sy; m[1][1] *= sy; m[1][2] *= sy;
64 m[2][0] *= sz; m[2][1] *= sz; m[2][2] *= sz;
65 }
66
67 //! Copy from a Matrix3x3
68 inline_ void Copy(const Matrix3x3& source) { CopyMemory(m, source.m, 9*sizeof(float)); }
69
70 // Row-column access
71 //! Returns a row.
72 inline_ void GetRow(const udword r, Point& p) const { p.x = m[r][0]; p.y = m[r][1]; p.z = m[r][2]; }
73 //! Returns a row.
74 inline_ const Point& GetRow(const udword r) const { return *(const Point*)&m[r][0]; }
75 //! Returns a row.
76 inline_ Point& GetRow(const udword r) { return *(Point*)&m[r][0]; }
77 //! Sets a row.
78 inline_ void SetRow(const udword r, const Point& p) { m[r][0] = p.x; m[r][1] = p.y; m[r][2] = p.z; }
79 //! Returns a column.
80 inline_ void GetCol(const udword c, Point& p) const { p.x = m[0][c]; p.y = m[1][c]; p.z = m[2][c]; }
81 //! Sets a column.
82 inline_ void SetCol(const udword c, const Point& p) { m[0][c] = p.x; m[1][c] = p.y; m[2][c] = p.z; }
83
84 //! Computes the trace. The trace is the sum of the 3 diagonal components.
85 inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2]; }
86 //! Clears the matrix.
87 inline_ void Zero() { ZeroMemory(&m, sizeof(m)); }
88 //! Sets the identity matrix.
89 inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = 1.0f; }
90 //! Checks for identity
91 inline_ bool IsIdentity() const
92 {
93 if(IR(m[0][0])!=IEEE_1_0) return false;
94 if(IR(m[0][1])!=0) return false;
95 if(IR(m[0][2])!=0) return false;
96
97 if(IR(m[1][0])!=0) return false;
98 if(IR(m[1][1])!=IEEE_1_0) return false;
99 if(IR(m[1][2])!=0) return false;
100
101 if(IR(m[2][0])!=0) return false;
102 if(IR(m[2][1])!=0) return false;
103 if(IR(m[2][2])!=IEEE_1_0) return false;
104
105 return true;
106 }
107
108 //! Checks matrix validity
109 inline_ BOOL IsValid() const
110 {
111 for(udword j=0;j<3;j++)
112 {
113 for(udword i=0;i<3;i++)
114 {
115 if(!IsValidFloat(m[j][i])) return FALSE;
116 }
117 }
118 return TRUE;
119 }
120
121 //! Makes a skew-symmetric matrix (a.k.a. Star(*) Matrix)
122 //! [ 0.0 -a.z a.y ]
123 //! [ a.z 0.0 -a.x ]
124 //! [ -a.y a.x 0.0 ]
125 //! This is also called a "cross matrix" since for any vectors A and B,
126 //! A^B = Skew(A) * B = - B * Skew(A);
127 inline_ void SkewSymmetric(const Point& a)
128 {
129 m[0][0] = 0.0f;
130 m[0][1] = -a.z;
131 m[0][2] = a.y;
132
133 m[1][0] = a.z;
134 m[1][1] = 0.0f;
135 m[1][2] = -a.x;
136
137 m[2][0] = -a.y;
138 m[2][1] = a.x;
139 m[2][2] = 0.0f;
140 }
141
142 //! Negates the matrix
143 inline_ void Neg()
144 {
145 m[0][0] = -m[0][0]; m[0][1] = -m[0][1]; m[0][2] = -m[0][2];
146 m[1][0] = -m[1][0]; m[1][1] = -m[1][1]; m[1][2] = -m[1][2];
147 m[2][0] = -m[2][0]; m[2][1] = -m[2][1]; m[2][2] = -m[2][2];
148 }
149
150 //! Neg from another matrix
151 inline_ void Neg(const Matrix3x3& mat)
152 {
153 m[0][0] = -mat.m[0][0]; m[0][1] = -mat.m[0][1]; m[0][2] = -mat.m[0][2];
154 m[1][0] = -mat.m[1][0]; m[1][1] = -mat.m[1][1]; m[1][2] = -mat.m[1][2];
155 m[2][0] = -mat.m[2][0]; m[2][1] = -mat.m[2][1]; m[2][2] = -mat.m[2][2];
156 }
157
158 //! Add another matrix
159 inline_ void Add(const Matrix3x3& mat)
160 {
161 m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2];
162 m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2];
163 m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2];
164 }
165
166 //! Sub another matrix
167 inline_ void Sub(const Matrix3x3& mat)
168 {
169 m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2];
170 m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2];
171 m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2];
172 }
173 //! Mac
174 inline_ void Mac(const Matrix3x3& a, const Matrix3x3& b, float s)
175 {
176 m[0][0] = a.m[0][0] + b.m[0][0] * s;
177 m[0][1] = a.m[0][1] + b.m[0][1] * s;
178 m[0][2] = a.m[0][2] + b.m[0][2] * s;
179
180 m[1][0] = a.m[1][0] + b.m[1][0] * s;
181 m[1][1] = a.m[1][1] + b.m[1][1] * s;
182 m[1][2] = a.m[1][2] + b.m[1][2] * s;
183
184 m[2][0] = a.m[2][0] + b.m[2][0] * s;
185 m[2][1] = a.m[2][1] + b.m[2][1] * s;
186 m[2][2] = a.m[2][2] + b.m[2][2] * s;
187 }
188 //! Mac
189 inline_ void Mac(const Matrix3x3& a, float s)
190 {
191 m[0][0] += a.m[0][0] * s; m[0][1] += a.m[0][1] * s; m[0][2] += a.m[0][2] * s;
192 m[1][0] += a.m[1][0] * s; m[1][1] += a.m[1][1] * s; m[1][2] += a.m[1][2] * s;
193 m[2][0] += a.m[2][0] * s; m[2][1] += a.m[2][1] * s; m[2][2] += a.m[2][2] * s;
194 }
195
196 //! this = A * s
197 inline_ void Mult(const Matrix3x3& a, float s)
198 {
199 m[0][0] = a.m[0][0] * s; m[0][1] = a.m[0][1] * s; m[0][2] = a.m[0][2] * s;
200 m[1][0] = a.m[1][0] * s; m[1][1] = a.m[1][1] * s; m[1][2] = a.m[1][2] * s;
201 m[2][0] = a.m[2][0] * s; m[2][1] = a.m[2][1] * s; m[2][2] = a.m[2][2] * s;
202 }
203
204 inline_ void Add(const Matrix3x3& a, const Matrix3x3& b)
205 {
206 m[0][0] = a.m[0][0] + b.m[0][0]; m[0][1] = a.m[0][1] + b.m[0][1]; m[0][2] = a.m[0][2] + b.m[0][2];
207 m[1][0] = a.m[1][0] + b.m[1][0]; m[1][1] = a.m[1][1] + b.m[1][1]; m[1][2] = a.m[1][2] + b.m[1][2];
208 m[2][0] = a.m[2][0] + b.m[2][0]; m[2][1] = a.m[2][1] + b.m[2][1]; m[2][2] = a.m[2][2] + b.m[2][2];
209 }
210
211 inline_ void Sub(const Matrix3x3& a, const Matrix3x3& b)
212 {
213 m[0][0] = a.m[0][0] - b.m[0][0]; m[0][1] = a.m[0][1] - b.m[0][1]; m[0][2] = a.m[0][2] - b.m[0][2];
214 m[1][0] = a.m[1][0] - b.m[1][0]; m[1][1] = a.m[1][1] - b.m[1][1]; m[1][2] = a.m[1][2] - b.m[1][2];
215 m[2][0] = a.m[2][0] - b.m[2][0]; m[2][1] = a.m[2][1] - b.m[2][1]; m[2][2] = a.m[2][2] - b.m[2][2];
216 }
217
218 //! this = a * b
219 inline_ void Mult(const Matrix3x3& a, const Matrix3x3& b)
220 {
221 m[0][0] = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[1][0] + a.m[0][2] * b.m[2][0];
222 m[0][1] = a.m[0][0] * b.m[0][1] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[2][1];
223 m[0][2] = a.m[0][0] * b.m[0][2] + a.m[0][1] * b.m[1][2] + a.m[0][2] * b.m[2][2];
224 m[1][0] = a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[1][2] * b.m[2][0];
225 m[1][1] = a.m[1][0] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[2][1];
226 m[1][2] = a.m[1][0] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[1][2] * b.m[2][2];
227 m[2][0] = a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[1][0] + a.m[2][2] * b.m[2][0];
228 m[2][1] = a.m[2][0] * b.m[0][1] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[2][1];
229 m[2][2] = a.m[2][0] * b.m[0][2] + a.m[2][1] * b.m[1][2] + a.m[2][2] * b.m[2][2];
230 }
231
232 //! this = transpose(a) * b
233 inline_ void MultAtB(const Matrix3x3& a, const Matrix3x3& b)
234 {
235 m[0][0] = a.m[0][0] * b.m[0][0] + a.m[1][0] * b.m[1][0] + a.m[2][0] * b.m[2][0];
236 m[0][1] = a.m[0][0] * b.m[0][1] + a.m[1][0] * b.m[1][1] + a.m[2][0] * b.m[2][1];
237 m[0][2] = a.m[0][0] * b.m[0][2] + a.m[1][0] * b.m[1][2] + a.m[2][0] * b.m[2][2];
238 m[1][0] = a.m[0][1] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[2][1] * b.m[2][0];
239 m[1][1] = a.m[0][1] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[2][1] * b.m[2][1];
240 m[1][2] = a.m[0][1] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[2][1] * b.m[2][2];
241 m[2][0] = a.m[0][2] * b.m[0][0] + a.m[1][2] * b.m[1][0] + a.m[2][2] * b.m[2][0];
242 m[2][1] = a.m[0][2] * b.m[0][1] + a.m[1][2] * b.m[1][1] + a.m[2][2] * b.m[2][1];
243 m[2][2] = a.m[0][2] * b.m[0][2] + a.m[1][2] * b.m[1][2] + a.m[2][2] * b.m[2][2];
244 }
245
246 //! this = a * transpose(b)
247 inline_ void MultABt(const Matrix3x3& a, const Matrix3x3& b)
248 {
249 m[0][0] = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[0][1] + a.m[0][2] * b.m[0][2];
250 m[0][1] = a.m[0][0] * b.m[1][0] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[1][2];
251 m[0][2] = a.m[0][0] * b.m[2][0] + a.m[0][1] * b.m[2][1] + a.m[0][2] * b.m[2][2];
252 m[1][0] = a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[0][1] + a.m[1][2] * b.m[0][2];
253 m[1][1] = a.m[1][0] * b.m[1][0] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[1][2];
254 m[1][2] = a.m[1][0] * b.m[2][0] + a.m[1][1] * b.m[2][1] + a.m[1][2] * b.m[2][2];
255 m[2][0] = a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[0][1] + a.m[2][2] * b.m[0][2];
256 m[2][1] = a.m[2][0] * b.m[1][0] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[1][2];
257 m[2][2] = a.m[2][0] * b.m[2][0] + a.m[2][1] * b.m[2][1] + a.m[2][2] * b.m[2][2];
258 }
259
260 //! Makes a rotation matrix mapping vector "from" to vector "to".
261 Matrix3x3& FromTo(const Point& from, const Point& to);
262
263 //! Set a rotation matrix around the X axis.
264 //! 1 0 0
265 //! RX = 0 cx sx
266 //! 0 -sx cx
267 void RotX(float angle);
268 //! Set a rotation matrix around the Y axis.
269 //! cy 0 -sy
270 //! RY = 0 1 0
271 //! sy 0 cy
272 void RotY(float angle);
273 //! Set a rotation matrix around the Z axis.
274 //! cz sz 0
275 //! RZ = -sz cz 0
276 //! 0 0 1
277 void RotZ(float angle);
278 //! cy sx.sy -sy.cx
279 //! RY.RX 0 cx sx
280 //! sy -sx.cy cx.cy
281 void RotYX(float y, float x);
282
283 //! Make a rotation matrix about an arbitrary axis
284 Matrix3x3& Rot(float angle, const Point& axis);
285
286 //! Transpose the matrix.
287 void Transpose()
288 {
289 IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]);
290 IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]);
291 IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]);
292 }
293
294 //! this = Transpose(a)
295 void Transpose(const Matrix3x3& a)
296 {
297 m[0][0] = a.m[0][0]; m[0][1] = a.m[1][0]; m[0][2] = a.m[2][0];
298 m[1][0] = a.m[0][1]; m[1][1] = a.m[1][1]; m[1][2] = a.m[2][1];
299 m[2][0] = a.m[0][2]; m[2][1] = a.m[1][2]; m[2][2] = a.m[2][2];
300 }
301
302 //! Compute the determinant of the matrix. We use the rule of Sarrus.
303 float Determinant() const
304 {
305 return (m[0][0]*m[1][1]*m[2][2] + m[0][1]*m[1][2]*m[2][0] + m[0][2]*m[1][0]*m[2][1])
306 - (m[2][0]*m[1][1]*m[0][2] + m[2][1]*m[1][2]*m[0][0] + m[2][2]*m[1][0]*m[0][1]);
307 }
308/*
309 //! Compute a cofactor. Used for matrix inversion.
310 float CoFactor(ubyte row, ubyte column) const
311 {
312 static sdword gIndex[3+2] = { 0, 1, 2, 0, 1 };
313 return (m[gIndex[row+1]][gIndex[column+1]]*m[gIndex[row+2]][gIndex[column+2]] - m[gIndex[row+2]][gIndex[column+1]]*m[gIndex[row+1]][gIndex[column+2]]);
314 }
315*/
316 //! Invert the matrix. Determinant must be different from zero, else matrix can't be inverted.
317 Matrix3x3& Invert()
318 {
319 float Det = Determinant(); // Must be !=0
320 float OneOverDet = 1.0f / Det;
321
322 Matrix3x3 Temp;
323 Temp.m[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDet;
324 Temp.m[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDet;
325 Temp.m[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDet;
326 Temp.m[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDet;
327 Temp.m[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDet;
328 Temp.m[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDet;
329 Temp.m[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDet;
330 Temp.m[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDet;
331 Temp.m[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDet;
332
333 *this = Temp;
334
335 return *this;
336 }
337
338 Matrix3x3& Normalize();
339
340 //! this = exp(a)
341 Matrix3x3& Exp(const Matrix3x3& a);
342
343void FromQuat(const Quat &q);
344void FromQuatL2(const Quat &q, float l2);
345
346 // Arithmetic operators
347 //! Operator for Matrix3x3 Plus = Matrix3x3 + Matrix3x3;
348 inline_ Matrix3x3 operator+(const Matrix3x3& mat) const
349 {
350 return Matrix3x3(
351 m[0][0] + mat.m[0][0], m[0][1] + mat.m[0][1], m[0][2] + mat.m[0][2],
352 m[1][0] + mat.m[1][0], m[1][1] + mat.m[1][1], m[1][2] + mat.m[1][2],
353 m[2][0] + mat.m[2][0], m[2][1] + mat.m[2][1], m[2][2] + mat.m[2][2]);
354 }
355
356 //! Operator for Matrix3x3 Minus = Matrix3x3 - Matrix3x3;
357 inline_ Matrix3x3 operator-(const Matrix3x3& mat) const
358 {
359 return Matrix3x3(
360 m[0][0] - mat.m[0][0], m[0][1] - mat.m[0][1], m[0][2] - mat.m[0][2],
361 m[1][0] - mat.m[1][0], m[1][1] - mat.m[1][1], m[1][2] - mat.m[1][2],
362 m[2][0] - mat.m[2][0], m[2][1] - mat.m[2][1], m[2][2] - mat.m[2][2]);
363 }
364
365 //! Operator for Matrix3x3 Mul = Matrix3x3 * Matrix3x3;
366 inline_ Matrix3x3 operator*(const Matrix3x3& mat) const
367 {
368 return Matrix3x3(
369 m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0],
370 m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1],
371 m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2],
372
373 m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0],
374 m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1],
375 m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2],
376
377 m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0],
378 m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1],
379 m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2]);
380 }
381
382 //! Operator for Point Mul = Matrix3x3 * Point;
383 inline_ Point operator*(const Point& v) const { return Point(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v); }
384
385 //! Operator for Matrix3x3 Mul = Matrix3x3 * float;
386 inline_ Matrix3x3 operator*(float s) const
387 {
388 return Matrix3x3(
389 m[0][0]*s, m[0][1]*s, m[0][2]*s,
390 m[1][0]*s, m[1][1]*s, m[1][2]*s,
391 m[2][0]*s, m[2][1]*s, m[2][2]*s);
392 }
393
394 //! Operator for Matrix3x3 Mul = float * Matrix3x3;
395 inline_ friend Matrix3x3 operator*(float s, const Matrix3x3& mat)
396 {
397 return Matrix3x3(
398 s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2],
399 s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2],
400 s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2]);
401 }
402
403 //! Operator for Matrix3x3 Div = Matrix3x3 / float;
404 inline_ Matrix3x3 operator/(float s) const
405 {
406 if (s) s = 1.0f / s;
407 return Matrix3x3(
408 m[0][0]*s, m[0][1]*s, m[0][2]*s,
409 m[1][0]*s, m[1][1]*s, m[1][2]*s,
410 m[2][0]*s, m[2][1]*s, m[2][2]*s);
411 }
412
413 //! Operator for Matrix3x3 Div = float / Matrix3x3;
414 inline_ friend Matrix3x3 operator/(float s, const Matrix3x3& mat)
415 {
416 return Matrix3x3(
417 s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2],
418 s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2],
419 s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2]);
420 }
421
422 //! Operator for Matrix3x3 += Matrix3x3
423 inline_ Matrix3x3& operator+=(const Matrix3x3& mat)
424 {
425 m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2];
426 m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2];
427 m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2];
428 return *this;
429 }
430
431 //! Operator for Matrix3x3 -= Matrix3x3
432 inline_ Matrix3x3& operator-=(const Matrix3x3& mat)
433 {
434 m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2];
435 m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2];
436 m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2];
437 return *this;
438 }
439
440 //! Operator for Matrix3x3 *= Matrix3x3
441 inline_ Matrix3x3& operator*=(const Matrix3x3& mat)
442 {
443 Point TempRow;
444
445 GetRow(0, TempRow);
446 m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0];
447 m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1];
448 m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2];
449
450 GetRow(1, TempRow);
451 m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0];
452 m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1];
453 m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2];
454
455 GetRow(2, TempRow);
456 m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0];
457 m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1];
458 m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2];
459 return *this;
460 }
461
462 //! Operator for Matrix3x3 *= float
463 inline_ Matrix3x3& operator*=(float s)
464 {
465 m[0][0] *= s; m[0][1] *= s; m[0][2] *= s;
466 m[1][0] *= s; m[1][1] *= s; m[1][2] *= s;
467 m[2][0] *= s; m[2][1] *= s; m[2][2] *= s;
468 return *this;
469 }
470
471 //! Operator for Matrix3x3 /= float
472 inline_ Matrix3x3& operator/=(float s)
473 {
474 if (s) s = 1.0f / s;
475 m[0][0] *= s; m[0][1] *= s; m[0][2] *= s;
476 m[1][0] *= s; m[1][1] *= s; m[1][2] *= s;
477 m[2][0] *= s; m[2][1] *= s; m[2][2] *= s;
478 return *this;
479 }
480
481 // Cast operators
482 //! Cast a Matrix3x3 to a Matrix4x4.
483 operator Matrix4x4() const;
484 //! Cast a Matrix3x3 to a Quat.
485 operator Quat() const;
486
487 inline_ const Point& operator[](int row) const { return *(const Point*)&m[row][0]; }
488 inline_ Point& operator[](int row) { return *(Point*)&m[row][0]; }
489
490 public:
491
492 float m[3][3];
493 };
494
495#endif // __ICEMATRIX3X3_H__
496
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.cpp b/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.cpp
new file mode 100644
index 0000000..0b258f0
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.cpp
@@ -0,0 +1,135 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for 4x4 matrices.
4 * \file IceMatrix4x4.cpp
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * 4x4 matrix.
13 * DirectX-compliant, ie row-column order, ie m[Row][Col].
14 * Same as:
15 * m11 m12 m13 m14 first row.
16 * m21 m22 m23 m24 second row.
17 * m31 m32 m33 m34 third row.
18 * m41 m42 m43 m44 fourth row.
19 * Translation is (m41, m42, m43), (m14, m24, m34, m44) = (0, 0, 0, 1).
20 * Stored in memory as m11 m12 m13 m14 m21...
21 *
22 * Multiplication rules:
23 *
24 * [x'y'z'1] = [xyz1][M]
25 *
26 * x' = x*m11 + y*m21 + z*m31 + m41
27 * y' = x*m12 + y*m22 + z*m32 + m42
28 * z' = x*m13 + y*m23 + z*m33 + m43
29 * 1' = 0 + 0 + 0 + m44
30 *
31 * \class Matrix4x4
32 * \author Pierre Terdiman
33 * \version 1.0
34 */
35///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36
37///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
38// Precompiled Header
39#include "Stdafx.h"
40
41using namespace IceMaths;
42
43///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
44/**
45 * Inverts a PR matrix. (which only contains a rotation and a translation)
46 * This is faster and less subject to FPU errors than the generic inversion code.
47 *
48 * \relates Matrix4x4
49 * \fn InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src)
50 * \param dest [out] destination matrix
51 * \param src [in] source matrix
52 */
53///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54ICEMATHS_API void IceMaths::InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src)
55{
56 dest.m[0][0] = src.m[0][0];
57 dest.m[1][0] = src.m[0][1];
58 dest.m[2][0] = src.m[0][2];
59 dest.m[3][0] = -(src.m[3][0]*src.m[0][0] + src.m[3][1]*src.m[0][1] + src.m[3][2]*src.m[0][2]);
60
61 dest.m[0][1] = src.m[1][0];
62 dest.m[1][1] = src.m[1][1];
63 dest.m[2][1] = src.m[1][2];
64 dest.m[3][1] = -(src.m[3][0]*src.m[1][0] + src.m[3][1]*src.m[1][1] + src.m[3][2]*src.m[1][2]);
65
66 dest.m[0][2] = src.m[2][0];
67 dest.m[1][2] = src.m[2][1];
68 dest.m[2][2] = src.m[2][2];
69 dest.m[3][2] = -(src.m[3][0]*src.m[2][0] + src.m[3][1]*src.m[2][1] + src.m[3][2]*src.m[2][2]);
70
71 dest.m[0][3] = 0.0f;
72 dest.m[1][3] = 0.0f;
73 dest.m[2][3] = 0.0f;
74 dest.m[3][3] = 1.0f;
75}
76
77///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
78// Compute the cofactor of the Matrix at a specified location
79///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
80float Matrix4x4::CoFactor(udword row, udword col) const
81{
82 return (( m[(row+1)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+3)&3][(col+3)&3] +
83 m[(row+1)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+3)&3][(col+1)&3] +
84 m[(row+1)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+3)&3][(col+2)&3])
85 - (m[(row+3)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+1)&3][(col+3)&3] +
86 m[(row+3)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+1)&3][(col+1)&3] +
87 m[(row+3)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+1)&3][(col+2)&3])) * ((row + col) & 1 ? -1.0f : +1.0f);
88}
89
90///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91// Compute the determinant of the Matrix
92///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93float Matrix4x4::Determinant() const
94{
95 return m[0][0] * CoFactor(0, 0) +
96 m[0][1] * CoFactor(0, 1) +
97 m[0][2] * CoFactor(0, 2) +
98 m[0][3] * CoFactor(0, 3);
99}
100
101///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
102// Compute the inverse of the matrix
103///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
104Matrix4x4& Matrix4x4::Invert()
105{
106 float Det = Determinant();
107 Matrix4x4 Temp;
108
109 if(fabsf(Det) < MATRIX4X4_EPSILON)
110 return *this; // The matrix is not invertible! Singular case!
111
112 float IDet = 1.0f / Det;
113
114 Temp.m[0][0] = CoFactor(0,0) * IDet;
115 Temp.m[1][0] = CoFactor(0,1) * IDet;
116 Temp.m[2][0] = CoFactor(0,2) * IDet;
117 Temp.m[3][0] = CoFactor(0,3) * IDet;
118 Temp.m[0][1] = CoFactor(1,0) * IDet;
119 Temp.m[1][1] = CoFactor(1,1) * IDet;
120 Temp.m[2][1] = CoFactor(1,2) * IDet;
121 Temp.m[3][1] = CoFactor(1,3) * IDet;
122 Temp.m[0][2] = CoFactor(2,0) * IDet;
123 Temp.m[1][2] = CoFactor(2,1) * IDet;
124 Temp.m[2][2] = CoFactor(2,2) * IDet;
125 Temp.m[3][2] = CoFactor(2,3) * IDet;
126 Temp.m[0][3] = CoFactor(3,0) * IDet;
127 Temp.m[1][3] = CoFactor(3,1) * IDet;
128 Temp.m[2][3] = CoFactor(3,2) * IDet;
129 Temp.m[3][3] = CoFactor(3,3) * IDet;
130
131 *this = Temp;
132
133 return *this;
134}
135
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.h b/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.h
new file mode 100644
index 0000000..45919be
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.h
@@ -0,0 +1,455 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for 4x4 matrices.
4 * \file IceMatrix4x4.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEMATRIX4X4_H__
13#define __ICEMATRIX4X4_H__
14
15 // Forward declarations
16 class PRS;
17 class PR;
18
19 #define MATRIX4X4_EPSILON (1.0e-7f)
20
21 class ICEMATHS_API Matrix4x4
22 {
23// void LUBackwardSubstitution( sdword *indx, float* b );
24// void LUDecomposition( sdword* indx, float* d );
25
26 public:
27 //! Empty constructor.
28 inline_ Matrix4x4() {}
29 //! Constructor from 16 values
30 inline_ Matrix4x4( float m00, float m01, float m02, float m03,
31 float m10, float m11, float m12, float m13,
32 float m20, float m21, float m22, float m23,
33 float m30, float m31, float m32, float m33)
34 {
35 m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03;
36 m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13;
37 m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23;
38 m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33;
39 }
40 //! Copy constructor
41 inline_ Matrix4x4(const Matrix4x4& mat) { CopyMemory(m, &mat.m, 16*sizeof(float)); }
42 //! Destructor.
43 inline_ ~Matrix4x4() {}
44
45 //! Assign values (rotation only)
46 inline_ Matrix4x4& Set( float m00, float m01, float m02,
47 float m10, float m11, float m12,
48 float m20, float m21, float m22)
49 {
50 m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
51 m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
52 m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
53 return *this;
54 }
55 //! Assign values
56 inline_ Matrix4x4& Set( float m00, float m01, float m02, float m03,
57 float m10, float m11, float m12, float m13,
58 float m20, float m21, float m22, float m23,
59 float m30, float m31, float m32, float m33)
60 {
61 m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03;
62 m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13;
63 m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23;
64 m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33;
65 return *this;
66 }
67
68 //! Copy from a Matrix4x4
69 inline_ void Copy(const Matrix4x4& source) { CopyMemory(m, source.m, 16*sizeof(float)); }
70
71 // Row-column access
72 //! Returns a row.
73 inline_ void GetRow(const udword r, HPoint& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; p.w=m[r][3]; }
74 //! Returns a row.
75 inline_ void GetRow(const udword r, Point& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; }
76 //! Returns a row.
77 inline_ const HPoint& GetRow(const udword r) const { return *(const HPoint*)&m[r][0]; }
78 //! Returns a row.
79 inline_ HPoint& GetRow(const udword r) { return *(HPoint*)&m[r][0]; }
80 //! Sets a row.
81 inline_ void SetRow(const udword r, const HPoint& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]=p.w; }
82 //! Sets a row.
83 inline_ void SetRow(const udword r, const Point& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]= (r!=3) ? 0.0f : 1.0f; }
84 //! Returns a column.
85 inline_ void GetCol(const udword c, HPoint& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; p.w=m[3][c]; }
86 //! Returns a column.
87 inline_ void GetCol(const udword c, Point& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; }
88 //! Sets a column.
89 inline_ void SetCol(const udword c, const HPoint& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]=p.w; }
90 //! Sets a column.
91 inline_ void SetCol(const udword c, const Point& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]= (c!=3) ? 0.0f : 1.0f; }
92
93 // Translation
94 //! Returns the translation part of the matrix.
95 inline_ const HPoint& GetTrans() const { return GetRow(3); }
96 //! Gets the translation part of the matrix
97 inline_ void GetTrans(Point& p) const { p.x=m[3][0]; p.y=m[3][1]; p.z=m[3][2]; }
98 //! Sets the translation part of the matrix, from a Point.
99 inline_ void SetTrans(const Point& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; }
100 //! Sets the translation part of the matrix, from a HPoint.
101 inline_ void SetTrans(const HPoint& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; m[3][3]=p.w; }
102 //! Sets the translation part of the matrix, from floats.
103 inline_ void SetTrans(float tx, float ty, float tz) { m[3][0]=tx; m[3][1]=ty; m[3][2]=tz; }
104
105 // Scale
106 //! Sets the scale from a Point. The point is put on the diagonal.
107 inline_ void SetScale(const Point& p) { m[0][0]=p.x; m[1][1]=p.y; m[2][2]=p.z; }
108 //! Sets the scale from floats. Values are put on the diagonal.
109 inline_ void SetScale(float sx, float sy, float sz) { m[0][0]=sx; m[1][1]=sy; m[2][2]=sz; }
110 //! Scales from a Point. Each row is multiplied by a component.
111 void Scale(const Point& p)
112 {
113 m[0][0] *= p.x; m[1][0] *= p.y; m[2][0] *= p.z;
114 m[0][1] *= p.x; m[1][1] *= p.y; m[2][1] *= p.z;
115 m[0][2] *= p.x; m[1][2] *= p.y; m[2][2] *= p.z;
116 }
117 //! Scales from floats. Each row is multiplied by a value.
118 void Scale(float sx, float sy, float sz)
119 {
120 m[0][0] *= sx; m[1][0] *= sy; m[2][0] *= sz;
121 m[0][1] *= sx; m[1][1] *= sy; m[2][1] *= sz;
122 m[0][2] *= sx; m[1][2] *= sy; m[2][2] *= sz;
123 }
124/*
125 //! Returns a row.
126 inline_ HPoint GetRow(const udword row) const { return mRow[row]; }
127 //! Sets a row.
128 inline_ Matrix4x4& SetRow(const udword row, const HPoint& p) { mRow[row] = p; return *this; }
129 //! Sets a row.
130 Matrix4x4& SetRow(const udword row, const Point& p)
131 {
132 m[row][0] = p.x;
133 m[row][1] = p.y;
134 m[row][2] = p.z;
135 m[row][3] = (row != 3) ? 0.0f : 1.0f;
136 return *this;
137 }
138 //! Returns a column.
139 HPoint GetCol(const udword col) const
140 {
141 HPoint Res;
142 Res.x = m[0][col];
143 Res.y = m[1][col];
144 Res.z = m[2][col];
145 Res.w = m[3][col];
146 return Res;
147 }
148 //! Sets a column.
149 Matrix4x4& SetCol(const udword col, const HPoint& p)
150 {
151 m[0][col] = p.x;
152 m[1][col] = p.y;
153 m[2][col] = p.z;
154 m[3][col] = p.w;
155 return *this;
156 }
157 //! Sets a column.
158 Matrix4x4& SetCol(const udword col, const Point& p)
159 {
160 m[0][col] = p.x;
161 m[1][col] = p.y;
162 m[2][col] = p.z;
163 m[3][col] = (col != 3) ? 0.0f : 1.0f;
164 return *this;
165 }
166*/
167 //! Computes the trace. The trace is the sum of the 4 diagonal components.
168 inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2] + m[3][3]; }
169 //! Computes the trace of the upper 3x3 matrix.
170 inline_ float Trace3x3() const { return m[0][0] + m[1][1] + m[2][2]; }
171 //! Clears the matrix.
172 inline_ void Zero() { ZeroMemory(&m, sizeof(m)); }
173 //! Sets the identity matrix.
174 inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f; }
175 //! Checks for identity
176 inline_ bool IsIdentity() const
177 {
178 if(IR(m[0][0])!=IEEE_1_0) return false;
179 if(IR(m[0][1])!=0) return false;
180 if(IR(m[0][2])!=0) return false;
181 if(IR(m[0][3])!=0) return false;
182
183 if(IR(m[1][0])!=0) return false;
184 if(IR(m[1][1])!=IEEE_1_0) return false;
185 if(IR(m[1][2])!=0) return false;
186 if(IR(m[1][3])!=0) return false;
187
188 if(IR(m[2][0])!=0) return false;
189 if(IR(m[2][1])!=0) return false;
190 if(IR(m[2][2])!=IEEE_1_0) return false;
191 if(IR(m[2][3])!=0) return false;
192
193 if(IR(m[3][0])!=0) return false;
194 if(IR(m[3][1])!=0) return false;
195 if(IR(m[3][2])!=0) return false;
196 if(IR(m[3][3])!=IEEE_1_0) return false;
197 return true;
198 }
199
200 //! Checks matrix validity
201 inline_ BOOL IsValid() const
202 {
203 for(udword j=0;j<4;j++)
204 {
205 for(udword i=0;i<4;i++)
206 {
207 if(!IsValidFloat(m[j][i])) return FALSE;
208 }
209 }
210 return TRUE;
211 }
212
213 //! Sets a rotation matrix around the X axis.
214 void RotX(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[1][1] = m[2][2] = Cos; m[2][1] = -Sin; m[1][2] = Sin; }
215 //! Sets a rotation matrix around the Y axis.
216 void RotY(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[2][2] = Cos; m[2][0] = Sin; m[0][2] = -Sin; }
217 //! Sets a rotation matrix around the Z axis.
218 void RotZ(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[1][1] = Cos; m[1][0] = -Sin; m[0][1] = Sin; }
219
220 //! Makes a rotation matrix about an arbitrary axis
221 Matrix4x4& Rot(float angle, Point& p1, Point& p2);
222
223 //! Transposes the matrix.
224 void Transpose()
225 {
226 IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]);
227 IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]);
228 IR(m[3][0]) ^= IR(m[0][3]); IR(m[0][3]) ^= IR(m[3][0]); IR(m[3][0]) ^= IR(m[0][3]);
229 IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]);
230 IR(m[1][3]) ^= IR(m[3][1]); IR(m[3][1]) ^= IR(m[1][3]); IR(m[1][3]) ^= IR(m[3][1]);
231 IR(m[2][3]) ^= IR(m[3][2]); IR(m[3][2]) ^= IR(m[2][3]); IR(m[2][3]) ^= IR(m[3][2]);
232 }
233
234 //! Computes a cofactor. Used for matrix inversion.
235 float CoFactor(udword row, udword col) const;
236 //! Computes the determinant of the matrix.
237 float Determinant() const;
238 //! Inverts the matrix. Determinant must be different from zero, else matrix can't be inverted.
239 Matrix4x4& Invert();
240// Matrix& ComputeAxisMatrix(Point& axis, float angle);
241
242 // Cast operators
243 //! Casts a Matrix4x4 to a Matrix3x3.
244 inline_ operator Matrix3x3() const
245 {
246 return Matrix3x3(
247 m[0][0], m[0][1], m[0][2],
248 m[1][0], m[1][1], m[1][2],
249 m[2][0], m[2][1], m[2][2]);
250 }
251 //! Casts a Matrix4x4 to a Quat.
252 operator Quat() const;
253 //! Casts a Matrix4x4 to a PR.
254 operator PR() const;
255
256 // Arithmetic operators
257 //! Operator for Matrix4x4 Plus = Matrix4x4 + Matrix4x4;
258 inline_ Matrix4x4 operator+(const Matrix4x4& mat) const
259 {
260 return Matrix4x4(
261 m[0][0]+mat.m[0][0], m[0][1]+mat.m[0][1], m[0][2]+mat.m[0][2], m[0][3]+mat.m[0][3],
262 m[1][0]+mat.m[1][0], m[1][1]+mat.m[1][1], m[1][2]+mat.m[1][2], m[1][3]+mat.m[1][3],
263 m[2][0]+mat.m[2][0], m[2][1]+mat.m[2][1], m[2][2]+mat.m[2][2], m[2][3]+mat.m[2][3],
264 m[3][0]+mat.m[3][0], m[3][1]+mat.m[3][1], m[3][2]+mat.m[3][2], m[3][3]+mat.m[3][3]);
265 }
266
267 //! Operator for Matrix4x4 Minus = Matrix4x4 - Matrix4x4;
268 inline_ Matrix4x4 operator-(const Matrix4x4& mat) const
269 {
270 return Matrix4x4(
271 m[0][0]-mat.m[0][0], m[0][1]-mat.m[0][1], m[0][2]-mat.m[0][2], m[0][3]-mat.m[0][3],
272 m[1][0]-mat.m[1][0], m[1][1]-mat.m[1][1], m[1][2]-mat.m[1][2], m[1][3]-mat.m[1][3],
273 m[2][0]-mat.m[2][0], m[2][1]-mat.m[2][1], m[2][2]-mat.m[2][2], m[2][3]-mat.m[2][3],
274 m[3][0]-mat.m[3][0], m[3][1]-mat.m[3][1], m[3][2]-mat.m[3][2], m[3][3]-mat.m[3][3]);
275 }
276
277 //! Operator for Matrix4x4 Mul = Matrix4x4 * Matrix4x4;
278 inline_ Matrix4x4 operator*(const Matrix4x4& mat) const
279 {
280 return Matrix4x4(
281 m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0] + m[0][3]*mat.m[3][0],
282 m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1] + m[0][3]*mat.m[3][1],
283 m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2] + m[0][3]*mat.m[3][2],
284 m[0][0]*mat.m[0][3] + m[0][1]*mat.m[1][3] + m[0][2]*mat.m[2][3] + m[0][3]*mat.m[3][3],
285
286 m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0] + m[1][3]*mat.m[3][0],
287 m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1] + m[1][3]*mat.m[3][1],
288 m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2] + m[1][3]*mat.m[3][2],
289 m[1][0]*mat.m[0][3] + m[1][1]*mat.m[1][3] + m[1][2]*mat.m[2][3] + m[1][3]*mat.m[3][3],
290
291 m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0] + m[2][3]*mat.m[3][0],
292 m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1] + m[2][3]*mat.m[3][1],
293 m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2] + m[2][3]*mat.m[3][2],
294 m[2][0]*mat.m[0][3] + m[2][1]*mat.m[1][3] + m[2][2]*mat.m[2][3] + m[2][3]*mat.m[3][3],
295
296 m[3][0]*mat.m[0][0] + m[3][1]*mat.m[1][0] + m[3][2]*mat.m[2][0] + m[3][3]*mat.m[3][0],
297 m[3][0]*mat.m[0][1] + m[3][1]*mat.m[1][1] + m[3][2]*mat.m[2][1] + m[3][3]*mat.m[3][1],
298 m[3][0]*mat.m[0][2] + m[3][1]*mat.m[1][2] + m[3][2]*mat.m[2][2] + m[3][3]*mat.m[3][2],
299 m[3][0]*mat.m[0][3] + m[3][1]*mat.m[1][3] + m[3][2]*mat.m[2][3] + m[3][3]*mat.m[3][3]);
300 }
301
302 //! Operator for HPoint Mul = Matrix4x4 * HPoint;
303 inline_ HPoint operator*(const HPoint& v) const { return HPoint(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v, GetRow(3)|v); }
304
305 //! Operator for Point Mul = Matrix4x4 * Point;
306 inline_ Point operator*(const Point& v) const
307 {
308 return Point( m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3],
309 m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3],
310 m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3] );
311 }
312
313 //! Operator for Matrix4x4 Scale = Matrix4x4 * float;
314 inline_ Matrix4x4 operator*(float s) const
315 {
316 return Matrix4x4(
317 m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s,
318 m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s,
319 m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s,
320 m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s);
321 }
322
323 //! Operator for Matrix4x4 Scale = float * Matrix4x4;
324 inline_ friend Matrix4x4 operator*(float s, const Matrix4x4& mat)
325 {
326 return Matrix4x4(
327 s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], s*mat.m[0][3],
328 s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], s*mat.m[1][3],
329 s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2], s*mat.m[2][3],
330 s*mat.m[3][0], s*mat.m[3][1], s*mat.m[3][2], s*mat.m[3][3]);
331 }
332
333 //! Operator for Matrix4x4 Div = Matrix4x4 / float;
334 inline_ Matrix4x4 operator/(float s) const
335 {
336 if(s) s = 1.0f / s;
337
338 return Matrix4x4(
339 m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s,
340 m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s,
341 m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s,
342 m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s);
343 }
344
345 //! Operator for Matrix4x4 Div = float / Matrix4x4;
346 inline_ friend Matrix4x4 operator/(float s, const Matrix4x4& mat)
347 {
348 return Matrix4x4(
349 s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], s/mat.m[0][3],
350 s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], s/mat.m[1][3],
351 s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2], s/mat.m[2][3],
352 s/mat.m[3][0], s/mat.m[3][1], s/mat.m[3][2], s/mat.m[3][3]);
353 }
354
355 //! Operator for Matrix4x4 += Matrix4x4;
356 inline_ Matrix4x4& operator+=(const Matrix4x4& mat)
357 {
358 m[0][0]+=mat.m[0][0]; m[0][1]+=mat.m[0][1]; m[0][2]+=mat.m[0][2]; m[0][3]+=mat.m[0][3];
359 m[1][0]+=mat.m[1][0]; m[1][1]+=mat.m[1][1]; m[1][2]+=mat.m[1][2]; m[1][3]+=mat.m[1][3];
360 m[2][0]+=mat.m[2][0]; m[2][1]+=mat.m[2][1]; m[2][2]+=mat.m[2][2]; m[2][3]+=mat.m[2][3];
361 m[3][0]+=mat.m[3][0]; m[3][1]+=mat.m[3][1]; m[3][2]+=mat.m[3][2]; m[3][3]+=mat.m[3][3];
362 return *this;
363 }
364
365 //! Operator for Matrix4x4 -= Matrix4x4;
366 inline_ Matrix4x4& operator-=(const Matrix4x4& mat)
367 {
368 m[0][0]-=mat.m[0][0]; m[0][1]-=mat.m[0][1]; m[0][2]-=mat.m[0][2]; m[0][3]-=mat.m[0][3];
369 m[1][0]-=mat.m[1][0]; m[1][1]-=mat.m[1][1]; m[1][2]-=mat.m[1][2]; m[1][3]-=mat.m[1][3];
370 m[2][0]-=mat.m[2][0]; m[2][1]-=mat.m[2][1]; m[2][2]-=mat.m[2][2]; m[2][3]-=mat.m[2][3];
371 m[3][0]-=mat.m[3][0]; m[3][1]-=mat.m[3][1]; m[3][2]-=mat.m[3][2]; m[3][3]-=mat.m[3][3];
372 return *this;
373 }
374
375 //! Operator for Matrix4x4 *= Matrix4x4;
376 Matrix4x4& operator*=(const Matrix4x4& mat)
377 {
378 HPoint TempRow;
379
380 GetRow(0, TempRow);
381 m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
382 m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
383 m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
384 m[0][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
385
386 GetRow(1, TempRow);
387 m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
388 m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
389 m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
390 m[1][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
391
392 GetRow(2, TempRow);
393 m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
394 m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
395 m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
396 m[2][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
397
398 GetRow(3, TempRow);
399 m[3][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0];
400 m[3][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1];
401 m[3][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2];
402 m[3][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3];
403
404 return *this;
405 }
406
407 //! Operator for Matrix4x4 *= float;
408 inline_ Matrix4x4& operator*=(float s)
409 {
410 m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s;
411 m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s;
412 m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s;
413 m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s;
414 return *this;
415 }
416
417 //! Operator for Matrix4x4 /= float;
418 inline_ Matrix4x4& operator/=(float s)
419 {
420 if(s) s = 1.0f / s;
421 m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s;
422 m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s;
423 m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s;
424 m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s;
425 return *this;
426 }
427
428 inline_ const HPoint& operator[](int row) const { return *(const HPoint*)&m[row][0]; }
429 inline_ HPoint& operator[](int row) { return *(HPoint*)&m[row][0]; }
430
431 public:
432
433 float m[4][4];
434 };
435
436 //! Quickly rotates & translates a vector, using the 4x3 part of a 4x4 matrix
437 inline_ void TransformPoint4x3(Point& dest, const Point& source, const Matrix4x4& rot)
438 {
439 dest.x = rot.m[3][0] + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
440 dest.y = rot.m[3][1] + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
441 dest.z = rot.m[3][2] + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
442 }
443
444 //! Quickly rotates a vector, using the 3x3 part of a 4x4 matrix
445 inline_ void TransformPoint3x3(Point& dest, const Point& source, const Matrix4x4& rot)
446 {
447 dest.x = source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
448 dest.y = source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
449 dest.z = source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
450 }
451
452 ICEMATHS_API void InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src);
453
454#endif // __ICEMATRIX4X4_H__
455
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceMemoryMacros.h b/libraries/ode-0.9/OPCODE/Ice/IceMemoryMacros.h
new file mode 100644
index 0000000..6386333
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceMemoryMacros.h
@@ -0,0 +1,109 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains all memory macros.
4 * \file IceMemoryMacros.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEMEMORYMACROS_H__
13#define __ICEMEMORYMACROS_H__
14
15#undef ZeroMemory
16#undef CopyMemory
17#undef MoveMemory
18#undef FillMemory
19
20 //! Clears a buffer.
21 //! \param addr [in] buffer address
22 //! \param size [in] buffer length
23 //! \see FillMemory
24 //! \see StoreDwords
25 //! \see CopyMemory
26 //! \see MoveMemory
27 inline_ void ZeroMemory(void* addr, udword size) { memset(addr, 0, size); }
28
29 //! Fills a buffer with a given byte.
30 //! \param addr [in] buffer address
31 //! \param size [in] buffer length
32 //! \param val [in] the byte value
33 //! \see StoreDwords
34 //! \see ZeroMemory
35 //! \see CopyMemory
36 //! \see MoveMemory
37 inline_ void FillMemory(void* dest, udword size, ubyte val) { memset(dest, val, size); }
38
39 //! Fills a buffer with a given dword.
40 //! \param addr [in] buffer address
41 //! \param nb [in] number of dwords to write
42 //! \param value [in] the dword value
43 //! \see FillMemory
44 //! \see ZeroMemory
45 //! \see CopyMemory
46 //! \see MoveMemory
47 //! \warning writes nb*4 bytes !
48 inline_ void StoreDwords(udword* dest, udword nb, udword value)
49 {
50 // The asm code below **SHOULD** be equivalent to one of those C versions
51 // or the other if your compiled is good: (checked on VC++ 6.0)
52 //
53 // 1) while(nb--) *dest++ = value;
54 //
55 // 2) for(udword i=0;i<nb;i++) dest[i] = value;
56 //
57#ifdef _MSC_VER
58 _asm push eax
59 _asm push ecx
60 _asm push edi
61 _asm mov edi, dest
62 _asm mov ecx, nb
63 _asm mov eax, value
64 _asm rep stosd
65 _asm pop edi
66 _asm pop ecx
67 _asm pop eax
68#else
69 while(nb--) *dest++ = value;
70#endif
71 }
72
73 //! Copies a buffer.
74 //! \param addr [in] destination buffer address
75 //! \param addr [in] source buffer address
76 //! \param size [in] buffer length
77 //! \see ZeroMemory
78 //! \see FillMemory
79 //! \see StoreDwords
80 //! \see MoveMemory
81 inline_ void CopyMemory(void* dest, const void* src, udword size) { memcpy(dest, src, size); }
82
83 //! Moves a buffer.
84 //! \param addr [in] destination buffer address
85 //! \param addr [in] source buffer address
86 //! \param size [in] buffer length
87 //! \see ZeroMemory
88 //! \see FillMemory
89 //! \see StoreDwords
90 //! \see CopyMemory
91 inline_ void MoveMemory(void* dest, const void* src, udword size) { memmove(dest, src, size); }
92
93 #define SIZEOFOBJECT sizeof(*this) //!< Gives the size of current object. Avoid some mistakes (e.g. "sizeof(this)").
94 //#define CLEAROBJECT { memset(this, 0, SIZEOFOBJECT); } //!< Clears current object. Laziness is my business. HANDLE WITH CARE.
95 #define DELETESINGLE(x) if (x) { delete x; x = null; } //!< Deletes an instance of a class.
96 #define DELETEARRAY(x) if (x) { delete []x; x = null; } //!< Deletes an array.
97 #define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = null; } //!< Safe D3D-style release
98 #define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; } //!< Safe ICE-style release
99
100#ifdef __ICEERROR_H__
101 #define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY); //!< Standard alloc checking. HANDLE WITH CARE.
102#else
103 #define CHECKALLOC(x) if(!x) return false;
104#endif
105
106 //! Standard allocation cycle
107 #define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr);
108
109#endif // __ICEMEMORYMACROS_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceOBB.cpp b/libraries/ode-0.9/OPCODE/Ice/IceOBB.cpp
new file mode 100644
index 0000000..0b1b6f7
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceOBB.cpp
@@ -0,0 +1,323 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains OBB-related code.
4 * \file IceOBB.cpp
5 * \author Pierre Terdiman
6 * \date January, 29, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * An Oriented Bounding Box (OBB).
13 * \class OBB
14 * \author Pierre Terdiman
15 * \version 1.0
16 */
17///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18
19///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20// Precompiled Header
21#include "Stdafx.h"
22
23using namespace IceMaths;
24
25///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26/**
27 * Tests if a point is contained within the OBB.
28 * \param p [in] the world point to test
29 * \return true if inside the OBB
30 */
31///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32bool OBB::ContainsPoint(const Point& p) const
33{
34 // Point in OBB test using lazy evaluation and early exits
35
36 // Translate to box space
37 Point RelPoint = p - mCenter;
38
39 // Point * mRot maps from box space to world space
40 // mRot * Point maps from world space to box space (what we need here)
41
42 float f = mRot.m[0][0] * RelPoint.x + mRot.m[0][1] * RelPoint.y + mRot.m[0][2] * RelPoint.z;
43 if(f >= mExtents.x || f <= -mExtents.x) return false;
44
45 f = mRot.m[1][0] * RelPoint.x + mRot.m[1][1] * RelPoint.y + mRot.m[1][2] * RelPoint.z;
46 if(f >= mExtents.y || f <= -mExtents.y) return false;
47
48 f = mRot.m[2][0] * RelPoint.x + mRot.m[2][1] * RelPoint.y + mRot.m[2][2] * RelPoint.z;
49 if(f >= mExtents.z || f <= -mExtents.z) return false;
50 return true;
51}
52
53///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54/**
55 * Builds an OBB from an AABB and a world transform.
56 * \param aabb [in] the aabb
57 * \param mat [in] the world transform
58 */
59///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60void OBB::Create(const AABB& aabb, const Matrix4x4& mat)
61{
62 // Note: must be coherent with Rotate()
63
64 aabb.GetCenter(mCenter);
65 aabb.GetExtents(mExtents);
66 // Here we have the same as OBB::Rotate(mat) where the obb is (mCenter, mExtents, Identity).
67
68 // So following what's done in Rotate:
69 // - x-form the center
70 mCenter *= mat;
71 // - combine rotation with identity, i.e. just use given matrix
72 mRot = mat;
73}
74
75///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
76/**
77 * Computes the obb planes.
78 * \param planes [out] 6 box planes
79 * \return true if success
80 */
81///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
82bool OBB::ComputePlanes(Plane* planes) const
83{
84 // Checkings
85 if(!planes) return false;
86
87 Point Axis0 = mRot[0];
88 Point Axis1 = mRot[1];
89 Point Axis2 = mRot[2];
90
91 // Writes normals
92 planes[0].n = Axis0;
93 planes[1].n = -Axis0;
94 planes[2].n = Axis1;
95 planes[3].n = -Axis1;
96 planes[4].n = Axis2;
97 planes[5].n = -Axis2;
98
99 // Compute a point on each plane
100 Point p0 = mCenter + Axis0 * mExtents.x;
101 Point p1 = mCenter - Axis0 * mExtents.x;
102 Point p2 = mCenter + Axis1 * mExtents.y;
103 Point p3 = mCenter - Axis1 * mExtents.y;
104 Point p4 = mCenter + Axis2 * mExtents.z;
105 Point p5 = mCenter - Axis2 * mExtents.z;
106
107 // Compute d
108 planes[0].d = -(planes[0].n|p0);
109 planes[1].d = -(planes[1].n|p1);
110 planes[2].d = -(planes[2].n|p2);
111 planes[3].d = -(planes[3].n|p3);
112 planes[4].d = -(planes[4].n|p4);
113 planes[5].d = -(planes[5].n|p5);
114
115 return true;
116}
117
118///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
119/**
120 * Computes the obb points.
121 * \param pts [out] 8 box points
122 * \return true if success
123 */
124///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
125bool OBB::ComputePoints(Point* pts) const
126{
127 // Checkings
128 if(!pts) return false;
129
130 Point Axis0 = mRot[0];
131 Point Axis1 = mRot[1];
132 Point Axis2 = mRot[2];
133
134 Axis0 *= mExtents.x;
135 Axis1 *= mExtents.y;
136 Axis2 *= mExtents.z;
137
138 // 7+------+6 0 = ---
139 // /| /| 1 = +--
140 // / | / | 2 = ++-
141 // / 4+---/--+5 3 = -+-
142 // 3+------+2 / y z 4 = --+
143 // | / | / | / 5 = +-+
144 // |/ |/ |/ 6 = +++
145 // 0+------+1 *---x 7 = -++
146
147 pts[0] = mCenter - Axis0 - Axis1 - Axis2;
148 pts[1] = mCenter + Axis0 - Axis1 - Axis2;
149 pts[2] = mCenter + Axis0 + Axis1 - Axis2;
150 pts[3] = mCenter - Axis0 + Axis1 - Axis2;
151 pts[4] = mCenter - Axis0 - Axis1 + Axis2;
152 pts[5] = mCenter + Axis0 - Axis1 + Axis2;
153 pts[6] = mCenter + Axis0 + Axis1 + Axis2;
154 pts[7] = mCenter - Axis0 + Axis1 + Axis2;
155
156 return true;
157}
158
159///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
160/**
161 * Computes vertex normals.
162 * \param pts [out] 8 box points
163 * \return true if success
164 */
165///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
166bool OBB::ComputeVertexNormals(Point* pts) const
167{
168 static float VertexNormals[] =
169 {
170 -INVSQRT3, -INVSQRT3, -INVSQRT3,
171 INVSQRT3, -INVSQRT3, -INVSQRT3,
172 INVSQRT3, INVSQRT3, -INVSQRT3,
173 -INVSQRT3, INVSQRT3, -INVSQRT3,
174 -INVSQRT3, -INVSQRT3, INVSQRT3,
175 INVSQRT3, -INVSQRT3, INVSQRT3,
176 INVSQRT3, INVSQRT3, INVSQRT3,
177 -INVSQRT3, INVSQRT3, INVSQRT3
178 };
179
180 if(!pts) return false;
181
182 const Point* VN = (const Point*)VertexNormals;
183 for(udword i=0;i<8;i++)
184 {
185 pts[i] = VN[i] * mRot;
186 }
187
188 return true;
189}
190
191///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
192/**
193 * Returns edges.
194 * \return 24 indices (12 edges) indexing the list returned by ComputePoints()
195 */
196///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
197const udword* OBB::GetEdges() const
198{
199 static udword Indices[] = {
200 0, 1, 1, 2, 2, 3, 3, 0,
201 7, 6, 6, 5, 5, 4, 4, 7,
202 1, 5, 6, 2,
203 3, 7, 4, 0
204 };
205 return Indices;
206}
207
208///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
209/**
210 * Returns local edge normals.
211 * \return edge normals in local space
212 */
213///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
214const Point* OBB::GetLocalEdgeNormals() const
215{
216 static float EdgeNormals[] =
217 {
218 0, -INVSQRT2, -INVSQRT2, // 0-1
219 INVSQRT2, 0, -INVSQRT2, // 1-2
220 0, INVSQRT2, -INVSQRT2, // 2-3
221 -INVSQRT2, 0, -INVSQRT2, // 3-0
222
223 0, INVSQRT2, INVSQRT2, // 7-6
224 INVSQRT2, 0, INVSQRT2, // 6-5
225 0, -INVSQRT2, INVSQRT2, // 5-4
226 -INVSQRT2, 0, INVSQRT2, // 4-7
227
228 INVSQRT2, -INVSQRT2, 0, // 1-5
229 INVSQRT2, INVSQRT2, 0, // 6-2
230 -INVSQRT2, INVSQRT2, 0, // 3-7
231 -INVSQRT2, -INVSQRT2, 0 // 4-0
232 };
233 return (const Point*)EdgeNormals;
234}
235
236///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
237/**
238 * Returns world edge normal
239 * \param edge_index [in] 0 <= edge index < 12
240 * \param world_normal [out] edge normal in world space
241 */
242///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
243void OBB::ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const
244{
245 ASSERT(edge_index<12);
246 world_normal = GetLocalEdgeNormals()[edge_index] * mRot;
247}
248
249///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
250/**
251 * Computes an LSS surrounding the OBB.
252 * \param lss [out] the LSS
253 */
254///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
255void OBB::ComputeLSS(LSS& lss) const
256{
257 Point Axis0 = mRot[0];
258 Point Axis1 = mRot[1];
259 Point Axis2 = mRot[2];
260
261 switch(mExtents.LargestAxis())
262 {
263 case 0:
264 lss.mRadius = (mExtents.y + mExtents.z)*0.5f;
265 lss.mP0 = mCenter + Axis0 * (mExtents.x - lss.mRadius);
266 lss.mP1 = mCenter - Axis0 * (mExtents.x - lss.mRadius);
267 break;
268 case 1:
269 lss.mRadius = (mExtents.x + mExtents.z)*0.5f;
270 lss.mP0 = mCenter + Axis1 * (mExtents.y - lss.mRadius);
271 lss.mP1 = mCenter - Axis1 * (mExtents.y - lss.mRadius);
272 break;
273 case 2:
274 lss.mRadius = (mExtents.x + mExtents.y)*0.5f;
275 lss.mP0 = mCenter + Axis2 * (mExtents.z - lss.mRadius);
276 lss.mP1 = mCenter - Axis2 * (mExtents.z - lss.mRadius);
277 break;
278 }
279}
280
281///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
282/**
283 * Checks the OBB is inside another OBB.
284 * \param box [in] the other OBB
285 * \return TRUE if we're inside the other box
286 */
287///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
288BOOL OBB::IsInside(const OBB& box) const
289{
290 // Make a 4x4 from the box & inverse it
291 Matrix4x4 M0Inv;
292 {
293 Matrix4x4 M0 = box.mRot;
294 M0.SetTrans(box.mCenter);
295 InvertPRMatrix(M0Inv, M0);
296 }
297
298 // With our inversed 4x4, create box1 in space of box0
299 OBB _1in0;
300 Rotate(M0Inv, _1in0);
301
302 // This should cancel out box0's rotation, i.e. it's now an AABB.
303 // => Center(0,0,0), Rot(identity)
304
305 // The two boxes are in the same space so now we can compare them.
306
307 // Create the AABB of (box1 in space of box0)
308 const Matrix3x3& mtx = _1in0.mRot;
309
310 float f = fabsf(mtx.m[0][0] * mExtents.x) + fabsf(mtx.m[1][0] * mExtents.y) + fabsf(mtx.m[2][0] * mExtents.z) - box.mExtents.x;
311 if(f > _1in0.mCenter.x) return FALSE;
312 if(-f < _1in0.mCenter.x) return FALSE;
313
314 f = fabsf(mtx.m[0][1] * mExtents.x) + fabsf(mtx.m[1][1] * mExtents.y) + fabsf(mtx.m[2][1] * mExtents.z) - box.mExtents.y;
315 if(f > _1in0.mCenter.y) return FALSE;
316 if(-f < _1in0.mCenter.y) return FALSE;
317
318 f = fabsf(mtx.m[0][2] * mExtents.x) + fabsf(mtx.m[1][2] * mExtents.y) + fabsf(mtx.m[2][2] * mExtents.z) - box.mExtents.z;
319 if(f > _1in0.mCenter.z) return FALSE;
320 if(-f < _1in0.mCenter.z) return FALSE;
321
322 return TRUE;
323}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceOBB.h b/libraries/ode-0.9/OPCODE/Ice/IceOBB.h
new file mode 100644
index 0000000..d6cf43e
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceOBB.h
@@ -0,0 +1,177 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains OBB-related code. (oriented bounding box)
4 * \file IceOBB.h
5 * \author Pierre Terdiman
6 * \date January, 13, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEOBB_H__
13#define __ICEOBB_H__
14
15 // Forward declarations
16 class LSS;
17
18 class ICEMATHS_API OBB
19 {
20 public:
21 //! Constructor
22 inline_ OBB() {}
23 //! Constructor
24 inline_ OBB(const Point& center, const Point& extents, const Matrix3x3& rot) : mCenter(center), mExtents(extents), mRot(rot) {}
25 //! Destructor
26 inline_ ~OBB() {}
27
28 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
29 /**
30 * Setups an empty OBB.
31 */
32 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
33 void SetEmpty()
34 {
35 mCenter.Zero();
36 mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);
37 mRot.Identity();
38 }
39
40 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
41 /**
42 * Tests if a point is contained within the OBB.
43 * \param p [in] the world point to test
44 * \return true if inside the OBB
45 */
46 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
47 bool ContainsPoint(const Point& p) const;
48
49 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
50 /**
51 * Builds an OBB from an AABB and a world transform.
52 * \param aabb [in] the aabb
53 * \param mat [in] the world transform
54 */
55 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
56 void Create(const AABB& aabb, const Matrix4x4& mat);
57
58 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
59 /**
60 * Recomputes the OBB after an arbitrary transform by a 4x4 matrix.
61 * \param mtx [in] the transform matrix
62 * \param obb [out] the transformed OBB
63 */
64 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
65 inline_ void Rotate(const Matrix4x4& mtx, OBB& obb) const
66 {
67 // The extents remain constant
68 obb.mExtents = mExtents;
69 // The center gets x-formed
70 obb.mCenter = mCenter * mtx;
71 // Combine rotations
72 obb.mRot = mRot * Matrix3x3(mtx);
73 }
74
75 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
76 /**
77 * Checks the OBB is valid.
78 * \return true if the box is valid
79 */
80 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 inline_ BOOL IsValid() const
82 {
83 // Consistency condition for (Center, Extents) boxes: Extents >= 0.0f
84 if(mExtents.x < 0.0f) return FALSE;
85 if(mExtents.y < 0.0f) return FALSE;
86 if(mExtents.z < 0.0f) return FALSE;
87 return TRUE;
88 }
89
90 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91 /**
92 * Computes the obb planes.
93 * \param planes [out] 6 box planes
94 * \return true if success
95 */
96 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
97 bool ComputePlanes(Plane* planes) const;
98
99 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
100 /**
101 * Computes the obb points.
102 * \param pts [out] 8 box points
103 * \return true if success
104 */
105 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
106 bool ComputePoints(Point* pts) const;
107
108 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
109 /**
110 * Computes vertex normals.
111 * \param pts [out] 8 box points
112 * \return true if success
113 */
114 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
115 bool ComputeVertexNormals(Point* pts) const;
116
117 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
118 /**
119 * Returns edges.
120 * \return 24 indices (12 edges) indexing the list returned by ComputePoints()
121 */
122 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
123 const udword* GetEdges() const;
124
125 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
126 /**
127 * Returns local edge normals.
128 * \return edge normals in local space
129 */
130 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
131 const Point* GetLocalEdgeNormals() const;
132
133 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
134 /**
135 * Returns world edge normal
136 * \param edge_index [in] 0 <= edge index < 12
137 * \param world_normal [out] edge normal in world space
138 */
139 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
140 void ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const;
141
142 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
143 /**
144 * Computes an LSS surrounding the OBB.
145 * \param lss [out] the LSS
146 */
147 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
148 void ComputeLSS(LSS& lss) const;
149
150 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
151 /**
152 * Checks the OBB is inside another OBB.
153 * \param box [in] the other OBB
154 * \return TRUE if we're inside the other box
155 */
156 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
157 BOOL IsInside(const OBB& box) const;
158
159 inline_ const Point& GetCenter() const { return mCenter; }
160 inline_ const Point& GetExtents() const { return mExtents; }
161 inline_ const Matrix3x3& GetRot() const { return mRot; }
162
163 inline_ void GetRotatedExtents(Matrix3x3& extents) const
164 {
165 extents = mRot;
166 extents.Scale(mExtents);
167 }
168
169 Point mCenter; //!< B for Box
170 Point mExtents; //!< B for Bounding
171 Matrix3x3 mRot; //!< O for Oriented
172
173 // Orientation is stored in row-major format,
174 // i.e. rows = eigen vectors of the covariance matrix
175 };
176
177#endif // __ICEOBB_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePairs.h b/libraries/ode-0.9/OPCODE/Ice/IcePairs.h
new file mode 100644
index 0000000..2c09b92
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IcePairs.h
@@ -0,0 +1,45 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains a simple pair class.
4 * \file IcePairs.h
5 * \author Pierre Terdiman
6 * \date January, 13, 2003
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEPAIRS_H__
13#define __ICEPAIRS_H__
14
15 //! A generic couple structure
16 struct ICECORE_API Pair
17 {
18 inline_ Pair() {}
19 inline_ Pair(udword i0, udword i1) : id0(i0), id1(i1) {}
20
21 udword id0; //!< First index of the pair
22 udword id1; //!< Second index of the pair
23 };
24
25 class ICECORE_API Pairs : private Container
26 {
27 public:
28 // Constructor / Destructor
29 Pairs() {}
30 ~Pairs() {}
31
32 inline_ udword GetNbPairs() const { return GetNbEntries()>>1; }
33 inline_ const Pair* GetPairs() const { return (const Pair*)GetEntries(); }
34 inline_ const Pair* GetPair(udword i) const { return (const Pair*)&GetEntries()[i+i]; }
35
36 inline_ BOOL HasPairs() const { return IsNotEmpty(); }
37
38 inline_ void ResetPairs() { Reset(); }
39 inline_ void DeleteLastPair() { DeleteLastEntry(); DeleteLastEntry(); }
40
41 inline_ void AddPair(const Pair& p) { Add(p.id0).Add(p.id1); }
42 inline_ void AddPair(udword id0, udword id1) { Add(id0).Add(id1); }
43 };
44
45#endif // __ICEPAIRS_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePlane.cpp b/libraries/ode-0.9/OPCODE/Ice/IcePlane.cpp
new file mode 100644
index 0000000..394b31b
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IcePlane.cpp
@@ -0,0 +1,45 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for planes.
4 * \file IcePlane.cpp
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * Plane class.
13 * \class Plane
14 * \author Pierre Terdiman
15 * \version 1.0
16 */
17///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18
19///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20// Precompiled Header
21#include "Stdafx.h"
22
23using namespace IceMaths;
24
25///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26/**
27 * Computes the plane equation from 3 points.
28 * \param p0 [in] first point
29 * \param p1 [in] second point
30 * \param p2 [in] third point
31 * \return Self-reference
32 */
33///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
34Plane& Plane::Set(const Point& p0, const Point& p1, const Point& p2)
35{
36 Point Edge0 = p1 - p0;
37 Point Edge1 = p2 - p0;
38
39 n = Edge0 ^ Edge1;
40 n.Normalize();
41
42 d = -(p0 | n);
43
44 return *this;
45}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePlane.h b/libraries/ode-0.9/OPCODE/Ice/IcePlane.h
new file mode 100644
index 0000000..4d47081
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IcePlane.h
@@ -0,0 +1,113 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for planes.
4 * \file IcePlane.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEPLANE_H__
13#define __ICEPLANE_H__
14
15 #define PLANE_EPSILON (1.0e-7f)
16
17 class ICEMATHS_API Plane
18 {
19 public:
20 //! Constructor
21 inline_ Plane() { }
22 //! Constructor from a normal and a distance
23 inline_ Plane(float nx, float ny, float nz, float d) { Set(nx, ny, nz, d); }
24 //! Constructor from a point on the plane and a normal
25 inline_ Plane(const Point& p, const Point& n) { Set(p, n); }
26 //! Constructor from three points
27 inline_ Plane(const Point& p0, const Point& p1, const Point& p2) { Set(p0, p1, p2); }
28 //! Constructor from a normal and a distance
29 inline_ Plane(const Point& _n, float _d) { n = _n; d = _d; }
30 //! Copy constructor
31 inline_ Plane(const Plane& plane) : n(plane.n), d(plane.d) { }
32 //! Destructor
33 inline_ ~Plane() { }
34
35 inline_ Plane& Zero() { n.Zero(); d = 0.0f; return *this; }
36 inline_ Plane& Set(float nx, float ny, float nz, float _d) { n.Set(nx, ny, nz); d = _d; return *this; }
37 inline_ Plane& Set(const Point& p, const Point& _n) { n = _n; d = - p | _n; return *this; }
38 Plane& Set(const Point& p0, const Point& p1, const Point& p2);
39
40 inline_ float Distance(const Point& p) const { return (p | n) + d; }
41 inline_ bool Belongs(const Point& p) const { return fabsf(Distance(p)) < PLANE_EPSILON; }
42
43 inline_ void Normalize()
44 {
45 float Denom = 1.0f / n.Magnitude();
46 n.x *= Denom;
47 n.y *= Denom;
48 n.z *= Denom;
49 d *= Denom;
50 }
51 public:
52 // Members
53 Point n; //!< The normal to the plane
54 float d; //!< The distance from the origin
55
56 // Cast operators
57 inline_ operator Point() const { return n; }
58 inline_ operator HPoint() const { return HPoint(n, d); }
59
60 // Arithmetic operators
61 inline_ Plane operator*(const Matrix4x4& m) const
62 {
63 // Old code from Irion. Kept for reference.
64 Plane Ret(*this);
65 return Ret *= m;
66 }
67
68 inline_ Plane& operator*=(const Matrix4x4& m)
69 {
70 // Old code from Irion. Kept for reference.
71 Point n2 = HPoint(n, 0.0f) * m;
72 d = -((Point) (HPoint( -d*n, 1.0f ) * m) | n2);
73 n = n2;
74 return *this;
75 }
76 };
77
78 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
79 /**
80 * Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster.
81 * \param transformed [out] transformed plane
82 * \param plane [in] source plane
83 * \param transform [in] transform matrix
84 * \warning the plane normal must be unit-length
85 */
86 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
87 inline_ void TransformPlane(Plane& transformed, const Plane& plane, const Matrix4x4& transform)
88 {
89 // Rotate the normal using the rotation part of the 4x4 matrix
90 transformed.n = plane.n * Matrix3x3(transform);
91
92 // Compute new d
93 transformed.d = plane.d - (Point(transform.GetTrans())|transformed.n);
94 }
95
96 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
97 /**
98 * Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster.
99 * \param plane [in/out] source plane (transformed on return)
100 * \param transform [in] transform matrix
101 * \warning the plane normal must be unit-length
102 */
103 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
104 inline_ void TransformPlane(Plane& plane, const Matrix4x4& transform)
105 {
106 // Rotate the normal using the rotation part of the 4x4 matrix
107 plane.n *= Matrix3x3(transform);
108
109 // Compute new d
110 plane.d -= Point(transform.GetTrans())|plane.n;
111 }
112
113#endif // __ICEPLANE_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp b/libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp
new file mode 100644
index 0000000..e715055
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp
@@ -0,0 +1,193 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for 3D vectors.
4 * \file IcePoint.cpp
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * 3D point.
13 *
14 * The name is "Point" instead of "Vector" since a vector is N-dimensional, whereas a point is an implicit "vector of dimension 3".
15 * So the choice was between "Point" and "Vector3", the first one looked better (IMHO).
16 *
17 * Some people, then, use a typedef to handle both points & vectors using the same class: typedef Point Vector3;
18 * This is bad since it opens the door to a lot of confusion while reading the code. I know it may sounds weird but check this out:
19 *
20 * \code
21 * Point P0,P1 = some 3D points;
22 * Point Delta = P1 - P0;
23 * \endcode
24 *
25 * This compiles fine, although you should have written:
26 *
27 * \code
28 * Point P0,P1 = some 3D points;
29 * Vector3 Delta = P1 - P0;
30 * \endcode
31 *
32 * Subtle things like this are not caught at compile-time, and when you find one in the code, you never know whether it's a mistake
33 * from the author or something you don't get.
34 *
35 * One way to handle it at compile-time would be to use different classes for Point & Vector3, only overloading operator "-" for vectors.
36 * But then, you get a lot of redundant code in thoses classes, and basically it's really a lot of useless work.
37 *
38 * Another way would be to use homogeneous points: w=1 for points, w=0 for vectors. That's why the HPoint class exists. Now, to store
39 * your model's vertices and in most cases, you really want to use Points to save ram.
40 *
41 * \class Point
42 * \author Pierre Terdiman
43 * \version 1.0
44 */
45///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
46
47///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
48// Precompiled Header
49#include "Stdafx.h"
50
51using namespace IceMaths;
52
53///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54/**
55 * Creates a positive unit random vector.
56 * \return Self-reference
57 */
58///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
59Point& Point::PositiveUnitRandomVector()
60{
61 x = UnitRandomFloat();
62 y = UnitRandomFloat();
63 z = UnitRandomFloat();
64 Normalize();
65 return *this;
66}
67
68///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
69/**
70 * Creates a unit random vector.
71 * \return Self-reference
72 */
73///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
74Point& Point::UnitRandomVector()
75{
76 x = UnitRandomFloat() - 0.5f;
77 y = UnitRandomFloat() - 0.5f;
78 z = UnitRandomFloat() - 0.5f;
79 Normalize();
80 return *this;
81}
82
83// Cast operator
84// WARNING: not inlined
85Point::operator HPoint() const { return HPoint(x, y, z, 0.0f); }
86
87Point& Point::Refract(const Point& eye, const Point& n, float refractindex, Point& refracted)
88{
89 // Point EyePt = eye position
90 // Point p = current vertex
91 // Point n = vertex normal
92 // Point rv = refracted vector
93 // Eye vector - doesn't need to be normalized
94 Point Env;
95 Env.x = eye.x - x;
96 Env.y = eye.y - y;
97 Env.z = eye.z - z;
98
99 float NDotE = n|Env;
100 float NDotN = n|n;
101 NDotE /= refractindex;
102
103 // Refracted vector
104 refracted = n*NDotE - Env*NDotN;
105
106 return *this;
107}
108
109Point& Point::ProjectToPlane(const Plane& p)
110{
111 *this-= (p.d + (*this|p.n))*p.n;
112 return *this;
113}
114
115void Point::ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const
116{
117 projected = HPoint(x, y, z, 1.0f) * mat;
118 projected.w = 1.0f / projected.w;
119
120 projected.x*=projected.w;
121 projected.y*=projected.w;
122 projected.z*=projected.w;
123
124 projected.x *= halfrenderwidth; projected.x += halfrenderwidth;
125 projected.y *= -halfrenderheight; projected.y += halfrenderheight;
126}
127
128void Point::SetNotUsed()
129{
130 // We use a particular integer pattern : 0xffffffff everywhere. This is a NAN.
131 IR(x) = 0xffffffff;
132 IR(y) = 0xffffffff;
133 IR(z) = 0xffffffff;
134}
135
136BOOL Point::IsNotUsed() const
137{
138 if(IR(x)!=0xffffffff) return FALSE;
139 if(IR(y)!=0xffffffff) return FALSE;
140 if(IR(z)!=0xffffffff) return FALSE;
141 return TRUE;
142}
143
144Point& Point::Mult(const Matrix3x3& mat, const Point& a)
145{
146 x = a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2];
147 y = a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2];
148 z = a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2];
149 return *this;
150}
151
152Point& Point::Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2)
153{
154 x = a1.x * mat1.m[0][0] + a1.y * mat1.m[0][1] + a1.z * mat1.m[0][2] + a2.x * mat2.m[0][0] + a2.y * mat2.m[0][1] + a2.z * mat2.m[0][2];
155 y = a1.x * mat1.m[1][0] + a1.y * mat1.m[1][1] + a1.z * mat1.m[1][2] + a2.x * mat2.m[1][0] + a2.y * mat2.m[1][1] + a2.z * mat2.m[1][2];
156 z = a1.x * mat1.m[2][0] + a1.y * mat1.m[2][1] + a1.z * mat1.m[2][2] + a2.x * mat2.m[2][0] + a2.y * mat2.m[2][1] + a2.z * mat2.m[2][2];
157 return *this;
158}
159
160Point& Point::Mac(const Matrix3x3& mat, const Point& a)
161{
162 x += a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2];
163 y += a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2];
164 z += a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2];
165 return *this;
166}
167
168Point& Point::TransMult(const Matrix3x3& mat, const Point& a)
169{
170 x = a.x * mat.m[0][0] + a.y * mat.m[1][0] + a.z * mat.m[2][0];
171 y = a.x * mat.m[0][1] + a.y * mat.m[1][1] + a.z * mat.m[2][1];
172 z = a.x * mat.m[0][2] + a.y * mat.m[1][2] + a.z * mat.m[2][2];
173 return *this;
174}
175
176Point& Point::Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos)
177{
178 x = r.x * rotpos.m[0][0] + r.y * rotpos.m[0][1] + r.z * rotpos.m[0][2] + linpos.x;
179 y = r.x * rotpos.m[1][0] + r.y * rotpos.m[1][1] + r.z * rotpos.m[1][2] + linpos.y;
180 z = r.x * rotpos.m[2][0] + r.y * rotpos.m[2][1] + r.z * rotpos.m[2][2] + linpos.z;
181 return *this;
182}
183
184Point& Point::InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos)
185{
186 float sx = r.x - linpos.x;
187 float sy = r.y - linpos.y;
188 float sz = r.z - linpos.z;
189 x = sx * rotpos.m[0][0] + sy * rotpos.m[1][0] + sz * rotpos.m[2][0];
190 y = sx * rotpos.m[0][1] + sy * rotpos.m[1][1] + sz * rotpos.m[2][1];
191 z = sx * rotpos.m[0][2] + sy * rotpos.m[1][2] + sz * rotpos.m[2][2];
192 return *this;
193}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePoint.h b/libraries/ode-0.9/OPCODE/Ice/IcePoint.h
new file mode 100644
index 0000000..a97fbe6
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IcePoint.h
@@ -0,0 +1,528 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for 3D vectors.
4 * \file IcePoint.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEPOINT_H__
13#define __ICEPOINT_H__
14
15 // Forward declarations
16 class HPoint;
17 class Plane;
18 class Matrix3x3;
19 class Matrix4x4;
20
21 #define CROSS2D(a, b) (a.x*b.y - b.x*a.y)
22
23 const float EPSILON2 = 1.0e-20f;
24
25 class ICEMATHS_API Point
26 {
27 public:
28
29 //! Empty constructor
30 inline_ Point() {}
31 //! Constructor from a single float
32// inline_ Point(float val) : x(val), y(val), z(val) {}
33// Removed since it introduced the nasty "Point T = *Matrix4x4.GetTrans();" bug.......
34 //! Constructor from floats
35 inline_ Point(float xx, float yy, float zz) : x(xx), y(yy), z(zz) {}
36 //! Constructor from array
37 inline_ Point(const float f[3]) : x(f[X]), y(f[Y]), z(f[Z]) {}
38 //! Copy constructor
39 inline_ Point(const Point& p) : x(p.x), y(p.y), z(p.z) {}
40 //! Destructor
41 inline_ ~Point() {}
42
43 //! Clears the vector
44 inline_ Point& Zero() { x = y = z = 0.0f; return *this; }
45
46 //! + infinity
47 inline_ Point& SetPlusInfinity() { x = y = z = MAX_FLOAT; return *this; }
48 //! - infinity
49 inline_ Point& SetMinusInfinity() { x = y = z = MIN_FLOAT; return *this; }
50
51 //! Sets positive unit random vector
52 Point& PositiveUnitRandomVector();
53 //! Sets unit random vector
54 Point& UnitRandomVector();
55
56 //! Assignment from values
57 inline_ Point& Set(float xx, float yy, float zz) { x = xx; y = yy; z = zz; return *this; }
58 //! Assignment from array
59 inline_ Point& Set(const float f[3]) { x = f[X]; y = f[Y]; z = f[Z]; return *this; }
60 //! Assignment from another point
61 inline_ Point& Set(const Point& src) { x = src.x; y = src.y; z = src.z; return *this; }
62
63 //! Adds a vector
64 inline_ Point& Add(const Point& p) { x += p.x; y += p.y; z += p.z; return *this; }
65 //! Adds a vector
66 inline_ Point& Add(float xx, float yy, float zz) { x += xx; y += yy; z += zz; return *this; }
67 //! Adds a vector
68 inline_ Point& Add(const float f[3]) { x += f[X]; y += f[Y]; z += f[Z]; return *this; }
69 //! Adds vectors
70 inline_ Point& Add(const Point& p, const Point& q) { x = p.x+q.x; y = p.y+q.y; z = p.z+q.z; return *this; }
71
72 //! Subtracts a vector
73 inline_ Point& Sub(const Point& p) { x -= p.x; y -= p.y; z -= p.z; return *this; }
74 //! Subtracts a vector
75 inline_ Point& Sub(float xx, float yy, float zz) { x -= xx; y -= yy; z -= zz; return *this; }
76 //! Subtracts a vector
77 inline_ Point& Sub(const float f[3]) { x -= f[X]; y -= f[Y]; z -= f[Z]; return *this; }
78 //! Subtracts vectors
79 inline_ Point& Sub(const Point& p, const Point& q) { x = p.x-q.x; y = p.y-q.y; z = p.z-q.z; return *this; }
80
81 //! this = -this
82 inline_ Point& Neg() { x = -x; y = -y; z = -z; return *this; }
83 //! this = -a
84 inline_ Point& Neg(const Point& a) { x = -a.x; y = -a.y; z = -a.z; return *this; }
85
86 //! Multiplies by a scalar
87 inline_ Point& Mult(float s) { x *= s; y *= s; z *= s; return *this; }
88
89 //! this = a * scalar
90 inline_ Point& Mult(const Point& a, float scalar)
91 {
92 x = a.x * scalar;
93 y = a.y * scalar;
94 z = a.z * scalar;
95 return *this;
96 }
97
98 //! this = a + b * scalar
99 inline_ Point& Mac(const Point& a, const Point& b, float scalar)
100 {
101 x = a.x + b.x * scalar;
102 y = a.y + b.y * scalar;
103 z = a.z + b.z * scalar;
104 return *this;
105 }
106
107 //! this = this + a * scalar
108 inline_ Point& Mac(const Point& a, float scalar)
109 {
110 x += a.x * scalar;
111 y += a.y * scalar;
112 z += a.z * scalar;
113 return *this;
114 }
115
116 //! this = a - b * scalar
117 inline_ Point& Msc(const Point& a, const Point& b, float scalar)
118 {
119 x = a.x - b.x * scalar;
120 y = a.y - b.y * scalar;
121 z = a.z - b.z * scalar;
122 return *this;
123 }
124
125 //! this = this - a * scalar
126 inline_ Point& Msc(const Point& a, float scalar)
127 {
128 x -= a.x * scalar;
129 y -= a.y * scalar;
130 z -= a.z * scalar;
131 return *this;
132 }
133
134 //! this = a + b * scalarb + c * scalarc
135 inline_ Point& Mac2(const Point& a, const Point& b, float scalarb, const Point& c, float scalarc)
136 {
137 x = a.x + b.x * scalarb + c.x * scalarc;
138 y = a.y + b.y * scalarb + c.y * scalarc;
139 z = a.z + b.z * scalarb + c.z * scalarc;
140 return *this;
141 }
142
143 //! this = a - b * scalarb - c * scalarc
144 inline_ Point& Msc2(const Point& a, const Point& b, float scalarb, const Point& c, float scalarc)
145 {
146 x = a.x - b.x * scalarb - c.x * scalarc;
147 y = a.y - b.y * scalarb - c.y * scalarc;
148 z = a.z - b.z * scalarb - c.z * scalarc;
149 return *this;
150 }
151
152 //! this = mat * a
153 inline_ Point& Mult(const Matrix3x3& mat, const Point& a);
154
155 //! this = mat1 * a1 + mat2 * a2
156 inline_ Point& Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2);
157
158 //! this = this + mat * a
159 inline_ Point& Mac(const Matrix3x3& mat, const Point& a);
160
161 //! this = transpose(mat) * a
162 inline_ Point& TransMult(const Matrix3x3& mat, const Point& a);
163
164 //! Linear interpolate between two vectors: this = a + t * (b - a)
165 inline_ Point& Lerp(const Point& a, const Point& b, float t)
166 {
167 x = a.x + t * (b.x - a.x);
168 y = a.y + t * (b.y - a.y);
169 z = a.z + t * (b.z - a.z);
170 return *this;
171 }
172
173 //! Hermite interpolate between p1 and p2. p0 and p3 are used for finding gradient at p1 and p2.
174 //! this = p0 * (2t^2 - t^3 - t)/2
175 //! + p1 * (3t^3 - 5t^2 + 2)/2
176 //! + p2 * (4t^2 - 3t^3 + t)/2
177 //! + p3 * (t^3 - t^2)/2
178 inline_ Point& Herp(const Point& p0, const Point& p1, const Point& p2, const Point& p3, float t)
179 {
180 float t2 = t * t;
181 float t3 = t2 * t;
182 float kp0 = (2.0f * t2 - t3 - t) * 0.5f;
183 float kp1 = (3.0f * t3 - 5.0f * t2 + 2.0f) * 0.5f;
184 float kp2 = (4.0f * t2 - 3.0f * t3 + t) * 0.5f;
185 float kp3 = (t3 - t2) * 0.5f;
186 x = p0.x * kp0 + p1.x * kp1 + p2.x * kp2 + p3.x * kp3;
187 y = p0.y * kp0 + p1.y * kp1 + p2.y * kp2 + p3.y * kp3;
188 z = p0.z * kp0 + p1.z * kp1 + p2.z * kp2 + p3.z * kp3;
189 return *this;
190 }
191
192 //! this = rotpos * r + linpos
193 inline_ Point& Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos);
194
195 //! this = trans(rotpos) * (r - linpos)
196 inline_ Point& InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos);
197
198 //! Returns MIN(x, y, z);
199 inline_ float Min() const { return MIN(x, MIN(y, z)); }
200 //! Returns MAX(x, y, z);
201 inline_ float Max() const { return MAX(x, MAX(y, z)); }
202 //! Sets each element to be componentwise minimum
203 inline_ Point& Min(const Point& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); return *this; }
204 //! Sets each element to be componentwise maximum
205 inline_ Point& Max(const Point& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); return *this; }
206
207 //! Clamps each element
208 inline_ Point& Clamp(float min, float max)
209 {
210 if(x<min) x=min; if(x>max) x=max;
211 if(y<min) y=min; if(y>max) y=max;
212 if(z<min) z=min; if(z>max) z=max;
213 return *this;
214 }
215
216 //! Computes square magnitude
217 inline_ float SquareMagnitude() const { return x*x + y*y + z*z; }
218 //! Computes magnitude
219 inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z); }
220 //! Computes volume
221 inline_ float Volume() const { return x * y * z; }
222
223 //! Checks the point is near zero
224 inline_ bool ApproxZero() const { return SquareMagnitude() < EPSILON2; }
225
226 //! Tests for exact zero vector
227 inline_ BOOL IsZero() const
228 {
229 if(IR(x) || IR(y) || IR(z)) return FALSE;
230 return TRUE;
231 }
232
233 //! Checks point validity
234 inline_ BOOL IsValid() const
235 {
236 if(!IsValidFloat(x)) return FALSE;
237 if(!IsValidFloat(y)) return FALSE;
238 if(!IsValidFloat(z)) return FALSE;
239 return TRUE;
240 }
241
242 //! Slighty moves the point
243 void Tweak(udword coord_mask, udword tweak_mask)
244 {
245 if(coord_mask&1) { udword Dummy = IR(x); Dummy^=tweak_mask; x = FR(Dummy); }
246 if(coord_mask&2) { udword Dummy = IR(y); Dummy^=tweak_mask; y = FR(Dummy); }
247 if(coord_mask&4) { udword Dummy = IR(z); Dummy^=tweak_mask; z = FR(Dummy); }
248 }
249
250 #define TWEAKMASK 0x3fffff
251 #define TWEAKNOTMASK ~TWEAKMASK
252 //! Slighty moves the point out
253 inline_ void TweakBigger()
254 {
255 udword Dummy = (IR(x)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(x)) Dummy+=TWEAKMASK+1; x = FR(Dummy);
256 Dummy = (IR(y)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(y)) Dummy+=TWEAKMASK+1; y = FR(Dummy);
257 Dummy = (IR(z)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(z)) Dummy+=TWEAKMASK+1; z = FR(Dummy);
258 }
259
260 //! Slighty moves the point in
261 inline_ void TweakSmaller()
262 {
263 udword Dummy = (IR(x)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(x)) Dummy+=TWEAKMASK+1; x = FR(Dummy);
264 Dummy = (IR(y)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(y)) Dummy+=TWEAKMASK+1; y = FR(Dummy);
265 Dummy = (IR(z)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(z)) Dummy+=TWEAKMASK+1; z = FR(Dummy);
266 }
267
268 //! Normalizes the vector
269 inline_ Point& Normalize()
270 {
271 float M = x*x + y*y + z*z;
272 if(M)
273 {
274 M = 1.0f / sqrtf(M);
275 x *= M;
276 y *= M;
277 z *= M;
278 }
279 return *this;
280 }
281
282 //! Sets vector length
283 inline_ Point& SetLength(float length)
284 {
285 float NewLength = length / Magnitude();
286 x *= NewLength;
287 y *= NewLength;
288 z *= NewLength;
289 return *this;
290 }
291
292 //! Clamps vector length
293 inline_ Point& ClampLength(float limit_length)
294 {
295 if(limit_length>=0.0f) // Magnitude must be positive
296 {
297 float CurrentSquareLength = SquareMagnitude();
298
299 if(CurrentSquareLength > limit_length * limit_length)
300 {
301 float Coeff = limit_length / sqrtf(CurrentSquareLength);
302 x *= Coeff;
303 y *= Coeff;
304 z *= Coeff;
305 }
306 }
307 return *this;
308 }
309
310 //! Computes distance to another point
311 inline_ float Distance(const Point& b) const
312 {
313 return sqrtf((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z));
314 }
315
316 //! Computes square distance to another point
317 inline_ float SquareDistance(const Point& b) const
318 {
319 return ((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z));
320 }
321
322 //! Dot product dp = this|a
323 inline_ float Dot(const Point& p) const { return p.x * x + p.y * y + p.z * z; }
324
325 //! Cross product this = a x b
326 inline_ Point& Cross(const Point& a, const Point& b)
327 {
328 x = a.y * b.z - a.z * b.y;
329 y = a.z * b.x - a.x * b.z;
330 z = a.x * b.y - a.y * b.x;
331 return *this;
332 }
333
334 //! Vector code ( bitmask = sign(z) | sign(y) | sign(x) )
335 inline_ udword VectorCode() const
336 {
337 return (IR(x)>>31) | ((IR(y)&SIGN_BITMASK)>>30) | ((IR(z)&SIGN_BITMASK)>>29);
338 }
339
340 //! Returns largest axis
341 inline_ PointComponent LargestAxis() const
342 {
343 const float* Vals = &x;
344 PointComponent m = X;
345 if(Vals[Y] > Vals[m]) m = Y;
346 if(Vals[Z] > Vals[m]) m = Z;
347 return m;
348 }
349
350 //! Returns closest axis
351 inline_ PointComponent ClosestAxis() const
352 {
353 const float* Vals = &x;
354 PointComponent m = X;
355 if(AIR(Vals[Y]) > AIR(Vals[m])) m = Y;
356 if(AIR(Vals[Z]) > AIR(Vals[m])) m = Z;
357 return m;
358 }
359
360 //! Returns smallest axis
361 inline_ PointComponent SmallestAxis() const
362 {
363 const float* Vals = &x;
364 PointComponent m = X;
365 if(Vals[Y] < Vals[m]) m = Y;
366 if(Vals[Z] < Vals[m]) m = Z;
367 return m;
368 }
369
370 //! Refracts the point
371 Point& Refract(const Point& eye, const Point& n, float refractindex, Point& refracted);
372
373 //! Projects the point onto a plane
374 Point& ProjectToPlane(const Plane& p);
375
376 //! Projects the point onto the screen
377 void ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const;
378
379 //! Unfolds the point onto a plane according to edge(a,b)
380 Point& Unfold(Plane& p, Point& a, Point& b);
381
382 //! Hash function from Ville Miettinen
383 inline_ udword GetHashValue() const
384 {
385 const udword* h = (const udword*)(this);
386 udword f = (h[0]+h[1]*11-(h[2]*17)) & 0x7fffffff; // avoid problems with +-0
387 return (f>>22)^(f>>12)^(f);
388 }
389
390 //! Stuff magic values in the point, marking it as explicitely not used.
391 void SetNotUsed();
392 //! Checks the point is marked as not used
393 BOOL IsNotUsed() const;
394
395 // Arithmetic operators
396
397 //! Unary operator for Point Negate = - Point
398 inline_ Point operator-() const { return Point(-x, -y, -z); }
399
400 //! Operator for Point Plus = Point + Point.
401 inline_ Point operator+(const Point& p) const { return Point(x + p.x, y + p.y, z + p.z); }
402 //! Operator for Point Minus = Point - Point.
403 inline_ Point operator-(const Point& p) const { return Point(x - p.x, y - p.y, z - p.z); }
404
405 //! Operator for Point Mul = Point * Point.
406 inline_ Point operator*(const Point& p) const { return Point(x * p.x, y * p.y, z * p.z); }
407 //! Operator for Point Scale = Point * float.
408 inline_ Point operator*(float s) const { return Point(x * s, y * s, z * s ); }
409 //! Operator for Point Scale = float * Point.
410 inline_ friend Point operator*(float s, const Point& p) { return Point(s * p.x, s * p.y, s * p.z); }
411
412 //! Operator for Point Div = Point / Point.
413 inline_ Point operator/(const Point& p) const { return Point(x / p.x, y / p.y, z / p.z); }
414 //! Operator for Point Scale = Point / float.
415 inline_ Point operator/(float s) const { s = 1.0f / s; return Point(x * s, y * s, z * s); }
416 //! Operator for Point Scale = float / Point.
417 inline_ friend Point operator/(float s, const Point& p) { return Point(s / p.x, s / p.y, s / p.z); }
418
419 //! Operator for float DotProd = Point | Point.
420 inline_ float operator|(const Point& p) const { return x*p.x + y*p.y + z*p.z; }
421 //! Operator for Point VecProd = Point ^ Point.
422 inline_ Point operator^(const Point& p) const
423 {
424 return Point(
425 y * p.z - z * p.y,
426 z * p.x - x * p.z,
427 x * p.y - y * p.x );
428 }
429
430 //! Operator for Point += Point.
431 inline_ Point& operator+=(const Point& p) { x += p.x; y += p.y; z += p.z; return *this; }
432 //! Operator for Point += float.
433 inline_ Point& operator+=(float s) { x += s; y += s; z += s; return *this; }
434
435 //! Operator for Point -= Point.
436 inline_ Point& operator-=(const Point& p) { x -= p.x; y -= p.y; z -= p.z; return *this; }
437 //! Operator for Point -= float.
438 inline_ Point& operator-=(float s) { x -= s; y -= s; z -= s; return *this; }
439
440 //! Operator for Point *= Point.
441 inline_ Point& operator*=(const Point& p) { x *= p.x; y *= p.y; z *= p.z; return *this; }
442 //! Operator for Point *= float.
443 inline_ Point& operator*=(float s) { x *= s; y *= s; z *= s; return *this; }
444
445 //! Operator for Point /= Point.
446 inline_ Point& operator/=(const Point& p) { x /= p.x; y /= p.y; z /= p.z; return *this; }
447 //! Operator for Point /= float.
448 inline_ Point& operator/=(float s) { s = 1.0f/s; x *= s; y *= s; z *= s; return *this; }
449
450 // Logical operators
451
452 //! Operator for "if(Point==Point)"
453 inline_ bool operator==(const Point& p) const { return ( (IR(x)==IR(p.x))&&(IR(y)==IR(p.y))&&(IR(z)==IR(p.z))); }
454 //! Operator for "if(Point!=Point)"
455 inline_ bool operator!=(const Point& p) const { return ( (IR(x)!=IR(p.x))||(IR(y)!=IR(p.y))||(IR(z)!=IR(p.z))); }
456
457 // Arithmetic operators
458
459 //! Operator for Point Mul = Point * Matrix3x3.
460 inline_ Point operator*(const Matrix3x3& mat) const
461 {
462 class ShadowMatrix3x3{ public: float m[3][3]; }; // To allow inlining
463 const ShadowMatrix3x3* Mat = (const ShadowMatrix3x3*)&mat;
464
465 return Point(
466 x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0],
467 x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1],
468 x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] );
469 }
470
471 //! Operator for Point Mul = Point * Matrix4x4.
472 inline_ Point operator*(const Matrix4x4& mat) const
473 {
474 class ShadowMatrix4x4{ public: float m[4][4]; }; // To allow inlining
475 const ShadowMatrix4x4* Mat = (const ShadowMatrix4x4*)&mat;
476
477 return Point(
478 x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0] + Mat->m[3][0],
479 x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1] + Mat->m[3][1],
480 x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] + Mat->m[3][2]);
481 }
482
483 //! Operator for Point *= Matrix3x3.
484 inline_ Point& operator*=(const Matrix3x3& mat)
485 {
486 class ShadowMatrix3x3{ public: float m[3][3]; }; // To allow inlining
487 const ShadowMatrix3x3* Mat = (const ShadowMatrix3x3*)&mat;
488
489 float xp = x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0];
490 float yp = x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1];
491 float zp = x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2];
492
493 x = xp; y = yp; z = zp;
494
495 return *this;
496 }
497
498 //! Operator for Point *= Matrix4x4.
499 inline_ Point& operator*=(const Matrix4x4& mat)
500 {
501 class ShadowMatrix4x4{ public: float m[4][4]; }; // To allow inlining
502 const ShadowMatrix4x4* Mat = (const ShadowMatrix4x4*)&mat;
503
504 float xp = x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0] + Mat->m[3][0];
505 float yp = x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1] + Mat->m[3][1];
506 float zp = x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] + Mat->m[3][2];
507
508 x = xp; y = yp; z = zp;
509
510 return *this;
511 }
512
513 // Cast operators
514
515 //! Cast a Point to a HPoint. w is set to zero.
516 operator HPoint() const;
517
518 inline_ operator const float*() const { return &x; }
519 inline_ operator float*() { return &x; }
520
521 public:
522 float x, y, z;
523 };
524
525 FUNCTION ICEMATHS_API void Normalize1(Point& a);
526 FUNCTION ICEMATHS_API void Normalize2(Point& a);
527
528#endif //__ICEPOINT_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePreprocessor.h b/libraries/ode-0.9/OPCODE/Ice/IcePreprocessor.h
new file mode 100644
index 0000000..dbeca38
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IcePreprocessor.h
@@ -0,0 +1,132 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains preprocessor stuff. This should be the first included header.
4 * \file IcePreprocessor.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEPREPROCESSOR_H__
13#define __ICEPREPROCESSOR_H__
14
15 // Check platform
16 #if defined( _WIN32 ) || defined( WIN32 )
17 // #pragma message("Compiling on Windows...")
18 #define PLATFORM_WINDOWS
19 #else
20 // don't issue pragmas on unknown platforms
21 // #pragma message("Compiling on unknown platform...")
22 #endif
23
24 // Check compiler
25 #if defined(_MSC_VER)
26 // #pragma message("Compiling with VC++...")
27 #define COMPILER_VISUAL_CPP
28 #else
29 // don't issue pragmas on unknown platforms
30 // #pragma message("Compiling with unknown compiler...")
31 #endif
32
33 // Check compiler options. If this file is included in user-apps, this
34 // shouldn't be needed, so that they can use what they like best.
35 #ifndef ICE_DONT_CHECK_COMPILER_OPTIONS
36 #ifdef COMPILER_VISUAL_CPP
37 #if defined(_CHAR_UNSIGNED)
38 #endif
39
40 #if defined(_CPPRTTI)
41 #error Please disable RTTI...
42 #endif
43
44 #if defined(_CPPUNWIND)
45 #error Please disable exceptions...
46 #endif
47
48 #if defined(_MT)
49 // Multithreading
50 #endif
51 #endif
52 #endif
53
54 // Check debug mode
55 #ifdef DEBUG // May be defined instead of _DEBUG. Let's fix it.
56 #ifndef _DEBUG
57 #define _DEBUG
58 #endif
59 #endif
60
61 #ifdef _DEBUG
62 // Here you may define items for debug builds
63 #endif
64
65 #ifndef THIS_FILE
66 #define THIS_FILE __FILE__
67 #endif
68
69 #ifndef ICE_NO_DLL
70 #ifdef ICECORE_EXPORTS
71 #define ICECORE_API __declspec(dllexport)
72 #else
73 #define ICECORE_API __declspec(dllimport)
74 #endif
75 #else
76 #define ICECORE_API
77 #endif
78
79 // Don't override new/delete
80// #define DEFAULT_NEWDELETE
81 #define DONT_TRACK_MEMORY_LEAKS
82
83 #define FUNCTION extern "C"
84
85 // Cosmetic stuff [mainly useful with multiple inheritance]
86 #define override(base_class) virtual
87
88 // Our own inline keyword, so that:
89 // - we can switch to __forceinline to check it's really better or not
90 // - we can remove __forceinline if the compiler doesn't support it
91// #define inline_ __forceinline
92// #define inline_ inline
93
94 // Contributed by Bruce Mitchener
95 #if defined(COMPILER_VISUAL_CPP)
96 #define inline_ __forceinline
97// #define inline_ inline
98 #elif defined(__GNUC__) && __GNUC__ < 3
99 #define inline_ inline
100 #elif defined(__GNUC__)
101 #define inline_ inline __attribute__ ((always_inline))
102 #else
103 #define inline_ inline
104 #endif
105
106 // Down the hatch
107#ifdef _MSC_VER
108 #pragma inline_depth( 255 )
109#endif
110
111 #ifdef COMPILER_VISUAL_CPP
112 #pragma intrinsic(memcmp)
113 #pragma intrinsic(memcpy)
114 #pragma intrinsic(memset)
115 #pragma intrinsic(strcat)
116 #pragma intrinsic(strcmp)
117 #pragma intrinsic(strcpy)
118 #pragma intrinsic(strlen)
119 #pragma intrinsic(abs)
120 #pragma intrinsic(labs)
121 #endif
122
123 // ANSI compliance
124 #ifdef _DEBUG
125 // Remove painful warning in debug
126 inline_ bool __False__(){ return false; }
127 #define for if(__False__()){} else for
128 #else
129 #define for if(0){} else for
130 #endif
131
132#endif // __ICEPREPROCESSOR_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRandom.cpp b/libraries/ode-0.9/OPCODE/Ice/IceRandom.cpp
new file mode 100644
index 0000000..cc63a04
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceRandom.cpp
@@ -0,0 +1,35 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for random generators.
4 * \file IceRandom.cpp
5 * \author Pierre Terdiman
6 * \date August, 9, 2001
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Precompiled Header
12#include "Stdafx.h"
13
14using namespace IceCore;
15
16void IceCore:: SRand(udword seed)
17{
18 srand(seed);
19}
20
21udword IceCore::Rand()
22{
23 return rand();
24}
25
26
27static BasicRandom gRandomGenerator(42);
28
29udword IceCore::GetRandomIndex(udword max_index)
30{
31 // We don't use rand() since it's limited to RAND_MAX
32 udword Index = gRandomGenerator.Randomize();
33 return Index % max_index;
34}
35
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRandom.h b/libraries/ode-0.9/OPCODE/Ice/IceRandom.h
new file mode 100644
index 0000000..3170b33
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceRandom.h
@@ -0,0 +1,42 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for random generators.
4 * \file IceRandom.h
5 * \author Pierre Terdiman
6 * \date August, 9, 2001
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICERANDOM_H__
13#define __ICERANDOM_H__
14
15 FUNCTION ICECORE_API void SRand(udword seed);
16 FUNCTION ICECORE_API udword Rand();
17
18 //! Returns a unit random floating-point value
19 inline_ float UnitRandomFloat() { return float(Rand()) * ONE_OVER_RAND_MAX; }
20
21 //! Returns a random index so that 0<= index < max_index
22 ICECORE_API udword GetRandomIndex(udword max_index);
23
24 class ICECORE_API BasicRandom
25 {
26 public:
27
28 //! Constructor
29 inline_ BasicRandom(udword seed=0) : mRnd(seed) {}
30 //! Destructor
31 inline_ ~BasicRandom() {}
32
33 inline_ void SetSeed(udword seed) { mRnd = seed; }
34 inline_ udword GetCurrentValue() const { return mRnd; }
35 inline_ udword Randomize() { mRnd = mRnd * 2147001325 + 715136305; return mRnd; }
36
37 private:
38 udword mRnd;
39 };
40
41#endif // __ICERANDOM_H__
42
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRay.cpp b/libraries/ode-0.9/OPCODE/Ice/IceRay.cpp
new file mode 100644
index 0000000..6cf0330
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceRay.cpp
@@ -0,0 +1,84 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for rays.
4 * \file IceRay.cpp
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * Ray class.
13 * A ray is a half-line P(t) = mOrig + mDir * t, with 0 <= t <= +infinity
14 * \class Ray
15 * \author Pierre Terdiman
16 * \version 1.0
17 */
18///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19
20/*
21 O = Origin = impact point
22 i = normalized vector along the x axis
23 j = normalized vector along the y axis = actually the normal vector in O
24 D = Direction vector, norm |D| = 1
25 N = Projection of D on y axis, norm |N| = normal reaction
26 T = Projection of D on x axis, norm |T| = tangential reaction
27 R = Reflexion vector
28
29 ^y
30 |
31 |
32 |
33 _ _ _| _ _ _
34 * * *|
35 \ | /
36 \ |N / |
37 R\ | /D
38 \ | / |
39 \ | /
40 _________\|/______*_______>x
41 O T
42
43 Let define theta = angle between D and N. Then cos(theta) = |N| / |D| = |N| since D is normalized.
44
45 j|D = |j|*|D|*cos(theta) => |N| = j|D
46
47 Then we simply have:
48
49 D = N + T
50
51 To compute tangential reaction :
52
53 T = D - N
54
55 To compute reflexion vector :
56
57 R = N - T = N - (D-N) = 2*N - D
58*/
59
60///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
61// Precompiled Header
62#include "Stdafx.h"
63
64using namespace IceMaths;
65
66float Ray::SquareDistance(const Point& point, float* t) const
67{
68 Point Diff = point - mOrig;
69 float fT = Diff | mDir;
70
71 if(fT<=0.0f)
72 {
73 fT = 0.0f;
74 }
75 else
76 {
77 fT /= mDir.SquareMagnitude();
78 Diff -= fT*mDir;
79 }
80
81 if(t) *t = fT;
82
83 return Diff.SquareMagnitude();
84}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRay.h b/libraries/ode-0.9/OPCODE/Ice/IceRay.h
new file mode 100644
index 0000000..0268287
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceRay.h
@@ -0,0 +1,98 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for rays.
4 * \file IceRay.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICERAY_H__
13#define __ICERAY_H__
14
15 class ICEMATHS_API Ray
16 {
17 public:
18 //! Constructor
19 inline_ Ray() {}
20 //! Constructor
21 inline_ Ray(const Point& orig, const Point& dir) : mOrig(orig), mDir(dir) {}
22 //! Copy constructor
23 inline_ Ray(const Ray& ray) : mOrig(ray.mOrig), mDir(ray.mDir) {}
24 //! Destructor
25 inline_ ~Ray() {}
26
27 float SquareDistance(const Point& point, float* t=null) const;
28 inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); }
29
30 Point mOrig; //!< Ray origin
31 Point mDir; //!< Normalized direction
32 };
33
34 inline_ void ComputeReflexionVector(Point& reflected, const Point& incoming_dir, const Point& outward_normal)
35 {
36 reflected = incoming_dir - outward_normal * 2.0f * (incoming_dir|outward_normal);
37 }
38
39 inline_ void ComputeReflexionVector(Point& reflected, const Point& source, const Point& impact, const Point& normal)
40 {
41 Point V = impact - source;
42 reflected = V - normal * 2.0f * (V|normal);
43 }
44
45 inline_ void DecomposeVector(Point& normal_compo, Point& tangent_compo, const Point& outward_dir, const Point& outward_normal)
46 {
47 normal_compo = outward_normal * (outward_dir|outward_normal);
48 tangent_compo = outward_dir - normal_compo;
49 }
50
51 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
52 /**
53 * Transforms a direction vector from world space to local space
54 * \param local_dir [out] direction vector in local space
55 * \param world_dir [in] direction vector in world space
56 * \param world [in] world transform
57 */
58 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
59 inline_ void ComputeLocalDirection(Point& local_dir, const Point& world_dir, const Matrix4x4& world)
60 {
61 // Get world direction back in local space
62// Matrix3x3 InvWorld = world;
63// local_dir = InvWorld * world_dir;
64 local_dir = Matrix3x3(world) * world_dir;
65 }
66
67 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
68 /**
69 * Transforms a position vector from world space to local space
70 * \param local_pt [out] position vector in local space
71 * \param world_pt [in] position vector in world space
72 * \param world [in] world transform
73 */
74 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
75 inline_ void ComputeLocalPoint(Point& local_pt, const Point& world_pt, const Matrix4x4& world)
76 {
77 // Get world vertex back in local space
78 Matrix4x4 InvWorld = world;
79 InvWorld.Invert();
80 local_pt = world_pt * InvWorld;
81 }
82
83 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
84 /**
85 * Transforms a ray from world space to local space
86 * \param local_ray [out] ray in local space
87 * \param world_ray [in] ray in world space
88 * \param world [in] world transform
89 */
90 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91 inline_ void ComputeLocalRay(Ray& local_ray, const Ray& world_ray, const Matrix4x4& world)
92 {
93 // Get world ray back in local space
94 ComputeLocalDirection(local_ray.mDir, world_ray.mDir, world);
95 ComputeLocalPoint(local_ray.mOrig, world_ray.mOrig, world);
96 }
97
98#endif // __ICERAY_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.cpp b/libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.cpp
new file mode 100644
index 0000000..3e351da
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.cpp
@@ -0,0 +1,520 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains source code from the article "Radix Sort Revisited".
4 * \file IceRevisitedRadix.cpp
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * Revisited Radix Sort.
13 * This is my new radix routine:
14 * - it uses indices and doesn't recopy the values anymore, hence wasting less ram
15 * - it creates all the histograms in one run instead of four
16 * - it sorts words faster than dwords and bytes faster than words
17 * - it correctly sorts negative floating-point values by patching the offsets
18 * - it automatically takes advantage of temporal coherence
19 * - multiple keys support is a side effect of temporal coherence
20 * - it may be worth recoding in asm... (mainly to use FCOMI, FCMOV, etc) [it's probably memory-bound anyway]
21 *
22 * History:
23 * - 08.15.98: very first version
24 * - 04.04.00: recoded for the radix article
25 * - 12.xx.00: code lifting
26 * - 09.18.01: faster CHECK_PASS_VALIDITY thanks to Mark D. Shattuck (who provided other tips, not included here)
27 * - 10.11.01: added local ram support
28 * - 01.20.02: bugfix! In very particular cases the last pass was skipped in the float code-path, leading to incorrect sorting......
29 * - 01.02.02: - "mIndices" renamed => "mRanks". That's a rank sorter after all.
30 * - ranks are not "reset" anymore, but implicit on first calls
31 * - 07.05.02: - offsets rewritten with one less indirection.
32 * - 11.03.02: - "bool" replaced with RadixHint enum
33 *
34 * \class RadixSort
35 * \author Pierre Terdiman
36 * \version 1.4
37 * \date August, 15, 1998
38 */
39///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
40
41/*
42To do:
43 - add an offset parameter between two input values (avoid some data recopy sometimes)
44 - unroll ? asm ?
45 - 11 bits trick & 3 passes as Michael did
46 - prefetch stuff the day I have a P3
47 - make a version with 16-bits indices ?
48*/
49
50///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
51// Precompiled Header
52#include "Stdafx.h"
53
54using namespace IceCore;
55
56#define INVALIDATE_RANKS mCurrentSize|=0x80000000
57#define VALIDATE_RANKS mCurrentSize&=0x7fffffff
58#define CURRENT_SIZE (mCurrentSize&0x7fffffff)
59#define INVALID_RANKS (mCurrentSize&0x80000000)
60
61#define CHECK_RESIZE(n) \
62 if(n!=mPreviousSize) \
63 { \
64 if(n>mCurrentSize) Resize(n); \
65 else ResetRanks(); \
66 mPreviousSize = n; \
67 }
68
69#define CREATE_HISTOGRAMS(type, buffer) \
70 /* Clear counters/histograms */ \
71 ZeroMemory(mHistogram, 256*4*sizeof(udword)); \
72 \
73 /* Prepare to count */ \
74 ubyte* p = (ubyte*)input; \
75 ubyte* pe = &p[nb*4]; \
76 udword* h0= &mHistogram[0]; /* Histogram for first pass (LSB) */ \
77 udword* h1= &mHistogram[256]; /* Histogram for second pass */ \
78 udword* h2= &mHistogram[512]; /* Histogram for third pass */ \
79 udword* h3= &mHistogram[768]; /* Histogram for last pass (MSB) */ \
80 \
81 bool AlreadySorted = true; /* Optimism... */ \
82 \
83 if(INVALID_RANKS) \
84 { \
85 /* Prepare for temporal coherence */ \
86 type* Running = (type*)buffer; \
87 type PrevVal = *Running; \
88 \
89 while(p!=pe) \
90 { \
91 /* Read input buffer in previous sorted order */ \
92 type Val = *Running++; \
93 /* Check whether already sorted or not */ \
94 if(Val<PrevVal) { AlreadySorted = false; break; } /* Early out */ \
95 /* Update for next iteration */ \
96 PrevVal = Val; \
97 \
98 /* Create histograms */ \
99 h0[*p++]++; h1[*p++]++; h2[*p++]++; h3[*p++]++; \
100 } \
101 \
102 /* If all input values are already sorted, we just have to return and leave the */ \
103 /* previous list unchanged. That way the routine may take advantage of temporal */ \
104 /* coherence, for example when used to sort transparent faces. */ \
105 if(AlreadySorted) \
106 { \
107 mNbHits++; \
108 for(udword i=0;i<nb;i++) mRanks[i] = i; \
109 return *this; \
110 } \
111 } \
112 else \
113 { \
114 /* Prepare for temporal coherence */ \
115 udword* Indices = mRanks; \
116 type PrevVal = (type)buffer[*Indices]; \
117 \
118 while(p!=pe) \
119 { \
120 /* Read input buffer in previous sorted order */ \
121 type Val = (type)buffer[*Indices++]; \
122 /* Check whether already sorted or not */ \
123 if(Val<PrevVal) { AlreadySorted = false; break; } /* Early out */ \
124 /* Update for next iteration */ \
125 PrevVal = Val; \
126 \
127 /* Create histograms */ \
128 h0[*p++]++; h1[*p++]++; h2[*p++]++; h3[*p++]++; \
129 } \
130 \
131 /* If all input values are already sorted, we just have to return and leave the */ \
132 /* previous list unchanged. That way the routine may take advantage of temporal */ \
133 /* coherence, for example when used to sort transparent faces. */ \
134 if(AlreadySorted) { mNbHits++; return *this; } \
135 } \
136 \
137 /* Else there has been an early out and we must finish computing the histograms */ \
138 while(p!=pe) \
139 { \
140 /* Create histograms without the previous overhead */ \
141 h0[*p++]++; h1[*p++]++; h2[*p++]++; h3[*p++]++; \
142 }
143
144#define CHECK_PASS_VALIDITY(pass) \
145 /* Shortcut to current counters */ \
146 udword* CurCount = &mHistogram[pass<<8]; \
147 \
148 /* Reset flag. The sorting pass is supposed to be performed. (default) */ \
149 bool PerformPass = true; \
150 \
151 /* Check pass validity */ \
152 \
153 /* If all values have the same byte, sorting is useless. */ \
154 /* It may happen when sorting bytes or words instead of dwords. */ \
155 /* This routine actually sorts words faster than dwords, and bytes */ \
156 /* faster than words. Standard running time (O(4*n))is reduced to O(2*n) */ \
157 /* for words and O(n) for bytes. Running time for floats depends on actual values... */ \
158 \
159 /* Get first byte */ \
160 ubyte UniqueVal = *(((ubyte*)input)+pass); \
161 \
162 /* Check that byte's counter */ \
163 if(CurCount[UniqueVal]==nb) PerformPass=false;
164
165///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
166/**
167 * Constructor.
168 */
169///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
170RadixSort::RadixSort() : mRanks(null), mRanks2(null), mCurrentSize(0), mTotalCalls(0), mNbHits(0)
171{
172#ifndef RADIX_LOCAL_RAM
173 // Allocate input-independent ram
174 mHistogram = new udword[256*4];
175 mOffset = new udword[256];
176#endif
177 // Initialize indices
178 INVALIDATE_RANKS;
179}
180
181///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
182/**
183 * Destructor.
184 */
185///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
186RadixSort::~RadixSort()
187{
188 // Release everything
189#ifndef RADIX_LOCAL_RAM
190 DELETEARRAY(mOffset);
191 DELETEARRAY(mHistogram);
192#endif
193 DELETEARRAY(mRanks2);
194 DELETEARRAY(mRanks);
195}
196
197///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
198/**
199 * Resizes the inner lists.
200 * \param nb [in] new size (number of dwords)
201 * \return true if success
202 */
203///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
204bool RadixSort::Resize(udword nb)
205{
206 // Free previously used ram
207 DELETEARRAY(mRanks2);
208 DELETEARRAY(mRanks);
209
210 // Get some fresh one
211 mRanks = new udword[nb]; CHECKALLOC(mRanks);
212 mRanks2 = new udword[nb]; CHECKALLOC(mRanks2);
213
214 return true;
215}
216
217inline_ void RadixSort::CheckResize(udword nb)
218{
219 udword CurSize = CURRENT_SIZE;
220 if(nb!=CurSize)
221 {
222 if(nb>CurSize) Resize(nb);
223 mCurrentSize = nb;
224 INVALIDATE_RANKS;
225 }
226}
227
228///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
229/**
230 * Main sort routine.
231 * This one is for integer values. After the call, mRanks contains a list of indices in sorted order, i.e. in the order you may process your data.
232 * \param input [in] a list of integer values to sort
233 * \param nb [in] number of values to sort, must be < 2^31
234 * \param hint [in] RADIX_SIGNED to handle negative values, RADIX_UNSIGNED if you know your input buffer only contains positive values
235 * \return Self-Reference
236 */
237///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
238RadixSort& RadixSort::Sort(const udword* input, udword nb, RadixHint hint)
239{
240 // Checkings
241 if(!input || !nb || nb&0x80000000) return *this;
242
243 // Stats
244 mTotalCalls++;
245
246 // Resize lists if needed
247 CheckResize(nb);
248
249#ifdef RADIX_LOCAL_RAM
250 // Allocate histograms & offsets on the stack
251 udword mHistogram[256*4];
252// udword mOffset[256];
253 udword* mLink[256];
254#endif
255
256 // Create histograms (counters). Counters for all passes are created in one run.
257 // Pros: read input buffer once instead of four times
258 // Cons: mHistogram is 4Kb instead of 1Kb
259 // We must take care of signed/unsigned values for temporal coherence.... I just
260 // have 2 code paths even if just a single opcode changes. Self-modifying code, someone?
261 if(hint==RADIX_UNSIGNED) { CREATE_HISTOGRAMS(udword, input); }
262 else { CREATE_HISTOGRAMS(sdword, input); }
263
264 // Compute #negative values involved if needed
265 udword NbNegativeValues = 0;
266 if(hint==RADIX_SIGNED)
267 {
268 // An efficient way to compute the number of negatives values we'll have to deal with is simply to sum the 128
269 // last values of the last histogram. Last histogram because that's the one for the Most Significant Byte,
270 // responsible for the sign. 128 last values because the 128 first ones are related to positive numbers.
271 udword* h3= &mHistogram[768];
272 for(udword i=128;i<256;i++) NbNegativeValues += h3[i]; // 768 for last histogram, 128 for negative part
273 }
274
275 // Radix sort, j is the pass number (0=LSB, 3=MSB)
276 for(udword j=0;j<4;j++)
277 {
278 CHECK_PASS_VALIDITY(j);
279
280 // Sometimes the fourth (negative) pass is skipped because all numbers are negative and the MSB is 0xFF (for example). This is
281 // not a problem, numbers are correctly sorted anyway.
282 if(PerformPass)
283 {
284 // Should we care about negative values?
285 if(j!=3 || hint==RADIX_UNSIGNED)
286 {
287 // Here we deal with positive values only
288
289 // Create offsets
290// mOffset[0] = 0;
291// for(udword i=1;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1];
292 mLink[0] = mRanks2;
293 for(udword i=1;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1];
294 }
295 else
296 {
297 // This is a special case to correctly handle negative integers. They're sorted in the right order but at the wrong place.
298
299 // Create biased offsets, in order for negative numbers to be sorted as well
300// mOffset[0] = NbNegativeValues; // First positive number takes place after the negative ones
301 mLink[0] = &mRanks2[NbNegativeValues]; // First positive number takes place after the negative ones
302// for(udword i=1;i<128;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers
303 for(udword i=1;i<128;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers
304
305 // Fixing the wrong place for negative values
306// mOffset[128] = 0;
307 mLink[128] = mRanks2;
308// for(i=129;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1];
309 for(udword i=129;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1];
310 }
311
312 // Perform Radix Sort
313 ubyte* InputBytes = (ubyte*)input;
314 InputBytes += j;
315 if(INVALID_RANKS)
316 {
317// for(udword i=0;i<nb;i++) mRanks2[mOffset[InputBytes[i<<2]]++] = i;
318 for(udword i=0;i<nb;i++) *mLink[InputBytes[i<<2]]++ = i;
319 VALIDATE_RANKS;
320 }
321 else
322 {
323 udword* Indices = mRanks;
324 udword* IndicesEnd = &mRanks[nb];
325 while(Indices!=IndicesEnd)
326 {
327 udword id = *Indices++;
328// mRanks2[mOffset[InputBytes[id<<2]]++] = id;
329 *mLink[InputBytes[id<<2]]++ = id;
330 }
331 }
332
333 // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap.
334 udword* Tmp = mRanks; mRanks = mRanks2; mRanks2 = Tmp;
335 }
336 }
337 return *this;
338}
339
340///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
341/**
342 * Main sort routine.
343 * This one is for floating-point values. After the call, mRanks contains a list of indices in sorted order, i.e. in the order you may process your data.
344 * \param input [in] a list of floating-point values to sort
345 * \param nb [in] number of values to sort, must be < 2^31
346 * \return Self-Reference
347 * \warning only sorts IEEE floating-point values
348 */
349///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
350RadixSort& RadixSort::Sort(const float* input2, udword nb)
351{
352 // Checkings
353 if(!input2 || !nb || nb&0x80000000) return *this;
354
355 // Stats
356 mTotalCalls++;
357
358 udword* input = (udword*)input2;
359
360 // Resize lists if needed
361 CheckResize(nb);
362
363#ifdef RADIX_LOCAL_RAM
364 // Allocate histograms & offsets on the stack
365 udword mHistogram[256*4];
366// udword mOffset[256];
367 udword* mLink[256];
368#endif
369
370 // Create histograms (counters). Counters for all passes are created in one run.
371 // Pros: read input buffer once instead of four times
372 // Cons: mHistogram is 4Kb instead of 1Kb
373 // Floating-point values are always supposed to be signed values, so there's only one code path there.
374 // Please note the floating point comparison needed for temporal coherence! Although the resulting asm code
375 // is dreadful, this is surprisingly not such a performance hit - well, I suppose that's a big one on first
376 // generation Pentiums....We can't make comparison on integer representations because, as Chris said, it just
377 // wouldn't work with mixed positive/negative values....
378 { CREATE_HISTOGRAMS(float, input2); }
379
380 // Compute #negative values involved if needed
381 udword NbNegativeValues = 0;
382 // An efficient way to compute the number of negatives values we'll have to deal with is simply to sum the 128
383 // last values of the last histogram. Last histogram because that's the one for the Most Significant Byte,
384 // responsible for the sign. 128 last values because the 128 first ones are related to positive numbers.
385 udword* h3= &mHistogram[768];
386 for(udword i=128;i<256;i++) NbNegativeValues += h3[i]; // 768 for last histogram, 128 for negative part
387
388 // Radix sort, j is the pass number (0=LSB, 3=MSB)
389 for(udword j=0;j<4;j++)
390 {
391 // Should we care about negative values?
392 if(j!=3)
393 {
394 // Here we deal with positive values only
395 CHECK_PASS_VALIDITY(j);
396
397 if(PerformPass)
398 {
399 // Create offsets
400// mOffset[0] = 0;
401 mLink[0] = mRanks2;
402// for(udword i=1;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1];
403 for(udword i=1;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1];
404
405 // Perform Radix Sort
406 ubyte* InputBytes = (ubyte*)input;
407 InputBytes += j;
408 if(INVALID_RANKS)
409 {
410// for(i=0;i<nb;i++) mRanks2[mOffset[InputBytes[i<<2]]++] = i;
411 for(udword i=0;i<nb;i++) *mLink[InputBytes[i<<2]]++ = i;
412 VALIDATE_RANKS;
413 }
414 else
415 {
416 udword* Indices = mRanks;
417 udword* IndicesEnd = &mRanks[nb];
418 while(Indices!=IndicesEnd)
419 {
420 udword id = *Indices++;
421// mRanks2[mOffset[InputBytes[id<<2]]++] = id;
422 *mLink[InputBytes[id<<2]]++ = id;
423 }
424 }
425
426 // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap.
427 udword* Tmp = mRanks; mRanks = mRanks2; mRanks2 = Tmp;
428 }
429 }
430 else
431 {
432 // This is a special case to correctly handle negative values
433 CHECK_PASS_VALIDITY(j);
434
435 if(PerformPass)
436 {
437 // Create biased offsets, in order for negative numbers to be sorted as well
438// mOffset[0] = NbNegativeValues; // First positive number takes place after the negative ones
439 mLink[0] = &mRanks2[NbNegativeValues]; // First positive number takes place after the negative ones
440// for(udword i=1;i<128;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers
441 for(udword i=1;i<128;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers
442
443 // We must reverse the sorting order for negative numbers!
444// mOffset[255] = 0;
445 mLink[255] = mRanks2;
446// for(i=0;i<127;i++) mOffset[254-i] = mOffset[255-i] + CurCount[255-i]; // Fixing the wrong order for negative values
447 for(udword i=0;i<127;i++) mLink[254-i] = mLink[255-i] + CurCount[255-i]; // Fixing the wrong order for negative values
448// for(i=128;i<256;i++) mOffset[i] += CurCount[i]; // Fixing the wrong place for negative values
449 for(udword i=128;i<256;i++) mLink[i] += CurCount[i]; // Fixing the wrong place for negative values
450
451 // Perform Radix Sort
452 if(INVALID_RANKS)
453 {
454 for(udword i=0;i<nb;i++)
455 {
456 udword Radix = input[i]>>24; // Radix byte, same as above. AND is useless here (udword).
457 // ### cmp to be killed. Not good. Later.
458// if(Radix<128) mRanks2[mOffset[Radix]++] = i; // Number is positive, same as above
459// else mRanks2[--mOffset[Radix]] = i; // Number is negative, flip the sorting order
460 if(Radix<128) *mLink[Radix]++ = i; // Number is positive, same as above
461 else *(--mLink[Radix]) = i; // Number is negative, flip the sorting order
462 }
463 VALIDATE_RANKS;
464 }
465 else
466 {
467 for(udword i=0;i<nb;i++)
468 {
469 udword Radix = input[mRanks[i]]>>24; // Radix byte, same as above. AND is useless here (udword).
470 // ### cmp to be killed. Not good. Later.
471// if(Radix<128) mRanks2[mOffset[Radix]++] = mRanks[i]; // Number is positive, same as above
472// else mRanks2[--mOffset[Radix]] = mRanks[i]; // Number is negative, flip the sorting order
473 if(Radix<128) *mLink[Radix]++ = mRanks[i]; // Number is positive, same as above
474 else *(--mLink[Radix]) = mRanks[i]; // Number is negative, flip the sorting order
475 }
476 }
477 // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap.
478 udword* Tmp = mRanks; mRanks = mRanks2; mRanks2 = Tmp;
479 }
480 else
481 {
482 // The pass is useless, yet we still have to reverse the order of current list if all values are negative.
483 if(UniqueVal>=128)
484 {
485 if(INVALID_RANKS)
486 {
487 // ###Possible?
488 for(udword i=0;i<nb;i++) mRanks2[i] = nb-i-1;
489 VALIDATE_RANKS;
490 }
491 else
492 {
493 for(udword i=0;i<nb;i++) mRanks2[i] = mRanks[nb-i-1];
494 }
495
496 // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap.
497 udword* Tmp = mRanks; mRanks = mRanks2; mRanks2 = Tmp;
498 }
499 }
500 }
501 }
502 return *this;
503}
504
505///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
506/**
507 * Gets the ram used.
508 * \return memory used in bytes
509 */
510///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
511udword RadixSort::GetUsedRam() const
512{
513 udword UsedRam = sizeof(RadixSort);
514#ifndef RADIX_LOCAL_RAM
515 UsedRam += 256*4*sizeof(udword); // Histograms
516 UsedRam += 256*sizeof(udword); // Offsets
517#endif
518 UsedRam += 2*CURRENT_SIZE*sizeof(udword); // 2 lists of indices
519 return UsedRam;
520}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.h b/libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.h
new file mode 100644
index 0000000..3bdfc22
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.h
@@ -0,0 +1,65 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains source code from the article "Radix Sort Revisited".
4 * \file IceRevisitedRadix.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICERADIXSORT_H__
13#define __ICERADIXSORT_H__
14
15 //! Allocate histograms & offsets locally
16 #define RADIX_LOCAL_RAM
17
18 enum RadixHint
19 {
20 RADIX_SIGNED, //!< Input values are signed
21 RADIX_UNSIGNED, //!< Input values are unsigned
22
23 RADIX_FORCE_DWORD = 0x7fffffff
24 };
25
26 class ICECORE_API RadixSort
27 {
28 public:
29 // Constructor/Destructor
30 RadixSort();
31 ~RadixSort();
32 // Sorting methods
33 RadixSort& Sort(const udword* input, udword nb, RadixHint hint=RADIX_SIGNED);
34 RadixSort& Sort(const float* input, udword nb);
35
36 //! Access to results. mRanks is a list of indices in sorted order, i.e. in the order you may further process your data
37 inline_ const udword* GetRanks() const { return mRanks; }
38
39 //! mIndices2 gets trashed on calling the sort routine, but otherwise you can recycle it the way you want.
40 inline_ udword* GetRecyclable() const { return mRanks2; }
41
42 // Stats
43 udword GetUsedRam() const;
44 //! Returns the total number of calls to the radix sorter.
45 inline_ udword GetNbTotalCalls() const { return mTotalCalls; }
46 //! Returns the number of eraly exits due to temporal coherence.
47 inline_ udword GetNbHits() const { return mNbHits; }
48
49 private:
50#ifndef RADIX_LOCAL_RAM
51 udword* mHistogram; //!< Counters for each byte
52 udword* mOffset; //!< Offsets (nearly a cumulative distribution function)
53#endif
54 udword mCurrentSize; //!< Current size of the indices list
55 udword* mRanks; //!< Two lists, swapped each pass
56 udword* mRanks2;
57 // Stats
58 udword mTotalCalls; //!< Total number of calls to the sort routine
59 udword mNbHits; //!< Number of early exits due to coherence
60 // Internal methods
61 void CheckResize(udword nb);
62 bool Resize(udword nb);
63 };
64
65#endif // __ICERADIXSORT_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceSegment.cpp b/libraries/ode-0.9/OPCODE/Ice/IceSegment.cpp
new file mode 100644
index 0000000..cd9ceb7
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceSegment.cpp
@@ -0,0 +1,57 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for segments.
4 * \file IceSegment.cpp
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * Segment class.
13 * A segment is defined by S(t) = mP0 * (1 - t) + mP1 * t, with 0 <= t <= 1
14 * Alternatively, a segment is S(t) = Origin + t * Direction for 0 <= t <= 1.
15 * Direction is not necessarily unit length. The end points are Origin = mP0 and Origin + Direction = mP1.
16 *
17 * \class Segment
18 * \author Pierre Terdiman
19 * \version 1.0
20 */
21///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
22
23///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24// Precompiled Header
25#include "Stdafx.h"
26
27using namespace IceMaths;
28
29float Segment::SquareDistance(const Point& point, float* t) const
30{
31 Point Diff = point - mP0;
32 Point Dir = mP1 - mP0;
33 float fT = Diff | Dir;
34
35 if(fT<=0.0f)
36 {
37 fT = 0.0f;
38 }
39 else
40 {
41 float SqrLen= Dir.SquareMagnitude();
42 if(fT>=SqrLen)
43 {
44 fT = 1.0f;
45 Diff -= Dir;
46 }
47 else
48 {
49 fT /= SqrLen;
50 Diff -= fT*Dir;
51 }
52 }
53
54 if(t) *t = fT;
55
56 return Diff.SquareMagnitude();
57}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceSegment.h b/libraries/ode-0.9/OPCODE/Ice/IceSegment.h
new file mode 100644
index 0000000..8d66322
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceSegment.h
@@ -0,0 +1,55 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for segments.
4 * \file IceSegment.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICESEGMENT_H__
13#define __ICESEGMENT_H__
14
15 class ICEMATHS_API Segment
16 {
17 public:
18 //! Constructor
19 inline_ Segment() {}
20 //! Constructor
21 inline_ Segment(const Point& p0, const Point& p1) : mP0(p0), mP1(p1) {}
22 //! Copy constructor
23 inline_ Segment(const Segment& seg) : mP0(seg.mP0), mP1(seg.mP1) {}
24 //! Destructor
25 inline_ ~Segment() {}
26
27 inline_ const Point& GetOrigin() const { return mP0; }
28 inline_ Point ComputeDirection() const { return mP1 - mP0; }
29 inline_ void ComputeDirection(Point& dir) const { dir = mP1 - mP0; }
30 inline_ float ComputeLength() const { return mP1.Distance(mP0); }
31 inline_ float ComputeSquareLength() const { return mP1.SquareDistance(mP0); }
32
33 inline_ void SetOriginDirection(const Point& origin, const Point& direction)
34 {
35 mP0 = mP1 = origin;
36 mP1 += direction;
37 }
38
39 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
40 /**
41 * Computes a point on the segment
42 * \param pt [out] point on segment
43 * \param t [in] point's parameter [t=0 => pt = mP0, t=1 => pt = mP1]
44 */
45 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
46 inline_ void ComputePoint(Point& pt, float t) const { pt = mP0 + t * (mP1 - mP0); }
47
48 float SquareDistance(const Point& point, float* t=null) const;
49 inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); }
50
51 Point mP0; //!< Start of segment
52 Point mP1; //!< End of segment
53 };
54
55#endif // __ICESEGMENT_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceTriList.h b/libraries/ode-0.9/OPCODE/Ice/IceTriList.h
new file mode 100644
index 0000000..b2b6ecf
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceTriList.h
@@ -0,0 +1,61 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains code for a triangle container.
4 * \file IceTrilist.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICETRILIST_H__
13#define __ICETRILIST_H__
14
15 class ICEMATHS_API TriList : public Container
16 {
17 public:
18 // Constructor / Destructor
19 TriList() {}
20 ~TriList() {}
21
22 inline_ udword GetNbTriangles() const { return GetNbEntries()/9; }
23 inline_ Triangle* GetTriangles() const { return (Triangle*)GetEntries(); }
24
25 void AddTri(const Triangle& tri)
26 {
27 Add(tri.mVerts[0].x).Add(tri.mVerts[0].y).Add(tri.mVerts[0].z);
28 Add(tri.mVerts[1].x).Add(tri.mVerts[1].y).Add(tri.mVerts[1].z);
29 Add(tri.mVerts[2].x).Add(tri.mVerts[2].y).Add(tri.mVerts[2].z);
30 }
31
32 void AddTri(const Point& p0, const Point& p1, const Point& p2)
33 {
34 Add(p0.x).Add(p0.y).Add(p0.z);
35 Add(p1.x).Add(p1.y).Add(p1.z);
36 Add(p2.x).Add(p2.y).Add(p2.z);
37 }
38 };
39
40 class ICEMATHS_API TriangleList : public Container
41 {
42 public:
43 // Constructor / Destructor
44 TriangleList() {}
45 ~TriangleList() {}
46
47 inline_ udword GetNbTriangles() const { return GetNbEntries()/3; }
48 inline_ IndexedTriangle* GetTriangles() const { return (IndexedTriangle*)GetEntries();}
49
50 void AddTriangle(const IndexedTriangle& tri)
51 {
52 Add(tri.mVRef[0]).Add(tri.mVRef[1]).Add(tri.mVRef[2]);
53 }
54
55 void AddTriangle(udword vref0, udword vref1, udword vref2)
56 {
57 Add(vref0).Add(vref1).Add(vref2);
58 }
59 };
60
61#endif //__ICETRILIST_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceTriangle.cpp b/libraries/ode-0.9/OPCODE/Ice/IceTriangle.cpp
new file mode 100644
index 0000000..4268ff4
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceTriangle.cpp
@@ -0,0 +1,286 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains a handy triangle class.
4 * \file IceTriangle.cpp
5 * \author Pierre Terdiman
6 * \date January, 17, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Precompiled Header
12#include "Stdafx.h"
13
14using namespace IceMaths;
15
16///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17/**
18 * Contains a triangle class.
19 *
20 * \class Tri
21 * \author Pierre Terdiman
22 * \version 1.0
23 * \date 08.15.98
24*/
25///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26
27static sdword VPlaneSideEps(const Point& v, const Plane& plane, float epsilon)
28{
29 // Compute distance from current vertex to the plane
30 float Dist = plane.Distance(v);
31 // Compute side:
32 // 1 = the vertex is on the positive side of the plane
33 // -1 = the vertex is on the negative side of the plane
34 // 0 = the vertex is on the plane (within epsilon)
35 return Dist > epsilon ? 1 : Dist < -epsilon ? -1 : 0;
36}
37
38///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
39/**
40 * Flips the winding order.
41 */
42///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
43void Triangle::Flip()
44{
45 Point Tmp = mVerts[1];
46 mVerts[1] = mVerts[2];
47 mVerts[2] = Tmp;
48}
49
50///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
51/**
52 * Computes the triangle area.
53 * \return the area
54 */
55///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
56float Triangle::Area() const
57{
58 const Point& p0 = mVerts[0];
59 const Point& p1 = mVerts[1];
60 const Point& p2 = mVerts[2];
61 return ((p0 - p1)^(p0 - p2)).Magnitude() * 0.5f;
62}
63
64///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
65/**
66 * Computes the triangle perimeter.
67 * \return the perimeter
68 */
69///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
70float Triangle::Perimeter() const
71{
72 const Point& p0 = mVerts[0];
73 const Point& p1 = mVerts[1];
74 const Point& p2 = mVerts[2];
75 return p0.Distance(p1)
76 + p0.Distance(p2)
77 + p1.Distance(p2);
78}
79
80///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81/**
82 * Computes the triangle compacity.
83 * \return the compacity
84 */
85///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
86float Triangle::Compacity() const
87{
88 float P = Perimeter();
89 if(P==0.0f) return 0.0f;
90 return (4.0f*PI*Area()/(P*P));
91}
92
93///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
94/**
95 * Computes the triangle normal.
96 * \param normal [out] the computed normal
97 */
98///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
99void Triangle::Normal(Point& normal) const
100{
101 const Point& p0 = mVerts[0];
102 const Point& p1 = mVerts[1];
103 const Point& p2 = mVerts[2];
104 normal = ((p0 - p1)^(p0 - p2)).Normalize();
105}
106
107///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
108/**
109 * Computes the triangle denormalized normal.
110 * \param normal [out] the computed normal
111 */
112///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
113void Triangle::DenormalizedNormal(Point& normal) const
114{
115 const Point& p0 = mVerts[0];
116 const Point& p1 = mVerts[1];
117 const Point& p2 = mVerts[2];
118 normal = ((p0 - p1)^(p0 - p2));
119}
120
121///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
122/**
123 * Computes the triangle center.
124 * \param center [out] the computed center
125 */
126///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
127void Triangle::Center(Point& center) const
128{
129 const Point& p0 = mVerts[0];
130 const Point& p1 = mVerts[1];
131 const Point& p2 = mVerts[2];
132 center = (p0 + p1 + p2)*INV3;
133}
134
135PartVal Triangle::TestAgainstPlane(const Plane& plane, float epsilon) const
136{
137 bool Pos = false, Neg = false;
138
139 // Loop through all vertices
140 for(udword i=0;i<3;i++)
141 {
142 // Compute side:
143 sdword Side = VPlaneSideEps(mVerts[i], plane, epsilon);
144
145 if (Side < 0) Neg = true;
146 else if (Side > 0) Pos = true;
147 }
148
149 if (!Pos && !Neg) return TRI_ON_PLANE;
150 else if (Pos && Neg) return TRI_INTERSECT;
151 else if (Pos && !Neg) return TRI_PLUS_SPACE;
152 else if (!Pos && Neg) return TRI_MINUS_SPACE;
153
154 // What?!
155 return TRI_FORCEDWORD;
156}
157
158///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
159/**
160 * Computes the triangle moment.
161 * \param m [out] the moment
162 */
163///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
164/*
165void Triangle::ComputeMoment(Moment& m)
166{
167 // Compute the area of the triangle
168 m.mArea = Area();
169
170 // Compute the centroid
171 Center(m.mCentroid);
172
173 // Second-order components. Handle zero-area faces.
174 Point& p = mVerts[0];
175 Point& q = mVerts[1];
176 Point& r = mVerts[2];
177 if(m.mArea==0.0f)
178 {
179 // This triangle has zero area. The second order components would be eliminated with the usual formula, so, for the
180 // sake of robustness we use an alternative form. These are the centroid and second-order components of the triangle's vertices.
181 m.mCovariance.m[0][0] = (p.x*p.x + q.x*q.x + r.x*r.x);
182 m.mCovariance.m[0][1] = (p.x*p.y + q.x*q.y + r.x*r.y);
183 m.mCovariance.m[0][2] = (p.x*p.z + q.x*q.z + r.x*r.z);
184 m.mCovariance.m[1][1] = (p.y*p.y + q.y*q.y + r.y*r.y);
185 m.mCovariance.m[1][2] = (p.y*p.z + q.y*q.z + r.y*r.z);
186 m.mCovariance.m[2][2] = (p.z*p.z + q.z*q.z + r.z*r.z);
187 m.mCovariance.m[2][1] = m.mCovariance.m[1][2];
188 m.mCovariance.m[1][0] = m.mCovariance.m[0][1];
189 m.mCovariance.m[2][0] = m.mCovariance.m[0][2];
190 }
191 else
192 {
193 const float OneOverTwelve = 1.0f / 12.0f;
194 m.mCovariance.m[0][0] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.x + p.x*p.x + q.x*q.x + r.x*r.x) * OneOverTwelve;
195 m.mCovariance.m[0][1] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.y + p.x*p.y + q.x*q.y + r.x*r.y) * OneOverTwelve;
196 m.mCovariance.m[1][1] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.y + p.y*p.y + q.y*q.y + r.y*r.y) * OneOverTwelve;
197 m.mCovariance.m[0][2] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.z + p.x*p.z + q.x*q.z + r.x*r.z) * OneOverTwelve;
198 m.mCovariance.m[1][2] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.z + p.y*p.z + q.y*q.z + r.y*r.z) * OneOverTwelve;
199 m.mCovariance.m[2][2] = m.mArea * (9.0f * m.mCentroid.z*m.mCentroid.z + p.z*p.z + q.z*q.z + r.z*r.z) * OneOverTwelve;
200 m.mCovariance.m[2][1] = m.mCovariance.m[1][2];
201 m.mCovariance.m[1][0] = m.mCovariance.m[0][1];
202 m.mCovariance.m[2][0] = m.mCovariance.m[0][2];
203 }
204}
205*/
206
207///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
208/**
209 * Computes the triangle's smallest edge length.
210 * \return the smallest edge length
211 */
212///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
213float Triangle::MinEdgeLength() const
214{
215 float Min = MAX_FLOAT;
216 float Length01 = mVerts[0].Distance(mVerts[1]);
217 float Length02 = mVerts[0].Distance(mVerts[2]);
218 float Length12 = mVerts[1].Distance(mVerts[2]);
219 if(Length01 < Min) Min = Length01;
220 if(Length02 < Min) Min = Length02;
221 if(Length12 < Min) Min = Length12;
222 return Min;
223}
224
225///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
226/**
227 * Computes the triangle's largest edge length.
228 * \return the largest edge length
229 */
230///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
231float Triangle::MaxEdgeLength() const
232{
233 float Max = MIN_FLOAT;
234 float Length01 = mVerts[0].Distance(mVerts[1]);
235 float Length02 = mVerts[0].Distance(mVerts[2]);
236 float Length12 = mVerts[1].Distance(mVerts[2]);
237 if(Length01 > Max) Max = Length01;
238 if(Length02 > Max) Max = Length02;
239 if(Length12 > Max) Max = Length12;
240 return Max;
241}
242
243///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
244/**
245 * Computes a point on the triangle according to the stabbing information.
246 * \param u,v [in] point's barycentric coordinates
247 * \param pt [out] point on triangle
248 * \param nearvtx [out] index of nearest vertex
249 */
250///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
251void Triangle::ComputePoint(float u, float v, Point& pt, udword* nearvtx) const
252{
253 // Compute point coordinates
254 pt = (1.0f - u - v)*mVerts[0] + u*mVerts[1] + v*mVerts[2];
255
256 // Compute nearest vertex if needed
257 if(nearvtx)
258 {
259 // Compute distance vector
260 Point d(mVerts[0].SquareDistance(pt), // Distance^2 from vertex 0 to point on the face
261 mVerts[1].SquareDistance(pt), // Distance^2 from vertex 1 to point on the face
262 mVerts[2].SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face
263
264 // Get smallest distance
265 *nearvtx = d.SmallestAxis();
266 }
267}
268
269void Triangle::Inflate(float fat_coeff, bool constant_border)
270{
271 // Compute triangle center
272 Point TriangleCenter;
273 Center(TriangleCenter);
274
275 // Don't normalize?
276 // Normalize => add a constant border, regardless of triangle size
277 // Don't => add more to big triangles
278 for(udword i=0;i<3;i++)
279 {
280 Point v = mVerts[i] - TriangleCenter;
281
282 if(constant_border) v.Normalize();
283
284 mVerts[i] += v * fat_coeff;
285 }
286}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceTriangle.h b/libraries/ode-0.9/OPCODE/Ice/IceTriangle.h
new file mode 100644
index 0000000..a984db8
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceTriangle.h
@@ -0,0 +1,68 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains a handy triangle class.
4 * \file IceTriangle.h
5 * \author Pierre Terdiman
6 * \date January, 17, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICETRIANGLE_H__
13#define __ICETRIANGLE_H__
14
15 // Forward declarations
16 class Moment;
17
18 // Partitioning values
19 enum PartVal
20 {
21 TRI_MINUS_SPACE = 0, //!< Triangle is in the negative space
22 TRI_PLUS_SPACE = 1, //!< Triangle is in the positive space
23 TRI_INTERSECT = 2, //!< Triangle intersects plane
24 TRI_ON_PLANE = 3, //!< Triangle and plane are coplanar
25
26 TRI_FORCEDWORD = 0x7fffffff
27 };
28
29 // A triangle class.
30 class ICEMATHS_API Triangle
31 {
32 public:
33 //! Constructor
34 inline_ Triangle() {}
35 //! Constructor
36 inline_ Triangle(const Point& p0, const Point& p1, const Point& p2) { mVerts[0]=p0; mVerts[1]=p1; mVerts[2]=p2; }
37 //! Copy constructor
38 inline_ Triangle(const Triangle& triangle)
39 {
40 mVerts[0] = triangle.mVerts[0];
41 mVerts[1] = triangle.mVerts[1];
42 mVerts[2] = triangle.mVerts[2];
43 }
44 //! Destructor
45 inline_ ~Triangle() {}
46 //! Vertices
47 Point mVerts[3];
48
49 // Methods
50 void Flip();
51 float Area() const;
52 float Perimeter() const;
53 float Compacity() const;
54 void Normal(Point& normal) const;
55 void DenormalizedNormal(Point& normal) const;
56 void Center(Point& center) const;
57 inline_ Plane PlaneEquation() const { return Plane(mVerts[0], mVerts[1], mVerts[2]); }
58
59 PartVal TestAgainstPlane(const Plane& plane, float epsilon) const;
60// float Distance(Point& cp, Point& cq, Tri& tri);
61 void ComputeMoment(Moment& m);
62 float MinEdgeLength() const;
63 float MaxEdgeLength() const;
64 void ComputePoint(float u, float v, Point& pt, udword* nearvtx=null) const;
65 void Inflate(float fat_coeff, bool constant_border);
66 };
67
68#endif // __ICETRIANGLE_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceTypes.h b/libraries/ode-0.9/OPCODE/Ice/IceTypes.h
new file mode 100644
index 0000000..4ff71b5
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceTypes.h
@@ -0,0 +1,171 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains custom types.
4 * \file IceTypes.h
5 * \author Pierre Terdiman
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICETYPES_H__
13#define __ICETYPES_H__
14
15///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16// Things to help us compile on non-windows platforms
17
18#if defined(__MACOSX__) || defined(__APPLE__)
19#undef bool
20#define bool char
21#undef true
22#define true ((bool)-1)
23#undef false
24#define false ((bool)0)
25#endif // mac stuff
26
27///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28
29 #define USE_HANDLE_MANAGER
30
31 // Constants
32 #define PI 3.1415926535897932384626433832795028841971693993751f //!< PI
33 #define HALFPI 1.57079632679489661923f //!< 0.5 * PI
34 #define TWOPI 6.28318530717958647692f //!< 2.0 * PI
35 #define INVPI 0.31830988618379067154f //!< 1.0 / PI
36
37 #define RADTODEG 57.2957795130823208768f //!< 180.0 / PI, convert radians to degrees
38 #define DEGTORAD 0.01745329251994329577f //!< PI / 180.0, convert degrees to radians
39
40 #define EXP 2.71828182845904523536f //!< e
41 #define INVLOG2 3.32192809488736234787f //!< 1.0 / log10(2)
42 #define LN2 0.693147180559945f //!< ln(2)
43 #define INVLN2 1.44269504089f //!< 1.0f / ln(2)
44
45 #define INV3 0.33333333333333333333f //!< 1/3
46 #define INV6 0.16666666666666666666f //!< 1/6
47 #define INV7 0.14285714285714285714f //!< 1/7
48 #define INV9 0.11111111111111111111f //!< 1/9
49 #define INV255 0.00392156862745098039f //!< 1/255
50
51 #define SQRT2 1.41421356237f //!< sqrt(2)
52 #define INVSQRT2 0.707106781188f //!< 1 / sqrt(2)
53
54 #define SQRT3 1.73205080757f //!< sqrt(3)
55 #define INVSQRT3 0.577350269189f //!< 1 / sqrt(3)
56
57 #define null 0 //!< our own NULL pointer
58
59 // Custom types used in ICE
60 typedef signed char sbyte; //!< sizeof(sbyte) must be 1
61 typedef unsigned char ubyte; //!< sizeof(ubyte) must be 1
62 typedef signed short sword; //!< sizeof(sword) must be 2
63 typedef unsigned short uword; //!< sizeof(uword) must be 2
64 typedef signed int sdword; //!< sizeof(sdword) must be 4
65 typedef unsigned int udword; //!< sizeof(udword) must be 4
66 typedef signed __int64 sqword; //!< sizeof(sqword) must be 8
67 typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8
68 typedef float float32; //!< sizeof(float32) must be 4
69 typedef double float64; //!< sizeof(float64) must be 4
70
71 ICE_COMPILE_TIME_ASSERT(sizeof(bool)==1); // ...otherwise things might fail with VC++ 4.2 !
72 ICE_COMPILE_TIME_ASSERT(sizeof(ubyte)==1);
73 ICE_COMPILE_TIME_ASSERT(sizeof(sbyte)==1);
74 ICE_COMPILE_TIME_ASSERT(sizeof(sword)==2);
75 ICE_COMPILE_TIME_ASSERT(sizeof(uword)==2);
76 ICE_COMPILE_TIME_ASSERT(sizeof(udword)==4);
77 ICE_COMPILE_TIME_ASSERT(sizeof(sdword)==4);
78 ICE_COMPILE_TIME_ASSERT(sizeof(uqword)==8);
79 ICE_COMPILE_TIME_ASSERT(sizeof(sqword)==8);
80
81 //! TO BE DOCUMENTED
82 #define DECLARE_ICE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
83
84 typedef udword DynID; //!< Dynamic identifier
85#ifdef USE_HANDLE_MANAGER
86 typedef udword KID; //!< Kernel ID
87// DECLARE_ICE_HANDLE(KID);
88#else
89 typedef uword KID; //!< Kernel ID
90#endif
91 typedef udword RTYPE; //!< Relationship-type (!) between owners and references
92 #define INVALID_ID 0xffffffff //!< Invalid dword ID (counterpart of null pointers)
93#ifdef USE_HANDLE_MANAGER
94 #define INVALID_KID 0xffffffff //!< Invalid Kernel ID
95#else
96 #define INVALID_KID 0xffff //!< Invalid Kernel ID
97#endif
98 #define INVALID_NUMBER 0xDEADBEEF //!< Standard junk value
99
100 // Define BOOL if needed
101 #ifndef BOOL
102 typedef int BOOL; //!< Another boolean type.
103 #endif
104
105 //! Union of a float and a sdword
106 typedef union {
107 float f; //!< The float
108 sdword d; //!< The integer
109 }scell;
110
111 //! Union of a float and a udword
112 typedef union {
113 float f; //!< The float
114 udword d; //!< The integer
115 }ucell;
116
117 // Type ranges
118 #define MAX_SBYTE 0x7f //!< max possible sbyte value
119 #define MIN_SBYTE 0x80 //!< min possible sbyte value
120 #define MAX_UBYTE 0xff //!< max possible ubyte value
121 #define MIN_UBYTE 0x00 //!< min possible ubyte value
122 #define MAX_SWORD 0x7fff //!< max possible sword value
123 #define MIN_SWORD 0x8000 //!< min possible sword value
124 #define MAX_UWORD 0xffff //!< max possible uword value
125 #define MIN_UWORD 0x0000 //!< min possible uword value
126 #define MAX_SDWORD 0x7fffffff //!< max possible sdword value
127 #define MIN_SDWORD 0x80000000 //!< min possible sdword value
128 #define MAX_UDWORD 0xffffffff //!< max possible udword value
129 #define MIN_UDWORD 0x00000000 //!< min possible udword value
130 #define MAX_FLOAT FLT_MAX //!< max possible float value
131 #define MIN_FLOAT (-FLT_MAX) //!< min possible loat value
132 #define IEEE_1_0 0x3f800000 //!< integer representation of 1.0
133 #define IEEE_255_0 0x437f0000 //!< integer representation of 255.0
134 #define IEEE_MAX_FLOAT 0x7f7fffff //!< integer representation of MAX_FLOAT
135 #define IEEE_MIN_FLOAT 0xff7fffff //!< integer representation of MIN_FLOAT
136 #define IEEE_UNDERFLOW_LIMIT 0x1a000000
137
138 #define ONE_OVER_RAND_MAX (1.0f / float(RAND_MAX)) //!< Inverse of the max possible value returned by rand()
139
140 typedef int (__stdcall* PROC)(); //!< A standard procedure call.
141 typedef bool (*ENUMERATION)(udword value, udword param, udword context); //!< ICE standard enumeration call
142 typedef void** VTABLE; //!< A V-Table.
143
144 #undef MIN
145 #undef MAX
146 #define MIN(a, b) ((a) < (b) ? (a) : (b)) //!< Returns the min value between a and b
147 #define MAX(a, b) ((a) > (b) ? (a) : (b)) //!< Returns the max value between a and b
148 #define MAXMAX(a,b,c) ((a) > (b) ? MAX (a,c) : MAX (b,c)) //!< Returns the max value between a, b and c
149
150 template<class T> inline_ const T& TMin (const T& a, const T& b) { return b < a ? b : a; }
151 template<class T> inline_ const T& TMax (const T& a, const T& b) { return a < b ? b : a; }
152 template<class T> inline_ void TSetMin (T& a, const T& b) { if(a>b) a = b; }
153 template<class T> inline_ void TSetMax (T& a, const T& b) { if(a<b) a = b; }
154
155 #define SQR(x) ((x)*(x)) //!< Returns x square
156 #define CUBE(x) ((x)*(x)*(x)) //!< Returns x cube
157
158 #define AND & //!< ...
159 #define OR | //!< ...
160 #define XOR ^ //!< ...
161
162 #define QUADRAT(x) ((x)*(x)) //!< Returns x square
163
164#ifdef _WIN32
165# define srand48(x) srand((unsigned int) (x))
166# define srandom(x) srand((unsigned int) (x))
167# define random() ((double) rand())
168# define drand48() ((double) (((double) rand()) / ((double) RAND_MAX)))
169#endif
170
171#endif // __ICETYPES_H__
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceUtils.cpp b/libraries/ode-0.9/OPCODE/Ice/IceUtils.cpp
new file mode 100644
index 0000000..29b6c57
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceUtils.cpp
@@ -0,0 +1,39 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains misc. useful macros & defines.
4 * \file IceUtils.cpp
5 * \author Pierre Terdiman (collected from various sources)
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Precompiled Header
12#include "Stdafx.h"
13
14using namespace IceCore;
15
16///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17/**
18 * Returns the alignment of the input address.
19 * \fn Alignment()
20 * \param address [in] address to check
21 * \return the best alignment (e.g. 1 for odd addresses, etc)
22 */
23///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24udword IceCore::Alignment(udword address)
25{
26 // Returns 0 for null addresses
27 if(!address) return 0;
28
29 // Test all bits
30 udword Align = 1;
31 for(udword i=1;i<32;i++)
32 {
33 // Returns as soon as the alignment is broken
34 if(address&Align) return Align;
35 Align<<=1;
36 }
37 // Here all bits are null, except the highest one (else the address would be null)
38 return Align;
39}
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceUtils.h b/libraries/ode-0.9/OPCODE/Ice/IceUtils.h
new file mode 100644
index 0000000..f4552ec
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceUtils.h
@@ -0,0 +1,256 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains misc. useful macros & defines.
4 * \file IceUtils.h
5 * \author Pierre Terdiman (collected from various sources)
6 * \date April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEUTILS_H__
13#define __ICEUTILS_H__
14
15 #define START_RUNONCE { static bool __RunOnce__ = false; if(!__RunOnce__){
16 #define END_RUNONCE __RunOnce__ = true;}}
17
18 //! Reverse all the bits in a 32 bit word (from Steve Baker's Cute Code Collection)
19 //! (each line can be done in any order.
20 inline_ void ReverseBits(udword& n)
21 {
22 n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
23 n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
24 n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
25 n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
26 n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
27 // Etc for larger intergers (64 bits in Java)
28 // NOTE: the >> operation must be unsigned! (>>> in java)
29 }
30
31 //! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection)
32 inline_ udword CountBits(udword n)
33 {
34 // This relies of the fact that the count of n bits can NOT overflow
35 // an n bit interger. EG: 1 bit count takes a 1 bit interger, 2 bit counts
36 // 2 bit interger, 3 bit count requires only a 2 bit interger.
37 // So we add all bit pairs, then each nible, then each byte etc...
38 n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1);
39 n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2);
40 n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4);
41 n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8);
42 n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16);
43 // Etc for larger intergers (64 bits in Java)
44 // NOTE: the >> operation must be unsigned! (>>> in java)
45 return n;
46 }
47
48 //! Even faster?
49 inline_ udword CountBits2(udword bits)
50 {
51 bits = bits - ((bits >> 1) & 0x55555555);
52 bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333);
53 bits = ((bits >> 4) + bits) & 0x0F0F0F0F;
54 return (bits * 0x01010101) >> 24;
55 }
56
57 //! Spread out bits. EG 00001111 -> 0101010101
58 //! 00001010 -> 0100010000
59 //! This is used to interleve to intergers to produce a `Morten Key'
60 //! used in Space Filling Curves (See DrDobbs Journal, July 1999)
61 //! Order is important.
62 inline_ void SpreadBits(udword& n)
63 {
64 n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16);
65 n = ( n & 0x000000ff) | (( n & 0x0000ff00) << 8);
66 n = ( n & 0x000f000f) | (( n & 0x00f000f0) << 4);
67 n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) << 2);
68 n = ( n & 0x11111111) | (( n & 0x22222222) << 1);
69 }
70
71 // Next Largest Power of 2
72 // Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
73 // that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
74 // the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
75 // largest power of 2. For a 32-bit value:
76 inline_ udword nlpo2(udword x)
77 {
78 x |= (x >> 1);
79 x |= (x >> 2);
80 x |= (x >> 4);
81 x |= (x >> 8);
82 x |= (x >> 16);
83 return x+1;
84 }
85
86 //! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection)
87 inline_ bool IsPowerOfTwo(udword n) { return ((n&(n-1))==0); }
88
89 //! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection)
90 inline_ void ZeroLeastSetBit(udword& n) { n&=(n-1); }
91
92 //! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection)
93 inline_ void SetLeastNBits(udword& x, udword n) { x|=~(~0<<n); }
94
95 //! Classic XOR swap (from Steve Baker's Cute Code Collection)
96 //! x ^= y; /* x' = (x^y) */
97 //! y ^= x; /* y' = (y^(x^y)) = x */
98 //! x ^= y; /* x' = (x^y)^x = y */
99 inline_ void Swap(udword& x, udword& y) { x ^= y; y ^= x; x ^= y; }
100
101 //! Little/Big endian (from Steve Baker's Cute Code Collection)
102 //!
103 //! Extra comments by Kenny Hoff:
104 //! Determines the byte-ordering of the current machine (little or big endian)
105 //! by setting an integer value to 1 (so least significant bit is now 1); take
106 //! the address of the int and cast to a byte pointer (treat integer as an
107 //! array of four bytes); check the value of the first byte (must be 0 or 1).
108 //! If the value is 1, then the first byte least significant byte and this
109 //! implies LITTLE endian. If the value is 0, the first byte is the most
110 //! significant byte, BIG endian. Examples:
111 //! integer 1 on BIG endian: 00000000 00000000 00000000 00000001
112 //! integer 1 on LITTLE endian: 00000001 00000000 00000000 00000000
113 //!---------------------------------------------------------------------------
114 //! int IsLittleEndian() { int x=1; return ( ((char*)(&x))[0] ); }
115 inline_ char LittleEndian() { int i = 1; return *((char*)&i); }
116
117 //!< Alternative abs function
118 inline_ udword abs_(sdword x) { sdword y= x >> 31; return (x^y)-y; }
119
120 //!< Alternative min function
121 inline_ sdword min_(sdword a, sdword b) { sdword delta = b-a; return a + (delta&(delta>>31)); }
122
123 // Determine if one of the bytes in a 4 byte word is zero
124 inline_ BOOL HasNullByte(udword x) { return ((x + 0xfefefeff) & (~x) & 0x80808080); }
125
126 // To find the smallest 1 bit in a word EG: ~~~~~~10---0 => 0----010---0
127 inline_ udword LowestOneBit(udword w) { return ((w) & (~(w)+1)); }
128// inline_ udword LowestOneBit_(udword w) { return ((w) & (-(w))); }
129
130 // Most Significant 1 Bit
131 // Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set)
132 // can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits.
133 // This process yields a bit vector with the same most significant 1 as x, but all 1's below it.
134 // Bitwise AND of the original value with the complement of the "folded" value shifted down by one
135 // yields the most significant bit. For a 32-bit value:
136 inline_ udword msb32(udword x)
137 {
138 x |= (x >> 1);
139 x |= (x >> 2);
140 x |= (x >> 4);
141 x |= (x >> 8);
142 x |= (x >> 16);
143 return (x & ~(x >> 1));
144 }
145
146 /*
147 "Just call it repeatedly with various input values and always with the same variable as "memory".
148 The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1
149 does no filtering at all.
150
151 I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed
152 to the more typical FIR (Finite Impulse Response).
153
154 Also, I'd say that you can make more intelligent and interesting filters than this, for example filters
155 that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter
156 to be applied before this one, of course."
157
158 (JCAB on Flipcode)
159 */
160 inline_ float FeedbackFilter(float val, float& memory, float sharpness)
161 {
162 ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter");
163 if(sharpness<0.0f) sharpness = 0.0f;
164 else if(sharpness>1.0f) sharpness = 1.0f;
165 return memory = val * sharpness + memory * (1.0f - sharpness);
166 }
167
168 //! If you can guarantee that your input domain (i.e. value of x) is slightly
169 //! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the
170 //! following code to clamp the resulting value into [-32768,+32767] range:
171 inline_ int ClampToInt16(int x)
172 {
173// ASSERT(abs(x) < (int)((1<<31u)-32767));
174
175 int delta = 32767 - x;
176 x += (delta>>31) & delta;
177 delta = x + 32768;
178 x -= (delta>>31) & delta;
179 return x;
180 }
181
182 // Generic functions
183 template<class Type> inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; }
184 template<class Type> inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((x<lo) ? lo : (x>hi) ? hi : x); }
185
186 template<class Type> inline_ void TSort(Type& a, Type& b)
187 {
188 if(a>b) TSwap(a, b);
189 }
190
191 template<class Type> inline_ void TSort(Type& a, Type& b, Type& c)
192 {
193 if(a>b) TSwap(a, b);
194 if(b>c) TSwap(b, c);
195 if(a>b) TSwap(a, b);
196 if(b>c) TSwap(b, c);
197 }
198
199 // Prevent nasty user-manipulations (strategy borrowed from Charles Bloom)
200// #define PREVENT_COPY(curclass) void operator = (const curclass& object) { ASSERT(!"Bad use of operator ="); }
201 // ... actually this is better !
202 #define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object); cur_class& operator=(const cur_class& object);
203
204 //! TO BE DOCUMENTED
205 #define OFFSET_OF(Class, Member) (size_t)&(((Class*)0)->Member)
206 //! TO BE DOCUMENTED
207 #define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0]))
208
209 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
210 /**
211 * Returns the alignment of the input address.
212 * \fn Alignment()
213 * \param address [in] address to check
214 * \return the best alignment (e.g. 1 for odd addresses, etc)
215 */
216 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
217 FUNCTION ICECORE_API udword Alignment(udword address);
218
219 #define IS_ALIGNED_2(x) ((x&1)==0)
220 #define IS_ALIGNED_4(x) ((x&3)==0)
221 #define IS_ALIGNED_8(x) ((x&7)==0)
222
223 inline_ void _prefetch(void const* ptr) { (void)*(char const volatile *)ptr; }
224
225 // Compute implicit coords from an index:
226 // The idea is to get back 2D coords from a 1D index.
227 // For example:
228 //
229 // 0 1 2 ... nbu-1
230 // nbu nbu+1 i ...
231 //
232 // We have i, we're looking for the equivalent (u=2, v=1) location.
233 // i = u + v*nbu
234 // <=> i/nbu = u/nbu + v
235 // Since 0 <= u < nbu, u/nbu = 0 (integer)
236 // Hence: v = i/nbu
237 // Then we simply put it back in the original equation to compute u = i - v*nbu
238 inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu)
239 {
240 v = i / nbu;
241 u = i - (v * nbu);
242 }
243
244 // In 3D: i = u + v*nbu + w*nbu*nbv
245 // <=> i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w
246 // u/(nbu*nbv) is null since u/nbu was null already.
247 // v/nbv is null as well for the same reason.
248 // Hence w = i/(nbu*nbv)
249 // Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu
250 inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv)
251 {
252 w = i / (nbu_nbv);
253 Compute2DCoords(u, v, i - (w * nbu_nbv), nbu);
254 }
255
256#endif // __ICEUTILS_H__