xsi_matrix3f.h
Go to the documentation of this file.
00001 //*****************************************************************************
00011 //*****************************************************************************
00012 
00013 #if (_MSC_VER > 1000) || defined(SGI_COMPILER)
00014 #pragma once
00015 #endif
00016 
00017 #ifndef __XSIMATRIX3F_H__
00018 #define __XSIMATRIX3F_H__
00019 
00020 #include "sicppsdk.h"
00021 #include "xsi_math.h"
00022 
00023 namespace XSI {
00024 namespace MATH {
00025 
00026 class CVector3f;
00027 
00028 //*****************************************************************************
00033 //*****************************************************************************
00034 class SICPPSDKDECL CMatrix3f
00035 {
00036 public:
00037 
00039     SICPPSDK_INLINE CMatrix3f();
00040 
00052     SICPPSDK_INLINE CMatrix3f(  float in_00, float in_01, float in_02,
00053                                 float in_10, float in_11, float in_12,
00054                                 float in_20, float in_21, float in_22);
00055 
00059     SICPPSDK_INLINE CMatrix3f( const CMatrix3f& in_matrix3);
00060 
00062     SICPPSDK_INLINE ~CMatrix3f();
00063 
00067     SICPPSDK_INLINE CMatrix3f  & operator=( const CMatrix3f & in_matrix3 );
00068 
00074     SICPPSDK_INLINE CMatrix3f & operator*=(const CMatrix3f & in_matrix3 );
00075 
00079     SICPPSDK_INLINE CMatrix3f& SetIdentity();
00080 
00085     SICPPSDK_INLINE bool Invert(const CMatrix3f& in_matrix3);
00086 
00090     SICPPSDK_INLINE bool TransposeInverseInPlace();
00091 
00097     SICPPSDK_INLINE bool TransposeInverse(const CMatrix3f& in_matrix3);
00098 
00101     SICPPSDK_INLINE void TransposeInPlace();
00102 
00106     SICPPSDK_INLINE void Transpose(const CMatrix3f& in_matrix3);
00107 
00112     SICPPSDK_INLINE CMatrix3f& MulInPlace(const CMatrix3f& in_matrix3);
00113 
00120     SICPPSDK_INLINE CMatrix3f& Mul(const CMatrix3f& in_matrix3A, const CMatrix3f& in_matrix3B);
00121 
00133     SICPPSDK_INLINE void Get(   float& io_00, float& io_01, float& io_02,
00134                                 float& io_10, float& io_11, float& io_12,
00135                                 float& io_20, float& io_21, float& io_22) const;
00136 
00148     SICPPSDK_INLINE void Set(   float in_00, float in_01, float in_02,
00149                                 float in_10, float in_11, float in_12,
00150                                 float in_20, float in_21, float in_22);
00151 
00155     SICPPSDK_INLINE void Set(const float in_Val[3][3]);
00156 
00160     SICPPSDK_INLINE float* Get();
00161 
00167     SICPPSDK_INLINE float GetValue(short in_sRow,short in_sCol )const;
00168 
00174     SICPPSDK_INLINE void SetValue(short in_sRow, short in_sCol, float in_Val );
00175 
00181     bool EpsilonEquals( const CMatrix3f& in_matrix3, float in_Epsilon ) const;
00182 
00187     SICPPSDK_INLINE bool Equals(const CMatrix3f& in_matrix3) const;
00188 
00194     SICPPSDK_INLINE bool operator ==(const CMatrix3f & in_matrix3 ) const;
00195 
00201     SICPPSDK_INLINE bool operator !=(const CMatrix3f & in_matrix3 ) const;
00202 
00210     SICPPSDK_INLINE bool operator < (const CMatrix3f& in_matrix3 )const;
00211 
00216     SICPPSDK_INLINE const float* Get() const;
00217 
00218 private:
00219     float m_Mat[3][3];
00220 
00221     SICPPSDK_INLINE void ComputeDetAndDetSize
00222     (
00223         const float in_fMat[3][3],
00224         float &out_fDet,
00225         float &out_fDetSize
00226     );
00227     SICPPSDK_INLINE void ComputeAdjoint
00228     (
00229         const float in_fMat[3][3],
00230         float out_fAdj[3][3]
00231     );
00232     SICPPSDK_INLINE bool ComputeInverse
00233     (
00234         const float in_fMat[3][3],
00235         float out_fInv[3][3],
00236         const bool in_bTransposeResult = false,
00237         const float in_fEps = MicroEPS
00238     );
00239 };
00240 
00241 SICPPSDK_INLINE CMatrix3f::CMatrix3f()
00242 {
00243     m_Mat[0][0] = 0.0;
00244     m_Mat[0][1] = 0.0;
00245     m_Mat[0][2] = 0.0;
00246     m_Mat[1][0] = 0.0;
00247     m_Mat[1][1] = 0.0;
00248     m_Mat[1][2] = 0.0;
00249     m_Mat[2][0] = 0.0;
00250     m_Mat[2][1] = 0.0;
00251     m_Mat[2][2] = 0.0;
00252 }
00253 
00254 SICPPSDK_INLINE CMatrix3f::CMatrix3f
00255 (
00256     float in_00, float in_01, float in_02,
00257     float in_10, float in_11, float in_12,
00258     float in_20, float in_21, float in_22
00259 )
00260 {
00261     m_Mat[0][0] = in_00;
00262     m_Mat[0][1] = in_01;
00263     m_Mat[0][2] = in_02;
00264     m_Mat[1][0] = in_10;
00265     m_Mat[1][1] = in_11;
00266     m_Mat[1][2] = in_12;
00267     m_Mat[2][0] = in_20;
00268     m_Mat[2][1] = in_21;
00269     m_Mat[2][2] = in_22;
00270 }
00271 
00272 SICPPSDK_INLINE CMatrix3f::CMatrix3f(const CMatrix3f& in_matrix3)
00273 {
00274     m_Mat[0][0] = in_matrix3.m_Mat[0][0];
00275     m_Mat[0][1] = in_matrix3.m_Mat[0][1];
00276     m_Mat[0][2] = in_matrix3.m_Mat[0][2];
00277     m_Mat[1][0] = in_matrix3.m_Mat[1][0];
00278     m_Mat[1][1] = in_matrix3.m_Mat[1][1];
00279     m_Mat[1][2] = in_matrix3.m_Mat[1][2];
00280     m_Mat[2][0] = in_matrix3.m_Mat[2][0];
00281     m_Mat[2][1] = in_matrix3.m_Mat[2][1];
00282     m_Mat[2][2] = in_matrix3.m_Mat[2][2];
00283 }
00284 
00285 SICPPSDK_INLINE CMatrix3f::~CMatrix3f()
00286 {}
00287 
00288 SICPPSDK_INLINE CMatrix3f& CMatrix3f::operator=( const CMatrix3f & in_matrix3 )
00289 {
00290     Set(in_matrix3.m_Mat);
00291     return *this;
00292 }
00293 
00294 SICPPSDK_INLINE CMatrix3f& CMatrix3f::operator *=(const CMatrix3f& in_matrix3)
00295 {
00296     return MulInPlace(in_matrix3);
00297 }
00298 
00299 SICPPSDK_INLINE CMatrix3f&  CMatrix3f::SetIdentity()
00300 {
00301     m_Mat[0][0] =  1.0;
00302     m_Mat[0][1] =  0.0;
00303     m_Mat[0][2] =  0.0;
00304     m_Mat[1][0] =  0.0;
00305     m_Mat[1][1] =  1.0;
00306     m_Mat[1][2] =  0.0;
00307     m_Mat[2][0] =  0.0;
00308     m_Mat[2][1] =  0.0;
00309     m_Mat[2][2] =  1.0;
00310     return *this;
00311 }
00312 
00313 SICPPSDK_INLINE bool CMatrix3f::Invert(const CMatrix3f& in_matrix3)
00314 {
00315     float Inv[3][3];
00316 
00317     if (ComputeInverse(in_matrix3.m_Mat, Inv))
00318     {
00319         Set( Inv);
00320         return true;
00321     }
00322     else // singular matrix
00323     {
00324         return false;
00325     }
00326 }
00327 
00328 SICPPSDK_INLINE bool CMatrix3f::TransposeInverseInPlace()
00329 {
00330     return TransposeInverse(*this);
00331 }
00332 
00333 SICPPSDK_INLINE bool CMatrix3f::TransposeInverse(const CMatrix3f& in_matrix3)
00334 {
00335     float TransInv[3][3];
00336 
00337     if(ComputeInverse(in_matrix3.m_Mat, TransInv, true))
00338     {
00339         Set(TransInv);
00340         return true;
00341     }
00342     else // singular matrix
00343     {
00344         return false;
00345     }
00346 }
00347 
00348 SICPPSDK_INLINE void CMatrix3f::TransposeInPlace()
00349 {
00350     Transpose(*this);
00351 }
00352 
00353 SICPPSDK_INLINE void CMatrix3f::Transpose(const CMatrix3f& in_matrix3)
00354 {
00355    float  fTempMat[3][3];
00356 
00357    for(int nR=0; nR<3; nR++)
00358    {
00359        for(int nC=0; nC<3; nC++)
00360        {
00361          fTempMat[nR][nC] = in_matrix3.m_Mat[nC][nR];
00362        }
00363    }
00364 
00365     Set(fTempMat);
00366 }
00367 
00368 SICPPSDK_INLINE CMatrix3f&  CMatrix3f::MulInPlace(const CMatrix3f& in_matrix3)
00369 {
00370     return Mul(*this,in_matrix3);
00371 }
00372 
00373 SICPPSDK_INLINE CMatrix3f& CMatrix3f::Mul
00374 (
00375     const CMatrix3f& in_matrix3A,
00376     const CMatrix3f& in_matrix3B
00377 )
00378 {
00379     float  fTempMat[3][3];
00380 
00381     for(int nR=0; nR<3; nR++)
00382     {
00383         for(int nC=0; nC<3; nC++)
00384         {
00385             fTempMat[nR][nC] =
00386                 in_matrix3A.m_Mat[nR][0] * in_matrix3B.m_Mat[0][nC] +
00387                 in_matrix3A.m_Mat[nR][1] * in_matrix3B.m_Mat[1][nC] +
00388                 in_matrix3A.m_Mat[nR][2] * in_matrix3B.m_Mat[2][nC];
00389         }
00390     }
00391     Set(fTempMat);
00392     return *this;
00393 }
00394 
00395 SICPPSDK_INLINE void CMatrix3f::Get
00396 (
00397     float& io_00, float& io_01, float& io_02,
00398     float& io_10, float& io_11, float& io_12,
00399     float& io_20, float& io_21, float& io_22
00400 ) const
00401 {
00402     io_00 = m_Mat[0][0];
00403     io_01 = m_Mat[0][1];
00404     io_02 = m_Mat[0][2];
00405     io_10 = m_Mat[1][0];
00406     io_11 = m_Mat[1][1];
00407     io_12 = m_Mat[1][2];
00408     io_20 = m_Mat[2][0];
00409     io_21 = m_Mat[2][1];
00410     io_22 = m_Mat[2][2];
00411 }
00412 
00413 SICPPSDK_INLINE void CMatrix3f::Set
00414 (
00415     float in_00, float in_01, float in_02,
00416     float in_10, float in_11, float in_12,
00417     float in_20, float in_21, float in_22
00418 )
00419 {
00420     m_Mat[0][0] = in_00;
00421     m_Mat[0][1] = in_01;
00422     m_Mat[0][2] = in_02;
00423     m_Mat[1][0] = in_10;
00424     m_Mat[1][1] = in_11;
00425     m_Mat[1][2] = in_12;
00426     m_Mat[2][0] = in_20;
00427     m_Mat[2][1] = in_21;
00428     m_Mat[2][2] = in_22;
00429 }
00430 
00431 SICPPSDK_INLINE void CMatrix3f::Set(const float in_Val[3][3])
00432 {
00433     m_Mat[0][0] = in_Val[0][0];
00434     m_Mat[0][1] = in_Val[0][1];
00435     m_Mat[0][2] = in_Val[0][2];
00436     m_Mat[1][0] = in_Val[1][0];
00437     m_Mat[1][1] = in_Val[1][1];
00438     m_Mat[1][2] = in_Val[1][2];
00439     m_Mat[2][0] = in_Val[2][0];
00440     m_Mat[2][1] = in_Val[2][1];
00441     m_Mat[2][2] = in_Val[2][2];
00442 }
00443 
00444 SICPPSDK_INLINE float* CMatrix3f::Get()
00445 {
00446     return &m_Mat[0][0];
00447 }
00448 
00449 SICPPSDK_INLINE const float* CMatrix3f::Get() const
00450 {
00451     return &m_Mat[0][0];
00452 }
00453 
00454 SICPPSDK_INLINE float CMatrix3f::GetValue(short in_sRow,short in_sCol ) const
00455 {
00456     bool l_bValidIndex =  ( in_sRow >=0 && in_sCol >= 0 && in_sRow <=2 && in_sCol <= 2);
00457     assert(l_bValidIndex);
00458 
00459     if(l_bValidIndex)
00460     {
00461         return m_Mat[in_sRow][in_sCol];
00462     }
00463     return 0.0;
00464 }
00465 
00466 SICPPSDK_INLINE void CMatrix3f::SetValue(short in_sRow, short in_sCol, float in_Val )
00467 {
00468     bool l_bValidIndex =  ( in_sRow >=0 && in_sCol >= 0 &&
00469                             in_sRow <=2 && in_sCol <= 2);
00470     assert(l_bValidIndex);
00471 
00472     if(l_bValidIndex)
00473     {
00474         m_Mat[in_sRow][in_sCol] = in_Val;
00475     }
00476 }
00477 
00478 SICPPSDK_INLINE bool CMatrix3f::Equals(const CMatrix3f& in_matrix3) const
00479 {
00480     return (this == &in_matrix3) ? true :
00481         m_Mat[0][0] == in_matrix3.m_Mat[0][0] &&
00482         m_Mat[0][1] == in_matrix3.m_Mat[0][1] &&
00483         m_Mat[0][2] == in_matrix3.m_Mat[0][2] &&
00484         m_Mat[1][0] == in_matrix3.m_Mat[1][0] &&
00485         m_Mat[1][1] == in_matrix3.m_Mat[1][1] &&
00486         m_Mat[1][2] == in_matrix3.m_Mat[1][2] &&
00487         m_Mat[2][0] == in_matrix3.m_Mat[2][0] &&
00488         m_Mat[2][1] == in_matrix3.m_Mat[2][1] &&
00489         m_Mat[2][2] == in_matrix3.m_Mat[2][2];
00490 }
00491 
00492 SICPPSDK_INLINE bool CMatrix3f::operator ==(const CMatrix3f & in_matrix3 ) const
00493 {
00494     return Equals( in_matrix3 );
00495 }
00496 
00497 SICPPSDK_INLINE bool CMatrix3f::operator !=(const CMatrix3f & in_matrix3 ) const
00498 {
00499     return ! Equals( in_matrix3 );
00500 }
00501 
00502 SICPPSDK_INLINE bool CMatrix3f::operator < (const CMatrix3f& in_matrix3 )const
00503 {
00504     if ( m_Mat[0][0] != in_matrix3.m_Mat[0][0] ) return m_Mat[0][0] < in_matrix3.m_Mat[0][0];
00505     if ( m_Mat[0][1] != in_matrix3.m_Mat[0][1] ) return m_Mat[0][1] < in_matrix3.m_Mat[0][1];
00506     if ( m_Mat[0][2] != in_matrix3.m_Mat[0][2] ) return m_Mat[0][2] < in_matrix3.m_Mat[0][2];
00507     if ( m_Mat[1][0] != in_matrix3.m_Mat[1][0] ) return m_Mat[1][0] < in_matrix3.m_Mat[1][0];
00508     if ( m_Mat[1][1] != in_matrix3.m_Mat[1][1] ) return m_Mat[1][1] < in_matrix3.m_Mat[1][1];
00509     if ( m_Mat[1][2] != in_matrix3.m_Mat[1][2] ) return m_Mat[1][2] < in_matrix3.m_Mat[1][2];
00510     if ( m_Mat[2][0] != in_matrix3.m_Mat[2][0] ) return m_Mat[2][0] < in_matrix3.m_Mat[2][0];
00511     if ( m_Mat[2][1] != in_matrix3.m_Mat[2][1] ) return m_Mat[2][1] < in_matrix3.m_Mat[2][1];
00512     if ( m_Mat[2][2] != in_matrix3.m_Mat[2][2] ) return m_Mat[2][2] < in_matrix3.m_Mat[2][2];
00513     return false;
00514 }
00515 
00516 SICPPSDK_INLINE void CMatrix3f::ComputeDetAndDetSize
00517 (
00518     const float in_fMat[3][3],
00519     float &out_fDet,
00520     float &out_fDetSize
00521 )
00522 {
00523     float fTemp;
00524     out_fDet = 0.0;
00525     out_fDetSize = 0.0;
00526 
00527     fTemp =  in_fMat[0][0] * in_fMat[1][1] * in_fMat[2][2];
00528     out_fDet += fTemp;
00529     out_fDetSize += fabs(fTemp);
00530 
00531     fTemp =  in_fMat[0][1] * in_fMat[1][2] * in_fMat[2][0];
00532     out_fDet += fTemp;
00533     out_fDetSize += fabs(fTemp);
00534 
00535     fTemp =  in_fMat[0][2] * in_fMat[1][0] * in_fMat[2][1];
00536     out_fDet += fTemp;
00537     out_fDetSize += fabs(fTemp);
00538 
00539     fTemp = -in_fMat[0][2] * in_fMat[1][1] * in_fMat[2][0];
00540     out_fDet += fTemp;
00541     out_fDetSize += fabs(fTemp);
00542 
00543     fTemp = -in_fMat[0][1] * in_fMat[1][0] * in_fMat[2][2];
00544     out_fDet += fTemp;
00545     out_fDetSize += fabs(fTemp);
00546 
00547     fTemp = -in_fMat[0][0] * in_fMat[1][2] * in_fMat[2][1];
00548     out_fDet += fTemp;
00549     out_fDetSize += fabs(fTemp);
00550 }
00551 
00552 SICPPSDK_INLINE void CMatrix3f::ComputeAdjoint
00553 (
00554     const float in_fMat[3][3],
00555     float out_fAdj[3][3]
00556 )
00557 {
00558     out_fAdj[0][0] = (in_fMat[1][1]*in_fMat[2][2] - in_fMat[1][2]*in_fMat[2][1]);
00559     out_fAdj[0][1] = - (in_fMat[0][1]*in_fMat[2][2] - in_fMat[0][2]*in_fMat[2][1]);
00560     out_fAdj[0][2] = (in_fMat[0][1]*in_fMat[1][2] - in_fMat[0][2]*in_fMat[1][1]);
00561 
00562     out_fAdj[1][0] = - (in_fMat[1][0]*in_fMat[2][2] - in_fMat[1][2]*in_fMat[2][0]);
00563     out_fAdj[1][1] = (in_fMat[0][0]*in_fMat[2][2] - in_fMat[0][2]*in_fMat[2][0]);
00564     out_fAdj[1][2] = - (in_fMat[0][0]*in_fMat[1][2] - in_fMat[0][2]*in_fMat[1][0]);
00565 
00566     out_fAdj[2][0] = (in_fMat[1][0]*in_fMat[2][1] - in_fMat[1][1]*in_fMat[2][0]);
00567     out_fAdj[2][1] = - (in_fMat[0][0]*in_fMat[2][1] - in_fMat[0][1]*in_fMat[2][0]);
00568     out_fAdj[2][2] = (in_fMat[0][0]*in_fMat[1][1] - in_fMat[0][1]*in_fMat[1][0]);
00569 }
00570 
00571 SICPPSDK_INLINE bool CMatrix3f::ComputeInverse
00572 (
00573     const float in_fMat[3][3],
00574     float out_fInv[3][3],
00575     const bool in_bTransposeResult,
00576     const float in_fEps
00577 )
00578 {
00579     float fAdj[3][3];
00580     float fDet=0.0, fDetSize=0.0, fInvDet;
00581 
00582     ComputeDetAndDetSize(in_fMat, fDet, fDetSize);
00583     if(fDetSize != 0.0 && fabs(fDet/fDetSize) >= in_fEps)
00584     {
00585         ComputeAdjoint(in_fMat, fAdj);
00586         fInvDet = 1.0f/fDet;
00587         if(in_bTransposeResult)
00588         {
00589             for(int nR=0; nR<3; nR++)
00590             {
00591                 for(int nC=0; nC<3; nC++)
00592                 {
00593                     out_fInv[nC][nR] = fAdj[nR][nC] * fInvDet;
00594                 }
00595             }
00596         }
00597         else
00598         {
00599             for(int nR=0; nR<3; nR++)
00600             {
00601                 for(int nC=0; nC<3; nC++)
00602                 {
00603                     out_fInv[nR][nC] = fAdj[nR][nC] * fInvDet;
00604                 }
00605             }
00606         }
00607         return true;
00608     }
00609     else
00610     {
00611         return false;
00612     }
00613 }
00614 
00615 };
00616 };
00617 
00618 #endif // __XSIMATRIX3F_H__