00001 #pragma once
00002 #ifndef MATRIX_H
00003 #define MATRIX_H
00004
00005 #include <math.h>
00006 #include <limits.h>
00007 #include <string>
00008 #include <iostream>
00009 #include <vector>
00010
00011 #ifndef M_PI
00012 #define M_PI 3.1415926535897932384626433832795
00013 #endif
00014
00016
00017 using namespace std;
00018
00019 namespace RenderTools{
00020
00021 class Vec2;
00022 class Vec3;
00023 class Vec4;
00024 class Quat;
00025 class Mat2;
00026 class Mat3;
00027 class Mat4;
00028
00029 typedef Vec2 * Vec2Ptr;
00030 typedef Vec3 * Vec3Ptr;
00031 typedef Vec4 * Vec4Ptr;
00032 typedef Mat2 * Mat2Ptr;
00033 typedef Mat3 * Mat3Ptr;
00034 typedef Mat4 * Mat4Ptr;
00035
00036 typedef vector<Vec2> Vec2List;
00037 typedef vector<Vec3> Vec3List;
00038 typedef vector<Vec4> Vec4List;
00039 typedef vector<Mat2> Mat2List;
00040 typedef vector<Mat3> Mat3List;
00041 typedef vector<Mat4> Mat4List;
00042
00043 template<typename T>
00044 void swapValues( T & a, T & b ){
00045 T c = a;
00046 a = b;
00047 b = c;
00048 }
00049
00050 float smallest( float, float );
00051 float largest( float, float );
00052 double smallest( double, double );
00053 double largest( double, double );
00054 float smallest( float, double );
00055 float largest( float, double );
00056 float smallest( double, float );
00057 float largest( double, float );
00058
00059 float sgn( float );
00060 float clamp( float, float min, float max );
00061 float clampMax( float, float max );
00062 float clampMin( float, float min );
00063 float toRadians( float degrees );
00064 float toDegrees( float radians );
00065 float distance( const Vec2 &, const Vec2 & );
00066 float distance( const Vec3 &, const Vec3 & );
00067 float distance( const Vec4 &, const Vec4 & );
00068 float distance2( const Vec2 &, const Vec2 & );
00069 float distance2( const Vec3 &, const Vec3 & );
00070 float distance2( const Vec4 &, const Vec4 & );
00071 float length( const Vec2 & );
00072 float length( const Vec3 & );
00073 float length( const Vec4 & );
00074 float length2( const Vec2 & );
00075 float length2( const Vec3 & );
00076 float length2( const Vec4 & );
00077 float dot( const Vec2 &, const Vec2 & v2 );
00078 float dot( const Vec3 &, const Vec3 & v2 );
00079 float dot( const Vec4 &, const Vec4 & v2 );
00080 Vec3 cross( const Vec3 &, const Vec3 & v2 );
00081 float cross( const Vec2 &, const Vec2 & v2 );
00082 float mix( float, float, float );
00083 Vec2 mix( const Vec2 &, const Vec2 &, float );
00084 Mat2 mix( const Mat2 &, const Mat2 &, float );
00085 Vec3 mix( const Vec3 &, const Vec3 &, float );
00086 Mat3 mix( const Mat3 &, const Mat3 &, float );
00087 Vec4 mix( const Vec4 &, const Vec4 &, float );
00088 Mat4 mix( const Mat4 &, const Mat4 &, float );
00089
00090 Vec2 normalize( const Vec2 & );
00091 Vec3 normalize( const Vec3 & );
00092 Vec4 normalize( const Vec4 & );
00093
00094
00095 Vec2 operator * ( float, const Vec2 & );
00096 Vec3 operator * ( float, const Vec3 & );
00097 Vec4 operator * ( float, const Vec4 & );
00098
00100 istream & operator >> ( istream & s, Vec2 & v );
00101 istream & operator >> ( istream & s, Vec3 & v );
00102 istream & operator >> ( istream & s, Vec4 & v );
00103 istream & operator >> ( istream & s, Quat & v );
00104 istream & operator >> ( istream & s, Mat2 & v );
00105 istream & operator >> ( istream & s, Mat3 & v );
00106 istream & operator >> ( istream & s, Mat4 & v );
00107
00109 ostream & operator << ( ostream & s, const Vec2 & v );
00110 ostream & operator << ( ostream & s, const Vec3 & v );
00111 ostream & operator << ( ostream & s, const Vec4 & v );
00112 ostream & operator << ( ostream & s, const Quat & v );
00113 ostream & operator << ( ostream & s, const Mat2 & v );
00114 ostream & operator << ( ostream & s, const Mat3 & v );
00115 ostream & operator << ( ostream & s, const Mat4 & v );
00116
00117 class Vec2 {
00118 public:
00119 Vec2( float xy = 0.0f );
00120 Vec2( float x, float y );
00121 Vec2( const float * );
00122
00123 bool operator < ( const float ) const;
00124 bool operator < ( const Vec2 & ) const;
00125 bool operator < ( const Vec3 & ) const;
00126 bool operator < ( const Vec4 & ) const;
00127 Vec2 operator - ( void ) const;
00128 Vec2 operator + ( const Vec2 & ) const;
00129 Vec2 operator - ( const Vec2 & ) const;
00130 Vec2 operator * ( const Vec2 & ) const;
00131 Vec2 operator * ( float ) const;
00132 Vec2 operator / ( const Vec2 & ) const;
00133 Vec2 operator / ( float ) const;
00134 bool operator == ( const Vec2 & ) const;
00135 const float & operator [] ( const int ) const;
00136 const float * operator * ( void ) const;
00137
00138 float & operator [] ( int );
00139 Vec2 & operator += ( const Vec2 & );
00140 Vec2 & operator -= ( const Vec2 & );
00141 Vec2 & operator *= ( float );
00142 Vec2 & operator *= ( const Vec2 & );
00143 Vec2 & operator /= ( float );
00144 Vec2 & operator /= ( const Vec2 & );
00145
00146 float hyp( void ) const;
00147 float len( void ) const;
00148 void normalize( void );
00149 Vec2 normalized( void ) const;
00150 Vec2 abs( void ) const;
00151 Vec2 sgn( void ) const;
00152 Vec2 clamp( float min = 0.0f, float max = 1.0f ) const;
00153 float dot( const Vec2 & ) const;
00154 Vec2 cross( void ) const;
00155 float cross( const Vec2 & ) const;
00156 bool equals( const Vec2 &, float epsilon = 0.0f ) const;
00157 bool equals( const float *, float epsilon = 0.0f ) const;
00158 float toAngle() const;
00159
00160 static Vec2 fromAngle( float radians );
00161
00162 private:
00163 float m_v[2];
00164 };
00165
00166 class Mat2 {
00167 public:
00168 Mat2( float v00 = 1.0f, float v01 = 0.0f, float v10 = 0.0f, float v11 = 1.0f );
00169 Mat2( const float * );
00170
00171 Vec2 operator * ( const Vec2 & ) const;
00172 Mat2 operator * ( float ) const;
00173 Mat2 operator * ( const Mat2 & ) const;
00174 const float * operator * ( void ) const;
00175 Mat2 operator / ( float ) const;
00176 const float & operator [] ( const int ) const;
00177 bool operator == ( const Mat2 & ) const;
00178
00179 float & operator [] ( int );
00180 Mat2 & operator *= ( const Mat2 & );
00181 Mat2 & operator *= ( float );
00182 Mat2 & operator /= ( float );
00183
00184 Vec2 getRow( int ) const;
00185 Vec2 getCol( int ) const;
00186 const float & getElement( int column, int row ) const;
00187 Mat2 transpose( void ) const;
00188 float determinant( void ) const;
00189 Mat2 inverse( void ) const;
00190 bool equals( const Mat2 &, float epsilon = 0.0f ) const;
00191 bool equals( const float *, float epsilon = 0.0f ) const;
00192
00193 float & getElement( int column, int row );
00194 void setRow( int index, const Vec2 & row );
00195 void setCol( int index, const Vec2 & col );
00196 void setElement( int col, int row, float );
00197 void setIdentity( void );
00198 void setRotation( float radians = 0.0f );
00199 void setScaling( const Vec2 & scaling = Vec2( 1.0f, 1.0f ) );
00200
00201 static Mat2 fromIdentity( void );
00202
00203 private:
00204 float m_v[4];
00205 };
00206
00207 class Vec3 {
00208 public:
00209 Vec3( float xyz = 0.0f );
00210 Vec3( float x, float y, float z );
00211 Vec3( const Vec2 & xy, float z = 0.0 );
00212 Vec3( const float * v );
00213
00214 bool operator < ( const float ) const;
00215 bool operator < ( const Vec2 & ) const;
00216 bool operator < ( const Vec3 & ) const;
00217 bool operator < ( const Vec4 & ) const;
00218 Vec3 operator - ( void ) const;
00219 Vec3 operator + ( const Vec3 & ) const;
00220 Vec3 operator - ( const Vec3 & ) const;
00221 Vec3 operator * ( const Vec3 & ) const;
00222 Vec3 operator * ( float ) const;
00223 Vec3 operator / ( float ) const;
00224 Vec3 operator / ( const Vec3 & ) const;
00225 const float & operator [] ( const int ) const;
00226 bool operator == ( const Vec3 & ) const;
00227 const float * operator * ( void ) const;
00228
00229 float & operator [] ( int );
00230 Vec3 & operator += ( const Vec3 & );
00231 Vec3 & operator -= ( const Vec3 & );
00232 Vec3 & operator *= ( float );
00233 Vec3 & operator *= ( const Vec3 & );
00234 Vec3 & operator /= ( float );
00235 Vec3 & operator /= ( const Vec3 & );
00236
00237 Vec2 xy( void ) const;
00238 float hyp( void ) const;
00239 float len( void ) const;
00240 void normalize( void );
00241 Vec3 normalized( void ) const;
00242 Vec3 abs( void ) const;
00243 Vec3 sgn( void ) const;
00244 Vec3 clamp( float min = 0.0f, float max = 1.0f ) const;
00245 float dot( const Vec3 & ) const;
00246 Vec3 cross( const Vec3 & ) const;
00247 bool equals( const Vec3 &, float epsilon = 0.0f ) const;
00248 bool equals( const float *, float epsilon = 0.0f ) const;
00249 Vec2 toPolar( void ) const;
00250 float getAngle( const Vec3 & xAxis = Vec3( 1,0,0 ), const Vec3 & yAxis = Vec3( 0,1,0 ) ) const;
00251
00252 static Vec3 fromPolar( const Vec2 & );
00253 static Vec3 fromAxisAngle( const Vec3 &, const Vec3 &, float radians );
00254
00255 private:
00256 float m_v[3];
00257 };
00258
00259 class Mat3 {
00260 friend class Quat;
00261 public:
00262 Mat3( float v00 = 1.0f, float v01 = 0.0f, float v02 = 0.0f,
00263 float v10 = 0.0f, float v11 = 1.0f, float v12 = 0.0f,
00264 float v20 = 0.0f, float v21 = 0.0f, float v22 = 1.0f );
00265 Mat3( const Vec3 & c0, const Vec3 & c1, const Vec3 & c2 );
00266 Mat3( const float * );
00267
00268 Vec3 operator * ( const Vec3 & ) const;
00269 Mat3 operator * ( float ) const;
00270 Mat3 operator * ( const Mat3 & ) const;
00271 const float * operator * ( void ) const;
00272 Mat3 operator / ( float ) const;
00273 const float & operator [] ( const int ) const;
00274 bool operator == ( const Mat3 & )const;
00275
00276 float & operator [] ( int );
00277 Mat3 & operator *= ( const Mat3 & );
00278 Mat3 & operator *= ( float );
00279 Mat3 & operator /= ( float );
00280
00281 Vec3 getRow( int ) const;
00282 Vec3 getCol( int ) const;
00283 const float & getElement( int column, int row ) const;
00284 Mat3 transpose( void ) const;
00285 Mat3 adjugate( void ) const;
00286 float trace( void ) const;
00287 float determinant( void ) const;
00288 Mat3 inverse( void ) const;
00289 bool equals( const Mat3 &, float epsilon = 0.0f ) const;
00290 bool equals( const float *, float epsilon = 0.0f ) const;
00291 void toAxisAngle( const Vec3 &, float & radians ) const;
00292
00293 float & getElement( int column, int row );
00294 void setRow( int index, const Vec3 & row );
00295 void setCol( int index, const Vec3 & col );
00296 void setElement( int col, int row, float );
00297 void setIdentity( void );
00298
00299 static Mat3 fromAxisAngle( const Vec3 & axis, float radians );
00300 static Mat3 fromIdentity();
00301
00302 private:
00303 float m_v[9];
00304 };
00305
00306 class Vec4 {
00307 public:
00308 Vec4( float xyzw = 0.0f );
00309 Vec4( float x, float y, float z, float w = 1.0f );
00310 Vec4( const Vec2 & xy, float z, float w = 1.0f );
00311 Vec4( const Vec3 & xyz, float w = 1.0f );
00312 Vec4( const Vec2 & xy, const Vec2 & zw );
00313 Vec4( float x, const Vec3 & yzw );
00314 Vec4( float x, float y, const Vec2 & zw );
00315 Vec4( const float * v );
00316
00317 bool operator < ( const float ) const;
00318 bool operator < ( const Vec2 & ) const;
00319 bool operator < ( const Vec3 & ) const;
00320 bool operator < ( const Vec4 & ) const;
00321 Vec4 operator - () const;
00322 Vec4 operator + ( const Vec4 & b ) const;
00323 Vec4 operator - ( const Vec4 & b ) const;
00324 Vec4 operator * ( const Vec4 & b ) const;
00325 Vec4 operator * ( float b ) const;
00326 Vec4 operator / ( float b ) const;
00327 Vec4 operator / ( const Vec4 & b ) const;
00328 const float & operator [] ( const int index ) const;
00329 bool operator == ( const Vec4 & b ) const;
00330 const float * operator * ( void ) const;
00331
00332 float & operator [] ( int index );
00333 Vec4 & operator += ( const Vec4 & b );
00334 Vec4 & operator -= ( const Vec4 & b );
00335 Vec4 & operator *= ( float b );
00336 Vec4 & operator *= ( const Vec4 & b );
00337 Vec4 & operator /= ( float b );
00338 Vec4 & operator /= ( const Vec4 & b );
00339
00340 Vec2 xy() const;
00341 Vec2 zw() const;
00342 Vec3 xyz() const;
00343 float hyp( void ) const;
00344 float len( void ) const;
00345 void normalize( void );
00346 Vec4 normalized( void ) const;
00347 Vec4 abs( void ) const;
00348 Vec4 sgn( void ) const;
00349 Vec4 clamp( float min = 0.0f, float max = 1.0f ) const;
00350 float dot( const Vec4 & b ) const;
00351 bool equals( const Vec4 & compare, float epsilon = 0.0f ) const;
00352 bool equals( const float * compare, float epsilon = 0.0f ) const;
00353
00354 float & getElement( int index );
00355
00356 private:
00357 float m_v[4];
00358 };
00359
00360 class Quat {
00361 public:
00362 Quat( float v0 = 0.0f, float v1 = 0.0f, float v2 = 0.0f, float v3 = 0.0f );
00363 Quat( const Mat3 & mat );
00364 Quat( const float * v );
00365
00366 bool operator == ( const Quat & ) const;
00367 bool operator != ( const Quat & ) const;
00368 Quat operator + ( const Quat & ) const;
00369 Quat operator - ( const Quat & ) const;
00370 Quat operator * ( const Quat & ) const;
00371 Quat operator * ( float s ) const;
00372 Quat operator / ( float s ) const;
00373 Quat operator - () const;
00374 const float & operator [] ( const int ) const;
00375 const float * operator * ( void ) const;
00376
00377 float & operator [] ( int index );
00378 Quat & operator += ( const Quat & );
00379 Quat & operator -= ( const Quat & );
00380 Quat & operator *= ( float scalar );
00381 Quat & operator /= ( float scalar );
00382
00383 Vec2 xy( void ) const;
00384 Vec2 zw( void ) const;
00385 Vec3 xyz( void ) const;
00386 const float & getElement( int index ) const;
00387 float hyp( void ) const;
00388 float len( void ) const;
00389 void normalize( void );
00390 Quat normalized( void ) const;
00391 float dot( const Quat & ) const;
00392 Quat inverse( void ) const;
00393 Quat conjugate( void ) const;
00394 Quat exp( void ) const;
00395 Quat log( void ) const;
00396 bool equals( const Quat & compare, float epsilon = 0.0f ) const;
00397 bool equals( const float * compare, float epsilon = 0.0f ) const;
00398 Mat3 toMat3( void ) const;
00399 void toAxisAngle( Vec3 & axis, float & radians ) const;
00400
00401 float & getElement( int index );
00402
00403 static Quat fromMat3( const Mat3 & );
00404 static Quat fromAxisAngle( const Vec3 & axis, float radians );
00405
00406 private:
00407 float m_v[4];
00408 };
00409
00410 class Mat4 {
00411 public:
00412 Mat4( float v00 = 1.0f, float v01 = 0.0f, float v02 = 0.0f, float v03 = 0.0f,
00413 float v10 = 0.0f, float v11 = 1.0f, float v12 = 0.0f, float v13 = 0.0f,
00414 float v20 = 0.0f, float v21 = 0.0f, float v22 = 1.0f, float v23 = 0.0f,
00415 float v30 = 0.0f, float v31 = 0.0f, float v32 = 0.0f, float v33 = 1.0f );
00416 Mat4( const float * );
00417
00418 Vec3 operator * ( const Vec3 & ) const;
00419 Vec4 operator * ( const Vec4 & ) const;
00420 Mat3 operator * ( const Mat3 & ) const;
00421 Mat4 operator * ( const Mat4 & ) const;
00422 Mat4 operator * ( float ) const;
00423 Mat4 operator + ( const Vec2 & ) const;
00424 Mat4 operator + ( const Vec3 & ) const;
00425 const float & operator [] ( const int index ) const;
00426 bool operator == ( const Mat4 & b ) const;
00427 const float * operator * ( void ) const;
00428
00429 float & operator [] ( int );
00430 Mat4 & operator *= ( const Mat4 & b );
00431 Mat4 & operator = ( const Mat3 & b );
00432 Mat4 & operator = ( const Vec3 & b );
00433 Mat4 & operator *= ( float );
00434 Mat4 & operator *= ( const Vec3 & );
00435 Mat4 & operator += ( const Vec2 & );
00436 Mat4 & operator += ( const Vec3 & );
00437
00438 Vec4 getRow( int ) const;
00439 Vec4 getCol( int ) const;
00440 const float & getElement( int column, int row ) const;
00441 bool equals( const Mat4 &, float epsilon = 0.0f ) const;
00442 bool equals( const float *, float epsilon = 0.0f ) const;
00443
00444 Vec3 translation( void ) const;
00445 Mat3 rotation( void ) const;
00446 Mat4 transpose( void ) const;
00447 Mat4 inverse( void ) const;
00448 Vec4 toPolar( void ) const;
00449 Mat3 toMat3( void ) const;
00450 Quat toQuaternion( void ) const;
00451 Vec4 toPlaneEquation( void ) const;
00452
00453 float & getElement( int column, int row );
00454 void setElement( int col, int row, float v );
00455 void setRow( int index, const Vec4 & row );
00456 void setCol( int index, const Vec4 & col );
00457 void setIdentity( void );
00458 void ortho( float left, float right, float bottom, float top, float near, float far );
00459 void frustum( float left, float right, float bottom, float top, float near, float far );
00460 void perspective( float fovy, float aspect, float near, float far );
00461 void lookAt( const Vec3 & eye, const Vec3 & center, const Vec3 & up = Vec3( 0.0f, 0.0f, 1.0f ) );
00462 void translate( const Vec3 & b );
00463 void setTranslation( const Vec3 & b );
00464
00465 static Mat4 fromQuaternion( const Quat & );
00466 static Mat4 fromPlaneEquation( const Vec4 & xyzd );
00467 static Mat4 fromDirectionalAxis( const Vec3 &, char principalAxis = 'z' );
00468 static Mat4 fromPolar( const Vec4 & xyVectors );
00469 static Mat4 fromTransformation( const Vec3 & position, const Mat3 & rotation );
00470 static Mat4 fromAxisAngle( const Vec3 &, float radians = 0.0, const Vec3 & position = Vec3( 0.0f ) );
00471 static Mat4 fromIdentity( void );
00472 static Mat4 fromOrtho( float left, float right, float bottom, float top, float near, float far );
00473 static Mat4 fromFrustum( float left, float right, float bottom, float top, float near, float far );
00474 static Mat4 fromPerspective( float fovy, float aspect, float near, float far );
00475 static Mat4 fromLookAt( const Vec3 & eye, const Vec3 & center = Vec3(), const Vec3 & up = Vec3( 0.0f, 0.0f, 1.0f ) );
00476
00477 private:
00478 float m_v[16];
00479 };
00480
00481 namespace Matrix {
00482 enum Mode{
00483 PROJECTION = 0,
00484 MODELVIEW = 1,
00485 TEXTURE = 2
00486 };
00487
00488 void initialize( void );
00489
00490 const Mat4 & get( Mode );
00491 void set( Mode, const Mat4 & );
00492 void push( Mode );
00493 void push( Mode, const Mat4 & );
00494 Mat4 pop( Mode );
00495
00496 Vec3 project( const Vec3 & object, const Vec4 & viewport );
00497 Vec3 unProject( const Vec3 & window, const Vec4 & viewport );
00498 };
00499
00500 };
00501
00502 #endif //MATRIXMATH_H
00503