[657] | 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 | /*
|
---|
| 42 | * 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced
|
---|
| 43 | * p and q indexes apart respectively. dDOT() means dDOT11.
|
---|
| 44 | * in C++ we could use function templates to get all the versions of these
|
---|
| 45 | * functions - but on some compilers this will result in sub-optimal code.
|
---|
| 46 | */
|
---|
| 47 |
|
---|
| 48 | #define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)])
|
---|
| 49 |
|
---|
| 50 | #ifdef __cplusplus
|
---|
| 51 |
|
---|
| 52 | PURE_INLINE dReal dDOT (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,1); }
|
---|
| 53 | PURE_INLINE dReal dDOT13 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,3); }
|
---|
| 54 | PURE_INLINE dReal dDOT31 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,1); }
|
---|
| 55 | PURE_INLINE dReal dDOT33 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,3); }
|
---|
| 56 | PURE_INLINE dReal dDOT14 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,4); }
|
---|
| 57 | PURE_INLINE dReal dDOT41 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,1); }
|
---|
| 58 | PURE_INLINE dReal dDOT44 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,4); }
|
---|
| 59 |
|
---|
| 60 | #else
|
---|
| 61 |
|
---|
| 62 | #define dDOT(a,b) dDOTpq(a,b,1,1)
|
---|
| 63 | #define dDOT13(a,b) dDOTpq(a,b,1,3)
|
---|
| 64 | #define dDOT31(a,b) dDOTpq(a,b,3,1)
|
---|
| 65 | #define dDOT33(a,b) dDOTpq(a,b,3,3)
|
---|
| 66 | #define dDOT14(a,b) dDOTpq(a,b,1,4)
|
---|
| 67 | #define dDOT41(a,b) dDOTpq(a,b,4,1)
|
---|
| 68 | #define dDOT44(a,b) dDOTpq(a,b,4,4)
|
---|
| 69 |
|
---|
| 70 | #endif /* __cplusplus */
|
---|
| 71 |
|
---|
| 72 |
|
---|
| 73 | /*
|
---|
| 74 | * cross product, set a = b x c. dCROSSpqr means that elements of `a', `b'
|
---|
| 75 | * and `c' are spaced p, q and r indexes apart respectively.
|
---|
| 76 | * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to
|
---|
| 77 | * +=, -= etc to get other effects.
|
---|
| 78 | */
|
---|
| 79 |
|
---|
| 80 | #define dCROSS(a,op,b,c) \
|
---|
| 81 | (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
|
---|
| 82 | (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
|
---|
| 83 | (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]);
|
---|
| 84 | #define dCROSSpqr(a,op,b,c,p,q,r) \
|
---|
| 85 | (a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \
|
---|
| 86 | (a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \
|
---|
| 87 | (a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]);
|
---|
| 88 | #define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4)
|
---|
| 89 | #define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1)
|
---|
| 90 | #define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4)
|
---|
| 91 | #define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1)
|
---|
| 92 | #define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4)
|
---|
| 93 | #define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1)
|
---|
| 94 | #define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4)
|
---|
| 95 |
|
---|
| 96 |
|
---|
| 97 | /*
|
---|
| 98 | * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b.
|
---|
| 99 | * A is stored by rows, and has `skip' elements per row. the matrix is
|
---|
| 100 | * assumed to be already zero, so this does not write zero elements!
|
---|
| 101 | * if (plus,minus) is (+,-) then a positive version will be written.
|
---|
| 102 | * if (plus,minus) is (-,+) then a negative version will be written.
|
---|
| 103 | */
|
---|
| 104 |
|
---|
| 105 | #define dCROSSMAT(A,a,skip,plus,minus) \
|
---|
| 106 | (A)[1] = minus (a)[2]; \
|
---|
| 107 | (A)[2] = plus (a)[1]; \
|
---|
| 108 | (A)[(skip)+0] = plus (a)[2]; \
|
---|
| 109 | (A)[(skip)+2] = minus (a)[0]; \
|
---|
| 110 | (A)[2*(skip)+0] = minus (a)[1]; \
|
---|
| 111 | (A)[2*(skip)+1] = plus (a)[0];
|
---|
| 112 |
|
---|
| 113 |
|
---|
| 114 | /*
|
---|
| 115 | * compute the distance between two 3-vectors
|
---|
| 116 | */
|
---|
| 117 |
|
---|
| 118 | #ifdef __cplusplus
|
---|
| 119 | PURE_INLINE float dDISTANCE (const float a[3], const float b[3])
|
---|
| 120 | { return (float) 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]) ); }
|
---|
| 121 | PURE_INLINE double dDISTANCE (const double a[3], const double b[3])
|
---|
| 122 | { 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]) ); }
|
---|
| 123 | #else
|
---|
| 124 | #define dDISTANCE(a,b) \
|
---|
| 125 | (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]) ))
|
---|
| 126 | #endif
|
---|
| 127 |
|
---|
| 128 |
|
---|
| 129 | /*
|
---|
| 130 | * special case matrix multipication, with operator selection
|
---|
| 131 | */
|
---|
| 132 |
|
---|
| 133 | #define dMULTIPLYOP0_331(A,op,B,C) \
|
---|
| 134 | (A)[0] op dDOT((B),(C)); \
|
---|
| 135 | (A)[1] op dDOT((B+4),(C)); \
|
---|
| 136 | (A)[2] op dDOT((B+8),(C));
|
---|
| 137 | #define dMULTIPLYOP1_331(A,op,B,C) \
|
---|
| 138 | (A)[0] op dDOT41((B),(C)); \
|
---|
| 139 | (A)[1] op dDOT41((B+1),(C)); \
|
---|
| 140 | (A)[2] op dDOT41((B+2),(C));
|
---|
| 141 | #define dMULTIPLYOP0_133(A,op,B,C) \
|
---|
| 142 | (A)[0] op dDOT14((B),(C)); \
|
---|
| 143 | (A)[1] op dDOT14((B),(C+1)); \
|
---|
| 144 | (A)[2] op dDOT14((B),(C+2));
|
---|
| 145 | #define dMULTIPLYOP0_333(A,op,B,C) \
|
---|
| 146 | (A)[0] op dDOT14((B),(C)); \
|
---|
| 147 | (A)[1] op dDOT14((B),(C+1)); \
|
---|
| 148 | (A)[2] op dDOT14((B),(C+2)); \
|
---|
| 149 | (A)[4] op dDOT14((B+4),(C)); \
|
---|
| 150 | (A)[5] op dDOT14((B+4),(C+1)); \
|
---|
| 151 | (A)[6] op dDOT14((B+4),(C+2)); \
|
---|
| 152 | (A)[8] op dDOT14((B+8),(C)); \
|
---|
| 153 | (A)[9] op dDOT14((B+8),(C+1)); \
|
---|
| 154 | (A)[10] op dDOT14((B+8),(C+2));
|
---|
| 155 | #define dMULTIPLYOP1_333(A,op,B,C) \
|
---|
| 156 | (A)[0] op dDOT44((B),(C)); \
|
---|
| 157 | (A)[1] op dDOT44((B),(C+1)); \
|
---|
| 158 | (A)[2] op dDOT44((B),(C+2)); \
|
---|
| 159 | (A)[4] op dDOT44((B+1),(C)); \
|
---|
| 160 | (A)[5] op dDOT44((B+1),(C+1)); \
|
---|
| 161 | (A)[6] op dDOT44((B+1),(C+2)); \
|
---|
| 162 | (A)[8] op dDOT44((B+2),(C)); \
|
---|
| 163 | (A)[9] op dDOT44((B+2),(C+1)); \
|
---|
| 164 | (A)[10] op dDOT44((B+2),(C+2));
|
---|
| 165 | #define dMULTIPLYOP2_333(A,op,B,C) \
|
---|
| 166 | (A)[0] op dDOT((B),(C)); \
|
---|
| 167 | (A)[1] op dDOT((B),(C+4)); \
|
---|
| 168 | (A)[2] op dDOT((B),(C+8)); \
|
---|
| 169 | (A)[4] op dDOT((B+4),(C)); \
|
---|
| 170 | (A)[5] op dDOT((B+4),(C+4)); \
|
---|
| 171 | (A)[6] op dDOT((B+4),(C+8)); \
|
---|
| 172 | (A)[8] op dDOT((B+8),(C)); \
|
---|
| 173 | (A)[9] op dDOT((B+8),(C+4)); \
|
---|
| 174 | (A)[10] op dDOT((B+8),(C+8));
|
---|
| 175 |
|
---|
| 176 | #ifdef __cplusplus
|
---|
| 177 |
|
---|
| 178 | #define DECL template <class TA, class TB, class TC> PURE_INLINE void
|
---|
| 179 |
|
---|
| 180 | DECL dMULTIPLY0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,=,B,C) }
|
---|
| 181 | DECL dMULTIPLY1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,=,B,C) }
|
---|
| 182 | DECL dMULTIPLY0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,=,B,C) }
|
---|
| 183 | DECL dMULTIPLY0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,=,B,C) }
|
---|
| 184 | DECL dMULTIPLY1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,=,B,C) }
|
---|
| 185 | DECL dMULTIPLY2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,=,B,C) }
|
---|
| 186 |
|
---|
| 187 | DECL dMULTIPLYADD0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,+=,B,C) }
|
---|
| 188 | DECL dMULTIPLYADD1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,+=,B,C) }
|
---|
| 189 | DECL dMULTIPLYADD0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,+=,B,C) }
|
---|
| 190 | DECL dMULTIPLYADD0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,+=,B,C) }
|
---|
| 191 | DECL dMULTIPLYADD1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,+=,B,C) }
|
---|
| 192 | DECL dMULTIPLYADD2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,+=,B,C) }
|
---|
| 193 |
|
---|
| 194 | #undef DECL
|
---|
| 195 |
|
---|
| 196 | #else
|
---|
| 197 |
|
---|
| 198 | #define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C)
|
---|
| 199 | #define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C)
|
---|
| 200 | #define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C)
|
---|
| 201 | #define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C)
|
---|
| 202 | #define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C)
|
---|
| 203 | #define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C)
|
---|
| 204 |
|
---|
| 205 | #define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C)
|
---|
| 206 | #define dMULTIPLYADD1_331(A,B,C) dMULTIPLYOP1_331(A,+=,B,C)
|
---|
| 207 | #define dMULTIPLYADD0_133(A,B,C) dMULTIPLYOP0_133(A,+=,B,C)
|
---|
| 208 | #define dMULTIPLYADD0_333(A,B,C) dMULTIPLYOP0_333(A,+=,B,C)
|
---|
| 209 | #define dMULTIPLYADD1_333(A,B,C) dMULTIPLYOP1_333(A,+=,B,C)
|
---|
| 210 | #define dMULTIPLYADD2_333(A,B,C) dMULTIPLYOP2_333(A,+=,B,C)
|
---|
| 211 |
|
---|
| 212 | #endif
|
---|
| 213 |
|
---|
| 214 | // Terrain callback mod (start)
|
---|
| 215 | #define dOP(a,op,b,c) \
|
---|
| 216 | (a)[0] = ((b)[0]) op ((c)[0]); \
|
---|
| 217 | (a)[1] = ((b)[1]) op ((c)[1]); \
|
---|
| 218 | (a)[2] = ((b)[2]) op ((c)[2]);
|
---|
| 219 | #define dOPC(a,op,b,c) \
|
---|
| 220 | (a)[0] = ((b)[0]) op (c); \
|
---|
| 221 | (a)[1] = ((b)[1]) op (c); \
|
---|
| 222 | (a)[2] = ((b)[2]) op (c);
|
---|
| 223 | #define dOPE(a,op,b) \
|
---|
| 224 | (a)[0] op ((b)[0]); \
|
---|
| 225 | (a)[1] op ((b)[1]); \
|
---|
| 226 | (a)[2] op ((b)[2]);
|
---|
| 227 | #define dOPEC(a,op,c) \
|
---|
| 228 | (a)[0] op (c); \
|
---|
| 229 | (a)[1] op (c); \
|
---|
| 230 | (a)[2] op (c);
|
---|
| 231 | #define dLENGTH(a) \
|
---|
| 232 | (dSqrt( ((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2]) ));
|
---|
| 233 | #define dLENGTHSQUARED(a) \
|
---|
| 234 | (((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2]));
|
---|
| 235 | // Terrain callback mod (end)
|
---|
| 236 |
|
---|
| 237 | #ifdef __cplusplus
|
---|
| 238 | extern "C" {
|
---|
| 239 | #endif
|
---|
| 240 |
|
---|
| 241 | /*
|
---|
| 242 | * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length)
|
---|
| 243 | */
|
---|
| 244 | void dNormalize3 (dVector3 a);
|
---|
| 245 | void dNormalize4 (dVector4 a);
|
---|
| 246 |
|
---|
| 247 |
|
---|
| 248 | /*
|
---|
| 249 | * given a unit length "normal" vector n, generate vectors p and q vectors
|
---|
| 250 | * that are an orthonormal basis for the plane space perpendicular to n.
|
---|
| 251 | * i.e. this makes p,q such that n,p,q are all perpendicular to each other.
|
---|
| 252 | * q will equal n x p. if n is not unit length then p will be unit length but
|
---|
| 253 | * q wont be.
|
---|
| 254 | */
|
---|
| 255 |
|
---|
| 256 | void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q);
|
---|
| 257 |
|
---|
| 258 | #ifdef __cplusplus
|
---|
| 259 | }
|
---|
| 260 | #endif
|
---|
| 261 |
|
---|
| 262 | #endif
|
---|