Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGMatrix.inl

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
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 /*                            Class Get                                    */
00087 
00088 template<class ValueTypeT> inline
00089 const TransformationMatrix<ValueTypeT> &
00090     TransformationMatrix<ValueTypeT>::identity(void)
00091 {
00092     return _identityMatrix;
00093 }
00094 
00095 /*-------------------------------------------------------------------------*/
00096 /*                            Constructors                                 */
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 /*                             Destructor                                  */
00171 
00172 template<class ValueTypeT> inline
00173 TransformationMatrix<ValueTypeT>::~TransformationMatrix(void)
00174 {
00175 }
00176 
00177 /*-------------------------------------------------------------------------*/
00178 /*                                Set                                      */
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 /*                                Get                                      */
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 /*                       Set Transformation                                */
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     // Calculate the 4x4 rotation matrix
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     // Calculate the resulting transformation matrix
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     // Calculate the 3x3 rotation matrix
00549     r.getValuesOnly(*this);
00550 
00551     // Calculate the resulting transformation matrix
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     // Concatenate the rotations r and so
00578     QuaternionType rg(r);
00579     rg.mult(so);
00580 
00581     // Calculate the inverse of so
00582     QuaternionType soi(so);
00583     soi.invert();
00584 
00585     // Calculate the 3x3 rotation matrix
00586     rg. getValue(tmpMat1);
00587     soi.getValue(tmpMat2);
00588 
00589     // Calculate the resulting transformation matrix
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   &center)
00666 {
00667     Matrix tmpMat1;
00668     Matrix tmpMat2;
00669 
00670     // Concatenate the translations t and c
00671     VectorType3f tg(translation);
00672     tg += center;
00673 
00674     // Concatenate the rotations r and so
00675     QuaternionType rg(rotation);
00676     rg *= scaleOrientation;
00677 
00678     // Calculate the inverse of so
00679     QuaternionType soi(scaleOrientation);
00680     soi.invert();
00681 
00682     // Calculate the 3x3 rotation matrix
00683     rg. getValue(tmpMat1);
00684     soi.getValue(tmpMat2);
00685 
00686     // Calculate the resulting transformation matrix
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 /*                           Get Transform                                 */
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   &center          ) 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     // gives us transpose of correct answer.
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     /* (3) Compute det A. If negative, set sign = -1, else sign = 1 */
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;      // singular
00885     
00886     /* (4) B = A * A^  (here A^ means A transpose) */
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     /* Compute s = sqrt(evalues), with sign. Set si = s-inverse */
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     /* (5) Compute U = RT S! R A. */
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 /*---------------------------- transform objects ---------------------------*/
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     //CHECK
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 
01022 
01023 template<class ValueTypeT> inline
01024 void TransformationMatrix<ValueTypeT>::multMatrixVec(VectorType3f &vec) const
01025 {
01026     multMatrixVec(vec, vec);
01027 }
01028 
01033 template<class ValueTypeT> inline
01034 void TransformationMatrix<ValueTypeT>::mult(const PointType3f &src,
01035                                                   PointType3f &dest) const
01036 {
01037     multMatrixPnt(src, dest);
01038 }
01039 
01041 
01042 template<class ValueTypeT> inline
01043 void TransformationMatrix<ValueTypeT>::mult(PointType3f &pnt) const
01044 {
01045     multMatrixPnt(pnt, pnt);
01046 }
01047 
01052 template<class ValueTypeT> inline
01053 void TransformationMatrix<ValueTypeT>::mult(const VectorType3f &src,
01054                                                   VectorType3f &dest) const
01055 {
01056     multMatrixVec(src, dest);
01057 }
01058 
01060 
01061 template<class ValueTypeT> inline
01062 void TransformationMatrix<ValueTypeT>::mult(VectorType3f &vec) const
01063 {
01064     multMatrixVec(vec, vec);
01065 }
01066 
01067 
01068 
01073 template<class ValueTypeT> inline
01074 void TransformationMatrix<ValueTypeT>::multPntMatrix(
01075     const PointType3f &src,
01076           PointType3f &dst) const
01077 {
01078     dst.setValues((src[0] * _matrix[0][0] +
01079                    src[1] * _matrix[0][1] +
01080                    src[2] * _matrix[0][2] +
01081                             _matrix[0][3]),
01082                   (src[0] * _matrix[1][0] +
01083                    src[1] * _matrix[1][1] +
01084                    src[2] * _matrix[1][2] +
01085                             _matrix[1][3]),
01086                   (src[0] * _matrix[2][0] +
01087                    src[1] * _matrix[2][1] +
01088                    src[2] * _matrix[2][2] +
01089                             _matrix[2][3]));
01090 }
01091 
01093 
01094 template<class ValueTypeT> inline
01095 void TransformationMatrix<ValueTypeT>::multPntMatrix(PointType3f &pnt) const
01096 {
01097     multPntMatrix(pnt, pnt);
01098 }
01099 
01104 template<class ValueTypeT> inline
01105 void TransformationMatrix<ValueTypeT>::multPntFullMatrix(
01106     const PointType3f &src,
01107           PointType3f &dst) const
01108 {
01109     ValueTypeT w =  src[0] * _matrix[3][0] +
01110                     src[1] * _matrix[3][1] +
01111                     src[2] * _matrix[3][2] +
01112                              _matrix[3][3];
01113 
01114     if( w == 0.0f )
01115     {
01116         SINFO << "multFullMatrixPnt: w == 0.0f!" << std::endl;
01117 
01118         dst.setValues(0, 0, 0);
01119 
01120         return;
01121     }
01122 
01123     w = 1./w;
01124 
01125     dst.setValues((src[0] * _matrix[0][0] +
01126                    src[1] * _matrix[0][1] +
01127                    src[2] * _matrix[0][2] +
01128                             _matrix[0][3]) * w,
01129                   (src[0] * _matrix[1][0] +
01130                    src[1] * _matrix[1][1] +
01131                    src[2] * _matrix[1][2] +
01132                             _matrix[1][3]) * w,
01133                   (src[0] * _matrix[2][0] +
01134                    src[1] * _matrix[2][1] +
01135                    src[2] * _matrix[2][2] +
01136                             _matrix[2][3]) * w);
01137 }
01138 
01140  
01141 template<class ValueTypeT> inline
01142 void TransformationMatrix<ValueTypeT>::multPntFullMatrix(PointType3f &pnt)const
01143 {
01144     multPntFullMatrix(pnt, pnt);
01145 }
01146 
01151 template<class ValueTypeT> inline
01152 void TransformationMatrix<ValueTypeT>::multVecMatrix(
01153     const VectorType3f &src,
01154           VectorType3f &dst) const
01155 {
01156     dst.setValues((src[0] * _matrix[0][0] +
01157                    src[1] * _matrix[0][1] +
01158                    src[2] * _matrix[0][2]),
01159                   (src[0] * _matrix[1][0] +
01160                    src[1] * _matrix[1][1] +
01161                    src[2] * _matrix[1][2]),
01162                   (src[0] * _matrix[2][0] +
01163                    src[1] * _matrix[2][1] +
01164                    src[2] * _matrix[2][2]));
01165 }
01166 
01168 
01169 template<class ValueTypeT> inline
01170 void TransformationMatrix<ValueTypeT>::multVecMatrix(VectorType3f &vec) const
01171 {
01172     multVecMatrix(vec, vec);
01173 }
01174 
01175 /*---------------------------- simple math ---------------------------------*/
01176 
01181 template<class ValueTypeT> inline
01182 bool TransformationMatrix<ValueTypeT>::equals(
01183     const TransformationMatrix &matrix,
01184     const ValueType             tolerance) const
01185 {
01186     UInt32 i;
01187     bool returnValue = true;
01188 
01189     for(i = 0; i < 4; i++)
01190     {
01191         returnValue &= _matrix[i].equals(matrix._matrix[i], tolerance);
01192 
01193         if(returnValue == false)
01194             break;
01195     }
01196 
01197     return returnValue;
01198 }
01199 
01201 
01202 template<class ValueTypeT> inline
01203 ValueTypeT TransformationMatrix<ValueTypeT>::det3(void) const
01204 {
01205     return (_matrix[0][0] * _matrix[1][1] * _matrix[2][2] +
01206             _matrix[0][1] * _matrix[1][2] * _matrix[2][0] +
01207             _matrix[0][2] * _matrix[1][0] * _matrix[2][1] -
01208             _matrix[0][2] * _matrix[1][1] * _matrix[2][0] -
01209             _matrix[0][1] * _matrix[1][0] * _matrix[2][2] -
01210             _matrix[0][0] * _matrix[1][2] * _matrix[2][1]);
01211 }
01212 
01214 
01215 template<class ValueTypeT> inline
01216 ValueTypeT TransformationMatrix<ValueTypeT>::det (void) const
01217 {
01218     ValueTypeT
01219         a1, a2, a3, a4,
01220         b1, b2, b3, b4,
01221         c1, c2, c3, c4,
01222         d1, d2, d3, d4;
01223 
01224     a1 = _matrix[0][0];
01225     b1 = _matrix[1][0];
01226     c1 = _matrix[2][0];
01227     d1 = _matrix[3][0];
01228 
01229     a2 = _matrix[0][1];
01230     b2 = _matrix[1][1];
01231     c2 = _matrix[2][1];
01232     d2 = _matrix[3][1];
01233 
01234     a3 = _matrix[0][2];
01235     b3 = _matrix[1][2];
01236     c3 = _matrix[2][2];
01237     d3 = _matrix[3][2];
01238 
01239     a4 = _matrix[0][3];
01240     b4 = _matrix[1][3];
01241     c4 = _matrix[2][3];
01242     d4 = _matrix[3][3];
01243 
01244     return(   a1 * det3(b2, b3, b4, c2, c3, c4, d2, d3, d4)
01245             - b1 * det3(a2, a3, a4, c2, c3, c4, d2, d3, d4)
01246             + c1 * det3(a2, a3, a4, b2, b3, b4, d2, d3, d4)
01247             - d1 * det3(a2, a3, a4, b2, b3, b4, c2, c3, c4));
01248 
01249 }
01250 
01251 // This inverse stuff should be grouped in a better way :-). It's just a
01252 // Cut&Paste section. I will have a look at it lateron (GV)
01253 
01258 template<class ValueTypeT> inline
01259 bool TransformationMatrix<ValueTypeT>::inverse(
01260     TransformationMatrix &result) const
01261 {
01262     ValueTypeT rDet;
01263 
01264     ValueTypeT
01265         a1, a2, a3, a4,
01266         b1, b2, b3, b4,
01267         c1, c2, c3, c4,
01268         d1, d2, d3, d4;
01269 
01270     a1 = _matrix[0][0];
01271     b1 = _matrix[1][0];
01272     c1 = _matrix[2][0];
01273     d1 = _matrix[3][0];
01274 
01275     a2 = _matrix[0][1];
01276     b2 = _matrix[1][1];
01277     c2 =