00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GLMATRIX_H
00021 #define GLMATRIX_H
00022 #include "GLVector.h"
00023 #include "LinearPolynomial.h"
00024 #ifdef GLMATRIX_IOSTREAM
00025 #include <iostream>
00026 #endif
00027 namespace mathglpp
00028 {
00029
00030 template <typename T>
00031
00032 inline void swap(T& a, T& b) { T temp = a; a = b; b = temp; }
00034 template <typename T>
00035 class GLMatrix
00036 {
00037 public:
00038
00040 GLMatrix()
00041 { }
00042
00044 GLMatrix(const T val)
00045 { m0=m1=m2=m3=m4=m5=m6=m7=m8=m9=m10=m11=m12=m13=m14=m15=val; }
00046
00048 GLMatrix(const T* const val)
00049 { memmove(m,val,16*sizeof(T)); }
00050
00052 GLMatrix(const T* const v0, const T* const v1, const T* const v2, const T* const v3)
00053 {
00054 memmove(m,v0,4*sizeof(T)); memmove(m+4,v1,4*sizeof(T));
00055 memmove(m+8,v2,4*sizeof(T)); memmove(m+12,v3,4*sizeof(T));
00056 }
00057
00059 GLMatrix(const GLMatrix& mat)
00060 { memmove(m,mat.m,16*sizeof(T)); }
00061
00063 ~GLMatrix()
00064 {}
00065
00067 inline const T det() const
00068 { return m0 * cofactorm0() - m1 * cofactorm1() + m2 * cofactorm2() - m3 * cofactorm3(); }
00069
00071 GLMatrix adjoint() const
00072 {
00073 GLMatrix ret;
00074 ret[0] = cofactorm0();
00075 ret[1] = -cofactorm4();
00076 ret[2] = cofactorm8();
00077 ret[3] = -cofactorm12();
00078 ret[4] = -cofactorm1();
00079 ret[5] = cofactorm5();
00080 ret[6] = -cofactorm9();
00081 ret[7] = cofactorm13();
00082 ret[8] = cofactorm2();
00083 ret[9] = -cofactorm6();
00084 ret[10] = cofactorm10();
00085 ret[11] = -cofactorm14();
00086 ret[12] = -cofactorm3();
00087 ret[13] = cofactorm7();
00088 ret[14] = -cofactorm11();
00089 ret[15] = cofactorm15();
00090 return ret;
00091 }
00092
00094 GLMatrix inverse() const
00095 {
00096 GLMatrix ret(adjoint());
00097 const T determinant = m0 * ret[0] + m1 * ret[4] + m2 * ret[8] + m3 * ret[12];
00098 assert(determinant!=0 && "Singular matrix has no inverse");
00099 ret /= determinant;
00100 return ret;
00101 }
00102
00104 GLVector4<T> eigenValues()
00105 {
00106 LinearPolynomial<T> lpoly(5);
00107 lpoly[0] = det();
00108 lpoly[1] = -_a*_f*_k -_a*_f*_p -_a*_k*_p -_f*_k*_p
00109 -(-_a -_f)*_l*_o
00110 -(-_a -_p)*_g*_j
00111 -(-_a -_k)*_h*_n
00112 -(-_k -_p)*_b*_e
00113 -(-_f -_p)*_c*_i
00114 -(-_f -_k)*_d*_n
00115 -_g*_l*_n -_h*_g*_o +_b*_g*_i -_b*_h*_m
00116 -_c*_e*_j -_c*_l*_n +_d*_i*_o;
00117 lpoly[2] = _a*(_f +_k +_p) +_f*(_k +_p) +_k*_p -_l*_o -_g*_j -_h*_n +_b*_e -_c*_i +_d*_n;
00118 lpoly[3] = -_a -_f -_k -_p;
00119 lpoly[4] = 1;
00120
00122 std::vector<T> roots = lpoly.findRoots();
00123
00124 return GLVector4<T>(roots[0], roots[1], roots[2], roots[3]);
00125 }
00126
00128 inline GLMatrix& operator= (const GLMatrix& mat)
00129 { memmove(m,mat.m,16*sizeof(T)); return *this; }
00130
00132 inline bool operator== (const GLMatrix& mat)
00133 { return memcmp(m,mat.m,16*sizeof(T))==0; }
00134
00136 inline T& operator[] (const int ind)
00137 { assert(ind > -1 && ind < 16); return m[ind]; }
00138
00140 inline operator const T*(void) const { return m; }
00141
00143 inline operator T*(void) { return m; }
00144
00146 inline GLMatrix& operator*= (const T& val)
00147 { for(register unsigned i = 0; i < 16; ++i) m[i] *= val; return *this; }
00148
00150 inline GLMatrix& operator/= (const T& val)
00151 { for(register unsigned i = 0; i < 16; ++i) m[i] /= val; return *this; }
00152
00154 inline GLMatrix& operator+= (const GLMatrix& mat)
00155 { for(register unsigned i = 0; i < 16; ++i) m[i] += mat.m[i]; return *this; }
00157 inline GLMatrix operator+ (const GLMatrix& mat)
00158 { GLMatrix ret(*this); ret += mat; return ret; }
00159
00161 inline GLMatrix& operator-= (const GLMatrix& mat)
00162 { for(register unsigned i = 0; i < 16; ++i) m[i] -= mat.m[i]; return *this; }
00163
00165 inline GLMatrix operator- (const GLMatrix& mat)
00166 { GLMatrix ret(*this); ret -= mat; return ret; }
00167
00169 inline GLMatrix operator* (const GLMatrix& mat)
00170 {
00171 GLMatrix ret;
00172 ret.m[0] = m[0]*mat.m0 + m[0+4]*mat.m1 + m[0+8]*mat.m2 + m[0+12]*mat.m3;
00173 ret.m[1] = m[1]*mat.m0 + m[1+4]*mat.m1 + m[1+8]*mat.m2 + m[1+12]*mat.m3;
00174 ret.m[2] = m[2]*mat.m0 + m[2+4]*mat.m1 + m[2+8]*mat.m2 + m[2+12]*mat.m3;
00175 ret.m[3] = m[3]*mat.m0 + m[3+4]*mat.m1 + m[3+8]*mat.m2 + m[3+12]*mat.m3;
00176 ret.m[0+4] = m[0]*mat.m4 + m[0+4]*mat.m5 + m[0+8]*mat.m6 + m[0+12]*mat.m7;
00177 ret.m[1+4] = m[1]*mat.m4 + m[1+4]*mat.m5 + m[1+8]*mat.m6 + m[1+12]*mat.m7;
00178 ret.m[2+4] = m[2]*mat.m4 + m[2+4]*mat.m5 + m[2+8]*mat.m6 + m[2+12]*mat.m7;
00179 ret.m[3+4] = m[3]*mat.m4 + m[3+4]*mat.m5 + m[3+8]*mat.m6 + m[3+12]*mat.m7;
00180 ret.m[0+8] = m[0]*mat.m8 + m[0+4]*mat.m9 + m[0+8]*mat.m10 + m[0+12]*mat.m11;
00181 ret.m[1+8] = m[1]*mat.m8 + m[1+4]*mat.m9 + m[1+8]*mat.m10 + m[1+12]*mat.m11;
00182 ret.m[2+8] = m[2]*mat.m8 + m[2+4]*mat.m9 + m[2+8]*mat.m10 + m[2+12]*mat.m11;
00183 ret.m[3+8] = m[3]*mat.m8 + m[3+4]*mat.m9 + m[3+8]*mat.m10 + m[3+12]*mat.m11;
00184 ret.m[0+12] = m[0]*mat.m12 + m[0+4]*mat.m13 + m[0+8]*mat.m14 + m[0+12]*mat.m15;
00185 ret.m[1+12] = m[1]*mat.m12 + m[1+4]*mat.m13 + m[1+8]*mat.m14 + m[1+12]*mat.m15;
00186 ret.m[2+12] = m[2]*mat.m12 + m[2+4]*mat.m13 + m[2+8]*mat.m14 + m[2+12]*mat.m15;
00187 ret.m[3+12] = m[3]*mat.m12 + m[3+4]*mat.m13 + m[3+8]*mat.m14 + m[3+12]*mat.m15;
00188 return ret;
00189 }
00190
00192 inline GLMatrix& operator*= (const GLMatrix& mat)
00193 {
00194 GLMatrix temp(*this);
00195 m[0] = temp.m[0]*mat.m0 + temp.m[0+4]*mat.m1 + temp.m[0+8]*mat.m2 + temp.m[0+12]*mat.m3;
00196 m[1] = temp.m[1]*mat.m0 + temp.m[1+4]*mat.m1 + temp.m[1+8]*mat.m2 + temp.m[1+12]*mat.m3;
00197 m[2] = temp.m[2]*mat.m0 + temp.m[2+4]*mat.m1 + temp.m[2+8]*mat.m2 + temp.m[2+12]*mat.m3;
00198 m[3] = temp.m[3]*mat.m0 + temp.m[3+4]*mat.m1 + temp.m[3+8]*mat.m2 + temp.m[3+12]*mat.m3;
00199 m[0+4] = temp.m[0]*mat.m4 + temp.m[0+4]*mat.m5 + temp.m[0+8]*mat.m6 + temp.m[0+12]*mat.m7;
00200 m[1+4] = temp.m[1]*mat.m4 + temp.m[1+4]*mat.m5 + temp.m[1+8]*mat.m6 + temp.m[1+12]*mat.m7;
00201 m[2+4] = temp.m[2]*mat.m4 + temp.m[2+4]*mat.m5 + temp.m[2+8]*mat.m6 + temp.m[2+12]*mat.m7;
00202 m[3+4] = temp.m[3]*mat.m4 + temp.m[3+4]*mat.m5 + temp.m[3+8]*mat.m6 + temp.m[3+12]*mat.m7;
00203 m[0+8] = temp.m[0]*mat.m8 + temp.m[0+4]*mat.m9 + temp.m[0+8]*mat.m10 + temp.m[0+12]*mat.m11;
00204 m[1+8] = temp.m[1]*mat.m8 + temp.m[1+4]*mat.m9 + temp.m[1+8]*mat.m10 + temp.m[1+12]*mat.m11;
00205 m[2+8] = temp.m[2]*mat.m8 + temp.m[2+4]*mat.m9 + temp.m[2+8]*mat.m10 + temp.m[2+12]*mat.m11;
00206 m[3+8] = temp.m[3]*mat.m8 + temp.m[3+4]*mat.m9 + temp.m[3+8]*mat.m10 + temp.m[3+12]*mat.m11;
00207 m[0+12] = temp.m[0]*mat.m12 + temp.m[0+4]*mat.m13 + temp.m[0+8]*mat.m14 + temp.m[0+12]*mat.m15;
00208 m[1+12] = temp.m[1]*mat.m12 + temp.m[1+4]*mat.m13 + temp.m[1+8]*mat.m14 + temp.m[1+12]*mat.m15;
00209 m[2+12] = temp.m[2]*mat.m12 + temp.m[2+4]*mat.m13 + temp.m[2+8]*mat.m14 + temp.m[2+12]*mat.m15;
00210 m[3+12] = temp.m[3]*mat.m12 + temp.m[3+4]*mat.m13 + temp.m[3+8]*mat.m14 + temp.m[3+12]*mat.m15;
00211 return *this;
00212 }
00213
00216 inline GLMatrix& mult3by3(const GLMatrix& mat)
00217 {
00218 GLMatrix temp(*this);
00219 m0 = temp.m0*mat.m0+temp.m4*mat.m1+temp.m8*mat.m2;
00220 m4 = temp.m0*mat.m4+temp.m4*mat.m5+temp.m8*mat.m6;
00221 m8 = temp.m0*mat.m8+temp.m4*mat.m9+temp.m8*mat.m10;
00222 m1 = temp.m1*mat.m0+temp.m5*mat.m1+temp.m9*mat.m2;
00223 m5 = temp.m1*mat.m4+temp.m5*mat.m5+temp.m9*mat.m6;
00224 m9 = temp.m1*mat.m8+temp.m5*mat.m9+temp.m9*mat.m10;
00225 m2 = temp.m2*mat.m0+temp.m6*mat.m1+temp.m10*mat.m2;
00226 m6 = temp.m2*mat.m4+temp.m6*mat.m5+temp.m10*mat.m6;
00227 m10 = temp.m2*mat.m8+temp.m6*mat.m9+temp.m10*mat.m10;
00228 m3 = temp.m3*mat.m0+temp.m7*mat.m1+temp.m11*mat.m2;
00229 m7 = temp.m3*mat.m4+temp.m7*mat.m5+temp.m11*mat.m6;
00230 m11 = temp.m3*mat.m8+temp.m7*mat.m9+temp.m11*mat.m10;
00231 return *this;
00232 }
00233
00235 inline GLVector4<T> operator* (const GLVector4<T>& vec)
00236 {
00237 GLVector4<T> ret;
00238 ret.val[0] = vec.x * m[0] + vec.y * m[0+4] + vec.z * m[0+8] + vec.w * m[0+12];
00239 ret.val[1] = vec.x * m[1] + vec.y * m[1+4] + vec.z * m[1+8] + vec.w * m[1+12];
00240 ret.val[2] = vec.x * m[2] + vec.y * m[2+4] + vec.z * m[2+8] + vec.w * m[2+12];
00241 ret.val[3] = vec.x * m[3] + vec.y * m[3+4] + vec.z * m[3+8] + vec.w * m[3+12];
00242 return ret;
00243 }
00244
00246 inline GLVector3<T> operator* (const GLVector3<T>& vec)
00247 {
00248 GLVector3<T> ret;
00249
00250 ret[0] = vec[0] * m[0] + vec[1] * m[0+4] + vec[2] * m[0+8] + m[0+12];
00251 ret[1] = vec[0] * m[1] + vec[1] * m[1+4] + vec[2] * m[1+8] + m[1+12];
00252 ret[2] = vec[0] * m[2] + vec[1] * m[2+4] + vec[2] * m[2+8] + m[2+12];
00253
00254 register T resip = 1 / (vec[0]*m[3] + vec[1]*m[3+4] + vec[2]*m[3+8] + m[3+12]);
00255 ret[0] *= resip;
00256 ret[1] *= resip;
00257 ret[2] *= resip;
00258 return ret;
00259 }
00260
00262 inline GLVector2<T> operator* (const GLVector2<T>& vec)
00263 {
00264 GLVector2<T> ret;
00265 ret[0] = vec[0]*m[0] + vec[1]*m[0+4] + m[0+12];
00266 ret[1] = vec[0]*m[1] + vec[1]*m[1+4] + m[1+12];
00267
00268
00269 register T resip = 1/(vec[0]*m[3] + vec[1]*m[3+4] + m[3+12]);
00270 ret[0] *= resip;
00271 ret[1] *= resip;
00272 return ret;
00273 }
00274
00276 inline GLVector4<T> operator* (const T* const v_arr)
00277 {
00278 GLVector4<T> ret;
00279 ret.val[0] = v_arr[0]*m[0] + v_arr[1]*m[0+4] + v_arr[2]*m[0+8] + v_arr[3]*m[0+12];
00280 ret.val[1] = v_arr[0]*m[1] + v_arr[1]*m[1+4] + v_arr[2]*m[1+8] + v_arr[3]*m[1+12];
00281 ret.val[2] = v_arr[0]*m[2] + v_arr[1]*m[2+4] + v_arr[2]*m[2+8] + v_arr[3]*m[2+12];
00282 ret.val[3] = v_arr[0]*m[3] + v_arr[1]*m[3+4] + v_arr[2]*m[3+8] + v_arr[3]*m[3+12];
00283 return ret;
00284 }
00285
00287 inline GLVector2<T> dot2 (const T* const v_arr) const
00288 {
00289 GLVector2<T> ret;
00290 ret[0] = v_arr[0]*m[0] + v_arr[1]*m[0+4] + m[0+12];
00291 ret[1] = v_arr[0]*m[1] + v_arr[1]*m[1+4] + m[1+12];
00292
00293
00294 register T resip = 1/(v_arr[0]*m[3] + v_arr[1]*m[3+4] + m[3+12]);
00295 ret[0] *= resip;
00296 ret[1] *= resip;
00297 return ret;
00298 }
00299
00301 inline GLVector2<T> dot2 (const T x, const T y, const T w = 1) const
00302 {
00303 GLVector2<T> ret;
00304 ret[0] = x*m[0] + y*m[0+4] + w*m[0+12];
00305 ret[0] = x*m[0] + y*m[1+4] + w*m[1+12];
00307 T resip = 1/(x*m[3] + y*m[3+4] + w*m[3+12]);
00308 ret[0] *= resip;
00309 ret[1] *= resip;
00310 return ret;
00311 }
00312
00314 inline void vdot2 (T* const v_arr, const T w = 1) const
00315 {
00316 const T x = v_arr[0];
00317 const T y = v_arr[1];
00318 v_arr[0] = x * m[0] + y * m[0+4] + w * m[0+12];
00319 v_arr[1] = x * m[1] + y * m[1+4] + w * m[1+12];
00321 T resip = 1 / (x * m[3] + y * m[3+4] + w * m[3+12]);
00322 v_arr[0] *= resip;
00323 v_arr[1] *= resip;
00324 }
00325
00327 inline GLVector3<T> dot3 (const T* const v_arr) const
00328 {
00329 GLVector3<T> ret;
00330
00331 ret[0] = v_arr[0]*m[0] + v_arr[1]*m[0+4] + v_arr[2]*m[0+8] + m[0+12];
00332 ret[1] = v_arr[0]*m[1] + v_arr[1]*m[1+4] + v_arr[2]*m[1+8] + m[1+12];
00333 ret[2] = v_arr[0]*m[2] + v_arr[1]*m[2+4] + v_arr[2]*m[2+8] + m[2+12];
00334
00335 register T resip = 1/(v_arr[0]*m[3] + v_arr[1]*m[3+4] + v_arr[2]*m[3+8] + m[3+12]);
00336 ret[0] *= resip;
00337 ret[1] *= resip;
00338 ret[2] *= resip;
00339 return ret;
00340 }
00341
00343 inline GLVector3<T> dot3 (const T x, const T y, const T z, const T w = 1) const
00344 {
00345 GLVector3<T> ret;
00346 ret[0] = x * m[0] + y * m[0 + 4] + z * m[0 + 8] + w * m[0 + 12];
00347 ret[1] = x * m[1] + y * m[1 + 4] + z * m[1 + 8] + w * m[1 + 12];
00348 ret[1] = x * m[2] + y * m[2 + 4] + z * m[2 + 8] + w * m[2 + 12];
00350 const T resip = 1 / (x * m[3] + y * m[3 + 4] + z * m[3 + 8] + w * m[3 + 12]);
00351 ret[0] *= resip;
00352 ret[1] *= resip;
00353 ret[2] *= resip;
00354 return ret;
00355 }
00356
00358 inline void vdot3 (T* const v_arr, const T w = 1) const
00359 {
00360 const T x = v_arr[0];
00361 const T y = v_arr[1];
00362 const T z = v_arr[2];
00363
00364 v_arr[0] = x * m[0] + y * m[0 + 4] + z * m[0 + 8] + w * m[0 + 12];
00365 v_arr[1] = x * m[1] + y * m[1 + 4] + z * m[1 + 8] + w * m[1 + 12];
00366 v_arr[2] = x * m[2] + y * m[2 + 4] + z * m[2 + 8] + w * m[2 + 12];
00368 const T resip = 1 / (x * m[3] + y * m[3 + 4] + z * m[3 + 8] + w * m[3 + 12]);
00369 v_arr[0] *= resip;
00370 v_arr[1] *= resip;
00371 v_arr[2] *= resip;
00372 }
00373
00375 inline GLVector4<T> dot4 (const T* const v_arr) const
00376 {
00377 GLVector4<T> ret;
00378 const T x = v_arr[0];
00379 const T y = v_arr[1];
00380 const T z = v_arr[2];
00381 const T w = v_arr[3];
00382
00383
00384 ret[0] = x * m[0] + y * m[0 + 4] + z * m[0 + 8] + w * m[0 + 12];
00385 ret[1] = x * m[1] + y * m[1 + 4] + z * m[1 + 8] + w * m[1 + 12];
00386 ret[2] = x * m[2] + y * m[2 + 4] + z * m[2 + 8] + w * m[2 + 12];
00387 ret[3] = x * m[3] + y * m[3 + 4] + z * m[3 + 8] + w * m[3 + 12];
00388 return ret;
00389 }
00390
00392 inline void vdot4 (T* const v_arr) const
00393 {
00394 const T x = v_arr[0];
00395 const T y = v_arr[1];
00396 const T z = v_arr[2];
00397 const T w = v_arr[3];
00398 v_arr[0] = x * m[0] + y * m[0 + 4] + z * m[0 + 8] + w * m[0 + 12];
00399 v_arr[1] = x * m[1] + y * m[1 + 4] + z * m[1 + 8] + w * m[1 + 12];
00400 v_arr[2] = x * m[2] + y * m[2 + 4] + z * m[2 + 8] + w * m[2 + 12];
00401 v_arr[3] = x * m[3] + y * m[3 + 4] + z * m[3 + 8] + w * m[3 + 12];
00402 }
00403
00405 inline GLVector4<T> dot4 (const T x, const T y, const T z, const T w)
00406 {
00407 GLVector4<T> ret;
00408 ret.val[0] = x * m[0] + y * m[0+4] + z * m[0+8] + w * m[0+12];
00409 ret.val[1] = x * m[1] + y * m[1+4] + z * m[1+8] + w * m[1+12];
00410 ret.val[2] = x * m[2] + y * m[2+4] + z * m[2+8] + w * m[2+12];
00411 ret.val[3] = x * m[3] + y * m[3+4] + z * m[3+8] + w * m[3+12];
00412 return ret;
00413 }
00414
00416 inline void glVertex3v(const T* const v_arr)
00417 {
00418 (this->dot3(v_arr)).glVertex();
00419 }
00420
00422 inline void glVertex3(const T x, const T y, const T z)
00423 {
00424 (this->dot3(x,y,z)).glVertex();
00425 }
00426
00428 inline void glVertex4v(const T* const v_arr)
00429 {
00430 (this->operator *(v_arr)).glVertex();
00431 }
00432
00434 inline void glVertex4(const T x, const T y, const T z, const T w)
00435 {
00436 (this->dot4(x,y,z,w)).glVertex();
00437 }
00438
00440 void glVertex3v(const int num, const T* const v_arr);
00441
00443 void glVertex4v(const int num, const T* const v_arr);
00444
00446 inline void glMultMatrix(void) { mathglpp::glMultMatrix<T>(m); };
00448 inline void glLoadMatrix(void) { mathglpp::glLoadMatrix<T>(m); };
00450 inline void glGet(const GLenum pname) { mathglpp::glGet<T>(pname,m); };
00451
00453 inline GLMatrix& transpose(void)
00454 {
00455 swap(m1,m4); swap(m2,m8); swap(m3,m12);
00456 swap(m6,m9); swap(m7,m13); swap(m11,m14);
00457
00458 return *this;
00459 }
00460
00462 inline GLMatrix getTranspose(void)
00463 {
00464 return (GLMatrix(this).transpose());
00465 }
00466
00469 static GLMatrix identity(void)
00470 {
00471 GLMatrix ret;
00472
00473 ret.m0 = 1; ret.m4 = 0; ret.m8 = 0; ret.m12 = 0;
00474 ret.m1 = 0; ret.m5 = 1; ret.m9 = 0; ret.m13 = 0;
00475 ret.m2 = 0; ret.m6 = 0; ret.m10 = 1; ret.m14 = 0;
00476 ret.m3 = 0; ret.m7 = 0; ret.m11 = 0; ret.m15 = 1;
00477
00478 return ret;
00479 }
00480
00482 inline GLMatrix& loadIdentity(void)
00483 {
00484 m0 = 1; m4 = 0; m8 = 0; m12 = 0;
00485 m1 = 0; m5 = 1; m9 = 0; m13 = 0;
00486 m2 = 0; m6 = 0; m10 = 1; m14 = 0;
00487 m3 = 0; m7 = 0; m11 = 0; m15 = 1;
00488
00489 return *this;
00490 }
00491
00493 static GLMatrix zero(void)
00494 {
00495 return GLMatrix(T(0));
00496 }
00497
00499 inline GLMatrix& loadZero(void)
00500 {
00501 m0 = 0; m4 = 0; m8 = 0; m12 = 0;
00502 m1 = 0; m5 = 0; m9 = 0; m13 = 0;
00503 m2 = 0; m6 = 0; m10 = 0; m14 = 0;
00504 m3 = 0; m7 = 0; m11 = 0; m15 = 0;
00505
00506 return *this;
00507 }
00508
00510 static GLMatrix glRotate(const T angle, T x, T y, T z);
00511
00513 inline GLMatrix& loadRotate(const T angle, T x, T y, T z)
00514 {
00515 register T magSqr = x*x + y*y + z*z;
00516 if(magSqr != 1.0)
00517 {
00518 const T mag = sqrt(magSqr);
00519 x /= mag;
00520 y /= mag;
00521 z /= mag;
00522 }
00523 const T c = T(cos(angle * M_PI / 180));
00524 const T s = T(sin(angle * M_PI / 180));
00525 m0 = x*x*(1-c)+c;
00526 m1 = y*x*(1-c)+z*s;
00527 m2 = z*x*(1-c)-y*s;
00528 m3 = 0;
00529
00530 m4 = x*y*(1-c)-z*s;
00531 m5 = y*y*(1-c)+c;
00532 m6 = z*y*(1-c)+x*s;
00533 m7 = 0;
00534
00535 m8 = x*z*(1-c)+y*s;
00536 m9 = y*z*(1-c)-x*s;
00537 m10 = z*z*(1-c)+c;
00538 m11 = 0;
00539
00540 m12 = 0;
00541 m13 = 0;
00542 m14 = 0;
00543 m15 = 1;
00544
00545 return *this;
00546 }
00547
00550 inline GLMatrix& loadRotateX(const T angle)
00551 {
00552 const T c = T(cos(angle * M_PI / 180));
00553 const T s = T(sin(angle * M_PI / 180));
00554 m0 = 1;
00555 m1 = 0;
00556 m2 = 0;
00557 m3 = 0;
00558
00559 m4 = 0;
00560 m5 = c;
00561 m6 = s;
00562 m7 = 0;
00563
00564 m8 = 0;
00565 m9 = -s;
00566 m10 = c;
00567 m11 = 0;
00568
00569 m12 = 0;
00570 m13 = 0;
00571 m14 = 0;
00572 m15 = 1;
00573
00574 return *this;
00575 }
00576
00578 inline GLMatrix& loadRotateY(const T angle)
00579 {
00580 const T c = T(cos(angle * M_PI / 180));
00581 const T s = T(sin(angle * M_PI / 180));
00582 m0 = c;
00583 m1 = 0;
00584 m2 = -s;
00585 m3 = 0;
00586
00587 m4 = 0;
00588 m5 = 1;
00589 m6 = 0;
00590 m7 = 0;
00591
00592 m8 = s;
00593 m9 = 0;
00594 m10 = c;
00595 m11 = 0;
00596
00597 m12 = 0;
00598 m13 = 0;
00599 m14 = 0;
00600 m15 = 1;
00601
00602 return *this;
00603 }
00604
00606 inline GLMatrix& loadRotateZ(const T angle)
00607 {
00608 const T c = T(cos(angle * M_PI / 180));
00609 const T s = T(sin(angle * M_PI / 180));
00610 m0 = c;
00611 m1 = s;
00612 m2 = 0;
00613 m3 = 0;
00614
00615 m4 = -s;
00616 m5 = c;
00617 m6 = 0;
00618 m7 = 0;
00619
00620 m8 = 0;
00621 m9 = 0;
00622 m10 = 1;
00623 m11 = 0;
00624
00625 m12 = 0;
00626 m13 = 0;
00627 m14 = 0;
00628 m15 = 1;
00629
00630 return *this;
00631 }
00632
00634 inline GLMatrix& applyRotate(const T angle, const T x, const T y, const T z)
00635 {
00636 static GLMatrix temp;
00637 temp.loadRotate(angle, x, y, z);
00638 return mult3by3(temp);
00639 }
00640
00643 inline GLMatrix& applyRotateX(const T angle)
00644 {
00645 static GLMatrix temp;
00646 temp.loadRotateX(angle);
00647 return mult3by3(temp);
00648 }
00649
00651 inline GLMatrix& applyRotateY(const T angle)
00652 {
00653 static GLMatrix temp;
00654 temp.loadRotateY(angle);
00655 return mult3by3(temp);
00656 }
00657
00659 inline GLMatrix& applyRotateZ(const T angle)
00660 {
00661 static GLMatrix temp;
00662 temp.loadRotateZ(angle);
00663 return mult3by3(temp);
00664 }
00665
00667 GLMatrix& applyRotateXYZ(const T x, const T y, const T z)
00668 {
00669 static GLMatrix temp;
00670 temp.loadRotateX(x);
00671 mult3by3(temp);
00672 temp.loadRotateY(y);
00673 mult3by3(temp);
00674 temp.loadRotateZ(z);
00675 return mult3by3(temp);
00676 }
00677
00679 static GLMatrix glScale(const T x, const T y, const T z)
00680 {
00681 GLMatrix ret;
00682 ret.m0 = x; ret.m4 = 0; ret.m8 = 0; ret.m12 = 0;
00683 ret.m1 = 0; ret.m5 = y; ret.m9 = 0; ret.m13 = 0;
00684 ret.m2 = 0; ret.m6 = 0; ret.m10 = z; ret.m14 = 0;
00685 ret.m3 = 0; ret.m7 = 0; ret.m11 = 0; ret.m15 = 1;
00686 return ret;
00687 }
00688
00690 inline GLMatrix& loadScale(const T x, const T y, const T z)
00691 {
00692 m0 = x; m4 = 0; m8 = 0; m12 = 0;
00693 m1 = 0; m5 = y; m9 = 0; m13 = 0;
00694 m2 = 0; m6 = 0; m10 = z; m14 = 0;
00695 m3 = 0; m7 = 0; m11 = 0; m15 = 1;
00696 return *this;
00697 }
00698
00700 inline GLMatrix& applyScale(const T x, const T y)
00701 {
00702
00703
00704 m0 *= x; m1 *= x; m2 *= x; m3 *= x;
00705 m4 *= y; m5 *= y; m6 *= y; m7 *= y;
00706 return *this;
00707 }
00708
00710 inline GLMatrix& applyScale(const T x, const T y, const T z)
00711 {
00712
00713 m0 *= x; m1 *= x; m2 *= x; m3 *= x;
00714 m4 *= y; m5 *= y; m6 *= y; m7 *= y;
00715 m8 *= z; m9 *= z; m10 *= z; m11 *= z;
00716 return *this;
00717 }
00718
00720 inline GLMatrix& applyScale(const GLVector2<T>& scale)
00721 {
00722
00723
00724 m0 *= scale.x; m1 *= scale.x; m2 *= scale.x; m3 *= scale.x;
00725 m4 *= scale.y; m5 *= scale.y; m6 *= scale.y; m7 *= scale.y;
00726 return *this;
00727 }
00728
00730 inline GLMatrix& applyScale(const GLVector3<T>& scale)
00731 {
00732
00733 m0 *= scale.x; m1 *= scale.x; m2 *= scale.x; m3 *= scale.x;
00734 m4 *= scale.y; m5 *= scale.y; m6 *= scale.y; m7 *= scale.y;
00735 m8 *= scale.z; m9 *= scale.z; m10 *= scale.z; m11 *= scale.z;
00736 return *this;
00737 }
00738
00740 static GLMatrix glTranslate(const T x, const T y, const T z);
00741
00743 inline GLMatrix& loadTranslate(const T x, const T y, const T z)
00744 {
00745 m0 = 1; m4 = 0; m8 = 0; m12 = x;
00746 m1 = 0; m5 = 1; m9 = 0; m13 = y;
00747 m2 = 0; m6 = 0; m10 = 1; m14 = z;
00748 m3 = 0; m7 = 0; m11 = 0; m15 = 1;
00749 return *this;
00750 }
00751
00753 inline GLMatrix& applyTranslate(const T x, const T y)
00754 {
00755
00756
00757 m12 += m0*x + m4*y;
00758 m13 += m1*x + m5*y;
00759 m14 += m2*x + m6*y;
00760 return *this;
00761 }
00762
00764 inline GLMatrix& applyTranslate(const T x, const T y, const T z)
00765 {
00766
00767 m12 += m0*x + m4*y + m8*z;
00768 m13 += m1*x + m5*y + m9*z;
00769 m14 += m2*x + m6*y + m10*z;
00770 return *this;
00771 }
00772
00774 inline GLMatrix& applyTranslate(const GLVector2<T>& trans)
00775 {
00776
00777
00778 m12 += m0 * trans.x + m4 * trans.y;
00779 m13 += m1 * trans.x + m5 * trans.y;
00780 m14 += m2 * trans.x + m6 * trans.y;
00781 return *this;
00782 }
00783
00785 inline GLMatrix& applyTranslate(const GLVector3<T>& trans)
00786 {
00787
00788 m12 += m0 * trans.x + m4 * trans.y + m8 * trans.z;
00789 m13 += m1 * trans.x + m5 * trans.y + m9 * trans.z;
00790 m14 += m2 * trans.x + m6 * trans.y + m10 * trans.z;
00791 return *this;
00792 }
00793
00794 #define glFrustrum glFrustum
00796 static GLMatrix glFrustum(const GLdouble left, const GLdouble right,
00797 const GLdouble bottom, const GLdouble top,
00798 const GLdouble zNear, const GLdouble zFar)
00799 {
00800 GLMatrix ret;
00801 ret.m0 = T(2 * zNear / (right - left));
00802 ret.m1 = 0;
00803 ret.m2 = 0;
00804 ret.m3 = 0;
00805
00806 ret.m4 = 0;
00807 ret.m5 = T(2 * zNear / (top - bottom));
00808 ret.m6 = 0;
00809 ret.m7 = 0;
00810
00811 ret.m8 = T((right + left) / (right - left));
00812 ret.m9 = T((top + bottom) / (top - bottom));
00813 ret.m10 = -T((zFar + zNear) / (zFar - zNear));
00814 ret.m11 = -1;
00815
00816 ret.m12 = 0;
00817 ret.m13 = 0;
00818 ret.m14 = -T(2 * zFar * zNear / (zFar - zNear));
00819 ret.m15 = 0;
00820
00821 return ret;
00822 }
00823
00824 #define loadFrustrum loadFrustum
00826 inline GLMatrix& loadFrustum(const GLdouble left, const GLdouble right,
00827 const GLdouble bottom, const GLdouble top,
00828 const GLdouble zNear, const GLdouble zFar)
00829 {
00830 m0 = T(2 * zNear / (right-left));
00831 m1 = 0;
00832 m2 = 0;
00833 m3 = 0;
00834
00835 m4 = 0;
00836 m5 = T(2 * zNear / (top-bottom));
00837 m6 = 0;
00838 m7 = 0;
00839
00840 m8 = T((right + left) / (right - left));
00841 m9 = T((top + bottom) / (top - bottom));
00842 m10 = -T((zFar + zNear) / (zFar - zNear));
00843 m11 = -1;
00844
00845 m12 = 0;
00846 m13 = 0;
00847 m14 = T(-2 * zFar * zNear / (zFar - zNear));
00848 m15 = 0;
00849
00850 return *this;
00851 }
00852
00854 static GLMatrix glOrtho(const GLdouble left, const GLdouble right,
00855 const GLdouble bottom, const GLdouble top,
00856 const GLdouble zNear, const GLdouble zFar)
00857 {
00858 GLMatrix ret;
00859 ret.m0 = T(2 / (right - left));
00860 ret.m1 = 0;
00861 ret.m2 = 0;
00862 ret.m3 = 0;
00863
00864 ret.m4 = 0;
00865 ret.m5 = T(2 / (top - bottom));
00866 ret.m6 = 0;
00867 ret.m7 = 0;
00868
00869 ret.m8 = 0;
00870 ret.m9 = 0;
00871 ret.m10 = T(-2 / (zFar - zNear));
00872 ret.m11 = 0;
00873
00874 ret.m12 = -T((right + left) / (right - left));
00875 ret.m13 = -T((top + bottom) / (top - bottom));
00876 ret.m14 = -T((zFar + zNear) / (zFar - zNear));
00877 ret.m15 = 1;
00878
00879 return ret;
00880 }
00881
00883 inline GLMatrix& loadOrtho(const GLdouble left, const GLdouble right,
00884 const GLdouble bottom, const GLdouble top,
00885 const GLdouble zNear, const GLdouble zFar)
00886 {
00887 m0 = T(2 / (right - left));
00888 m1 = 0;
00889 m2 = 0;
00890 m3 = 0;
00891
00892 m4 = 0;
00893 m5 = T(2 / (top - bottom));
00894 m6 = 0;
00895 m7 = 0;
00896
00897 m8 = 0;
00898 m9 = 0;
00899 m10 = -T(2 / (zFar - zNear));
00900 m11 = 0;
00901
00902 m12 = -T((right + left) / (right - left));
00903 m13 = -T((top + bottom) / (top - bottom));
00904 m14 = -T((zFar + zNear) / (zFar - zNear));
00905 m15 = 1;
00906
00907 return *this;
00908 }
00909
00911 inline GLMatrix& loadView(const T fx, const T fy, const T fz,
00912 const T ux, const T uy, const T uz,
00913 const T sx, const T sy, const T sz)
00914 {
00915 m0 = sx;
00916 m1 = ux;
00917 m2 = -fx;
00918 m3 = 0;
00919
00920 m4 = sy;
00921 m5 = uy;
00922 m6 = -fy;
00923 m7 = 0;
00924
00925 m8 = sz;
00926 m9 = uz;
00927 m10 = -fz;
00928 m11 = 0;
00929
00930 m12 = 0;
00931 m13 = 0;
00932 m14 = 0;
00933 m15 = 1;
00934
00935 return *this;
00936 }
00937
00939 inline GLMatrix& loadView(const T* const f, const T* const u, const T* const s)
00940 {
00941 m0 = s[0];
00942 m1 = u[0];
00943 m2 = -f[0];
00944 m3 = 0;
00945
00946 m4 = s[1];
00947 m5 = u[1];
00948 m6 = -f[1];
00949 m7 = 0;
00950
00951 m8 = s[2];
00952 m9 = u[2];
00953 m10 = -f[2];
00954 m11 = 0;
00955
00956 m12 = 0;
00957 m13 = 0;
00958 m14 = 0;
00959 m15 = 1;
00960
00961 return *this;
00962 }
00963
00965 inline GLMatrix& loadView(const GLVector3<T>& front, const GLVector3<T>& up, const GLVector3<T> side)
00966 {
00967 m0 = side.x;
00968 m1 = up.x;
00969 m2 = -front.x;
00970 m3 = 0;
00971
00972 m4 = side.y;
00973 m5 = up.y;
00974 m6 = -front.y;
00975 m7 = 0;
00976
00977 m8 = side.z;
00978 m9 = up.z;
00979 m10 = -front.z;
00980 m11 = 0;
00981
00982 m12 = 0;
00983 m13 = 0;
00984 m14 = 0;
00985 m15 = 1;
00986
00987 return *this;
00988 }
00989
00990
00991 #ifdef GLMATRIX_IOSTREAM
00994 friend std::basic_istream<char, std::char_traits<char> >& operator >>
00995 ( std::basic_istream<char, std::char_traits<char> >& in, GLMatrix& mat)
00996 {
00997 for(int j = 0; j < 4; ++j)
00998 for(int i = 0; i < 4; ++i)
00999 in>>mat[i*4+j];
01000 return in;
01001 }
01002
01005 friend std::basic_ostream<char, std::char_traits<char> >& operator <<
01006 ( std::basic_ostream<char, std::char_traits<char> >& out, GLMatrix& mat)
01007 {
01008 for(int j = 0; j < 4; ++j)
01009 {
01010 for(int i = 0; i < 4; ++i)
01011 {
01012 out<<mat[i*4+j]<<" ";
01013 }
01014 out<<std::endl;
01015 }
01016 return out;
01017 }
01018 #endif
01019
01020
01021 protected:
01022
01041 #define cofactor_maker(f1,mj1,mi1, f2,mj2,mi2, f3,mj3,mi3) \
01042 f1*(mj1*mi1-mj2*mi3) + f2*(mj2*mi2-mj3*mi1) + f3*(mj3*mi3-mj1*mi2)
01043
01044
01046 inline const T cofactorm0() const { return cofactor_maker(m5,m10,m15, m6,m11,m13, m7,m9,m14); }
01048 inline const T cofactorm1() const { return cofactor_maker(m6,m11,m12, m7,m8,m14, m4,m10,m15); }
01050 inline const T cofactorm2() const { return cofactor_maker(m7,m8,m13, m4,m9,m15, m5,m11,m12); }
01052 inline const T cofactorm3() const { return cofactor_maker(m4,m9,m14, m5,m10,m12, m6,m8,m13); }
01053
01055 inline const T cofactorm4() const { return cofactor_maker(m9,m14,m3, m10,m15,m1, m11,m13,m2); }
01057 inline const T cofactorm5() const { return cofactor_maker(m10,m15,m0, m11,m12,m2, m8,m14,m3); }
01059 inline const T cofactorm6() const { return cofactor_maker(m11,m12,m1, m8,m13,m3, m9,m15,m0); }
01061 inline const T cofactorm7() const { return cofactor_maker(m8,m13,m2, m9,m14,m0, m10,m12,m1); }
01062
01064 inline const T cofactorm8() const { return cofactor_maker(m13,m2,m7, m14,m3,m5, m15,m1,m6); }
01066 inline const T cofactorm9() const { return cofactor_maker(m14,m13,m4, m15,m0,m6, m12,m2,m7); }
01068 inline const T cofactorm10() const { return cofactor_maker(m15,m0,m5, m12,m1,m7, m13,m3,m4); }
01070 inline const T cofactorm11() const { return cofactor_maker(m12,m1,m6, m13,m2,m4, m14,m0,m5); }
01071
01073 inline const T cofactorm12() const { return cofactor_maker(m1,m6,m11, m2,m7,m9, m3,m5,m10); }
01075 inline const T cofactorm13() const { return cofactor_maker(m2,m7,m8, m3,m4,m10, m10,m6,m11); }
01077 inline const T cofactorm14() const { return cofactor_maker(m3,m4,m9, m0,m5,m11, m1,m7,m8); }
01079 inline const T cofactorm15() const { return cofactor_maker(m0,m5,m10, m1,m6,m8, m2,m4,m9); }
01080
01081 private:
01084 union
01085 {
01087 T m[16];
01089 T m_c_r[4][4];
01090 struct
01091 {
01093 T m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15;
01094 };
01095 struct
01096 {
01098 T _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,_p;
01099 };
01100 };
01101 };
01102
01103 typedef GLMatrix<GLfloat> GLMatrix4f;
01104 typedef GLMatrix<GLdouble> GLMatrix4d;
01105
01106
01107
01108 }
01109
01110 #endif
01111