--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/classicui_plat/ode_api/inc/odemath.h Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,282 @@
+/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+#ifndef _ODE_ODEMATH_H_
+#define _ODE_ODEMATH_H_
+
+#include <ode/common.h>
+
+#ifdef __GNUC__
+#define PURE_INLINE extern inline
+#else
+#define PURE_INLINE inline
+#endif
+
+/*
+ * macro to access elements i,j in an NxM matrix A, independent of the
+ * matrix storage convention.
+ */
+#define dACCESS33(A,i,j) ((A)[(i)*4+(j)])
+
+/*
+ * Macro to test for valid floating point values
+ */
+#define dVALIDVEC3(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2])))
+#define dVALIDVEC4(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]) || dIsNan(v[3])))
+#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])))
+#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]) ))
+
+
+
+/*
+ * General purpose vector operations with other vectors or constants.
+ */
+
+#define dOP(a,op,b,c) \
+ (a)[0] = ((b)[0]) op ((c)[0]); \
+ (a)[1] = ((b)[1]) op ((c)[1]); \
+ (a)[2] = ((b)[2]) op ((c)[2]);
+#define dOPC(a,op,b,c) \
+ (a)[0] = ((b)[0]) op (c); \
+ (a)[1] = ((b)[1]) op (c); \
+ (a)[2] = ((b)[2]) op (c);
+#define dOPE(a,op,b) \
+ (a)[0] op ((b)[0]); \
+ (a)[1] op ((b)[1]); \
+ (a)[2] op ((b)[2]);
+#define dOPEC(a,op,c) \
+ (a)[0] op (c); \
+ (a)[1] op (c); \
+ (a)[2] op (c);
+
+
+
+
+
+/*
+ * 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced
+ * p and q indexes apart respectively. dDOT() means dDOT11.
+ * in C++ we could use function templates to get all the versions of these
+ * functions - but on some compilers this will result in sub-optimal code.
+ */
+
+#define dDOTpq(a,b,p,q) (dMUL((a)[0],(b)[0]) + dMUL((a)[p],(b)[q]) + dMUL((a)[2*(p)],(b)[2*(q)]))
+
+
+#ifdef __cplusplus
+
+PURE_INLINE dReal dDOT (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,1); }
+PURE_INLINE dReal dDOT13 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,3); }
+PURE_INLINE dReal dDOT31 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,1); }
+PURE_INLINE dReal dDOT33 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,3); }
+PURE_INLINE dReal dDOT14 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,4); }
+PURE_INLINE dReal dDOT41 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,1); }
+PURE_INLINE dReal dDOT44 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,4); }
+
+#endif /* __cplusplus */
+
+
+/*
+ * cross product, set a = b x c. dCROSSpqr means that elements of `a', `b'
+ * and `c' are spaced p, q and r indexes apart respectively.
+ * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to
+ * +=, -= etc to get other effects.
+ */
+
+#define dCROSS(a,op,b,c) \
+do { \
+ (a)[0] op (dMUL((b)[1],(c)[2]) - dMUL((b)[2],(c)[1])); \
+ (a)[1] op (dMUL((b)[2],(c)[0]) - dMUL((b)[0],(c)[2])); \
+ (a)[2] op (dMUL((b)[0],(c)[1]) - dMUL((b)[1],(c)[0])); \
+} while(0)
+
+#define dCROSSpqr(a,op,b,c,p,q,r) \
+do { \
+ (a)[ 0] op (dMUL((b)[ q],(c)[2*r]) - dMUL((b)[2*q],(c)[ r])); \
+ (a)[ p] op (dMUL((b)[2*q],(c)[ 0]) - dMUL((b)[ 0],(c)[2*r])); \
+ (a)[2*p] op (dMUL((b)[ 0],(c)[ r]) - dMUL((b)[ q],(c)[ 0])); \
+} while(0)
+#define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4)
+#define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1)
+#define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4)
+#define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1)
+#define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4)
+#define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1)
+#define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4)
+
+
+/*
+ * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b.
+ * A is stored by rows, and has `skip' elements per row. the matrix is
+ * assumed to be already zero, so this does not write zero elements!
+ * if (plus,minus) is (+,-) then a positive version will be written.
+ * if (plus,minus) is (-,+) then a negative version will be written.
+ */
+
+#define dCROSSMAT(A,a,skip,plus,minus) \
+do { \
+ (A)[1] = minus (a)[2]; \
+ (A)[2] = plus (a)[1]; \
+ (A)[(skip)+0] = plus (a)[2]; \
+ (A)[(skip)+2] = minus (a)[0]; \
+ (A)[2*(skip)+0] = minus (a)[1]; \
+ (A)[2*(skip)+1] = plus (a)[0]; \
+} while(0)
+
+
+/*
+ * compute the distance between two 3D-vectors
+ */
+
+#ifdef __cplusplus
+#define dDISTANCE(a,b) \
+ (dSqrt( dMUL(((a)[0]-(b)[0]),((a)[0]-(b)[0])) + dMUL(((a)[1]-(b)[1]),((a)[1]-(b)[1])) + dMUL(((a)[2]-(b)[2]),((a)[2]-(b)[2])) ))
+#endif
+
+
+/*
+ * special case matrix multipication, with operator selection
+ */
+
+#define dMULTIPLYOP0_331(A,op,B,C) \
+do { \
+ (A)[0] op dDOT((B),(C)); \
+ (A)[1] op dDOT((B+4),(C)); \
+ (A)[2] op dDOT((B+8),(C)); \
+} while(0)
+#define dMULTIPLYOP1_331(A,op,B,C) \
+do { \
+ (A)[0] op dDOT41((B),(C)); \
+ (A)[1] op dDOT41((B+1),(C)); \
+ (A)[2] op dDOT41((B+2),(C)); \
+} while(0)
+#define dMULTIPLYOP0_133(A,op,B,C) \
+do { \
+ (A)[0] op dDOT14((B),(C)); \
+ (A)[1] op dDOT14((B),(C+1)); \
+ (A)[2] op dDOT14((B),(C+2)); \
+} while(0)
+#define dMULTIPLYOP0_333(A,op,B,C) \
+do { \
+ (A)[0] op dDOT14((B),(C)); \
+ (A)[1] op dDOT14((B),(C+1)); \
+ (A)[2] op dDOT14((B),(C+2)); \
+ (A)[4] op dDOT14((B+4),(C)); \
+ (A)[5] op dDOT14((B+4),(C+1)); \
+ (A)[6] op dDOT14((B+4),(C+2)); \
+ (A)[8] op dDOT14((B+8),(C)); \
+ (A)[9] op dDOT14((B+8),(C+1)); \
+ (A)[10] op dDOT14((B+8),(C+2)); \
+} while(0)
+#define dMULTIPLYOP1_333(A,op,B,C) \
+do { \
+ (A)[0] op dDOT44((B),(C)); \
+ (A)[1] op dDOT44((B),(C+1)); \
+ (A)[2] op dDOT44((B),(C+2)); \
+ (A)[4] op dDOT44((B+1),(C)); \
+ (A)[5] op dDOT44((B+1),(C+1)); \
+ (A)[6] op dDOT44((B+1),(C+2)); \
+ (A)[8] op dDOT44((B+2),(C)); \
+ (A)[9] op dDOT44((B+2),(C+1)); \
+ (A)[10] op dDOT44((B+2),(C+2)); \
+} while(0)
+#define dMULTIPLYOP2_333(A,op,B,C) \
+do { \
+ (A)[0] op dDOT((B),(C)); \
+ (A)[1] op dDOT((B),(C+4)); \
+ (A)[2] op dDOT((B),(C+8)); \
+ (A)[4] op dDOT((B+4),(C)); \
+ (A)[5] op dDOT((B+4),(C+4)); \
+ (A)[6] op dDOT((B+4),(C+8)); \
+ (A)[8] op dDOT((B+8),(C)); \
+ (A)[9] op dDOT((B+8),(C+4)); \
+ (A)[10] op dDOT((B+8),(C+8)); \
+} while(0)
+
+#ifdef __cplusplus
+
+#define DECL template <class TA, class TB, class TC> PURE_INLINE void
+
+DECL dMULTIPLY0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,=,B,C); }
+DECL dMULTIPLY1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,=,B,C); }
+DECL dMULTIPLY0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,=,B,C); }
+DECL dMULTIPLY0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,=,B,C); }
+DECL dMULTIPLY1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,=,B,C); }
+DECL dMULTIPLY2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,=,B,C); }
+
+DECL dMULTIPLYADD0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,+=,B,C); }
+DECL dMULTIPLYADD1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,+=,B,C); }
+DECL dMULTIPLYADD0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,+=,B,C); }
+DECL dMULTIPLYADD0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,+=,B,C); }
+DECL dMULTIPLYADD1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,+=,B,C); }
+DECL dMULTIPLYADD2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,+=,B,C); }
+
+#undef DECL
+
+#else
+
+#define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C)
+#define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C)
+#define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C)
+#define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C)
+#define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C)
+#define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C)
+
+#define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C)
+#define dMULTIPLYADD1_331(A,B,C) dMULTIPLYOP1_331(A,+=,B,C)
+#define dMULTIPLYADD0_133(A,B,C) dMULTIPLYOP0_133(A,+=,B,C)
+#define dMULTIPLYADD0_333(A,B,C) dMULTIPLYOP0_333(A,+=,B,C)
+#define dMULTIPLYADD1_333(A,B,C) dMULTIPLYOP1_333(A,+=,B,C)
+#define dMULTIPLYADD2_333(A,B,C) dMULTIPLYOP2_333(A,+=,B,C)
+
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length)
+ */
+ODE_API IMPORT_C void dNormalize3 (dVector3 a);
+ODE_API IMPORT_C void dNormalize4 (dVector4 a);
+
+
+/*
+ * given a unit length "normal" vector n, generate vectors p and q vectors
+ * that are an orthonormal basis for the plane space perpendicular to n.
+ * i.e. this makes p,q such that n,p,q are all perpendicular to each other.
+ * q will equal n x p. if n is not unit length then p will be unit length but
+ * q wont be.
+ */
+
+ODE_API IMPORT_C void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q);
+
+ODE_API IMPORT_C dReal dArcTan2(const dReal x, const dReal y);
+ODE_API IMPORT_C dReal dArcSin(const dReal arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif