diff options
author | dan miller | 2007-10-19 05:20:48 +0000 |
---|---|---|
committer | dan miller | 2007-10-19 05:20:48 +0000 |
commit | d48ea5bb797037069d641da41da0f195f0124491 (patch) | |
tree | 40ff433d94859d629aac933d5ec73b382f62ba1a /libraries/ode-0.9/include/ode/odemath.h | |
parent | dont ask (diff) | |
download | opensim-SC_OLD-d48ea5bb797037069d641da41da0f195f0124491.zip opensim-SC_OLD-d48ea5bb797037069d641da41da0f195f0124491.tar.gz opensim-SC_OLD-d48ea5bb797037069d641da41da0f195f0124491.tar.bz2 opensim-SC_OLD-d48ea5bb797037069d641da41da0f195f0124491.tar.xz |
one more for the gipper
Diffstat (limited to 'libraries/ode-0.9/include/ode/odemath.h')
-rw-r--r-- | libraries/ode-0.9/include/ode/odemath.h | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/libraries/ode-0.9/include/ode/odemath.h b/libraries/ode-0.9/include/ode/odemath.h new file mode 100644 index 0000000..f8fa3c7 --- /dev/null +++ b/libraries/ode-0.9/include/ode/odemath.h | |||
@@ -0,0 +1,330 @@ | |||
1 | /************************************************************************* | ||
2 | * * | ||
3 | * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * | ||
4 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * | ||
5 | * * | ||
6 | * This library is free software; you can redistribute it and/or * | ||
7 | * modify it under the terms of EITHER: * | ||
8 | * (1) The GNU Lesser General Public License as published by the Free * | ||
9 | * Software Foundation; either version 2.1 of the License, or (at * | ||
10 | * your option) any later version. The text of the GNU Lesser * | ||
11 | * General Public License is included with this library in the * | ||
12 | * file LICENSE.TXT. * | ||
13 | * (2) The BSD-style license that is included with this library in * | ||
14 | * the file LICENSE-BSD.TXT. * | ||
15 | * * | ||
16 | * This library is distributed in the hope that it will be useful, * | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * | ||
19 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * | ||
20 | * * | ||
21 | *************************************************************************/ | ||
22 | |||
23 | #ifndef _ODE_ODEMATH_H_ | ||
24 | #define _ODE_ODEMATH_H_ | ||
25 | |||
26 | #include <ode/common.h> | ||
27 | |||
28 | #ifdef __GNUC__ | ||
29 | #define PURE_INLINE extern inline | ||
30 | #else | ||
31 | #define PURE_INLINE inline | ||
32 | #endif | ||
33 | |||
34 | /* | ||
35 | * macro to access elements i,j in an NxM matrix A, independent of the | ||
36 | * matrix storage convention. | ||
37 | */ | ||
38 | #define dACCESS33(A,i,j) ((A)[(i)*4+(j)]) | ||
39 | |||
40 | /* | ||
41 | * Macro to test for valid floating point values | ||
42 | */ | ||
43 | #define dVALIDVEC3(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]))) | ||
44 | #define dVALIDVEC4(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]) || dIsNan(v[3]))) | ||
45 | #define dVALIDMAT3(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]))) | ||
46 | #define dVALIDMAT4(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]) || dIsNan(m[12]) || dIsNan(m[13]) || dIsNan(m[14]) || dIsNan(m[15]) )) | ||
47 | |||
48 | |||
49 | |||
50 | /* | ||
51 | * General purpose vector operations with other vectors or constants. | ||
52 | */ | ||
53 | |||
54 | #define dOP(a,op,b,c) \ | ||
55 | (a)[0] = ((b)[0]) op ((c)[0]); \ | ||
56 | (a)[1] = ((b)[1]) op ((c)[1]); \ | ||
57 | (a)[2] = ((b)[2]) op ((c)[2]); | ||
58 | #define dOPC(a,op,b,c) \ | ||
59 | (a)[0] = ((b)[0]) op (c); \ | ||
60 | (a)[1] = ((b)[1]) op (c); \ | ||
61 | (a)[2] = ((b)[2]) op (c); | ||
62 | #define dOPE(a,op,b) \ | ||
63 | (a)[0] op ((b)[0]); \ | ||
64 | (a)[1] op ((b)[1]); \ | ||
65 | (a)[2] op ((b)[2]); | ||
66 | #define dOPEC(a,op,c) \ | ||
67 | (a)[0] op (c); \ | ||
68 | (a)[1] op (c); \ | ||
69 | (a)[2] op (c); | ||
70 | |||
71 | |||
72 | /* | ||
73 | * Length, and squared length helpers. dLENGTH returns the length of a dVector3. | ||
74 | * dLENGTHSQUARED return the squared length of a dVector3. | ||
75 | */ | ||
76 | |||
77 | #define dLENGTHSQUARED(a) (((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2])) | ||
78 | |||
79 | #ifdef __cplusplus | ||
80 | |||
81 | PURE_INLINE dReal dLENGTH (const dReal *a) { return dSqrt(dLENGTHSQUARED(a)); } | ||
82 | |||
83 | #else | ||
84 | |||
85 | #define dLENGTH(a) ( dSqrt( ((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2]) ) ) | ||
86 | |||
87 | #endif /* __cplusplus */ | ||
88 | |||
89 | |||
90 | |||
91 | |||
92 | |||
93 | /* | ||
94 | * 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced | ||
95 | * p and q indexes apart respectively. dDOT() means dDOT11. | ||
96 | * in C++ we could use function templates to get all the versions of these | ||
97 | * functions - but on some compilers this will result in sub-optimal code. | ||
98 | */ | ||
99 | |||
100 | #define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)]) | ||
101 | |||
102 | #ifdef __cplusplus | ||
103 | |||
104 | PURE_INLINE dReal dDOT (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,1); } | ||
105 | PURE_INLINE dReal dDOT13 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,3); } | ||
106 | PURE_INLINE dReal dDOT31 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,1); } | ||
107 | PURE_INLINE dReal dDOT33 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,3); } | ||
108 | PURE_INLINE dReal dDOT14 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,4); } | ||
109 | PURE_INLINE dReal dDOT41 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,1); } | ||
110 | PURE_INLINE dReal dDOT44 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,4); } | ||
111 | |||
112 | #else | ||
113 | |||
114 | #define dDOT(a,b) dDOTpq(a,b,1,1) | ||
115 | #define dDOT13(a,b) dDOTpq(a,b,1,3) | ||
116 | #define dDOT31(a,b) dDOTpq(a,b,3,1) | ||
117 | #define dDOT33(a,b) dDOTpq(a,b,3,3) | ||
118 | #define dDOT14(a,b) dDOTpq(a,b,1,4) | ||
119 | #define dDOT41(a,b) dDOTpq(a,b,4,1) | ||
120 | #define dDOT44(a,b) dDOTpq(a,b,4,4) | ||
121 | |||
122 | #endif /* __cplusplus */ | ||
123 | |||
124 | |||
125 | /* | ||
126 | * cross product, set a = b x c. dCROSSpqr means that elements of `a', `b' | ||
127 | * and `c' are spaced p, q and r indexes apart respectively. | ||
128 | * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to | ||
129 | * +=, -= etc to get other effects. | ||
130 | */ | ||
131 | |||
132 | #define dCROSS(a,op,b,c) \ | ||
133 | do { \ | ||
134 | (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ | ||
135 | (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ | ||
136 | (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \ | ||
137 | } while(0) | ||
138 | #define dCROSSpqr(a,op,b,c,p,q,r) \ | ||
139 | do { \ | ||
140 | (a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \ | ||
141 | (a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \ | ||
142 | (a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]); \ | ||
143 | } while(0) | ||
144 | #define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4) | ||
145 | #define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1) | ||
146 | #define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4) | ||
147 | #define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1) | ||
148 | #define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4) | ||
149 | #define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1) | ||
150 | #define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4) | ||
151 | |||
152 | |||
153 | /* | ||
154 | * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b. | ||
155 | * A is stored by rows, and has `skip' elements per row. the matrix is | ||
156 | * assumed to be already zero, so this does not write zero elements! | ||
157 | * if (plus,minus) is (+,-) then a positive version will be written. | ||
158 | * if (plus,minus) is (-,+) then a negative version will be written. | ||
159 | */ | ||
160 | |||
161 | #define dCROSSMAT(A,a,skip,plus,minus) \ | ||
162 | do { \ | ||
163 | (A)[1] = minus (a)[2]; \ | ||
164 | (A)[2] = plus (a)[1]; \ | ||
165 | (A)[(skip)+0] = plus (a)[2]; \ | ||
166 | (A)[(skip)+2] = minus (a)[0]; \ | ||
167 | (A)[2*(skip)+0] = minus (a)[1]; \ | ||
168 | (A)[2*(skip)+1] = plus (a)[0]; \ | ||
169 | } while(0) | ||
170 | |||
171 | |||
172 | /* | ||
173 | * compute the distance between two 3D-vectors | ||
174 | */ | ||
175 | |||
176 | #ifdef __cplusplus | ||
177 | PURE_INLINE dReal dDISTANCE (const dVector3 a, const dVector3 b) | ||
178 | { return dSqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) + (a[2]-b[2])*(a[2]-b[2]) ); } | ||
179 | #else | ||
180 | #define dDISTANCE(a,b) \ | ||
181 | (dSqrt( ((a)[0]-(b)[0])*((a)[0]-(b)[0]) + ((a)[1]-(b)[1])*((a)[1]-(b)[1]) + ((a)[2]-(b)[2])*((a)[2]-(b)[2]) )) | ||
182 | #endif | ||
183 | |||
184 | |||
185 | /* | ||
186 | * special case matrix multipication, with operator selection | ||
187 | */ | ||
188 | |||
189 | #define dMULTIPLYOP0_331(A,op,B,C) \ | ||
190 | do { \ | ||
191 | (A)[0] op dDOT((B),(C)); \ | ||
192 | (A)[1] op dDOT((B+4),(C)); \ | ||
193 | (A)[2] op dDOT((B+8),(C)); \ | ||
194 | } while(0) | ||
195 | #define dMULTIPLYOP1_331(A,op,B,C) \ | ||
196 | do { \ | ||
197 | (A)[0] op dDOT41((B),(C)); \ | ||
198 | (A)[1] op dDOT41((B+1),(C)); \ | ||
199 | (A)[2] op dDOT41((B+2),(C)); \ | ||
200 | } while(0) | ||
201 | #define dMULTIPLYOP0_133(A,op,B,C) \ | ||
202 | do { \ | ||
203 | (A)[0] op dDOT14((B),(C)); \ | ||
204 | (A)[1] op dDOT14((B),(C+1)); \ | ||
205 | (A)[2] op dDOT14((B),(C+2)); \ | ||
206 | } while(0) | ||
207 | #define dMULTIPLYOP0_333(A,op,B,C) \ | ||
208 | do { \ | ||
209 | (A)[0] op dDOT14((B),(C)); \ | ||
210 | (A)[1] op dDOT14((B),(C+1)); \ | ||
211 | (A)[2] op dDOT14((B),(C+2)); \ | ||
212 | (A)[4] op dDOT14((B+4),(C)); \ | ||
213 | (A)[5] op dDOT14((B+4),(C+1)); \ | ||
214 | (A)[6] op dDOT14((B+4),(C+2)); \ | ||
215 | (A)[8] op dDOT14((B+8),(C)); \ | ||
216 | (A)[9] op dDOT14((B+8),(C+1)); \ | ||
217 | (A)[10] op dDOT14((B+8),(C+2)); \ | ||
218 | } while(0) | ||
219 | #define dMULTIPLYOP1_333(A,op,B,C) \ | ||
220 | do { \ | ||
221 | (A)[0] op dDOT44((B),(C)); \ | ||
222 | (A)[1] op dDOT44((B),(C+1)); \ | ||
223 | (A)[2] op dDOT44((B),(C+2)); \ | ||
224 | (A)[4] op dDOT44((B+1),(C)); \ | ||
225 | (A)[5] op dDOT44((B+1),(C+1)); \ | ||
226 | (A)[6] op dDOT44((B+1),(C+2)); \ | ||
227 | (A)[8] op dDOT44((B+2),(C)); \ | ||
228 | (A)[9] op dDOT44((B+2),(C+1)); \ | ||
229 | (A)[10] op dDOT44((B+2),(C+2)); \ | ||
230 | } while(0) | ||
231 | #define dMULTIPLYOP2_333(A,op,B,C) \ | ||
232 | do { \ | ||
233 | (A)[0] op dDOT((B),(C)); \ | ||
234 | (A)[1] op dDOT((B),(C+4)); \ | ||
235 | (A)[2] op dDOT((B),(C+8)); \ | ||
236 | (A)[4] op dDOT((B+4),(C)); \ | ||
237 | (A)[5] op dDOT((B+4),(C+4)); \ | ||
238 | (A)[6] op dDOT((B+4),(C+8)); \ | ||
239 | (A)[8] op dDOT((B+8),(C)); \ | ||
240 | (A)[9] op dDOT((B+8),(C+4)); \ | ||
241 | (A)[10] op dDOT((B+8),(C+8)); \ | ||
242 | } while(0) | ||
243 | |||
244 | #ifdef __cplusplus | ||
245 | |||
246 | #define DECL template <class TA, class TB, class TC> PURE_INLINE void | ||
247 | |||
248 | DECL dMULTIPLY0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,=,B,C); } | ||
249 | DECL dMULTIPLY1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,=,B,C); } | ||
250 | DECL dMULTIPLY0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,=,B,C); } | ||
251 | DECL dMULTIPLY0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,=,B,C); } | ||
252 | DECL dMULTIPLY1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,=,B,C); } | ||
253 | DECL dMULTIPLY2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,=,B,C); } | ||
254 | |||
255 | DECL dMULTIPLYADD0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,+=,B,C); } | ||
256 | DECL dMULTIPLYADD1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,+=,B,C); } | ||
257 | DECL dMULTIPLYADD0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,+=,B,C); } | ||
258 | DECL dMULTIPLYADD0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,+=,B,C); } | ||
259 | DECL dMULTIPLYADD1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,+=,B,C); } | ||
260 | DECL dMULTIPLYADD2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,+=,B,C); } | ||
261 | |||
262 | #undef DECL | ||
263 | |||
264 | #else | ||
265 | |||
266 | #define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C) | ||
267 | #define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C) | ||
268 | #define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C) | ||
269 | #define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C) | ||
270 | #define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C) | ||
271 | #define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C) | ||
272 | |||
273 | #define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C) | ||
274 | #define dMULTIPLYADD1_331(A,B,C) dMULTIPLYOP1_331(A,+=,B,C) | ||
275 | #define dMULTIPLYADD0_133(A,B,C) dMULTIPLYOP0_133(A,+=,B,C) | ||
276 | #define dMULTIPLYADD0_333(A,B,C) dMULTIPLYOP0_333(A,+=,B,C) | ||
277 | #define dMULTIPLYADD1_333(A,B,C) dMULTIPLYOP1_333(A,+=,B,C) | ||
278 | #define dMULTIPLYADD2_333(A,B,C) dMULTIPLYOP2_333(A,+=,B,C) | ||
279 | |||
280 | #endif | ||
281 | |||
282 | |||
283 | #ifdef __cplusplus | ||
284 | extern "C" { | ||
285 | #endif | ||
286 | |||
287 | /* | ||
288 | * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) | ||
289 | */ | ||
290 | ODE_API int dSafeNormalize3 (dVector3 a); | ||
291 | ODE_API int dSafeNormalize4 (dVector4 a); | ||
292 | |||
293 | // For some reason demo_chain1.c does not understand "inline" keyword. | ||
294 | static __inline void _dNormalize3(dVector3 a) | ||
295 | { | ||
296 | int bNormalizationResult = dSafeNormalize3(a); | ||
297 | dIASSERT(bNormalizationResult); | ||
298 | dVARIABLEUSED(bNormalizationResult); | ||
299 | } | ||
300 | |||
301 | static __inline void _dNormalize4(dVector4 a) | ||
302 | { | ||
303 | int bNormalizationResult = dSafeNormalize4(a); | ||
304 | dIASSERT(bNormalizationResult); | ||
305 | dVARIABLEUSED(bNormalizationResult); | ||
306 | } | ||
307 | |||
308 | // For DLL export | ||
309 | ODE_API void dNormalize3 (dVector3 a); // Potentially asserts on zero vec | ||
310 | ODE_API void dNormalize4 (dVector4 a); // Potentially asserts on zero vec | ||
311 | |||
312 | // For internal use | ||
313 | #define dNormalize3(a) _dNormalize3(a) | ||
314 | #define dNormalize4(a) _dNormalize4(a) | ||
315 | |||
316 | /* | ||
317 | * given a unit length "normal" vector n, generate vectors p and q vectors | ||
318 | * that are an orthonormal basis for the plane space perpendicular to n. | ||
319 | * i.e. this makes p,q such that n,p,q are all perpendicular to each other. | ||
320 | * q will equal n x p. if n is not unit length then p will be unit length but | ||
321 | * q wont be. | ||
322 | */ | ||
323 | |||
324 | ODE_API void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q); | ||
325 | |||
326 | #ifdef __cplusplus | ||
327 | } | ||
328 | #endif | ||
329 | |||
330 | #endif | ||