"L. Spiro Engine"
|
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