$search
00001 // Copyright (C) 2003-2008 Rosen Diankov 00002 // Computer Science Department 00003 // Carnegie Mellon University, Robotics Institute 00004 // 5000 Forbes Ave. Pittsburgh, PA 15213 00005 // U.S.A. 00006 // 00007 // This file is part of OpenRAVE. 00008 // OpenRAVE is free software: you can redistribute it and/or modify 00009 // it under the terms of the GNU Lesser General Public License as published by 00010 // the Free Software Foundation, either version 3 of the License, or 00011 // at your option) any later version. 00012 // 00013 // This program is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 // GNU Lesser General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Lesser General Public License 00019 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00028 #ifndef RAVE_MATH_H 00029 #define RAVE_MATH_H 00030 00031 #ifndef ODE_API 00032 00033 // special defines from ODE in case ODE isn't present 00034 00035 #define dSINGLE 00036 00037 #if defined(dSINGLE) 00038 typedef float dReal; 00039 #define dSqrt(x) (sqrtf(x)) // square root 00040 #define dRecip(x) ((1.0f/(x))) // reciprocal 00041 #define dSin(x) (sinf(x)) // sin 00042 #define dCos(x) (cosf(x)) // cos 00043 #else 00044 typedef double dReal; 00045 #define dSqrt(x) (sqrt(x)) // square root 00046 #define dRecip(x) ((1.0/(x))) // reciprocal 00047 #define dSin(x) (sin(x)) // sin 00048 #define dCos(x) (cos(x)) // cos 00049 #endif 00050 typedef dReal dVector3[4]; 00051 typedef dReal dVector4[4]; 00052 typedef dReal dMatrix3[4*3]; 00053 typedef dReal dMatrix4[4*4]; 00054 typedef dReal dMatrix6[8*6]; 00055 typedef dReal dQuaternion[4]; 00056 00057 #define _R(i,j) R[(i)*4+(j)] 00058 00059 00060 inline void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) 00061 { 00062 assert(qa && qb && qc); 00063 qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3]; 00064 qa[1] = qb[0]*qc[1] + qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2]; 00065 qa[2] = qb[0]*qc[2] + qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3]; 00066 qa[3] = qb[0]*qc[3] + qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1]; 00067 } 00068 00069 inline void dRfromQ (dMatrix3 R, const dQuaternion q) 00070 { 00071 assert (q && R); 00072 // q = (s,vx,vy,vz) 00073 dReal qq1 = 2*q[1]*q[1]; 00074 dReal qq2 = 2*q[2]*q[2]; 00075 dReal qq3 = 2*q[3]*q[3]; 00076 _R(0,0) = 1 - qq2 - qq3; 00077 _R(0,1) = 2*(q[1]*q[2] - q[0]*q[3]); 00078 _R(0,2) = 2*(q[1]*q[3] + q[0]*q[2]); 00079 _R(0,3) = (dReal)(0.0); 00080 _R(1,0) = 2*(q[1]*q[2] + q[0]*q[3]); 00081 _R(1,1) = 1 - qq1 - qq3; 00082 _R(1,2) = 2*(q[2]*q[3] - q[0]*q[1]); 00083 _R(1,3) = (dReal)(0.0); 00084 _R(2,0) = 2*(q[1]*q[3] - q[0]*q[2]); 00085 _R(2,1) = 2*(q[2]*q[3] + q[0]*q[1]); 00086 _R(2,2) = 1 - qq1 - qq2; 00087 _R(2,3) = (dReal)(0.0); 00088 } 00089 00090 inline void dQfromR (dQuaternion q, const dMatrix3 R) 00091 { 00092 assert(q && R); 00093 dReal tr,s; 00094 tr = _R(0,0) + _R(1,1) + _R(2,2); 00095 if (tr >= 0) { 00096 s = dSqrt (tr + 1); 00097 q[0] = (dReal)(0.5) * s; 00098 s = (dReal)(0.5) * dRecip(s); 00099 q[1] = (_R(2,1) - _R(1,2)) * s; 00100 q[2] = (_R(0,2) - _R(2,0)) * s; 00101 q[3] = (_R(1,0) - _R(0,1)) * s; 00102 } 00103 else { 00104 // find the largest diagonal element and jump to the appropriate case 00105 if (_R(1,1) > _R(0,0)) { 00106 if (_R(2,2) > _R(1,1)) goto case_2; 00107 goto case_1; 00108 } 00109 if (_R(2,2) > _R(0,0)) goto case_2; 00110 goto case_0; 00111 00112 case_0: 00113 s = dSqrt((_R(0,0) - (_R(1,1) + _R(2,2))) + 1); 00114 q[1] = (dReal)(0.5) * s; 00115 s = (dReal)(0.5) * dRecip(s); 00116 q[2] = (_R(0,1) + _R(1,0)) * s; 00117 q[3] = (_R(2,0) + _R(0,2)) * s; 00118 q[0] = (_R(2,1) - _R(1,2)) * s; 00119 return; 00120 00121 case_1: 00122 s = dSqrt((_R(1,1) - (_R(2,2) + _R(0,0))) + 1); 00123 q[2] = (dReal)(0.5) * s; 00124 s = (dReal)(0.5) * dRecip(s); 00125 q[3] = (_R(1,2) + _R(2,1)) * s; 00126 q[1] = (_R(0,1) + _R(1,0)) * s; 00127 q[0] = (_R(0,2) - _R(2,0)) * s; 00128 return; 00129 00130 case_2: 00131 s = dSqrt((_R(2,2) - (_R(0,0) + _R(1,1))) + 1); 00132 q[3] = (dReal)(0.5) * s; 00133 s = (dReal)(0.5) * dRecip(s); 00134 q[1] = (_R(2,0) + _R(0,2)) * s; 00135 q[2] = (_R(1,2) + _R(2,1)) * s; 00136 q[0] = (_R(1,0) - _R(0,1)) * s; 00137 return; 00138 } 00139 } 00140 00141 #undef _R 00142 00143 #endif 00144 00145 #ifndef PI 00146 #define PI ((dReal)3.141592654) 00147 #endif 00148 00149 #define rswap(x, y) *(int*)&(x) ^= *(int*)&(y) ^= *(int*)&(x) ^= *(int*)&(y); 00150 00151 #define g_fEpsilon 1e-8 00152 #define distinctRoots 0 // roots r0 < r1 < r2 00153 #define singleRoot 1 // root r0 00154 #define floatRoot01 2 // roots r0 = r1 < r2 00155 #define floatRoot12 4 // roots r0 < r1 = r2 00156 #define tripleRoot 6 // roots r0 = r1 = r2 00157 00158 template <class T> inline T RAD_2_DEG(T radians) { return (radians * (T)57.29577951); } 00159 00160 template <class T> class RaveTransform; 00161 template <class T> class RaveTransformMatrix; 00162 00163 // multiplies 4x4 matrices 00164 inline float* mult4(float* pfres, const float* pf1, const float* pf2); 00165 00166 // pf1^T * pf2 00167 inline float* multtrans3(float* pfres, const float* pf1, const float* pf2); 00168 inline float* multtrans4(float* pfres, const float* pf1, const float* pf2); 00169 inline float* transnorm3(float* pfout, const float* pfmat, const float* pf); 00170 00171 inline float* transpose3(const float* pf, float* pfres); 00172 inline float* transpose4(const float* pf, float* pfres); 00173 00174 inline float dot2(const float* pf1, const float* pf2); 00175 inline float dot3(const float* pf1, const float* pf2); 00176 inline float dot4(const float* pf1, const float* pf2); 00177 00178 inline float lengthsqr2(const float* pf); 00179 inline float lengthsqr3(const float* pf); 00180 inline float lengthsqr4(const float* pf); 00181 00182 inline float* normalize2(float* pfout, const float* pf); 00183 inline float* normalize3(float* pfout, const float* pf); 00184 inline float* normalize4(float* pfout, const float* pf); 00185 00186 inline float* cross3(float* pfout, const float* pf1, const float* pf2); 00187 00188 // multiplies 3x3 matrices 00189 inline float* mult3_s4(float* pfres, const float* pf1, const float* pf2); 00190 inline float* mult3_s3(float* pfres, const float* pf1, const float* pf2); 00191 00192 inline float* inv3(const float* pf, float* pfres, float* pfdet, int stride); 00193 inline float* inv4(const float* pf, float* pfres); 00194 00195 00196 inline double* mult4(double* pfres, const double* pf1, const double* pf2); 00197 00198 // pf1^T * pf2 00199 inline double* multtrans3(double* pfres, const double* pf1, const double* pf2); 00200 inline double* multtrans4(double* pfres, const double* pf1, const double* pf2); 00201 inline double* transnorm3(double* pfout, const double* pfmat, const double* pf); 00202 00203 inline double* transpose3(const double* pf, double* pfres); 00204 inline double* transpose4(const double* pf, double* pfres); 00205 00206 inline double dot2(const double* pf1, const double* pf2); 00207 inline double dot3(const double* pf1, const double* pf2); 00208 inline double dot4(const double* pf1, const double* pf2); 00209 00210 inline double lengthsqr2(const double* pf); 00211 inline double lengthsqr3(const double* pf); 00212 inline double lengthsqr4(const double* pf); 00213 00214 inline double* normalize2(double* pfout, const double* pf); 00215 inline double* normalize3(double* pfout, const double* pf); 00216 inline double* normalize4(double* pfout, const double* pf); 00217 00218 inline double* cross3(double* pfout, const double* pf1, const double* pf2); 00219 00220 // multiplies 3x3 matrices 00221 inline double* mult3_s4(double* pfres, const double* pf1, const double* pf2); 00222 inline double* mult3_s3(double* pfres, const double* pf1, const double* pf2); 00223 00224 inline double* inv3(const double* pf, double* pfres, double* pfdet, int stride); 00225 inline double* inv4(const double* pf, double* pfres); 00226 00227 00228 inline float RaveSqrt(float f) { return sqrtf(f); } 00229 inline double RaveSqrt(double f) { return sqrt(f); } 00230 inline float RaveSin(float f) { return sinf(f); } 00231 inline double RaveSin(double f) { return sin(f); } 00232 inline float RaveCos(float f) { return cosf(f); } 00233 inline double RaveCos(double f) { return cos(f); } 00234 inline float RaveFabs(float f) { return fabsf(f); } 00235 inline double RaveFabs(double f) { return fabs(f); } 00236 inline float RaveAcos(float f) { return acosf(f); } 00237 inline double RaveAcos(double f) { return acos(f); } 00238 00241 template <class T> 00242 class RaveVector 00243 { 00244 public: 00245 T x, y, z, w; 00246 00247 RaveVector() : x(0), y(0), z(0), w(0) {} 00248 00249 RaveVector(T x, T y, T z) : x(x), y(y), z(z), w(0) {} 00250 RaveVector(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {} 00251 template<class U> RaveVector(const RaveVector<U> &vec) : x((T)vec.x), y((T)vec.y), z((T)vec.z), w((T)vec.w) {} 00252 00254 template<class U> RaveVector(const U* pf) { assert(pf != NULL); x = (T)pf[0]; y = (T)pf[1]; z = (T)pf[2]; w = 0; } 00255 00256 T operator[](int i) const { return (&x)[i]; } 00257 T& operator[](int i) { return (&x)[i]; } 00258 00259 // casting operators 00260 operator T* () { return &x; } 00261 operator const T* () const { return (const T*)&x; } 00262 00263 template <class U> 00264 RaveVector<T>& operator=(const RaveVector<U>& r) { x = (T)r.x; y = (T)r.y; z = (T)r.z; w = (T)r.w; return *this; } 00265 00266 // SCALAR FUNCTIONS 00267 template <class U> inline T dot(const RaveVector<U> &v) const { return x*v.x + y*v.y + z*v.z + w*v.w; } 00268 inline RaveVector<T>& normalize() { return normalize4(); } 00269 00270 inline RaveVector<T>& normalize4() { 00271 T f = x*x+y*y+z*z+w*w; 00272 assert( f > 0 ); 00273 f = 1.0f / RaveSqrt(f); 00274 x *= f; y *= f; z *= f; w *= f; 00275 return *this; 00276 } 00277 inline RaveVector<T>& normalize3() { 00278 T f = x*x+y*y+z*z; 00279 assert( f > 0 ); 00280 f = 1.0f / RaveSqrt(f); 00281 x *= f; y *= f; z *= f; 00282 return *this; 00283 } 00284 00285 inline T lengthsqr2() const { return x*x + y*y; } 00286 inline T lengthsqr3() const { return x*x + y*y + z*z; } 00287 inline T lengthsqr4() const { return x*x + y*y + z*z + w*w; } 00288 00289 inline void Set3(const T* pvals) { x = pvals[0]; y = pvals[1]; z = pvals[2]; } 00290 inline void Set3(T val1, T val2, T val3) { x = val1; y = val2; z = val3; } 00291 inline void Set4(const T* pvals) { x = pvals[0]; y = pvals[1]; z = pvals[2]; w = pvals[3]; } 00292 inline void Set4(T val1, T val2, T val3, T val4) { x = val1; y = val2; z = val3; w = val4;} 00295 inline RaveVector<T>& Cross(const RaveVector<T> &v) { Cross(*this, v); return *this; } 00296 00298 inline RaveVector<T>& Cross(const RaveVector<T> &u, const RaveVector<T> &v) { 00299 RaveVector<T> ucrossv; 00300 ucrossv[0] = u[1] * v[2] - u[2] * v[1]; 00301 ucrossv[1] = u[2] * v[0] - u[0] * v[2]; 00302 ucrossv[2] = u[0] * v[1] - u[1] * v[0]; 00303 *this = ucrossv; 00304 return *this; 00305 } 00306 00307 inline RaveVector<T> operator-() const { RaveVector<T> v; v.x = -x; v.y = -y; v.z = -z; v.w = -w; return v; } 00308 template <class U> inline RaveVector<T> operator+(const RaveVector<U> &r) const { RaveVector<T> v; v.x = x+r.x; v.y = y+r.y; v.z = z+r.z; v.w = w+r.w; return v; } 00309 template <class U> inline RaveVector<T> operator-(const RaveVector<U> &r) const { RaveVector<T> v; v.x = x-r.x; v.y = y-r.y; v.z = z-r.z; v.w = w-r.w; return v; } 00310 template <class U> inline RaveVector<T> operator*(const RaveVector<U> &r) const { RaveVector<T> v; v.x = r.x*x; v.y = r.y*y; v.z = r.z*z; v.w = r.w*w; return v; } 00311 inline RaveVector<T> operator*(T k) const { RaveVector<T> v; v.x = k*x; v.y = k*y; v.z = k*z; v.w = k*w; return v; } 00312 00313 template <class U> inline RaveVector<T>& operator += (const RaveVector<U>& r) { x += r.x; y += r.y; z += r.z; w += r.w; return *this; } 00314 template <class U> inline RaveVector<T>& operator -= (const RaveVector<U>& r) { x -= r.x; y -= r.y; z -= r.z; w -= r.w; return *this; } 00315 template <class U> inline RaveVector<T>& operator *= (const RaveVector<U>& r) { x *= r.x; y *= r.y; z *= r.z; w *= r.w; return *this; } 00316 00317 inline RaveVector<T>& operator *= (const T k) { x *= k; y *= k; z *= k; w *= k; return *this; } 00318 inline RaveVector<T>& operator /= (const T _k) { T k=1/_k; x *= k; y *= k; z *= k; w *= k; return *this; } 00319 00320 template <class U> friend RaveVector<U> operator* (float f, const RaveVector<U>& v); 00321 template <class U> friend RaveVector<U> operator* (double f, const RaveVector<U>& v); 00322 00323 template <class S, class U> friend std::basic_ostream<S>& operator<<(std::basic_ostream<S>& O, const RaveVector<U>& v); 00324 template <class S, class U> friend std::basic_istream<S>& operator>>(std::basic_istream<S>& I, RaveVector<U>& v); 00325 00327 template <class U> inline RaveVector<T> operator^(const RaveVector<U> &v) const { 00328 RaveVector<T> ucrossv; 00329 ucrossv[0] = y * v[2] - z * v[1]; 00330 ucrossv[1] = z * v[0] - x * v[2]; 00331 ucrossv[2] = x * v[1] - y * v[0]; 00332 return ucrossv; 00333 } 00334 }; 00335 00336 typedef RaveVector<dReal> Vector; 00337 00338 template <class T> 00339 inline RaveVector<T> operator* (float f, const RaveVector<T>& left) 00340 { 00341 RaveVector<T> v; 00342 v.x = (T)f * left.x; 00343 v.y = (T)f * left.y; 00344 v.z = (T)f * left.z; 00345 v.w = (T)f * left.w; 00346 return v; 00347 } 00348 00349 template <class T> 00350 inline RaveVector<T> operator* (double f, const RaveVector<T>& left) 00351 { 00352 RaveVector<T> v; 00353 v.x = (T)f * left.x; 00354 v.y = (T)f * left.y; 00355 v.z = (T)f * left.z; 00356 v.w = (T)f * left.w; 00357 return v; 00358 } 00359 00361 template <class T> 00362 class RaveTransform 00363 { 00364 public: 00365 RaveTransform() { rot.x = 1; } 00366 template <class U> RaveTransform(const RaveTransform<U>& t) { 00367 rot = t.rot; 00368 trans = t.trans; 00369 } 00370 template <class U> RaveTransform(const RaveVector<U>& rot, const RaveVector<U>& trans) : rot(rot), trans(trans) {} 00371 inline RaveTransform(const RaveTransformMatrix<T>& t); 00372 00373 void identity() { 00374 rot.x = 1; rot.y = rot.z = rot.w = 0; 00375 trans.x = trans.y = trans.z = 0; 00376 } 00377 00378 template <class U> 00379 inline void rotfromaxisangle(const RaveVector<U>& axis, U angle) { 00380 U sinang = (U)RaveSin(angle/2); 00381 rot.x = (U)RaveCos(angle/2); 00382 rot.y = axis.x*sinang; 00383 rot.z = axis.y*sinang; 00384 rot.w = axis.z*sinang; 00385 } 00386 00388 inline RaveVector<T> operator* (const RaveVector<T>& r) const { 00389 return trans + rotate(r); 00390 } 00391 00392 inline RaveVector<T> rotate(const RaveVector<T>& r) const { 00393 T xx = 2 * rot.y * rot.y; 00394 T xy = 2 * rot.y * rot.z; 00395 T xz = 2 * rot.y * rot.w; 00396 T xw = 2 * rot.y * rot.x; 00397 T yy = 2 * rot.z * rot.z; 00398 T yz = 2 * rot.z * rot.w; 00399 T yw = 2 * rot.z * rot.x; 00400 T zz = 2 * rot.w * rot.w; 00401 T zw = 2 * rot.w * rot.x; 00402 00403 RaveVector<T> v; 00404 v.x = (1-yy-zz) * r.x + (xy-zw) * r.y + (xz+yw)*r.z; 00405 v.y = (xy+zw) * r.x + (1-xx-zz) * r.y + (yz-xw)*r.z; 00406 v.z = (xz-yw) * r.x + (yz+xw) * r.y + (1-xx-yy)*r.z; 00407 return v; 00408 } 00409 00411 inline RaveTransform<T> operator* (const RaveTransform<T>& r) const { 00412 RaveTransform<T> t; 00413 t.trans = operator*(r.trans); 00414 t.rot.x = rot.x*r.rot.x - rot.y*r.rot.y - rot.z*r.rot.z - rot.w*r.rot.w; 00415 t.rot.y = rot.x*r.rot.y + rot.y*r.rot.x + rot.z*r.rot.w - rot.w*r.rot.z; 00416 t.rot.z = rot.x*r.rot.z + rot.z*r.rot.x + rot.w*r.rot.y - rot.y*r.rot.w; 00417 t.rot.w = rot.x*r.rot.w + rot.w*r.rot.x + rot.y*r.rot.z - rot.z*r.rot.y; 00418 00419 return t; 00420 } 00421 00422 inline RaveTransform<T>& operator*= (const RaveTransform<T>& right) { 00423 *this = operator*(right); 00424 return *this; 00425 } 00426 00427 inline RaveTransform<T> inverse() const { 00428 RaveTransform<T> inv; 00429 inv.rot.x = rot.x; 00430 inv.rot.y = -rot.y; 00431 inv.rot.z = -rot.z; 00432 inv.rot.w = -rot.w; 00433 00434 inv.trans = -inv.rotate(trans); 00435 return inv; 00436 } 00437 00438 template <class S, class U> friend std::basic_ostream<S>& operator<<(std::basic_ostream<S>& O, const RaveTransform<U>& v); 00439 template <class S, class U> friend std::basic_istream<S>& operator>>(std::basic_istream<S>& I, RaveTransform<U>& v); 00440 00441 RaveVector<T> rot, trans; 00442 }; 00443 00444 typedef RaveTransform<dReal> Transform; 00445 00447 template <class T> 00448 class RaveTransformMatrix 00449 { 00450 public: 00451 inline RaveTransformMatrix() { identity(); m[3] = m[7] = m[11] = 0; } 00452 template <class U> RaveTransformMatrix(const RaveTransformMatrix<U>& t) { 00453 // don't memcpy! 00454 m[0] = t.m[0]; m[1] = t.m[1]; m[2] = t.m[2]; m[3] = t.m[3]; 00455 m[4] = t.m[4]; m[5] = t.m[5]; m[6] = t.m[6]; m[7] = t.m[7]; 00456 m[8] = t.m[8]; m[9] = t.m[9]; m[10] = t.m[10]; m[11] = t.m[11]; 00457 trans = t.trans; 00458 } 00459 inline RaveTransformMatrix(const RaveTransform<T>& t); 00460 00461 inline void identity() { 00462 m[0] = 1; m[1] = 0; m[2] = 0; 00463 m[4] = 0; m[5] = 1; m[6] = 0; 00464 m[8] = 0; m[9] = 0; m[10] = 1; 00465 trans.x = trans.y = trans.z = 0; 00466 } 00467 00468 template <class U> 00469 inline void rotfromaxisangle(const RaveVector<U>& axis, U angle) { 00470 RaveVector<T> quat; 00471 U sinang = (U)RaveSin(angle/2); 00472 quat.x = (U)RaveCos(angle/2); 00473 quat.y = axis.x*sinang; 00474 quat.z = axis.y*sinang; 00475 quat.w = axis.z*sinang; 00476 rotfromquat(quat); 00477 } 00478 00479 template <class U> 00480 inline void rotfromquat(const RaveVector<U>& quat) { 00481 // q = (s,vx,vy,vz) 00482 T qq1 = 2*quat[1]*quat[1]; 00483 T qq2 = 2*quat[2]*quat[2]; 00484 T qq3 = 2*quat[3]*quat[3]; 00485 m[4*0+0] = 1 - qq2 - qq3; 00486 m[4*0+1] = 2*(quat[1]*quat[2] - quat[0]*quat[3]); 00487 m[4*0+2] = 2*(quat[1]*quat[3] + quat[0]*quat[2]); 00488 m[4*0+3] = 0; 00489 m[4*1+0] = 2*(quat[1]*quat[2] + quat[0]*quat[3]); 00490 m[4*1+1] = 1 - qq1 - qq3; 00491 m[4*1+2] = 2*(quat[2]*quat[3] - quat[0]*quat[1]); 00492 m[4*1+3] = 0; 00493 m[4*2+0] = 2*(quat[1]*quat[3] - quat[0]*quat[2]); 00494 m[4*2+1] = 2*(quat[2]*quat[3] + quat[0]*quat[1]); 00495 m[4*2+2] = 1 - qq1 - qq2; 00496 m[4*2+3] = 0; 00497 } 00498 00499 inline void rotfrommat(T m_00, T m_01, T m_02, T m_10, T m_11, T m_12, T m_20, T m_21, T m_22) { 00500 m[0] = m_00; m[1] = m_01; m[2] = m_02; m[3] = 0; 00501 m[4] = m_10; m[5] = m_11; m[6] = m_12; m[7] = 0; 00502 m[8] = m_20; m[9] = m_21; m[10] = m_22; m[11] = 0; 00503 } 00504 00505 inline T rot(int i, int j) const { 00506 assert( i >= 0 && i < 3 && j >= 0 && j < 3); 00507 return m[4*i+j]; 00508 } 00509 inline T& rot(int i, int j) { 00510 assert( i >= 0 && i < 3 && j >= 0 && j < 3); 00511 return m[4*i+j]; 00512 } 00513 00514 template <class U> 00515 inline RaveVector<T> operator* (const RaveVector<U>& r) const { 00516 RaveVector<T> v; 00517 v[0] = r[0] * m[0] + r[1] * m[1] + r[2] * m[2] + trans.x; 00518 v[1] = r[0] * m[4] + r[1] * m[5] + r[2] * m[6] + trans.y; 00519 v[2] = r[0] * m[8] + r[1] * m[9] + r[2] * m[10] + trans.z; 00520 return v; 00521 } 00522 00524 inline RaveTransformMatrix<T> operator* (const RaveTransformMatrix<T>& r) const { 00525 RaveTransformMatrix<T> t; 00526 mult3_s4(&t.m[0], &m[0], &r.m[0]); 00527 t.trans[0] = r.trans[0] * m[0] + r.trans[1] * m[1] + r.trans[2] * m[2] + trans.x; 00528 t.trans[1] = r.trans[0] * m[4] + r.trans[1] * m[5] + r.trans[2] * m[6] + trans.y; 00529 t.trans[2] = r.trans[0] * m[8] + r.trans[1] * m[9] + r.trans[2] * m[10] + trans.z; 00530 return t; 00531 } 00532 00533 inline RaveTransformMatrix<T> operator*= (const RaveTransformMatrix<T>& r) const { 00534 *this = *this * r; 00535 return *this; 00536 } 00537 00538 template <class U> 00539 inline RaveVector<U> rotate(const RaveVector<U>& r) const { 00540 RaveVector<U> v; 00541 v.x = r.x * m[0] + r.y * m[1] + r.z * m[2]; 00542 v.y = r.x * m[4] + r.y * m[5] + r.z * m[6]; 00543 v.z = r.x * m[8] + r.y * m[9] + r.z * m[10]; 00544 return v; 00545 } 00546 inline RaveTransformMatrix<T> inverse() const { 00547 RaveTransformMatrix<T> inv; 00548 inv3(m, inv.m, NULL, 4); 00549 inv.trans = -inv.rotate(trans); 00550 return inv; 00551 } 00552 00553 template <class U> 00554 inline void Extract(RaveVector<U>& right, RaveVector<U>& up, RaveVector<U>& dir, RaveVector<U>& pos) const { 00555 pos = trans; 00556 right.x = m[0]; up.x = m[1]; dir.x = m[2]; 00557 right.y = m[4]; up.y = m[5]; dir.y = m[6]; 00558 right.z = m[8]; up.z = m[9]; dir.z = m[10]; 00559 } 00560 00561 template <class S, class U> friend std::basic_ostream<S>& operator<<(std::basic_ostream<S>& O, const RaveTransformMatrix<U>& v); 00562 template <class S, class U> friend std::basic_istream<S>& operator>>(std::basic_istream<S>& I, RaveTransformMatrix<U>& v); 00563 00566 T m[12]; 00567 RaveVector<T> trans; 00568 }; 00569 typedef RaveTransformMatrix<dReal> TransformMatrix; 00570 00571 template <class T> 00572 RaveTransform<T>::RaveTransform(const RaveTransformMatrix<T>& t) 00573 { 00574 trans = t.trans; 00575 dReal tr,s; 00576 tr = t.m[4*0+0] + t.m[4*1+1] + t.m[4*2+2]; 00577 if (tr >= 0) { 00578 s = RaveSqrt(tr + 1); 00579 rot[0] = (dReal)(0.5) * s; 00580 s = (dReal)(0.5) * dRecip(s); 00581 rot[1] = (t.m[4*2+1] - t.m[4*1+2]) * s; 00582 rot[2] = (t.m[4*0+2] - t.m[4*2+0]) * s; 00583 rot[3] = (t.m[4*1+0] - t.m[4*0+1]) * s; 00584 } 00585 else { 00586 // find the largest diagonal element and jump to the appropriate case 00587 if (t.m[4*1+1] > t.m[4*0+0]) { 00588 if (t.m[4*2+2] > t.m[4*1+1]) goto case_2; 00589 goto case_1; 00590 } 00591 if (t.m[4*2+2] > t.m[4*0+0]) goto case_2; 00592 goto case_0; 00593 00594 case_0: 00595 s = RaveSqrt((t.m[4*0+0] - (t.m[4*1+1] + t.m[4*2+2])) + 1); 00596 rot[1] = (dReal)(0.5) * s; 00597 s = (dReal)(0.5) * dRecip(s); 00598 rot[2] = (t.m[4*0+1] + t.m[4*1+0]) * s; 00599 rot[3] = (t.m[4*2+0] + t.m[4*0+2]) * s; 00600 rot[0] = (t.m[4*2+1] - t.m[4*1+2]) * s; 00601 return; 00602 00603 case_1: 00604 s = RaveSqrt((t.m[4*1+1] - (t.m[4*2+2] + t.m[4*0+0])) + 1); 00605 rot[2] = (dReal)(0.5) * s; 00606 s = (dReal)(0.5) * dRecip(s); 00607 rot[3] = (t.m[4*1+2] + t.m[4*2+1]) * s; 00608 rot[1] = (t.m[4*0+1] + t.m[4*1+0]) * s; 00609 rot[0] = (t.m[4*0+2] - t.m[4*2+0]) * s; 00610 return; 00611 00612 case_2: 00613 s = RaveSqrt((t.m[4*2+2] - (t.m[4*0+0] + t.m[4*1+1])) + 1); 00614 rot[3] = (dReal)(0.5) * s; 00615 s = (dReal)(0.5) * dRecip(s); 00616 rot[1] = (t.m[4*2+0] + t.m[4*0+2]) * s; 00617 rot[2] = (t.m[4*1+2] + t.m[4*2+1]) * s; 00618 rot[0] = (t.m[4*1+0] - t.m[4*0+1]) * s; 00619 return; 00620 } 00621 } 00622 00623 template <class T> 00624 RaveTransformMatrix<T>::RaveTransformMatrix(const RaveTransform<T>& t) 00625 { 00626 rotfromquat(t.rot); 00627 trans = t.trans; 00628 00629 } 00630 00631 struct RAY 00632 { 00633 RAY() {} 00634 RAY(const Vector& _pos, const Vector& _dir) : pos(_pos), dir(_dir) {} 00635 Vector pos, dir; 00636 }; 00637 00638 struct AABB 00639 { 00640 AABB() {} 00641 AABB(const Vector& vpos, const Vector& vextents) : pos(vpos), extents(vextents) {} 00642 Vector pos, extents; 00643 }; 00644 00645 struct OBB 00646 { 00647 Vector right, up, dir, pos, extents; 00648 }; 00649 00650 struct TRIANGLE 00651 { 00652 TRIANGLE() {} 00653 TRIANGLE(const Vector& v1, const Vector& v2, const Vector& v3) : v1(v1), v2(v2), v3(v3) {} 00654 ~TRIANGLE() {} 00655 00656 Vector v1, v2, v3; 00657 00658 const Vector& operator[](int i) const { return (&v1)[i]; } 00659 Vector& operator[](int i) { return (&v1)[i]; } 00660 00662 inline Vector ComputeNormal() { 00663 Vector normal; 00664 cross3(normal, v2-v1, v3-v1); 00665 return normal; 00666 } 00667 }; 00668 00669 00671 inline dReal* transcoord3(dReal* pfout, const TransformMatrix* pmat, const dReal* pf); 00672 00674 inline dReal* transnorm3(dReal* pfout, const TransformMatrix* pmat, const dReal* pf); 00675 00676 // Routines made for 3D graphics that deal with 3 or 4 dim algebra structures 00677 // Functions with postfix 3 are for 3x3 operations, etc 00678 00679 // all fns return pfout on success or NULL on failure 00680 // results and arguments can share pointers 00681 00682 00684 // More complex ops that deal with arbitrary matrices // 00686 00687 // extract eigen values and vectors from a 2x2 matrix and returns true if all values are real 00688 // returned eigen vectors are normalized 00689 inline bool eig2(const dReal* pfmat, dReal* peigs, dReal& fv1x, dReal& fv1y, dReal& fv2x, dReal& fv2y); 00690 00691 // Simple routines for linear algebra algorithms // 00692 int CubicRoots (double c0, double c1, double c2, double *r0, double *r1, double *r2); 00693 template <class T, class S> void Tridiagonal3 (S* mat, T* diag, T* subd); 00694 bool QLAlgorithm3 (float* m_aafEntry, float* afDiag, float* afSubDiag); 00695 bool QLAlgorithm3 (double* m_aafEntry, double* afDiag, double* afSubDiag); 00696 00697 void EigenSymmetric3(dReal* fCovariance, dReal* eval, dReal* fAxes); 00698 00699 void GetCovarBasisVectors(dReal fCovariance[3][3], Vector* vRight, Vector* vUp, Vector* vDir); 00700 00704 void svd3(const dReal* A, dReal* U, dReal* D, dReal* V); 00705 00706 // first root returned is always >= second, roots are defined if the quadratic doesn't have real solutions 00707 void QuadraticSolver(dReal* pfQuadratic, dReal* pfRoots); 00708 00709 int insideQuadrilateral(const Vector* p0,const Vector* p1, const Vector* p2,const Vector* p3); 00710 int insideTriangle(const Vector* p0, const Vector* p1, const Vector* p2); 00711 00712 bool RayOBBTest(const RAY& r, const OBB& obb); 00713 dReal DistVertexOBBSq(const Vector& v, const OBB& o); 00714 00715 template <class T> int Min(T* pts, int stride, int numPts); // returns the index, stride in units of T 00716 template <class T> int Max(T* pts, int stride, int numPts); // returns the index 00717 00718 // multiplies a matrix by a scalar 00719 template <class T> inline void mult(T* pf, T fa, int r); 00720 00721 // multiplies a r1xc1 by c1xc2 matrix into pfres, if badd is true adds the result to pfres 00722 // does not handle cases where pfres is equal to pf1 or pf2, use multtox for those cases 00723 template <class T, class R, class S> 00724 inline S* mult(T* pf1, R* pf2, int r1, int c1, int c2, S* pfres, bool badd = false); 00725 00726 // pf1 is transposed before mult 00727 // rows of pf2 must equal rows of pf1 00728 // pfres will be c1xc2 matrix 00729 template <class T, class R, class S> 00730 inline S* multtrans(T* pf1, R* pf2, int r1, int c1, int c2, S* pfres, bool badd = false); 00731 00732 // pf2 is transposed before mult 00733 // the columns of both matrices must be the same and equal to c1 00734 // r2 is the number of rows in pf2 00735 // pfres must be an r1xr2 matrix 00736 template <class T, class R, class S> 00737 inline S* multtrans_to2(T* pf1, R* pf2, int r1, int c1, int r2, S* pfres, bool badd = false); 00738 00739 // multiplies rxc matrix pf1 and cxc matrix pf2 and stores the result in pf1, 00740 // the function needs a temporary buffer the size of c doubles, if pftemp == NULL, 00741 // the function will allocate the necessary memory, otherwise pftemp should be big 00742 // enough to store all the entries 00743 template <class T> inline T* multto1(T* pf1, T* pf2, int r1, int c1, T* pftemp = NULL); 00744 00745 // same as multto1 except stores the result in pf2, pf1 has to be an r2xr2 matrix 00746 // pftemp must be of size r2 if not NULL 00747 template <class T, class S> inline T* multto2(T* pf1, S* pf2, int r2, int c2, S* pftemp = NULL); 00748 00749 // add pf1 + pf2 and store in pf1 00750 template <class T> inline void sub(T* pf1, T* pf2, int r); 00751 template <class T> inline T normsqr(const T* pf1, int r); 00752 template <class T> inline T lengthsqr(const T* pf1, const T* pf2, int length); 00753 template <class T> inline T dot(T* pf1, T* pf2, int length); 00754 00755 template <class T> inline T sum(T* pf, int length); 00756 00757 // takes the inverse of the 3x3 matrix pf and stores it into pfres, returns true if matrix is invertible 00758 template <class T> inline bool inv2(T* pf, T* pfres); 00759 00761 // Function Definitions 00763 bool eig2(const dReal* pfmat, dReal* peigs, dReal& fv1x, dReal& fv1y, dReal& fv2x, dReal& fv2y) 00764 { 00765 // x^2 + bx + c 00766 dReal a, b, c, d; 00767 b = -(pfmat[0] + pfmat[3]); 00768 c = pfmat[0] * pfmat[3] - pfmat[1] * pfmat[2]; 00769 d = b * b - 4.0f * c + 1e-16f; 00770 00771 if( d < 0 ) return false; 00772 if( d < 1e-16f ) { 00773 a = -0.5f * b; 00774 peigs[0] = a; peigs[1] = a; 00775 fv1x = pfmat[1]; fv1y = a - pfmat[0]; 00776 c = 1 / RaveSqrt(fv1x*fv1x + fv1y*fv1y); 00777 fv1x *= c; fv1y *= c; 00778 fv2x = -fv1y; fv2y = fv1x; 00779 return true; 00780 } 00781 00782 // two roots 00783 d = RaveSqrt(d); 00784 a = -0.5f * (b + d); 00785 peigs[0] = a; 00786 fv1x = pfmat[1]; fv1y = a-pfmat[0]; 00787 c = 1 / RaveSqrt(fv1x*fv1x + fv1y*fv1y); 00788 fv1x *= c; fv1y *= c; 00789 00790 a += d; 00791 peigs[1] = a; 00792 fv2x = pfmat[1]; fv2y = a-pfmat[0]; 00793 c = 1 / RaveSqrt(fv2x*fv2x + fv2y*fv2y); 00794 fv2x *= c; fv2y *= c; 00795 return true; 00796 } 00797 00798 // returns the number of real roots, fills r1 and r2 with the answers 00799 template <class T> 00800 inline int solvequad(T a, T b, T c, T& r1, T& r2) 00801 { 00802 T d = b * b - (T)4 * c * a + (T)1e-16; 00803 00804 if( d < 0 ) return 0; 00805 00806 if( d < (T)1e-16 ) { 00807 r1 = r2 = (T)-0.5 * b / a; 00808 return 1; 00809 } 00810 00811 // two roots 00812 d = RaveSqrt(d); 00813 r1 = (T)-0.5 * (b + d) / a; 00814 r2 = r1 + d/a; 00815 return 2; 00816 } 00817 00818 //#ifndef TI_USING_IPP 00819 00820 #define MULT3(stride) { \ 00821 pfres2[0*stride+0] = pf1[0*stride+0]*pf2[0*stride+0]+pf1[0*stride+1]*pf2[1*stride+0]+pf1[0*stride+2]*pf2[2*stride+0]; \ 00822 pfres2[0*stride+1] = pf1[0*stride+0]*pf2[0*stride+1]+pf1[0*stride+1]*pf2[1*stride+1]+pf1[0*stride+2]*pf2[2*stride+1]; \ 00823 pfres2[0*stride+2] = pf1[0*stride+0]*pf2[0*stride+2]+pf1[0*stride+1]*pf2[1*stride+2]+pf1[0*stride+2]*pf2[2*stride+2]; \ 00824 pfres2[1*stride+0] = pf1[1*stride+0]*pf2[0*stride+0]+pf1[1*stride+1]*pf2[1*stride+0]+pf1[1*stride+2]*pf2[2*stride+0]; \ 00825 pfres2[1*stride+1] = pf1[1*stride+0]*pf2[0*stride+1]+pf1[1*stride+1]*pf2[1*stride+1]+pf1[1*stride+2]*pf2[2*stride+1]; \ 00826 pfres2[1*stride+2] = pf1[1*stride+0]*pf2[0*stride+2]+pf1[1*stride+1]*pf2[1*stride+2]+pf1[1*stride+2]*pf2[2*stride+2]; \ 00827 pfres2[2*stride+0] = pf1[2*stride+0]*pf2[0*stride+0]+pf1[2*stride+1]*pf2[1*stride+0]+pf1[2*stride+2]*pf2[2*stride+0]; \ 00828 pfres2[2*stride+1] = pf1[2*stride+0]*pf2[0*stride+1]+pf1[2*stride+1]*pf2[1*stride+1]+pf1[2*stride+2]*pf2[2*stride+1]; \ 00829 pfres2[2*stride+2] = pf1[2*stride+0]*pf2[0*stride+2]+pf1[2*stride+1]*pf2[1*stride+2]+pf1[2*stride+2]*pf2[2*stride+2]; \ 00830 } 00831 00833 template <class T> 00834 inline T* _mult3_s4(T* pfres, const T* pf1, const T* pf2) 00835 { 00836 assert( pf1 != NULL && pf2 != NULL && pfres != NULL ); 00837 00838 T* pfres2; 00839 if( pfres == pf1 || pfres == pf2 ) pfres2 = (T*)alloca(12 * sizeof(T)); 00840 else pfres2 = pfres; 00841 00842 MULT3(4) 00843 00844 if( pfres2 != pfres ) memcpy(pfres, pfres2, 12*sizeof(T)); 00845 00846 return pfres; 00847 } 00848 00850 template <class T> 00851 inline T* _mult3_s3(T* pfres, const T* pf1, const T* pf2) 00852 { 00853 assert( pf1 != NULL && pf2 != NULL && pfres != NULL ); 00854 00855 T* pfres2; 00856 if( pfres == pf1 || pfres == pf2 ) pfres2 = (T*)alloca(9 * sizeof(T)); 00857 else pfres2 = pfres; 00858 00859 MULT3(3) 00860 00861 if( pfres2 != pfres ) memcpy(pfres, pfres2, 9*sizeof(T)); 00862 00863 return pfres; 00864 } 00865 00866 // mult4 00867 template <class T> 00868 inline T* _mult4(T* pfres, const T* p1, const T* p2) 00869 { 00870 assert( pfres != NULL && p1 != NULL && p2 != NULL ); 00871 00872 T* pfres2; 00873 if( pfres == p1 || pfres == p2 ) pfres2 = (T*)alloca(16 * sizeof(T)); 00874 else pfres2 = pfres; 00875 00876 pfres2[0*4+0] = p1[0*4+0]*p2[0*4+0] + p1[0*4+1]*p2[1*4+0] + p1[0*4+2]*p2[2*4+0] + p1[0*4+3]*p2[3*4+0]; 00877 pfres2[0*4+1] = p1[0*4+0]*p2[0*4+1] + p1[0*4+1]*p2[1*4+1] + p1[0*4+2]*p2[2*4+1] + p1[0*4+3]*p2[3*4+1]; 00878 pfres2[0*4+2] = p1[0*4+0]*p2[0*4+2] + p1[0*4+1]*p2[1*4+2] + p1[0*4+2]*p2[2*4+2] + p1[0*4+3]*p2[3*4+2]; 00879 pfres2[0*4+3] = p1[0*4+0]*p2[0*4+3] + p1[0*4+1]*p2[1*4+3] + p1[0*4+2]*p2[2*4+3] + p1[0*4+3]*p2[3*4+3]; 00880 00881 pfres2[1*4+0] = p1[1*4+0]*p2[0*4+0] + p1[1*4+1]*p2[1*4+0] + p1[1*4+2]*p2[2*4+0] + p1[1*4+3]*p2[3*4+0]; 00882 pfres2[1*4+1] = p1[1*4+0]*p2[0*4+1] + p1[1*4+1]*p2[1*4+1] + p1[1*4+2]*p2[2*4+1] + p1[1*4+3]*p2[3*4+1]; 00883 pfres2[1*4+2] = p1[1*4+0]*p2[0*4+2] + p1[1*4+1]*p2[1*4+2] + p1[1*4+2]*p2[2*4+2] + p1[1*4+3]*p2[3*4+2]; 00884 pfres2[1*4+3] = p1[1*4+0]*p2[0*4+3] + p1[1*4+1]*p2[1*4+3] + p1[1*4+2]*p2[2*4+3] + p1[1*4+3]*p2[3*4+3]; 00885 00886 pfres2[2*4+0] = p1[2*4+0]*p2[0*4+0] + p1[2*4+1]*p2[1*4+0] + p1[2*4+2]*p2[2*4+0] + p1[2*4+3]*p2[3*4+0]; 00887 pfres2[2*4+1] = p1[2*4+0]*p2[0*4+1] + p1[2*4+1]*p2[1*4+1] + p1[2*4+2]*p2[2*4+1] + p1[2*4+3]*p2[3*4+1]; 00888 pfres2[2*4+2] = p1[2*4+0]*p2[0*4+2] + p1[2*4+1]*p2[1*4+2] + p1[2*4+2]*p2[2*4+2] + p1[2*4+3]*p2[3*4+2]; 00889 pfres2[2*4+3] = p1[2*4+0]*p2[0*4+3] + p1[2*4+1]*p2[1*4+3] + p1[2*4+2]*p2[2*4+3] + p1[2*4+3]*p2[3*4+3]; 00890 00891 pfres2[3*4+0] = p1[3*4+0]*p2[0*4+0] + p1[3*4+1]*p2[1*4+0] + p1[3*4+2]*p2[2*4+0] + p1[3*4+3]*p2[3*4+0]; 00892 pfres2[3*4+1] = p1[3*4+0]*p2[0*4+1] + p1[3*4+1]*p2[1*4+1] + p1[3*4+2]*p2[2*4+1] + p1[3*4+3]*p2[3*4+1]; 00893 pfres2[3*4+2] = p1[3*4+0]*p2[0*4+2] + p1[3*4+1]*p2[1*4+2] + p1[3*4+2]*p2[2*4+2] + p1[3*4+3]*p2[3*4+2]; 00894 pfres2[3*4+3] = p1[3*4+0]*p2[0*4+3] + p1[3*4+1]*p2[1*4+3] + p1[3*4+2]*p2[2*4+3] + p1[3*4+3]*p2[3*4+3]; 00895 00896 if( pfres != pfres2 ) memcpy(pfres, pfres2, sizeof(T)*16); 00897 return pfres; 00898 } 00899 00900 template <class T> 00901 inline T* _multtrans3(T* pfres, const T* pf1, const T* pf2) 00902 { 00903 T* pfres2; 00904 if( pfres == pf1 ) pfres2 = (T*)alloca(9 * sizeof(T)); 00905 else pfres2 = pfres; 00906 00907 pfres2[0] = pf1[0]*pf2[0]+pf1[3]*pf2[3]+pf1[6]*pf2[6]; 00908 pfres2[1] = pf1[0]*pf2[1]+pf1[3]*pf2[4]+pf1[6]*pf2[7]; 00909 pfres2[2] = pf1[0]*pf2[2]+pf1[3]*pf2[5]+pf1[6]*pf2[8]; 00910 00911 pfres2[3] = pf1[1]*pf2[0]+pf1[4]*pf2[3]+pf1[7]*pf2[6]; 00912 pfres2[4] = pf1[1]*pf2[1]+pf1[4]*pf2[4]+pf1[7]*pf2[7]; 00913 pfres2[5] = pf1[1]*pf2[2]+pf1[4]*pf2[5]+pf1[7]*pf2[8]; 00914 00915 pfres2[6] = pf1[2]*pf2[0]+pf1[5]*pf2[3]+pf1[8]*pf2[6]; 00916 pfres2[7] = pf1[2]*pf2[1]+pf1[5]*pf2[4]+pf1[8]*pf2[7]; 00917 pfres2[8] = pf1[2]*pf2[2]+pf1[5]*pf2[5]+pf1[8]*pf2[8]; 00918 00919 if( pfres2 != pfres ) memcpy(pfres, pfres2, 9*sizeof(T)); 00920 00921 return pfres; 00922 } 00923 00924 template <class T> 00925 inline T* _multtrans4(T* pfres, const T* pf1, const T* pf2) 00926 { 00927 T* pfres2; 00928 if( pfres == pf1 ) pfres2 = (T*)alloca(16 * sizeof(T)); 00929 else pfres2 = pfres; 00930 00931 for(int i = 0; i < 4; ++i) { 00932 for(int j = 0; j < 4; ++j) { 00933 pfres[4*i+j] = pf1[i] * pf2[j] + pf1[i+4] * pf2[j+4] + pf1[i+8] * pf2[j+8] + pf1[i+12] * pf2[j+12]; 00934 } 00935 } 00936 00937 return pfres; 00938 } 00939 00940 //generate a random quaternion 00941 inline Vector GetRandomQuat(void) 00942 { 00943 Vector q; 00944 00945 while(1) { 00946 q.x = -1 + 2*(rand()/((dReal)RAND_MAX)); 00947 q.y = -1 + 2*(rand()/((dReal)RAND_MAX)); 00948 q.z = -1 + 2*(rand()/((dReal)RAND_MAX)); 00949 q.w = -1 + 2*(rand()/((dReal)RAND_MAX)); 00950 00951 dReal norm = q.lengthsqr4(); 00952 if(norm <= 1) { 00953 q = q * (1 / RaveSqrt(norm)); 00954 break; 00955 } 00956 } 00957 00958 return q; 00959 } 00960 00961 template <class T> 00962 inline RaveVector<T> AxisAngle2Quat(const RaveVector<T>& rotaxis, T angle) 00963 { 00964 angle *= (T)0.5; 00965 T fsin = RaveSin(angle); 00966 return RaveVector<T>(RaveCos(angle), rotaxis.x*fsin, rotaxis.y * fsin, rotaxis.z * fsin); 00967 } 00968 00969 template <class T> 00970 inline RaveVector<T> dQSlerp(const RaveVector<T>& qa, const RaveVector<T>& qb, T t) 00971 { 00972 // quaternion to return 00973 RaveVector<T> qm; 00974 00975 // Calculate angle between them. 00976 T cosHalfTheta = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z; 00977 // if qa=qb or qa=-qb then theta = 0 and we can return qa 00978 if (RaveFabs(cosHalfTheta) >= 1.0){ 00979 qm.w = qa.w;qm.x = qa.x;qm.y = qa.y;qm.z = qa.z; 00980 return qm; 00981 } 00982 // Calculate temporary values. 00983 T halfTheta = RaveAcos(cosHalfTheta); 00984 T sinHalfTheta = RaveSqrt(1 - cosHalfTheta*cosHalfTheta); 00985 // if theta = 180 degrees then result is not fully defined 00986 // we could rotate around any axis normal to qa or qb 00987 if (RaveFabs(sinHalfTheta) < 0.0001f){ // fabs is floating point absolute 00988 qm.w = (qa.w * 0.5f + qb.w * 0.5f); 00989 qm.x = (qa.x * 0.5f + qb.x * 0.5f); 00990 qm.y = (qa.y * 0.5f + qb.y * 0.5f); 00991 qm.z = (qa.z * 0.5f + qb.z * 0.5f); 00992 return qm; 00993 } 00994 00995 T ratioA = RaveSin((1 - t) * halfTheta) / sinHalfTheta; 00996 T ratioB = RaveSin(t * halfTheta) / sinHalfTheta; 00997 //calculate Quaternion. 00998 qm.w = (qa.w * ratioA + qb.w * ratioB); 00999 qm.x = (qa.x * ratioA + qb.x * ratioB); 01000 qm.y = (qa.y * ratioA + qb.y * ratioB); 01001 qm.z = (qa.z * ratioA + qb.z * ratioB); 01002 return qm; 01003 } 01004 01006 template <class T> inline T matrixdet3(const T* pf, int stride) 01007 { 01008 return pf[0*stride+2] * (pf[1*stride + 0] * pf[2*stride + 1] - pf[1*stride + 1] * pf[2*stride + 0]) + 01009 pf[1*stride+2] * (pf[0*stride + 1] * pf[2*stride + 0] - pf[0*stride + 0] * pf[2*stride + 1]) + 01010 pf[2*stride+2] * (pf[0*stride + 0] * pf[1*stride + 1] - pf[0*stride + 1] * pf[1*stride + 0]); 01011 } 01012 01015 template <class T> 01016 inline T* _inv3(const T* pf, T* pfres, T* pfdet, int stride) 01017 { 01018 T* pfres2; 01019 if( pfres == pf ) pfres2 = (T*)alloca(3 * stride * sizeof(T)); 01020 else pfres2 = pfres; 01021 01022 // inverse = C^t / det(pf) where C is the matrix of coefficients 01023 01024 // calc C^t 01025 pfres2[0*stride + 0] = pf[1*stride + 1] * pf[2*stride + 2] - pf[1*stride + 2] * pf[2*stride + 1]; 01026 pfres2[0*stride + 1] = pf[0*stride + 2] * pf[2*stride + 1] - pf[0*stride + 1] * pf[2*stride + 2]; 01027 pfres2[0*stride + 2] = pf[0*stride + 1] * pf[1*stride + 2] - pf[0*stride + 2] * pf[1*stride + 1]; 01028 pfres2[1*stride + 0] = pf[1*stride + 2] * pf[2*stride + 0] - pf[1*stride + 0] * pf[2*stride + 2]; 01029 pfres2[1*stride + 1] = pf[0*stride + 0] * pf[2*stride + 2] - pf[0*stride + 2] * pf[2*stride + 0]; 01030 pfres2[1*stride + 2] = pf[0*stride + 2] * pf[1*stride + 0] - pf[0*stride + 0] * pf[1*stride + 2]; 01031 pfres2[2*stride + 0] = pf[1*stride + 0] * pf[2*stride + 1] - pf[1*stride + 1] * pf[2*stride + 0]; 01032 pfres2[2*stride + 1] = pf[0*stride + 1] * pf[2*stride + 0] - pf[0*stride + 0] * pf[2*stride + 1]; 01033 pfres2[2*stride + 2] = pf[0*stride + 0] * pf[1*stride + 1] - pf[0*stride + 1] * pf[1*stride + 0]; 01034 01035 T fdet = pf[0*stride + 2] * pfres2[2*stride + 0] + pf[1*stride + 2] * pfres2[2*stride + 1] + 01036 pf[2*stride + 2] * pfres2[2*stride + 2]; 01037 01038 if( pfdet != NULL ) 01039 pfdet[0] = fdet; 01040 01041 if( fabs(fdet) < 1e-12 ) { 01042 return NULL; 01043 } 01044 01045 fdet = 1 / fdet; 01046 //if( pfdet != NULL ) *pfdet = fdet; 01047 01048 if( pfres != pf ) { 01049 pfres[0*stride+0] *= fdet; pfres[0*stride+1] *= fdet; pfres[0*stride+2] *= fdet; 01050 pfres[1*stride+0] *= fdet; pfres[1*stride+1] *= fdet; pfres[1*stride+2] *= fdet; 01051 pfres[2*stride+0] *= fdet; pfres[2*stride+1] *= fdet; pfres[2*stride+2] *= fdet; 01052 return pfres; 01053 } 01054 01055 pfres[0*stride+0] = pfres2[0*stride+0] * fdet; 01056 pfres[0*stride+1] = pfres2[0*stride+1] * fdet; 01057 pfres[0*stride+2] = pfres2[0*stride+2] * fdet; 01058 pfres[1*stride+0] = pfres2[1*stride+0] * fdet; 01059 pfres[1*stride+1] = pfres2[1*stride+1] * fdet; 01060 pfres[1*stride+2] = pfres2[1*stride+2] * fdet; 01061 pfres[2*stride+0] = pfres2[2*stride+0] * fdet; 01062 pfres[2*stride+1] = pfres2[2*stride+1] * fdet; 01063 pfres[2*stride+2] = pfres2[2*stride+2] * fdet; 01064 return pfres; 01065 } 01066 01067 // inverse if 92 mults and 39 adds 01068 template <class T> 01069 inline T* _inv4(const T* pf, T* pfres) 01070 { 01071 T* pfres2; 01072 if( pfres == pf ) pfres2 = (T*)alloca(16 * sizeof(T)); 01073 else pfres2 = pfres; 01074 01075 // inverse = C^t / det(pf) where C is the matrix of coefficients 01076 01077 // calc C^t 01078 01079 // determinants of all possibel 2x2 submatrices formed by last two rows 01080 T fd0, fd1, fd2; 01081 T f1, f2, f3; 01082 fd0 = pf[2*4 + 0] * pf[3*4 + 1] - pf[2*4 + 1] * pf[3*4 + 0]; 01083 fd1 = pf[2*4 + 1] * pf[3*4 + 2] - pf[2*4 + 2] * pf[3*4 + 1]; 01084 fd2 = pf[2*4 + 2] * pf[3*4 + 3] - pf[2*4 + 3] * pf[3*4 + 2]; 01085 01086 f1 = pf[2*4 + 1] * pf[3*4 + 3] - pf[2*4 + 3] * pf[3*4 + 1]; 01087 f2 = pf[2*4 + 0] * pf[3*4 + 3] - pf[2*4 + 3] * pf[3*4 + 0]; 01088 f3 = pf[2*4 + 0] * pf[3*4 + 2] - pf[2*4 + 2] * pf[3*4 + 0]; 01089 01090 pfres2[0*4 + 0] = pf[1*4 + 1] * fd2 - pf[1*4 + 2] * f1 + pf[1*4 + 3] * fd1; 01091 pfres2[0*4 + 1] = -(pf[0*4 + 1] * fd2 - pf[0*4 + 2] * f1 + pf[0*4 + 3] * fd1); 01092 01093 pfres2[1*4 + 0] = -(pf[1*4 + 0] * fd2 - pf[1*4 + 2] * f2 + pf[1*4 + 3] * f3); 01094 pfres2[1*4 + 1] = pf[0*4 + 0] * fd2 - pf[0*4 + 2] * f2 + pf[0*4 + 3] * f3; 01095 01096 pfres2[2*4 + 0] = pf[1*4 + 0] * f1 - pf[1*4 + 1] * f2 + pf[1*4 + 3] * fd0; 01097 pfres2[2*4 + 1] = -(pf[0*4 + 0] * f1 - pf[0*4 + 1] * f2 + pf[0*4 + 3] * fd0); 01098 01099 pfres2[3*4 + 0] = -(pf[1*4 + 0] * fd1 - pf[1*4 + 1] * f3 + pf[1*4 + 2] * fd0); 01100 pfres2[3*4 + 1] = pf[0*4 + 0] * fd1 - pf[0*4 + 1] * f3 + pf[0*4 + 2] * fd0; 01101 01102 // determinants of first 2 rows of 4x4 matrix 01103 fd0 = pf[0*4 + 0] * pf[1*4 + 1] - pf[0*4 + 1] * pf[1*4 + 0]; 01104 fd1 = pf[0*4 + 1] * pf[1*4 + 2] - pf[0*4 + 2] * pf[1*4 + 1]; 01105 fd2 = pf[0*4 + 2] * pf[1*4 + 3] - pf[0*4 + 3] * pf[1*4 + 2]; 01106 01107 f1 = pf[0*4 + 1] * pf[1*4 + 3] - pf[0*4 + 3] * pf[1*4 + 1]; 01108 f2 = pf[0*4 + 0] * pf[1*4 + 3] - pf[0*4 + 3] * pf[1*4 + 0]; 01109 f3 = pf[0*4 + 0] * pf[1*4 + 2] - pf[0*4 + 2] * pf[1*4 + 0]; 01110 01111 pfres2[0*4 + 2] = pf[3*4 + 1] * fd2 - pf[3*4 + 2] * f1 + pf[3*4 + 3] * fd1; 01112 pfres2[0*4 + 3] = -(pf[2*4 + 1] * fd2 - pf[2*4 + 2] * f1 + pf[2*4 + 3] * fd1); 01113 01114 pfres2[1*4 + 2] = -(pf[3*4 + 0] * fd2 - pf[3*4 + 2] * f2 + pf[3*4 + 3] * f3); 01115 pfres2[1*4 + 3] = pf[2*4 + 0] * fd2 - pf[2*4 + 2] * f2 + pf[2*4 + 3] * f3; 01116 01117 pfres2[2*4 + 2] = pf[3*4 + 0] * f1 - pf[3*4 + 1] * f2 + pf[3*4 + 3] * fd0; 01118 pfres2[2*4 + 3] = -(pf[2*4 + 0] * f1 - pf[2*4 + 1] * f2 + pf[2*4 + 3] * fd0); 01119 01120 pfres2[3*4 + 2] = -(pf[3*4 + 0] * fd1 - pf[3*4 + 1] * f3 + pf[3*4 + 2] * fd0); 01121 pfres2[3*4 + 3] = pf[2*4 + 0] * fd1 - pf[2*4 + 1] * f3 + pf[2*4 + 2] * fd0; 01122 01123 T fdet = pf[0*4 + 3] * pfres2[3*4 + 0] + pf[1*4 + 3] * pfres2[3*4 + 1] + 01124 pf[2*4 + 3] * pfres2[3*4 + 2] + pf[3*4 + 3] * pfres2[3*4 + 3]; 01125 01126 if( fabs(fdet) < 1e-9) return NULL; 01127 01128 fdet = 1 / fdet; 01129 //if( pfdet != NULL ) *pfdet = fdet; 01130 01131 if( pfres2 == pfres ) { 01132 mult(pfres, fdet, 16); 01133 return pfres; 01134 } 01135 01136 int i = 0; 01137 while(i < 16) { 01138 pfres[i] = pfres2[i] * fdet; 01139 ++i; 01140 } 01141 01142 return pfres; 01143 } 01144 01145 template <class T> 01146 inline T* _transpose3(const T* pf, T* pfres) 01147 { 01148 assert( pf != NULL && pfres != NULL ); 01149 01150 if( pf == pfres ) { 01151 rswap(pfres[1], pfres[3]); 01152 rswap(pfres[2], pfres[6]); 01153 rswap(pfres[5], pfres[7]); 01154 return pfres; 01155 } 01156 01157 pfres[0] = pf[0]; pfres[1] = pf[3]; pfres[2] = pf[6]; 01158 pfres[3] = pf[1]; pfres[4] = pf[4]; pfres[5] = pf[7]; 01159 pfres[6] = pf[2]; pfres[7] = pf[5]; pfres[8] = pf[8]; 01160 01161 return pfres; 01162 } 01163 01164 template <class T> 01165 inline T* _transpose4(const T* pf, T* pfres) 01166 { 01167 assert( pf != NULL && pfres != NULL ); 01168 01169 if( pf == pfres ) { 01170 rswap(pfres[1], pfres[4]); 01171 rswap(pfres[2], pfres[8]); 01172 rswap(pfres[3], pfres[12]); 01173 rswap(pfres[6], pfres[9]); 01174 rswap(pfres[7], pfres[13]); 01175 rswap(pfres[11], pfres[15]); 01176 return pfres; 01177 } 01178 01179 pfres[0] = pf[0]; pfres[1] = pf[4]; pfres[2] = pf[8]; pfres[3] = pf[12]; 01180 pfres[4] = pf[1]; pfres[5] = pf[5]; pfres[6] = pf[9]; pfres[7] = pf[13]; 01181 pfres[8] = pf[2]; pfres[9] = pf[6]; pfres[10] = pf[10]; pfres[11] = pf[14]; 01182 pfres[12] = pf[3]; pfres[13] = pf[7]; pfres[14] = pf[11]; pfres[15] = pf[15]; 01183 return pfres; 01184 } 01185 01186 template <class T> 01187 inline T _dot2(const T* pf1, const T* pf2) 01188 { 01189 assert( pf1 != NULL && pf2 != NULL ); 01190 return pf1[0]*pf2[0] + pf1[1]*pf2[1]; 01191 } 01192 01193 template <class T> 01194 inline T _dot3(const T* pf1, const T* pf2) 01195 { 01196 assert( pf1 != NULL && pf2 != NULL ); 01197 return pf1[0]*pf2[0] + pf1[1]*pf2[1] + pf1[2]*pf2[2]; 01198 } 01199 01200 template <class T> 01201 inline T _dot4(const T* pf1, const T* pf2) 01202 { 01203 assert( pf1 != NULL && pf2 != NULL ); 01204 return pf1[0]*pf2[0] + pf1[1]*pf2[1] + pf1[2]*pf2[2] + pf1[3] * pf2[3]; 01205 } 01206 01207 template <class T> 01208 inline T _lengthsqr2(const T* pf) 01209 { 01210 assert( pf != NULL ); 01211 return pf[0] * pf[0] + pf[1] * pf[1]; 01212 } 01213 01214 template <class T> 01215 inline T _lengthsqr3(const T* pf) 01216 { 01217 assert( pf != NULL ); 01218 return pf[0] * pf[0] + pf[1] * pf[1] + pf[2] * pf[2]; 01219 } 01220 01221 template <class T> 01222 inline T _lengthsqr4(const T* pf) 01223 { 01224 assert( pf != NULL ); 01225 return pf[0] * pf[0] + pf[1] * pf[1] + pf[2] * pf[2] + pf[3] * pf[3]; 01226 } 01227 01228 template <class T> 01229 inline T* _normalize2(T* pfout, const T* pf) 01230 { 01231 assert(pf != NULL); 01232 01233 T f = pf[0]*pf[0] + pf[1]*pf[1]; 01234 f = 1 / RaveSqrt(f); 01235 pfout[0] = pf[0] * f; 01236 pfout[1] = pf[1] * f; 01237 01238 return pfout; 01239 } 01240 01241 template <class T> 01242 inline T* _normalize3(T* pfout, const T* pf) 01243 { 01244 assert(pf != NULL); 01245 01246 T f = pf[0]*pf[0] + pf[1]*pf[1] + pf[2]*pf[2]; 01247 01248 f = 1 / RaveSqrt(f); 01249 pfout[0] = pf[0] * f; 01250 pfout[1] = pf[1] * f; 01251 pfout[2] = pf[2] * f; 01252 01253 return pfout; 01254 } 01255 01256 template <class T> 01257 inline T* _normalize4(T* pfout, const T* pf) 01258 { 01259 assert(pf != NULL); 01260 01261 T f = pf[0]*pf[0] + pf[1]*pf[1] + pf[2]*pf[2] + pf[3]*pf[3]; 01262 01263 f = 1 / RaveSqrt(f); 01264 pfout[0] = pf[0] * f; 01265 pfout[1] = pf[1] * f; 01266 pfout[2] = pf[2] * f; 01267 pfout[3] = pf[3] * f; 01268 01269 return pfout; 01270 } 01271 01272 template <class T> 01273 inline T* _cross3(T* pfout, const T* pf1, const T* pf2) 01274 { 01275 assert( pfout != NULL && pf1 != NULL && pf2 != NULL ); 01276 01277 T temp[3]; 01278 temp[0] = pf1[1] * pf2[2] - pf1[2] * pf2[1]; 01279 temp[1] = pf1[2] * pf2[0] - pf1[0] * pf2[2]; 01280 temp[2] = pf1[0] * pf2[1] - pf1[1] * pf2[0]; 01281 01282 pfout[0] = temp[0]; pfout[1] = temp[1]; pfout[2] = temp[2]; 01283 return pfout; 01284 } 01285 01286 template <class T> 01287 inline T* transcoord3(T* pfout, const RaveTransformMatrix<T>* pmat, const T* pf) 01288 { 01289 assert( pfout != NULL && pf != NULL && pmat != NULL ); 01290 01291 T dummy[3]; 01292 T* pfreal = (pfout == pf) ? dummy : pfout; 01293 01294 pfreal[0] = pf[0] * pmat->m[0] + pf[1] * pmat->m[1] + pf[2] * pmat->m[2] + pmat->trans.x; 01295 pfreal[1] = pf[0] * pmat->m[4] + pf[1] * pmat->m[5] + pf[2] * pmat->m[6] + pmat->trans.y; 01296 pfreal[2] = pf[0] * pmat->m[8] + pf[1] * pmat->m[9] + pf[2] * pmat->m[10] + pmat->trans.z; 01297 01298 if( pfout ==pf ) { 01299 pfout[0] = pfreal[0]; 01300 pfout[1] = pfreal[1]; 01301 pfout[2] = pfreal[2]; 01302 } 01303 01304 return pfout; 01305 } 01306 01307 template <class T> 01308 inline T* _transnorm3(T* pfout, const T* pfmat, const T* pf) 01309 { 01310 assert( pfout != NULL && pf != NULL && pfmat != NULL ); 01311 01312 T dummy[3]; 01313 T* pfreal = (pfout == pf) ? dummy : pfout; 01314 01315 pfreal[0] = pf[0] * pfmat[0] + pf[1] * pfmat[1] + pf[2] * pfmat[2]; 01316 pfreal[1] = pf[0] * pfmat[3] + pf[1] * pfmat[4] + pf[2] * pfmat[5]; 01317 pfreal[2] = pf[0] * pfmat[6] + pf[1] * pfmat[7] + pf[2] * pfmat[8]; 01318 01319 if( pfout ==pf ) { 01320 pfout[0] = pfreal[0]; 01321 pfout[1] = pfreal[1]; 01322 pfout[2] = pfreal[2]; 01323 } 01324 01325 return pfout; 01326 } 01327 01328 template <class T> 01329 inline T* transnorm3(T* pfout, const RaveTransformMatrix<T>* pmat, const T* pf) 01330 { 01331 assert( pfout != NULL && pf != NULL && pmat != NULL ); 01332 01333 T dummy[3]; 01334 T* pfreal = (pfout == pf) ? dummy : pfout; 01335 01336 pfreal[0] = pf[0] * pmat->m[0] + pf[1] * pmat->m[1] + pf[2] * pmat->m[2]; 01337 pfreal[1] = pf[0] * pmat->m[4] + pf[1] * pmat->m[5] + pf[2] * pmat->m[6]; 01338 pfreal[2] = pf[0] * pmat->m[8] + pf[1] * pmat->m[9] + pf[2] * pmat->m[10]; 01339 01340 if( pfreal != pfout ) { 01341 pfout[0] = pfreal[0]; 01342 pfout[1] = pfreal[1]; 01343 pfout[2] = pfreal[2]; 01344 } 01345 01346 return pfout; 01347 } 01348 01349 inline float* mult4(float* pfres, const float* pf1, const float* pf2) { return _mult4<float>(pfres, pf1, pf2); } 01350 // pf1^T * pf2 01351 inline float* multtrans3(float* pfres, const float* pf1, const float* pf2) { return _multtrans3<float>(pfres, pf1, pf2); } 01352 inline float* multtrans4(float* pfres, const float* pf1, const float* pf2) { return _multtrans4<float>(pfres, pf1, pf2); } 01353 inline float* transnorm3(float* pfout, const float* pfmat, const float* pf) { return _transnorm3<float>(pfout, pfmat, pf); } 01354 01355 inline float* transpose3(const float* pf, float* pfres) { return _transpose3<float>(pf, pfres); } 01356 inline float* transpose4(const float* pf, float* pfres) { return _transpose4<float>(pf, pfres); } 01357 01358 inline float dot2(const float* pf1, const float* pf2) { return _dot2<float>(pf1, pf2); } 01359 inline float dot3(const float* pf1, const float* pf2) { return _dot3<float>(pf1, pf2); } 01360 inline float dot4(const float* pf1, const float* pf2) { return _dot4<float>(pf1, pf2); } 01361 01362 inline float lengthsqr2(const float* pf) { return _lengthsqr2<float>(pf); } 01363 inline float lengthsqr3(const float* pf) { return _lengthsqr3<float>(pf); } 01364 inline float lengthsqr4(const float* pf) { return _lengthsqr4<float>(pf); } 01365 01366 inline float* normalize2(float* pfout, const float* pf) { return _normalize2<float>(pfout, pf); } 01367 inline float* normalize3(float* pfout, const float* pf) { return _normalize3<float>(pfout, pf); } 01368 inline float* normalize4(float* pfout, const float* pf) { return _normalize4<float>(pfout, pf); } 01369 01370 inline float* cross3(float* pfout, const float* pf1, const float* pf2) { return _cross3<float>(pfout, pf1, pf2); } 01371 01372 // multiplies 3x3 matrices 01373 inline float* mult3_s4(float* pfres, const float* pf1, const float* pf2) { return _mult3_s4<float>(pfres, pf1, pf2); } 01374 inline float* mult3_s3(float* pfres, const float* pf1, const float* pf2) { return _mult3_s3<float>(pfres, pf1, pf2); } 01375 01376 inline float* inv3(const float* pf, float* pfres, float* pfdet, int stride) { return _inv3<float>(pf, pfres, pfdet, stride); } 01377 inline float* inv4(const float* pf, float* pfres) { return _inv4<float>(pf, pfres); } 01378 01379 01380 inline double* mult4(double* pfres, const double* pf1, const double* pf2) { return _mult4<double>(pfres, pf1, pf2); } 01381 // pf1^T * pf2 01382 inline double* multtrans3(double* pfres, const double* pf1, const double* pf2) { return _multtrans3<double>(pfres, pf1, pf2); } 01383 inline double* multtrans4(double* pfres, const double* pf1, const double* pf2) { return _multtrans4<double>(pfres, pf1, pf2); } 01384 inline double* transnorm3(double* pfout, const double* pfmat, const double* pf) { return _transnorm3<double>(pfout, pfmat, pf); } 01385 01386 inline double* transpose3(const double* pf, double* pfres) { return _transpose3<double>(pf, pfres); } 01387 inline double* transpose4(const double* pf, double* pfres) { return _transpose4<double>(pf, pfres); } 01388 01389 inline double dot2(const double* pf1, const double* pf2) { return _dot2<double>(pf1, pf2); } 01390 inline double dot3(const double* pf1, const double* pf2) { return _dot3<double>(pf1, pf2); } 01391 inline double dot4(const double* pf1, const double* pf2) { return _dot4<double>(pf1, pf2); } 01392 01393 inline double lengthsqr2(const double* pf) { return _lengthsqr2<double>(pf); } 01394 inline double lengthsqr3(const double* pf) { return _lengthsqr3<double>(pf); } 01395 inline double lengthsqr4(const double* pf) { return _lengthsqr4<double>(pf); } 01396 01397 inline double* normalize2(double* pfout, const double* pf) { return _normalize2<double>(pfout, pf); } 01398 inline double* normalize3(double* pfout, const double* pf) { return _normalize3<double>(pfout, pf); } 01399 inline double* normalize4(double* pfout, const double* pf) { return _normalize4<double>(pfout, pf); } 01400 01401 inline double* cross3(double* pfout, const double* pf1, const double* pf2) { return _cross3<double>(pfout, pf1, pf2); } 01402 01403 // multiplies 3x3 matrices 01404 inline double* mult3_s4(double* pfres, const double* pf1, const double* pf2) { return _mult3_s4<double>(pfres, pf1, pf2); } 01405 inline double* mult3_s3(double* pfres, const double* pf1, const double* pf2) { return _mult3_s3<double>(pfres, pf1, pf2); } 01406 01407 inline double* inv3(const double* pf, double* pfres, double* pfdet, int stride) { return _inv3<double>(pf, pfres, pfdet, stride); } 01408 inline double* inv4(const double* pf, double* pfres) { return _inv4<double>(pf, pfres); } 01409 01410 // if the two triangles collide, returns true and fills contactpos with the intersection point 01411 // assuming triangles are declared counter-clockwise!! 01412 // contactnorm is the normal of the second triangle 01413 bool TriTriCollision(const RaveVector<float>& u1, const RaveVector<float>& u2, const RaveVector<float>& u3, 01414 const RaveVector<float>& v1, const RaveVector<float>& v2, const RaveVector<float>& v3, 01415 RaveVector<float>& contactpos, RaveVector<float>& contactnorm); 01416 bool TriTriCollision(const RaveVector<double>& u1, const RaveVector<double>& u2, const RaveVector<double>& u3, 01417 const RaveVector<double>& v1, const RaveVector<double>& v2, const RaveVector<double>& v3, 01418 RaveVector<double>& contactpos, RaveVector<double>& contactnorm); 01419 01420 template <class T> inline void mult(T* pf, T fa, int r) 01421 { 01422 assert( pf != NULL ); 01423 01424 while(r > 0) { 01425 --r; 01426 pf[r] *= fa; 01427 } 01428 } 01429 01430 template <class T, class R, class S> 01431 inline S* mult(T* pf1, R* pf2, int r1, int c1, int c2, S* pfres, bool badd) 01432 { 01433 assert( pf1 != NULL && pf2 != NULL && pfres != NULL); 01434 int j, k; 01435 01436 if( !badd ) memset(pfres, 0, sizeof(S) * r1 * c2); 01437 01438 while(r1 > 0) { 01439 --r1; 01440 01441 j = 0; 01442 while(j < c2) { 01443 k = 0; 01444 while(k < c1) { 01445 pfres[j] += (S)(pf1[k] * pf2[k*c2 + j]); 01446 ++k; 01447 } 01448 ++j; 01449 } 01450 01451 pf1 += c1; 01452 pfres += c2; 01453 } 01454 01455 return pfres; 01456 } 01457 01458 template <class T, class R, class S> 01459 inline S* multtrans(T* pf1, R* pf2, int r1, int c1, int c2, S* pfres, bool badd) 01460 { 01461 assert( pf1 != NULL && pf2 != NULL && pfres != NULL); 01462 int i, j, k; 01463 01464 if( !badd ) memset(pfres, 0, sizeof(S) * c1 * c2); 01465 01466 i = 0; 01467 while(i < c1) { 01468 01469 j = 0; 01470 while(j < c2) { 01471 01472 k = 0; 01473 while(k < r1) { 01474 pfres[j] += (S)(pf1[k*c1] * pf2[k*c2 + j]); 01475 ++k; 01476 } 01477 ++j; 01478 } 01479 01480 pfres += c2; 01481 ++pf1; 01482 01483 ++i; 01484 } 01485 01486 return pfres; 01487 } 01488 01489 template <class T, class R, class S> 01490 inline S* multtrans_to2(T* pf1, R* pf2, int r1, int c1, int r2, S* pfres, bool badd) 01491 { 01492 assert( pf1 != NULL && pf2 != NULL && pfres != NULL); 01493 int j, k; 01494 01495 if( !badd ) memset(pfres, 0, sizeof(S) * r1 * r2); 01496 01497 while(r1 > 0) { 01498 --r1; 01499 01500 j = 0; 01501 while(j < r2) { 01502 k = 0; 01503 while(k < c1) { 01504 pfres[j] += (S)(pf1[k] * pf2[j*c1 + k]); 01505 ++k; 01506 } 01507 ++j; 01508 } 01509 01510 pf1 += c1; 01511 pfres += r2; 01512 } 01513 01514 return pfres; 01515 } 01516 01517 template <class T> inline T* multto1(T* pf1, T* pf2, int r, int c, T* pftemp) 01518 { 01519 assert( pf1 != NULL && pf2 != NULL ); 01520 01521 int j, k; 01522 bool bdel = false; 01523 01524 if( pftemp == NULL ) { 01525 pftemp = new T[c]; 01526 bdel = true; 01527 } 01528 01529 while(r > 0) { 01530 --r; 01531 01532 j = 0; 01533 while(j < c) { 01534 01535 pftemp[j] = 0.0; 01536 01537 k = 0; 01538 while(k < c) { 01539 pftemp[j] += pf1[k] * pf2[k*c + j]; 01540 ++k; 01541 } 01542 ++j; 01543 } 01544 01545 memcpy(pf1, pftemp, c * sizeof(T)); 01546 pf1 += c; 01547 } 01548 01549 if( bdel ) delete[] pftemp; 01550 01551 return pf1; 01552 } 01553 01554 template <class T, class S> inline T* multto2(T* pf1, S* pf2, int r2, int c2, S* pftemp) 01555 { 01556 assert( pf1 != NULL && pf2 != NULL ); 01557 01558 int i, j, k; 01559 bool bdel = false; 01560 01561 if( pftemp == NULL ) { 01562 pftemp = new S[r2]; 01563 bdel = true; 01564 } 01565 01566 // do columns first 01567 j = 0; 01568 while(j < c2) { 01569 i = 0; 01570 while(i < r2) { 01571 01572 pftemp[i] = 0.0; 01573 01574 k = 0; 01575 while(k < r2) { 01576 pftemp[i] += pf1[i*r2 + k] * pf2[k*c2 + j]; 01577 ++k; 01578 } 01579 ++i; 01580 } 01581 01582 i = 0; 01583 while(i < r2) { 01584 *(pf2+i*c2+j) = pftemp[i]; 01585 ++i; 01586 } 01587 01588 ++j; 01589 } 01590 01591 if( bdel ) delete[] pftemp; 01592 01593 return pf1; 01594 } 01595 01596 template <class T> inline void add(T* pf1, T* pf2, int r) 01597 { 01598 assert( pf1 != NULL && pf2 != NULL); 01599 01600 while(r > 0) { 01601 --r; 01602 pf1[r] += pf2[r]; 01603 } 01604 } 01605 01606 template <class T> inline void sub(T* pf1, T* pf2, int r) 01607 { 01608 assert( pf1 != NULL && pf2 != NULL); 01609 01610 while(r > 0) { 01611 --r; 01612 pf1[r] -= pf2[r]; 01613 } 01614 } 01615 01616 template <class T> inline T normsqr(const T* pf1, int r) 01617 { 01618 assert( pf1 != NULL ); 01619 01620 T d = 0.0; 01621 while(r > 0) { 01622 --r; 01623 d += pf1[r] * pf1[r]; 01624 } 01625 01626 return d; 01627 } 01628 01629 template <class T> inline T lengthsqr(const T* pf1, const T* pf2, int length) 01630 { 01631 T d = 0; 01632 while(length > 0) { 01633 --length; 01634 T t = pf1[length] - pf2[length]; 01635 d += t * t; 01636 } 01637 01638 return d; 01639 } 01640 01641 template <class T> inline T dot(T* pf1, T* pf2, int length) 01642 { 01643 T d = 0; 01644 while(length > 0) { 01645 --length; 01646 d += pf1[length] * pf2[length]; 01647 } 01648 01649 return d; 01650 } 01651 01652 template <class T> inline T sum(T* pf, int length) 01653 { 01654 T d = 0; 01655 while(length > 0) { 01656 --length; 01657 d += pf[length]; 01658 } 01659 01660 return d; 01661 } 01662 01663 template <class T> inline bool inv2(T* pf, T* pfres) 01664 { 01665 T fdet = pf[0] * pf[3] - pf[1] * pf[2]; 01666 01667 if( fabs(fdet) < 1e-16 ) return false; 01668 01669 fdet = 1 / fdet; 01670 //if( pfdet != NULL ) *pfdet = fdet; 01671 01672 if( pfres != pf ) { 01673 pfres[0] = fdet * pf[3]; pfres[1] = -fdet * pf[1]; 01674 pfres[2] = -fdet * pf[2]; pfres[3] = fdet * pf[0]; 01675 return true; 01676 } 01677 01678 T ftemp = pf[0]; 01679 pfres[0] = pf[3] * fdet; 01680 pfres[1] *= -fdet; 01681 pfres[2] *= -fdet; 01682 pfres[3] = ftemp * pf[0]; 01683 01684 return true; 01685 } 01686 01687 template <class T, class S> 01688 void Tridiagonal3 (S* mat, T* diag, T* subd) 01689 { 01690 T a, b, c, d, e, f, ell, q; 01691 01692 a = mat[0*3+0]; 01693 b = mat[0*3+1]; 01694 c = mat[0*3+2]; 01695 d = mat[1*3+1]; 01696 e = mat[1*3+2]; 01697 f = mat[2*3+2]; 01698 01699 subd[2] = 0.0; 01700 diag[0] = a; 01701 if ( fabs(c) >= g_fEpsilon ) { 01702 ell = (T)RaveSqrt(b*b+c*c); 01703 b /= ell; 01704 c /= ell; 01705 q = 2*b*e+c*(f-d); 01706 diag[1] = d+c*q; 01707 diag[2] = f-c*q; 01708 subd[0] = ell; 01709 subd[1] = e-b*q; 01710 mat[0*3+0] = (S)1; mat[0*3+1] = (S)0; mat[0*3+2] = (T)0; 01711 mat[1*3+0] = (S)0; mat[1*3+1] = b; mat[1*3+2] = c; 01712 mat[2*3+0] = (S)0; mat[2*3+1] = c; mat[2*3+2] = -b; 01713 } 01714 else { 01715 diag[1] = d; 01716 diag[2] = f; 01717 subd[0] = b; 01718 subd[1] = e; 01719 mat[0*3+0] = (S)1; mat[0*3+1] = (S)0; mat[0*3+2] = (S)0; 01720 mat[1*3+0] = (S)0; mat[1*3+1] = (S)1; mat[1*3+2] = (S)0; 01721 mat[2*3+0] = (S)0; mat[2*3+1] = (S)0; mat[2*3+2] = (S)1; 01722 } 01723 } 01724 01725 template <class T> 01726 int Min(T* pts, int stride, int numPts) 01727 { 01728 assert( pts != NULL && numPts > 0 && stride > 0 ); 01729 01730 int best = pts[0]; pts += stride; 01731 for(int i = 1; i < numPts; ++i, pts += stride) { 01732 if( best > pts[0] ) 01733 best = pts[0]; 01734 } 01735 01736 return best; 01737 } 01738 01739 template <class T> 01740 int Max(T* pts, int stride, int numPts) 01741 { 01742 assert( pts != NULL && numPts > 0 && stride > 0 ); 01743 01744 int best = pts[0]; pts += stride; 01745 for(int i = 1; i < numPts; ++i, pts += stride) { 01746 if( best < pts[0] ) 01747 best = pts[0]; 01748 } 01749 01750 return best; 01751 } 01752 01753 // Don't add new lines to the output << operators. Some applications use it to serialize the data 01754 // to send across the network. 01755 01756 template <class T, class U> 01757 std::basic_ostream<T>& operator<<(std::basic_ostream<T>& O, const RaveVector<U>& v) 01758 { 01759 return O << v.x << " " << v.y << " " << v.z << " " << v.w << " "; 01760 } 01761 01762 template <class T, class U> 01763 std::basic_istream<T>& operator>>(std::basic_istream<T>& I, RaveVector<U>& v) 01764 { 01765 return I >> v.x >> v.y >> v.z >> v.w; 01766 } 01767 01768 template <class T, class U> 01769 std::basic_ostream<T>& operator<<(std::basic_ostream<T>& O, const RaveTransform<U>& v) 01770 { 01771 return O << v.rot.x << " " << v.rot.y << " " << v.rot.z << " " << v.rot.w << " " 01772 << v.trans.x << " " << v.trans.y << " " << v.trans.z << " "; 01773 } 01774 01775 template <class T, class U> 01776 std::basic_istream<T>& operator>>(std::basic_istream<T>& I, RaveTransform<U>& v) 01777 { 01778 return I >> v.rot.x >> v.rot.y >> v.rot.z >> v.rot.w >> v.trans.x >> v.trans.y >> v.trans.z; 01779 } 01780 01781 // serial in column order! This is the format transformations are passed across the network 01782 template <class T, class U> 01783 std::basic_ostream<T>& operator<<(std::basic_ostream<T>& O, const RaveTransformMatrix<U>& v) 01784 { 01785 return O << v.m[0] << " " << v.m[4] << " " << v.m[8] << " " 01786 << v.m[1] << " " << v.m[5] << " " << v.m[9] << " " 01787 << v.m[2] << " " << v.m[6] << " " << v.m[10] << " " 01788 << v.trans.x << " " << v.trans.y << " " << v.trans.z << " "; 01789 } 01790 01791 // read in column order! This is the format transformations are passed across the network 01792 template <class T, class U> 01793 std::basic_istream<T>& operator>>(std::basic_istream<T>& I, RaveTransformMatrix<U>& v) 01794 { 01795 return I >> v.m[0] >> v.m[4] >> v.m[8] 01796 >> v.m[1] >> v.m[5] >> v.m[9] 01797 >> v.m[2] >> v.m[6] >> v.m[10] 01798 >> v.trans.x >> v.trans.y >> v.trans.z; 01799 } 01800 01801 #endif