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 
00212 private:
00213     float m_Mat[3][3];
00214 
00215     SICPPSDK_INLINE void ComputeDetAndDetSize
00216     (
00217         const float in_fMat[3][3],
00218         float &out_fDet,
00219         float &out_fDetSize
00220     );
00221     SICPPSDK_INLINE void ComputeAdjoint
00222     (
00223         const float in_fMat[3][3],
00224         float out_fAdj[3][3]
00225     );
00226     SICPPSDK_INLINE bool ComputeInverse
00227     (
00228         const float in_fMat[3][3],
00229         float out_fInv[3][3],
00230         const bool in_bTransposeResult = false,
00231         const float in_fEps = MicroEPS
00232     );
00233 };
00234 
00235 SICPPSDK_INLINE CMatrix3f::CMatrix3f()
00236 {
00237     m_Mat[0][0] = 0.0;
00238     m_Mat[0][1] = 0.0;
00239     m_Mat[0][2] = 0.0;
00240     m_Mat[1][0] = 0.0;
00241     m_Mat[1][1] = 0.0;
00242     m_Mat[1][2] = 0.0;
00243     m_Mat[2][0] = 0.0;
00244     m_Mat[2][1] = 0.0;
00245     m_Mat[2][2] = 0.0;
00246 }
00247 
00248 SICPPSDK_INLINE CMatrix3f::CMatrix3f
00249 (
00250     float in_00, float in_01, float in_02,
00251     float in_10, float in_11, float in_12,
00252     float in_20, float in_21, float in_22
00253 )
00254 {
00255     m_Mat[0][0] = in_00;
00256     m_Mat[0][1] = in_01;
00257     m_Mat[0][2] = in_02;
00258     m_Mat[1][0] = in_10;
00259     m_Mat[1][1] = in_11;
00260     m_Mat[1][2] = in_12;
00261     m_Mat[2][0] = in_20;
00262     m_Mat[2][1] = in_21;
00263     m_Mat[2][2] = in_22;
00264 }
00265 
00266 SICPPSDK_INLINE CMatrix3f::CMatrix3f(const CMatrix3f& in_matrix3)
00267 {
00268     m_Mat[0][0] = in_matrix3.m_Mat[0][0];
00269     m_Mat[0][1] = in_matrix3.m_Mat[0][1];
00270     m_Mat[0][2] = in_matrix3.m_Mat[0][2];
00271     m_Mat[1][0] = in_matrix3.m_Mat[1][0];
00272     m_Mat[1][1] = in_matrix3.m_Mat[1][1];
00273     m_Mat[1][2] = in_matrix3.m_Mat[1][2];
00274     m_Mat[2][0] = in_matrix3.m_Mat[2][0];
00275     m_Mat[2][1] = in_matrix3.m_Mat[2][1];
00276     m_Mat[2][2] = in_matrix3.m_Mat[2][2];
00277 }
00278 
00279 SICPPSDK_INLINE CMatrix3f::~CMatrix3f()
00280 {}
00281 
00282 SICPPSDK_INLINE CMatrix3f& CMatrix3f::operator=( const CMatrix3f & in_matrix3 )
00283 {
00284     Set(in_matrix3.m_Mat);
00285     return *this;
00286 }
00287 
00288 SICPPSDK_INLINE CMatrix3f& CMatrix3f::operator *=(const CMatrix3f& in_matrix3)
00289 {
00290     return MulInPlace(in_matrix3);
00291 }
00292 
00293 SICPPSDK_INLINE CMatrix3f&  CMatrix3f::SetIdentity()
00294 {
00295     m_Mat[0][0] =  1.0;
00296     m_Mat[0][1] =  0.0;
00297     m_Mat[0][2] =  0.0;
00298     m_Mat[1][0] =  0.0;
00299     m_Mat[1][1] =  1.0;
00300     m_Mat[1][2] =  0.0;
00301     m_Mat[2][0] =  0.0;
00302     m_Mat[2][1] =  0.0;
00303     m_Mat[2][2] =  1.0;
00304     return *this;
00305 }
00306 
00307 SICPPSDK_INLINE bool CMatrix3f::Invert(const CMatrix3f& in_matrix3)
00308 {
00309     float Inv[3][3];
00310 
00311     if (ComputeInverse(in_matrix3.m_Mat, Inv))
00312     {
00313         Set( Inv);
00314         return true;
00315     }
00316     else // singular matrix
00317     {
00318         return false;
00319     }
00320 }
00321 
00322 SICPPSDK_INLINE bool CMatrix3f::TransposeInverseInPlace()
00323 {
00324     return TransposeInverse(*this);
00325 }
00326 
00327 SICPPSDK_INLINE bool CMatrix3f::TransposeInverse(const CMatrix3f& in_matrix3)
00328 {
00329     float TransInv[3][3];
00330 
00331     if(ComputeInverse(in_matrix3.m_Mat, TransInv, true))
00332     {
00333         Set(TransInv);
00334         return true;
00335     }
00336     else // singular matrix
00337     {
00338         return false;
00339     }
00340 }
00341 
00342 SICPPSDK_INLINE void CMatrix3f::TransposeInPlace()
00343 {
00344     Transpose(*this);
00345 }
00346 
00347 SICPPSDK_INLINE void CMatrix3f::Transpose(const CMatrix3f& in_matrix3)
00348 {
00349    float  fTempMat[3][3];
00350 
00351    for(int nR=0; nR<3; nR++)
00352    {
00353        for(int nC=0; nC<3; nC++)
00354        {
00355          fTempMat[nR][nC] = in_matrix3.m_Mat[nC][nR];
00356        }
00357    }
00358 
00359     Set(fTempMat);
00360 }
00361 
00362 SICPPSDK_INLINE CMatrix3f&  CMatrix3f::MulInPlace(const CMatrix3f& in_matrix3)
00363 {
00364     return Mul(*this,in_matrix3);
00365 }
00366 
00367 SICPPSDK_INLINE CMatrix3f& CMatrix3f::Mul
00368 (
00369     const CMatrix3f& in_matrix3A,
00370     const CMatrix3f& in_matrix3B
00371 )
00372 {
00373     float  fTempMat[3][3];
00374 
00375     for(int nR=0; nR<3; nR++)
00376     {
00377         for(int nC=0; nC<3; nC++)
00378         {
00379             fTempMat[nR][nC] =
00380                 in_matrix3A.m_Mat[nR][0] * in_matrix3B.m_Mat[0][nC] +
00381                 in_matrix3A.m_Mat[nR][1] * in_matrix3B.m_Mat[1][nC] +
00382                 in_matrix3A.m_Mat[nR][2] * in_matrix3B.m_Mat[2][nC];
00383         }
00384     }
00385     Set(fTempMat);
00386     return *this;
00387 }
00388 
00389 SICPPSDK_INLINE void CMatrix3f::Get
00390 (
00391     float& io_00, float& io_01, float& io_02,
00392     float& io_10, float& io_11, float& io_12,
00393     float& io_20, float& io_21, float& io_22
00394 ) const
00395 {
00396     io_00 = m_Mat[0][0];
00397     io_01 = m_Mat[0][1];
00398     io_02 = m_Mat[0][2];
00399     io_10 = m_Mat[1][0];
00400     io_11 = m_Mat[1][1];
00401     io_12 = m_Mat[1][2];
00402     io_20 = m_Mat[2][0];
00403     io_21 = m_Mat[2][1];
00404     io_22 = m_Mat[2][2];
00405 }
00406 
00407 SICPPSDK_INLINE void CMatrix3f::Set
00408 (
00409     float in_00, float in_01, float in_02,
00410     float in_10, float in_11, float in_12,
00411     float in_20, float in_21, float in_22
00412 )
00413 {
00414     m_Mat[0][0] = in_00;
00415     m_Mat[0][1] = in_01;
00416     m_Mat[0][2] = in_02;
00417     m_Mat[1][0] = in_10;
00418     m_Mat[1][1] = in_11;
00419     m_Mat[1][2] = in_12;
00420     m_Mat[2][0] = in_20;
00421     m_Mat[2][1] = in_21;
00422     m_Mat[2][2] = in_22;
00423 }
00424 
00425 SICPPSDK_INLINE void CMatrix3f::Set(const float in_Val[3][3])
00426 {
00427     m_Mat[0][0] = in_Val[0][0];
00428     m_Mat[0][1] = in_Val[0][1];
00429     m_Mat[0][2] = in_Val[0][2];
00430     m_Mat[1][0] = in_Val[1][0];
00431     m_Mat[1][1] = in_Val[1][1];
00432     m_Mat[1][2] = in_Val[1][2];
00433     m_Mat[2][0] = in_Val[2][0];
00434     m_Mat[2][1] = in_Val[2][1];
00435     m_Mat[2][2] = in_Val[2][2];
00436 }
00437 
00438 SICPPSDK_INLINE float* CMatrix3f::Get()
00439 {
00440     return &m_Mat[0][0];
00441 }
00442 
00443 SICPPSDK_INLINE float CMatrix3f::GetValue(short in_sRow,short in_sCol ) const
00444 {
00445     bool l_bValidIndex =  ( in_sRow >=0 && in_sCol >= 0 && in_sRow <=2 && in_sCol <= 2);
00446     assert(l_bValidIndex);
00447 
00448     if(l_bValidIndex)
00449     {
00450         return m_Mat[in_sRow][in_sCol];
00451     }
00452     return 0.0;
00453 }
00454 
00455 SICPPSDK_INLINE void CMatrix3f::SetValue(short in_sRow, short in_sCol, float in_Val )
00456 {
00457     bool l_bValidIndex =  ( in_sRow >=0 && in_sCol >= 0 &&
00458                             in_sRow <=2 && in_sCol <= 2);
00459     assert(l_bValidIndex);
00460 
00461     if(l_bValidIndex)
00462     {
00463         m_Mat[in_sRow][in_sCol] = in_Val;
00464     }
00465 }
00466 
00467 SICPPSDK_INLINE bool CMatrix3f::Equals(const CMatrix3f& in_matrix3) const
00468 {
00469     return (this == &in_matrix3) ? true :
00470         m_Mat[0][0] == in_matrix3.m_Mat[0][0] &&
00471         m_Mat[0][1] == in_matrix3.m_Mat[0][1] &&
00472         m_Mat[0][2] == in_matrix3.m_Mat[0][2] &&
00473         m_Mat[1][0] == in_matrix3.m_Mat[1][0] &&
00474         m_Mat[1][1] == in_matrix3.m_Mat[1][1] &&
00475         m_Mat[1][2] == in_matrix3.m_Mat[1][2] &&
00476         m_Mat[2][0] == in_matrix3.m_Mat[2][0] &&
00477         m_Mat[2][1] == in_matrix3.m_Mat[2][1] &&
00478         m_Mat[2][2] == in_matrix3.m_Mat[2][2];
00479 }
00480 
00481 SICPPSDK_INLINE bool CMatrix3f::operator ==(const CMatrix3f & in_matrix3 ) const
00482 {
00483     return Equals( in_matrix3 );
00484 }
00485 
00486 SICPPSDK_INLINE bool CMatrix3f::operator !=(const CMatrix3f & in_matrix3 ) const
00487 {
00488     return ! Equals( in_matrix3 );
00489 }
00490 
00491 SICPPSDK_INLINE bool CMatrix3f::operator < (const CMatrix3f& in_matrix3 )const
00492 {
00493     if ( m_Mat[0][0] != in_matrix3.m_Mat[0][0] ) return m_Mat[0][0] < in_matrix3.m_Mat[0][0];
00494     if ( m_Mat[0][1] != in_matrix3.m_Mat[0][1] ) return m_Mat[0][1] < in_matrix3.m_Mat[0][1];
00495     if ( m_Mat[0][2] != in_matrix3.m_Mat[0][2] ) return m_Mat[0][2] < in_matrix3.m_Mat[0][2];
00496     if ( m_Mat[1][0] != in_matrix3.m_Mat[1][0] ) return m_Mat[1][0] < in_matrix3.m_Mat[1][0];
00497     if ( m_Mat[1][1] != in_matrix3.m_Mat[1][1] ) return m_Mat[1][1] < in_matrix3.m_Mat[1][1];
00498     if ( m_Mat[1][2] != in_matrix3.m_Mat[1][2] ) return m_Mat[1][2] < in_matrix3.m_Mat[1][2];
00499     if ( m_Mat[2][0] != in_matrix3.m_Mat[2][0] ) return m_Mat[2][0] < in_matrix3.m_Mat[2][0];
00500     if ( m_Mat[2][1] != in_matrix3.m_Mat[2][1] ) return m_Mat[2][1] < in_matrix3.m_Mat[2][1];
00501     if ( m_Mat[2][2] != in_matrix3.m_Mat[2][2] ) return m_Mat[2][2] < in_matrix3.m_Mat[2][2];
00502     return false;
00503 }
00504 
00505 SICPPSDK_INLINE void CMatrix3f::ComputeDetAndDetSize
00506 (
00507     const float in_fMat[3][3],
00508     float &out_fDet,
00509     float &out_fDetSize
00510 )
00511 {
00512     float fTemp;
00513     out_fDet = 0.0;
00514     out_fDetSize = 0.0;
00515 
00516     fTemp =  in_fMat[0][0] * in_fMat[1][1] * in_fMat[2][2];
00517     out_fDet += fTemp;
00518     out_fDetSize += fabs(fTemp);
00519 
00520     fTemp =  in_fMat[0][1] * in_fMat[1][2] * in_fMat[2][0];
00521     out_fDet += fTemp;
00522     out_fDetSize += fabs(fTemp);
00523 
00524     fTemp =  in_fMat[0][2] * in_fMat[1][0] * in_fMat[2][1];
00525     out_fDet += fTemp;
00526     out_fDetSize += fabs(fTemp);
00527 
00528     fTemp = -in_fMat[0][2] * in_fMat[1][1] * in_fMat[2][0];
00529     out_fDet += fTemp;
00530     out_fDetSize += fabs(fTemp);
00531 
00532     fTemp = -in_fMat[0][1] * in_fMat[1][0] * in_fMat[2][2];
00533     out_fDet += fTemp;
00534     out_fDetSize += fabs(fTemp);
00535 
00536     fTemp = -in_fMat[0][0] * in_fMat[1][2] * in_fMat[2][1];
00537     out_fDet += fTemp;
00538     out_fDetSize += fabs(fTemp);
00539 }
00540 
00541 SICPPSDK_INLINE void CMatrix3f::ComputeAdjoint
00542 (
00543     const float in_fMat[3][3],
00544     float out_fAdj[3][3]
00545 )
00546 {
00547     out_fAdj[0][0] = (in_fMat[1][1]*in_fMat[2][2] - in_fMat[1][2]*in_fMat[2][1]);
00548     out_fAdj[0][1] = - (in_fMat[0][1]*in_fMat[2][2] - in_fMat[0][2]*in_fMat[2][1]);
00549     out_fAdj[0][2] = (in_fMat[0][1]*in_fMat[1][2] - in_fMat[0][2]*in_fMat[1][1]);
00550 
00551     out_fAdj[1][0] = - (in_fMat[1][0]*in_fMat[2][2] - in_fMat[1][2]*in_fMat[2][0]);
00552     out_fAdj[1][1] = (in_fMat[0][0]*in_fMat[2][2] - in_fMat[0][2]*in_fMat[2][0]);
00553     out_fAdj[1][2] = - (in_fMat[0][0]*in_fMat[1][2] - in_fMat[0][2]*in_fMat[1][0]);
00554 
00555     out_fAdj[2][0] = (in_fMat[1][0]*in_fMat[2][1] - in_fMat[1][1]*in_fMat[2][0]);
00556     out_fAdj[2][1] = - (in_fMat[0][0]*in_fMat[2][1] - in_fMat[0][1]*in_fMat[2][0]);
00557     out_fAdj[2][2] = (in_fMat[0][0]*in_fMat[1][1] - in_fMat[0][1]*in_fMat[1][0]);
00558 }
00559 
00560 SICPPSDK_INLINE bool CMatrix3f::ComputeInverse
00561 (
00562     const float in_fMat[3][3],
00563     float out_fInv[3][3],
00564     const bool in_bTransposeResult,
00565     const float in_fEps
00566 )
00567 {
00568     float fAdj[3][3];
00569     float fDet=0.0, fDetSize=0.0, fInvDet;
00570 
00571     ComputeDetAndDetSize(in_fMat, fDet, fDetSize);
00572     if(fDetSize != 0.0 && fabs(fDet/fDetSize) >= in_fEps)
00573     {
00574         ComputeAdjoint(in_fMat, fAdj);
00575         fInvDet = 1.0f/fDet;
00576         if(in_bTransposeResult)
00577         {
00578             for(int nR=0; nR<3; nR++)
00579             {
00580                 for(int nC=0; nC<3; nC++)
00581                 {
00582                     out_fInv[nC][nR] = fAdj[nR][nC] * fInvDet;
00583                 }
00584             }
00585         }
00586         else
00587         {
00588             for(int nR=0; nR<3; nR++)
00589             {
00590                 for(int nC=0; nC<3; nC++)
00591                 {
00592                     out_fInv[nR][nC] = fAdj[nR][nC] * fInvDet;
00593                 }
00594             }
00595         }
00596         return true;
00597     }
00598     else
00599     {
00600         return false;
00601     }
00602 }
00603 
00604 };
00605 };
00606 
00607 #endif // __XSIMATRIX3F_H__