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
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
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__