00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041
00042 #include <iostream>
00043 #include <iomanip>
00044
00045 #include <OSGLog.h>
00046
00047 OSG_BEGIN_NAMESPACE
00048
00076 #if defined(__hpux)
00077 template<class ValueTypeT>
00078 const UInt32 TransformationMatrix<ValueTypeT>::JacobiRank;
00079 #endif
00080
00081 template<class ValueTypeT>
00082 TransformationMatrix<ValueTypeT>
00083 TransformationMatrix<ValueTypeT>::_identityMatrix;
00084
00085
00086
00087
00088 template<class ValueTypeT> inline
00089 const TransformationMatrix<ValueTypeT> &
00090 TransformationMatrix<ValueTypeT>::identity(void)
00091 {
00092 return _identityMatrix;
00093 }
00094
00095
00096
00097
00098 template<class ValueTypeT> inline
00099 TransformationMatrix<ValueTypeT>::TransformationMatrix(void)
00100 {
00101 for(UInt32 i = 0; i < 4; i++)
00102 {
00103 _matrix[i][i] = TypeTraits<ValueType>::getOneElement();
00104 }
00105 }
00106
00107 template<class ValueTypeT> inline
00108 TransformationMatrix<ValueTypeT>::TransformationMatrix(
00109 const TransformationMatrix &source)
00110 {
00111 for(UInt32 i = 0; i < 4; i++)
00112 {
00113 _matrix[i] = source._matrix[i];
00114 }
00115 }
00116
00117 template<class ValueTypeT> inline
00118 TransformationMatrix<ValueTypeT>::TransformationMatrix(
00119 const VectorType3f &vector1,
00120 const VectorType3f &vector2,
00121 const VectorType3f &vector3)
00122 {
00123 _matrix[0].setValue(vector1);
00124 _matrix[1].setValue(vector2);
00125 _matrix[2].setValue(vector3);
00126 }
00127
00128 template<class ValueTypeT> inline
00129 TransformationMatrix<ValueTypeT>::TransformationMatrix(
00130 const VectorType3f &vector1,
00131 const VectorType3f &vector2,
00132 const VectorType3f &vector3,
00133 const VectorType3f &vector4)
00134 {
00135 _matrix[0].setValue(vector1);
00136 _matrix[1].setValue(vector2);
00137 _matrix[2].setValue(vector3);
00138 _matrix[3].setValue(vector4);
00139 }
00140
00141 template<class ValueTypeT> inline
00142 TransformationMatrix<ValueTypeT>::TransformationMatrix(
00143 const ValueTypeT rVal00,
00144 const ValueTypeT rVal10,
00145 const ValueTypeT rVal20,
00146 const ValueTypeT rVal30,
00147
00148 const ValueTypeT rVal01,
00149 const ValueTypeT rVal11,
00150 const ValueTypeT rVal21,
00151 const ValueTypeT rVal31,
00152
00153 const ValueTypeT rVal02,
00154 const ValueTypeT rVal12,
00155 const ValueTypeT rVal22,
00156 const ValueTypeT rVal32,
00157
00158 const ValueTypeT rVal03,
00159 const ValueTypeT rVal13,
00160 const ValueTypeT rVal23,
00161 const ValueTypeT rVal33)
00162 {
00163 _matrix[0].setValues(rVal00, rVal01, rVal02, rVal03);
00164 _matrix[1].setValues(rVal10, rVal11, rVal12, rVal13);
00165 _matrix[2].setValues(rVal20, rVal21, rVal22, rVal23);
00166 _matrix[3].setValues(rVal30, rVal31, rVal32, rVal33);
00167 }
00168
00169
00170
00171
00172 template<class ValueTypeT> inline
00173 TransformationMatrix<ValueTypeT>::~TransformationMatrix(void)
00174 {
00175 }
00176
00177
00178
00179
00180 template<class ValueTypeT> inline
00181 void TransformationMatrix<ValueTypeT>::setIdentity(void)
00182 {
00183 for(UInt32 i = 0; i < 4; i++)
00184 {
00185 _matrix[i].setNull();
00186 _matrix[i][i] = TypeTraits<ValueType>::getOneElement();
00187 }
00188 }
00189
00190 template<class ValueTypeT> inline
00191 void TransformationMatrix<ValueTypeT>::setValue(
00192 const TransformationMatrix &mat)
00193 {
00194 for(UInt32 i = 0; i < 4; i++)
00195 {
00196 _matrix[i] = mat._matrix[i];
00197 }
00198 }
00199
00200 template<class ValueTypeT> inline
00201 void TransformationMatrix<ValueTypeT>::setValue(const VectorType3f &vector1,
00202 const VectorType3f &vector2,
00203 const VectorType3f &vector3)
00204 {
00205 _matrix[0].setValue(vector1);
00206 _matrix[1].setValue(vector2);
00207 _matrix[2].setValue(vector3);
00208 }
00209
00210 template<class ValueTypeT> inline
00211 void TransformationMatrix<ValueTypeT>::setValue(const VectorType3f &vector1,
00212 const VectorType3f &vector2,
00213 const VectorType3f &vector3,
00214 const VectorType3f &vector4)
00215 {
00216 _matrix[0].setValue(vector1);
00217 _matrix[1].setValue(vector2);
00218 _matrix[2].setValue(vector3);
00219 _matrix[3].setValue(vector4);
00220 }
00221
00222 template<class ValueTypeT> inline
00223 void TransformationMatrix<ValueTypeT>::setValue(const ValueTypeT rVal00,
00224 const ValueTypeT rVal10,
00225 const ValueTypeT rVal20,
00226 const ValueTypeT rVal30,
00227
00228 const ValueTypeT rVal01,
00229 const ValueTypeT rVal11,
00230 const ValueTypeT rVal21,
00231 const ValueTypeT rVal31,
00232
00233 const ValueTypeT rVal02,
00234 const ValueTypeT rVal12,
00235 const ValueTypeT rVal22,
00236 const ValueTypeT rVal32,
00237
00238 const ValueTypeT rVal03,
00239 const ValueTypeT rVal13,
00240 const ValueTypeT rVal23,
00241 const ValueTypeT rVal33)
00242 {
00243 _matrix[0].setValues(rVal00, rVal01, rVal02, rVal03);
00244 _matrix[1].setValues(rVal10, rVal11, rVal12, rVal13);
00245 _matrix[2].setValues(rVal20, rVal21, rVal22, rVal23);
00246 _matrix[3].setValues(rVal30, rVal31, rVal32, rVal33);
00247 }
00248
00249 template<class ValueTypeT> inline
00250 void TransformationMatrix<ValueTypeT>::setValueTransposed(
00251 const ValueTypeT rVal00,
00252 const ValueTypeT rVal01,
00253 const ValueTypeT rVal02,
00254 const ValueTypeT rVal03,
00255
00256 const ValueTypeT rVal10,
00257 const ValueTypeT rVal11,
00258 const ValueTypeT rVal12,
00259 const ValueTypeT rVal13,
00260
00261 const ValueTypeT rVal20,
00262 const ValueTypeT rVal21,
00263 const ValueTypeT rVal22,
00264 const ValueTypeT rVal23,
00265
00266 const ValueTypeT rVal30,
00267 const ValueTypeT rVal31,
00268 const ValueTypeT rVal32,
00269 const ValueTypeT rVal33)
00270 {
00271 _matrix[0].setValues(rVal00, rVal01, rVal02, rVal03);
00272 _matrix[1].setValues(rVal10, rVal11, rVal12, rVal13);
00273 _matrix[2].setValues(rVal20, rVal21, rVal22, rVal23);
00274 _matrix[3].setValues(rVal30, rVal31, rVal32, rVal33);
00275 }
00276
00278
00279 template<class ValueTypeT> inline
00280 void TransformationMatrix<ValueTypeT>::setValue(const ValueTypeT *pMat,
00281 bool bTransposed)
00282 {
00283 const ValueTypeT *pTmpMat = pMat;
00284
00285 if(bTransposed == true)
00286 {
00287 for(UInt32 i = 0; i < 4; i++)
00288 {
00289 _matrix[i].setValue(pTmpMat);
00290
00291 pTmpMat += 4;
00292 }
00293 }
00294 else
00295 {
00296 for(UInt32 i = 0; i < 4; i++)
00297 {
00298 for(UInt32 j = 0; j < 4; j++)
00299 {
00300 _matrix[i][j] = pTmpMat[j * 4 + i];
00301 }
00302 }
00303 }
00304 }
00305
00307
00308 template<class ValueTypeT> inline
00309 void TransformationMatrix<ValueTypeT>::setValue(const VectorType *pMat)
00310 {
00311 for(UInt32 i = 0; i < 4; i++)
00312 {
00313 _matrix[i] = pMat[i];
00314 }
00315 }
00316
00317 #ifndef WIN32
00318
00320
00321 template<class ValueTypeT> inline
00322 void TransformationMatrix<ValueTypeT>::setValue(const VectorType3f *pMat)
00323 {
00324 for(UInt32 i = 0; i < 4; i++)
00325 {
00326 _matrix[i].setValue(pMat[i]);
00327 }
00328 }
00329
00330 #endif
00331
00336 template<class ValueTypeT> inline
00337 void TransformationMatrix<ValueTypeT>::setValue(const Char8 *str,
00338 bool bTransposed)
00339 {
00340 UInt32 i;
00341 UInt32 numOfToken = 16;
00342
00343 Char8 *c = const_cast<char*>(str);
00344
00345 Char8 *tokenC = 0;
00346 Char8 token[256];
00347
00348 ValueTypeT vec[16];
00349
00350 if( (str == NULL) ||
00351 (*str == '\0') )
00352 {
00353 setIdentity();
00354 return;
00355 }
00356
00357 for(i = 0; i < numOfToken; c++)
00358 {
00359 switch (*c)
00360 {
00361 case '\0':
00362 if (tokenC)
00363 {
00364 *tokenC = 0;
00365 vec[i++] = TypeTraits<ValueTypeT>::getFromString(token);
00366
00367 }
00368
00369 while (i < numOfToken)
00370 {
00371 vec[i++] = TypeTraits<ValueTypeT>::getZeroElement();
00372 }
00373
00374 break;
00375 case ' ':
00376 case '\t':
00377 case '\n':
00378 case ',':
00379 if (tokenC)
00380 {
00381 *tokenC = 0;
00382 vec[i++] = TypeTraits<ValueTypeT>::getFromString(token);
00383 tokenC = 0;
00384 }
00385 break;
00386 default:
00387 if (!tokenC)
00388 {
00389 tokenC = token;
00390 }
00391 *tokenC++ = *c;
00392 break;
00393 }
00394 }
00395
00396 if(bTransposed == true)
00397 {
00398 setValueTransposed(vec[0], vec[1], vec[2], vec[3],
00399 vec[4], vec[5], vec[6], vec[7],
00400 vec[8], vec[9], vec[10], vec[11],
00401 vec[12], vec[13], vec[14], vec[15]);
00402 }
00403 else
00404 {
00405 setValue(vec[0], vec[1], vec[2], vec[3],
00406 vec[4], vec[5], vec[6], vec[7],
00407 vec[8], vec[9], vec[10], vec[11],
00408 vec[12], vec[13], vec[14], vec[15]);
00409 }
00410 }
00411
00412
00413
00414
00416
00417 template<class ValueTypeT> inline
00418 ValueTypeT *TransformationMatrix<ValueTypeT>::getValues(void)
00419 {
00420 return _matrix[0].getValues();
00421 }
00422
00423 template<class ValueTypeT> inline
00424 const ValueTypeT *TransformationMatrix<ValueTypeT>::getValues(void) const
00425 {
00426 return _matrix[0].getValues();
00427 }
00428
00429
00430
00431
00433
00434 template<class ValueTypeT> inline
00435 void TransformationMatrix<ValueTypeT>::setScale(const ValueTypeT s)
00436 {
00437 _matrix[0][0] = s;
00438 _matrix[1][1] = s;
00439 _matrix[2][2] = s;
00440 }
00441
00443
00444 template<class ValueTypeT> inline
00445 void TransformationMatrix<ValueTypeT>::setScale(const ValueTypeT sx,
00446 const ValueTypeT sy,
00447 const ValueTypeT sz)
00448 {
00449 _matrix[0][0] = sx;
00450 _matrix[1][1] = sy;
00451 _matrix[2][2] = sz;
00452 }
00453
00455
00456 template<class ValueTypeT> inline
00457 void TransformationMatrix<ValueTypeT>::setScale(const VectorType3f &s)
00458 {
00459 _matrix[0][0] = s[0];
00460 _matrix[1][1] = s[1];
00461 _matrix[2][2] = s[2];
00462 }
00463
00465
00466 template<class ValueTypeT> inline
00467 void TransformationMatrix<ValueTypeT>::setTranslate(const ValueTypeT tx,
00468 const ValueTypeT ty,
00469 const ValueTypeT tz)
00470 {
00471 _matrix[3][0] = tx;
00472 _matrix[3][1] = ty;
00473 _matrix[3][2] = tz;
00474 }
00475
00477
00478 template<class ValueTypeT> inline
00479 void TransformationMatrix<ValueTypeT>::setTranslate(const VectorType3f &t)
00480 {
00481 _matrix[3].setValue(t);
00482 }
00483
00485
00486 template<class ValueTypeT> inline
00487 void TransformationMatrix<ValueTypeT>::setTranslate(const PointType3f &t)
00488 {
00489 _matrix[3].setValue(t);
00490 }
00491
00493
00494 template<class ValueTypeT> inline
00495 void TransformationMatrix<ValueTypeT>::setRotate(const QuaternionType &q)
00496 {
00497 q.getValuesOnly(*this);
00498 }
00499
00501
00502 template<class ValueTypeT> inline
00503 void TransformationMatrix<ValueTypeT>::setTransform(const VectorType3f &t)
00504 {
00505 setIdentity();
00506
00507 _matrix[3][0] = t[0];
00508 _matrix[3][1] = t[1];
00509 _matrix[3][2] = t[2];
00510
00511 }
00512
00514
00515 template<class ValueTypeT> inline
00516 void TransformationMatrix<ValueTypeT>::setTransform(const QuaternionType &r)
00517 {
00518
00519 r.getValue(*this);
00520 }
00521
00523
00524 template<class ValueTypeT> inline
00525 void TransformationMatrix<ValueTypeT>::setTransform(const VectorType3f &t,
00526 const QuaternionType &r)
00527 {
00528 r.getValuesOnly(*this);
00529
00530
00531 _matrix[0][3] = 0.0;
00532 _matrix[1][3] = 0.0;
00533 _matrix[2][3] = 0.0;
00534
00535 _matrix[3][0] = t[0];
00536 _matrix[3][1] = t[1];
00537 _matrix[3][2] = t[2];
00538 _matrix[3][3] = 1.0;
00539 }
00540
00542
00543 template<class ValueTypeT> inline
00544 void TransformationMatrix<ValueTypeT>::setTransform(const VectorType3f &t,
00545 const QuaternionType &r,
00546 const VectorType3f &s)
00547 {
00548
00549 r.getValuesOnly(*this);
00550
00551
00552 _matrix[0][0] *= s[0]; _matrix[0][1] *= s[0]; _matrix[0][2] *=s[0];
00553 _matrix[1][0] *= s[1]; _matrix[1][1] *= s[1]; _matrix[1][2] *=s[1];
00554 _matrix[2][0] *= s[2]; _matrix[2][1] *= s[2]; _matrix[2][2] *=s[2];
00555
00556 _matrix[0][3] = 0.0;
00557 _matrix[1][3] = 0.0;
00558 _matrix[2][3] = 0.0;
00559
00560 _matrix[3][0] = t[0];
00561 _matrix[3][1] = t[1];
00562 _matrix[3][2] = t[2];
00563 _matrix[3][3] = 1.0;
00564 }
00565
00567
00568 template<class ValueTypeT> inline
00569 void TransformationMatrix<ValueTypeT>::setTransform(const VectorType3f &t,
00570 const QuaternionType &r,
00571 const VectorType3f &s,
00572 const QuaternionType &so)
00573 {
00574 Matrix tmpMat1;
00575 Matrix tmpMat2;
00576
00577
00578 QuaternionType rg(r);
00579 rg.mult(so);
00580
00581
00582 QuaternionType soi(so);
00583 soi.invert();
00584
00585
00586 rg. getValue(tmpMat1);
00587 soi.getValue(tmpMat2);
00588
00589
00590 tmpMat1[0][0] *= s[0]; tmpMat1[0][1] *= s[0]; tmpMat1[0][2] *=s[0];
00591 tmpMat1[1][0] *= s[1]; tmpMat1[1][1] *= s[1]; tmpMat1[1][2] *=s[1];
00592 tmpMat1[2][0] *= s[2]; tmpMat1[2][1] *= s[2]; tmpMat1[2][2] *=s[2];
00593
00594 _matrix[0][0] =
00595 tmpMat2[0][0] * tmpMat1[0][0] +
00596 tmpMat2[0][1] * tmpMat1[1][0] +
00597 tmpMat2[0][2] * tmpMat1[2][0];
00598
00599 _matrix[0][1] =
00600 tmpMat2[0][0] * tmpMat1[0][1] +
00601 tmpMat2[0][1] * tmpMat1[1][1] +
00602 tmpMat2[0][2] * tmpMat1[2][1];
00603
00604 _matrix[0][2] =
00605 tmpMat2[0][0] * tmpMat1[0][2] +
00606 tmpMat2[0][1] * tmpMat1[1][2] +
00607 tmpMat2[0][2] * tmpMat1[2][2];
00608
00609 _matrix[0][3] = 0.0;
00610
00611
00612 _matrix[1][0] =
00613 tmpMat2[1][0] * tmpMat1[0][0] +
00614 tmpMat2[1][1] * tmpMat1[1][0] +
00615 tmpMat2[1][2] * tmpMat1[2][0];
00616
00617 _matrix[1][1] =
00618 tmpMat2[1][0] * tmpMat1[0][1] +
00619 tmpMat2[1][1] * tmpMat1[1][1] +
00620 tmpMat2[1][2] * tmpMat1[2][1];
00621
00622 _matrix[1][2] =
00623 tmpMat2[1][0] * tmpMat1[0][2] +
00624 tmpMat2[1][1] * tmpMat1[1][2] +
00625 tmpMat2[1][2] * tmpMat1[2][2];
00626
00627 _matrix[1][3] = 0.0;
00628
00629
00630 _matrix[2][0] =
00631 tmpMat2[2][0] * tmpMat1[0][0] +
00632 tmpMat2[2][1] * tmpMat1[1][0] +
00633 tmpMat2[2][2] * tmpMat1[2][0];
00634
00635 _matrix[2][1] =
00636 tmpMat2[2][0] * tmpMat1[0][1] +
00637 tmpMat2[2][1] * tmpMat1[1][1] +
00638 tmpMat2[2][2] * tmpMat1[2][1];
00639
00640 _matrix[2][2] =
00641 tmpMat2[2][0] * tmpMat1[0][2] +
00642 tmpMat2[2][1] * tmpMat1[1][2] +
00643 tmpMat2[2][2] * tmpMat1[2][2];
00644
00645 _matrix[2][3] = 0.0;
00646
00647 _matrix[3][0] = t[0];
00648 _matrix[3][1] = t[1];
00649 _matrix[3][2] = t[2];
00650 _matrix[3][3] = 1.0;
00651 }
00652
00659 template<class ValueTypeT> inline
00660 void TransformationMatrix<ValueTypeT>::setTransform(
00661 const VectorType3f &translation,
00662 const QuaternionType &rotation,
00663 const VectorType3f &scaleFactor,
00664 const QuaternionType &scaleOrientation,
00665 const VectorType3f ¢er)
00666 {
00667 Matrix tmpMat1;
00668 Matrix tmpMat2;
00669
00670
00671 VectorType3f tg(translation);
00672 tg += center;
00673
00674
00675 QuaternionType rg(rotation);
00676 rg *= scaleOrientation;
00677
00678
00679 QuaternionType soi(scaleOrientation);
00680 soi.invert();
00681
00682
00683 rg. getValue(tmpMat1);
00684 soi.getValue(tmpMat2);
00685
00686
00687
00688 tmpMat1[0][0] *= scaleFactor[0];
00689 tmpMat1[0][1] *= scaleFactor[0];
00690 tmpMat1[0][2] *= scaleFactor[0];
00691
00692 tmpMat1[1][0] *= scaleFactor[1];
00693 tmpMat1[1][1] *= scaleFactor[1];
00694 tmpMat1[1][2] *= scaleFactor[1];
00695
00696 tmpMat1[2][0] *= scaleFactor[2];
00697 tmpMat1[2][1] *= scaleFactor[2];
00698 tmpMat1[2][2] *= scaleFactor[2];
00699
00700 _matrix[0][0] =
00701 tmpMat2[0][0] * tmpMat1[0][0] +
00702 tmpMat2[0][1] * tmpMat1[1][0] +
00703 tmpMat2[0][2] * tmpMat1[2][0];
00704
00705 _matrix[0][1] =
00706 tmpMat2[0][0] * tmpMat1[0][1] +
00707 tmpMat2[0][1] * tmpMat1[1][1] +
00708 tmpMat2[0][2] * tmpMat1[2][1];
00709
00710 _matrix[0][2] =
00711 tmpMat2[0][0] * tmpMat1[0][2] +
00712 tmpMat2[0][1] * tmpMat1[1][2] +
00713 tmpMat2[0][2] * tmpMat1[2][2];
00714
00715 _matrix[0][3] = 0.0;
00716
00717
00718 _matrix[1][0] =
00719 tmpMat2[1][0] * tmpMat1[0][0] +
00720 tmpMat2[1][1] * tmpMat1[1][0] +
00721 tmpMat2[1][2] * tmpMat1[2][0];
00722
00723 _matrix[1][1] =
00724 tmpMat2[1][0] * tmpMat1[0][1] +
00725 tmpMat2[1][1] * tmpMat1[1][1] +
00726 tmpMat2[1][2] * tmpMat1[2][1];
00727
00728 _matrix[1][2] =
00729 tmpMat2[1][0] * tmpMat1[0][2] +
00730 tmpMat2[1][1] * tmpMat1[1][2] +
00731 tmpMat2[1][2] * tmpMat1[2][2];
00732
00733 _matrix[1][3] = 0.0;
00734
00735
00736 _matrix[2][0] =
00737 tmpMat2[2][0] * tmpMat1[0][0] +
00738 tmpMat2[2][1] * tmpMat1[1][0] +
00739 tmpMat2[2][2] * tmpMat1[2][0];
00740
00741 _matrix[2][1] =
00742 tmpMat2[2][0] * tmpMat1[0][1] +
00743 tmpMat2[2][1] * tmpMat1[1][1] +
00744 tmpMat2[2][2] * tmpMat1[2][1];
00745
00746 _matrix[2][2] =
00747 tmpMat2[2][0] * tmpMat1[0][2] +
00748 tmpMat2[2][1] * tmpMat1[1][2] +
00749 tmpMat2[2][2] * tmpMat1[2][2];
00750
00751 _matrix[2][3] = 0.0;
00752
00753
00754 _matrix[3][0] =
00755 _matrix[0][0] * -center[0] +
00756 _matrix[1][0] * -center[1] +
00757 _matrix[2][0] * -center[2] + tg[0];
00758
00759 _matrix[3][1] =
00760 _matrix[0][1] * -center[0] +
00761 _matrix[1][1] * -center[1] +
00762 _matrix[2][1] * -center[2] + tg[1];
00763
00764 _matrix[3][2] =
00765 _matrix[0][2] * -center[0] +
00766 _matrix[1][2] * -center[1] +
00767 _matrix[2][2] * -center[2] + tg[2];
00768
00769 _matrix[3][3] = 1.0;
00770
00771 }
00772
00773
00774
00775
00785 template<class ValueTypeT> inline
00786 void TransformationMatrix<ValueTypeT>::getTransform(
00787 VectorType3f &translation,
00788 QuaternionType &rotation,
00789 VectorType3f &scaleFactor,
00790 QuaternionType &scaleOrientation,
00791 const VectorType3f ¢er ) const
00792 {
00793 TransformationMatrix m;
00794 TransformationMatrix c;
00795
00796 m.setTranslate(-center);
00797
00798 m.mult(*this);
00799
00800 c.setTranslate(center);
00801
00802 m.mult(c);
00803
00804 m.getTransform(translation, rotation, scaleFactor, scaleOrientation);
00805 }
00806
00808
00809 template<class ValueTypeT> inline
00810 void TransformationMatrix<ValueTypeT>::getTransform(
00811 VectorType3f &translation,
00812 QuaternionType &rotation,
00813 VectorType3f &scaleFactor,
00814 QuaternionType &scaleOrientation) const
00815 {
00816 TransformationMatrix so;
00817 TransformationMatrix rot;
00818 TransformationMatrix proj;
00819
00820 this->factor(so, scaleFactor, rot, translation, proj);
00821
00822 so.transpose();
00823 scaleOrientation.setValue(so);
00824
00825
00826 rotation.setValue(rot);
00827
00828 }
00829
00836 template<class ValueTypeT> inline
00837 bool TransformationMatrix<ValueTypeT>::factor(TransformationMatrix &r,
00838 VectorType3f &s,
00839 TransformationMatrix &u,
00840 VectorType3f &t,
00841 TransformationMatrix &proj) const
00842 {
00843 Real64 det;
00844 Real64 det_sign;
00845 Real64 scratch;
00846 Int32 i;
00847 Int32 j;
00848 Int32 junk;
00849 TransformationMatrix a;
00850 TransformationMatrix aT;
00851 TransformationMatrix rT;
00852 TransformationMatrix b;
00853 TransformationMatrix si;
00854 ValueTypeT evalues [3];
00855 VectorType3f evectors[3];
00856
00857 a = *this;
00858
00859 proj.setIdentity();
00860
00861 scratch = 1.0;
00862
00863 for (i = 0; i < 3; i++)
00864 {
00865 for (j = 0; j < 3; j++)
00866 {
00867 a._matrix[i][j] *= ValueTypeT(scratch);
00868 }
00869
00870 t[i] = _matrix[3][i] * ValueTypeT(scratch);
00871
00872 a._matrix[3][i] = a._matrix[i][3] = 0.0;
00873 }
00874
00875 a._matrix[3][3] = 1.0;
00876
00877
00878
00879 det = a.det3();
00880
00881 det_sign = (det < 0.0 ? -1.0 : 1.0);
00882
00883 if(det_sign * det < 1e-12)
00884 return false;
00885
00886
00887
00888 aT.transposeFrom(a);
00889 b = a;
00890 b.mult(aT);
00891
00892 b.jacobi(evalues, evectors, junk);
00893
00894 r.setValue(evectors[0][0], evectors[0][1], evectors[0][2], 0.0,
00895 evectors[1][0], evectors[1][1], evectors[1][2], 0.0,
00896 evectors[2][0], evectors[2][1], evectors[2][2], 0.0,
00897 0.0, 0.0, 0.0, 1.0);
00898
00899
00900
00901 si.setIdentity();
00902
00903 for(i = 0; i < 3; i++)
00904 {
00905 s[i] = ValueTypeT(det_sign * osgsqrt(evalues[i]));
00906
00907 si._matrix[i][i] = 1.0f / s[i];
00908 }
00909
00910
00911
00912 rT.transposeFrom(r);
00913 u = r;
00914 u.mult(si);
00915 u.mult(rT);
00916 u.mult(a);
00917
00918 return true;
00919 }
00920
00921
00922
00927 template<class ValueTypeT> inline
00928 void TransformationMatrix<ValueTypeT>::multMatrixPnt(
00929 const PointType3f &src,
00930 PointType3f &dst) const
00931 {
00932 dst.setValues((src[0] * _matrix[0][0] +
00933 src[1] * _matrix[1][0] +
00934 src[2] * _matrix[2][0] +
00935 _matrix[3][0]),
00936 (src[0] * _matrix[0][1] +
00937 src[1] * _matrix[1][1] +
00938 src[2] * _matrix[2][1] +
00939 _matrix[3][1]),
00940 (src[0] * _matrix[0][2] +
00941 src[1] * _matrix[1][2] +
00942 src[2] * _matrix[2][2] +
00943 _matrix[3][2]));
00944 }
00945
00947
00948 template<class ValueTypeT> inline
00949 void TransformationMatrix<ValueTypeT>::multMatrixPnt(PointType3f &pnt) const
00950 {
00951 multMatrixPnt(pnt, pnt);
00952 }
00953
00958 template<class ValueTypeT> inline
00959 void TransformationMatrix<ValueTypeT>::multFullMatrixPnt(
00960 const PointType3f &src,
00961 PointType3f &dst) const
00962 {
00963 ValueTypeT w = src[0] * _matrix[0][3] +
00964 src[1] * _matrix[1][3] +
00965 src[2] * _matrix[2][3] +
00966 _matrix[3][3];
00967
00968 if( w == 0.0f )
00969 {
00970 SINFO << "multFullMatrixPnt: w == 0.0f!" << std::endl;
00971
00972 dst.setValues(0, 0, 0);
00973
00974 return;
00975 }
00976
00977
00978 w = ValueTypeT(1.)/w;
00979 dst.setValues((src[0] * _matrix[0][0] +
00980 src[1] * _matrix[1][0] +
00981 src[2] * _matrix[2][0] +
00982 _matrix[3][0]) * w,
00983 (src[0] * _matrix[0][1] +
00984 src[1] * _matrix[1][1] +
00985 src[2] * _matrix[2][1] +
00986 _matrix[3][1]) * w,
00987 (src[0] * _matrix[0][2] +
00988 src[1] * _matrix[1][2] +
00989 src[2] * _matrix[2][2] +
00990 _matrix[3][2]) * w);
00991 }
00992
00994
00995 template<class ValueTypeT> inline
00996 void TransformationMatrix<ValueTypeT>::multFullMatrixPnt(PointType3f &pnt)const
00997 {
00998 multFullMatrixPnt(pnt, pnt);
00999 }
01000
01005 template<class ValueTypeT> inline
01006 void TransformationMatrix<ValueTypeT>::multMatrixVec(
01007 const VectorType3f &src,
01008 VectorType3f &dst) const
01009 {
01010 dst.setValues((src[0] * _matrix[0][0] +
01011 src[1] * _matrix[1][0] +
01012 src[2] * _matrix[2][0]),
01013 (src[0] * _matrix[0][1] +
01014 src[1] * _matrix[1][1] +
01015 src[2] * _matrix[2][1]),
01016 (src[0] * _matrix[0][2] +
01017 src[1] * _matrix[1][2] +
01018 src[2] * _matrix[2][2]));
01019 }
01020
01021
01023
01024 template<class ValueTypeT> inline
01025 void TransformationMatrix<ValueTypeT>::multMatrixVec(VectorType3f &vec) const
01026 {
01027 multMatrixVec(vec, vec);
01028 }
01029
01034 template<class ValueTypeT> inline
01035 void TransformationMatrix<ValueTypeT>::multMatrixVec(
01036 const VectorType &src,
01037 VectorType &dst) const
01038 {
01039 dst.setValues((src[0] * _matrix[0][0] +
01040 src[1] * _matrix[1][0] +
01041 src[2] * _matrix[2][0] +
01042 src[3] * _matrix[3][0]),
01043 (src[0] * _matrix[0][1] +
01044 src[1] * _matrix[1][1] +
01045 src[2] * _matrix[2][1] +
01046 src[3] * _matrix[3][1]),
01047 (src[0] * _matrix[0][2] +
01048 src[1] * _matrix[1][2] +
01049 src[2] * _matrix[2][2] +
01050 src[3] * _matrix[3][2]),
01051 (src[0] * _matrix[0][3] +
01052 src[1] * _matrix[1][3] +
01053 src[2] * _matrix[2][3] +
01054 src[3] * _matrix[3][3]));
01055 }
01056
01057
01059
01060 template<class ValueTypeT> inline
01061 void TransformationMatrix<ValueTypeT>::multMatrixVec(VectorType &vec) const
01062 {
01063 multMatrixVec(vec, vec);
01064 }
01065
01070 template<class ValueTypeT> inline
01071 void TransformationMatrix<ValueTypeT>::mult(const PointType3f &src,
01072 PointType3f &dest) const
01073 {
01074 multMatrixPnt(src, dest);
01075 }
01076
01078
01079 template<class ValueTypeT> inline
01080 void TransformationMatrix<ValueTypeT>::mult(PointType3f &pnt) const
01081 {
01082 multMatrixPnt(pnt, pnt);
01083 }
01084
01089 template<class ValueTypeT> inline
01090 void TransformationMatrix<ValueTypeT>::mult(const VectorType3f &src,
01091 VectorType3f &dest) const
01092 {
01093 multMatrixVec(src, dest);
01094 }
01095
01097
01098 template<class ValueTypeT> inline
01099 void TransformationMatrix<ValueTypeT>::mult(VectorType3f &vec) const
01100 {
01101 multMatrixVec(vec, vec);
01102 }
01103
01104
01105
01110 template<class ValueTypeT> inline
01111 void TransformationMatrix<ValueTypeT>::multPntMatrix(
01112 const PointType3f &src,
01113 PointType3f &dst) const
01114 {
01115 dst.setValues((src[0] * _matrix[0][0] +
01116 src[1] * _matrix[0][1] +
01117 src[2] * _matrix[0][2] +
01118 _matrix[0][3]),
01119 (src[0] * _matrix[1][0] +
01120 src[1] * _matrix[1][1] +
01121 src[2] * _matrix[1][2] +
01122 _matrix[1][3]),
01123 (src[0] * _matrix[2][0] +
01124 src[1] * _matrix[2][1] +
01125 src[2] * _matrix[2][2] +
01126 _matrix[2][3]));
01127 }
01128
01130
01131 template<class ValueTypeT> inline
01132 void TransformationMatrix<ValueTypeT>::multPntMatrix(PointType3f &pnt) const
01133 {
01134 multPntMatrix(pnt, pnt);
01135 }
01136
01141 template<class ValueTypeT> inline
01142 void TransformationMatrix<ValueTypeT>::multPntFullMatrix(
01143 const PointType3f &src,
01144 PointType3f &dst) const
01145 {
01146 ValueTypeT w = src[0] * _matrix[3][0] +
01147 src[1] * _matrix[3][1] +
01148 src[2] * _matrix[3][2] +
01149 _matrix[3][3];
01150
01151 if( w == 0.0f )
01152 {
01153 SINFO << "multFullMatrixPnt: w == 0.0f!" << std::endl;
01154
01155 dst.setValues(0, 0, 0);
01156
01157 return;
01158 }
01159
01160 w = 1./w;
01161
01162 dst.setValues((src[0] * _matrix[0][0] +
01163 src[1] * _matrix[0][1] +
01164 src[2] * _matrix[0][2] +
01165 _matrix[0][3]) * w,
01166 (src[0] * _matrix[1][0] +
01167 src[1] * _matrix[1][1] +
01168 src[2] * _matrix[1][2] +
01169 _matrix[1][3]) * w,
01170 (src[0] * _matrix[2][0] +
01171 src[1] * _matrix[2][1] +
01172 src[2] * _matrix[2][2] +
01173 _matrix[2][3]) * w);
01174 }
01175
01177
01178 template<class ValueTypeT> inline
01179 void TransformationMatrix<ValueTypeT>::multPntFullMatrix(PointType3f &pnt)const
01180 {
01181 multPntFullMatrix(pnt, pnt);
01182 }
01183
01188 template<class ValueTypeT> inline
01189 void TransformationMatrix<ValueTypeT>::multVecMatrix(
01190 const VectorType3f &src,
01191 VectorType3f &dst) const
01192 {
01193 dst.setValues((src[0] * _matrix[0][0] +
01194 src[1] * _matrix[0][1] +
01195 src[2] * _matrix[0][2]),
01196 (src[0] * _matrix[1][0] +
01197 src[1] * _matrix[1][1] +
01198 src[2] * _matrix[1][2]),
01199 (src[0] * _matrix[2][0] +
01200 src[1] * _matrix[2][1] +
01201 src[2] * _matrix[2][2]));
01202 }
01203
01205
01206 template<class ValueTypeT> inline
01207 void TransformationMatrix<ValueTypeT>::multVecMatrix(VectorType3f &vec) const
01208 {
01209 multVecMatrix(vec, vec);
01210 }
01211
01212
01213
01218 template<class ValueTypeT> inline
01219 bool TransformationMatrix<ValueTypeT>::equals(
01220 const TransformationMatrix &matrix,
01221 const ValueType tolerance) const
01222 {
01223 UInt32 i;
01224 bool returnValue = true;
01225
01226 for(i = 0; i < 4; i++)
01227 {
01228 returnValue &= _matrix[i].equals(matrix._matrix[i], tolerance);
01229
01230 if(returnValue == false)
01231 break;
01232 }
01233
01234 return returnValue;
01235 }
01236
01238
01239 template<class ValueTypeT> inline
01240 ValueTypeT TransformationMatrix<ValueTypeT>::det3(void) const
01241 {
01242 return (_matrix[0][0] * _matrix[1][1] * _matrix[2][2] +
01243 _matrix[0][1] * _matrix[1][2] * _matrix[2][0] +
01244 _matrix[0][2] * _matrix[1][0] * _matrix[2][1] -
01245 _matrix[0][2] * _matrix[1][1] * _matrix[2][0] -
01246 _matrix[0][1] * _matrix[1][0] * _matrix[2][2] -
01247 _matrix[0][0] * _matrix[1][2] * _matrix[2][1]);
01248 }
01249
01251
01252 template<class ValueTypeT> inline
01253 ValueTypeT TransformationMatrix<ValueTypeT>::det (void) const
01254 {
01255 ValueTypeT
01256 a1, a2, a3, a4,
01257 b1, b2, b3, b4,
01258 c1, c2, c3, c4,
01259 d1, d2, d3, d4;
01260
01261 a1 = _matrix[0][0];
01262 b1 = _matrix[1][0];
01263 c1 = _matrix[2][0];
01264 d1 = _matrix[3][0];
01265
01266 a2 = _matrix[0][1];
01267 b2 = _matrix[1][1];
01268 c2 = _matrix[2][1];
01269 d2 = _matrix[3][1];
01270
01271 a3 = _matrix[0][2];
01272 b3 = _matrix[1][2];
01273 c3 = _matrix[2][2];
01274 d3 = _matrix[3][2];
01275
01276 a4 = _matrix[0][3];
01277 b4 = _matrix[1][3];
01278 c4 = _matrix[2][3];
01279 d4 = _matrix[3][3];
01280
01281 return( a1 * det3(b2, b3, b4, c2, c3, c4, d2, d3, d4)
01282 - b1 * det3(a2, a3, a4, c2, c3, c4, d2, d3, d4)
01283 + c1 * det3(a2, a3, a4, b2, b3, b4, d2, d3, d4)
01284 - d1 * det3(a2, a3, a4, b2, b3, b4, c2, c3, c4));
01285
01286 }
01287
01288
01289
01290
01295 template<class ValueTypeT> inline
01296 bool TransformationMatrix<ValueTypeT>::inverse(
01297 TransformationMatrix &result) const
01298 {
01299 ValueTypeT rDet;
01300
01301 ValueTypeT
01302 a1, a2, a3, a4,
01303 b1, b2, b3, b4,
01304 c1, c2, c3, c4,
01305 d1, d2, d3, d4;
01306
01307 a1 = _matrix[0][0];
01308 b1 = _matrix[1][0];
01309 c1 = _matrix[2][0];
01310 d1 = _matrix[3][0];
01311
01312 a2 = _matrix[0][1];
01313 b2 = _matrix[1][1];
01314 c2 = _matrix[2][1];
01315 d2 = _matrix[3][1];
01316
01317 a3 = _matrix[0][2];
01318 b3 = _matrix[1][2];
01319 c3 = _matrix[2][2];
01320 d3 = _matrix[3][2];
01321
01322 a4 = _matrix[0][3];
01323 b4 = _matrix[1][3];
01324 c4 = _matrix[2][3];
01325 d4 = _matrix[3][3];
01326
01327 rDet = det();
01328
01329 if(osgabs(rDet) < 1E-30)
01330 {
01331 #ifdef OSG_PRINT_MATHERR
01332 fprintf(stderr, "invertMatrix: Singular matrix, no inverse!\n");
01333 #endif
01334 result.setIdentity();
01335
01336 return false;
01337 }
01338
01339 rDet = 1.f / rDet;
01340
01341 result[0][0] = det3(b2, b3, b4, c2, c3,
01342 c4, d2, d3, d4) * rDet;
01343 result[0][1] = - det3(a2, a3, a4, c2, c3, c4,
01344 d2, d3, d4) * rDet;
01345 result[0][2] = det3(a2, a3, a4, b2, b3, b4,
01346 d2, d3, d4) * rDet;
01347 result[0][3] = - det3(a2, a3, a4, b2, b3, b4,
01348 c2, c3, c4) * rDet;
01349
01350 result[1][0] = - det3(b1, b3, b4, c1, c3, c4,
01351 d1, d3, d4) * rDet;
01352 result[1][1] = det3(a1, a3, a4, c1, c3, c4,
01353 d1, d3, d4) * rDet;
01354 result[1][2] = - det3(a1, a3, a4, b1, b3, b4,
01355 d1, d3, d4) * rDet;
01356 result[1][3] = det3(a1, a3, a4, b1, b3, b4,
01357 c1, c3, c4) * rDet;
01358
01359 result[2][0] = det3(b1, b2, b4, c1, c2, c4,
01360 d1, d2, d4) * rDet;
01361 result[2][1] = - det3(a1, a2, a4, c1, c2, c4,
01362 d1, d2, d4) * rDet;
01363 result[2][2] = det3(a1, a2, a4, b1, b2, b4,
01364 d1, d2, d4) * rDet;
01365 result[2][3] = - det3(a1, a2, a4, b1, b2, b4,
01366 c1, c2, c4) * rDet;
01367
01368 result[3][0] = - det3(b1, b2, b3, c1, c2, c3,
01369 d1, d2, d3) * rDet;
01370 result[3][1] = det3(a1, a2, a3, c1, c2, c3,
01371 d1, d2, d3) * rDet;
01372 result[3][2] = - det3(a1, a2, a3, b1, b2, b3,
01373 d1, d2, d3) * rDet;
01374 result[3][3] = det3(a1, a2, a3, b1, b2, b3,
01375 c1, c2, c3) * rDet;
01376
01377 return true;
01378 }
01379
01384 template<class ValueTypeT> inline
01385 bool TransformationMatrix<ValueTypeT>::invert(void)
01386 {
01387 ValueTypeT rDet;
01388 TransformationMatrix result;
01389
01390 ValueTypeT
01391 a1, a2, a3, a4,
01392 b1, b2, b3, b4,
01393 c1, c2, c3, c4,
01394 d1, d2, d3, d4;
01395
01396 a1 = _matrix[0][0];
01397 b1 = _matrix[1][0];
01398 c1 = _matrix[2][0];
01399 d1 = _matrix[3][0];
01400
01401 a2 = _matrix[0][1];
01402 b2 = _matrix[1][1];
01403 c2 = _matrix[2][1];
01404 d2 = _matrix[3][1];
01405
01406 a3 = _matrix[0][2];
01407 b3 = _matrix[1][2];
01408 c3 = _matrix[2][2];
01409 d3 = _matrix[3][2];
01410
01411 a4 = _matrix[0][3];
01412 b4 = _matrix[1][3];
01413 c4 = _matrix[2][3];
01414 d4 = _matrix[3][3];
01415
01416 rDet = det();
01417
01418 if(osgabs(rDet) < 1E-30)
01419 {
01420 #ifdef OSG_PRINT_MATHERR
01421 fprintf(stderr, "invertMatrix: Singular matrix, no inverse!\n");
01422 #endif
01423 setIdentity();
01424
01425 return false;
01426 }
01427
01428 rDet = 1.f / rDet;
01429
01430 result[0][0] = det3(b2, b3, b4, c2, c3,
01431 c4, d2, d3, d4) * rDet;
01432 result[0][1] = - det3(a2, a3, a4, c2, c3, c4,
01433 d2, d3, d4) * rDet;
01434 result[0][2] = det3(a2, a3, a4, b2, b3, b4,
01435 d2, d3, d4) * rDet;
01436 result[0][3] = - det3(a2, a3, a4, b2, b3, b4,
01437 c2, c3, c4) * rDet;
01438
01439 result[1][0] = - det3(b1, b3, b4, c1, c3, c4,
01440 d1, d3, d4) * rDet;
01441 result[1][1] = det3(a1, a3, a4, c1, c3, c4,
01442 d1, d3, d4) * rDet;
01443 result[1][2] = - det3(a1, a3, a4, b1, b3, b4,
01444 d1, d3, d4) * rDet;
01445 result[1][3] = det3(a1, a3, a4, b1, b3, b4,
01446 c1, c3, c4) * rDet;
01447
01448 result[2][0] = det3(b1, b2, b4, c1, c2, c4,
01449 d1, d2, d4) * rDet;
01450 result[2][1] = - det3(a1, a2, a4, c1, c2, c4,
01451 d1, d2, d4) * rDet;
01452 result[2][2] = det3(a1, a2, a4, b1, b2, b4,
01453 d1, d2, d4) * rDet;
01454 result[2][3] = - det3(a1, a2, a4, b1, b2, b4,
01455 c1, c2, c4) * rDet;
01456
01457 result[3][0] = - det3(b1, b2, b3, c1, c2, c3,
01458 d1, d2, d3) * rDet;
01459 result[3][1] = det3(a1, a2, a3, c1, c2, c3,
01460 d1, d2, d3) * rDet;
01461 result[3][2] = - det3(a1, a2, a3, b1, b2, b3,
01462 d1, d2, d3) * rDet;
01463 result[3][3] = det3(a1, a2, a3, b1, b2, b3,
01464 c1, c2, c3) * rDet;
01465
01466 *this = result;
01467
01468 return true;
01469 }
01470
01475 template<class ValueTypeT> inline
01476 bool TransformationMatrix<ValueTypeT>::invertFrom(
01477 const TransformationMatrix &matrix)
01478 {
01479 ValueTypeT rDet;
01480
01481 ValueTypeT
01482 a1, a2, a3, a4,
01483 b1, b2, b3, b4,
01484 c1, c2, c3, c4,
01485 d1, d2, d3, d4;
01486
01487 a1 = matrix._matrix[0][0];
01488 b1 = matrix._matrix[1][0];
01489 c1 = matrix._matrix[2][0];
01490 d1 = matrix._matrix[3][0];
01491
01492 a2 = matrix._matrix[0][1];
01493 b2 = matrix._matrix[1][1];
01494 c2 = matrix._matrix[2][1];
01495 d2 = matrix._matrix[3][1];
01496
01497 a3 = matrix._matrix[0][2];
01498 b3 = matrix._matrix[1][2];
01499 c3 = matrix._matrix[2][2];
01500 d3 = matrix._matrix[3][2];
01501
01502 a4 = matrix._matrix[0][3];
01503 b4 = matrix._matrix[1][3];
01504 c4 = matrix._matrix[2][3];
01505 d4 = matrix._matrix[3][3];
01506
01507 rDet = matrix.det();
01508
01509 if (osgabs(rDet) < 1E-30)
01510 {
01511 #ifdef OSG_PRINT_MATHERR
01512 fprintf(stderr, "invertMatrix: Singular matrix, no inverse!\n");
01513 #endif
01514 setIdentity();
01515
01516 return false;
01517 }
01518
01519 rDet = 1.f / rDet;
01520
01521 _matrix[0][0] = det3(b2, b3, b4, c2, c3,
01522 c4, d2, d3, d4) * rDet;
01523 _matrix[0][1] = - det3(a2, a3, a4, c2, c3, c4,
01524 d2, d3, d4) * rDet;
01525 _matrix[0][2] = det3(a2, a3, a4, b2, b3, b4,
01526 d2, d3, d4) * rDet;
01527 _matrix[0][3] = - det3(a2, a3, a4, b2, b3, b4,
01528 c2, c3, c4) * rDet;
01529
01530 _matrix[1][0] = - det3(b1, b3, b4, c1, c3, c4,
01531 d1, d3, d4) * rDet;
01532 _matrix[1][1] = det3(a1, a3, a4, c1, c3, c4,
01533 d1, d3, d4) * rDet;
01534 _matrix[1][2] = - det3(a1, a3, a4, b1, b3, b4,
01535 d1, d3, d4) * rDet;
01536 _matrix[1][3] = det3(a1, a3, a4, b1, b3, b4,
01537 c1, c3, c4) * rDet;
01538
01539 _matrix[2][0] = det3(b1, b2, b4, c1, c2, c4,
01540 d1, d2, d4) * rDet;
01541 _matrix[2][1] = - det3(a1, a2, a4, c1, c2, c4,
01542 d1, d2, d4) * rDet;
01543 _matrix[2][2] = det3(a1, a2, a4, b1, b2, b4,
01544 d1, d2, d4) * rDet;
01545 _matrix[2][3] = - det3(a1, a2, a4, b1, b2, b4,
01546 c1, c2, c4) * rDet;
01547
01548 _matrix[3][0] = - det3(b1, b2, b3, c1, c2, c3,
01549 d1, d2, d3) * rDet;
01550 _matrix[3][1] = det3(a1, a2, a3, c1, c2, c3,
01551 d1, d2, d3) * rDet;
01552 _matrix[3][2] = - det3(a1, a2, a3, b1, b2, b3,
01553 d1, d2, d3) * rDet;
01554 _matrix[3][3] = det3(a1, a2, a3, b1, b2, b3,
01555 c1, c2, c3) * rDet;
01556
01557 return true;
01558 }
01559
01560 template<class ValueTypeT> inline
01561 bool TransformationMatrix<ValueTypeT>::inverse3(
01562 TransformationMatrix &result) const
01563 {
01564 ValueTypeT rDet = det3();
01565
01566 if(osgabs(rDet) < 1E-20)
01567 {
01568 #ifdef OSG_PRINT_MATHERR
01569 fprintf(stderr, "inverse3: matrix singular, no inverse!\n");
01570 #endif
01571
01572 result.setIdentity();
01573
01574 return false;
01575 }
01576
01577 rDet = 1.0f / rDet;
01578
01579 result[0][0] = det2(_matrix[1][1],
01580 _matrix[1][2],
01581 _matrix[2][1],
01582 _matrix[2][2]) * rDet;
01583 result[0][1] = - det2(_matrix[0][1],
01584 _matrix[0][2],
01585 _matrix[2][1],
01586 _matrix[2][2]) * rDet;
01587 result[0][2] = det2(_matrix[0][1],
01588 _matrix[0][2],
01589 _matrix[1][1],
01590 _matrix[1][2]) * rDet;
01591
01592 result[1][0] = - det2(_matrix[1][0],
01593 _matrix[1][2],
01594 _matrix[2][0],
01595 _matrix[2][2]) * rDet;
01596 result[1][1] = det2(_matrix[0][0],
01597 _matrix[0][2],
01598 _matrix[2][0],
01599 _matrix[2][2]) * rDet;
01600 result[1][2] = - det2(_matrix[0][0],
01601 _matrix[0][2],
01602 _matrix[1][0],
01603 _matrix[1][2]) * rDet;
01604
01605 result[2][0] = det2(_matrix[1][0],
01606 _matrix[1][1],
01607 _matrix[2][0],
01608 _matrix[2][1]) * rDet;
01609 result[2][1] = - det2(_matrix[0][0],
01610 _matrix[0][1],
01611 _matrix[2][0],
01612 _matrix[2][1]) * rDet;
01613 result[2][2] = det2(_matrix[0][0],
01614 _matrix[0][1],
01615 _matrix[1][0],
01616 _matrix[1][1]) * rDet;
01617
01618 result[3][0] =
01619 result[3][1] =
01620 result[3][2] = TypeTraits<ValueType>::getZeroElement();
01621
01622 result[3][3] = TypeTraits<ValueType>::getOneElement();
01623
01624 return true;
01625 }
01626
01627 template<class ValueTypeT> inline
01628 bool TransformationMatrix<ValueTypeT>::invert3(void)
01629 {
01630 ValueTypeT rDet = det3();
01631 TransformationMatrix result;
01632
01633 if(osgabs(rDet) < 1E-20)
01634 {
01635 #ifdef OSG_PRINT_MATHERR
01636 fprintf(stderr, "invert3: matrix singular, no inverse!\n");
01637 #endif
01638 result.setIdentity();
01639
01640 return false;
01641 }
01642
01643 rDet = 1.0f / rDet;
01644
01645 result[0][0] = det2(_matrix[1][1],
01646 _matrix[1][2],
01647 _matrix[2][1],
01648 _matrix[2][2]) * rDet;
01649 result[0][1] = - det2(_matrix[0][1],
01650 _matrix[0][2],
01651 _matrix[2][1],
01652 _matrix[2][2]) * rDet;
01653 result[0][2] = det2(_matrix[0][1],
01654 _matrix[0][2],
01655 _matrix[1][1],
01656 _matrix[1][2]) * rDet;
01657
01658 result[1][0] = - det2(_matrix[1][0],
01659 _matrix[1][2],
01660 _matrix[2][0],
01661 _matrix[2][2]) * rDet;
01662 result[1][1] = det2(_matrix[0][0],
01663 _matrix[0][2],
01664 _matrix[2][0],
01665 _matrix[2][2]) * rDet;
01666 result[1][2] = - det2(_matrix[0][0],
01667 _matrix[0][2],
01668 _matrix[1][0],
01669 _matrix[1][2]) * rDet;
01670
01671 result[2][0] = det2(_matrix[1][0],
01672 _matrix[1][1],
01673 _matrix[2][0],
01674 _matrix[2][1]) * rDet;
01675 result[2][1] = - det2(_matrix[0][0],
01676 _matrix[0][1],
01677 _matrix[2][0],
01678 _matrix[2][1]) * rDet;
01679 result[2][2] = det2(_matrix[0][0],
01680 _matrix[0][1],
01681 _matrix[1][0],
01682 _matrix[1][1]) * rDet;
01683
01684 result[3][0] =
01685 result[3][1] =
01686 result[3][2] = TypeTraits<ValueType>::getZeroElement();
01687
01688 result[3][3] = TypeTraits<ValueType>::getOneElement();
01689
01690 *this = result;
01691
01692 return true;
01693 }
01694
01695 template<class ValueTypeT> inline
01696 bool TransformationMatrix<ValueTypeT>::invertFrom3(
01697 const TransformationMatrix &matrix)
01698 {
01699 ValueTypeT rDet = matrix.det3();
01700
01701 if(osgabs(rDet) < 1E-20)
01702 {
01703 #ifdef OSG_PRINT_MATHERR
01704 fprintf(stderr, "invertFrom3: matrix singular, no inverse!\n");
01705 #endif
01706
01707 setIdentity();
01708
01709 return false;
01710 }
01711
01712 rDet = 1.0f / rDet;
01713
01714 _matrix[0][0] = det2(matrix._matrix[1][1],
01715 matrix._matrix[1][2],
01716 matrix._matrix[2][1],
01717 matrix._matrix[2][2]) * rDet;
01718 _matrix[0][1] = - det2(matrix._matrix[0][1],
01719 matrix._matrix[0][2],
01720 matrix._matrix[2][1],
01721 matrix._matrix[2][2]) * rDet;
01722 _matrix[0][2] = det2(matrix._matrix[0][1],
01723 matrix._matrix[0][2],
01724 matrix._matrix[1][1],
01725 matrix._matrix[1][2]) * rDet;
01726
01727 _matrix[1][0] = - det2(matrix._matrix[1][0],
01728 matrix._matrix[1][2],
01729 matrix._matrix[2][0],
01730 matrix._matrix[2][2]) * rDet;
01731 _matrix[1][1] = det2(matrix._matrix[0][0],
01732 matrix._matrix[0][2],
01733 matrix._matrix[2][0],
01734 matrix._matrix[2][2]) * rDet;
01735 _matrix[1][2] = - det2(matrix._matrix[0][0],
01736 matrix._matrix[0][2],
01737 matrix._matrix[1][0],
01738 matrix._matrix[1][2]) * rDet;
01739
01740 _matrix[2][0] = det2(matrix._matrix[1][0],
01741 matrix._matrix[1][1],
01742 matrix._matrix[2][0],
01743 matrix._matrix[2][1]) * rDet;
01744 _matrix[2][1] = - det2(matrix._matrix[0][0],
01745 matrix._matrix[0][1],
01746 matrix._matrix[2][0],
01747 matrix._matrix[2][1]) * rDet;
01748 _matrix[2][2] = det2(matrix._matrix[0][0],
01749 matrix._matrix[0][1],
01750 matrix._matrix[1][0],
01751 matrix._matrix[1][1]) * rDet;
01752
01753 _matrix[3][0] =
01754 _matrix[3][1] =
01755 _matrix[3][2] = TypeTraits<ValueType>::getZeroElement();
01756
01757 _matrix[3][3] = TypeTraits<ValueType>::getOneElement();
01758
01759 return true;
01760 }
01761
01762 template<class ValueTypeT> inline
01763 bool TransformationMatrix<ValueTypeT>::transposed(
01764 TransformationMatrix &result) const
01765 {
01766 result.setValueTransposed(
01767 (*this)[0][0], (*this)[1][0], (*this)[2][0], (*this)[3][0],
01768 (*this)[0][1], (*this)[1][1], (*this)[2][1], (*this)[3][1],
01769 (*this)[0][2], (*this)[1][2], (*this)[2][2], (*this)[3][2],
01770 (*this)[0][3], (*this)[1][3], (*this)[2][3], (*this)[3][3]);
01771
01772 return true;
01773 }
01774
01775 template<class ValueTypeT> inline
01776 bool TransformationMatrix<ValueTypeT>::transpose(void)
01777 {
01778 ValueTypeT tmp;
01779
01780 tmp = (*this)[1][0]; (*this)[1][0] = (*this)[0][1]; (*this)[0][1] = tmp;
01781 tmp = (*this)[2][0]; (*this)[2][0] = (*this)[0][2]; (*this)[0][2] = tmp;
01782 tmp = (*this)[3][0]; (*this)[3][0] = (*this)[0][3]; (*this)[0][3] = tmp;
01783 tmp = (*this)[2][1]; (*this)[2][1] = (*this)[1][2]; (*this)[1][2] = tmp;
01784 tmp = (*this)[3][1]; (*this)[3][1] = (*this)[1][3]; (*this)[1][3] = tmp;
01785 tmp = (*this)[3][2]; (*this)[3][2] = (*this)[2][3]; (*this)[2][3] = tmp;
01786
01787 return true;
01788 }
01789
01790 template<class ValueTypeT> inline
01791 bool TransformationMatrix<ValueTypeT>::transposeFrom(
01792 const TransformationMatrix &matrix)
01793 {
01794 this->setValueTransposed(
01795 matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0],
01796 matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1],
01797 matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2],
01798 matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]);
01799
01800 return true;
01801 }
01802
01803 template<class ValueTypeT> inline
01804 void TransformationMatrix<ValueTypeT>::mult(const TransformationMatrix &matrix)
01805 {
01806 ValueTypeT rTmpMat[4][4];
01807
01808 (rTmpMat)[0][0] = rowMulCol4((*this), 0, (matrix), 0);
01809 (rTmpMat)[0][1] = rowMulCol4((*this), 1, (matrix), 0);
01810 (rTmpMat)[0][2] = rowMulCol4((*this), 2, (matrix), 0);
01811 (rTmpMat)[0][3] = rowMulCol4((*this), 3, (matrix), 0);
01812
01813 (rTmpMat)[1][0] = rowMulCol4((*this), 0, (matrix), 1);
01814 (rTmpMat)[1][1] = rowMulCol4((*this), 1, (matrix), 1);
01815 (rTmpMat)[1][2] = rowMulCol4((*this), 2, (matrix), 1);
01816 (rTmpMat)[1][3] = rowMulCol4((*this), 3, (matrix), 1);
01817
01818 (rTmpMat)[2][0] = rowMulCol4((*this), 0, (matrix), 2);
01819 (rTmpMat)[2][1] = rowMulCol4((*this), 1, (matrix), 2);
01820 (rTmpMat)[2][2] = rowMulCol4((*this), 2, (matrix), 2);
01821 (rTmpMat)[2][3] = rowMulCol4((*this), 3, (matrix), 2);
01822
01823 (rTmpMat)[3][0] = rowMulCol4((*this), 0, (matrix), 3);
01824 (rTmpMat)[3][1] = rowMulCol4((*this), 1, (matrix), 3);
01825 (rTmpMat)[3][2] = rowMulCol4((*this), 2, (matrix), 3);
01826 (rTmpMat)[3][3] = rowMulCol4((*this), 3, (matrix), 3);
01827
01828 _matrix[0][0] = rTmpMat[0][0];
01829 _matrix[0][1] = rTmpMat[0][1];
01830 _matrix[0][2] = rTmpMat[0][2];
01831 _matrix[0][3] = rTmpMat[0][3];
01832
01833 _matrix[1][0] = rTmpMat[1][0];
01834 _matrix[1][1] = rTmpMat[1][1];
01835 _matrix[1][2] = rTmpMat[1][2];
01836 _matrix[1][3] = rTmpMat[1][3];
01837
01838 _matrix[2][0] = rTmpMat[2][0];
01839 _matrix[2][1] = rTmpMat[2][1];
01840 _matrix[2][2] = rTmpMat[2][2];
01841 _matrix[2][3] = rTmpMat[2][3];
01842
01843 _matrix[3][0] = rTmpMat[3][0];
01844 _matrix[3][1] = rTmpMat[3][1];
01845 _matrix[3][2] = rTmpMat[3][2];
01846 _matrix[3][3] = rTmpMat[3][3];
01847 }
01848
01849 template<class ValueTypeT> inline
01850 void TransformationMatrix<ValueTypeT>::multLeft(
01851 const TransformationMatrix &matrix)
01852 {
01853 ValueTypeT rTmpMat[4][4];
01854
01855 (rTmpMat)[0][0] = rowMulCol4((matrix), 0, (*this), 0);
01856 (rTmpMat)[0][1] = rowMulCol4((matrix), 1, (*this), 0);
01857 (rTmpMat)[0][2] = rowMulCol4((matrix), 2, (*this), 0);
01858 (rTmpMat)[0][3] = rowMulCol4((matrix), 3, (*this), 0);
01859
01860 (rTmpMat)[1][0] = rowMulCol4((matrix), 0, (*this), 1);
01861 (rTmpMat)[1][1] = rowMulCol4((matrix), 1, (*this), 1);
01862 (rTmpMat)[1][2] = rowMulCol4((matrix), 2, (*this), 1);
01863 (rTmpMat)[1][3] = rowMulCol4((matrix), 3, (*this), 1);
01864
01865 (rTmpMat)[2][0] = rowMulCol4((matrix), 0, (*this), 2);
01866 (rTmpMat)[2][1] = rowMulCol4((matrix), 1, (*this), 2);
01867 (rTmpMat)[2][2] = rowMulCol4((matrix), 2, (*this), 2);
01868 (rTmpMat)[2][3] = rowMulCol4((matrix), 3, (*this), 2);
01869
01870 (rTmpMat)[3][0] = rowMulCol4((matrix), 0, (*this), 3);
01871 (rTmpMat)[3][1] = rowMulCol4((matrix), 1, (*this), 3);
01872 (rTmpMat)[3][2] = rowMulCol4((matrix), 2, (*this), 3);
01873 (rTmpMat)[3][3] = rowMulCol4((matrix), 3, (*this), 3);
01874
01875 _matrix[0][0] = rTmpMat[0][0];
01876 _matrix[0][1] = rTmpMat[0][1];
01877 _matrix[0][2] = rTmpMat[0][2];
01878 _matrix[0][3] = rTmpMat[0][3];
01879
01880 _matrix[1][0] = rTmpMat[1][0];
01881 _matrix[1][1] = rTmpMat[1][1];
01882 _matrix[1][2] = rTmpMat[1][2];
01883 _matrix[1][3] = rTmpMat[1][3];
01884
01885 _matrix[2][0] = rTmpMat[2][0];
01886 _matrix[2][1] = rTmpMat[2][1];
01887 _matrix[2][2] = rTmpMat[2][2];
01888 _matrix[2][3] = rTmpMat[2][3];
01889
01890 _matrix[3][0] = rTmpMat[3][0];
01891 _matrix[3][1] = rTmpMat[3][1];
01892 _matrix[3][2] = rTmpMat[3][2];
01893 _matrix[3][3] = rTmpMat[3][3];
01894 }
01895
01897
01898 template<class ValueTypeT> inline
01899 void TransformationMatrix<ValueTypeT>::add(const TransformationMatrix &matrix)
01900 {
01901 _matrix[0][0] += matrix._matrix[0][0];
01902 _matrix[0][1] += matrix._matrix[0][1];
01903 _matrix[0][2] += matrix._matrix[0][2];
01904 _matrix[0][3] += matrix._matrix[0][3];
01905
01906 _matrix[1][0] += matrix._matrix[1][0];
01907 _matrix[1][1] += matrix._matrix[1][1];
01908 _matrix[1][2] += matrix._matrix[1][2];
01909 _matrix[1][3] += matrix._matrix[1][3];
01910
01911 _matrix[2][0] += matrix._matrix[2][0];
01912 _matrix[2][1] += matrix._matrix[2][1];
01913 _matrix[2][2] += matrix._matrix[2][2];
01914 _matrix[2][3] += matrix._matrix[2][3];
01915
01916 _matrix[3][0] += matrix._matrix[3][0];
01917 _matrix[3][1] += matrix._matrix[3][1];
01918 _matrix[3][2] += matrix._matrix[3][2];
01919 _matrix[3][3] += matrix._matrix[3][3];
01920 }
01921
01923
01924 template<class ValueTypeT> inline
01925 void TransformationMatrix<ValueTypeT>::scale(ValueTypeT s)
01926 {
01927 _matrix[0][0] *= s;
01928 _matrix[0][1] *= s;
01929 _matrix[0][2] *= s;
01930 _matrix[0][3] *= s;
01931
01932 _matrix[1][0] *= s;
01933 _matrix[1][1] *= s;
01934 _matrix[1][2] *= s;
01935 _matrix[1][3] *= s;
01936
01937 _matrix[2][0] *= s;
01938 _matrix[2][1] *= s;
01939 _matrix[2][2] *= s;
01940 _matrix[2][3] *= s;
01941
01942 _matrix[3][0] *= s;
01943 _matrix[3][1] *= s;
01944 _matrix[3][2] *= s;
01945 _matrix[3][3] *= s;
01946 }
01947
01949
01950 template<class ValueTypeT> inline
01951 void TransformationMatrix<ValueTypeT>::addScaled(
01952 const TransformationMatrix &matrix,
01953 ValueTypeT s)
01954 {
01955 _matrix[0][0] += s*matrix._matrix[0][0];
01956 _matrix[0][1] += s*matrix._matrix[0][1];
01957 _matrix[0][2] += s*matrix._matrix[0][2];
01958 _matrix[0][3] += s*matrix._matrix[0][3];
01959
01960 _matrix[1][0] += s*matrix._matrix[1][0];
01961 _matrix[1][1] += s*matrix._matrix[1][1];
01962 _matrix[1][2] += s*matrix._matrix[1][2];
01963 _matrix[1][3] += s*matrix._matrix[1][3];
01964
01965 _matrix[2][0] += s*matrix._matrix[2][0];
01966 _matrix[2][1] += s*matrix._matrix[2][1];
01967 _matrix[2][2] += s*matrix._matrix[2][2];
01968 _matrix[2][3] += s*matrix._matrix[2][3];
01969
01970 _matrix[3][0] += s*matrix._matrix[3][0];
01971 _matrix[3][1] += s*matrix._matrix[3][1];
01972 _matrix[3][2] += s*matrix._matrix[3][2];
01973 _matrix[3][3] += s*matrix._matrix[3][3];
01974 }
01975
01977
01978 template<class ValueTypeT> inline
01979 void TransformationMatrix<ValueTypeT>::negate(void)
01980 {
01981 _matrix[0][0] *= -1.0;
01982 _matrix[0][1] *= -1.0;
01983 _matrix[0][2] *= -1.0;
01984 _matrix[0][3] *= -1.0;
01985
01986 _matrix[1][0] *= -1.0;
01987 _matrix[1][1] *= -1.0;
01988 _matrix[1][2] *= -1.0;
01989 _matrix[1][3] *= -1.0;
01990
01991 _matrix[2][0] *= -1.0;
01992 _matrix[2][1] *= -1.0;
01993 _matrix[2][2] *= -1.0;
01994 _matrix[2][3] *= -1.0;
01995
01996 _matrix[3][0] *= -1.0;
01997 _matrix[3][1] *= -1.0;
01998 _matrix[3][2] *= -1.0;
01999 _matrix[3][3] *= -1.0;
02000 }
02001
02003
02004 template<class ValueTypeT> inline
02005 ValueTypeT TransformationMatrix<ValueTypeT>::norm1(void) const
02006 {
02007 ValueTypeT m(0);
02008
02009 m += osgabs(_matrix[0][0]);
02010 m += osgabs(_matrix[0][1]);
02011 m += osgabs(_matrix[0][2]);
02012 m += osgabs(_matrix[0][3]);
02013 m += osgabs(_matrix[1][0]);
02014 m += osgabs(_matrix[1][1]);
02015 m += osgabs(_matrix[1][2]);
02016 m += osgabs(_matrix[1][3]);
02017 m += osgabs(_matrix[2][0]);
02018 m += osgabs(_matrix[2][1]);
02019 m += osgabs(_matrix[2][2]);
02020 m += osgabs(_matrix[2][3]);
02021 m += osgabs(_matrix[3][0]);
02022 m += osgabs(_matrix[3][1]);
02023 m += osgabs(_matrix[3][2]);
02024 m += osgabs(_matrix[3][3]);
02025
02026 return m;
02027 }
02028
02030
02031 template<class ValueTypeT> inline
02032 ValueTypeT TransformationMatrix<ValueTypeT>::norm2(void) const
02033 {
02034 ValueTypeT m = 0.;
02035 ValueTypeT t;
02036
02037 t = _matrix[0][0]; m += t*t;
02038 t = _matrix[0][1]; m += t*t;
02039 t = _matrix[0][2]; m += t*t;
02040 t = _matrix[0][3]; m += t*t;
02041 t = _matrix[1][0]; m += t*t;
02042 t = _matrix[1][1]; m += t*t;
02043 t = _matrix[1][2]; m += t*t;
02044 t = _matrix[1][3]; m += t*t;
02045 t = _matrix[2][0]; m += t*t;
02046 t = _matrix[2][1]; m += t*t;
02047 t = _matrix[2][2]; m += t*t;
02048 t = _matrix[2][3]; m += t*t;
02049 t = _matrix[3][0]; m += t*t;
02050 t = _matrix[3][1]; m += t*t;
02051 t = _matrix[3][2]; m += t*t;
02052 t = _matrix[3][3]; m += t*t;
02053
02054 return osgsqrt(m);
02055 }
02056
02058
02059 template<class ValueTypeT> inline
02060 ValueTypeT TransformationMatrix<ValueTypeT>::normInfinity(void) const
02061 {
02062 ValueTypeT m = 0.;
02063 ValueTypeT t;
02064
02065 if((t = osgabs(_matrix[0][0])) > m)
02066 m = t;
02067 if((t = osgabs(_matrix[0][1])) > m)
02068 m = t;
02069 if((t = osgabs(_matrix[0][2])) > m)
02070 m = t;
02071 if((t = osgabs(_matrix[0][3])) > m)
02072 m = t;
02073 if((t = osgabs(_matrix[1][0])) > m)
02074 m = t;
02075 if((t = osgabs(_matrix[1][1])) > m)
02076 m = t;
02077 if((t = osgabs(_matrix[1][2])) > m)
02078 m = t;
02079 if((t = osgabs(_matrix[1][3])) > m)
02080 m = t;
02081 if((t = osgabs(_matrix[2][0])) > m)
02082 m = t;
02083 if((t = osgabs(_matrix[2][1])) > m)
02084 m = t;
02085 if((t = osgabs(_matrix[2][2])) > m)
02086 m = t;
02087 if((t = osgabs(_matrix[2][3])) > m)
02088 m = t;
02089 if((t = osgabs(_matrix[3][0])) > m)
02090 m = t;
02091 if((t = osgabs(_matrix[3][1])) > m)
02092 m = t;
02093 if((t = osgabs(_matrix[3][2])) > m)
02094 m = t;
02095 if((t = osgabs(_matrix[3][3])) > m)
02096 m = t;
02097
02098 return m;
02099 }
02100
02105 template<class ValueTypeT> inline
02106 bool TransformationMatrix<ValueTypeT>::sqrt(TransformationMatrix &result) const
02107 {
02108 TransformationMatrix iX;
02109 TransformationMatrix Y;
02110 TransformationMatrix iY;
02111
02112 ValueTypeT g;
02113 ValueTypeT ig;
02114
02115 result.setValue(*this);
02116
02117 Y.setIdentity();
02118
02119 for(UInt32 i = 0; i < 6; i++)
02120 {
02121 result.inverse(iX);
02122
02123 Y.inverse(iY);
02124
02125 g = osgabs(osgpow(result.det() * Y.det(), ValueTypeT(-0.125)));
02126
02127 ig = ValueTypeT(1.0 / g);
02128
02129 result.scale (g );
02130 result.addScaled(iY, ig);
02131 result.scale (0.5 );
02132
02133 Y.scale (g );
02134 Y.addScaled(iX, ig);
02135 Y.scale (0.5 );
02136 }
02137
02138
02139 return true;
02140 }
02141
02146 template<class ValueTypeT> inline
02147 bool TransformationMatrix<ValueTypeT>::sqrtOf(
02148 const TransformationMatrix &matrix)
02149 {
02150 TransformationMatrix iX;
02151 TransformationMatrix Y;
02152 TransformationMatrix iY;
02153
02154 ValueTypeT g;
02155 ValueTypeT ig;
02156
02157 setValue(matrix);
02158
02159 Y.setIdentity();
02160
02161 for(Int32 i = 0; i < 6; i++)
02162 {
02163 inverse(iX);
02164
02165 Y.inverse(iY);
02166
02167 g = osgabs(osgpow(det() * Y.det(), ValueTypeT(-0.125)));
02168
02169 ig = ValueTypeT(1.0 / g);
02170
02171 scale (g );
02172 addScaled(iY, ig);
02173 scale (0.5 );
02174
02175 Y.scale (g );
02176 Y.addScaled(iX, ig);
02177 Y.scale (0.5);
02178 }
02179
02180
02181 return true;
02182 }
02183
02185
02186 template<class ValueTypeT> inline
02187 bool TransformationMatrix<ValueTypeT>::sqrt(void)
02188 {
02189 TransformationMatrix iX;
02190 TransformationMatrix Y;
02191 TransformationMatrix iY;
02192
02193 ValueTypeT g;
02194 ValueTypeT ig;
02195
02196 Y.setIdentity();
02197
02198 for(Int32 i = 0; i < 6; i++)
02199 {
02200 inverse(iX);
02201
02202 Y.inverse(iY);
02203
02204 g = osgabs(osgpow(det() * Y.det(), ValueTypeT(-0.125)));
02205
02206 ig = ValueTypeT(1.0 / g);
02207
02208 scale (g );
02209 addScaled(iY, ig);
02210 scale (0.5 );
02211
02212 Y.scale (g );
02213 Y.addScaled(iX, ig);
02214 Y.scale (0.5 );
02215 }
02216
02217
02218 return true;
02219 }
02220
02225 template<class ValueTypeT> inline
02226 bool TransformationMatrix<ValueTypeT>::log(TransformationMatrix &result) const
02227 {
02228 const Int32 maxiter = 12;
02229 Int32 k = 0;
02230 Int32 i = 0;
02231 const ValueTypeT eps = 1e-12;
02232
02233 TransformationMatrix A(*this);
02234 TransformationMatrix Z;
02235
02236
02237 Z.setValue(A);
02238
02239 Z[0][0] -= TypeTraits<ValueType>::getOneElement();
02240 Z[1][1] -= TypeTraits<ValueType>::getOneElement();
02241 Z[2][2] -= TypeTraits<ValueType>::getOneElement();
02242 Z[3][3] -= TypeTraits<ValueType>::getOneElement();
02243
02244 while(Z.normInfinity() > 0.5)
02245 {
02246 A.sqrt ( );
02247 Z.setValue(A);
02248
02249 Z[0][0] -= TypeTraits<ValueType>::getOneElement();
02250 Z[1][1] -= TypeTraits<ValueType>::getOneElement();
02251 Z[2][2] -= TypeTraits<ValueType>::getOneElement();
02252 Z[3][3] -= TypeTraits<ValueType>::getOneElement();
02253
02254 k++;
02255 }
02256
02257 A[0][0] -= TypeTraits<ValueType>::getOneElement();
02258 A[1][1] -= TypeTraits<ValueType>::getOneElement();
02259 A[2][2] -= TypeTraits<ValueType>::getOneElement();
02260 A[3][3] -= TypeTraits<ValueType>::getOneElement();
02261
02262 A.negate();
02263
02264 result.setValue(A);
02265
02266 Z.setValue(A);
02267
02268 i = 1;
02269
02270 while(Z.normInfinity() > eps && i < maxiter)
02271 {
02272 Z.mult(A);
02273
02274 i++;
02275
02276 result.addScaled(Z, ValueTypeT(1.0) / ValueTypeT(i));
02277 }
02278
02279 result.scale(ValueTypeT(-1.0) * ValueTypeT(1 << k));
02280
02281 return (i < maxiter);
02282 }
02283
02288 template<class ValueTypeT> inline
02289 bool TransformationMatrix<ValueTypeT>::logOf(
02290 const TransformationMatrix &matrix)
02291 {
02292 const Int32 maxiter = 12;
02293 Int32 k = 0;
02294 Int32 i = 0;
02295 const ValueTypeT eps = 1e-12;
02296
02297 TransformationMatrix<ValueTypeT> A(matrix),Z;
02298
02299
02300 Z.setValue(A);
02301
02302 Z[0][0] -= TypeTraits<ValueType>::getOneElement();
02303 Z[1][1] -= TypeTraits<ValueType>::getOneElement();
02304 Z[2][2] -= TypeTraits<ValueType>::getOneElement();
02305 Z[3][3] -= TypeTraits<ValueType>::getOneElement();
02306
02307 while(Z.normInfinity() > 0.5)
02308 {
02309 A.sqrt();
02310
02311 Z.setValue(A);
02312
02313 Z[0][0] -= TypeTraits<ValueType>::getOneElement();
02314 Z[1][1] -= TypeTraits<ValueType>::getOneElement();
02315 Z[2][2] -= TypeTraits<ValueType>::getOneElement();
02316 Z[3][3] -= TypeTraits<ValueType>::getOneElement();
02317
02318 k++;
02319 }
02320
02321 A[0][0] -= TypeTraits<ValueType>::getOneElement();
02322 A[1][1] -= TypeTraits<ValueType>::getOneElement();
02323 A[2][2] -= TypeTraits<ValueType>::getOneElement();
02324 A[3][3] -= TypeTraits<ValueType>::getOneElement();
02325
02326 A.negate();
02327
02328 setValue(A);
02329
02330 Z.setValue(A);
02331
02332 i = 1;
02333 while(Z.normInfinity() > eps && i < maxiter)
02334 {
02335 Z.mult(A);
02336
02337 i++;
02338
02339 addScaled(Z, ValueTypeT(1.0) / ValueTypeT(i));
02340 }
02341
02342 scale(ValueTypeT(-1.0) * ValueTypeT(1 << k));
02343
02344 return (i<maxiter);
02345 }
02346
02351 template<class ValueTypeT> inline
02352 bool TransformationMatrix<ValueTypeT>::exp(TransformationMatrix &result) const
02353 {
02354 const Int32 q = 6;
02355
02356 TransformationMatrix A(*this);
02357 TransformationMatrix D;
02358 TransformationMatrix N;
02359
02360 Int32 j = 1;
02361 Int32 k;
02362
02363 ValueTypeT c(1.0);
02364
02365 j += Int32(osglog(A.normInfinity() / 0.693));
02366
02367 if(j < 0)
02368 j = 0;
02369
02370 A.scale(ValueTypeT(1.0f / (1 << j)));
02371
02372 result.setIdentity();
02373
02374 for(k = 1; k <= q; k++)
02375 {
02376 c *= ValueTypeT(q - k + 1) / ValueTypeT(k * (2 * q - k + 1));
02377
02378 result.multLeft(A);
02379
02380 N.addScaled(result, c);
02381
02382 if(k % 2)
02383 {
02384 D.addScaled(result, -c);
02385 }
02386 else
02387 {
02388 D.addScaled(result, c);
02389 }
02390 }
02391
02392 result.invertFrom(D);
02393 result.mult (N);
02394
02395 for(k = 0; k < j; k++)
02396 result.mult(result);
02397
02398
02399 return true;
02400 }
02401
02405 template<class ValueTypeT> inline
02406 bool TransformationMatrix<ValueTypeT>::expOf(
02407 const TransformationMatrix &matrix)
02408 {
02409 const Int32 q = 6;
02410
02411 TransformationMatrix A(matrix);
02412 TransformationMatrix D;
02413 TransformationMatrix N;
02414
02415 Int32 j = 1;
02416 Int32 k;
02417
02418 ValueTypeT c(1.0);
02419
02420 j += int(osglog(A.normInfinity() / 0.693));
02421
02422 if(j < 0)
02423 j = 0;
02424
02425 A.scale(1.0 / (ValueTypeT(1 << j)));
02426
02427 setIdentity();
02428
02429 for(k = 1; k <= q; k++)
02430 {
02431 c *= ValueTypeT(q - k + 1) / ValueTypeT(k * (2 *q - k + 1));
02432
02433 multLeft(A);
02434
02435 N.addScaled(*this,c);
02436
02437 if(k % 2)
02438 {
02439 D.addScaled(*this, -c);
02440 }
02441 else
02442 {
02443 D.addScaled(*this, c);
02444 }
02445 }
02446
02447 invertFrom(D);
02448 mult (N);
02449
02450 for(k = 0; k < j; k++)
02451 mult(*this);
02452
02453
02454 return true;
02455 }
02456
02457
02458
02459
02460 template<class ValueTypeT> inline
02461 typename TransformationMatrix<ValueTypeT>::VectorType &
02462 TransformationMatrix<ValueTypeT>::operator [](UInt32 uiIndex)
02463 {
02464 return _matrix[uiIndex];
02465 }
02466
02467 template<class ValueTypeT> inline
02468 const typename TransformationMatrix<ValueTypeT>::VectorType &
02469 TransformationMatrix<ValueTypeT>::operator [](UInt32 uiIndex) const
02470 {
02471 return _matrix[uiIndex];
02472 }
02473
02474
02475
02476
02477 template<class ValueTypeT> inline
02478 TransformationMatrix<ValueTypeT> &
02479 TransformationMatrix<ValueTypeT>::operator = (
02480 const TransformationMatrix &source)
02481 {
02482 UInt32 i;
02483
02484 if (this == &source)
02485 return *this;
02486
02487 for(i = 0; i < 4; i++)
02488 _matrix[i] = source._matrix[i];
02489
02490 return *this;
02491 }
02492
02493
02494
02495
02500 template<class ValueTypeT> inline
02501 bool TransformationMatrix<ValueTypeT>::operator == (
02502 const TransformationMatrix &other) const
02503 {
02504 return equals(other, Eps);
02505 }
02506
02511 template<class ValueTypeT> inline
02512 bool TransformationMatrix<ValueTypeT>::operator != (
02513 const TransformationMatrix &other) const
02514 {
02515 return ! (*this == other);
02516 }
02517
02518
02519
02520
02521 template<class ValueTypeT> inline
02522 ValueTypeT TransformationMatrix<ValueTypeT>::rowMulCol4(
02523 const TransformationMatrix &gRowMat, UInt32 iRow,
02524 const TransformationMatrix &gColMat, UInt32 iColumn) const
02525 {
02526 return
02527 gRowMat[0][iRow] * gColMat[iColumn][0] +
02528 gRowMat[1][iRow] * gColMat[iColumn][1] +
02529 gRowMat[2][iRow] * gColMat[iColumn][2] +
02530 gRowMat[3][iRow] * gColMat[iColumn][3];
02531 }
02532
02533
02534 template<class ValueTypeT> inline
02535 ValueTypeT TransformationMatrix<ValueTypeT>::det2(
02536 const ValueTypeT a1, const ValueTypeT a2,
02537 const ValueTypeT b1, const ValueTypeT b2) const
02538 {
02539 return (a1 * b2) - (a2 * b1);
02540 }
02541
02542 template<class ValueTypeT> inline
02543 ValueTypeT TransformationMatrix<ValueTypeT>::det3(
02544 const ValueTypeT a1,
02545 const ValueTypeT a2,
02546 const ValueTypeT a3,
02547 const ValueTypeT b1,
02548 const ValueTypeT b2,
02549 const ValueTypeT b3,
02550 const ValueTypeT c1,
02551 const ValueTypeT c2,
02552 const ValueTypeT c3) const
02553 {
02554 return
02555 (a1 * b2 * c3) + (a2 * b3 * c1) + (a3 * b1 * c2) -
02556 (a1 * b3 * c2) - (a2 * b1 * c3) - (a3 * b2 * c1);
02557 }
02558
02559 #ifdef __sgi
02560 #pragma set woff 1424
02561 #endif
02562
02563 template<class ValueTypeT> inline
02564 bool TransformationMatrix<ValueTypeT>::jacobi(
02565 ValueTypeT evalues [JacobiRank],
02566 VectorType3f evectors[JacobiRank],
02567 Int32 &rots)
02568 {
02569 Real64 sm;
02570 Real64 theta;
02571 Real64 c, s, t;
02572 Real64 tau;
02573 Real64 h, g;
02574 Real64 thresh;
02575 Real64 b[JacobiRank];
02576 Real64 z[JacobiRank];
02577 UInt32 p, q, i, j;
02578 Real64 a[JacobiRank][JacobiRank];
02579
02580
02581 for (i = 0; i < JacobiRank; i++)
02582 {
02583 b[i] = evalues[i] = _matrix[i][i];
02584 z[i] = 0.0;
02585
02586 for (j = 0; j < JacobiRank; j++)
02587 {
02588 evectors[i][j] = (i == j) ? 1.0f : 0.0f;
02589 a[i][j] = _matrix[i][j];
02590 }
02591 }
02592
02593 rots = 0;
02594
02595 for(i = 0; i < 50; i++)
02596 {
02597 sm = 0.0;
02598
02599 for(p = 0; p < JacobiRank - 1; p++)
02600 {
02601 for(q = p+1; q < JacobiRank; q++)
02602 {
02603 sm += osgabs(a[p][q]);
02604 }
02605 }
02606
02607 if (sm == 0.0)
02608 return false;
02609
02610 thresh = (i < 3 ?
02611 (.2 * sm / (JacobiRank * JacobiRank)) :
02612 0.0);
02613
02614 for (p = 0; p < JacobiRank - 1; p++)
02615 {
02616 for (q = p + 1; q < JacobiRank; q++)
02617 {
02618 g = 100.0 * osgabs(a[p][q]);
02619
02620 if (i > 3 &&
02621 (osgabs(evalues[p]) + g == osgabs(evalues[p])) &&
02622 (osgabs(evalues[q]) + g == osgabs(evalues[q])))
02623 {
02624 a[p][q] = 0.0;
02625 }
02626 else if (osgabs(a[p][q]) > thresh)
02627 {
02628 h = evalues[q] - evalues[p];
02629
02630 if (osgabs(h) + g == osgabs(h))
02631 {
02632 t = a[p][q] / h;
02633 }
02634 else
02635 {
02636 theta = .5 * h / a[p][q];
02637 t = 1.0 / (osgabs(theta) + osgsqrt(1 + theta * theta));
02638 if (theta < 0.0) t = -t;
02639 }
02640
02641
02642 c = 1.0 / osgsqrt(1.0 + t * t);
02643 s = t * c;
02644
02645 tau = s / (1.0 + c);
02646 h = t * a[p][q];
02647
02648 z[p] -= h;
02649 z[q] += h;
02650
02651 evalues[p] -= ValueTypeT(h);
02652 evalues[q] += ValueTypeT(h);
02653
02654 a[p][q] = 0.0;
02655
02656 for (j = 0; j < p; j++)
02657 {
02658 g = a[j][p];
02659 h = a[j][q];
02660
02661 a[j][p] = g - s * (h + g * tau);
02662 a[j][q] = h + s * (g - h * tau);
02663 }
02664
02665 for (j = p+1; j < q; j++)
02666 {
02667 g = a[p][j];
02668 h = a[j][q];
02669
02670 a[p][j] = g - s * (h + g * tau);
02671 a[j][q] = h + s * (g - h * tau);
02672 }
02673
02674 for (j = q+1; j < JacobiRank; j++)
02675 {
02676 g = a[p][j];
02677 h = a[q][j];
02678
02679 a[p][j] = g - s * (h + g * tau);
02680 a[q][j] = h + s * (g - h * tau);
02681 }
02682
02683 for (j = 0; j < JacobiRank; j++)
02684 {
02685 g = evectors[j][p];
02686 h = evectors[j][q];
02687
02688 evectors[j][p] = ValueTypeT(g - s * (h + g * tau));
02689 evectors[j][q] = ValueTypeT(h + s * (g - h * tau));
02690 }
02691 }
02692 rots++;
02693 }
02694 }
02695 for (p = 0; p < JacobiRank; p++)
02696 {
02697 evalues[p] = ValueTypeT(b[p] += z[p]);
02698
02699 z[p] = 0;
02700 }
02701 }
02702
02703 return true;
02704 }
02705
02706 #ifdef __sgi
02707 #pragma reset woff 1424
02708 #endif
02709
02710
02711
02712
02714
02715 template<class ValueTypeT> inline
02716 std::ostream &operator <<( std::ostream &os,
02717 const TransformationMatrix<ValueTypeT> &obj)
02718 {
02719 UInt32 i;
02720 UInt32 j;
02721
02722 std::ios::fmtflags oldflags = os.flags(std::ios::showpoint |
02723 std::ios::fixed);
02724
02725 Int32 pr = os.precision(3 );
02726 Char8 fill = os.fill (' ');
02727 Int32 width = os.width (8 );
02728
02729 for(j = 0; j < 4; j++)
02730 {
02731 for(i = 0; i < 4; i++)
02732 {
02733 os << std::setw(8) << obj[i][j] << " ";
02734 }
02735
02736 os << "\n";
02737 }
02738
02739 os.flags (oldflags);
02740 os.precision(pr );
02741 os.fill (fill );
02742 os.width (width );
02743
02744 return os;
02745 }
02746
02747 OSG_END_NAMESPACE
02748
02749 #define OSGMATRIX_INLINE_CVSID "@(#)$Id: $"