$search
00001 /* Mathlib 00002 * 00003 * Copyright (C) 2003-2004, Alexander Zaprjagaev <frustum@frustum.org> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 */ 00019 00020 #ifndef TG_MATHLIB_H 00021 #define TG_MATHLIB_H 00022 00023 #include <math.h> 00024 #include <stdlib.h> 00025 00026 #ifndef PI 00027 #define PI 3.14159265358979323846f 00028 #endif 00029 00030 // #define epsilon 1e-6f 00031 #define DEG2RAD (PI / 180.0f) 00032 #define RAD2DEG (180.0f / PI) 00033 00034 //namespace TomGine{ 00035 00036 struct vec2; 00037 struct vec3; 00038 struct vec4; 00039 struct mat3; 00040 struct mat4; 00041 struct quat; 00042 00043 const float epsilon = 1e-6f; 00044 00045 inline unsigned int ilog2(unsigned int value) 00046 { 00047 unsigned int f=0, s=32; 00048 while(s) { 00049 s>>=1; 00050 if( value > static_cast<unsigned int>(1<<(f+s)) ) f+=s; 00051 } 00052 return (f+1); 00053 } 00054 00055 /*****************************************************************************/ 00056 /* */ 00057 /* vec2 */ 00058 /* */ 00059 /*****************************************************************************/ 00060 00061 struct vec2 { 00062 00063 inline vec2() : x(0), y(0) { } 00064 inline vec2(float x,float y) : x(x), y(y) { } 00065 inline vec2(const float *v) : x(v[0]), y(v[1]) { } 00066 inline vec2(const vec2 &v) : x(v.x), y(v.y) { } 00067 00068 inline int operator==(const vec2 &v) { return (fabs(x - v.x) < epsilon && fabs(y - v.y) < epsilon); } 00069 inline int operator!=(const vec2 &v) { return !(*this == v); } 00070 00071 inline const vec2 operator*(float f) const { return vec2(x * f,y * f); } 00072 inline const vec2 operator/(float f) const { float vf = 1.0f/f; return vec2(x * vf,y * vf); } 00073 inline const vec2 operator+(const vec2 &v) const { return vec2(x + v.x,y + v.y); } 00074 inline const vec2 operator-() const { return vec2(-x,-y); } 00075 inline const vec2 operator-(const vec2 &v) const { return vec2(x - v.x,y - v.y); } 00076 00077 inline vec2 &operator*=(float f) { return *this = *this * f; } 00078 inline vec2 &operator/=(float f) { return *this = *this / f; } 00079 inline vec2 &operator+=(const vec2 &v) { return *this = *this + v; } 00080 inline vec2 &operator-=(const vec2 &v) { return *this = *this - v; } 00081 00082 inline float operator*(const vec2 &v) const { return x * v.x + y * v.y; } 00083 00084 inline operator float*() { return (float*)&x; } 00085 inline operator const float*() const { return (float*)&x; } 00086 00087 inline float &operator[](int i) { return ((float*)&x)[i]; } 00088 inline float operator[](int i) const { return v[i]; } // ((float*)&x)[i] 00089 00090 inline float length() const { return sqrt(x * x + y * y); } 00091 inline float normalize() { 00092 float inv,length = sqrt(x * x + y * y); 00093 if(length < epsilon) return 0.0; 00094 inv = 1.0f / length; 00095 x *= inv; 00096 y *= inv; 00097 return length; 00098 } 00099 inline void absolute(){ 00100 x = abs(x); 00101 y = abs(y); 00102 } 00103 00104 union { 00105 struct { 00106 float x,y; 00107 }; 00108 float v[2]; 00109 }; 00110 }; 00111 00112 /*****************************************************************************/ 00113 /* */ 00114 /* vec3 */ 00115 /* */ 00116 /*****************************************************************************/ 00117 00118 struct vec3 { 00119 00120 inline vec3() : x(0), y(0), z(0) { } 00121 inline vec3(float x,float y,float z) : x(x), y(y), z(z) { } 00122 inline vec3(const float *v) : x(v[0]), y(v[1]), z(v[2]) { } 00123 inline vec3(const vec3 &v) : x(v.x), y(v.y), z(v.z) { } 00124 inline vec3(const vec4 &v); 00125 00126 inline void random(){ x = float(rand())/float(RAND_MAX); 00127 y = float(rand())/float(RAND_MAX); 00128 z = float(rand())/float(RAND_MAX); } 00129 00130 inline int operator==(const vec3 &v) { return (fabs(x - v.x) < epsilon && fabs(y - v.y) < epsilon && fabs(z - v.z) < epsilon); } 00131 inline int operator!=(const vec3 &v) { return !(*this == v); } 00132 00133 inline const vec3 operator*(float f) const { return vec3(x * f,y * f,z * f); } 00134 inline const vec3 operator/(float f) const { float vf = 1.0f/f; return vec3(x * vf,y * vf,z * vf); } 00135 inline const vec3 operator+(const vec3 &v) const { return vec3(x + v.x,y + v.y,z + v.z); } 00136 inline const vec3 operator-() const { return vec3(-x,-y,-z); } 00137 inline const vec3 operator-(const vec3 &v) const { return vec3(x - v.x,y - v.y,z - v.z); } 00138 inline const vec3 operator^(const vec3 &v) const { return vec3(y * v.z - z * v.y, 00139 z * v.x - x * v.z, x * v.y - y * v.x); } 00140 00141 inline vec3 &operator*=(float f) { return *this = *this * f; } 00142 inline vec3 &operator/=(float f) { return *this = *this / f; } 00143 inline vec3 &operator+=(const vec3 &v) { return *this = *this + v; } 00144 inline vec3 &operator-=(const vec3 &v) { return *this = *this - v; } 00145 00146 inline float operator*(const vec3 &v) const { return x * v.x + y * v.y + z * v.z; } 00147 inline float operator*(const vec4 &v) const; 00148 00149 inline operator float*() { return &x; } 00150 inline operator const float*() const { return &x; } 00151 00152 inline float &operator[](int i) { return v[i]; } 00153 inline float operator[](int i) const { return v[i]; } 00154 00155 inline float length() const { return sqrt(x * x + y * y + z * z); } 00156 inline float normalize() { 00157 float length = sqrt(x * x + y * y + z * z); 00158 if(length < epsilon) return 0.0; 00159 float inv = 1.0f / length; 00160 x *= inv; 00161 y *= inv; 00162 z *= inv; 00163 return length; 00164 } 00165 00166 inline void cross(const vec3 &v1,const vec3 &v2) { 00167 x = v1.y * v2.z - v1.z * v2.y; 00168 y = v1.z * v2.x - v1.x * v2.z; 00169 z = v1.x * v2.y - v1.y * v2.x; 00170 } 00171 inline void absolute(){ 00172 x = abs(x); 00173 y = abs(y); 00174 z = abs(z); 00175 } 00176 00177 union { 00178 struct { 00179 float x,y,z; 00180 }; 00181 float v[3]; 00182 }; 00183 }; 00184 00185 inline vec3 normalize(const vec3 &v) { 00186 float length = v.length(); 00187 if(length < epsilon) return vec3(0,0,0); 00188 return v / length; 00189 } 00190 00191 inline vec3 cross(const vec3 &v1,const vec3 &v2) { 00192 vec3 ret; 00193 ret.x = v1.y * v2.z - v1.z * v2.y; 00194 ret.y = v1.z * v2.x - v1.x * v2.z; 00195 ret.z = v1.x * v2.y - v1.y * v2.x; 00196 return ret; 00197 } 00198 00199 inline vec3 absolute(const vec3 &v1) { 00200 vec3 ret; 00201 ret.x = abs(v1.x); 00202 ret.y = abs(v1.y); 00203 ret.z = abs(v1.z); 00204 return ret; 00205 } 00206 00207 inline vec3 saturate(const vec3 &v) { 00208 vec3 ret = v; 00209 if(ret.x < 0.0) ret.x = 0.0; 00210 else if(ret.x > 1.0f) ret.x = 1.0f; 00211 if(ret.y < 0.0) ret.y = 0.0; 00212 else if(ret.y > 1.0f) ret.y = 1.0f; 00213 if(ret.z < 0.0) ret.z = 0.0; 00214 else if(ret.z > 1.0f) ret.z = 1.0f; 00215 return ret; 00216 } 00217 00218 /*****************************************************************************/ 00219 /* */ 00220 /* vec4 */ 00221 /* */ 00222 /*****************************************************************************/ 00223 00224 struct vec4 { 00225 00226 inline vec4() : x(0), y(0), z(0), w(1) { } 00227 inline vec4(float x,float y,float z,float w) : x(x), y(y), z(z), w(w) { } 00228 inline vec4(const float *v) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) { } 00229 inline vec4(const vec3 &v) : x(v.x), y(v.y), z(v.z), w(1) { } 00230 inline vec4(const vec3 &v,float w) : x(v.x), y(v.y), z(v.z), w(w) { } 00231 inline vec4(const vec4 &v) : x(v.x), y(v.y), z(v.z), w(v.w) { } 00232 00233 inline void random(){ x = float(rand())/float(RAND_MAX); 00234 y = float(rand())/float(RAND_MAX); 00235 z = float(rand())/float(RAND_MAX); 00236 w = float(rand())/float(RAND_MAX); } 00237 00238 inline int operator==(const vec4 &v) { return (fabs(x - v.x) < epsilon && fabs(y - v.y) < epsilon && fabs(z - v.z) < epsilon && fabs(w - v.w) < epsilon); } 00239 inline int operator!=(const vec4 &v) { return !(*this == v); } 00240 00241 inline const vec4 operator*(float f) const { return vec4(x * f,y * f,z * f,w * f); } 00242 inline const vec4 operator/(float f) const { float vf = 1.0f/f; return vec4(x * vf,y * vf,z * vf,w * vf); } 00243 inline const vec4 operator+(const vec4 &v) const { return vec4(x + v.x,y + v.y,z + v.z,w + v.w); } 00244 inline const vec4 operator-() const { return vec4(-x,-y,-z,-w); } 00245 inline const vec4 operator-(const vec4 &v) const { return vec4(x - v.x,y - v.y,z - v.z,z - v.w); } 00246 00247 inline vec4 &operator*=(float f) { return *this = *this * f; } 00248 inline vec4 &operator/=(float f) { return *this = *this / f; } 00249 inline vec4 &operator+=(const vec4 &v) { return *this = *this + v; } 00250 inline vec4 &operator-=(const vec4 &v) { return *this = *this - v; } 00251 00252 inline float operator*(const vec3 &v) const { return x * v.x + y * v.y + z * v.z + w; } 00253 inline float operator*(const vec4 &v) const { return x * v.x + y * v.y + z * v.z + w * v.w; } 00254 00255 inline operator float*() { return (float*)&x; } 00256 inline operator const float*() const { return (float*)&x; } 00257 00258 inline float &operator[](int i) { return v[i]; } 00259 inline float operator[](int i) const { return v[i]; } 00260 00261 inline float length() const { return sqrt(x * x + y * y + z * z + w * w); } 00262 inline float normalize() { 00263 float length = sqrt(x * x + y * y + z * z + w * w); 00264 if(length < epsilon) return 0.0; 00265 float inv = 1.0f / length; 00266 x *= inv; 00267 y *= inv; 00268 z *= inv; 00269 w *= inv; 00270 return length; 00271 } 00272 00273 union { 00274 struct { 00275 float x,y,z,w; 00276 }; 00277 float v[4]; 00278 }; 00279 }; 00280 00281 inline vec3::vec3(const vec4 &v) { 00282 x = v.x; 00283 y = v.y; 00284 z = v.z; 00285 } 00286 00287 inline float vec3::operator*(const vec4 &v) const { 00288 return x * v.x + y * v.y + z * v.z + v.w; 00289 } 00290 00291 inline vec4 normalize(const vec4 &v) { 00292 float length = v.length(); 00293 if(length < epsilon) return vec4(0,0,0,0); 00294 return v / length; 00295 } 00296 00297 inline vec4 saturate(const vec4 &v) { 00298 vec4 ret = v; 00299 if(ret.x < 0.0) ret.x = 0.0; 00300 else if(ret.x > 1.0f) ret.x = 1.0f; 00301 if(ret.y < 0.0) ret.y = 0.0; 00302 else if(ret.y > 1.0f) ret.y = 1.0f; 00303 if(ret.z < 0.0) ret.z = 0.0; 00304 else if(ret.z > 1.0f) ret.z = 1.0f; 00305 if(ret.w < 0.0) ret.w = 0.0; 00306 else if(ret.w > 1.0f) ret.w = 1.0f; 00307 return ret; 00308 } 00309 00310 /*****************************************************************************/ 00311 /* */ 00312 /* mat3 */ 00313 /* */ 00314 /*****************************************************************************/ 00315 00316 struct mat3 { 00317 00318 mat3() { 00319 mat[0] = 1.0; mat[3] = 0.0; mat[6] = 0.0; 00320 mat[1] = 0.0; mat[4] = 1.0; mat[7] = 0.0; 00321 mat[2] = 0.0; mat[5] = 0.0; mat[8] = 1.0; 00322 } 00323 mat3(const float *m) { 00324 mat[0] = m[0]; mat[3] = m[3]; mat[6] = m[6]; 00325 mat[1] = m[1]; mat[4] = m[4]; mat[7] = m[7]; 00326 mat[2] = m[2]; mat[5] = m[5]; mat[8] = m[8]; 00327 } 00328 mat3(const mat3 &m) { 00329 mat[0] = m[0]; mat[3] = m[3]; mat[6] = m[6]; 00330 mat[1] = m[1]; mat[4] = m[4]; mat[7] = m[7]; 00331 mat[2] = m[2]; mat[5] = m[5]; mat[8] = m[8]; 00332 } 00333 mat3(const mat4 &m); 00334 00335 vec3 operator*(const vec3 &v) const { 00336 vec3 ret; 00337 ret[0] = mat[0] * v[0] + mat[3] * v[1] + mat[6] * v[2]; 00338 ret[1] = mat[1] * v[0] + mat[4] * v[1] + mat[7] * v[2]; 00339 ret[2] = mat[2] * v[0] + mat[5] * v[1] + mat[8] * v[2]; 00340 return ret; 00341 } 00342 vec4 operator*(const vec4 &v) const { 00343 vec4 ret; 00344 ret[0] = mat[0] * v[0] + mat[3] * v[1] + mat[6] * v[2]; 00345 ret[1] = mat[1] * v[0] + mat[4] * v[1] + mat[7] * v[2]; 00346 ret[2] = mat[2] * v[0] + mat[5] * v[1] + mat[8] * v[2]; 00347 ret[3] = v[3]; 00348 return ret; 00349 } 00350 mat3 operator*(float f) const { 00351 mat3 ret; 00352 ret[0] = mat[0] * f; ret[3] = mat[3] * f; ret[6] = mat[6] * f; 00353 ret[1] = mat[1] * f; ret[4] = mat[4] * f; ret[7] = mat[7] * f; 00354 ret[2] = mat[2] * f; ret[5] = mat[5] * f; ret[8] = mat[8] * f; 00355 return ret; 00356 } 00357 mat3 operator*(const mat3 &m) const { 00358 mat3 ret; 00359 ret[0] = mat[0] * m[0] + mat[3] * m[1] + mat[6] * m[2]; 00360 ret[1] = mat[1] * m[0] + mat[4] * m[1] + mat[7] * m[2]; 00361 ret[2] = mat[2] * m[0] + mat[5] * m[1] + mat[8] * m[2]; 00362 ret[3] = mat[0] * m[3] + mat[3] * m[4] + mat[6] * m[5]; 00363 ret[4] = mat[1] * m[3] + mat[4] * m[4] + mat[7] * m[5]; 00364 ret[5] = mat[2] * m[3] + mat[5] * m[4] + mat[8] * m[5]; 00365 ret[6] = mat[0] * m[6] + mat[3] * m[7] + mat[6] * m[8]; 00366 ret[7] = mat[1] * m[6] + mat[4] * m[7] + mat[7] * m[8]; 00367 ret[8] = mat[2] * m[6] + mat[5] * m[7] + mat[8] * m[8]; 00368 return ret; 00369 } 00370 mat3 operator+(const mat3 &m) const { 00371 mat3 ret; 00372 ret[0] = mat[0] + m[0]; ret[3] = mat[3] + m[3]; ret[6] = mat[6] + m[6]; 00373 ret[1] = mat[1] + m[1]; ret[4] = mat[4] + m[4]; ret[7] = mat[7] + m[7]; 00374 ret[2] = mat[2] + m[2]; ret[5] = mat[5] + m[5]; ret[8] = mat[8] + m[8]; 00375 return ret; 00376 } 00377 mat3 operator-(const mat3 &m) const { 00378 mat3 ret; 00379 ret[0] = mat[0] - m[0]; ret[3] = mat[3] - m[3]; ret[6] = mat[6] - m[6]; 00380 ret[1] = mat[1] - m[1]; ret[4] = mat[4] - m[4]; ret[7] = mat[7] - m[7]; 00381 ret[2] = mat[2] - m[2]; ret[5] = mat[5] - m[5]; ret[8] = mat[8] - m[8]; 00382 return ret; 00383 } 00384 00385 mat3 &operator*=(float f) { return *this = *this * f; } 00386 mat3 &operator*=(const mat3 &m) { return *this = *this * m; } 00387 mat3 &operator+=(const mat3 &m) { return *this = *this + m; } 00388 mat3 &operator-=(const mat3 &m) { return *this = *this - m; } 00389 00390 operator float*() { return mat; } 00391 operator const float*() const { return mat; } 00392 00393 float &operator[](int i) { return mat[i]; } 00394 float operator[](int i) const { return mat[i]; } 00395 00396 mat3 transpose() const { 00397 mat3 ret; 00398 ret[0] = mat[0]; ret[3] = mat[1]; ret[6] = mat[2]; 00399 ret[1] = mat[3]; ret[4] = mat[4]; ret[7] = mat[5]; 00400 ret[2] = mat[6]; ret[5] = mat[7]; ret[8] = mat[8]; 00401 return ret; 00402 } 00403 float det() const { 00404 float det; 00405 det = mat[0] * mat[4] * mat[8]; 00406 det += mat[3] * mat[7] * mat[2]; 00407 det += mat[6] * mat[1] * mat[5]; 00408 det -= mat[6] * mat[4] * mat[2]; 00409 det -= mat[3] * mat[1] * mat[8]; 00410 det -= mat[0] * mat[7] * mat[5]; 00411 return det; 00412 } 00413 mat3 inverse() const { 00414 mat3 ret; 00415 float idet = 1.0f / det(); 00416 ret[0] = (mat[4] * mat[8] - mat[7] * mat[5]) * idet; 00417 ret[1] = -(mat[1] * mat[8] - mat[7] * mat[2]) * idet; 00418 ret[2] = (mat[1] * mat[5] - mat[4] * mat[2]) * idet; 00419 ret[3] = -(mat[3] * mat[8] - mat[6] * mat[5]) * idet; 00420 ret[4] = (mat[0] * mat[8] - mat[6] * mat[2]) * idet; 00421 ret[5] = -(mat[0] * mat[5] - mat[3] * mat[2]) * idet; 00422 ret[6] = (mat[3] * mat[7] - mat[6] * mat[4]) * idet; 00423 ret[7] = -(mat[0] * mat[7] - mat[6] * mat[1]) * idet; 00424 ret[8] = (mat[0] * mat[4] - mat[3] * mat[1]) * idet; 00425 return ret; 00426 } 00427 00428 void zero() { 00429 mat[0] = 0.0; mat[3] = 0.0; mat[6] = 0.0; 00430 mat[1] = 0.0; mat[4] = 0.0; mat[7] = 0.0; 00431 mat[2] = 0.0; mat[5] = 0.0; mat[8] = 0.0; 00432 } 00433 void identity() { 00434 mat[0] = 1.0; mat[3] = 0.0; mat[6] = 0.0; 00435 mat[1] = 0.0; mat[4] = 1.0; mat[7] = 0.0; 00436 mat[2] = 0.0; mat[5] = 0.0; mat[8] = 1.0; 00437 } 00438 void rotate(const vec3 &axis,float angle) { 00439 float rad = angle * DEG2RAD; 00440 float c = cos(rad); 00441 float s = sin(rad); 00442 vec3 v = axis; 00443 v.normalize(); 00444 float xx = v.x * v.x; 00445 float yy = v.y * v.y; 00446 float zz = v.z * v.z; 00447 float xy = v.x * v.y; 00448 float yz = v.y * v.z; 00449 float zx = v.z * v.x; 00450 float xs = v.x * s; 00451 float ys = v.y * s; 00452 float zs = v.z * s; 00453 mat[0] = (1.0f - c) * xx + c; mat[3] = (1.0f - c) * xy - zs; mat[6] = (1.0f - c) * zx + ys; 00454 mat[1] = (1.0f - c) * xy + zs; mat[4] = (1.0f - c) * yy + c; mat[7] = (1.0f - c) * yz - xs; 00455 mat[2] = (1.0f - c) * zx - ys; mat[5] = (1.0f - c) * yz + xs; mat[8] = (1.0f - c) * zz + c; 00456 } 00457 void rotate(float x,float y,float z,float angle) { 00458 rotate(vec3(x,y,z),angle); 00459 } 00460 void rotate_x(float angle) { 00461 float rad = angle * DEG2RAD; 00462 float c = cos(rad); 00463 float s = sin(rad); 00464 mat[0] = 1.0; mat[3] = 0.0; mat[6] = 0.0; 00465 mat[1] = 0.0; mat[4] = c; mat[7] = -s; 00466 mat[2] = 0.0; mat[5] = s; mat[8] = c; 00467 } 00468 void rotate_y(float angle) { 00469 float rad = angle * DEG2RAD; 00470 float c = cos(rad); 00471 float s = sin(rad); 00472 mat[0] = c; mat[3] = 0.0; mat[6] = s; 00473 mat[1] = 0.0; mat[4] = 1.0; mat[7] = 0.0; 00474 mat[2] = -s; mat[5] = 0.0; mat[8] = c; 00475 } 00476 void rotate_z(float angle) { 00477 float rad = angle * DEG2RAD; 00478 float c = cos(rad); 00479 float s = sin(rad); 00480 mat[0] = c; mat[3] = -s; mat[6] = 0.0; 00481 mat[1] = s; mat[4] = c; mat[7] = 0.0; 00482 mat[2] = 0.0; mat[5] = 0.0; mat[8] = 1.0; 00483 } 00484 void scale(const vec3 &v) { 00485 mat[0] = v.x; mat[3] = 0.0; mat[6] = 0.0; 00486 mat[1] = 0.0; mat[4] = v.y; mat[7] = 0.0; 00487 mat[2] = 0.0; mat[5] = 0.0; mat[8] = v.z; 00488 } 00489 void scale(float x,float y,float z) { 00490 scale(vec3(x,y,z)); 00491 } 00492 void orthonormalize() { 00493 vec3 x(mat[0],mat[1],mat[2]); 00494 vec3 y(mat[3],mat[4],mat[5]); 00495 vec3 z; 00496 x.normalize(); 00497 z.cross(x,y); 00498 z.normalize(); 00499 y.cross(z,x); 00500 y.normalize(); 00501 mat[0] = x.x; mat[3] = y.x; mat[6] = z.x; 00502 mat[1] = x.y; mat[4] = y.y; mat[7] = z.y; 00503 mat[2] = x.z; mat[5] = y.z; mat[8] = z.z; 00504 } 00505 00506 // Vector/Matrix Conversions 00507 void fromAngleAxis(float angle, const vec3& axis) 00508 { 00509 float s = sin(angle), c = cos(angle); 00510 float v = (float)1.0 - c, x = axis.x*v, y = axis.y*v, z = axis.z*v; 00511 00512 mat[0] = axis.x*x + c; 00513 mat[1] = axis.x*y - axis.z*s; 00514 mat[2] = axis.x*z + axis.y*s; 00515 00516 mat[3] = axis.y*x + axis.z*s; 00517 mat[4] = axis.y*y + c; 00518 mat[5] = axis.y*z - axis.x*s; 00519 00520 mat[6] = axis.z*x - axis.y*s; 00521 mat[7] = axis.z*y + axis.x*s; 00522 mat[8] = axis.z*z + c; 00523 } 00524 00525 // creates rotation matrix from rotation vector (= axis plus angle). 00526 void fromRotVector(const vec3& r) 00527 { 00528 vec3 axis(r); 00529 float angle = axis.normalize(); 00530 fromAngleAxis(angle, axis); 00531 } 00532 00533 void getAxisAngle(vec3 &axis, float &angle) 00534 { 00535 angle = acos(( mat[0] + mat[4] + mat[8] - 1.0f)/2.0f); 00536 axis.x = (mat[5] - mat[7])/sqrt(pow(mat[5] - mat[7],2)+pow(mat[6] - mat[2],2)+pow(mat[1] - mat[3],2)); 00537 axis.y = (mat[6] - mat[2])/sqrt(pow(mat[5] - mat[7],2)+pow(mat[6] - mat[2],2)+pow(mat[1] - mat[3],2)); 00538 axis.z = (mat[1] - mat[3])/sqrt(pow(mat[5] - mat[7],2)+pow(mat[6] - mat[2],2)+pow(mat[1] - mat[3],2)); 00539 } 00540 00541 float mat[9]; 00542 }; 00543 00544 /*****************************************************************************/ 00545 /* */ 00546 /* mat4 */ 00547 /* */ 00548 /*****************************************************************************/ 00549 00550 struct mat4 { 00551 00552 mat4() { 00553 mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0; 00554 mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0; 00555 mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0; 00556 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; 00557 } 00558 mat4(const vec3 &v) { 00559 translate(v); 00560 } 00561 mat4(float x,float y,float z) { 00562 translate(x,y,z); 00563 } 00564 mat4(const vec3 &axis,float angle) { 00565 rotate(axis,angle); 00566 } 00567 mat4(float x,float y,float z,float angle) { 00568 rotate(x,y,z,angle); 00569 } 00570 mat4(const mat3 &m) { 00571 mat[0] = m[0]; mat[4] = m[3]; mat[8] = m[6]; mat[12] = 0.0; 00572 mat[1] = m[1]; mat[5] = m[4]; mat[9] = m[7]; mat[13] = 0.0; 00573 mat[2] = m[2]; mat[6] = m[5]; mat[10] = m[8]; mat[14] = 0.0; 00574 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; 00575 } 00576 mat4(const float *m) { 00577 mat[0] = m[0]; mat[4] = m[4]; mat[8] = m[8]; mat[12] = m[12]; 00578 mat[1] = m[1]; mat[5] = m[5]; mat[9] = m[9]; mat[13] = m[13]; 00579 mat[2] = m[2]; mat[6] = m[6]; mat[10] = m[10]; mat[14] = m[14]; 00580 mat[3] = m[3]; mat[7] = m[7]; mat[11] = m[11]; mat[15] = m[15]; 00581 } 00582 mat4(const mat4 &m) { 00583 mat[0] = m[0]; mat[4] = m[4]; mat[8] = m[8]; mat[12] = m[12]; 00584 mat[1] = m[1]; mat[5] = m[5]; mat[9] = m[9]; mat[13] = m[13]; 00585 mat[2] = m[2]; mat[6] = m[6]; mat[10] = m[10]; mat[14] = m[14]; 00586 mat[3] = m[3]; mat[7] = m[7]; mat[11] = m[11]; mat[15] = m[15]; 00587 } 00588 00589 vec3 operator*(const vec3 &v) const { 00590 vec3 ret; 00591 ret[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12]; 00592 ret[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13]; 00593 ret[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14]; 00594 return ret; 00595 } 00596 vec4 operator*(const vec4 &v) const { 00597 vec4 ret; 00598 ret[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12] * v[3]; 00599 ret[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13] * v[3]; 00600 ret[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14] * v[3]; 00601 ret[3] = mat[3] * v[0] + mat[7] * v[1] + mat[11] * v[2] + mat[15] * v[3]; 00602 return ret; 00603 } 00604 mat4 operator*(float f) const { 00605 mat4 ret; 00606 ret[0] = mat[0] * f; ret[4] = mat[4] * f; ret[8] = mat[8] * f; ret[12] = mat[12] * f; 00607 ret[1] = mat[1] * f; ret[5] = mat[5] * f; ret[9] = mat[9] * f; ret[13] = mat[13] * f; 00608 ret[2] = mat[2] * f; ret[6] = mat[6] * f; ret[10] = mat[10] * f; ret[14] = mat[14] * f; 00609 ret[3] = mat[3] * f; ret[7] = mat[7] * f; ret[11] = mat[11] * f; ret[15] = mat[15] * f; 00610 return ret; 00611 } 00612 mat4 operator*(const mat4 &m) const { 00613 mat4 ret; 00614 ret[0] = mat[0] * m[0] + mat[4] * m[1] + mat[8] * m[2] + mat[12] * m[3]; 00615 ret[1] = mat[1] * m[0] + mat[5] * m[1] + mat[9] * m[2] + mat[13] * m[3]; 00616 ret[2] = mat[2] * m[0] + mat[6] * m[1] + mat[10] * m[2] + mat[14] * m[3]; 00617 ret[3] = mat[3] * m[0] + mat[7] * m[1] + mat[11] * m[2] + mat[15] * m[3]; 00618 ret[4] = mat[0] * m[4] + mat[4] * m[5] + mat[8] * m[6] + mat[12] * m[7]; 00619 ret[5] = mat[1] * m[4] + mat[5] * m[5] + mat[9] * m[6] + mat[13] * m[7]; 00620 ret[6] = mat[2] * m[4] + mat[6] * m[5] + mat[10] * m[6] + mat[14] * m[7]; 00621 ret[7] = mat[3] * m[4] + mat[7] * m[5] + mat[11] * m[6] + mat[15] * m[7]; 00622 ret[8] = mat[0] * m[8] + mat[4] * m[9] + mat[8] * m[10] + mat[12] * m[11]; 00623 ret[9] = mat[1] * m[8] + mat[5] * m[9] + mat[9] * m[10] + mat[13] * m[11]; 00624 ret[10] = mat[2] * m[8] + mat[6] * m[9] + mat[10] * m[10] + mat[14] * m[11]; 00625 ret[11] = mat[3] * m[8] + mat[7] * m[9] + mat[11] * m[10] + mat[15] * m[11]; 00626 ret[12] = mat[0] * m[12] + mat[4] * m[13] + mat[8] * m[14] + mat[12] * m[15]; 00627 ret[13] = mat[1] * m[12] + mat[5] * m[13] + mat[9] * m[14] + mat[13] * m[15]; 00628 ret[14] = mat[2] * m[12] + mat[6] * m[13] + mat[10] * m[14] + mat[14] * m[15]; 00629 ret[15] = mat[3] * m[12] + mat[7] * m[13] + mat[11] * m[14] + mat[15] * m[15]; 00630 return ret; 00631 } 00632 mat4 operator+(const mat4 &m) const { 00633 mat4 ret; 00634 ret[0] = mat[0] + m[0]; ret[4] = mat[4] + m[4]; ret[8] = mat[8] + m[8]; ret[12] = mat[12] + m[12]; 00635 ret[1] = mat[1] + m[1]; ret[5] = mat[5] + m[5]; ret[9] = mat[9] + m[9]; ret[13] = mat[13] + m[13]; 00636 ret[2] = mat[2] + m[2]; ret[6] = mat[6] + m[6]; ret[10] = mat[10] + m[10]; ret[14] = mat[14] + m[14]; 00637 ret[3] = mat[3] + m[3]; ret[7] = mat[7] + m[7]; ret[11] = mat[11] + m[11]; ret[15] = mat[15] + m[15]; 00638 return ret; 00639 } 00640 mat4 operator-(const mat4 &m) const { 00641 mat4 ret; 00642 ret[0] = mat[0] - m[0]; ret[4] = mat[4] - m[4]; ret[8] = mat[8] - m[8]; ret[12] = mat[12] - m[12]; 00643 ret[1] = mat[1] - m[1]; ret[5] = mat[5] - m[5]; ret[9] = mat[9] - m[9]; ret[13] = mat[13] - m[13]; 00644 ret[2] = mat[2] - m[2]; ret[6] = mat[6] - m[6]; ret[10] = mat[10] - m[10]; ret[14] = mat[14] - m[14]; 00645 ret[3] = mat[3] - m[3]; ret[7] = mat[7] - m[7]; ret[11] = mat[11] - m[11]; ret[15] = mat[15] - m[15]; 00646 return ret; 00647 } 00648 00649 mat4 &operator*=(float f) { return *this = *this * f; } 00650 mat4 &operator*=(const mat4 &m) { return *this = *this * m; } 00651 mat4 &operator+=(const mat4 &m) { return *this = *this + m; } 00652 mat4 &operator-=(const mat4 &m) { return *this = *this - m; } 00653 00654 operator float*() { return mat; } 00655 operator const float*() const { return mat; } 00656 00657 float &operator[](int i) { return mat[i]; } 00658 float operator[](int i) const { return mat[i]; } 00659 00660 mat4 rotation() const { 00661 mat4 ret; 00662 ret[0] = mat[0]; ret[4] = mat[4]; ret[8] = mat[8]; ret[12] = 0; 00663 ret[1] = mat[1]; ret[5] = mat[5]; ret[9] = mat[9]; ret[13] = 0; 00664 ret[2] = mat[2]; ret[6] = mat[6]; ret[10] = mat[10]; ret[14] = 0; 00665 ret[3] = 0; ret[7] = 0; ret[11] = 0; ret[15] = 1; 00666 return ret; 00667 } 00668 mat4 transpose() const { 00669 mat4 ret; 00670 ret[0] = mat[0]; ret[4] = mat[1]; ret[8] = mat[2]; ret[12] = mat[3]; 00671 ret[1] = mat[4]; ret[5] = mat[5]; ret[9] = mat[6]; ret[13] = mat[7]; 00672 ret[2] = mat[8]; ret[6] = mat[9]; ret[10] = mat[10]; ret[14] = mat[11]; 00673 ret[3] = mat[12]; ret[7] = mat[13]; ret[11] = mat[14]; ret[15] = mat[15]; 00674 return ret; 00675 } 00676 mat4 transpose_rotation() const { 00677 mat4 ret; 00678 ret[0] = mat[0]; ret[4] = mat[1]; ret[8] = mat[2]; ret[12] = mat[12]; 00679 ret[1] = mat[4]; ret[5] = mat[5]; ret[9] = mat[6]; ret[13] = mat[13]; 00680 ret[2] = mat[8]; ret[6] = mat[9]; ret[10] = mat[10]; ret[14] = mat[14]; 00681 ret[3] = mat[3]; ret[7] = mat[7]; ret[14] = mat[14]; ret[15] = mat[15]; 00682 return ret; 00683 } 00684 00685 float det() const { 00686 float det; 00687 det = mat[0] * mat[5] * mat[10]; 00688 det += mat[4] * mat[9] * mat[2]; 00689 det += mat[8] * mat[1] * mat[6]; 00690 det -= mat[8] * mat[5] * mat[2]; 00691 det -= mat[4] * mat[1] * mat[10]; 00692 det -= mat[0] * mat[9] * mat[6]; 00693 return det; 00694 } 00695 00696 mat4 inverse() const { 00697 mat4 ret; 00698 float idet = 1.0f / det(); 00699 ret[0] = (mat[5] * mat[10] - mat[9] * mat[6]) * idet; 00700 ret[1] = -(mat[1] * mat[10] - mat[9] * mat[2]) * idet; 00701 ret[2] = (mat[1] * mat[6] - mat[5] * mat[2]) * idet; 00702 ret[3] = 0.0; 00703 ret[4] = -(mat[4] * mat[10] - mat[8] * mat[6]) * idet; 00704 ret[5] = (mat[0] * mat[10] - mat[8] * mat[2]) * idet; 00705 ret[6] = -(mat[0] * mat[6] - mat[4] * mat[2]) * idet; 00706 ret[7] = 0.0; 00707 ret[8] = (mat[4] * mat[9] - mat[8] * mat[5]) * idet; 00708 ret[9] = -(mat[0] * mat[9] - mat[8] * mat[1]) * idet; 00709 ret[10] = (mat[0] * mat[5] - mat[4] * mat[1]) * idet; 00710 ret[11] = 0.0; 00711 ret[12] = -(mat[12] * ret[0] + mat[13] * ret[4] + mat[14] * ret[8]); 00712 ret[13] = -(mat[12] * ret[1] + mat[13] * ret[5] + mat[14] * ret[9]); 00713 ret[14] = -(mat[12] * ret[2] + mat[13] * ret[6] + mat[14] * ret[10]); 00714 ret[15] = 1.0; 00715 return ret; 00716 } 00717 00718 void zero() { 00719 mat[0] = 0.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0; 00720 mat[1] = 0.0; mat[5] = 0.0; mat[9] = 0.0; mat[13] = 0.0; 00721 mat[2] = 0.0; mat[6] = 0.0; mat[10] = 0.0; mat[14] = 0.0; 00722 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 0.0; 00723 } 00724 void identity() { 00725 mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0; 00726 mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0; 00727 mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0; 00728 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; 00729 } 00730 void rotate(const vec3 &axis,float angle) { 00731 float rad = angle * DEG2RAD; 00732 float c = cos(rad); 00733 float s = sin(rad); 00734 vec3 v = axis; 00735 v.normalize(); 00736 float xx = v.x * v.x; 00737 float yy = v.y * v.y; 00738 float zz = v.z * v.z; 00739 float xy = v.x * v.y; 00740 float yz = v.y * v.z; 00741 float zx = v.z * v.x; 00742 float xs = v.x * s; 00743 float ys = v.y * s; 00744 float zs = v.z * s; 00745 mat[0] = (1.0f - c) * xx + c; mat[4] = (1.0f - c) * xy - zs; mat[8] = (1.0f - c) * zx + ys; mat[12] = 0.0; 00746 mat[1] = (1.0f - c) * xy + zs; mat[5] = (1.0f - c) * yy + c; mat[9] = (1.0f - c) * yz - xs; mat[13] = 0.0; 00747 mat[2] = (1.0f - c) * zx - ys; mat[6] = (1.0f - c) * yz + xs; mat[10] = (1.0f - c) * zz + c; mat[14] = 0.0; 00748 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; 00749 } 00750 void rotate(float x,float y,float z,float angle) { 00751 rotate(vec3(x,y,z),angle); 00752 } 00753 void rotate_x(float angle) { 00754 float rad = angle * DEG2RAD; 00755 float c = cos(rad); 00756 float s = sin(rad); 00757 mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0; 00758 mat[1] = 0.0; mat[5] = c; mat[9] = -s; mat[13] = 0.0; 00759 mat[2] = 0.0; mat[6] = s; mat[10] = c; mat[14] = 0.0; 00760 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; 00761 } 00762 void rotate_y(float angle) { 00763 float rad = angle * DEG2RAD; 00764 float c = cos(rad); 00765 float s = sin(rad); 00766 mat[0] = c; mat[4] = 0.0; mat[8] = s; mat[12] = 0.0; 00767 mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0; 00768 mat[2] = -s; mat[6] = 0.0; mat[10] = c; mat[14] = 0.0; 00769 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; 00770 } 00771 void rotate_z(float angle) { 00772 float rad = angle * DEG2RAD; 00773 float c = cos(rad); 00774 float s = sin(rad); 00775 mat[0] = c; mat[4] = -s; mat[8] = 0.0; mat[12] = 0.0; 00776 mat[1] = s; mat[5] = c; mat[9] = 0.0; mat[13] = 0.0; 00777 mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0; 00778 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; 00779 } 00780 void scale(const vec3 &v) { 00781 mat[0] = v.x; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0; 00782 mat[1] = 0.0; mat[5] = v.y; mat[9] = 0.0; mat[13] = 0.0; 00783 mat[2] = 0.0; mat[6] = 0.0; mat[10] = v.z; mat[14] = 0.0; 00784 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; 00785 } 00786 void scale(float x,float y,float z) { 00787 scale(vec3(x,y,z)); 00788 } 00789 void translate(const vec3 &v) { 00790 mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = v.x; 00791 mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = v.y; 00792 mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = v.z; 00793 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; 00794 } 00795 void translate(float x,float y,float z) { 00796 translate(vec3(x,y,z)); 00797 } 00798 void reflect(const vec4 &plane) { 00799 float x = plane.x; 00800 float y = plane.y; 00801 float z = plane.z; 00802 float x2 = x * 2.0f; 00803 float y2 = y * 2.0f; 00804 float z2 = z * 2.0f; 00805 mat[0] = 1.0f - x * x2; mat[4] = -y * x2; mat[8] = -z * x2; mat[12] = -plane.w * x2; 00806 mat[1] = -x * y2; mat[5] = 1.0f - y * y2; mat[9] = -z * y2; mat[13] = -plane.w * y2; 00807 mat[2] = -x * z2; mat[6] = -y * z2; mat[10] = 1.0f - z * z2; mat[14] = -plane.w * z2; 00808 mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; 00809 } 00810 void reflect(float x,float y,float z,float w) { 00811 reflect(vec4(x,y,z,w)); 00812 } 00813 00814 void perspective(float fov,float aspect,float znear,float zfar) { 00815 if(fabs(fov - 90.0f) < epsilon) fov = 89.9f; 00816 float y = tan(fov * PI / 360.0f); 00817 float x = y; 00818 if(aspect > 1) 00819 x *= aspect; 00820 else 00821 y /= aspect; 00822 mat[0] = 1.0f / x; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0; 00823 mat[1] = 0.0; mat[5] = 1.0f / y; mat[9] = 0.0; mat[13] = 0.0; 00824 mat[2] = 0.0; mat[6] = 0.0; mat[10] = -(zfar + znear) / (zfar - znear); mat[14] = -(2.0f * zfar * znear) / (zfar - znear); 00825 mat[3] = 0.0; mat[7] = 0.0; mat[11] = -1.0; mat[15] = 0.0; 00826 } 00827 void look_at(const vec3 &eye,const vec3 &dir,const vec3 &up) { 00828 vec3 x,y,z; 00829 mat4 m0,m1; 00830 z = eye - dir; 00831 z.normalize(); 00832 x.cross(up,z); 00833 x.normalize(); 00834 y.cross(z,x); 00835 y.normalize(); 00836 m0[0] = x.x; m0[4] = x.y; m0[8] = x.z; m0[12] = 0.0; 00837 m0[1] = y.x; m0[5] = y.y; m0[9] = y.z; m0[13] = 0.0; 00838 m0[2] = z.x; m0[6] = z.y; m0[10] = z.z; m0[14] = 0.0; 00839 m0[3] = 0.0; m0[7] = 0.0; m0[11] = 0.0; m0[15] = 1.0; 00840 m1.translate(-eye); 00841 *this = m0 * m1; 00842 } 00843 void look_at(const float *eye,const float *dir,const float *up) { 00844 look_at(vec3(eye),vec3(dir),vec3(up)); 00845 } 00846 00847 float mat[16]; 00848 }; 00849 00850 inline mat3::mat3(const mat4 &m) { 00851 mat[0] = m[0]; mat[3] = m[4]; mat[6] = m[8]; 00852 mat[1] = m[1]; mat[4] = m[5]; mat[7] = m[9]; 00853 mat[2] = m[2]; mat[5] = m[6]; mat[8] = m[10]; 00854 } 00855 00856 /*****************************************************************************/ 00857 /* */ 00858 /* quat */ 00859 /* */ 00860 /*****************************************************************************/ 00861 00862 struct quat { 00863 00864 quat() : x(0), y(0), z(0), w(1) { } 00865 quat(const vec3 &dir,float angle) { 00866 set(dir,angle); 00867 } 00868 quat(float x,float y,float z,float angle) { 00869 set(x,y,z,angle); 00870 } 00871 quat(const mat3 &m) { 00872 float trace = m[0] + m[4] + m[8]; 00873 if(trace > 0.0) { 00874 float s = sqrt(trace + 1.0f); 00875 q[3] = 0.5f * s; 00876 s = 0.5f / s; 00877 q[0] = (m[5] - m[7]) * s; 00878 q[1] = (m[6] - m[2]) * s; 00879 q[2] = (m[1] - m[3]) * s; 00880 } else { 00881 static int next[3] = { 1, 2, 0 }; 00882 int i = 0; 00883 if(m[4] > m[0]) i = 1; 00884 if(m[8] > m[3 * i + i]) i = 2; 00885 int j = next[i]; 00886 int k = next[j]; 00887 float s = sqrt(m[3 * i + i] - m[3 * j + j] - m[3 * k + k] + 1.0f); 00888 q[i] = 0.5f * s; 00889 if(s != 0) s = 0.5f / s; 00890 q[3] = (m[3 * j + k] - m[3 * k + j]) * s; 00891 q[j] = (m[3 * i + j] + m[3 * j + i]) * s; 00892 q[k] = (m[3 * i + k] + m[3 * k + i]) * s; 00893 } 00894 } 00895 00896 operator float*() { return (float*)&x; } 00897 operator const float*() const { return (float*)&x; } 00898 00899 float &operator[](int i) { return q[i]; } 00900 float operator[](int i) const { return q[i]; } 00901 00902 quat operator*(const quat &q) const { 00903 quat ret; 00904 ret.x = w * q.x + x * q.x + y * q.z - z * q.y; 00905 ret.y = w * q.y + y * q.w + z * q.x - x * q.z; 00906 ret.z = w * q.z + z * q.w + x * q.y - y * q.x; 00907 ret.w = w * q.w - x * q.x - y * q.y - z * q.z; 00908 return ret; 00909 } 00910 00911 void set(const vec3 &dir,float angle) { 00912 float length = dir.length(); 00913 if(length != 0.0) { 00914 length = 1.0f / length; 00915 float sinangle = sin(angle * DEG2RAD / 2.0f); 00916 x = dir[0] * length * sinangle; 00917 y = dir[1] * length * sinangle; 00918 z = dir[2] * length * sinangle; 00919 w = cos(angle * DEG2RAD / 2.0f); 00920 } else { 00921 x = y = z = 0.0; 00922 w = 1.0; 00923 } 00924 } 00925 void set(float x,float y,float z,float angle) { 00926 set(vec3(x,y,z),angle); 00927 } 00928 00929 void slerp(const quat &q0,const quat &q1,float t) { 00930 float k0,k1,cosomega = q0.x * q1.x + q0.y * q1.y + q0.z * q1.z + q0.w * q1.w; 00931 quat q; 00932 if(cosomega < 0.0) { 00933 cosomega = -cosomega; 00934 q.x = -q1.x; 00935 q.y = -q1.y; 00936 q.z = -q1.z; 00937 q.w = -q1.w; 00938 } else { 00939 q.x = q1.x; 00940 q.y = q1.y; 00941 q.z = q1.z; 00942 q.w = q1.w; 00943 } 00944 if(1.0 - cosomega > 1e-6) { 00945 float omega = acos(cosomega); 00946 float sinomega = sin(omega); 00947 k0 = sin((1.0f - t) * omega) / sinomega; 00948 k1 = sin(t * omega) / sinomega; 00949 } else { 00950 k0 = 1.0f - t; 00951 k1 = t; 00952 } 00953 x = q0.x * k0 + q.x * k1; 00954 y = q0.y * k0 + q.y * k1; 00955 z = q0.z * k0 + q.z * k1; 00956 w = q0.w * k0 + q.w * k1; 00957 } 00958 00959 mat3 to_matrix() const { 00960 mat3 ret; 00961 float x2 = x + x; 00962 float y2 = y + y; 00963 float z2 = z + z; 00964 float xx = x * x2; 00965 float yy = y * y2; 00966 float zz = z * z2; 00967 float xy = x * y2; 00968 float yz = y * z2; 00969 float xz = z * x2; 00970 float wx = w * x2; 00971 float wy = w * y2; 00972 float wz = w * z2; 00973 ret[0] = 1.0f - (yy + zz); ret[3] = xy - wz; ret[6] = xz + wy; 00974 ret[1] = xy + wz; ret[4] = 1.0f - (xx + zz); ret[7] = yz - wx; 00975 ret[2] = xz - wy; ret[5] = yz + wx; ret[8] = 1.0f - (xx + yy); 00976 return ret; 00977 } 00978 00979 union { 00980 struct { 00981 float x,y,z,w; 00982 }; 00983 float q[4]; 00984 }; 00985 }; 00986 00987 //} // namespace TomGine 00988 00989 #endif /* __MATHLIB_H__ */