GLMatrix.h

00001 /***************************************************************************
00002  *   Copyright (C) 2004 by Jacques Gasselin                                *
00003  *   jacquesgasselin@hotmail.com                                           *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Library General Public License as       *
00007  *   published by the Free Software Foundation; either version 2 of the    *
00008  *   License, or (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 Library General Public     *
00016  *   License along with this program; if not, write to the                 *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
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         //scale translate and rotate disregarding w scaling
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         //do w scaling
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         //scale translate and rotate disregarding w scaling
00268         //do w scaling
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         //scale translate and rotate disregarding w scaling
00293         //do w scaling
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         //scale translate and rotate disregarding w scaling
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         //do w scaling
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         //scale translate and rotate disregarding w scaling
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         /*improved version*/
00703         //assuming z = 1
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         /*improved version*/
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         /*improved version*/
00723         //Assuming z = 1
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         /*improved version*/
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         /*improved version*/
00756         //assuming z = 0
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         /*improved version*/
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         /*improved version*/
00777         //assuming z = 0
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         /*improved version*/
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     //inline T cofactorm0()const { return m5*(m10*m15-m11*m14)+m6*(m11*m13-m8*m15)+m7*(m8*m14*m10*m13);  }
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 

Generated on Wed Oct 3 12:50:48 2007 for MathGL++ by  doxygen 1.5.2