00001
00002
00003
00004
00005 #ifndef __IRR_MATRIX_H_INCLUDED__
00006 #define __IRR_MATRIX_H_INCLUDED__
00007
00008 #include "irrTypes.h"
00009 #include "vector3d.h"
00010 #include "vector2d.h"
00011 #include "plane3d.h"
00012 #include "aabbox3d.h"
00013 #include "rect.h"
00014 #include "irrString.h"
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if defined( USE_MATRIX_TEST_DEBUG )
00025 #include <windows.h>
00026
00027 struct MatrixTest
00028 {
00029 MatrixTest () : ID(0), Calls(0) {}
00030 char buf[256];
00031 int Calls;
00032 int ID;
00033 };
00034 static MatrixTest MTest;
00035
00036 #endif
00037
00038 namespace irr
00039 {
00040 namespace core
00041 {
00042
00044
00045 template <class T>
00046 class CMatrix4
00047 {
00048 public:
00049
00051 enum eConstructor
00052 {
00053 EM4CONST_NOTHING = 0,
00054 EM4CONST_COPY,
00055 EM4CONST_IDENTITY,
00056 EM4CONST_TRANSPOSED,
00057 EM4CONST_INVERSE,
00058 EM4CONST_INVERSE_TRANSPOSED
00059 };
00060
00062
00063 CMatrix4( eConstructor constructor = EM4CONST_IDENTITY );
00065
00067 CMatrix4( const CMatrix4<T>& other,eConstructor constructor = EM4CONST_COPY);
00068
00070 T& operator()(const s32 row, const s32 col)
00071 {
00072 #if defined ( USE_MATRIX_TEST )
00073 definitelyIdentityMatrix=false;
00074 #endif
00075 return M[ row * 4 + col ];
00076 }
00077
00079 const T& operator()(const s32 row, const s32 col) const { return M[row * 4 + col]; }
00080
00082 T& operator[](u32 index)
00083 {
00084 #if defined ( USE_MATRIX_TEST )
00085 definitelyIdentityMatrix=false;
00086 #endif
00087 return M[index];
00088 }
00089
00091 const T& operator[](u32 index) const { return M[index]; }
00092
00094 inline CMatrix4<T>& operator=(const CMatrix4<T> &other);
00095
00097 inline CMatrix4<T>& operator=(const T& scalar);
00098
00100 const T* pointer() const { return M; }
00101 T* pointer()
00102 {
00103 #if defined ( USE_MATRIX_TEST )
00104 definitelyIdentityMatrix=false;
00105 #endif
00106 return M;
00107 }
00108
00110 bool operator==(const CMatrix4<T> &other) const;
00111
00113 bool operator!=(const CMatrix4<T> &other) const;
00114
00116 CMatrix4<T> operator+(const CMatrix4<T>& other) const;
00117
00119 CMatrix4<T>& operator+=(const CMatrix4<T>& other);
00120
00122 CMatrix4<T> operator-(const CMatrix4<T>& other) const;
00123
00125 CMatrix4<T>& operator-=(const CMatrix4<T>& other);
00126
00128 inline CMatrix4<T>& setbyproduct(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b );
00129
00131
00133 CMatrix4<T>& setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b );
00134
00136 CMatrix4<T> operator*(const CMatrix4<T>& other) const;
00137
00139 CMatrix4<T>& operator*=(const CMatrix4<T>& other);
00140
00142 CMatrix4<T> operator*(const T& scalar) const;
00143
00145 CMatrix4<T>& operator*=(const T& scalar);
00146
00148 inline CMatrix4<T>& makeIdentity();
00149
00151 inline bool isIdentity() const;
00152
00154 inline bool isOrthogonal() const;
00155
00157 bool isIdentity_integer_base () const;
00158
00160 CMatrix4<T>& setTranslation( const vector3d<T>& translation );
00161
00163 vector3d<T> getTranslation() const;
00164
00166 CMatrix4<T>& setInverseTranslation( const vector3d<T>& translation );
00167
00169 inline CMatrix4<T>& setRotationRadians( const vector3d<T>& rotation );
00170
00172 CMatrix4<T>& setRotationDegrees( const vector3d<T>& rotation );
00173
00175
00176 core::vector3d<T> getRotationDegrees() const;
00177
00179
00180 inline CMatrix4<T>& setInverseRotationRadians( const vector3d<T>& rotation );
00181
00183
00184 CMatrix4<T>& setInverseRotationDegrees( const vector3d<T>& rotation );
00185
00187 CMatrix4<T>& setScale( const vector3d<T>& scale );
00188
00190 CMatrix4<T>& setScale( const T scale ) { return setScale(core::vector3d<T>(scale,scale,scale)); }
00191
00193 core::vector3d<T> getScale() const;
00194
00196 void inverseTranslateVect( vector3df& vect ) const;
00197
00199 void inverseRotateVect( vector3df& vect ) const;
00200
00202 void rotateVect( vector3df& vect ) const;
00203
00205 void rotateVect(core::vector3df& out, const core::vector3df& in) const;
00206
00208 void rotateVect(T *out,const core::vector3df &in) const;
00209
00211 void transformVect( vector3df& vect) const;
00212
00214 void transformVect( vector3df& out, const vector3df& in ) const;
00215
00217 void transformVect(T *out,const core::vector3df &in) const;
00218
00220 void translateVect( vector3df& vect ) const;
00221
00223 void transformPlane( core::plane3d<f32> &plane) const;
00224
00226 void transformPlane( const core::plane3d<f32> &in, core::plane3d<f32> &out) const;
00227
00229
00231 void transformBox(core::aabbox3d<f32>& box) const;
00232
00234
00236 void transformBoxEx(core::aabbox3d<f32>& box) const;
00237
00239 void multiplyWith1x4Matrix(T* matrix) const;
00240
00242
00243 bool makeInverse();
00244
00245
00247
00248 bool getInversePrimitive ( CMatrix4<T>& out ) const;
00249
00251
00253 bool getInverse(CMatrix4<T>& out) const;
00254
00256 CMatrix4<T>& buildProjectionMatrixPerspectiveFovRH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar);
00257
00259 CMatrix4<T>& buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar);
00260
00262 CMatrix4<T>& buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
00263
00265 CMatrix4<T>& buildProjectionMatrixPerspectiveLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
00266
00268 CMatrix4<T>& buildProjectionMatrixOrthoLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
00269
00271 CMatrix4<T>& buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
00272
00274 CMatrix4<T>& buildCameraLookAtMatrixLH(
00275 const vector3df& position,
00276 const vector3df& target,
00277 const vector3df& upVector);
00278
00280 CMatrix4<T>& buildCameraLookAtMatrixRH(
00281 const vector3df& position,
00282 const vector3df& target,
00283 const vector3df& upVector);
00284
00286
00290 CMatrix4<T>& buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point=1.0f);
00291
00293
00294 CMatrix4<T>& buildNDCToDCMatrix( const core::rect<s32>& area, f32 zScale);
00295
00297
00299 CMatrix4<T> interpolate(const core::CMatrix4<T>& b, f32 time) const;
00300
00302 CMatrix4<T> getTransposed() const;
00303
00305 inline void getTransposed( CMatrix4<T>& dest ) const;
00306
00308
00311 CMatrix4<T>& buildRotateFromTo(const core::vector3df& from, const core::vector3df& to);
00312
00314
00317 void setRotationCenter(const core::vector3df& center, const core::vector3df& translate);
00318
00320
00326 void buildAxisAlignedBillboard( const core::vector3df& camPos,
00327 const core::vector3df& center,
00328 const core::vector3df& translation,
00329 const core::vector3df& axis,
00330 const core::vector3df& from
00331 );
00332
00333
00334
00335
00336
00338 CMatrix4<T>& buildTextureTransform( f32 rotateRad,
00339 const core::vector2df &rotatecenter,
00340 const core::vector2df &translate,
00341 const core::vector2df &scale);
00342
00344
00348 CMatrix4<T>& setTextureRotationCenter( f32 radAngle );
00349
00351
00355 CMatrix4<T>& setTextureTranslate( f32 x, f32 y );
00356
00358
00362 CMatrix4<T>& setTextureTranslateTransposed( f32 x, f32 y );
00363
00365
00369 CMatrix4<T>& setTextureScale( f32 sx, f32 sy );
00370
00372
00376 CMatrix4<T>& setTextureScaleCenter( f32 sx, f32 sy );
00377
00379 CMatrix4<T>& setM(const T* data);
00380
00382 void setDefinitelyIdentityMatrix( bool isDefinitelyIdentityMatrix);
00383
00385 bool getDefinitelyIdentityMatrix() const;
00386
00387 private:
00389 T M[16];
00390 #if defined ( USE_MATRIX_TEST )
00392 mutable u32 definitelyIdentityMatrix;
00393 #endif
00394 #if defined ( USE_MATRIX_TEST_DEBUG )
00395 u32 id;
00396 mutable u32 calls;
00397 #endif
00398
00399 };
00400
00401
00402 template <class T>
00403 inline CMatrix4<T>::CMatrix4( eConstructor constructor )
00404 #if defined ( USE_MATRIX_TEST )
00405 : definitelyIdentityMatrix(BIT_UNTESTED)
00406 #endif
00407 #if defined ( USE_MATRIX_TEST_DEBUG )
00408 ,id ( MTest.ID++), calls ( 0 )
00409 #endif
00410 {
00411 switch ( constructor )
00412 {
00413 case EM4CONST_NOTHING:
00414 case EM4CONST_COPY:
00415 break;
00416 case EM4CONST_IDENTITY:
00417 case EM4CONST_INVERSE:
00418 default:
00419 makeIdentity();
00420 break;
00421 }
00422 }
00423
00424
00425 template <class T>
00426 inline CMatrix4<T>::CMatrix4( const CMatrix4<T>& other, eConstructor constructor)
00427 #if defined ( USE_MATRIX_TEST )
00428 : definitelyIdentityMatrix(BIT_UNTESTED)
00429 #endif
00430 #if defined ( USE_MATRIX_TEST_DEBUG )
00431 ,id ( MTest.ID++), calls ( 0 )
00432 #endif
00433 {
00434 switch ( constructor )
00435 {
00436 case EM4CONST_IDENTITY:
00437 makeIdentity();
00438 break;
00439 case EM4CONST_NOTHING:
00440 break;
00441 case EM4CONST_COPY:
00442 *this = other;
00443 break;
00444 case EM4CONST_TRANSPOSED:
00445 other.getTransposed(*this);
00446 break;
00447 case EM4CONST_INVERSE:
00448 if (!other.getInverse(*this))
00449 memset(M, 0, 16*sizeof(T));
00450 break;
00451 case EM4CONST_INVERSE_TRANSPOSED:
00452 if (!other.getInverse(*this))
00453 memset(M, 0, 16*sizeof(T));
00454 else
00455 *this=getTransposed();
00456 break;
00457 }
00458 }
00459
00461 template <class T>
00462 inline CMatrix4<T> CMatrix4<T>::operator+(const CMatrix4<T>& other) const
00463 {
00464 CMatrix4<T> temp ( EM4CONST_NOTHING );
00465
00466 temp[0] = M[0]+other[0];
00467 temp[1] = M[1]+other[1];
00468 temp[2] = M[2]+other[2];
00469 temp[3] = M[3]+other[3];
00470 temp[4] = M[4]+other[4];
00471 temp[5] = M[5]+other[5];
00472 temp[6] = M[6]+other[6];
00473 temp[7] = M[7]+other[7];
00474 temp[8] = M[8]+other[8];
00475 temp[9] = M[9]+other[9];
00476 temp[10] = M[10]+other[10];
00477 temp[11] = M[11]+other[11];
00478 temp[12] = M[12]+other[12];
00479 temp[13] = M[13]+other[13];
00480 temp[14] = M[14]+other[14];
00481 temp[15] = M[15]+other[15];
00482
00483 return temp;
00484 }
00485
00487 template <class T>
00488 inline CMatrix4<T>& CMatrix4<T>::operator+=(const CMatrix4<T>& other)
00489 {
00490 M[0]+=other[0];
00491 M[1]+=other[1];
00492 M[2]+=other[2];
00493 M[3]+=other[3];
00494 M[4]+=other[4];
00495 M[5]+=other[5];
00496 M[6]+=other[6];
00497 M[7]+=other[7];
00498 M[8]+=other[8];
00499 M[9]+=other[9];
00500 M[10]+=other[10];
00501 M[11]+=other[11];
00502 M[12]+=other[12];
00503 M[13]+=other[13];
00504 M[14]+=other[14];
00505 M[15]+=other[15];
00506
00507 return *this;
00508 }
00509
00511 template <class T>
00512 inline CMatrix4<T> CMatrix4<T>::operator-(const CMatrix4<T>& other) const
00513 {
00514 CMatrix4<T> temp ( EM4CONST_NOTHING );
00515
00516 temp[0] = M[0]-other[0];
00517 temp[1] = M[1]-other[1];
00518 temp[2] = M[2]-other[2];
00519 temp[3] = M[3]-other[3];
00520 temp[4] = M[4]-other[4];
00521 temp[5] = M[5]-other[5];
00522 temp[6] = M[6]-other[6];
00523 temp[7] = M[7]-other[7];
00524 temp[8] = M[8]-other[8];
00525 temp[9] = M[9]-other[9];
00526 temp[10] = M[10]-other[10];
00527 temp[11] = M[11]-other[11];
00528 temp[12] = M[12]-other[12];
00529 temp[13] = M[13]-other[13];
00530 temp[14] = M[14]-other[14];
00531 temp[15] = M[15]-other[15];
00532
00533 return temp;
00534 }
00535
00537 template <class T>
00538 inline CMatrix4<T>& CMatrix4<T>::operator-=(const CMatrix4<T>& other)
00539 {
00540 M[0]-=other[0];
00541 M[1]-=other[1];
00542 M[2]-=other[2];
00543 M[3]-=other[3];
00544 M[4]-=other[4];
00545 M[5]-=other[5];
00546 M[6]-=other[6];
00547 M[7]-=other[7];
00548 M[8]-=other[8];
00549 M[9]-=other[9];
00550 M[10]-=other[10];
00551 M[11]-=other[11];
00552 M[12]-=other[12];
00553 M[13]-=other[13];
00554 M[14]-=other[14];
00555 M[15]-=other[15];
00556
00557 return *this;
00558 }
00559
00561 template <class T>
00562 inline CMatrix4<T> CMatrix4<T>::operator*(const T& scalar) const
00563 {
00564 CMatrix4<T> temp ( EM4CONST_NOTHING );
00565
00566 temp[0] = M[0]*scalar;
00567 temp[1] = M[1]*scalar;
00568 temp[2] = M[2]*scalar;
00569 temp[3] = M[3]*scalar;
00570 temp[4] = M[4]*scalar;
00571 temp[5] = M[5]*scalar;
00572 temp[6] = M[6]*scalar;
00573 temp[7] = M[7]*scalar;
00574 temp[8] = M[8]*scalar;
00575 temp[9] = M[9]*scalar;
00576 temp[10] = M[10]*scalar;
00577 temp[11] = M[11]*scalar;
00578 temp[12] = M[12]*scalar;
00579 temp[13] = M[13]*scalar;
00580 temp[14] = M[14]*scalar;
00581 temp[15] = M[15]*scalar;
00582
00583 return temp;
00584 }
00585
00587 template <class T>
00588 inline CMatrix4<T>& CMatrix4<T>::operator*=(const T& scalar)
00589 {
00590 M[0]*=scalar;
00591 M[1]*=scalar;
00592 M[2]*=scalar;
00593 M[3]*=scalar;
00594 M[4]*=scalar;
00595 M[5]*=scalar;
00596 M[6]*=scalar;
00597 M[7]*=scalar;
00598 M[8]*=scalar;
00599 M[9]*=scalar;
00600 M[10]*=scalar;
00601 M[11]*=scalar;
00602 M[12]*=scalar;
00603 M[13]*=scalar;
00604 M[14]*=scalar;
00605 M[15]*=scalar;
00606
00607 return *this;
00608 }
00609
00611 template <class T>
00612 inline CMatrix4<T>& CMatrix4<T>::operator*=(const CMatrix4<T>& other)
00613 {
00614 #if defined ( USE_MATRIX_TEST )
00615
00616 if ( !other.isIdentity() )
00617 {
00618 if ( this->isIdentity() )
00619 {
00620 return (*this = other);
00621 }
00622 else
00623 {
00624 CMatrix4<T> temp ( *this );
00625 return setbyproduct_nocheck( temp, other );
00626 }
00627 }
00628 return *this;
00629 #else
00630 CMatrix4<T> temp ( *this );
00631 return setbyproduct_nocheck( temp, other );
00632 #endif
00633 }
00634
00636
00637
00638 template <class T>
00639 inline CMatrix4<T>& CMatrix4<T>::setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b )
00640 {
00641 const T *m1 = other_a.M;
00642 const T *m2 = other_b.M;
00643
00644 M[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3];
00645 M[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3];
00646 M[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3];
00647 M[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3];
00648
00649 M[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7];
00650 M[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7];
00651 M[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7];
00652 M[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7];
00653
00654 M[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11];
00655 M[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11];
00656 M[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11];
00657 M[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11];
00658
00659 M[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15];
00660 M[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15];
00661 M[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
00662 M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
00663 #if defined ( USE_MATRIX_TEST )
00664 definitelyIdentityMatrix=false;
00665 #endif
00666 return *this;
00667 }
00668
00669
00671
00672
00673 template <class T>
00674 inline CMatrix4<T>& CMatrix4<T>::setbyproduct(const CMatrix4<T>& other_a, const CMatrix4<T>& other_b )
00675 {
00676 #if defined ( USE_MATRIX_TEST )
00677 if ( other_a.isIdentity () )
00678 return (*this = other_b);
00679 else
00680 if ( other_b.isIdentity () )
00681 return (*this = other_a);
00682 else
00683 return setbyproduct_nocheck(other_a,other_b);
00684 #else
00685 return setbyproduct_nocheck(other_a,other_b);
00686 #endif
00687 }
00688
00690 template <class T>
00691 inline CMatrix4<T> CMatrix4<T>::operator*(const CMatrix4<T>& m2) const
00692 {
00693 #if defined ( USE_MATRIX_TEST )
00694
00695 if ( this->isIdentity() )
00696 return m2;
00697 if ( m2.isIdentity() )
00698 return *this;
00699 #endif
00700
00701 CMatrix4<T> m3 ( EM4CONST_NOTHING );
00702
00703 const T *m1 = M;
00704
00705 m3[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3];
00706 m3[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3];
00707 m3[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3];
00708 m3[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3];
00709
00710 m3[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7];
00711 m3[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7];
00712 m3[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7];
00713 m3[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7];
00714
00715 m3[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11];
00716 m3[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11];
00717 m3[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11];
00718 m3[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11];
00719
00720 m3[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15];
00721 m3[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15];
00722 m3[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
00723 m3[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
00724 return m3;
00725 }
00726
00727
00728
00729 template <class T>
00730 inline vector3d<T> CMatrix4<T>::getTranslation() const
00731 {
00732 return vector3d<T>(M[12], M[13], M[14]);
00733 }
00734
00735
00736 template <class T>
00737 inline CMatrix4<T>& CMatrix4<T>::setTranslation( const vector3d<T>& translation )
00738 {
00739 M[12] = translation.X;
00740 M[13] = translation.Y;
00741 M[14] = translation.Z;
00742 #if defined ( USE_MATRIX_TEST )
00743 definitelyIdentityMatrix=false;
00744 #endif
00745 return *this;
00746 }
00747
00748 template <class T>
00749 inline CMatrix4<T>& CMatrix4<T>::setInverseTranslation( const vector3d<T>& translation )
00750 {
00751 M[12] = -translation.X;
00752 M[13] = -translation.Y;
00753 M[14] = -translation.Z;
00754 #if defined ( USE_MATRIX_TEST )
00755 definitelyIdentityMatrix=false;
00756 #endif
00757 return *this;
00758 }
00759
00760 template <class T>
00761 inline CMatrix4<T>& CMatrix4<T>::setScale( const vector3d<T>& scale )
00762 {
00763 M[0] = scale.X;
00764 M[5] = scale.Y;
00765 M[10] = scale.Z;
00766 #if defined ( USE_MATRIX_TEST )
00767 definitelyIdentityMatrix=false;
00768 #endif
00769 return *this;
00770 }
00771
00773
00780 template <class T>
00781 inline vector3d<T> CMatrix4<T>::getScale() const
00782 {
00783
00784
00785
00786
00787 if(core::iszero(M[1]) && core::iszero(M[2]) &&
00788 core::iszero(M[4]) && core::iszero(M[6]) &&
00789 core::iszero(M[8]) && core::iszero(M[9]))
00790 return vector3d<T>(M[0], M[5], M[10]);
00791
00792
00793 return vector3d<T>(sqrtf(M[0] * M[0] + M[1] * M[1] + M[2] * M[2]),
00794 sqrtf(M[4] * M[4] + M[5] * M[5] + M[6] * M[6]),
00795 sqrtf(M[8] * M[8] + M[9] * M[9] + M[10] * M[10]));
00796 }
00797
00798 template <class T>
00799 inline CMatrix4<T>& CMatrix4<T>::setRotationDegrees( const vector3d<T>& rotation )
00800 {
00801 return setRotationRadians( rotation * core::DEGTORAD );
00802 }
00803
00804 template <class T>
00805 inline CMatrix4<T>& CMatrix4<T>::setInverseRotationDegrees( const vector3d<T>& rotation )
00806 {
00807 return setInverseRotationRadians( rotation * core::DEGTORAD );
00808 }
00809
00810 template <class T>
00811 inline CMatrix4<T>& CMatrix4<T>::setRotationRadians( const vector3d<T>& rotation )
00812 {
00813 const f64 cr = cos( rotation.X );
00814 const f64 sr = sin( rotation.X );
00815 const f64 cp = cos( rotation.Y );
00816 const f64 sp = sin( rotation.Y );
00817 const f64 cy = cos( rotation.Z );
00818 const f64 sy = sin( rotation.Z );
00819
00820 M[0] = (T)( cp*cy );
00821 M[1] = (T)( cp*sy );
00822 M[2] = (T)( -sp );
00823
00824 const f64 srsp = sr*sp;
00825 const f64 crsp = cr*sp;
00826
00827 M[4] = (T)( srsp*cy-cr*sy );
00828 M[5] = (T)( srsp*sy+cr*cy );
00829 M[6] = (T)( sr*cp );
00830
00831 M[8] = (T)( crsp*cy+sr*sy );
00832 M[9] = (T)( crsp*sy-sr*cy );
00833 M[10] = (T)( cr*cp );
00834 #if defined ( USE_MATRIX_TEST )
00835 definitelyIdentityMatrix=false;
00836 #endif
00837 return *this;
00838 }
00839
00840
00842
00845 template <class T>
00846 inline core::vector3d<T> CMatrix4<T>::getRotationDegrees() const
00847 {
00848 const CMatrix4<T> &mat = *this;
00849
00850 f64 Y = -asin(mat(0,2));
00851 const f64 C = cos(Y);
00852 Y *= RADTODEG64;
00853
00854 f64 rotx, roty, X, Z;
00855
00856 if (fabs(C)>ROUNDING_ERROR_f64)
00857 {
00858 const T invC = (T)(1.0/C);
00859 rotx = mat(2,2) * invC;
00860 roty = mat(1,2) * invC;
00861 X = atan2( roty, rotx ) * RADTODEG64;
00862 rotx = mat(0,0) * invC;
00863 roty = mat(0,1) * invC;
00864 Z = atan2( roty, rotx ) * RADTODEG64;
00865 }
00866 else
00867 {
00868 X = 0.0;
00869 rotx = mat(1,1);
00870 roty = -mat(1,0);
00871 Z = atan2( roty, rotx ) * RADTODEG64;
00872 }
00873
00874
00875
00876
00877 if (X < 0.0) X += 360.0;
00878 if (Y < 0.0) Y += 360.0;
00879 if (Z < 0.0) Z += 360.0;
00880
00881 return vector3d<T>((T)X,(T)Y,(T)Z);
00882 }
00883
00884
00885 template <class T>
00886 inline CMatrix4<T>& CMatrix4<T>::setInverseRotationRadians( const vector3d<T>& rotation )
00887 {
00888 f64 cr = cos( rotation.X );
00889 f64 sr = sin( rotation.X );
00890 f64 cp = cos( rotation.Y );
00891 f64 sp = sin( rotation.Y );
00892 f64 cy = cos( rotation.Z );
00893 f64 sy = sin( rotation.Z );
00894
00895 M[0] = (T)( cp*cy );
00896 M[4] = (T)( cp*sy );
00897 M[8] = (T)( -sp );
00898
00899 f64 srsp = sr*sp;
00900 f64 crsp = cr*sp;
00901
00902 M[1] = (T)( srsp*cy-cr*sy );
00903 M[5] = (T)( srsp*sy+cr*cy );
00904 M[9] = (T)( sr*cp );
00905
00906 M[2] = (T)( crsp*cy+sr*sy );
00907 M[6] = (T)( crsp*sy-sr*cy );
00908 M[10] = (T)( cr*cp );
00909 #if defined ( USE_MATRIX_TEST )
00910 definitelyIdentityMatrix=false;
00911 #endif
00912 return *this;
00913 }
00914
00915
00918 template <class T>
00919 inline CMatrix4<T>& CMatrix4<T>::makeIdentity()
00920 {
00921 memset(M, 0, 16*sizeof(T));
00922 M[0] = M[5] = M[10] = M[15] = (T)1;
00923 #if defined ( USE_MATRIX_TEST )
00924 definitelyIdentityMatrix=true;
00925 #endif
00926 return *this;
00927 }
00928
00929
00930
00931
00932
00933
00934 template <class T>
00935 inline bool CMatrix4<T>::isIdentity() const
00936 {
00937 #if defined ( USE_MATRIX_TEST )
00938 if (definitelyIdentityMatrix)
00939 return true;
00940 #endif
00941 if (!equals( M[ 0], (T)1 ) ||
00942 !equals( M[ 5], (T)1 ) ||
00943 !equals( M[10], (T)1 ) ||
00944 !equals( M[15], (T)1 ))
00945 return false;
00946
00947 for (s32 i=0; i<4; ++i)
00948 for (s32 j=0; j<4; ++j)
00949 if ((j != i) && (!iszero((*this)(i,j))))
00950 return false;
00951
00952 #if defined ( USE_MATRIX_TEST )
00953 definitelyIdentityMatrix=true;
00954 #endif
00955 return true;
00956 }
00957
00958
00959
00960 template <class T>
00961 inline bool CMatrix4<T>::isOrthogonal() const
00962 {
00963 T dp=M[0] * M[4 ] + M[1] * M[5 ] + M[2 ] * M[6 ] + M[3 ] * M[7 ];
00964 if (!iszero(dp))
00965 return false;
00966 dp = M[0] * M[8 ] + M[1] * M[9 ] + M[2 ] * M[10] + M[3 ] * M[11];
00967 if (!iszero(dp))
00968 return false;
00969 dp = M[0] * M[12] + M[1] * M[13] + M[2 ] * M[14] + M[3 ] * M[15];
00970 if (!iszero(dp))
00971 return false;
00972 dp = M[4] * M[8 ] + M[5] * M[9 ] + M[6 ] * M[10] + M[7 ] * M[11];
00973 if (!iszero(dp))
00974 return false;
00975 dp = M[4] * M[12] + M[5] * M[13] + M[6 ] * M[14] + M[7 ] * M[15];
00976 if (!iszero(dp))
00977 return false;
00978 dp = M[8] * M[12] + M[9] * M[13] + M[10] * M[14] + M[11] * M[15];
00979 return (iszero(dp));
00980 }
00981
00982
00983
00984
00985
00986
00987
00988
00989 template <class T>
00990 inline bool CMatrix4<T>::isIdentity_integer_base() const
00991 {
00992 #if defined ( USE_MATRIX_TEST )
00993 if (definitelyIdentityMatrix)
00994 return true;
00995 #endif
00996 if(IR(M[0])!=F32_VALUE_1) return false;
00997 if(IR(M[1])!=0) return false;
00998 if(IR(M[2])!=0) return false;
00999 if(IR(M[3])!=0) return false;
01000
01001 if(IR(M[4])!=0) return false;
01002 if(IR(M[5])!=F32_VALUE_1) return false;
01003 if(IR(M[6])!=0) return false;
01004 if(IR(M[7])!=0) return false;
01005
01006 if(IR(M[8])!=0) return false;
01007 if(IR(M[9])!=0) return false;
01008 if(IR(M[10])!=F32_VALUE_1) return false;
01009 if(IR(M[11])!=0) return false;
01010
01011 if(IR(M[12])!=0) return false;
01012 if(IR(M[13])!=0) return false;
01013 if(IR(M[13])!=0) return false;
01014 if(IR(M[15])!=F32_VALUE_1) return false;
01015
01016 #if defined ( USE_MATRIX_TEST )
01017 definitelyIdentityMatrix=true;
01018 #endif
01019 return true;
01020 }
01021
01022
01023 template <class T>
01024 inline void CMatrix4<T>::rotateVect( vector3df& vect ) const
01025 {
01026 vector3df tmp = vect;
01027 vect.X = tmp.X*M[0] + tmp.Y*M[4] + tmp.Z*M[8];
01028 vect.Y = tmp.X*M[1] + tmp.Y*M[5] + tmp.Z*M[9];
01029 vect.Z = tmp.X*M[2] + tmp.Y*M[6] + tmp.Z*M[10];
01030 }
01031
01033 template <class T>
01034 inline void CMatrix4<T>::rotateVect(core::vector3df& out, const core::vector3df& in) const
01035 {
01036 out.X = in.X*M[0] + in.Y*M[4] + in.Z*M[8];
01037 out.Y = in.X*M[1] + in.Y*M[5] + in.Z*M[9];
01038 out.Z = in.X*M[2] + in.Y*M[6] + in.Z*M[10];
01039 }
01040
01042 template <class T>
01043 inline void CMatrix4<T>::rotateVect(T *out, const core::vector3df& in) const
01044 {
01045 out[0] = in.X*M[0] + in.Y*M[4] + in.Z*M[8];
01046 out[1] = in.X*M[1] + in.Y*M[5] + in.Z*M[9];
01047 out[2] = in.X*M[2] + in.Y*M[6] + in.Z*M[10];
01048 }
01049
01050 template <class T>
01051 inline void CMatrix4<T>::inverseRotateVect( vector3df& vect ) const
01052 {
01053 vector3df tmp = vect;
01054 vect.X = tmp.X*M[0] + tmp.Y*M[1] + tmp.Z*M[2];
01055 vect.Y = tmp.X*M[4] + tmp.Y*M[5] + tmp.Z*M[6];
01056 vect.Z = tmp.X*M[8] + tmp.Y*M[9] + tmp.Z*M[10];
01057 }
01058
01059 template <class T>
01060 inline void CMatrix4<T>::transformVect( vector3df& vect) const
01061 {
01062 f32 vector[3];
01063
01064 vector[0] = vect.X*M[0] + vect.Y*M[4] + vect.Z*M[8] + M[12];
01065 vector[1] = vect.X*M[1] + vect.Y*M[5] + vect.Z*M[9] + M[13];
01066 vector[2] = vect.X*M[2] + vect.Y*M[6] + vect.Z*M[10] + M[14];
01067
01068 vect.X = vector[0];
01069 vect.Y = vector[1];
01070 vect.Z = vector[2];
01071 }
01072
01073 template <class T>
01074 inline void CMatrix4<T>::transformVect( vector3df& out, const vector3df& in) const
01075 {
01076 out.X = in.X*M[0] + in.Y*M[4] + in.Z*M[8] + M[12];
01077 out.Y = in.X*M[1] + in.Y*M[5] + in.Z*M[9] + M[13];
01078 out.Z = in.X*M[2] + in.Y*M[6] + in.Z*M[10] + M[14];
01079 }
01080
01081
01082 template <class T>
01083 inline void CMatrix4<T>::transformVect(T *out, const core::vector3df &in) const
01084 {
01085 out[0] = in.X*M[0] + in.Y*M[4] + in.Z*M[8] + M[12];
01086 out[1] = in.X*M[1] + in.Y*M[5] + in.Z*M[9] + M[13];
01087 out[2] = in.X*M[2] + in.Y*M[6] + in.Z*M[10] + M[14];
01088 out[3] = in.X*M[3] + in.Y*M[7] + in.Z*M[11] + M[15];
01089 }
01090
01091
01093 template <class T>
01094 inline void CMatrix4<T>::transformPlane( core::plane3d<f32> &plane) const
01095 {
01096 vector3df member;
01097
01098 transformVect(member, plane.getMemberPoint());
01099
01100
01101 CMatrix4<T> transposedInverse(*this, EM4CONST_INVERSE_TRANSPOSED);
01102 vector3df normal = plane.Normal;
01103 transposedInverse.transformVect(normal);
01104
01105 plane.setPlane(member, normal);
01106 }
01107
01109 template <class T>
01110 inline void CMatrix4<T>::transformPlane( const core::plane3d<f32> &in, core::plane3d<f32> &out) const
01111 {
01112 out = in;
01113 transformPlane( out );
01114 }
01115
01117 template <class T>
01118 inline void CMatrix4<T>::transformBox(core::aabbox3d<f32>& box) const
01119 {
01120 #if defined ( USE_MATRIX_TEST )
01121 if (isIdentity())
01122 return;
01123 #endif
01124
01125 transformVect(box.MinEdge);
01126 transformVect(box.MaxEdge);
01127 box.repair();
01128 }
01129
01131 template <class T>
01132 inline void CMatrix4<T>::transformBoxEx(core::aabbox3d<f32>& box) const
01133 {
01134 #if defined ( USE_MATRIX_TEST )
01135 if (isIdentity())
01136 return;
01137 #endif
01138
01139 const f32 Amin[3] = {box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z};
01140 const f32 Amax[3] = {box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z};
01141
01142 f32 Bmin[3];
01143 f32 Bmax[3];
01144
01145 Bmin[0] = Bmax[0] = M[12];
01146 Bmin[1] = Bmax[1] = M[13];
01147 Bmin[2] = Bmax[2] = M[14];
01148
01149 const CMatrix4<T> &m = *this;
01150
01151 for (u32 i = 0; i < 3; ++i)
01152 {
01153 for (u32 j = 0; j < 3; ++j)
01154 {
01155 const f32 a = m(j,i) * Amin[j];
01156 const f32 b = m(j,i) * Amax[j];
01157
01158 if (a < b)
01159 {
01160 Bmin[i] += a;
01161 Bmax[i] += b;
01162 }
01163 else
01164 {
01165 Bmin[i] += b;
01166 Bmax[i] += a;
01167 }
01168 }
01169 }
01170
01171 box.MinEdge.X = Bmin[0];
01172 box.MinEdge.Y = Bmin[1];
01173 box.MinEdge.Z = Bmin[2];
01174
01175 box.MaxEdge.X = Bmax[0];
01176 box.MaxEdge.Y = Bmax[1];
01177 box.MaxEdge.Z = Bmax[2];
01178 }
01179
01180
01182 template <class T>
01183 inline void CMatrix4<T>::multiplyWith1x4Matrix(T* matrix) const
01184 {
01185
01186
01187
01188
01189
01190
01191
01192 T mat[4];
01193 mat[0] = matrix[0];
01194 mat[1] = matrix[1];
01195 mat[2] = matrix[2];
01196 mat[3] = matrix[3];
01197
01198 matrix[0] = M[0]*mat[0] + M[4]*mat[1] + M[8]*mat[2] + M[12]*mat[3];
01199 matrix[1] = M[1]*mat[0] + M[5]*mat[1] + M[9]*mat[2] + M[13]*mat[3];
01200 matrix[2] = M[2]*mat[0] + M[6]*mat[1] + M[10]*mat[2] + M[14]*mat[3];
01201 matrix[3] = M[3]*mat[0] + M[7]*mat[1] + M[11]*mat[2] + M[15]*mat[3];
01202 }
01203
01204 template <class T>
01205 inline void CMatrix4<T>::inverseTranslateVect( vector3df& vect ) const
01206 {
01207 vect.X = vect.X-M[12];
01208 vect.Y = vect.Y-M[13];
01209 vect.Z = vect.Z-M[14];
01210 }
01211
01212 template <class T>
01213 inline void CMatrix4<T>::translateVect( vector3df& vect ) const
01214 {
01215 vect.X = vect.X+M[12];
01216 vect.Y = vect.Y+M[13];
01217 vect.Z = vect.Z+M[14];
01218 }
01219
01220
01221 template <class T>
01222 inline bool CMatrix4<T>::getInverse(CMatrix4<T>& out) const
01223 {
01227
01228 #if defined ( USE_MATRIX_TEST )
01229 if ( this->isIdentity() )
01230 {
01231 out=*this;
01232 return true;
01233 }
01234 #endif
01235 const CMatrix4<T> &m = *this;
01236
01237 f32 d = (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) -
01238 (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) +
01239 (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1)) +
01240 (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) -
01241 (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) +
01242 (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0));
01243
01244 if( core::iszero ( d ) )
01245 return false;
01246
01247 d = core::reciprocal ( d );
01248
01249 out(0, 0) = d * (m(1, 1) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) +
01250 m(1, 2) * (m(2, 3) * m(3, 1) - m(2, 1) * m(3, 3)) +
01251 m(1, 3) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1)));
01252 out(0, 1) = d * (m(2, 1) * (m(0, 2) * m(3, 3) - m(0, 3) * m(3, 2)) +
01253 m(2, 2) * (m(0, 3) * m(3, 1) - m(0, 1) * m(3, 3)) +
01254 m(2, 3) * (m(0, 1) * m(3, 2) - m(0, 2) * m(3, 1)));
01255 out(0, 2) = d * (m(3, 1) * (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) +
01256 m(3, 2) * (m(0, 3) * m(1, 1) - m(0, 1) * m(1, 3)) +
01257 m(3, 3) * (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)));
01258 out(0, 3) = d * (m(0, 1) * (m(1, 3) * m(2, 2) - m(1, 2) * m(2, 3)) +
01259 m(0, 2) * (m(1, 1) * m(2, 3) - m(1, 3) * m(2, 1)) +
01260 m(0, 3) * (m(1, 2) * m(2, 1) - m(1, 1) * m(2, 2)));
01261 out(1, 0) = d * (m(1, 2) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) +
01262 m(1, 3) * (m(2, 2) * m(3, 0) - m(2, 0) * m(3, 2)) +
01263 m(1, 0) * (m(2, 3) * m(3, 2) - m(2, 2) * m(3, 3)));
01264 out(1, 1) = d * (m(2, 2) * (m(0, 0) * m(3, 3) - m(0, 3) * m(3, 0)) +
01265 m(2, 3) * (m(0, 2) * m(3, 0) - m(0, 0) * m(3, 2)) +
01266 m(2, 0) * (m(0, 3) * m(3, 2) - m(0, 2) * m(3, 3)));
01267 out(1, 2) = d * (m(3, 2) * (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) +
01268 m(3, 3) * (m(0, 2) * m(1, 0) - m(0, 0) * m(1, 2)) +
01269 m(3, 0) * (m(0, 3) * m(1, 2) - m(0, 2) * m(1, 3)));
01270 out(1, 3) = d * (m(0, 2) * (m(1, 3) * m(2, 0) - m(1, 0) * m(2, 3)) +
01271 m(0, 3) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) +
01272 m(0, 0) * (m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2)));
01273 out(2, 0) = d * (m(1, 3) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0)) +
01274 m(1, 0) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) +
01275 m(1, 1) * (m(2, 3) * m(3, 0) - m(2, 0) * m(3, 3)));
01276 out(2, 1) = d * (m(2, 3) * (m(0, 0) * m(3, 1) - m(0, 1) * m(3, 0)) +
01277 m(2, 0) * (m(0, 1) * m(3, 3) - m(0, 3) * m(3, 1)) +
01278 m(2, 1) * (m(0, 3) * m(3, 0) - m(0, 0) * m(3, 3)));
01279 out(2, 2) = d * (m(3, 3) * (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) +
01280 m(3, 0) * (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) +
01281 m(3, 1) * (m(0, 3) * m(1, 0) - m(0, 0) * m(1, 3)));
01282 out(2, 3) = d * (m(0, 3) * (m(1, 1) * m(2, 0) - m(1, 0) * m(2, 1)) +
01283 m(0, 0) * (m(1, 3) * m(2, 1) - m(1, 1) * m(2, 3)) +
01284 m(0, 1) * (m(1, 0) * m(2, 3) - m(1, 3) * m(2, 0)));
01285 out(3, 0) = d * (m(1, 0) * (m(2, 2) * m(3, 1) - m(2, 1) * m(3, 2)) +
01286 m(1, 1) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) +
01287 m(1, 2) * (m(2, 1) * m(3, 0) - m(2, 0) * m(3, 1)));
01288 out(3, 1) = d * (m(2, 0) * (m(0, 2) * m(3, 1) - m(0, 1) * m(3, 2)) +
01289 m(2, 1) * (m(0, 0) * m(3, 2) - m(0, 2) * m(3, 0)) +
01290 m(2, 2) * (m(0, 1) * m(3, 0) - m(0, 0) * m(3, 1)));
01291 out(3, 2) = d * (m(3, 0) * (m(0, 2) * m(1, 1) - m(0, 1) * m(1, 2)) +
01292 m(3, 1) * (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) +
01293 m(3, 2) * (m(0, 1) * m(1, 0) - m(0, 0) * m(1, 1)));
01294 out(3, 3) = d * (m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) +
01295 m(0, 1) * (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2)) +
01296 m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0)));
01297
01298 #if defined ( USE_MATRIX_TEST )
01299 out.definitelyIdentityMatrix = definitelyIdentityMatrix;
01300 #endif
01301 return true;
01302 }
01303
01304
01307 template <class T>
01308 inline bool CMatrix4<T>::getInversePrimitive ( CMatrix4<T>& out ) const
01309 {
01310 out.M[0 ] = M[0];
01311 out.M[1 ] = M[4];
01312 out.M[2 ] = M[8];
01313 out.M[3 ] = 0;
01314
01315 out.M[4 ] = M[1];
01316 out.M[5 ] = M[5];
01317 out.M[6 ] = M[9];
01318 out.M[7 ] = 0;
01319
01320 out.M[8 ] = M[2];
01321 out.M[9 ] = M[6];
01322 out.M[10] = M[10];
01323 out.M[11] = 0;
01324
01325 out.M[12] = (T)-(M[12]*M[0] + M[13]*M[1] + M[14]*M[2]);
01326 out.M[13] = (T)-(M[12]*M[4] + M[13]*M[5] + M[14]*M[6]);
01327 out.M[14] = (T)-(M[12]*M[8] + M[13]*M[9] + M[14]*M[10]);
01328 out.M[15] = 1;
01329
01330 #if defined ( USE_MATRIX_TEST )
01331 out.definitelyIdentityMatrix = definitelyIdentityMatrix;
01332 #endif
01333 return true;
01334 }
01335
01338 template <class T>
01339 inline bool CMatrix4<T>::makeInverse()
01340 {
01341 #if defined ( USE_MATRIX_TEST )
01342 if (definitelyIdentityMatrix)
01343 return true;
01344 #endif
01345 CMatrix4<T> temp ( EM4CONST_NOTHING );
01346
01347 if (getInverse(temp))
01348 {
01349 *this = temp;
01350 return true;
01351 }
01352
01353 return false;
01354 }
01355
01356
01357 template <class T>
01358 inline CMatrix4<T>& CMatrix4<T>::operator=(const CMatrix4<T> &other)
01359 {
01360 if (this==&other)
01361 return *this;
01362 memcpy(M, other.M, 16*sizeof(T));
01363 #if defined ( USE_MATRIX_TEST )
01364 definitelyIdentityMatrix=other.definitelyIdentityMatrix;
01365 #endif
01366 return *this;
01367 }
01368
01369
01370 template <class T>
01371 inline CMatrix4<T>& CMatrix4<T>::operator=(const T& scalar)
01372 {
01373 for (s32 i = 0; i < 16; ++i)
01374 M[i]=scalar;
01375
01376 #if defined ( USE_MATRIX_TEST )
01377 definitelyIdentityMatrix=false;
01378 #endif
01379 return *this;
01380 }
01381
01382
01383 template <class T>
01384 inline bool CMatrix4<T>::operator==(const CMatrix4<T> &other) const
01385 {
01386 #if defined ( USE_MATRIX_TEST )
01387 if (definitelyIdentityMatrix && other.definitelyIdentityMatrix)
01388 return true;
01389 #endif
01390 for (s32 i = 0; i < 16; ++i)
01391 if (M[i] != other.M[i])
01392 return false;
01393
01394 return true;
01395 }
01396
01397
01398 template <class T>
01399 inline bool CMatrix4<T>::operator!=(const CMatrix4<T> &other) const
01400 {
01401 return !(*this == other);
01402 }
01403
01404
01405
01406 template <class T>
01407 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovRH(
01408 f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar)
01409 {
01410 const f64 h = reciprocal(tan(fieldOfViewRadians*0.5));
01411 _IRR_DEBUG_BREAK_IF(aspectRatio==0.f);
01412 const T w = h / aspectRatio;
01413
01414 _IRR_DEBUG_BREAK_IF(zNear==zFar);
01415 M[0] = w;
01416 M[1] = 0;
01417 M[2] = 0;
01418 M[3] = 0;
01419
01420 M[4] = 0;
01421 M[5] = (T)h;
01422 M[6] = 0;
01423 M[7] = 0;
01424
01425 M[8] = 0;
01426 M[9] = 0;
01427 M[10] = (T)(zFar/(zNear-zFar));
01428
01429 M[11] = -1;
01430
01431 M[12] = 0;
01432 M[13] = 0;
01433 M[14] = (T)(zNear*zFar/(zNear-zFar));
01434
01435 M[15] = 0;
01436
01437 #if defined ( USE_MATRIX_TEST )
01438 definitelyIdentityMatrix=false;
01439 #endif
01440 return *this;
01441 }
01442
01443
01444
01445 template <class T>
01446 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovLH(
01447 f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar)
01448 {
01449 const f64 h = reciprocal(tan(fieldOfViewRadians*0.5));
01450 _IRR_DEBUG_BREAK_IF(aspectRatio==0.f);
01451 const T w = (T)(h / aspectRatio);
01452
01453 _IRR_DEBUG_BREAK_IF(zNear==zFar);
01454 M[0] = w;
01455 M[1] = 0;
01456 M[2] = 0;
01457 M[3] = 0;
01458
01459 M[4] = 0;
01460 M[5] = (T)h;
01461 M[6] = 0;
01462 M[7] = 0;
01463
01464 M[8] = 0;
01465 M[9] = 0;
01466 M[10] = (T)(zFar/(zFar-zNear));
01467 M[11] = 1;
01468
01469 M[12] = 0;
01470 M[13] = 0;
01471 M[14] = (T)(-zNear*zFar/(zFar-zNear));
01472 M[15] = 0;
01473
01474 #if defined ( USE_MATRIX_TEST )
01475 definitelyIdentityMatrix=false;
01476 #endif
01477 return *this;
01478 }
01479
01480
01481
01482 template <class T>
01483 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoLH(
01484 f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
01485 {
01486 _IRR_DEBUG_BREAK_IF(widthOfViewVolume==0.f);
01487 _IRR_DEBUG_BREAK_IF(heightOfViewVolume==0.f);
01488 _IRR_DEBUG_BREAK_IF(zNear==zFar);
01489 M[0] = (T)(2/widthOfViewVolume);
01490 M[1] = 0;
01491 M[2] = 0;
01492 M[3] = 0;
01493
01494 M[4] = 0;
01495 M[5] = (T)(2/heightOfViewVolume);
01496 M[6] = 0;
01497 M[7] = 0;
01498
01499 M[8] = 0;
01500 M[9] = 0;
01501 M[10] = (T)(1/(zFar-zNear));
01502 M[11] = 0;
01503
01504 M[12] = 0;
01505 M[13] = 0;
01506 M[14] = (T)(zNear/(zNear-zFar));
01507 M[15] = 1;
01508
01509 #if defined ( USE_MATRIX_TEST )
01510 definitelyIdentityMatrix=false;
01511 #endif
01512 return *this;
01513 }
01514
01515
01516
01517 template <class T>
01518 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoRH(
01519 f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
01520 {
01521 _IRR_DEBUG_BREAK_IF(widthOfViewVolume==0.f);
01522 _IRR_DEBUG_BREAK_IF(heightOfViewVolume==0.f);
01523 _IRR_DEBUG_BREAK_IF(zNear==zFar);
01524 M[0] = (T)(2/widthOfViewVolume);
01525 M[1] = 0;
01526 M[2] = 0;
01527 M[3] = 0;
01528
01529 M[4] = 0;
01530 M[5] = (T)(2/heightOfViewVolume);
01531 M[6] = 0;
01532 M[7] = 0;
01533
01534 M[8] = 0;
01535 M[9] = 0;
01536 M[10] = (T)(1/(zNear-zFar));
01537 M[11] = 0;
01538
01539 M[12] = 0;
01540 M[13] = 0;
01541 M[14] = (T)(zNear/(zNear-zFar));
01542 M[15] = -1;
01543
01544 #if defined ( USE_MATRIX_TEST )
01545 definitelyIdentityMatrix=false;
01546 #endif
01547 return *this;
01548 }
01549
01550
01551
01552 template <class T>
01553 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveRH(
01554 f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
01555 {
01556 _IRR_DEBUG_BREAK_IF(widthOfViewVolume==0.f);
01557 _IRR_DEBUG_BREAK_IF(heightOfViewVolume==0.f);
01558 _IRR_DEBUG_BREAK_IF(zNear==zFar);
01559 M[0] = (T)(2*zNear/widthOfViewVolume);
01560 M[1] = 0;
01561 M[2] = 0;
01562 M[3] = 0;
01563
01564 M[4] = 0;
01565 M[5] = (T)(2*zNear/heightOfViewVolume);
01566 M[6] = 0;
01567 M[7] = 0;
01568
01569 M[8] = 0;
01570 M[9] = 0;
01571 M[10] = (T)(zFar/(zNear-zFar));
01572 M[11] = -1;
01573
01574 M[12] = 0;
01575 M[13] = 0;
01576 M[14] = (T)(zNear*zFar/(zNear-zFar));
01577 M[15] = 0;
01578
01579 #if defined ( USE_MATRIX_TEST )
01580 definitelyIdentityMatrix=false;
01581 #endif
01582 return *this;
01583 }
01584
01585
01586
01587 template <class T>
01588 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveLH(
01589 f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
01590 {
01591 _IRR_DEBUG_BREAK_IF(widthOfViewVolume==0.f);
01592 _IRR_DEBUG_BREAK_IF(heightOfViewVolume==0.f);
01593 _IRR_DEBUG_BREAK_IF(zNear==zFar);
01594 M[0] = (T)(2*zNear/widthOfViewVolume);
01595 M[1] = 0;
01596 M[2] = 0;
01597 M[3] = 0;
01598
01599 M[4] = 0;
01600 M[5] = (T)(2*zNear/heightOfViewVolume);
01601 M[6] = 0;
01602 M[7] = 0;
01603
01604 M[8] = 0;
01605 M[9] = 0;
01606 M[10] = (T)(zFar/(zFar-zNear));
01607 M[11] = 1;
01608
01609 M[12] = 0;
01610 M[13] = 0;
01611 M[14] = (T)(zNear*zFar/(zNear-zFar));
01612 M[15] = 0;
01613 #if defined ( USE_MATRIX_TEST )
01614 definitelyIdentityMatrix=false;
01615 #endif
01616 return *this;
01617 }
01618
01619
01620
01621 template <class T>
01622 inline CMatrix4<T>& CMatrix4<T>::buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point)
01623 {
01624 plane.Normal.normalize();
01625 const f32 d = plane.Normal.dotProduct(light);
01626
01627 M[ 0] = (T)(-plane.Normal.X * light.X + d);
01628 M[ 1] = (T)(-plane.Normal.X * light.Y);
01629 M[ 2] = (T)(-plane.Normal.X * light.Z);
01630 M[ 3] = (T)(-plane.Normal.X * point);
01631
01632 M[ 4] = (T)(-plane.Normal.Y * light.X);
01633 M[ 5] = (T)(-plane.Normal.Y * light.Y + d);
01634 M[ 6] = (T)(-plane.Normal.Y * light.Z);
01635 M[ 7] = (T)(-plane.Normal.Y * point);
01636
01637 M[ 8] = (T)(-plane.Normal.Z * light.X);
01638 M[ 9] = (T)(-plane.Normal.Z * light.Y);
01639 M[10] = (T)(-plane.Normal.Z * light.Z + d);
01640 M[11] = (T)(-plane.Normal.Z * point);
01641
01642 M[12] = (T)(-plane.D * light.X);
01643 M[13] = (T)(-plane.D * light.Y);
01644 M[14] = (T)(-plane.D * light.Z);
01645 M[15] = (T)(-plane.D * point + d);
01646 #if defined ( USE_MATRIX_TEST )
01647 definitelyIdentityMatrix=false;
01648 #endif
01649 return *this;
01650 }
01651
01652
01653 template <class T>
01654 inline CMatrix4<T>& CMatrix4<T>::buildCameraLookAtMatrixLH(
01655 const vector3df& position,
01656 const vector3df& target,
01657 const vector3df& upVector)
01658 {
01659 vector3df zaxis = target - position;
01660 zaxis.normalize();
01661
01662 vector3df xaxis = upVector.crossProduct(zaxis);
01663 xaxis.normalize();
01664
01665 vector3df yaxis = zaxis.crossProduct(xaxis);
01666
01667 M[0] = (T)xaxis.X;
01668 M[1] = (T)yaxis.X;
01669 M[2] = (T)zaxis.X;
01670 M[3] = 0;
01671
01672 M[4] = (T)xaxis.Y;
01673 M[5] = (T)yaxis.Y;
01674 M[6] = (T)zaxis.Y;
01675 M[7] = 0;
01676
01677 M[8] = (T)xaxis.Z;
01678 M[9] = (T)yaxis.Z;
01679 M[10] = (T)zaxis.Z;
01680 M[11] = 0;
01681
01682 M[12] = (T)-xaxis.dotProduct(position);
01683 M[13] = (T)-yaxis.dotProduct(position);
01684 M[14] = (T)-zaxis.dotProduct(position);
01685 M[15] = 1;
01686 #if defined ( USE_MATRIX_TEST )
01687 definitelyIdentityMatrix=false;
01688 #endif
01689 return *this;
01690 }
01691
01692
01693
01694 template <class T>
01695 inline CMatrix4<T>& CMatrix4<T>::buildCameraLookAtMatrixRH(
01696 const vector3df& position,
01697 const vector3df& target,
01698 const vector3df& upVector)
01699 {
01700 vector3df zaxis = position - target;
01701 zaxis.normalize();
01702
01703 vector3df xaxis = upVector.crossProduct(zaxis);
01704 xaxis.normalize();
01705
01706 vector3df yaxis = zaxis.crossProduct(xaxis);
01707
01708 M[0] = (T)xaxis.X;
01709 M[1] = (T)yaxis.X;
01710 M[2] = (T)zaxis.X;
01711 M[3] = 0;
01712
01713 M[4] = (T)xaxis.Y;
01714 M[5] = (T)yaxis.Y;
01715 M[6] = (T)zaxis.Y;
01716 M[7] = 0;
01717
01718 M[8] = (T)xaxis.Z;
01719 M[9] = (T)yaxis.Z;
01720 M[10] = (T)zaxis.Z;
01721 M[11] = 0;
01722
01723 M[12] = (T)-xaxis.dotProduct(position);
01724 M[13] = (T)-yaxis.dotProduct(position);
01725 M[14] = (T)-zaxis.dotProduct(position);
01726 M[15] = 1;
01727 #if defined ( USE_MATRIX_TEST )
01728 definitelyIdentityMatrix=false;
01729 #endif
01730 return *this;
01731 }
01732
01733
01734
01735 template <class T>
01736 inline CMatrix4<T> CMatrix4<T>::interpolate(const core::CMatrix4<T>& b, f32 time) const
01737 {
01738 CMatrix4<T> mat ( EM4CONST_NOTHING );
01739
01740 for (u32 i=0; i < 16; i += 4)
01741 {
01742 mat.M[i+0] = (T)(M[i+0] + ( b.M[i+0] - M[i+0] ) * time);
01743 mat.M[i+1] = (T)(M[i+1] + ( b.M[i+1] - M[i+1] ) * time);
01744 mat.M[i+2] = (T)(M[i+2] + ( b.M[i+2] - M[i+2] ) * time);
01745 mat.M[i+3] = (T)(M[i+3] + ( b.M[i+3] - M[i+3] ) * time);
01746 }
01747 return mat;
01748 }
01749
01750
01751
01752 template <class T>
01753 inline CMatrix4<T> CMatrix4<T>::getTransposed() const
01754 {
01755 CMatrix4<T> t ( EM4CONST_NOTHING );
01756 getTransposed ( t );
01757 return t;
01758 }
01759
01760
01761
01762 template <class T>
01763 inline void CMatrix4<T>::getTransposed( CMatrix4<T>& o ) const
01764 {
01765 o[ 0] = M[ 0];
01766 o[ 1] = M[ 4];
01767 o[ 2] = M[ 8];
01768 o[ 3] = M[12];
01769
01770 o[ 4] = M[ 1];
01771 o[ 5] = M[ 5];
01772 o[ 6] = M[ 9];
01773 o[ 7] = M[13];
01774
01775 o[ 8] = M[ 2];
01776 o[ 9] = M[ 6];
01777 o[10] = M[10];
01778 o[11] = M[14];
01779
01780 o[12] = M[ 3];
01781 o[13] = M[ 7];
01782 o[14] = M[11];
01783 o[15] = M[15];
01784 #if defined ( USE_MATRIX_TEST )
01785 o.definitelyIdentityMatrix=definitelyIdentityMatrix;
01786 #endif
01787 }
01788
01789
01790
01791 template <class T>
01792 inline CMatrix4<T>& CMatrix4<T>::buildNDCToDCMatrix( const core::rect<s32>& viewport, f32 zScale)
01793 {
01794 const f32 scaleX = (viewport.getWidth() - 0.75f ) * 0.5f;
01795 const f32 scaleY = -(viewport.getHeight() - 0.75f ) * 0.5f;
01796
01797 const f32 dx = -0.5f + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) * 0.5f );
01798 const f32 dy = -0.5f + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) * 0.5f );
01799
01800 makeIdentity();
01801 M[12] = (T)dx;
01802 M[13] = (T)dy;
01803 return setScale(core::vector3d<T>((T)scaleX, (T)scaleY, (T)zScale));
01804 }
01805
01807
01812 template <class T>
01813 inline CMatrix4<T>& CMatrix4<T>::buildRotateFromTo(const core::vector3df& from, const core::vector3df& to)
01814 {
01815
01816 core::vector3df f ( from );
01817 core::vector3df t ( to );
01818 f.normalize ();
01819 t.normalize ();
01820
01821
01822 core::vector3df vs ( t.crossProduct ( f ) );
01823
01824
01825 core::vector3df v ( vs );
01826 v.normalize();
01827
01828
01829 T ca = f.dotProduct ( t );
01830
01831 core::vector3df vt ( v * ( (T) 1 - ca ) );
01832
01833 M[0] = vt.X * v.X + ca;
01834 M[5] = vt.Y * v.Y + ca;
01835 M[10] = vt.Z * v.Z + ca;
01836
01837 vt.X *= v.Y;
01838 vt.Z *= v.X;
01839 vt.Y *= v.Z;
01840
01841 M[1] = vt.X - vs.Z;
01842 M[2] = vt.Z + vs.Y;
01843 M[3] = (T) 0;
01844
01845 M[4] = vt.X + vs.Z;
01846 M[6] = vt.Y - vs.X;
01847 M[7] = (T) 0;
01848
01849 M[8] = vt.Z - vs.Y;
01850 M[9] = vt.Y + vs.X;
01851 M[11] = (T) 0;
01852
01853 M[12] = (T) 0;
01854 M[13] = (T) 0;
01855 M[14] = (T) 0;
01856 M[15] = (T) 1;
01857
01858 return *this;
01859 }
01860
01862
01868 template <class T>
01869 inline void CMatrix4<T>::buildAxisAlignedBillboard( const core::vector3df& camPos,
01870 const core::vector3df& center,
01871 const core::vector3df& translation,
01872 const core::vector3df& axis,
01873 const core::vector3df& from
01874 )
01875 {
01876
01877 core::vector3df up = axis;
01878 up.normalize ();
01879
01880 core::vector3df forward = camPos - center;
01881 forward.normalize();
01882
01883 core::vector3df right = up.crossProduct ( forward );
01884 right.normalize ();
01885
01886
01887 core::vector3df look = right.crossProduct ( up );
01888
01889
01890
01891
01892 core::vector3df vs = look.crossProduct ( from );
01893
01894
01895 f32 ca = from.dotProduct ( look );
01896
01897 core::vector3df vt ( up * ( 1.f - ca ) );
01898
01899 M[0] = vt.X * up.X + ca;
01900 M[5] = vt.Y * up.Y + ca;
01901 M[10] = vt.Z * up.Z + ca;
01902
01903 vt.X *= up.Y;
01904 vt.Z *= up.X;
01905 vt.Y *= up.Z;
01906
01907 M[1] = vt.X - vs.Z;
01908 M[2] = vt.Z + vs.Y;
01909 M[3] = (T) 0;
01910
01911 M[4] = vt.X + vs.Z;
01912 M[6] = vt.Y - vs.X;
01913 M[7] = (T) 0;
01914
01915 M[8] = vt.Z - vs.Y;
01916 M[9] = vt.Y + vs.X;
01917 M[11] = (T) 0;
01918
01919 setRotationCenter ( center, translation );
01920
01921 }
01922
01923
01925 template <class T>
01926 inline void CMatrix4<T>::setRotationCenter(const core::vector3df& center, const core::vector3df& translation)
01927 {
01928 M[12] = -M[0]*center.X - M[4]*center.Y - M[8]*center.Z + (center.X - translation.X );
01929 M[13] = -M[1]*center.X - M[5]*center.Y - M[9]*center.Z + (center.Y - translation.Y );
01930 M[14] = -M[2]*center.X - M[6]*center.Y - M[10]*center.Z + (center.Z - translation.Z );
01931 M[15] = (T) 1.0;
01932 #if defined ( USE_MATRIX_TEST )
01933 definitelyIdentityMatrix=false;
01934 #endif
01935 }
01936
01949 template <class T>
01950 inline CMatrix4<T>& CMatrix4<T>::buildTextureTransform( f32 rotateRad,
01951 const core::vector2df &rotatecenter,
01952 const core::vector2df &translate,
01953 const core::vector2df &scale)
01954 {
01955 const f32 c = cosf(rotateRad);
01956 const f32 s = sinf(rotateRad);
01957
01958 M[0] = (T)(c * scale.X);
01959 M[1] = (T)(s * scale.Y);
01960 M[2] = 0;
01961 M[3] = 0;
01962
01963 M[4] = (T)(-s * scale.X);
01964 M[5] = (T)(c * scale.Y);
01965 M[6] = 0;
01966 M[7] = 0;
01967
01968 M[8] = (T)(c * scale.X * rotatecenter.X + -s * rotatecenter.Y + translate.X);
01969 M[9] = (T)(s * scale.Y * rotatecenter.X + c * rotatecenter.Y + translate.Y);
01970 M[10] = 1;
01971 M[11] = 0;
01972
01973 M[12] = 0;
01974 M[13] = 0;
01975 M[14] = 0;
01976 M[15] = 1;
01977 #if defined ( USE_MATRIX_TEST )
01978 definitelyIdentityMatrix=false;
01979 #endif
01980 return *this;
01981 }
01982
01983
01984
01985 template <class T>
01986 inline CMatrix4<T>& CMatrix4<T>::setTextureRotationCenter( f32 rotateRad )
01987 {
01988 const f32 c = cosf(rotateRad);
01989 const f32 s = sinf(rotateRad);
01990 M[0] = (T)c;
01991 M[1] = (T)s;
01992
01993 M[4] = (T)-s;
01994 M[5] = (T)c;
01995
01996 M[8] = (T)(0.5f * ( s - c) + 0.5f);
01997 M[9] = (T)(-0.5f * ( s + c) + 0.5f);
01998
01999 #if defined ( USE_MATRIX_TEST )
02000 definitelyIdentityMatrix = definitelyIdentityMatrix && (rotateRad==0.0f);
02001 #endif
02002 return *this;
02003 }
02004
02005
02006 template <class T>
02007 inline CMatrix4<T>& CMatrix4<T>::setTextureTranslate ( f32 x, f32 y )
02008 {
02009 M[8] = (T)x;
02010 M[9] = (T)y;
02011
02012 #if defined ( USE_MATRIX_TEST )
02013 definitelyIdentityMatrix = definitelyIdentityMatrix && (x==0.0f) && (y==0.0f);
02014 #endif
02015 return *this;
02016 }
02017
02018
02019 template <class T>
02020 inline CMatrix4<T>& CMatrix4<T>::setTextureTranslateTransposed ( f32 x, f32 y )
02021 {
02022 M[2] = (T)x;
02023 M[6] = (T)y;
02024
02025 #if defined ( USE_MATRIX_TEST )
02026 definitelyIdentityMatrix = definitelyIdentityMatrix && (x==0.0f) && (y==0.0f) ;
02027 #endif
02028 return *this;
02029 }
02030
02031 template <class T>
02032 inline CMatrix4<T>& CMatrix4<T>::setTextureScale ( f32 sx, f32 sy )
02033 {
02034 M[0] = (T)sx;
02035 M[5] = (T)sy;
02036 #if defined ( USE_MATRIX_TEST )
02037 definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f);
02038 #endif
02039 return *this;
02040 }
02041
02042
02043 template <class T>
02044 inline CMatrix4<T>& CMatrix4<T>::setTextureScaleCenter( f32 sx, f32 sy )
02045 {
02046 M[0] = (T)sx;
02047 M[5] = (T)sy;
02048 M[8] = (T)(0.5f - 0.5f * sx);
02049 M[9] = (T)(0.5f - 0.5f * sy);
02050
02051 #if defined ( USE_MATRIX_TEST )
02052 definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f);
02053 #endif
02054 return *this;
02055 }
02056
02057
02058
02059 template <class T>
02060 inline CMatrix4<T>& CMatrix4<T>::setM(const T* data)
02061 {
02062 memcpy(M,data, 16*sizeof(T));
02063
02064 #if defined ( USE_MATRIX_TEST )
02065 definitelyIdentityMatrix=false;
02066 #endif
02067 return *this;
02068 }
02069
02070
02071
02072 template <class T>
02073 inline void CMatrix4<T>::setDefinitelyIdentityMatrix( bool isDefinitelyIdentityMatrix)
02074 {
02075 #if defined ( USE_MATRIX_TEST )
02076 definitelyIdentityMatrix = isDefinitelyIdentityMatrix;
02077 #endif
02078 }
02079
02080
02081
02082 template <class T>
02083 inline bool CMatrix4<T>::getDefinitelyIdentityMatrix() const
02084 {
02085 #if defined ( USE_MATRIX_TEST )
02086 return definitelyIdentityMatrix;
02087 #else
02088 return false;
02089 #endif
02090 }
02091
02092
02093
02094 template <class T>
02095 inline CMatrix4<T> operator*(const T scalar, const CMatrix4<T>& mat)
02096 {
02097 return mat*scalar;
02098 }
02099
02100
02102 typedef CMatrix4<f32> matrix4;
02103
02105 IRRLICHT_API extern const matrix4 IdentityMatrix;
02106
02107 }
02108 }
02109
02110 #endif
02111