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 namespace irr
00017 {
00018 namespace core
00019 {
00020
00022
00023 template <class T>
00024 class CMatrix4
00025 {
00026 public:
00027
00029 enum eConstructor
00030 {
00031 EM4CONST_NOTHING = 0,
00032 EM4CONST_COPY,
00033 EM4CONST_IDENTITY,
00034 EM4CONST_TRANSPOSED,
00035 EM4CONST_INVERSE,
00036 EM4CONST_INVERSE_TRANSPOSED
00037 };
00038
00040
00041 CMatrix4( eConstructor constructor = EM4CONST_IDENTITY );
00043
00045 CMatrix4( const CMatrix4<T>& other,eConstructor constructor = EM4CONST_COPY);
00046
00048 T& operator()(const s32 row, const s32 col) { definitelyIdentityMatrix=false; return M[ row * 4 + col ]; }
00049
00051 const T& operator()(const s32 row, const s32 col) const { return M[row * 4 + col]; }
00052
00054 T& operator[](u32 index) { definitelyIdentityMatrix=false; return M[index]; }
00055
00057 const T& operator[](u32 index) const { return M[index]; }
00058
00060 inline CMatrix4<T>& operator=(const CMatrix4<T> &other);
00061
00063 inline CMatrix4<T>& operator=(const T& scalar);
00064
00066 const T* pointer() const { return M; }
00067 T* pointer() { definitelyIdentityMatrix=false; return M; }
00068
00070 bool operator==(const CMatrix4<T> &other) const;
00071
00073 bool operator!=(const CMatrix4<T> &other) const;
00074
00076 CMatrix4<T> operator+(const CMatrix4<T>& other) const;
00077
00079 CMatrix4<T>& operator+=(const CMatrix4<T>& other);
00080
00082 CMatrix4<T> operator-(const CMatrix4<T>& other) const;
00083
00085 CMatrix4<T>& operator-=(const CMatrix4<T>& other);
00086
00088 inline CMatrix4<T>& setbyproduct(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b );
00089
00091
00093 CMatrix4<T>& setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b );
00094
00096 CMatrix4<T> operator*(const CMatrix4<T>& other) const;
00097
00099 CMatrix4<T>& operator*=(const CMatrix4<T>& other);
00100
00102 CMatrix4<T> operator*(const T& scalar) const;
00103
00105 CMatrix4<T>& operator*=(const T& scalar);
00106
00108 inline CMatrix4<T>& makeIdentity();
00109
00111 inline bool isIdentity() const;
00112
00114 bool isIdentity_integer_base () const;
00115
00117 CMatrix4<T>& setTranslation( const vector3d<T>& translation );
00118
00120 vector3d<T> getTranslation() const;
00121
00123 CMatrix4<T>& setInverseTranslation( const vector3d<T>& translation );
00124
00126 inline CMatrix4<T>& setRotationRadians( const vector3d<T>& rotation );
00127
00129 CMatrix4<T>& setRotationDegrees( const vector3d<T>& rotation );
00130
00132
00133 core::vector3d<T> getRotationDegrees() const;
00134
00136
00137 inline CMatrix4<T>& setInverseRotationRadians( const vector3d<T>& rotation );
00138
00140
00141 CMatrix4<T>& setInverseRotationDegrees( const vector3d<T>& rotation );
00142
00144 CMatrix4<T>& setScale( const vector3d<T>& scale );
00145
00147 CMatrix4<T>& setScale( const T scale ) { return setScale(core::vector3d<T>(scale,scale,scale)); }
00148
00150 core::vector3d<T> getScale() const;
00151
00153 void inverseTranslateVect( vector3df& vect ) const;
00154
00156 void inverseRotateVect( vector3df& vect ) const;
00157
00159 void rotateVect( vector3df& vect ) const;
00160
00162 void rotateVect(core::vector3df& out, const core::vector3df& in) const;
00163
00165 void rotateVect(T *out,const core::vector3df &in) const;
00166
00168 void transformVect( vector3df& vect) const;
00169
00171 void transformVect( vector3df& out, const vector3df& in ) const;
00172
00174 void transformVect(T *out,const core::vector3df &in) const;
00175
00177 void translateVect( vector3df& vect ) const;
00178
00180 void transformPlane( core::plane3d<f32> &plane) const;
00181
00183 void transformPlane_new( core::plane3d<f32> &plane) const;
00184
00186 void transformPlane( const core::plane3d<f32> &in, core::plane3d<f32> &out) const;
00187
00189
00191 void transformBox(core::aabbox3d<f32>& box) const;
00192
00194
00196 void transformBoxEx(core::aabbox3d<f32>& box) const;
00197
00199 void multiplyWith1x4Matrix(T* matrix) const;
00200
00202
00203 bool makeInverse();
00204
00205
00207
00208 bool getInversePrimitive ( CMatrix4<T>& out ) const;
00209
00211
00213 bool getInverse(CMatrix4<T>& out) const;
00214
00216 CMatrix4<T>& buildProjectionMatrixPerspectiveFovRH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar);
00217
00219 CMatrix4<T>& buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar);
00220
00222 CMatrix4<T>& buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
00223
00225 CMatrix4<T>& buildProjectionMatrixPerspectiveLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
00226
00228 CMatrix4<T>& buildProjectionMatrixOrthoLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
00229
00231 CMatrix4<T>& buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
00232
00234 CMatrix4<T>& buildCameraLookAtMatrixLH(
00235 const vector3df& position,
00236 const vector3df& target,
00237 const vector3df& upVector);
00238
00240 CMatrix4<T>& buildCameraLookAtMatrixRH(
00241 const vector3df& position,
00242 const vector3df& target,
00243 const vector3df& upVector);
00244
00246
00250 CMatrix4<T>& buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point=1.0f);
00251
00253
00254 CMatrix4<T>& buildNDCToDCMatrix( const core::rect<s32>& area, f32 zScale);
00255
00257
00259 CMatrix4<T> interpolate(const core::CMatrix4<T>& b, f32 time) const;
00260
00262 CMatrix4<T> getTransposed() const;
00263
00265 inline void getTransposed( CMatrix4<T>& dest ) const;
00266
00267
00268
00269
00270
00272 CMatrix4<T>& buildTextureTransform( f32 rotateRad,
00273 const core::vector2df &rotatecenter,
00274 const core::vector2df &translate,
00275 const core::vector2df &scale);
00276
00278
00282 CMatrix4<T>& setTextureRotationCenter( f32 radAngle );
00283
00285
00289 CMatrix4<T>& setTextureTranslate( f32 x, f32 y );
00290
00292
00296 CMatrix4<T>& setTextureScale( f32 sx, f32 sy );
00297
00299
00303 CMatrix4<T>& setTextureScaleCenter( f32 sx, f32 sy );
00304
00306 CMatrix4<T>& setM(const T* data);
00307
00309 void setDefinitelyIdentityMatrix( bool isDefinitelyIdentityMatrix);
00310
00312 bool getDefinitelyIdentityMatrix() const;
00313
00314 private:
00316 T M[16];
00318 mutable bool definitelyIdentityMatrix;
00319 };
00320
00321
00322 template <class T>
00323 inline CMatrix4<T>::CMatrix4( eConstructor constructor ) : definitelyIdentityMatrix(false)
00324 {
00325 switch ( constructor )
00326 {
00327 case EM4CONST_NOTHING:
00328 case EM4CONST_COPY:
00329 break;
00330 case EM4CONST_IDENTITY:
00331 case EM4CONST_INVERSE:
00332 default:
00333 makeIdentity();
00334 break;
00335 }
00336 }
00337
00338
00339 template <class T>
00340 inline CMatrix4<T>::CMatrix4( const CMatrix4<T>& other, eConstructor constructor) : definitelyIdentityMatrix(false)
00341 {
00342 switch ( constructor )
00343 {
00344 case EM4CONST_IDENTITY:
00345 makeIdentity();
00346 break;
00347 case EM4CONST_NOTHING:
00348 break;
00349 case EM4CONST_COPY:
00350 *this = other;
00351 break;
00352 case EM4CONST_TRANSPOSED:
00353 other.getTransposed(*this);
00354 break;
00355 case EM4CONST_INVERSE:
00356 if (!other.getInverse(*this))
00357 memset(M, 0, 16*sizeof(T));
00358 break;
00359 case EM4CONST_INVERSE_TRANSPOSED:
00360 if (!other.getInverse(*this))
00361 memset(M, 0, 16*sizeof(T));
00362 else
00363 *this=getTransposed();
00364 break;
00365 }
00366 }
00367
00369 template <class T>
00370 inline CMatrix4<T> CMatrix4<T>::operator+(const CMatrix4<T>& other) const
00371 {
00372 CMatrix4<T> temp ( EM4CONST_NOTHING );
00373
00374 temp[0] = M[0]+other[0];
00375 temp[1] = M[1]+other[1];
00376 temp[2] = M[2]+other[2];
00377 temp[3] = M[3]+other[3];
00378 temp[4] = M[4]+other[4];
00379 temp[5] = M[5]+other[5];
00380 temp[6] = M[6]+other[6];
00381 temp[7] = M[7]+other[7];
00382 temp[8] = M[8]+other[8];
00383 temp[9] = M[9]+other[9];
00384 temp[10] = M[10]+other[10];
00385 temp[11] = M[11]+other[11];
00386 temp[12] = M[12]+other[12];
00387 temp[13] = M[13]+other[13];
00388 temp[14] = M[14]+other[14];
00389 temp[15] = M[15]+other[15];
00390
00391 return temp;
00392 }
00393
00395 template <class T>
00396 inline CMatrix4<T>& CMatrix4<T>::operator+=(const CMatrix4<T>& other)
00397 {
00398 M[0]+=other[0];
00399 M[1]+=other[1];
00400 M[2]+=other[2];
00401 M[3]+=other[3];
00402 M[4]+=other[4];
00403 M[5]+=other[5];
00404 M[6]+=other[6];
00405 M[7]+=other[7];
00406 M[8]+=other[8];
00407 M[9]+=other[9];
00408 M[10]+=other[10];
00409 M[11]+=other[11];
00410 M[12]+=other[12];
00411 M[13]+=other[13];
00412 M[14]+=other[14];
00413 M[15]+=other[15];
00414
00415 return *this;
00416 }
00417
00419 template <class T>
00420 inline CMatrix4<T> CMatrix4<T>::operator-(const CMatrix4<T>& other) const
00421 {
00422 CMatrix4<T> temp ( EM4CONST_NOTHING );
00423
00424 temp[0] = M[0]-other[0];
00425 temp[1] = M[1]-other[1];
00426 temp[2] = M[2]-other[2];
00427 temp[3] = M[3]-other[3];
00428 temp[4] = M[4]-other[4];
00429 temp[5] = M[5]-other[5];
00430 temp[6] = M[6]-other[6];
00431 temp[7] = M[7]-other[7];
00432 temp[8] = M[8]-other[8];
00433 temp[9] = M[9]-other[9];
00434 temp[10] = M[10]-other[10];
00435 temp[11] = M[11]-other[11];
00436 temp[12] = M[12]-other[12];
00437 temp[13] = M[13]-other[13];
00438 temp[14] = M[14]-other[14];
00439 temp[15] = M[15]-other[15];
00440
00441 return temp;
00442 }
00443
00445 template <class T>
00446 inline CMatrix4<T>& CMatrix4<T>::operator-=(const CMatrix4<T>& other)
00447 {
00448 M[0]-=other[0];
00449 M[1]-=other[1];
00450 M[2]-=other[2];
00451 M[3]-=other[3];
00452 M[4]-=other[4];
00453 M[5]-=other[5];
00454 M[6]-=other[6];
00455 M[7]-=other[7];
00456 M[8]-=other[8];
00457 M[9]-=other[9];
00458 M[10]-=other[10];
00459 M[11]-=other[11];
00460 M[12]-=other[12];
00461 M[13]-=other[13];
00462 M[14]-=other[14];
00463 M[15]-=other[15];
00464
00465 return *this;
00466 }
00467
00469 template <class T>
00470 inline CMatrix4<T> CMatrix4<T>::operator*(const T& scalar) const
00471 {
00472 CMatrix4<T> temp ( EM4CONST_NOTHING );
00473
00474 temp[0] = M[0]*scalar;
00475 temp[1] = M[1]*scalar;
00476 temp[2] = M[2]*scalar;
00477 temp[3] = M[3]*scalar;
00478 temp[4] = M[4]*scalar;
00479 temp[5] = M[5]*scalar;
00480 temp[6] = M[6]*scalar;
00481 temp[7] = M[7]*scalar;
00482 temp[8] = M[8]*scalar;
00483 temp[9] = M[9]*scalar;
00484 temp[10] = M[10]*scalar;
00485 temp[11] = M[11]*scalar;
00486 temp[12] = M[12]*scalar;
00487 temp[13] = M[13]*scalar;
00488 temp[14] = M[14]*scalar;
00489 temp[15] = M[15]*scalar;
00490
00491 return temp;
00492 }
00493
00495 template <class T>
00496 inline CMatrix4<T>& CMatrix4<T>::operator*=(const T& scalar)
00497 {
00498 M[0]*=scalar;
00499 M[1]*=scalar;
00500 M[2]*=scalar;
00501 M[3]*=scalar;
00502 M[4]*=scalar;
00503 M[5]*=scalar;
00504 M[6]*=scalar;
00505 M[7]*=scalar;
00506 M[8]*=scalar;
00507 M[9]*=scalar;
00508 M[10]*=scalar;
00509 M[11]*=scalar;
00510 M[12]*=scalar;
00511 M[13]*=scalar;
00512 M[14]*=scalar;
00513 M[15]*=scalar;
00514
00515 return *this;
00516 }
00517
00519 template <class T>
00520 inline CMatrix4<T>& CMatrix4<T>::operator*=(const CMatrix4<T>& other)
00521 {
00522
00523 if ( !other.isIdentity() )
00524 {
00525 if ( this->isIdentity() )
00526 {
00527 return (*this = other);
00528 }
00529 else
00530 {
00531 CMatrix4<T> temp ( *this );
00532 return setbyproduct_nocheck( temp, other );
00533 }
00534 }
00535 return *this;
00536 }
00537
00539
00540
00541 template <class T>
00542 inline CMatrix4<T>& CMatrix4<T>::setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b )
00543 {
00544 const T *m1 = other_a.M;
00545 const T *m2 = other_b.M;
00546
00547 M[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3];
00548 M[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3];
00549 M[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3];
00550 M[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3];
00551
00552 M[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7];
00553 M[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7];
00554 M[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7];
00555 M[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7];
00556
00557 M[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11];
00558 M[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11];
00559 M[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11];
00560 M[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11];
00561
00562 M[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15];
00563 M[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15];
00564 M[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
00565 M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
00566 definitelyIdentityMatrix=false;
00567 return *this;
00568 }
00569
00570
00572
00573
00574 template <class T>
00575 inline CMatrix4<T>& CMatrix4<T>::setbyproduct(const CMatrix4<T>& other_a, const CMatrix4<T>& other_b )
00576 {
00577 if ( other_a.isIdentity () )
00578 return (*this = other_b);
00579 else
00580 if ( other_b.isIdentity () )
00581 return (*this = other_a);
00582 else
00583 return setbyproduct_nocheck(other_a,other_b);
00584 }
00585
00587 template <class T>
00588 inline CMatrix4<T> CMatrix4<T>::operator*(const CMatrix4<T>& m2) const
00589 {
00590
00591 if ( this->isIdentity() )
00592 return m2;
00593 if ( m2.isIdentity() )
00594 return *this;
00595
00596 CMatrix4<T> m3 ( EM4CONST_NOTHING );
00597
00598 const T *m1 = M;
00599
00600 m3[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3];
00601 m3[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3];
00602 m3[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3];
00603 m3[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3];
00604
00605 m3[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7];
00606 m3[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7];
00607 m3[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7];
00608 m3[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7];
00609
00610 m3[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11];
00611 m3[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11];
00612 m3[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11];
00613 m3[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11];
00614
00615 m3[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15];
00616 m3[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15];
00617 m3[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
00618 m3[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
00619 return m3;
00620 }
00621
00622
00623
00624 template <class T>
00625 inline vector3d<T> CMatrix4<T>::getTranslation() const
00626 {
00627 return vector3d<T>(M[12], M[13], M[14]);
00628 }
00629
00630
00631 template <class T>
00632 inline CMatrix4<T>& CMatrix4<T>::setTranslation( const vector3d<T>& translation )
00633 {
00634 M[12] = translation.X;
00635 M[13] = translation.Y;
00636 M[14] = translation.Z;
00637 definitelyIdentityMatrix=false;
00638 return *this;
00639 }
00640
00641 template <class T>
00642 inline CMatrix4<T>& CMatrix4<T>::setInverseTranslation( const vector3d<T>& translation )
00643 {
00644 M[12] = -translation.X;
00645 M[13] = -translation.Y;
00646 M[14] = -translation.Z;
00647 definitelyIdentityMatrix=false;
00648 return *this;
00649 }
00650
00651 template <class T>
00652 inline CMatrix4<T>& CMatrix4<T>::setScale( const vector3d<T>& scale )
00653 {
00654 M[0] = scale.X;
00655 M[5] = scale.Y;
00656 M[10] = scale.Z;
00657 definitelyIdentityMatrix=false;
00658 return *this;
00659 }
00660
00661 template <class T>
00662 inline vector3d<T> CMatrix4<T>::getScale() const
00663 {
00664 return vector3d<T>(M[0],M[5],M[10]);
00665 }
00666
00667 template <class T>
00668 inline CMatrix4<T>& CMatrix4<T>::setRotationDegrees( const vector3d<T>& rotation )
00669 {
00670 return setRotationRadians( rotation * core::DEGTORAD );
00671 }
00672
00673 template <class T>
00674 inline CMatrix4<T>& CMatrix4<T>::setInverseRotationDegrees( const vector3d<T>& rotation )
00675 {
00676 return setInverseRotationRadians( rotation * core::DEGTORAD );
00677 }
00678
00679 template <class T>
00680 inline CMatrix4<T>& CMatrix4<T>::setRotationRadians( const vector3d<T>& rotation )
00681 {
00682 const f64 cr = cos( rotation.X );
00683 const f64 sr = sin( rotation.X );
00684 const f64 cp = cos( rotation.Y );
00685 const f64 sp = sin( rotation.Y );
00686 const f64 cy = cos( rotation.Z );
00687 const f64 sy = sin( rotation.Z );
00688
00689 M[0] = (T)( cp*cy );
00690 M[1] = (T)( cp*sy );
00691 M[2] = (T)( -sp );
00692
00693 const f64 srsp = sr*sp;
00694 const f64 crsp = cr*sp;
00695
00696 M[4] = (T)( srsp*cy-cr*sy );
00697 M[5] = (T)( srsp*sy+cr*cy );
00698 M[6] = (T)( sr*cp );
00699
00700 M[8] = (T)( crsp*cy+sr*sy );
00701 M[9] = (T)( crsp*sy-sr*cy );
00702 M[10] = (T)( cr*cp );
00703 definitelyIdentityMatrix=false;
00704 return *this;
00705 }
00706
00707
00710 template <class T>
00711 inline core::vector3d<T> CMatrix4<T>::getRotationDegrees() const
00712 {
00713 const CMatrix4<T> &mat = *this;
00714
00715 f64 Y = -asin(mat(0,2));
00716 const f64 C = cos(Y);
00717 Y *= RADTODEG64;
00718
00719 f64 rotx, roty, X, Z;
00720
00721 if (fabs(C)>ROUNDING_ERROR_64)
00722 {
00723 const T invC = (T)(1.0/C);
00724 rotx = mat(2,2) * invC;
00725 roty = mat(1,2) * invC;
00726 X = atan2( roty, rotx ) * RADTODEG64;
00727 rotx = mat(0,0) * invC;
00728 roty = mat(0,1) * invC;
00729 Z = atan2( roty, rotx ) * RADTODEG64;
00730 }
00731 else
00732 {
00733 X = 0.0;
00734 rotx = mat(1,1);
00735 roty = -mat(1,0);
00736 Z = atan2( roty, rotx ) * RADTODEG64;
00737 }
00738
00739
00740
00741
00742 if (X < 0.0) X += 360.0;
00743 if (Y < 0.0) Y += 360.0;
00744 if (Z < 0.0) Z += 360.0;
00745
00746 return vector3d<T>((T)X,(T)Y,(T)Z);
00747 }
00748
00749
00750 template <class T>
00751 inline CMatrix4<T>& CMatrix4<T>::setInverseRotationRadians( const vector3d<T>& rotation )
00752 {
00753 f64 cr = cos( rotation.X );
00754 f64 sr = sin( rotation.X );
00755 f64 cp = cos( rotation.Y );
00756 f64 sp = sin( rotation.Y );
00757 f64 cy = cos( rotation.Z );
00758 f64 sy = sin( rotation.Z );
00759
00760 M[0] = (T)( cp*cy );
00761 M[4] = (T)( cp*sy );
00762 M[8] = (T)( -sp );
00763
00764 f64 srsp = sr*sp;
00765 f64 crsp = cr*sp;
00766
00767 M[1] = (T)( srsp*cy-cr*sy );
00768 M[5] = (T)( srsp*sy+cr*cy );
00769 M[9] = (T)( sr*cp );
00770
00771 M[2] = (T)( crsp*cy+sr*sy );
00772 M[6] = (T)( crsp*sy-sr*cy );
00773 M[10] = (T)( cr*cp );
00774 definitelyIdentityMatrix=false;
00775 return *this;
00776 }
00777
00778
00781 template <class T>
00782 inline CMatrix4<T>& CMatrix4<T>::makeIdentity()
00783 {
00784 memset(M, 0, 16*sizeof(T));
00785 M[0] = M[5] = M[10] = M[15] = (T)1;
00786 definitelyIdentityMatrix=true;
00787 return *this;
00788 }
00789
00790
00791
00792
00793
00794
00795 template <class T>
00796 inline bool CMatrix4<T>::isIdentity() const
00797 {
00798 if (definitelyIdentityMatrix)
00799 return true;
00800 if (!equals( M[ 0], (T)1 ) ||
00801 !equals( M[ 5], (T)1 ) ||
00802 !equals( M[10], (T)1 ) ||
00803 !equals( M[15], (T)1 ))
00804 return false;
00805
00806 for (s32 i=0; i<4; ++i)
00807 for (s32 j=0; j<4; ++j)
00808 if ((j != i) && (!iszero((*this)(i,j))))
00809 return false;
00810
00811 definitelyIdentityMatrix=true;
00812 return true;
00813 }
00814
00815
00816
00817
00818
00819
00820
00821 template <class T>
00822 inline bool CMatrix4<T>::isIdentity_integer_base() const
00823 {
00824 if (definitelyIdentityMatrix)
00825 return true;
00826 if(IR(M[0])!=F32_VALUE_1) return false;
00827 if(IR(M[1])!=0) return false;
00828 if(IR(M[2])!=0) return false;
00829 if(IR(M[3])!=0) return false;
00830
00831 if(IR(M[4])!=0) return false;
00832 if(IR(M[5])!=F32_VALUE_1) return false;
00833 if(IR(M[6])!=0) return false;
00834 if(IR(M[7])!=0) return false;
00835
00836 if(IR(M[8])!=0) return false;
00837 if(IR(M[9])!=0) return false;
00838 if(IR(M[10])!=F32_VALUE_1) return false;
00839 if(IR(M[11])!=0) return false;
00840
00841 if(IR(M[12])!=0) return false;
00842 if(IR(M[13])!=0) return false;
00843 if(IR(M[13])!=0) return false;
00844 if(IR(M[15])!=F32_VALUE_1) return false;
00845 definitelyIdentityMatrix=true;
00846 return true;
00847 }
00848
00849
00850 template <class T>
00851 inline void CMatrix4<T>::rotateVect( vector3df& vect ) const
00852 {
00853 vector3df tmp = vect;
00854 vect.X = tmp.X*M[0] + tmp.Y*M[4] + tmp.Z*M[8];
00855 vect.Y = tmp.X*M[1] + tmp.Y*M[5] + tmp.Z*M[9];
00856 vect.Z = tmp.X*M[2] + tmp.Y*M[6] + tmp.Z*M[10];
00857 }
00858
00860 template <class T>
00861 inline void CMatrix4<T>::rotateVect(core::vector3df& out, const core::vector3df& in) const
00862 {
00863 out.X = in.X*M[0] + in.Y*M[4] + in.Z*M[8];
00864 out.Y = in.X*M[1] + in.Y*M[5] + in.Z*M[9];
00865 out.Z = in.X*M[2] + in.Y*M[6] + in.Z*M[10];
00866 }
00867
00869 template <class T>
00870 inline void CMatrix4<T>::rotateVect(T *out, const core::vector3df& in) const
00871 {
00872 out[0] = in.X*M[0] + in.Y*M[4] + in.Z*M[8];
00873 out[1] = in.X*M[1] + in.Y*M[5] + in.Z*M[9];
00874 out[2] = in.X*M[2] + in.Y*M[6] + in.Z*M[10];
00875 }
00876
00877 template <class T>
00878 inline void CMatrix4<T>::inverseRotateVect( vector3df& vect ) const
00879 {
00880 vector3df tmp = vect;
00881 vect.X = tmp.X*M[0] + tmp.Y*M[1] + tmp.Z*M[2];
00882 vect.Y = tmp.X*M[4] + tmp.Y*M[5] + tmp.Z*M[6];
00883 vect.Z = tmp.X*M[8] + tmp.Y*M[9] + tmp.Z*M[10];
00884 }
00885
00886 template <class T>
00887 inline void CMatrix4<T>::transformVect( vector3df& vect) const
00888 {
00889 f32 vector[3];
00890
00891 vector[0] = vect.X*M[0] + vect.Y*M[4] + vect.Z*M[8] + M[12];
00892 vector[1] = vect.X*M[1] + vect.Y*M[5] + vect.Z*M[9] + M[13];
00893 vector[2] = vect.X*M[2] + vect.Y*M[6] + vect.Z*M[10] + M[14];
00894
00895 vect.X = vector[0];
00896 vect.Y = vector[1];
00897 vect.Z = vector[2];
00898 }
00899
00900 template <class T>
00901 inline void CMatrix4<T>::transformVect( vector3df& out, const vector3df& in) const
00902 {
00903 out.X = in.X*M[0] + in.Y*M[4] + in.Z*M[8] + M[12];
00904 out.Y = in.X*M[1] + in.Y*M[5] + in.Z*M[9] + M[13];
00905 out.Z = in.X*M[2] + in.Y*M[6] + in.Z*M[10] + M[14];
00906 }
00907
00908
00909 template <class T>
00910 inline void CMatrix4<T>::transformVect(T *out, const core::vector3df &in) const
00911 {
00912 out[0] = in.X*M[0] + in.Y*M[4] + in.Z*M[8] + M[12];
00913 out[1] = in.X*M[1] + in.Y*M[5] + in.Z*M[9] + M[13];
00914 out[2] = in.X*M[2] + in.Y*M[6] + in.Z*M[10] + M[14];
00915 out[3] = in.X*M[3] + in.Y*M[7] + in.Z*M[11] + M[15];
00916 }
00917
00918
00920 template <class T>
00921 inline void CMatrix4<T>::transformPlane( core::plane3d<f32> &plane) const
00922 {
00923 vector3df member;
00924 transformVect(member, plane.getMemberPoint());
00925
00926 vector3df origin(0,0,0);
00927 transformVect(plane.Normal);
00928 transformVect(origin);
00929
00930 plane.Normal -= origin;
00931 plane.D = - member.dotProduct(plane.Normal);
00932 }
00933
00935 template <class T>
00936 inline void CMatrix4<T>::transformPlane_new( core::plane3d<f32> &plane) const
00937 {
00938
00939 vector3df n;
00940 n.X = plane.Normal.X*M[0] + plane.Normal.Y*M[4] + plane.Normal.Z*M[8];
00941 n.Y = plane.Normal.X*M[1] + plane.Normal.Y*M[5] + plane.Normal.Z*M[9];
00942 n.Z = plane.Normal.X*M[2] + plane.Normal.Y*M[6] + plane.Normal.Z*M[10];
00943
00944
00945 plane.D -= M[12] * n.X + M[13] * n.Y + M[14] * n.Z;
00946 plane.Normal.X = n.X;
00947 plane.Normal.Y = n.Y;
00948 plane.Normal.Z = n.Z;
00949 }
00950
00952 template <class T>
00953 inline void CMatrix4<T>::transformPlane( const core::plane3d<f32> &in, core::plane3d<f32> &out) const
00954 {
00955 out = in;
00956 transformPlane( out );
00957 }
00958
00960 template <class T>
00961 inline void CMatrix4<T>::transformBox(core::aabbox3d<f32>& box) const
00962 {
00963 if (isIdentity())
00964 return;
00965
00966 transformVect(box.MinEdge);
00967 transformVect(box.MaxEdge);
00968 box.repair();
00969 }
00970
00972 template <class T>
00973 inline void CMatrix4<T>::transformBoxEx(core::aabbox3d<f32>& box) const
00974 {
00975 const f32 Amin[3] = {box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z};
00976 const f32 Amax[3] = {box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z};
00977
00978 f32 Bmin[3];
00979 f32 Bmax[3];
00980
00981 Bmin[0] = Bmax[0] = M[12];
00982 Bmin[1] = Bmax[1] = M[13];
00983 Bmin[2] = Bmax[2] = M[14];
00984
00985 const CMatrix4<T> &m = *this;
00986
00987 for (u32 i = 0; i < 3; ++i)
00988 {
00989 for (u32 j = 0; j < 3; ++j)
00990 {
00991 const f32 a = m(j,i) * Amin[j];
00992 const f32 b = m(j,i) * Amax[j];
00993
00994 if (a < b)
00995 {
00996 Bmin[i] += a;
00997 Bmax[i] += b;
00998 }
00999 else
01000 {
01001 Bmin[i] += b;
01002 Bmax[i] += a;
01003 }
01004 }
01005 }
01006
01007 box.MinEdge.X = Bmin[0];
01008 box.MinEdge.Y = Bmin[1];
01009 box.MinEdge.Z = Bmin[2];
01010
01011 box.MaxEdge.X = Bmax[0];
01012 box.MaxEdge.Y = Bmax[1];
01013 box.MaxEdge.Z = Bmax[2];
01014 }
01015
01016
01018 template <class T>
01019 inline void CMatrix4<T>::multiplyWith1x4Matrix(T* matrix) const
01020 {
01021
01022
01023
01024
01025
01026
01027
01028 T mat[4];
01029 mat[0] = matrix[0];
01030 mat[1] = matrix[1];
01031 mat[2] = matrix[2];
01032 mat[3] = matrix[3];
01033
01034 matrix[0] = M[0]*mat[0] + M[4]*mat[1] + M[8]*mat[2] + M[12]*mat[3];
01035 matrix[1] = M[1]*mat[0] + M[5]*mat[1] + M[9]*mat[2] + M[13]*mat[3];
01036 matrix[2] = M[2]*mat[0] + M[6]*mat[1] + M[10]*mat[2] + M[14]*mat[3];
01037 matrix[3] = M[3]*mat[0] + M[7]*mat[1] + M[11]*mat[2] + M[15]*mat[3];
01038 }
01039
01040 template <class T>
01041 inline void CMatrix4<T>::inverseTranslateVect( vector3df& vect ) const
01042 {
01043 vect.X = vect.X-M[12];
01044 vect.Y = vect.Y-M[13];
01045 vect.Z = vect.Z-M[14];
01046 }
01047
01048 template <class T>
01049 inline void CMatrix4<T>::translateVect( vector3df& vect ) const
01050 {
01051 vect.X = vect.X+M[12];
01052 vect.Y = vect.Y+M[13];
01053 vect.Z = vect.Z+M[14];
01054 }
01055
01056
01057 template <class T>
01058 inline bool CMatrix4<T>::getInverse(CMatrix4<T>& out) const
01059 {
01063
01064 if ( this->isIdentity() )
01065 {
01066 out=*this;
01067 return true;
01068 }
01069
01070 const CMatrix4<T> &m = *this;
01071
01072 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)) -
01073 (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) +
01074 (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1)) +
01075 (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) -
01076 (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) +
01077 (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0));
01078
01079 if( core::iszero ( d ) )
01080 return false;
01081
01082 d = core::reciprocal ( d );
01083
01084 out(0, 0) = d * (m(1, 1) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) +
01085 m(1, 2) * (m(2, 3) * m(3, 1) - m(2, 1) * m(3, 3)) +
01086 m(1, 3) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1)));
01087 out(0, 1) = d * (m(2, 1) * (m(0, 2) * m(3, 3) - m(0, 3) * m(3, 2)) +
01088 m(2, 2) * (m(0, 3) * m(3, 1) - m(0, 1) * m(3, 3)) +
01089 m(2, 3) * (m(0, 1) * m(3, 2) - m(0, 2) * m(3, 1)));
01090 out(0, 2) = d * (m(3, 1) * (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) +
01091 m(3, 2) * (m(0, 3) * m(1, 1) - m(0, 1) * m(1, 3)) +
01092 m(3, 3) * (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)));
01093 out(0, 3) = d * (m(0, 1) * (m(1, 3) * m(2, 2) - m(1, 2) * m(2, 3)) +
01094 m(0, 2) * (m(1, 1) * m(2, 3) - m(1, 3) * m(2, 1)) +
01095 m(0, 3) * (m(1, 2) * m(2, 1) - m(1, 1) * m(2, 2)));
01096 out(1, 0) = d * (m(1, 2) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) +
01097 m(1, 3) * (m(2, 2) * m(3, 0) - m(2, 0) * m(3, 2)) +
01098 m(1, 0) * (m(2, 3) * m(3, 2) - m(2, 2) * m(3, 3)));
01099 out(1, 1) = d * (m(2, 2) * (m(0, 0) * m(3, 3) - m(0, 3) * m(3, 0)) +
01100 m(2, 3) * (m(0, 2) * m(3, 0) - m(0, 0) * m(3, 2)) +
01101 m(2, 0) * (m(0, 3) * m(3, 2) - m(0, 2) * m(3, 3)));
01102 out(1, 2) = d * (m(3, 2) * (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) +
01103 m(3, 3) * (m(0, 2) * m(1, 0) - m(0, 0) * m(1, 2)) +
01104 m(3, 0) * (m(0, 3) * m(1, 2) - m(0, 2) * m(1, 3)));
01105 out(1, 3) = d * (m(0, 2) * (m(1, 3) * m(2, 0) - m(1, 0) * m(2, 3)) +
01106 m(0, 3) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) +
01107 m(0, 0) * (m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2)));
01108 out(2, 0) = d * (m(1, 3) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0)) +
01109 m(1, 0) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) +
01110 m(1, 1) * (m(2, 3) * m(3, 0) - m(2, 0) * m(3, 3)));
01111 out(2, 1) = d * (m(2, 3) * (m(0, 0) * m(3, 1) - m(0, 1) * m(3, 0)) +
01112 m(2, 0) * (m(0, 1) * m(3, 3) - m(0, 3) * m(3, 1)) +
01113 m(2, 1) * (m(0, 3) * m(3, 0) - m(0, 0) * m(3, 3)));
01114 out(2, 2) = d * (m(3, 3) * (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) +
01115 m(3, 0) * (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) +
01116 m(3, 1) * (m(0, 3) * m(1, 0) - m(0, 0) * m(1, 3)));
01117 out(2, 3) = d * (m(0, 3) * (m(1, 1) * m(2, 0) - m(1, 0) * m(2, 1)) +
01118 m(0, 0) * (m(1, 3) * m(2, 1) - m(1, 1) * m(2, 3)) +
01119 m(0, 1) * (m(1, 0) * m(2, 3) - m(1, 3) * m(2, 0)));
01120 out(3, 0) = d * (m(1, 0) * (m(2, 2) * m(3, 1) - m(2, 1) * m(3, 2)) +
01121 m(1, 1) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) +
01122 m(1, 2) * (m(2, 1) * m(3, 0) - m(2, 0) * m(3, 1)));
01123 out(3, 1) = d * (m(2, 0) * (m(0, 2) * m(3, 1) - m(0, 1) * m(3, 2)) +
01124 m(2, 1) * (m(0, 0) * m(3, 2) - m(0, 2) * m(3, 0)) +
01125 m(2, 2) * (m(0, 1) * m(3, 0) - m(0, 0) * m(3, 1)));
01126 out(3, 2) = d * (m(3, 0) * (m(0, 2) * m(1, 1) - m(0, 1) * m(1, 2)) +
01127 m(3, 1) * (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) +
01128 m(3, 2) * (m(0, 1) * m(1, 0) - m(0, 0) * m(1, 1)));
01129 out(3, 3) = d * (m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) +
01130 m(0, 1) * (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2)) +
01131 m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0)));
01132 out.definitelyIdentityMatrix = definitelyIdentityMatrix;
01133 return true;
01134 }
01135
01136
01139 template <class T>
01140 inline bool CMatrix4<T>::getInversePrimitive ( CMatrix4<T>& out ) const
01141 {
01142 out.M[0 ] = M[0];
01143 out.M[1 ] = M[4];
01144 out.M[2 ] = M[8];
01145 out.M[3 ] = 0;
01146
01147 out.M[4 ] = M[1];
01148 out.M[5 ] = M[5];
01149 out.M[6 ] = M[9];
01150 out.M[7 ] = 0;
01151
01152 out.M[8 ] = M[2];
01153 out.M[9 ] = M[6];
01154 out.M[10] = M[10];
01155 out.M[11] = 0;
01156
01157 out.M[12] = (T)-(M[12]*M[0] + M[13]*M[1] + M[14]*M[2]);
01158 out.M[13] = (T)-(M[12]*M[4] + M[13]*M[5] + M[14]*M[6]);
01159 out.M[14] = (T)-(M[12]*M[8] + M[13]*M[9] + M[14]*M[10]);
01160 out.M[15] = 1;
01161 out.definitelyIdentityMatrix = definitelyIdentityMatrix;
01162 return true;
01163 }
01164
01167 template <class T>
01168 inline bool CMatrix4<T>::makeInverse()
01169 {
01170 if (definitelyIdentityMatrix)
01171 return true;
01172
01173 CMatrix4<T> temp ( EM4CONST_NOTHING );
01174
01175 if (getInverse(temp))
01176 {
01177 *this = temp;
01178 return true;
01179 }
01180
01181 return false;
01182 }
01183
01184
01185 template <class T>
01186 inline CMatrix4<T>& CMatrix4<T>::operator=(const CMatrix4<T> &other)
01187 {
01188 if (this==&other)
01189 return *this;
01190 memcpy(M, other.M, 16*sizeof(T));
01191 definitelyIdentityMatrix=other.definitelyIdentityMatrix;
01192 return *this;
01193 }
01194
01195
01196 template <class T>
01197 inline CMatrix4<T>& CMatrix4<T>::operator=(const T& scalar)
01198 {
01199 for (s32 i = 0; i < 16; ++i)
01200 M[i]=scalar;
01201 definitelyIdentityMatrix=false;
01202 return *this;
01203 }
01204
01205
01206 template <class T>
01207 inline bool CMatrix4<T>::operator==(const CMatrix4<T> &other) const
01208 {
01209 if (definitelyIdentityMatrix && other.definitelyIdentityMatrix)
01210 return true;
01211 for (s32 i = 0; i < 16; ++i)
01212 if (M[i] != other.M[i])
01213 return false;
01214
01215 return true;
01216 }
01217
01218
01219 template <class T>
01220 inline bool CMatrix4<T>::operator!=(const CMatrix4<T> &other) const
01221 {
01222 return !(*this == other);
01223 }
01224
01225
01226
01227 template <class T>
01228 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovRH(
01229 f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar)
01230 {
01231 const f64 h = 1.0/tan(fieldOfViewRadians/2.0);
01232 const T w = h / aspectRatio;
01233
01234 M[0] = w;
01235 M[1] = 0;
01236 M[2] = 0;
01237 M[3] = 0;
01238
01239 M[4] = 0;
01240 M[5] = (T)h;
01241 M[6] = 0;
01242 M[7] = 0;
01243
01244 M[8] = 0;
01245 M[9] = 0;
01246 M[10] = (T)(zFar/(zNear-zFar));
01247
01248 M[11] = -1;
01249
01250 M[12] = 0;
01251 M[13] = 0;
01252 M[14] = (T)(zNear*zFar/(zNear-zFar));
01253
01254 M[15] = 0;
01255 definitelyIdentityMatrix=false;
01256 return *this;
01257 }
01258
01259
01260
01261 template <class T>
01262 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovLH(
01263 f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar)
01264 {
01265 const f64 h = 1.0/tan(fieldOfViewRadians/2.0);
01266 const T w = (T)(h / aspectRatio);
01267
01268 M[0] = w;
01269 M[1] = 0;
01270 M[2] = 0;
01271 M[3] = 0;
01272
01273 M[4] = 0;
01274 M[5] = (T)h;
01275 M[6] = 0;
01276 M[7] = 0;
01277
01278 M[8] = 0;
01279 M[9] = 0;
01280 M[10] = (T)(zFar/(zFar-zNear));
01281 M[11] = 1;
01282
01283 M[12] = 0;
01284 M[13] = 0;
01285 M[14] = (T)(-zNear*zFar/(zFar-zNear));
01286 M[15] = 0;
01287 definitelyIdentityMatrix=false;
01288 return *this;
01289 }
01290
01291
01292
01293 template <class T>
01294 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoLH(
01295 f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
01296 {
01297 M[0] = (T)(2/widthOfViewVolume);
01298 M[1] = 0;
01299 M[2] = 0;
01300 M[3] = 0;
01301
01302 M[4] = 0;
01303 M[5] = (T)(2/heightOfViewVolume);
01304 M[6] = 0;
01305 M[7] = 0;
01306
01307 M[8] = 0;
01308 M[9] = 0;
01309 M[10] = (T)(1/(zFar-zNear));
01310 M[11] = 0;
01311
01312 M[12] = 0;
01313 M[13] = 0;
01314 M[14] = (T)(zNear/(zNear-zFar));
01315 M[15] = 1;
01316 definitelyIdentityMatrix=false;
01317 return *this;
01318 }
01319
01320
01321
01322 template <class T>
01323 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoRH(
01324 f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
01325 {
01326 M[0] = (T)(2/widthOfViewVolume);
01327 M[1] = 0;
01328 M[2] = 0;
01329 M[3] = 0;
01330
01331 M[4] = 0;
01332 M[5] = (T)(2/heightOfViewVolume);
01333 M[6] = 0;
01334 M[7] = 0;
01335
01336 M[8] = 0;
01337 M[9] = 0;
01338 M[10] = (T)(1/(zNear-zFar));
01339 M[11] = 0;
01340
01341 M[12] = 0;
01342 M[13] = 0;
01343 M[14] = (T)(zNear/(zNear-zFar));
01344 M[15] = -1;
01345 definitelyIdentityMatrix=false;
01346 return *this;
01347 }
01348
01349
01350
01351 template <class T>
01352 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveRH(
01353 f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
01354 {
01355 M[0] = (T)(2*zNear/widthOfViewVolume);
01356 M[1] = 0;
01357 M[2] = 0;
01358 M[3] = 0;
01359
01360 M[4] = 0;
01361 M[5] = (T)(2*zNear/heightOfViewVolume);
01362 M[6] = 0;
01363 M[7] = 0;
01364
01365 M[8] = 0;
01366 M[9] = 0;
01367 M[10] = (T)(zFar/(zNear-zFar));
01368 M[11] = -1;
01369
01370 M[12] = 0;
01371 M[13] = 0;
01372 M[14] = (T)(zNear*zFar/(zNear-zFar));
01373 M[15] = 0;
01374 definitelyIdentityMatrix=false;
01375 return *this;
01376 }
01377
01378
01379
01380 template <class T>
01381 inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveLH(
01382 f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
01383 {
01384 M[0] = (T)(2*zNear/widthOfViewVolume);
01385 M[1] = 0;
01386 M[2] = 0;
01387 M[3] = 0;
01388
01389 M[4] = 0;
01390 M[5] = (T)(2*zNear/heightOfViewVolume);
01391 M[6] = 0;
01392 M[7] = 0;
01393
01394 M[8] = 0;
01395 M[9] = 0;
01396 M[10] = (T)(zFar/(zFar-zNear));
01397 M[11] = 1;
01398
01399 M[12] = 0;
01400 M[13] = 0;
01401 M[14] = (T)(zNear*zFar/(zNear-zFar));
01402 M[15] = 0;
01403 definitelyIdentityMatrix=false;
01404 return *this;
01405 }
01406
01407
01408
01409 template <class T>
01410 inline CMatrix4<T>& CMatrix4<T>::buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point)
01411 {
01412 plane.Normal.normalize();
01413 const f32 d = plane.Normal.dotProduct(light);
01414
01415 M[ 0] = (T)(-plane.Normal.X * light.X + d);
01416 M[ 1] = (T)(-plane.Normal.X * light.Y);
01417 M[ 2] = (T)(-plane.Normal.X * light.