"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSMathLib/Src/Matrix/LSMMatrix4x4Base.h

00001 
00016 #ifndef __LSM_MATRIX4X4BASE_H__
00017 #define __LSM_MATRIX4X4BASE_H__
00018 
00019 #include "../LSMMathLib.h"
00020 #include "../Vector/LSMVector3Base.h"
00021 #include "../Vector/LSMVector4Base.h"
00022 
00023 namespace lsm {
00024 
00031         template <typename _tType, typename _tVector3Type, typename _tVector4Type>
00032         class CMatrix4x4Base {
00033                 // All is public.  This class has no secrets.
00034         public :
00035                 // == Various constructors.
00036                 LSE_CALLCTOR                                                                    CMatrix4x4Base() {
00037                 }
00038                 LSE_CALLCTOR                                                                    CMatrix4x4Base( const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> &_m44bOther ) :
00039                         _11( _m44bOther._11 ), _12( _m44bOther._12 ), _13( _m44bOther._13 ), _14( _m44bOther._14 ),
00040                         _21( _m44bOther._21 ), _22( _m44bOther._22 ), _23( _m44bOther._23 ), _24( _m44bOther._24 ),
00041                         _31( _m44bOther._31 ), _32( _m44bOther._32 ), _33( _m44bOther._33 ), _34( _m44bOther._34 ),
00042                         _41( _m44bOther._41 ), _42( _m44bOther._42 ), _43( _m44bOther._43 ), _44( _m44bOther._44 ) {
00043                 }
00044                 LSE_CALLCTOR                                                                    CMatrix4x4Base( _tType _t11, _tType _t12, _tType _t13, _tType _t14,
00045                         _tType _t21, _tType _t22, _tType _t23, _tType _t24,
00046                         _tType _t31, _tType _t32, _tType _t33, _tType _t34,
00047                         _tType _t41, _tType _t42, _tType _t43, _tType _t44 ) :
00048                         _11( _t11 ), _12( _t12 ), _13( _t13 ), _14( _t14 ),
00049                         _21( _t21 ), _22( _t22 ), _23( _t23 ), _24( _t24 ),
00050                         _31( _t31 ), _32( _t32 ), _33( _t33 ), _34( _t34 ),
00051                         _41( _t41 ), _42( _t42 ), _43( _t43 ), _44( _t44 ) {
00052                 }
00053                 LSE_CALLCTOR                                                                    CMatrix4x4Base( const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> &_m44bOther, LSBOOL _bTranspose ) {
00054                         if ( !_bTranspose ) {
00055                                 _11 =_m44bOther._11; _12 =_m44bOther._12; _13 =_m44bOther._13; _14 =_m44bOther._14;
00056                                 _21 =_m44bOther._21; _22 =_m44bOther._22; _23 =_m44bOther._23; _24 =_m44bOther._24;
00057                                 _31 =_m44bOther._31; _32 =_m44bOther._32; _33 =_m44bOther._33; _34 =_m44bOther._34;
00058                                 _41 =_m44bOther._41; _42 =_m44bOther._42; _43 =_m44bOther._43; _44 =_m44bOther._44;
00059                         }
00060                         else {
00061                                 _11 =_m44bOther._11; _12 =_m44bOther._21; _13 =_m44bOther._31; _14 =_m44bOther._41;
00062                                 _21 =_m44bOther._12; _22 =_m44bOther._22; _23 =_m44bOther._32; _24 =_m44bOther._42;
00063                                 _31 =_m44bOther._13; _32 =_m44bOther._23; _33 =_m44bOther._33; _34 =_m44bOther._43;
00064                                 _41 =_m44bOther._14; _32 =_m44bOther._24; _43 =_m44bOther._34; _44 =_m44bOther._44;
00065                         }
00066                 }
00067                 explicit LSE_CALLCTOR                                                   CMatrix4x4Base( const _tType * _ptArray ) :
00068                         _11( _ptArray[0] ), _12( _ptArray[1] ), _13( _ptArray[2] ), _14( _ptArray[3] ),
00069                         _21( _ptArray[4] ), _22( _ptArray[5] ), _23( _ptArray[6] ), _24( _ptArray[7] ),
00070                         _31( _ptArray[8] ), _32( _ptArray[9] ), _33( _ptArray[10] ), _34( _ptArray[11] ),
00071                         _41( _ptArray[12] ), _42( _ptArray[13] ), _43( _ptArray[14] ), _44( _ptArray[15] ) {
00072                 }
00073 
00074 
00075                 // == Operators.
00084                 _tType & LSE_FCALL                                                              operator () ( LSUINT32 _ui32Row, LSUINT32 _ui32Col ) {
00085                         return reinterpret_cast<_tType *>(this)[(_ui32Row<<2UL)+_ui32Col];
00086                 }
00087 
00095                 _tType LSE_FCALL                                                                operator () ( LSUINT32 _ui32Row, LSUINT32 _ui32Col ) const {
00096                         return reinterpret_cast<const _tType *>(this)[(_ui32Row<<2UL)+_ui32Col];
00097                 }
00098 
00105                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> LSE_FCALL
00106                                                                                                                 operator * ( const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> &_mOther ) const {
00107                         CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> _mOut;
00108                         LSE_UNALIGNED const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> * /*LSE_RESTRICT*/ pmSrc1 = this;
00109                         // WTF.  Using LSE_RESTRICT on this screws it up.  Damn compiler bugs.
00110                         LSE_UNALIGNED const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> * /*LSE_RESTRICT*/ pmSrc2 = &_mOther;
00111 
00112                         const _tType * ptBufferIn = &reinterpret_cast<const _tType *>(pmSrc1)[3<<2];
00113                         _tType * pfBufferOut = &reinterpret_cast<_tType *>(&_mOut)[3<<2];
00114                         pfBufferOut[3] = ptBufferIn[3] * (*pmSrc2)( 3, 3 ) +
00115                                 ptBufferIn[2] * (*pmSrc2)( 2, 3 ) +
00116                                 ptBufferIn[1] * (*pmSrc2)( 1, 3 ) +
00117                                 ptBufferIn[0] * (*pmSrc2)( 0, 3 );
00118                         pfBufferOut[2] = ptBufferIn[3] * (*pmSrc2)( 3, 2 ) +
00119                                 ptBufferIn[2] * (*pmSrc2)( 2, 2 ) +
00120                                 ptBufferIn[1] * (*pmSrc2)( 1, 2 ) +
00121                                 ptBufferIn[0] * (*pmSrc2)( 0, 2 );
00122                         pfBufferOut[1] = ptBufferIn[3] * (*pmSrc2)( 3, 1 ) +
00123                                 ptBufferIn[2] * (*pmSrc2)( 2, 1 ) +
00124                                 ptBufferIn[1] * (*pmSrc2)( 1, 1 ) +
00125                                 ptBufferIn[0] * (*pmSrc2)( 0, 1 );
00126                         pfBufferOut[0] = ptBufferIn[3] * (*pmSrc2)( 3, 0 ) +
00127                                 ptBufferIn[2] * (*pmSrc2)( 2, 0 ) +
00128                                 ptBufferIn[1] * (*pmSrc2)( 1, 0 ) +
00129                                 ptBufferIn[0] * (*pmSrc2)( 0, 0 );
00130                         
00131                         ptBufferIn = &reinterpret_cast<const _tType *>(pmSrc1)[2<<2];
00132                         pfBufferOut = &reinterpret_cast<_tType *>(&_mOut)[2<<2];
00133                         pfBufferOut[3] = ptBufferIn[3] * (*pmSrc2)( 3, 3 ) +
00134                                 ptBufferIn[2] * (*pmSrc2)( 2, 3 ) +
00135                                 ptBufferIn[1] * (*pmSrc2)( 1, 3 ) +
00136                                 ptBufferIn[0] * (*pmSrc2)( 0, 3 );
00137                         pfBufferOut[2] = ptBufferIn[3] * (*pmSrc2)( 3, 2 ) +
00138                                 ptBufferIn[2] * (*pmSrc2)( 2, 2 ) +
00139                                 ptBufferIn[1] * (*pmSrc2)( 1, 2 ) +
00140                                 ptBufferIn[0] * (*pmSrc2)( 0, 2 );
00141                         pfBufferOut[1] = ptBufferIn[3] * (*pmSrc2)( 3, 1 ) +
00142                                 ptBufferIn[2] * (*pmSrc2)( 2, 1 ) +
00143                                 ptBufferIn[1] * (*pmSrc2)( 1, 1 ) +
00144                                 ptBufferIn[0] * (*pmSrc2)( 0, 1 );
00145                         pfBufferOut[0] = ptBufferIn[3] * (*pmSrc2)( 3, 0 ) +
00146                                 ptBufferIn[2] * (*pmSrc2)( 2, 0 ) +
00147                                 ptBufferIn[1] * (*pmSrc2)( 1, 0 ) +
00148                                 ptBufferIn[0] * (*pmSrc2)( 0, 0 );
00149                         
00150                         ptBufferIn = &reinterpret_cast<const _tType *>(pmSrc1)[1<<2];
00151                         pfBufferOut = &reinterpret_cast<_tType *>(&_mOut)[1<<2];
00152                         pfBufferOut[3] = ptBufferIn[3] * (*pmSrc2)( 3, 3 ) +
00153                                 ptBufferIn[2] * (*pmSrc2)( 2, 3 ) +
00154                                 ptBufferIn[1] * (*pmSrc2)( 1, 3 ) +
00155                                 ptBufferIn[0] * (*pmSrc2)( 0, 3 );
00156                         pfBufferOut[2] = ptBufferIn[3] * (*pmSrc2)( 3, 2 ) +
00157                                 ptBufferIn[2] * (*pmSrc2)( 2, 2 ) +
00158                                 ptBufferIn[1] * (*pmSrc2)( 1, 2 ) +
00159                                 ptBufferIn[0] * (*pmSrc2)( 0, 2 );
00160                         pfBufferOut[1] = ptBufferIn[3] * (*pmSrc2)( 3, 1 ) +
00161                                 ptBufferIn[2] * (*pmSrc2)( 2, 1 ) +
00162                                 ptBufferIn[1] * (*pmSrc2)( 1, 1 ) +
00163                                 ptBufferIn[0] * (*pmSrc2)( 0, 1 );
00164                         pfBufferOut[0] = ptBufferIn[3] * (*pmSrc2)( 3, 0 ) +
00165                                 ptBufferIn[2] * (*pmSrc2)( 2, 0 ) +
00166                                 ptBufferIn[1] * (*pmSrc2)( 1, 0 ) +
00167                                 ptBufferIn[0] * (*pmSrc2)( 0, 0 );
00168                         
00169                         ptBufferIn = &reinterpret_cast<const _tType *>(pmSrc1)[0<<2];
00170                         pfBufferOut = &reinterpret_cast<_tType *>(&_mOut)[0<<2];
00171                         pfBufferOut[3] = ptBufferIn[3] * (*pmSrc2)( 3, 3 ) +
00172                                 ptBufferIn[2] * (*pmSrc2)( 2, 3 ) +
00173                                 ptBufferIn[1] * (*pmSrc2)( 1, 3 ) +
00174                                 ptBufferIn[0] * (*pmSrc2)( 0, 3 );
00175                         pfBufferOut[2] = ptBufferIn[3] * (*pmSrc2)( 3, 2 ) +
00176                                 ptBufferIn[2] * (*pmSrc2)( 2, 2 ) +
00177                                 ptBufferIn[1] * (*pmSrc2)( 1, 2 ) +
00178                                 ptBufferIn[0] * (*pmSrc2)( 0, 2 );
00179                         pfBufferOut[1] = ptBufferIn[3] * (*pmSrc2)( 3, 1 ) +
00180                                 ptBufferIn[2] * (*pmSrc2)( 2, 1 ) +
00181                                 ptBufferIn[1] * (*pmSrc2)( 1, 1 ) +
00182                                 ptBufferIn[0] * (*pmSrc2)( 0, 1 );
00183                         pfBufferOut[0] = ptBufferIn[3] * (*pmSrc2)( 3, 0 ) +
00184                                 ptBufferIn[2] * (*pmSrc2)( 2, 0 ) +
00185                                 ptBufferIn[1] * (*pmSrc2)( 1, 0 ) +
00186                                 ptBufferIn[0] * (*pmSrc2)( 0, 0 );
00187                         return _mOut;
00188                 }
00189 
00196                 _tVector3Type LSE_FCALL                                                 operator * ( const _tVector3Type &_v3bOther ) const {
00197                         _tVector3Type v3bRet;
00198                         v3bRet.x = (_11 * _v3bOther.x + _21 * _v3bOther.y + 
00199                                 _31 * _v3bOther.z + _41);
00200                         v3bRet.y = (_12 * _v3bOther.x + _22 * _v3bOther.y +
00201                                 _32 * _v3bOther.z + _42);
00202                         v3bRet.z = (_13 * _v3bOther.x + _23 * _v3bOther.y +
00203                                 _33 * _v3bOther.z + _43);
00204                         return v3bRet;
00205                 }
00206 
00213                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00214                                                                                                                 operator = ( const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> &_mOther ) {
00215                         _11 = _mOther._11; _12 = _mOther._12; _13 = _mOther._13; _14 = _mOther._14;
00216                         _21 = _mOther._21; _22 = _mOther._22; _23 = _mOther._23; _24 = _mOther._24;
00217                         _31 = _mOther._31; _32 = _mOther._32; _33 = _mOther._33; _34 = _mOther._34;
00218                         _41 = _mOther._41; _42 = _mOther._42; _43 = _mOther._43; _44 = _mOther._44;
00219                         return (*this);
00220                 }
00221 
00222 
00223 
00224                 // == Functions.
00245                 LSVOID LSE_FCALL                                                                Set( _tType _t11, _tType _t12, _tType _t13, _tType _t14,
00246                         _tType _t21, _tType _t22, _tType _t23, _tType _t24,
00247                         _tType _t31, _tType _t32, _tType _t33, _tType _t34,
00248                         _tType _t41, _tType _t42, _tType _t43, _tType _t44 ) {
00249 #define LSM_MAT_COPY( VAL )  _ ## VAL = _t ## VAL
00250                         LSM_MAT_COPY( 11 ), LSM_MAT_COPY( 12 ), LSM_MAT_COPY( 13 ), LSM_MAT_COPY( 14 );
00251                         LSM_MAT_COPY( 21 ), LSM_MAT_COPY( 22 ), LSM_MAT_COPY( 23 ), LSM_MAT_COPY( 24 );
00252                         LSM_MAT_COPY( 31 ), LSM_MAT_COPY( 32 ), LSM_MAT_COPY( 33 ), LSM_MAT_COPY( 34 );
00253                         LSM_MAT_COPY( 41 ), LSM_MAT_COPY( 42 ), LSM_MAT_COPY( 43 ), LSM_MAT_COPY( 44 );
00254 #undef LSM_MAT_COPY
00255                 }
00256 
00262                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00263                                                                                                                 Identity() {
00264                         // Set the ones that need to be zero first.
00265                         _12 = _13 = _14 =
00266                         _21 = _23 = _24 =
00267                         _31 = _32 = _34 =
00268                         _41 = _42 = _43 = _tType( 0.0 );
00269                         
00270                         // Now the ones that need to be 1.
00271                         _11 = _22 = _33 = _44 = _tType( 1.0 );
00272                         return (*this);
00273                 }
00274                 
00280                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00281                                                                                                                 Transpose() {
00282                         CMathLib::Swap( _12, _21 );
00283                         CMathLib::Swap( _13, _31 );
00284                         CMathLib::Swap( _14, _41 );
00285                         CMathLib::Swap( _23, _32 );
00286                         CMathLib::Swap( _24, _42 );
00287                         CMathLib::Swap( _34, _43 );
00288                         return (*this);
00289                 }
00290                 
00296                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> LSE_FCALL
00297                                                                                                                 Inverse() const {
00298                         CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> m44bOut;
00299                         _tType fA0 = (*this)( 0, 0 ) * (*this)( 1, 1 ) - (*this)( 0, 1 ) * (*this)( 1, 0 );
00300                         _tType fA1 = (*this)( 0, 0 ) * (*this)( 1, 2 ) - (*this)( 0, 2 ) * (*this)( 1, 0 );
00301                         _tType fA2 = (*this)( 0, 0 ) * (*this)( 1, 3 ) - (*this)( 0, 3 ) * (*this)( 1, 0 );
00302                         _tType fA3 = (*this)( 0, 1 ) * (*this)( 1, 2 ) - (*this)( 0, 2 ) * (*this)( 1, 1 );
00303                         _tType fA4 = (*this)( 0, 1 ) * (*this)( 1, 3 ) - (*this)( 0, 3 ) * (*this)( 1, 1 );
00304                         _tType fA5 = (*this)( 0, 2 ) * (*this)( 1, 3 ) - (*this)( 0, 3 ) * (*this)( 1, 2 );
00305                         _tType fB0 = (*this)( 2, 0 ) * (*this)( 3, 1 ) - (*this)( 2, 1 ) * (*this)( 3, 0 );
00306                         _tType fB1 = (*this)( 2, 0 ) * (*this)( 3, 2 ) - (*this)( 2, 2 ) * (*this)( 3, 0 );
00307                         _tType fB2 = (*this)( 2, 0 ) * (*this)( 3, 3 ) - (*this)( 2, 3 ) * (*this)( 3, 0 );
00308                         _tType fB3 = (*this)( 2, 1 ) * (*this)( 3, 2 ) - (*this)( 2, 2 ) * (*this)( 3, 1 );
00309                         _tType fB4 = (*this)( 2, 1 ) * (*this)( 3, 3 ) - (*this)( 2, 3 ) * (*this)( 3, 1 );
00310                         _tType fB5 = (*this)( 2, 2 ) * (*this)( 3, 3 ) - (*this)( 2, 3 ) * (*this)( 3, 2 );
00311                         _tType fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0;
00312                         
00313                         LSE_UNALIGNED const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> * LSE_RESTRICT pmSrc = &(*this);
00314                         
00315                         if ( CMathLib::Abs( static_cast<LSREAL>(fDet) ) > LSM_MAT_EPSILON ) {
00316                                 register _tType fTemp = (*pmSrc)( 1, 3 );
00317                                 m44bOut( 0, 0 ) = +(*pmSrc)( 1, 1 ) * fB5 - (*pmSrc)( 1, 2 ) * fB4 + fTemp * fB3;
00318                                         m44bOut( 1, 0 ) = -(*pmSrc)( 1, 0 ) * fB5 + (*pmSrc)( 1, 2 ) * fB2 - fTemp * fB1;
00319                                         m44bOut( 2, 0 ) = +(*pmSrc)( 1, 0 ) * fB4 - (*pmSrc)( 1, 1 ) * fB2 + fTemp * fB0;
00320                                         m44bOut( 3, 0 ) = -(*pmSrc)( 1, 0 ) * fB3 + (*pmSrc)( 1, 1 ) * fB1 - (*pmSrc)( 1, 2 ) * fB0;
00321                                 fTemp = (*pmSrc)( 0, 3 );
00322                                 m44bOut( 0, 1 ) = -(*pmSrc)( 0, 1 ) * fB5 + (*pmSrc)( 0, 2 ) * fB4 - fTemp * fB3;
00323                                         m44bOut( 1, 1 ) = +(*pmSrc)( 0, 0 ) * fB5 - (*pmSrc)( 0, 2 ) * fB2 + fTemp * fB1;
00324                                         m44bOut( 2, 1 ) = -(*pmSrc)( 0, 0 ) * fB4 + (*pmSrc)( 0, 1 ) * fB2 - fTemp * fB0;
00325                                         m44bOut( 3, 1 ) = +(*pmSrc)( 0, 0 ) * fB3 - (*pmSrc)( 0, 1 ) * fB1 + (*pmSrc)( 0, 2 ) * fB0;
00326                                 fTemp = (*pmSrc)( 3, 3 );
00327                                 m44bOut( 0, 2 ) = +(*pmSrc)( 3, 1 ) * fA5 - (*pmSrc)( 3, 2 ) * fA4 + fTemp * fA3;
00328                                         m44bOut( 1, 2 ) = -(*pmSrc)( 3, 0 ) * fA5 + (*pmSrc)( 3, 2 ) * fA2 - fTemp * fA1;
00329                                         m44bOut( 2, 2 ) = +(*pmSrc)( 3, 0 ) * fA4 - (*pmSrc)( 3, 1 ) * fA2 + fTemp * fA0;
00330                                         m44bOut( 3, 2 ) = -(*pmSrc)( 3, 0 ) * fA3 + (*pmSrc)( 3, 1 ) * fA1 - (*pmSrc)( 3, 2 ) * fA0;
00331                                 fTemp = (*pmSrc)( 2, 3 );
00332                                 m44bOut( 0, 3 ) = -(*pmSrc)( 2, 1 ) * fA5 + (*pmSrc)( 2, 2 ) * fA4 - fTemp * fA3;
00333                                         m44bOut( 1, 3 ) = +(*pmSrc)( 2, 0 ) * fA5 - (*pmSrc)( 2, 2 ) * fA2 + fTemp * fA1;
00334                                         m44bOut( 2, 3 ) = -(*pmSrc)( 2, 0 ) * fA4 + (*pmSrc)( 2, 1 ) * fA2 - fTemp * fA0;
00335                                         m44bOut( 3, 3 ) = +(*pmSrc)( 2, 0 ) * fA3 - (*pmSrc)( 2, 1 ) * fA1 + (*pmSrc)( 2, 2 ) * fA0;
00336                                 
00337                                 _tType fInvDet = _tType( 1.0 ) / fDet;
00338                                 if ( fInvDet != _tType( 1.0 ) ) {
00339                                         _tType * pfThis = reinterpret_cast<_tType *>(&m44bOut);
00340                                         (*pfThis++) *= fInvDet;
00341                                         (*pfThis++) *= fInvDet;
00342                                         (*pfThis++) *= fInvDet;
00343                                         (*pfThis++) *= fInvDet;
00344                                         (*pfThis++) *= fInvDet;
00345                                         (*pfThis++) *= fInvDet;
00346                                         (*pfThis++) *= fInvDet;
00347                                         (*pfThis++) *= fInvDet;
00348                                         (*pfThis++) *= fInvDet;
00349                                         (*pfThis++) *= fInvDet;
00350                                         (*pfThis++) *= fInvDet;
00351                                         (*pfThis++) *= fInvDet;
00352                                         (*pfThis++) *= fInvDet;
00353                                         (*pfThis++) *= fInvDet;
00354                                         (*pfThis++) *= fInvDet;
00355                                         (*pfThis) *= fInvDet;
00356                                 }
00357                         }
00358                         else {
00359                                 m44bOut.Identity();
00360                         }
00361                         
00362                         return m44bOut;
00363                 }
00364                 
00370                 _tType LSE_FCALL                                                                Determ() const {
00371                         _tType fA0 = (*this)( 0, 0 ) * (*this)( 1, 1 ) - (*this)( 0, 1 ) * (*this)( 1, 0 );
00372                         _tType fA1 = (*this)( 0, 0 ) * (*this)( 1, 2 ) - (*this)( 0, 2 ) * (*this)( 1, 0 );
00373                         _tType fA2 = (*this)( 0, 0 ) * (*this)( 1, 3 ) - (*this)( 0, 3 ) * (*this)( 1, 0 );
00374                         _tType fA3 = (*this)( 0, 1 ) * (*this)( 1, 2 ) - (*this)( 0, 2 ) * (*this)( 1, 1 );
00375                         _tType fA4 = (*this)( 0, 1 ) * (*this)( 1, 3 ) - (*this)( 0, 3 ) * (*this)( 1, 1 );
00376                         _tType fA5 = (*this)( 0, 2 ) * (*this)( 1, 3 ) - (*this)( 0, 3 ) * (*this)( 1, 2 );
00377                         _tType fB0 = (*this)( 2, 0 ) * (*this)( 3, 1 ) - (*this)( 2, 1 ) * (*this)( 3, 0 );
00378                         _tType fB1 = (*this)( 2, 0 ) * (*this)( 3, 2 ) - (*this)( 2, 2 ) * (*this)( 3, 0 );
00379                         _tType fB2 = (*this)( 2, 0 ) * (*this)( 3, 3 ) - (*this)( 2, 3 ) * (*this)( 3, 0 );
00380                         _tType fB3 = (*this)( 2, 1 ) * (*this)( 3, 2 ) - (*this)( 2, 2 ) * (*this)( 3, 1 );
00381                         _tType fB4 = (*this)( 2, 1 ) * (*this)( 3, 3 ) - (*this)( 2, 3 ) * (*this)( 3, 1 );
00382                         _tType fB5 = (*this)( 2, 2 ) * (*this)( 3, 3 ) - (*this)( 2, 3 ) * (*this)( 3, 2 );
00383                         return fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0;
00384                 }
00385 
00392                 LSVOID LSE_FCALL                                                                GetRow( LSUINT32 _ui32Row, _tVector3Type &_v3bRet ) const {
00393                         LSE_UNALIGNED const _tType * pfData = &_11;
00394                         pfData += (_ui32Row << 2UL);
00395                         
00396                         _v3bRet.x = pfData[0];
00397                         _v3bRet.y = pfData[1];
00398                         _v3bRet.z = pfData[2];
00399                 }
00400 
00407                 LSVOID LSE_FCALL                                                                GetRow( LSUINT32 _ui32Row, _tVector4Type &_v4bRet ) const {
00408                         LSE_UNALIGNED const _tType * pfData = &_11;
00409                         pfData += (_ui32Row << 2UL);
00410                         
00411                         _v4bRet.x = pfData[0];
00412                         _v4bRet.y = pfData[1];
00413                         _v4bRet.z = pfData[2];
00414                         _v4bRet.w = pfData[3];
00415                 }
00416 
00423                 LSVOID LSE_FCALL                                                                SetRow( LSUINT32 _ui32Row, const _tVector3Type &_v3bVec ) {
00424                         LSE_UNALIGNED _tType * pfData = &_11;
00425                         pfData += (_ui32Row << 2);
00426                         
00427                         pfData[0] = _v3bVec.x;
00428                         pfData[1] = _v3bVec.y;
00429                         pfData[2] = _v3bVec.z;
00430                 }
00431 
00438                 LSVOID LSE_FCALL                                                                SetRow( LSUINT32 _ui32Row, const _tVector4Type &_v4bVec ) {
00439                         LSE_UNALIGNED _tType * pfData = &_11;
00440                         pfData += (_ui32Row << 2);
00441                         
00442                         pfData[0] = _v4bVec.x;
00443                         pfData[1] = _v4bVec.y;
00444                         pfData[2] = _v4bVec.z;
00445                         pfData[3] = _v4bVec.w;
00446                 }
00447 
00456                 LSVOID LSE_FCALL                                                                PerspectiveFovRH( _tType _tFov, _tType _tAspect, _tType _tNear, _tType _tFar ) {
00457                         // Zero out the ones that need to be zero.
00458                         _12 = _13 = _14 = _tType( 0.0 );
00459                         _21 = _23 = _24 = _tType( 0.0 );
00460                         _31 = _32 = _tType( 0.0 );
00461                         _41 = _42 = _44 = _tType( 0.0 );
00462                         
00463                         _tType fDist = _tType( 1.0 ) / (_tNear - _tFar);
00464                         
00465                         // Set the remaining ones.
00466                         _22 = _tType( 1.0 ) / CMathLib::Tan( static_cast<LSREAL>(_tType( 0.5 ) * _tFov) );
00467                         _11 = _22 / _tAspect;
00468 
00469                         _33 = _tFar * fDist;
00470                         _34 = -_tType( 1.0 );
00471 
00472                         _43 = (_tFar * _tNear) * fDist;
00473                 }
00474 
00482                 LSVOID LSE_FCALL                                                                PerspectiveFovRH( _tType _tFov, _tType _tAspect, _tType _tNear ) {
00483                         // Zero out the ones that need to be zero.
00484                         _12 = _13 = _14 = _tType( 0.0 );
00485                         _21 = _23 = _24 = _tType( 0.0 );
00486                         _31 = _32 = _tType( 0.0 );
00487                         _41 = _42 = _44 = _tType( 0.0 );
00488                         
00489                         // Set the remaining ones.
00490                         _22 = _tType( 1.0 ) / CMathLib::Tan( static_cast<LSREAL>(_tType( 0.5 ) * _tFov) );
00491                         _11 = _22 / _tAspect;
00492 
00493                         _33 = LSM_REAL_EPSILON - _tType( 1.0 );
00494                         _34 = -_tType( 1.0 );
00495 
00496                         _43 = _tNear * (LSM_REAL_EPSILON - _tType( 2.0 ));
00497                 }
00498 
00509                 LSVOID LSE_FCALL                                                                OrthoOffCenterRH( _tType _tLeft, _tType _tRight, _tType _tBottom, _tType _tTop, _tType _tNear, _tType _tFar ) {
00510                         // Zero out the ones that need to be zero.
00511                         _12 = _13 = _14 = _tType( 0.0 );
00512                         _21 = _23 = _24 = _tType( 0.0 );
00513                         _31 = _32 = _34 = _tType( 0.0 );
00514                         
00515                         register _tType fWidth = _tRight - _tLeft;
00516                         register _tType fHeight = _tTop - _tBottom;
00517                         
00518                         _11 = _tType( 2.0 ) / fWidth;
00519                         _22 = _tType( 2.0 ) / fHeight;
00520                         _33 = _tType( -2.0 ) / (_tNear - _tFar);
00521                         
00522                         _41 = (_tRight + _tLeft) / (_tLeft - _tRight);
00523                         _42 = (_tTop + _tBottom) / (_tBottom - _tTop);
00524                         _43 = (_tFar + _tNear) / (_tNear - _tFar);
00525                         _44 = _tType( 1.0 );
00526                 }
00527 
00538                 LSVOID LSE_FCALL                                                                OrthoOffCenterLH( _tType _tLeft, _tType _tRight, _tType _tBottom, _tType _tTop, _tType _tNear, _tType _tFar ) {
00539                         // Zero out the ones that need to be zero.
00540                         _12 = _13 = _14 = _tType( 0.0 );
00541                         _21 = _23 = _24 = _tType( 0.0 );
00542                         _31 = _32 = _34 = _tType( 0.0 );
00543                         
00544                         register _tType fWidth = _tRight - _tLeft;
00545                         register _tType fHeight = _tTop - _tBottom;
00546                         
00547                         _11 = _tType( 2.0 ) / fWidth;
00548                         _22 = _tType( 2.0 ) / fHeight;
00549                         _33 = _tType( 1.0 ) / (_tFar - _tNear);
00550                         
00551                         _41 = (_tRight + _tLeft) / (_tLeft - _tRight);
00552                         _42 = (_tTop + _tBottom) / (_tBottom - _tTop);
00553                         _43 = _tNear / (_tNear - _tFar);
00554                         _44 = _tType( 1.0 );
00555                 }
00556 
00566                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00567                                                                                                                 MatrixRotationAxis( _tType _tX, _tType _tY, _tType _tZ, _tType _tAngle ) {
00568                         LSREAL fS;
00569                         LSREAL fC;
00570                         CMathLib::SinCos( static_cast<LSREAL>(_tAngle), fS, fC );
00571                         
00572                         _tType fT = _tType( 1.0 ) - fC;
00573                         register _tType fTX = fT * _tX;
00574                         register _tType fTY = fT * _tY;
00575                         register _tType fTZ = fT * _tZ;
00576                         _tType fSX = fS * _tX;
00577                         _tType fSY = fS * _tY;
00578                         _tType fSZ = fS * _tZ;
00579                         
00580                         _11 = fTX * _tX + fC;
00581                         _12 = fTX * _tY + fSZ;
00582                         _13 = fTX * _tZ - fSY;
00583                         _14 = _tType( 0.0 );
00584                         
00585                         _21 = fTY * _tX - fSZ;
00586                         _22 = fTY * _tY + fC;
00587                         _23 = fTY * _tZ + fSX;
00588                         _24 = _tType( 0.0 );
00589                         
00590                         _31 = fTZ * _tX + fSY;
00591                         _32 = fTZ * _tY - fSX;
00592                         _33 = fTZ * _tZ + fC;
00593                         _34 = _tType( 0.0 );
00594                         
00595                         _41 = _tType( 0.0 );
00596                         _42 = _tType( 0.0 );
00597                         _43 = _tType( 0.0 );
00598                         _44 = _tType( 1.0 );
00599 
00600                         return (*this);
00601                 }
00602 
00610                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00611                                                                                                                 MatrixRotationAxis( const _tVector3Type &_v3bAxis, _tType _tAngle ) {
00612                         return MatrixRotationAxis( _v3bAxis.x, _v3bAxis.y, _v3bAxis.z, _tAngle );
00613                 }
00614 
00621                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00622                                                                                                                 MatrixRotationX( _tType _tAngle ) {
00623                         LSREAL fS;
00624                         LSREAL fC;
00625                         CMathLib::SinCos( static_cast<LSREAL>(_tAngle), fS, fC );
00626                         _11 = _tType( 1.0 );
00627                         _12 = _tType( 0.0 );
00628                         _13 = _tType( 0.0 );
00629                         _14 = _tType( 0.0 );
00630                         
00631                         _21 = _tType( 0.0 );
00632                         _22 = fC;
00633                         _23 = fS;
00634                         _24 = _tType( 0.0 );
00635                         
00636                         _31 = _tType( 0.0 );
00637                         _32 = -fS;
00638                         _33 = fC;
00639                         _34 = _tType( 0.0 );
00640                         
00641                         _41 = _tType( 0.0 );
00642                         _42 = _tType( 0.0 );
00643                         _43 = _tType( 0.0 );
00644                         _44 = _tType( 1.0 );
00645                         return (*this);
00646                 }
00647 
00654                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00655                                                                                                                 MatrixRotationY( _tType _tAngle ) {
00656                         LSREAL fS;
00657                         LSREAL fC;
00658                         CMathLib::SinCos( static_cast<LSREAL>(_tAngle), fS, fC );
00659                         _11 = fC;
00660                         _12 = _tType( 0.0 );
00661                         _13 = -fS;
00662                         _14 = _tType( 0.0 );
00663                         
00664                         _21 = _tType( 0.0 );
00665                         _22 = _tType( 1.0 );
00666                         _23 = _tType( 0.0 );
00667                         _24 = _tType( 0.0 );
00668                         
00669                         _31 = fS;
00670                         _32 = _tType( 0.0 );
00671                         _33 = fC;
00672                         _34 = _tType( 0.0 );
00673                         
00674                         _41 = _tType( 0.0 );
00675                         _42 = _tType( 0.0 );
00676                         _43 = _tType( 0.0 );
00677                         _44 = _tType( 1.0 );
00678                         return (*this);
00679                 }
00680 
00687                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00688                                                                                                                 MatrixRotationZ( _tType _tAngle ) {
00689                         LSREAL fS;
00690                         LSREAL fC;
00691                         CMathLib::SinCos( static_cast<LSREAL>(_tAngle), fS, fC );
00692                         _11 = fC;
00693                         _12 = fS;
00694                         _13 = _tType( 0.0 );
00695                         _14 = _tType( 0.0 );
00696                         
00697                         _21 = -fS;
00698                         _22 = fC;
00699                         _23 = _tType( 0.0 );
00700                         _24 = _tType( 0.0 );
00701                         
00702                         _31 = _tType( 0.0 );
00703                         _32 = _tType( 0.0 );
00704                         _33 = _tType( 1.0 );
00705                         _34 = _tType( 0.0 );
00706                         
00707                         _41 = _tType( 0.0 );
00708                         _42 = _tType( 0.0 );
00709                         _43 = _tType( 0.0 );
00710                         _44 = _tType( 1.0 );
00711                         return (*this);
00712                 }
00713 
00722                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00723                                                                                                                 MatrixRotationYawPitchRoll( _tType _tYaw, _tType _tPitch, _tType _tRoll ) {
00724                         LSREAL fSa, fCa;
00725                         CMathLib::SinCos( static_cast<LSREAL>(_tYaw), fSa, fCa );
00726 
00727                         LSREAL fSb, fCb;
00728                         CMathLib::SinCos( static_cast<LSREAL>(_tPitch), fSb, fCb );
00729 
00730                         LSREAL fSh, fCh;
00731                         CMathLib::SinCos( static_cast<LSREAL>(_tRoll), fSh, fCh );
00732 
00733 
00734                         _11 = fCa * fCb;
00735                         _12 = fCa * fSb * fSh - fSa * fCh;
00736                         _13 = fCa * fSb * fCh + fSa * fSh;
00737 
00738                         _21 = fSa * fCb;
00739                         _22 = fSa * fSb * fSh + fCa * fCh;
00740                         _23 = fSa * fSb * fCh - fCa * fSh;
00741 
00742                         _31 = -fSb;
00743                         _32 = fCb * fSh;
00744                         _33 = fCb * fCh;
00745 
00746                         _41 = _tType( 0.0 );
00747                         _42 = _tType( 0.0 );
00748                         _43 = _tType( 0.0 );
00749 
00750                         // Zero the position.
00751                         _14 = _tType( 0.0 );
00752                         _24 = _tType( 0.0 );
00753                         _34 = _tType( 0.0 );
00754                         _44 = _tType( 1.0 );
00755                         return (*this);
00756                 }
00757                 
00766                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00767                                                                                                                 MatrixScaling( _tType _tX, _tType _tY, _tType _tZ ) {
00768                         _12 = _13 = _14 = _tType( 0.0 );
00769                         _21 = _23 = _24 = _tType( 0.0 );
00770                         _31 = _32 = _34 = _tType( 0.0 );
00771                         
00772                         _11 = _tX;
00773                         _22 = _tY;
00774                         _33 = _tZ;
00775                         
00776                         _41 = _tType( 0.0 );
00777                         _42 = _tType( 0.0 );
00778                         _43 = _tType( 0.0 );
00779                         _44 = _tType( 1.0 );
00780                         
00781                         return (*this);
00782                 }
00783 
00792                 CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> & LSE_FCALL
00793                                                                                                                 MatrixTranslation( _tType _tX, _tType _tY, _tType _tZ ) {
00794                         _12 = _13 = _14 = _tType( 0.0 );
00795                         _21 = _23 = _24 = _tType( 0.0 );
00796                         _31 = _32 = _34 = _tType( 0.0 );
00797                         _11 = _22 = _33 = _tType( 1.0 );
00798 
00799                         _41 = _tX;
00800                         _42 = _tY;
00801                         _43 = _tZ;
00802                         _44 = _tType( 1.0 );
00803 
00804                         return (*this);
00805                 }
00806                 
00814                 LSVOID LSE_FCALL                                                                GetYawPitchRoll( _tType &_tYaw, _tType &_tPitch, _tType &_tRoll ) const {
00815                         _tYaw = CMathLib::ATan( static_cast<LSREAL>(_21), static_cast<LSREAL>(_11) );
00816                         _tPitch = CMathLib::ATan( static_cast<LSREAL>(-_31), CMathLib::Sqrt( static_cast<LSREAL>(_32 * _32 + _33 * _33) ) );
00817                         _tRoll = CMathLib::ATan( static_cast<LSREAL>(_32), static_cast<LSREAL>(_33) );
00818                 }
00819 
00826                 static _tVector3Type LSE_FCALL                                  MultiplyVec3( const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> &_m44bMat, const _tVector3Type &_v3bIn ) {
00827                         _tVector3Type _v3bOut;
00828                         const _tType * /*LSE_RESTRICT*/ pfIn = reinterpret_cast<const _tType *>(&_v3bIn);
00829                         _v3bOut.x = _m44bMat._11 * pfIn[0] + _m44bMat._21 * pfIn[1] + 
00830                                 _m44bMat._31 * pfIn[2] + _m44bMat._41;
00831                         _v3bOut.y = _m44bMat._12 * pfIn[0] + _m44bMat._22 * pfIn[1] +
00832                                 _m44bMat._32 * pfIn[2] + _m44bMat._42;
00833                         _v3bOut.z = _m44bMat._13 * pfIn[0] + _m44bMat._23 * pfIn[1] +
00834                                 _m44bMat._33 * pfIn[2] + _m44bMat._43;
00835                         return _v3bOut;
00836                 }
00837 
00845                 static _tVector3Type LSE_FCALL                                  MultiplyVec3Normal( const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> &_m44bMat, const _tVector3Type &_v3bIn ) {
00846                         _tVector3Type _v3bOut;
00847                         const _tType * /*LSE_RESTRICT*/ pfIn = reinterpret_cast<const _tType *>(&_v3bIn);
00848                         _v3bOut.x = _m44bMat._11 * pfIn[0] + _m44bMat._21 * pfIn[1] + 
00849                                 _m44bMat._31 * pfIn[2];
00850                         _v3bOut.y = _m44bMat._12 * pfIn[0] + _m44bMat._22 * pfIn[1] +
00851                                 _m44bMat._32 * pfIn[2];
00852                         _v3bOut.z = _m44bMat._13 * pfIn[0] + _m44bMat._23 * pfIn[1] +
00853                                 _m44bMat._33 * pfIn[2];
00854                         return _v3bOut;
00855                 }
00856 
00863                 static _tVector4Type LSE_FCALL                                  MultiplyVec4( const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> &_m44bMat, const _tVector4Type &_v4bIn ) {
00864                         _tVector4Type _v4bOut;
00865                         const _tType * /*LSE_RESTRICT*/ pfIn = reinterpret_cast<const _tType *>(&_v4bIn);
00866                         _v4bOut.x = _m44bMat._11 * pfIn[0] + _m44bMat._21 * pfIn[1] + 
00867                                 _m44bMat._31 * pfIn[2] + _m44bMat._41;
00868                         _v4bOut.y = _m44bMat._12 * pfIn[0] + _m44bMat._22 * pfIn[1] +
00869                                 _m44bMat._32 * pfIn[2] + _m44bMat._42;
00870                         _v4bOut.z = _m44bMat._13 * pfIn[0] + _m44bMat._23 * pfIn[1] +
00871                                 _m44bMat._33 * pfIn[2] + _m44bMat._43;
00872                         _v4bOut.w = _m44bMat._14 * pfIn[0] + _m44bMat._24 * pfIn[1] +
00873                                 _m44bMat._34 * pfIn[2] + _m44bMat._44;
00874                         return _v4bOut;
00875                 }
00876 
00885                 static LSVOID LSE_FCALL                                                 MultiplyVec3Batch( const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> &_m44bMat,
00886                         const _tVector3Type * _pv3bIn, LSUINT32 _ui32Total,
00887                         _tVector3Type * _pv3bOut ) {
00888                         while ( _ui32Total-- != 0UL ) {
00889                                 (*_pv3bOut++) = MultiplyVec3( _m44bMat, (*_pv3bIn++) );
00890                         }
00891                 }
00892 
00901                 static LSVOID LSE_FCALL                                                 MultiplyVec3BatchNormal( const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> &_m44bMat,
00902                         const _tVector3Type * _pv3bIn, LSUINT32 _ui32Total,
00903                         _tVector3Type * _pv3bOut ) {
00904                         while ( _ui32Total-- != 0UL ) {
00905                                 (*_pv3bOut++) = MultiplyVec3Normal( _m44bMat, (*_pv3bIn++) );
00906                         }
00907                 }
00908 
00917                 static LSVOID LSE_FCALL                                                 MultiplyVec4Batch( const CMatrix4x4Base<_tType, _tVector3Type, _tVector4Type> &_m44bMat,
00918                         const _tVector4Type * _pv4bIn, LSUINT32 _ui32Total,
00919                         _tVector4Type * _pv4bOut ) {
00920                         while ( _ui32Total-- != 0UL ) {
00921                                 (*_pv4bOut++) = MultiplyVec4( _m44bMat, (*_pv4bIn++) );
00922                         }
00923                 }
00924 
00925 
00926                 // == Members.
00927 #pragma pack( push, 1 ) // Enforce alignment for array access (() operator).
00928                 _tType                                                                                  _11, _12, _13, _14;
00929                 _tType                                                                                  _21, _22, _23, _24;
00930                 _tType                                                                                  _31, _32, _33, _34;
00931                 _tType                                                                                  _41, _42, _43, _44;
00932 #pragma pack( pop )
00933         };
00934 
00935 }       // namespace lsm
00936 
00937 #endif  // __LSM_MATRIX4X4BASE_H__
00938 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator