00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef GRINLIZ_MATRIX_DEFINED
00027 #define GRINLIZ_MATRIX_DEFINED
00028
00029 #include "gldebug.h"
00030 #include "glvector.h"
00031
00032 namespace grinliz {
00033
00045 class Matrix4
00046 {
00047 public:
00048 inline static int INDEX( int row, int col ) { return col*4+row; }
00049
00050 Matrix4() { SetIdentity(); }
00051 void SetIdentity() { x[0] = x[5] = x[10] = x[15] = 1.0f;
00052 x[1] = x[2] = x[3] = x[4] = x[6] = x[7] = x[8] = x[9] = x[11] = x[12] = x[13] = x[14] = 0.0f;
00053 }
00054 void SetTranslation( float _x, float _y, float _z )
00055 { x[12] = _x; x[13] = _y; x[14] = _z; }
00056 void SetTranslation( const Vector3F& vec )
00057 { x[12] = vec.x; x[13] = vec.y; x[14] = vec.z; }
00058
00059 void SetXRotation( float thetaDegree );
00060 void SetYRotation( float thetaDegree );
00061 void SetZRotation( float thetaDegree );
00062
00063 void SetScale( float scale ) { x[0] = x[5] = x[10] = scale; }
00064
00065 void SetAxisAngle( const Vector3F& axis, float angle );
00066
00067 void StripTrans() { x[12] = x[13] = x[14] = 0.0f;
00068 x[15] = 1.0f;
00069 }
00070
00071
00072 bool IsRotation() const;
00073
00074 void Row( unsigned i, Vector3F *row ) const { row->x=x[INDEX(i,0)]; row->y=x[INDEX(i,1)]; row->z=x[INDEX(i,2)]; }
00075 void Col( unsigned i, Vector3F *col ) const { col->x=x[INDEX(0,i)]; col->y=x[INDEX(1,i)]; col->z=x[INDEX(2,i)]; }
00076
00077 void Transpose( Matrix4* transpose ) const;
00078 float Determinant() const;
00079 void Adjoint( Matrix4* adjoint ) const;
00080 void Invert( Matrix4* inverse ) const;
00081 void Cofactor( Matrix4* cofactor ) const;
00082 float SubDeterminant(int excludeRow, int excludeCol) const;
00083
00084 void ApplyScalar( float v ) {
00085 for( int i=0; i<16; ++i )
00086 x[i] *= v;
00087 }
00088
00089
00090 bool IsTranslationOnly() const {
00091 if ( x[0] == 1.0f && x[5] == 1.0f && x[10] == 1.0f ) {
00092 if ( x[4] == 0.0f && x[8] == 0.0f && x[9] == 0.0f
00093 && x[1] == 0.0f && x[2] == 0.0f && x[6] == 0.0f ) {
00094 return true;
00095 }
00096 }
00097 return false;
00098 }
00099
00100 friend void MultMatrix4( const Matrix4& a, const Matrix4& b, Matrix4* c );
00101 friend void MultMatrix4( const Matrix4& a, const Vector3F& b, Vector3F* c );
00102
00103 #ifdef DEBUG
00104 void Dump( const char* name ) const
00105 {
00106 GLOUTPUT(( "Mat%4s: %6.2f %6.2f %6.2f %6.2f\n"
00107 " %6.2f %6.2f %6.2f %6.2f\n"
00108 " %6.2f %6.2f %6.2f %6.2f\n"
00109 " %6.2f %6.2f %6.2f %6.2f\n",
00110 name,
00111 x[0], x[4], x[8], x[12],
00112 x[1], x[5], x[9], x[13],
00113 x[2], x[6], x[10], x[14],
00114 x[3], x[7], x[11], x[15] ));
00115 }
00116 #endif
00117
00118
00119
00120
00121 union
00122 {
00123 float x[16];
00124 struct
00125 {
00126
00127 float m11, m21, m31, m41, m12, m22, m32, m42, m13, m23, m33, m43, m14, m24, m34, m44;
00128 };
00129 };
00130
00131 friend Matrix4 operator*( const Matrix4& a, const Matrix4& b )
00132 {
00133 Matrix4 result;
00134 MultMatrix4( a, b, &result );
00135 return result;
00136 }
00137 friend Vector3F operator*( const Matrix4& a, const Vector3F& b )
00138 {
00139 Vector3F result;
00140 MultMatrix4( a, b, &result );
00141 return result;
00142 }
00143
00144 friend bool Equal( const Matrix4& a, const Matrix4& b, float epsilon = 0.001f )
00145 {
00146 for( unsigned i=0; i<16; ++i )
00147 if ( !grinliz::Equal( a.x[i], b.x[i], epsilon ) )
00148 return false;
00149 return true;
00150 }
00151 };
00152
00153
00158 inline void MultMatrix4( const Matrix4& a, const Matrix4& b, Matrix4* c )
00159 {
00160
00161 GLASSERT( c != &a && c != &b && &a != &b );
00162
00163
00164 for( int i=0; i<4; ++i )
00165 {
00166 for( int j=0; j<4; ++j )
00167 {
00168
00169
00170
00171 *( c->x + i +4*j ) = a.x[i+0] * b.x[j*4+0]
00172 + a.x[i+4] * b.x[j*4+1]
00173 + a.x[i+8] * b.x[j*4+2]
00174 + a.x[i+12] * b.x[j*4+3];
00175 }
00176 }
00177 }
00178
00179
00182 inline void MultMatrix4( const Matrix4& m, const Vector3F& v, Vector3F* w )
00183 {
00184 GLASSERT( w != &v );
00185 for( int i=0; i<3; ++i )
00186 {
00187 *( &w->x + i ) = m.x[i+0] * v.x
00188 + m.x[i+4] * v.y
00189 + m.x[i+8] * v.z
00190 + m.x[i+12];
00191 }
00192 }
00193
00194
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 };
00212
00213 #endif