"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSMathLib/Src/Helpers/LSMHelpers.h

00001 
00017 #ifndef __LSM_HELPERS_H__
00018 #define __LSM_HELPERS_H__
00019 
00020 #include "../LSMMathLib.h"
00021 #include "../Matrix/LSMMatrix3x3.h"
00022 #include "../Matrix/LSMMatrix4x4.h"
00023 #include "../Quaternion/LSMQuaternion.h"
00024 #include "../Vector/LSMVector2.h"
00025 #include "../Vector/LSMVector3.h"
00026 
00027 namespace lsm {
00028 
00035         class CHelpers {
00036         public :
00048                 static LSVOID LSE_FCALL                 DecomposeMatrix( const CMatrix4x4 &_mMatrix,
00049                         CQuaternion &_qRot,
00050                         CVector3 &_vScale,
00051                         CVector3 &_vPos );
00052 
00063                 static CMatrix4x4 & LSE_FCALL   ComposeMatrix( CMatrix4x4 &_mMatrix,
00064                         const CQuaternion &_qRot,
00065                         const CVector3 &_vPos );
00066 
00077                 static CMatrix4x4 & LSE_FCALL   ComposeMatrix( CMatrix4x4 &_mMatrix,
00078                         const CQuaternion &_qRot,
00079                         const CVector3 &_vScale,
00080                         const CVector3 &_vPos );
00081 
00097                 static CMatrix4x4 & LSE_FCALL   TransformInterp( CMatrix4x4 &_mMatrix,
00098                         const CQuaternion &_qRot,
00099                         const CVector3 &_vScale,
00100                         const CVector3 &_vPos,
00101                         const CMatrix4x4 &_mTarget,
00102                         LSREAL _fFrac );
00103 
00120                 static CMatrix4x4 & LSE_FCALL   TransformInterp( CMatrix4x4 &_mMatrix,
00121                         const CQuaternion &_qRot,
00122                         const CVector3 &_vScale,
00123                         const CVector3 &_vPos,
00124                         const CQuaternion &_qTargetRot,
00125                         const CVector3 &_vTargetScale,
00126                         const CVector3 &_vTargetPos,
00127                         LSREAL _fFrac );
00128 
00136                 static LSVOID LSE_FCALL                 TransformInertiaTensor( CMatrix3x3 &_mWorld,
00137                         const CMatrix3x3 &_mInvInertiaTensor,
00138                         const CMatrix4x4 &_mRot );
00139 
00149                 static LSVOID LSE_FCALL                 MakeOrthonormalBasis( const CVector3 &_vX,
00150                         CVector3 &_vY,
00151                         CVector3 &_vZ );
00152 
00163                 static LSVOID LSE_FCALL                 MakeOrthonormalBasisSlow( const CVector3 &_vX,
00164                         CVector3 &_vY,
00165                         CVector3 &_vZ );
00166 
00174                 static LSREAL LSE_FCALL                 GetNormalizedZ( LSREAL _fX, LSREAL _fY );
00175 
00187                 static CVector2 LSE_CALL                InterpolateNonUniformQuad( const CVector2 &_vP0, const CVector2 &_vP1, const CVector2 &_vP2, const CVector2 &_vP3,
00188                         LSREAL _fX, LSREAL _fY );
00189 
00190         };
00191 
00192 
00193         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00194         // DEFINITIONS
00195         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00196         // == Functions.
00207         LSE_INLINE CMatrix4x4 & LSE_FCALL CHelpers::ComposeMatrix( CMatrix4x4 &_mMatrix,
00208                 const CQuaternion &_qRot,
00209                 const CVector3 &_vPos ) {
00210 
00211                 _qRot.ToRotationMatrix( _mMatrix );
00212                 _mMatrix( 0, 3 ) = LSM_ZERO;
00213                 _mMatrix( 1, 3 ) = LSM_ZERO;
00214                 _mMatrix( 2, 3 ) = LSM_ZERO;
00215                 _mMatrix( 3, 3 ) = LSM_ONE;
00216                 _mMatrix.SetRow( 3, _vPos );
00217                 return _mMatrix;
00218         }
00219 
00230         LSE_INLINE CMatrix4x4 & LSE_FCALL CHelpers::ComposeMatrix( CMatrix4x4 &_mMatrix,
00231                 const CQuaternion &_qRot,
00232                 const CVector3 &_vScale,
00233                 const CVector3 &_vPos ) {
00234                 _qRot.ToRotationMatrix( _mMatrix );
00235                 _mMatrix( 0, 0 ) *= _vScale.x;
00236                 _mMatrix( 0, 1 ) *= _vScale.x;
00237                 _mMatrix( 0, 2 ) *= _vScale.x;
00238                 _mMatrix( 1, 0 ) *= _vScale.y;
00239                 _mMatrix( 1, 1 ) *= _vScale.y;
00240                 _mMatrix( 1, 2 ) *= _vScale.y;
00241                 _mMatrix( 2, 0 ) *= _vScale.z;
00242                 _mMatrix( 2, 1 ) *= _vScale.z;
00243                 _mMatrix( 2, 2 ) *= _vScale.z;
00244                 _mMatrix( 0, 3 ) = LSM_ZERO;
00245                 _mMatrix( 1, 3 ) = LSM_ZERO;
00246                 _mMatrix( 2, 3 ) = LSM_ZERO;
00247                 _mMatrix( 3, 3 ) = LSM_ONE;
00248                 _mMatrix.SetRow( 3, _vPos );
00249                 return _mMatrix;
00250         }
00251 
00259         LSE_INLINE LSVOID LSE_FCALL CHelpers::TransformInertiaTensor( CMatrix3x3 &_mWorld,
00260                 const CMatrix3x3 &_mInvInertiaTensor,
00261                 const CMatrix4x4 &_mRot ) {
00262 
00263                 LSREAL fT0 = _mRot( 0, 0 ) * _mInvInertiaTensor( 0, 0 ) +
00264                         _mRot( 1, 0 ) * _mInvInertiaTensor( 0, 1 ) +
00265                         _mRot( 2, 0 ) * _mInvInertiaTensor( 0, 2 );
00266                 LSREAL fT1 = _mRot( 0, 0 ) * _mInvInertiaTensor( 1, 0 ) +
00267                         _mRot( 1, 0 ) * _mInvInertiaTensor( 1, 1 ) +
00268                         _mRot( 2, 0 ) * _mInvInertiaTensor( 1, 2 );
00269                 LSREAL fT2 = _mRot( 0, 0 ) * _mInvInertiaTensor( 2, 0 ) +
00270                         _mRot( 1, 0 ) * _mInvInertiaTensor( 2, 1 ) +
00271                         _mRot( 2, 0 ) * _mInvInertiaTensor( 2, 2 );
00272                 LSREAL fT3 = _mRot( 0, 1 ) * _mInvInertiaTensor( 0, 0 ) +
00273                         _mRot( 1, 1 ) * _mInvInertiaTensor( 0, 1 ) +
00274                         _mRot( 2, 1 ) * _mInvInertiaTensor( 0, 2 );
00275                 LSREAL fT4 = _mRot( 0, 1 ) * _mInvInertiaTensor( 1, 0 ) +
00276                         _mRot( 1, 1 ) * _mInvInertiaTensor( 1, 1 ) +
00277                         _mRot( 2, 1 ) * _mInvInertiaTensor( 1, 2 );
00278                 LSREAL fT5 = _mRot( 0, 1 ) * _mInvInertiaTensor( 2, 0 ) +
00279                         _mRot( 1, 1 ) * _mInvInertiaTensor( 2, 1 ) +
00280                         _mRot( 2, 1 ) * _mInvInertiaTensor( 2, 2 );
00281                 LSREAL fT6 = _mRot( 0, 2 ) * _mInvInertiaTensor( 0, 0 ) +
00282                         _mRot( 1, 2 ) * _mInvInertiaTensor( 0, 1 ) +
00283                         _mRot( 2, 2 ) * _mInvInertiaTensor( 0, 2 );
00284                 LSREAL fT7 = _mRot( 0, 2 ) * _mInvInertiaTensor( 1, 0 ) +
00285                         _mRot( 1, 2 ) * _mInvInertiaTensor( 1, 1 ) +
00286                         _mRot( 2, 2 ) * _mInvInertiaTensor( 1, 2 );
00287                 LSREAL fT8 = _mRot( 0, 2 ) * _mInvInertiaTensor( 2, 0 ) +
00288                         _mRot( 1, 2 ) * _mInvInertiaTensor( 2, 1 ) +
00289                         _mRot( 2, 2 ) * _mInvInertiaTensor( 2, 2 );
00290 
00291                 _mWorld( 0, 0 ) = fT0 * _mRot( 0, 0 ) +
00292                         fT1 * _mRot( 1, 0 ) +
00293                         fT2 * _mRot( 2, 0 );
00294                 _mWorld( 1, 0 ) = fT0 * _mRot( 0, 1 ) +
00295                         fT1 * _mRot( 1, 1 ) +
00296                         fT2 * _mRot( 2, 1 );
00297                 _mWorld( 2, 0 ) = fT0 * _mRot( 0, 2 ) +
00298                         fT1 * _mRot( 1, 2 ) +
00299                         fT2 * _mRot( 2, 2 );
00300                 _mWorld( 0, 1 ) = fT3 * _mRot( 0, 0 ) +
00301                         fT4 * _mRot( 1, 0 ) +
00302                         fT5 * _mRot( 2, 0 );
00303                 _mWorld( 1, 1 ) = fT3 * _mRot( 0, 1 ) +
00304                         fT4 * _mRot( 1, 1 ) +
00305                         fT5 * _mRot( 2, 1 );
00306                 _mWorld( 2, 1 ) = fT3 * _mRot( 0, 2 ) +
00307                         fT4 * _mRot( 1, 2 ) +
00308                         fT5 * _mRot( 2, 2 );
00309                 _mWorld( 0, 2 ) = fT6 * _mRot( 0, 0 ) +
00310                         fT7 * _mRot( 1, 0 ) +
00311                         fT8 * _mRot( 2, 0 );
00312                 _mWorld( 1, 2 ) = fT6 * _mRot( 0, 1 ) +
00313                         fT7 * _mRot( 1, 1 ) +
00314                         fT8 * _mRot( 2, 1 );
00315                 _mWorld( 2, 2 ) = fT6 * _mRot( 0, 2 ) +
00316                         fT7 * _mRot( 1, 2 ) +
00317                         fT8 * _mRot( 2, 2 );
00318         }
00319 
00329         LSE_INLINE LSVOID LSE_FCALL CHelpers::MakeOrthonormalBasis( const CVector3 &_vX,
00330                 CVector3 &_vY,
00331                 CVector3 &_vZ ) {
00332                 // Check whether the X-axis is nearer to the X or Y axis.
00333                 if ( CMathLib::Abs( _vX.x ) > CMathLib::Abs( _vX.y ) ) { 
00334                         // Scaling factor to ensure the results are normalized.
00335                         const LSREAL fS = CMathLib::InvSqrt( _vX.z * _vX.z +
00336                                 _vX.x * _vX.x );
00337 
00338                         // The new Y-axis is at right angles to the world Y-axis.
00339                         _vY.x = _vX.z * fS;
00340                         _vY.y = LSM_ZERO;
00341                         _vY.z = -_vX.x * fS;
00342 
00343                         // The new Z-axis is at right angles to the new X- and Y- axes.
00344                         _vZ.x = _vX.y * _vY.x;
00345                         _vZ.y = _vX.z * _vY.x -
00346                                 _vX.x * _vY.z;
00347                         _vZ.z = -_vX.y * _vY.x;
00348                 }
00349                 else {
00350                         // Scaling factor to ensure the results are normalized.
00351                         const LSREAL fS = CMathLib::InvSqrt( _vX.z * _vX.z + 
00352                                 _vX.y * _vX.y );
00353 
00354                         // The new Y-axis is at right angles to the world X-axis.
00355                         _vY.x = LSM_ZERO;
00356                         _vY.y = -_vX.z * fS;
00357                         _vY.z = _vX.y * fS;
00358 
00359                         // The new Z-axis is at right angles to the new X- and Y- axes.
00360                         _vZ.x = _vX.y * _vY.z - 
00361                                 _vX.z * _vY.y;
00362                         _vZ.y = -_vX.x * _vY.z;
00363                         _vZ.z = _vX.x * _vY.y;
00364                 }
00365         }
00366 
00377         LSE_INLINE LSVOID LSE_FCALL CHelpers::MakeOrthonormalBasisSlow( const CVector3 &_vX,
00378                 CVector3 &_vY,
00379                 CVector3 &_vZ ) {
00380 
00381                 // Check whether the Z-axis is nearer to the X or Y axis.
00382                 if ( CMathLib::Abs( _vX.x ) > CMathLib::Abs( _vX.y ) ) {
00383                         _vZ = CVector3( LSM_ZERO, LSM_ONE, LSM_ZERO ) % _vX;
00384                 }
00385                 else {
00386                         _vZ = CVector3( LSM_ONE, LSM_ZERO, LSM_ZERO ) % _vX;
00387                 }
00388                 _vY = _vX % _vZ;
00389 
00390                 _vZ.Normalize();
00391                 _vY.Normalize();
00392         }
00393 
00401         LSE_INLINE LSREAL LSE_FCALL CHelpers::GetNormalizedZ( LSREAL _fX, LSREAL _fY ) {
00402                 LSREAL fTemp = LSM_ONE - ((_fX * _fX) + (_fY * _fY));
00403                 if ( CMathLib::Equals( fTemp, LSM_ZERO, LSM_REAL_EPSILON ) ) { return LSM_ZERO; }
00404                 return CMathLib::Sqrt( fTemp );
00405         }
00406 
00407 }       // namespace lsm
00408 
00409 #endif  // __LSM_HELPERS_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator