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
00051 Matrix4() { SetIdentity(); }
00052 Matrix4( const Matrix4& rhs ) { memcpy( x, rhs.x, sizeof(float)*16 ); }
00053 void operator=( const Matrix4& rhs ) { memcpy( x, rhs.x, sizeof(float)*16 ); }
00054
00056 void SetIdentity() { x[0] = x[5] = x[10] = x[15] = 1.0f;
00057 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;
00058 }
00059
00061 void SetTranslation( float _x, float _y, float _z )
00062 { x[12] = _x; x[13] = _y; x[14] = _z; }
00064 void SetTranslation( const Vector3F& vec )
00065 { x[12] = vec.x; x[13] = vec.y; x[14] = vec.z; }
00066
00068 void SetXRotation( float thetaDegree );
00070 void SetYRotation( float thetaDegree );
00072 void SetZRotation( float thetaDegree );
00073
00075 float CalcRotationAroundAxis( int axis ) const;
00076
00078 void SetScale( float scale ) { x[0] = x[5] = x[10] = scale; }
00079
00081 void SetAxisAngle( const Vector3F& axis, float angle );
00082
00083 void StripTrans() { x[12] = x[13] = x[14] = 0.0f;
00084 x[15] = 1.0f;
00085 }
00086
00088 bool IsRotation() const;
00089
00090 bool operator==( const Matrix4& rhs ) const {
00091 for( int i=0; i<16; ++i )
00092 if ( x[i] != rhs.x[i] )
00093 return false;
00094 return true;
00095 }
00096
00097 bool operator!=( const Matrix4& rhs ) const {
00098 int match = 0;
00099 for( int i=0; i<16; ++i )
00100 if ( x[i] == rhs.x[i] )
00101 ++match;
00102 if ( match == 16 ) return false;
00103 return true;
00104 }
00105
00107 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)]; }
00109 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)]; }
00110
00112 void Transpose( Matrix4* transpose ) const;
00114 float Determinant() const;
00116 void Adjoint( Matrix4* adjoint ) const;
00118 void Invert( Matrix4* inverse ) const;
00120 void Cofactor( Matrix4* cofactor ) const;
00121
00122 float SubDeterminant(int excludeRow, int excludeCol) const;
00123
00125 void ApplyScalar( float v ) {
00126 for( int i=0; i<16; ++i )
00127 x[i] *= v;
00128 }
00129
00130
00131 bool IsTranslationOnly() const {
00132 if ( x[0] == 1.0f && x[5] == 1.0f && x[10] == 1.0f ) {
00133 if ( x[4] == 0.0f && x[8] == 0.0f && x[9] == 0.0f
00134 && x[1] == 0.0f && x[2] == 0.0f && x[6] == 0.0f ) {
00135 return true;
00136 }
00137 }
00138 return false;
00139 }
00140
00141 friend void MultMatrix4( const Matrix4& a, const Matrix4& b, Matrix4* c );
00142 friend void MultMatrix4( const Matrix4& a, const Vector3F& b, Vector3F* c );
00143
00144 #ifdef DEBUG
00145 void Dump( const char* name ) const
00146 {
00147 GLOUTPUT(( "Mat%4s: %6.2f %6.2f %6.2f %6.2f\n"
00148 " %6.2f %6.2f %6.2f %6.2f\n"
00149 " %6.2f %6.2f %6.2f %6.2f\n"
00150 " %6.2f %6.2f %6.2f %6.2f\n",
00151 name,
00152 x[0], x[4], x[8], x[12],
00153 x[1], x[5], x[9], x[13],
00154 x[2], x[6], x[10], x[14],
00155 x[3], x[7], x[11], x[15] ));
00156 }
00157 #endif
00158
00159
00160
00161
00162 union
00163 {
00164 float x[16];
00165 struct
00166 {
00167
00168 float m11, m21, m31, m41, m12, m22, m32, m42, m13, m23, m33, m43, m14, m24, m34, m44;
00169 };
00170 };
00171
00172 friend Matrix4 operator*( const Matrix4& a, const Matrix4& b )
00173 {
00174 Matrix4 result;
00175 MultMatrix4( a, b, &result );
00176 return result;
00177 }
00178 friend Vector3F operator*( const Matrix4& a, const Vector3F& b )
00179 {
00180 Vector3F result;
00181 MultMatrix4( a, b, &result );
00182 return result;
00183 }
00184
00185 friend bool Equal( const Matrix4& a, const Matrix4& b, float epsilon = 0.001f )
00186 {
00187 for( unsigned i=0; i<16; ++i )
00188 if ( !grinliz::Equal( a.x[i], b.x[i], epsilon ) )
00189 return false;
00190 return true;
00191 }
00192
00193
00194 };
00195
00196
00201 inline void MultMatrix4( const Matrix4& a, const Matrix4& b, Matrix4* c )
00202 {
00203
00204 GLASSERT( c != &a && c != &b && &a != &b );
00205
00206
00207 for( int i=0; i<4; ++i )
00208 {
00209 for( int j=0; j<4; ++j )
00210 {
00211
00212
00213
00214 *( c->x + i +4*j ) = a.x[i+0] * b.x[j*4+0]
00215 + a.x[i+4] * b.x[j*4+1]
00216 + a.x[i+8] * b.x[j*4+2]
00217 + a.x[i+12] * b.x[j*4+3];
00218 }
00219 }
00220 }
00221
00222
00225 inline void MultMatrix4( const Matrix4& m, const Vector3F& v, Vector3F* w )
00226 {
00227 GLASSERT( w != &v );
00228 for( int i=0; i<3; ++i )
00229 {
00230 *( &w->x + i ) = m.x[i+0] * v.x
00231 + m.x[i+4] * v.y
00232 + m.x[i+8] * v.z
00233 + m.x[i+12];
00234 }
00235 }
00236
00237
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 };
00255
00256 #endif