_Matrix4.h

Go to the documentation of this file.
00001 #ifndef __VECMATH_MATRIX4_HPP
00002 #define __VECMATH_MATRIX4_HPP
00003 
00004 #ifndef __LANG_MATH_HPP
00005 #include <vecmath/Math.h>
00006 #endif
00007 
00008 template <class Type> class VECMATH_EXPORT _Matrix4;
00009 
00010 #ifndef __VECMATH_MATRIX3_HPP
00011 #include <vecmath/_Matrix3.h>
00012 #endif
00013 
00014 //template <class Type> ostream& operator <<(ostream& os, const _Matrix4<Type>& m);
00015 //template <class Type> ostream& operator <<(ostream& os, const _Matrix4<Type>* m);
00016 
00017 //#define DEBUGMATRIX4(d) d
00018 #define DEBUGMATRIX4(d)
00019 
00020 template <class Type> class VECMATH_EXPORT _Matrix4 {
00021 public:
00022     // order is important! - used for casting
00023 //      Type    m00, m01, m02, m03,
00024 //          m10, m11, m12, m13,
00025 //          m20, m21, m22, m23,
00026 //          m30, m31, m32, m33;
00027 
00028     // order is important! - stored as OpenGL transponed matrix
00029     Type m00, m10, m20, m30,
00030         m01, m11, m21, m31,
00031         m02, m12, m22, m32,
00032         m03, m13, m23, m33;
00033 
00034     _Matrix4<Type>() {}
00035 
00036     _Matrix4<Type>(Type s) {
00037         setScaleTranslate(s);
00038         DEBUGMATRIX4(cout << "_Matrix4 constructor scale " << endl << *this << endl);
00039     }
00040 
00041     explicit _Matrix4<Type>(Type m00      , Type m01      , Type m02 = 0.0, Type m03 = 0.0,
00042                             Type m10 = 0.0, Type m11 = 0.0, Type m12 = 0.0, Type m13 = 0.0,
00043                             Type m20 = 0.0, Type m21 = 0.0, Type m22 = 0.0, Type m23 = 0.0,
00044                             Type m30 = 0.0, Type m31 = 0.0, Type m32 = 0.0, Type m33 = 0.0) {
00045         set(m00, m01, m02, m03,
00046             m10, m11, m12, m13,
00047             m20, m21, m22, m23,
00048             m30, m31, m32, m33);
00049         DEBUGMATRIX4(cout << "_Matrix4 constructor R16 " << endl << *this << endl);
00050     }
00051 
00052     _Matrix4<Type>(const _Matrix4<double>& m) {
00053         set(m);
00054         DEBUGMATRIX4(cout << "_Matrix4 constructor double& " << endl << *this << endl);
00055     }
00056 
00057     _Matrix4<Type>(const _Matrix4<float>& m) {
00058         set(m);
00059         DEBUGMATRIX4(cout << "_Matrix4 constructor float& " << endl << *this << endl);
00060     }
00061 
00062     _Matrix4<Type>(const Type v[16]) {
00063         set(v);
00064         DEBUGMATRIX4(cout << "_Matrix4 constructor v[16] " << endl << *this << endl);
00065     }
00066 
00067 
00068     void add(Type d) {
00069         add(d, *this);
00070     }
00071 
00072     void add(Type d, const _Matrix4<Type>& m);
00073 
00074     void add(const _Matrix4<Type>& m) {
00075         add(*this, m);
00076     }
00077 
00078     void add(const _Matrix4<Type>& m1, const _Matrix4<Type>& m2);
00079 
00080     void adjoint() {
00081         adjoint(*this);
00082     }
00083 
00084     void adjoint(const _Matrix4<Type>& m);
00085 
00086     // do it more effiently
00087     // usualy
00088     Type determinant() const {
00089         return m00 * _Matrix3<Type>::determinant3x3(m11, m12, m13,
00090                                                     m21, m22, m23,
00091                                                     m31, m32, m33) -
00092             m01 * _Matrix3<Type>::determinant3x3(m10, m12, m13,
00093                                                  m20, m22, m23,
00094                                                  m30, m32, m33) +
00095             m02 * _Matrix3<Type>::determinant3x3(m10, m11, m13,
00096                                                  m20, m21, m23,
00097                                                  m30, m31, m33) -
00098             m03 * _Matrix3<Type>::determinant3x3(m10, m11, m12,
00099                                                  m20, m21, m22,
00100                                                  m30, m31, m32);
00101 //  
00102 //          ((m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32)
00103 //           - m13 * m22 * m31 - m11 * m23 * m32 - m12 * m21 * m33)
00104 //          - m01 * ((m10 * m22 * m33 + m12 * m23 * m30 + m13 * m20 * m32)
00105 //                   - m13 * m22 * m30 - m10 * m23 * m32 - m12 * m20 * m33)
00106 //          + m02 * ((m10 * m21 * m33 + m11 * m23 * m30 + m13 * m20 * m31)
00107 //                   - m13 * m21 * m30 - m10 * m23 * m31 - m11 * m20 * m33)
00108 //          - m03 * ((m10 * m21 * m32 + m11 * m22 * m30 + m12 * m20 * m31)
00109 //                   - m12 * m21 * m30 - m10 * m22 * m31 - m11 * m20 * m32);
00110     }
00111 
00112     Type determinant3x3() const {
00113         return _Matrix3<Type>::determinant3x3(m00, m01, m02,
00114                                               m10, m11, m12,
00115                                               m20, m21, m22);
00116     }
00117 
00118     bool epsilonEquals(const _Matrix4<Type>& m, Type epsilon) const;
00119 
00120     bool equals(const _Matrix4<Type>& m) const {
00121         DEBUGMATRIX4(cout << "_Matrix4 equals " << endl << *this << " == " << endl << m << endl);
00122         return (m00 == m.m00 && m01 == m.m01 && m02 == m.m02 && m03 == m.m03 &&
00123                 m10 == m.m10 && m11 == m.m11 && m12 == m.m12 && m13 == m.m13 &&
00124                 m20 == m.m20 && m21 == m.m21 && m22 == m.m22 && m23 == m.m23 &&
00125                 m30 == m.m30 && m31 == m.m31 && m32 == m.m32 && m33 == m.m33);
00126     }
00127 
00128     void get(double m[16]) const {
00129         m[0]  = m00,  m[1] = m01,  m[2] = m02,  m[3] = m03;
00130         m[4]  = m10,  m[5] = m11,  m[6] = m12,  m[7] = m13;
00131         m[8]  = m20,  m[9] = m21, m[10] = m22, m[11] = m23;
00132         m[12] = m30, m[13] = m31, m[14] = m32, m[15] = m33;
00133     }
00134 
00135     void get(float m[16]) const {
00136         m[0]  = m00,  m[1] = m01,  m[2] = m02,  m[3] = m03;
00137         m[4]  = m10,  m[5] = m11,  m[6] = m12,  m[7] = m13;
00138         m[8]  = m20,  m[9] = m21, m[10] = m22, m[11] = m23;
00139         m[12] = m30, m[13] = m31, m[14] = m32, m[15] = m33;
00140     }
00141 
00142     void get(_Matrix3<double>& m) const;
00143     Type get(_Matrix3<double>& m, _Vector3<double>& v) const;
00144     void get(_Matrix3<double>& m, _Vector3<double>& v, _Vector3<double>& s) const;
00145     void get(_Matrix3<float>& m) const;
00146     Type get(_Matrix3<float>& m, _Vector3<float>& v) const;
00147     void get(_Matrix3<float>& m, _Vector3<float>& v, _Vector3<float>& s) const;
00148     void get(_Quat4<double>& q) const;
00149     void get(_Quat4<float>& q) const;
00150 
00151     void get(_Vector3<double>& v) const {
00152         v.set(m03, m13, m23);
00153     }
00154 
00155     void get(_Vector3<float>& v) const {
00156         v.set(m03, m13, m23);
00157     }
00158 
00159     void get3x3(double m[9]) const {
00160         m[0] = m00, m[1] = m01, m[2] = m02;
00161         m[3] = m10, m[4] = m11, m[5] = m12;
00162         m[6] = m20, m[7] = m21, m[8] = m22;
00163     }
00164 
00165     void getColumn(int column, _Vector4<Type>& v) const;
00166     void getColumn(int column, Type c[]) const;
00167     Type getElement(int row, int column) const;
00168 
00169     void getEuler(_Vector3<Type>) const;
00170 
00171     void getRotationScale(_Matrix3<double>& m3d) const;
00172     void getRotationScale(_Matrix3<float>& m3f) const;
00173     void getRow(int row, _Vector4<Type>& v) const;
00174     void getRow(int row, Type r[]) const;
00175 
00176     double getScale() const;
00177     // making it public (private in J3D)
00178     void getScaleRotate(double scale[3], double rot[9]) const;
00179 
00180     void invert() {
00181         invert(*this);
00182     }
00183 
00184     void invert(const _Matrix4<Type>& m);
00185 
00186     void mul(Type d) {
00187         mul(d, *this);
00188     }
00189 
00190     void mul(Type d, const _Matrix4<Type>& m);
00191     void mul(const _Matrix4<Type>& m);
00192     void mul(const _Matrix4<Type>& m1, const _Matrix4<Type>& m2);
00193     void mulTransposeBoth(const _Matrix4<Type>& m1, const _Matrix4<Type>& m2);
00194     void mulTransposeLeft(const _Matrix4<Type>& m1, const _Matrix4<Type>& m2);
00195     void mulTransposeRight(const _Matrix4<Type>& m1, const _Matrix4<Type>& m2);
00196 
00197     void negate() {
00198         negate(*this);
00199     }
00200 
00201     void negate(const _Matrix4<Type>& m) {
00202         set(-m.m00, -m.m01, -m.m02, -m.m03,
00203             -m.m10, -m.m11, -m.m12, -m.m13,
00204             -m.m20, -m.m21, -m.m22, -m.m23,
00205             -m.m30, -m.m31, -m.m32, -m.m33);
00206     }
00207 
00208     void scale(Type s) {
00209         m00 *= s, m01 *= s, m02 *= s, m03 *= s;
00210         m10 *= s, m11 *= s, m12 *= s, m13 *= s;
00211         m20 *= s, m21 *= s, m22 *= s, m23 *= s;
00212         m30 *= s, m31 *= s, m32 *= s, m33 *= s;
00213     }
00214 
00215     void scaleAdd(Type s, const _Matrix4<Type>& m) {
00216         scaleAdd(s, m, *this);
00217     }
00218 
00219     void scaleAdd(Type s, const _Matrix4<Type>& m, const _Matrix4& m1) {
00220         set(m.m00 * s + m1.m00, m.m01 * s + m1.m01, m.m02 * s + m1.m02, m.m03 * s + m1.m03,
00221             m.m10 * s + m1.m10, m.m11 * s + m1.m11, m.m12 * s + m1.m12, m.m13 * s + m1.m13,
00222             m.m20 * s + m1.m20, m.m21 * s + m1.m21, m.m22 * s + m1.m22, m.m23 * s + m1.m23,
00223             m.m30 * s + m1.m30, m.m31 * s + m1.m31, m.m32 * s + m1.m32, m.m33 * s + m1.m33);
00224     }
00225 
00226     void set3x3(Type mm00 = 0, Type mm01 = 0, Type mm02 = 0,
00227                 Type mm10 = 0, Type mm11 = 0, Type mm12 = 0,
00228                 Type mm20 = 0, Type mm21 = 0, Type mm22 = 0) {
00229         m00 = mm00, m01 = mm01, m02 = mm02,
00230         m10 = mm10, m11 = mm11, m12 = mm12,
00231         m20 = mm20, m21 = mm21, m22 = mm22;
00232     }
00233 
00234     void set(Type mm00      , Type mm01      , Type mm02 = 0.0, Type mm03 = 0.0,
00235              Type mm10 = 0.0, Type mm11 = 0.0, Type mm12 = 0.0, Type mm13 = 0.0,
00236              Type mm20 = 0.0, Type mm21 = 0.0, Type mm22 = 0.0, Type mm23 = 0.0,
00237              Type mm30 = 0.0, Type mm31 = 0.0, Type mm32 = 0.0, Type mm33 = 0.0) {
00238         m00 = mm00, m01 = mm01, m02 = mm02, m03 = mm03;
00239         m10 = mm10, m11 = mm11, m12 = mm12, m13 = mm13;
00240         m20 = mm20, m21 = mm21, m22 = mm22, m23 = mm23;
00241         m30 = mm30, m31 = mm31, m32 = mm32, m33 = mm33;
00242     }
00243 
00244     void set(const _Matrix4<double>& m) {
00245         set(m.m00, m.m01, m.m02, m.m03,
00246             m.m10, m.m11, m.m12, m.m13,
00247             m.m20, m.m21, m.m22, m.m23,
00248             m.m30, m.m31, m.m32, m.m33);
00249     }
00250 
00251     void set(const _Matrix4<float>& m) {
00252         set(m.m00, m.m01, m.m02, m.m03,
00253             m.m10, m.m11, m.m12, m.m13,
00254             m.m20, m.m21, m.m22, m.m23,
00255             m.m30, m.m31, m.m32, m.m33);
00256     }
00257 
00258     void set(const _Matrix3<double>& m) {
00259         set(m.m00, m.m01, m.m02, 0.0,
00260             m.m10, m.m11, m.m12, 0.0,
00261             m.m20, m.m21, m.m22, 0.0,
00262             0.0, 0.0, 0.0, 1.0);
00263     }
00264 
00265     void set(const _Matrix3<float>& m) {
00266         set(m.m00, m.m01, m.m02, 0.0,
00267             m.m10, m.m11, m.m12, 0.0,
00268             m.m20, m.m21, m.m22, 0.0,
00269             0.0, 0.0, 0.0, 1.0);
00270     }
00271 
00272     void set(const _Matrix3<double>& m, const _Vector3<double>& v, double s) {
00273         set(m.m00 * s, m.m01 * s, m.m02 * s, v.x,
00274             m.m10 * s, m.m11 * s, m.m12 * s, v.y,
00275             m.m20 * s, m.m21 * s, m.m22 * s, v.z,
00276             0.0, 0.0, 0.0, 1.0);
00277     }
00278 
00279     void set(const _Matrix3<float>& m, const _Vector3<double>& v, double s) {
00280         set(m.m00 * s, m.m01 * s, m.m02 * s, v.x,
00281             m.m10 * s, m.m11 * s, m.m12 * s, v.y,
00282             m.m20 * s, m.m21 * s, m.m22 * s, v.z,
00283             0.0, 0.0, 0.0, 1.0);
00284     }
00285 
00286     void set(const _Matrix3<double>& m, const _Vector3<double>& v, const _Vector3<double>& s) {
00287         set(m.m00 * s.x, m.m01 * s.y, m.m02 * s.z, v.x,
00288             m.m10 * s.x, m.m11 * s.y, m.m12 * s.z, v.y,
00289             m.m20 * s.x, m.m21 * s.y, m.m22 * s.z, v.z,
00290             0.0, 0.0, 0.0, 1.0);
00291     }
00292 
00293     void set(const _Matrix3<float>& m, const _Vector3<float>& v, const _Vector3<float>& s) {
00294         set(m.m00 * s.x, m.m01 * s.y, m.m02 * s.z, v.x,
00295             m.m10 * s.x, m.m11 * s.y, m.m12 * s.z, v.y,
00296             m.m20 * s.x, m.m21 * s.y, m.m22 * s.z, v.z,
00297             0.0, 0.0, 0.0, 1.0);
00298     }
00299 
00300     void set(const _Vector3<double>& v) {
00301         setIdentity();
00302         setTranslation(v);
00303     }
00304 
00305     void set(const _Vector3<float>& v) {
00306         setIdentity();
00307         setTranslation(v);
00308     }
00309 
00310     void set(const _Vector3<double>& v, double s) {
00311         setScaleTranslate(s, v.x, v.y, v.z);
00312         setTranslation(v);
00313     }
00314 
00315     void set(const _Vector3<float>& v, double s) {
00316         setScaleTranslate(s, v.x, v.y, v.z);
00317         setTranslation(v);
00318     }
00319 
00320     void set(const double at[16]) {
00321         set(at[0],   at[1],  at[2],  at[3],
00322             at[4],   at[5],  at[6],  at[7],
00323             at[8],   at[9], at[10], at[11],
00324             at[12], at[13], at[14], at[15]);
00325     }
00326 
00327     void set(const float at[16]) {
00328         set(at[0],   at[1],  at[2],  at[3],
00329             at[4],   at[5],  at[6],  at[7],
00330             at[8],   at[9], at[10], at[11],
00331             at[12], at[13], at[14], at[15]);
00332     }
00333 
00334     void setTranspose(const Type at[16]) {
00335         set(at[0], at[4],  at[8], at[12],
00336             at[1], at[5],  at[9], at[13],
00337             at[2], at[6], at[10], at[14],
00338             at[3], at[7], at[11], at[15]);
00339     }
00340 
00341     void setColumn(int column, Type x, Type y, Type z, Type w);
00342     void setElement(int row, int column, Type value);
00343 
00344     void setIdentity() {
00345         setScaleTranslate(1.0);
00346     }
00347 
00348     void setIdentity3x3() {
00349         set3x3(1.0, 0.0, 0.0,
00350                0.0, 1.0, 0.0,
00351                0.0, 0.0, 1.0);
00352     }
00353 
00354 //    void setRotation(const _AxisAngle4<double>& a);
00355 //    void setRotation(const _AxisAngle4<float>& a);
00356     void setRotation(const _Matrix3<double>& m);
00357     void setRotation(const _Matrix3<float>& m);
00358     void setRotation(const _Quat4<double>& q);
00359     void setRotation(const _Quat4<float>& q);
00360 
00361     void setRotationScale(const _Matrix3<double>& m) {
00362         set3x3(m.m00, m.m01, m.m02,
00363                m.m10, m.m11, m.m12,
00364                m.m20, m.m21, m.m22);
00365     }
00366 
00367     void setRotationScale(const _Matrix3<float>& m) {
00368         set3x3(m.m00, m.m01, m.m02,
00369                m.m10, m.m11, m.m12,
00370                m.m20, m.m21, m.m22);
00371     }
00372 
00373 
00374     void setRow(int row, Type x, Type y, Type z, Type w);
00375 
00376     //extension
00377     void setScaleTranslate(Type scale, Type x = 0.0, Type y = 0.0, Type z = 0.0) {
00378         set(scale, 0.0, 0.0, x,
00379             0.0, scale, 0.0, y,
00380             0.0, 0.0, scale, z,
00381             0.0, 0.0, 0.0,   1.0);
00382     }
00383 
00384     void setTranslation(const _Vector3<Type>& trans) {
00385         m03 = trans.x;
00386         m13 = trans.y;
00387         m23 = trans.z;
00388     }
00389 
00390     void setZero() {
00391         setScaleTranslate(0.0);
00392         m33 = 0.0;
00393     }
00394 
00395     void sub(const _Matrix4<Type>& m) {
00396         sub(*this, m);
00397     }
00398 
00399     void sub(const _Matrix4<Type>& m1, const _Matrix4<Type>& m2);
00400     void rotX(double angle);
00401     void rotY(double angle);
00402     void rotZ(double angle);
00403     void rotationGL(double angle, const _Vector3<Type>& axis);
00404     //void toString();
00405 
00406     void transform(_Tuple3<double>& t) const {
00407         transform(t, t);
00408     }
00409     void transform(const _Tuple3<double>& t, _Tuple3<double>& t1) const;
00410 
00411     void transform(_Tuple3<float>& t) const {
00412         transform(t, t);
00413     }
00414     void transform(const _Tuple3<float>& t, _Tuple3<float>& t1) const;
00415 
00416     void transform(_Tuple4<double>& t) const {
00417         transform(t, t);
00418     }
00419     void transform(const _Tuple4<double>& t, _Tuple4<double>& t1) const;
00420 
00421     void transform(_Tuple4<float>& t) const {
00422         transform(t, t);
00423     }
00424     void transform(const _Tuple4<float>& t, _Tuple4<float>& t1) const;
00425 
00426     void transpose();
00427     void transpose(const _Matrix4<Type>& m);
00428 
00429     _Matrix4<Type>& operator +=(const _Matrix4<Type>& t) {
00430         add(t);
00431         DEBUGTUPLE3(cout << "_Matrix4 operator+= _Matrix4 " << *this  << endl);
00432         return *this;
00433     }
00434 
00435     _Matrix4<Type>& operator -=(const _Matrix4<Type>& t) {
00436         sub(t);
00437         DEBUGTUPLE3(cout << "_Matrix4 operator+= _Matrix4 " << *this  << endl);
00438         return *this;
00439     }
00440 
00441     // can be used for casting to OpenGL transformation matrix
00442     operator const Type * () const {
00443         return &m00;
00444     }
00445 
00446     // quite hard to tune this part  - now it works
00447     Type& operator ()(int row, int column) const {
00448 //      cerr  << &m00 << "   -  " << &((&m00)[column * 4 + row]) << "  r:  " << row << "  c: " << column << endl;
00449 //      cerr  << (operator const Type *() + column * 4 + row) << endl;
00450         return (Type &)(*((operator const Type *()) + column * 4 + row));
00451     }
00452 
00453 //    friend ostream & operator << <>(ostream &, const _Matrix4<Type>& );
00454 //    friend ostream & operator << <>(ostream &, const _Matrix4<Type>* );
00455 
00456 private:
00457     static bool luDecomposition(Type ad[], int ai[]);
00458     static void luBacksubstitution(Type ad[], int ai[], Type ad1[]);
00459 
00460     void setRotationScale3x3(double mm00, double mm01, double mm02,
00461                              double mm10, double mm11, double mm12,
00462                              double mm20, double mm21, double mm22) {
00463         double tmp_scale[3];
00464         double tmp_rot[9];
00465         getScaleRotate(tmp_scale, tmp_rot);
00466         set3x3(mm00 * tmp_scale[0], mm01 * tmp_scale[1], mm02 * tmp_scale[2],
00467                mm10 * tmp_scale[0], mm11 * tmp_scale[1], mm12 * tmp_scale[2],
00468                mm20 * tmp_scale[0], mm21 * tmp_scale[1], mm22 * tmp_scale[2]);
00469     }
00470 };
00471 
00472 #endif

Generated on Thu Sep 29 13:39:44 2005 for vecmath by  doxygen 1.4.4