Blender  V2.59
ntl_matrices.h
Go to the documentation of this file.
00001 
00005 /******************************************************************************
00006  *
00007  * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
00008  * Copyright 2003-2006 Nils Thuerey
00009  *
00010  * Basic matrix utility include file
00011  *
00012  *****************************************************************************/
00013 #ifndef NTL_MATRICES_H
00014 
00015 #include "ntl_vector3dim.h"
00016 
00017 
00018 // The basic vector class
00019 template<class Scalar>
00020 class ntlMatrix4x4
00021 {
00022 public:
00023   // Constructor
00024   inline ntlMatrix4x4(void );
00025   // Copy-Constructor
00026   inline ntlMatrix4x4(const ntlMatrix4x4<Scalar> &v );
00027   // construct a vector from one Scalar
00028   inline ntlMatrix4x4(Scalar);
00029   // construct a vector from three Scalars
00030   inline ntlMatrix4x4(Scalar, Scalar, Scalar);
00031 
00032   // Assignment operator
00033   inline const ntlMatrix4x4<Scalar>& operator=  (const ntlMatrix4x4<Scalar>& v);
00034   // Assignment operator
00035   inline const ntlMatrix4x4<Scalar>& operator=  (Scalar s);
00036   // Assign and add operator
00037   inline const ntlMatrix4x4<Scalar>& operator+= (const ntlMatrix4x4<Scalar>& v);
00038   // Assign and add operator
00039   inline const ntlMatrix4x4<Scalar>& operator+= (Scalar s);
00040   // Assign and sub operator
00041   inline const ntlMatrix4x4<Scalar>& operator-= (const ntlMatrix4x4<Scalar>& v);
00042   // Assign and sub operator
00043   inline const ntlMatrix4x4<Scalar>& operator-= (Scalar s);
00044   // Assign and mult operator
00045   inline const ntlMatrix4x4<Scalar>& operator*= (const ntlMatrix4x4<Scalar>& v);
00046   // Assign and mult operator
00047   inline const ntlMatrix4x4<Scalar>& operator*= (Scalar s);
00048   // Assign and div operator
00049   inline const ntlMatrix4x4<Scalar>& operator/= (const ntlMatrix4x4<Scalar>& v);
00050   // Assign and div operator
00051   inline const ntlMatrix4x4<Scalar>& operator/= (Scalar s);
00052 
00053   
00054   // unary operator
00055   inline ntlMatrix4x4<Scalar> operator- () const;
00056 
00057   // binary operator add
00058   inline ntlMatrix4x4<Scalar> operator+ (const ntlMatrix4x4<Scalar>&) const;
00059   // binary operator add
00060   inline ntlMatrix4x4<Scalar> operator+ (Scalar) const;
00061   // binary operator sub
00062   inline ntlMatrix4x4<Scalar> operator- (const ntlMatrix4x4<Scalar>&) const;
00063   // binary operator sub
00064   inline ntlMatrix4x4<Scalar> operator- (Scalar) const;
00065   // binary operator mult
00066   inline ntlMatrix4x4<Scalar> operator* (const ntlMatrix4x4<Scalar>&) const;
00067   // binary operator mult
00068   inline ntlVector3Dim<Scalar> operator* (const ntlVector3Dim<Scalar>&) const;
00069   // binary operator mult
00070   inline ntlMatrix4x4<Scalar> operator* (Scalar) const;
00071   // binary operator div
00072   inline ntlMatrix4x4<Scalar> operator/ (Scalar) const;
00073 
00074         // init function
00076         inline void initId();
00078         inline void initTranslation(Scalar x, Scalar y, Scalar z);
00080         inline void initRotationX(Scalar rot);
00081         inline void initRotationY(Scalar rot);
00082         inline void initRotationZ(Scalar rot);
00083         inline void initRotationXYZ(Scalar rotx,Scalar roty, Scalar rotz);
00085         inline void initScaling(Scalar scale);
00086         inline void initScaling(Scalar x, Scalar y, Scalar z);
00088         inline void initArrayCheck(Scalar *array);
00089 
00091         void decompose(ntlVector3Dim<Scalar> &trans,ntlVector3Dim<Scalar> &scale,ntlVector3Dim<Scalar> &rot,ntlVector3Dim<Scalar> &shear);
00092 
00094   Scalar value[4][4];  //< Storage of vector values
00095 
00096 
00097 protected:
00098 
00099 };
00100 
00101 
00102 
00103 //------------------------------------------------------------------------------
00104 // TYPEDEFS
00105 //------------------------------------------------------------------------------
00106 
00107 // a 3D vector for graphics output, typically float?
00108 //typedef ntlMatrix4x4<float>  ntlVec3Gfx; 
00109 
00110 //typedef ntlMatrix4x4<double>  ntlMat4d; 
00111 typedef ntlMatrix4x4<double>  ntlMat4d; 
00112 
00113 // a 3D vector with single precision
00114 typedef ntlMatrix4x4<float>   ntlMat4f; 
00115 
00116 // a 3D vector with grafix precision
00117 typedef ntlMatrix4x4<gfxReal>   ntlMat4Gfx;
00118 
00119 // a 3D integer vector
00120 typedef ntlMatrix4x4<int>     ntlMat4i; 
00121 
00122 
00123 
00124 
00125 
00126 //------------------------------------------------------------------------------
00127 // STREAM FUNCTIONS
00128 //------------------------------------------------------------------------------
00129 
00130 
00131 
00132 /*************************************************************************
00133   Outputs the object in human readable form using the format
00134   [x,y,z]
00135   */
00136 template<class Scalar>
00137 std::ostream&
00138 operator<<( std::ostream& os, const ntlMatrix4x4<Scalar>& m )
00139 {
00140         for(int i=0; i<4; i++) {
00141         os << '|' << m.value[i][0] << ", " << m.value[i][1] << ", " << m.value[i][2] << ", " << m.value[i][3] << '|';
00142         }
00143   return os;
00144 }
00145 
00146 
00147 
00148 /*************************************************************************
00149   Reads the contents of the object from a stream using the same format
00150   as the output operator.
00151   */
00152 template<class Scalar>
00153 std::istream&
00154 operator>>( std::istream& is, ntlMatrix4x4<Scalar>& m )
00155 {
00156   char c;
00157   char dummy[3];
00158   
00159         for(int i=0; i<4; i++) {
00160         is >> c >> m.value[i][0] >> dummy >> m.value[i][1] >> dummy >> m.value[i][2] >> dummy >> m.value[i][3] >> c;
00161         }
00162   return is;
00163 }
00164 
00165 
00166 //------------------------------------------------------------------------------
00167 // VECTOR inline FUNCTIONS
00168 //------------------------------------------------------------------------------
00169 
00170 
00171 
00172 /*************************************************************************
00173   Constructor.
00174   */
00175 template<class Scalar>
00176 inline ntlMatrix4x4<Scalar>::ntlMatrix4x4( void )
00177 {
00178 #ifdef MATRIX_INIT_ZERO
00179         for(int i=0; i<4; i++) {
00180                 for(int j=0; j<4; j++) {
00181                 value[i][j] = 0.0;
00182                 }
00183         }
00184 #endif
00185 }
00186 
00187 
00188 
00189 /*************************************************************************
00190   Copy-Constructor.
00191   */
00192 template<class Scalar>
00193 inline ntlMatrix4x4<Scalar>::ntlMatrix4x4( const ntlMatrix4x4<Scalar> &v )
00194 {
00195   value[0][0] = v.value[0][0]; value[0][1] = v.value[0][1]; value[0][2] = v.value[0][2]; value[0][3] = v.value[0][3];
00196   value[1][0] = v.value[1][0]; value[1][1] = v.value[1][1]; value[1][2] = v.value[1][2]; value[1][3] = v.value[1][3];
00197   value[2][0] = v.value[2][0]; value[2][1] = v.value[2][1]; value[2][2] = v.value[2][2]; value[2][3] = v.value[2][3];
00198   value[3][0] = v.value[3][0]; value[3][1] = v.value[3][1]; value[3][2] = v.value[3][2]; value[3][3] = v.value[3][3];
00199 }
00200 
00201 
00202 
00203 /*************************************************************************
00204   Constructor for a vector from a single Scalar. All components of
00205   the vector get the same value.
00206   \param s The value to set
00207   \return The new vector
00208   */
00209 template<class Scalar>
00210 inline ntlMatrix4x4<Scalar>::ntlMatrix4x4(Scalar s )
00211 {
00212         for(int i=0; i<4; i++) {
00213                 for(int j=0; j<4; j++) {
00214                 value[i][j] = s;
00215                 }
00216         }
00217 }
00218 
00219 
00220 
00221 /*************************************************************************
00222   Copy a ntlMatrix4x4 componentwise.
00223   \param v vector with values to be copied
00224   \return Reference to self
00225   */
00226 template<class Scalar>
00227 inline const ntlMatrix4x4<Scalar>&
00228 ntlMatrix4x4<Scalar>::operator=( const ntlMatrix4x4<Scalar> &v )
00229 {
00230   value[0][0] = v.value[0][0]; value[0][1] = v.value[0][1]; value[0][2] = v.value[0][2]; value[0][3] = v.value[0][3];
00231   value[1][0] = v.value[1][0]; value[1][1] = v.value[1][1]; value[1][2] = v.value[1][2]; value[1][3] = v.value[1][3];
00232   value[2][0] = v.value[2][0]; value[2][1] = v.value[2][1]; value[2][2] = v.value[2][2]; value[2][3] = v.value[2][3];
00233   value[3][0] = v.value[3][0]; value[3][1] = v.value[3][1]; value[3][2] = v.value[3][2]; value[3][3] = v.value[3][3];
00234   return *this;
00235 }
00236 
00237 
00238 /*************************************************************************
00239   Copy a Scalar to each component.
00240   \param s The value to copy
00241   \return Reference to self
00242   */
00243 template<class Scalar>
00244 inline const ntlMatrix4x4<Scalar>&
00245 ntlMatrix4x4<Scalar>::operator=(Scalar s)
00246 {
00247         for(int i=0; i<4; i++) {
00248                 for(int j=0; j<4; j++) {
00249                 value[i][j] = s;
00250                 }
00251         }
00252   return *this;
00253 }
00254 
00255 
00256 /*************************************************************************
00257   Add another ntlMatrix4x4 componentwise.
00258   \param v vector with values to be added
00259   \return Reference to self
00260   */
00261 template<class Scalar>
00262 inline const ntlMatrix4x4<Scalar>&
00263 ntlMatrix4x4<Scalar>::operator+=( const ntlMatrix4x4<Scalar> &v )
00264 {
00265   value[0][0] += v.value[0][0]; value[0][1] += v.value[0][1]; value[0][2] += v.value[0][2]; value[0][3] += v.value[0][3];
00266   value[1][0] += v.value[1][0]; value[1][1] += v.value[1][1]; value[1][2] += v.value[1][2]; value[1][3] += v.value[1][3];
00267   value[2][0] += v.value[2][0]; value[2][1] += v.value[2][1]; value[2][2] += v.value[2][2]; value[2][3] += v.value[2][3];
00268   value[3][0] += v.value[3][0]; value[3][1] += v.value[3][1]; value[3][2] += v.value[3][2]; value[3][3] += v.value[3][3];
00269   return *this;
00270 }
00271 
00272 
00273 /*************************************************************************
00274   Add a Scalar value to each component.
00275   \param s Value to add
00276   \return Reference to self
00277   */
00278 template<class Scalar>
00279 inline const ntlMatrix4x4<Scalar>&
00280 ntlMatrix4x4<Scalar>::operator+=(Scalar s)
00281 {
00282         for(int i=0; i<4; i++) {
00283                 for(int j=0; j<4; j++) {
00284                 value[i][j] += s;
00285                 }
00286         }
00287   return *this;
00288 }
00289 
00290 
00291 /*************************************************************************
00292   Subtract another vector componentwise.
00293   \param v vector of values to subtract
00294   \return Reference to self
00295   */
00296 template<class Scalar>
00297 inline const ntlMatrix4x4<Scalar>&
00298 ntlMatrix4x4<Scalar>::operator-=( const ntlMatrix4x4<Scalar> &v )
00299 {
00300   value[0][0] -= v.value[0][0]; value[0][1] -= v.value[0][1]; value[0][2] -= v.value[0][2]; value[0][3] -= v.value[0][3];
00301   value[1][0] -= v.value[1][0]; value[1][1] -= v.value[1][1]; value[1][2] -= v.value[1][2]; value[1][3] -= v.value[1][3];
00302   value[2][0] -= v.value[2][0]; value[2][1] -= v.value[2][1]; value[2][2] -= v.value[2][2]; value[2][3] -= v.value[2][3];
00303   value[3][0] -= v.value[3][0]; value[3][1] -= v.value[3][1]; value[3][2] -= v.value[3][2]; value[3][3] -= v.value[3][3];
00304   return *this;
00305 }
00306 
00307 
00308 /*************************************************************************
00309   Subtract a Scalar value from each component.
00310   \param s Value to subtract
00311   \return Reference to self
00312   */
00313 template<class Scalar>
00314 inline const ntlMatrix4x4<Scalar>&
00315 ntlMatrix4x4<Scalar>::operator-=(Scalar s)
00316 {
00317         for(int i=0; i<4; i++) {
00318                 for(int j=0; j<4; j++) {
00319                 value[i][j] -= s;
00320                 }
00321         }
00322   return *this;
00323 }
00324 
00325 
00326 /*************************************************************************
00327   Multiply with another vector componentwise.
00328   \param v vector of values to multiply with
00329   \return Reference to self
00330   */
00331 template<class Scalar>
00332 inline const ntlMatrix4x4<Scalar>&
00333 ntlMatrix4x4<Scalar>::operator*=( const ntlMatrix4x4<Scalar> &v )
00334 {
00335         ntlMatrix4x4<Scalar> nv(0.0);
00336         for(int i=0; i<4; i++) {
00337                 for(int j=0; j<4; j++) {
00338 
00339                         for(int k=0;k<4;k++)
00340                                 nv.value[i][j] += (value[i][k] * v.value[k][j]);
00341                 }
00342         }
00343   *this = nv;
00344   return *this;
00345 }
00346 
00347 
00348 /*************************************************************************
00349   Multiply each component with a Scalar value.
00350   \param s Value to multiply with
00351   \return Reference to self
00352   */
00353 template<class Scalar>
00354 inline const ntlMatrix4x4<Scalar>&
00355 ntlMatrix4x4<Scalar>::operator*=(Scalar s)
00356 {
00357         for(int i=0; i<4; i++) {
00358                 for(int j=0; j<4; j++) {
00359                 value[i][j] *= s;
00360                 }
00361         }
00362   return *this;
00363 }
00364 
00365 
00366 
00367 /*************************************************************************
00368   Divide each component by a Scalar value.
00369   \param s Value to divide by
00370   \return Reference to self
00371   */
00372 template<class Scalar>
00373 inline const ntlMatrix4x4<Scalar>&
00374 ntlMatrix4x4<Scalar>::operator/=(Scalar s)
00375 {
00376         for(int i=0; i<4; i++) {
00377                 for(int j=0; j<4; j++) {
00378                 value[i][j] /= s;
00379                 }
00380         }
00381   return *this;
00382 }
00383 
00384 
00385 //------------------------------------------------------------------------------
00386 // unary operators
00387 //------------------------------------------------------------------------------
00388 
00389 
00390 /*************************************************************************
00391   Build componentwise the negative this vector.
00392   \return The new (negative) vector
00393   */
00394 template<class Scalar>
00395 inline ntlMatrix4x4<Scalar>
00396 ntlMatrix4x4<Scalar>::operator-() const
00397 {
00398         ntlMatrix4x4<Scalar> nv;
00399         for(int i=0; i<4; i++) {
00400                 for(int j=0; j<4; j++) {
00401                 nv[i][j] = -value[i][j];
00402                 }
00403         }
00404   return nv;
00405 }
00406 
00407 
00408 
00409 //------------------------------------------------------------------------------
00410 // binary operators
00411 //------------------------------------------------------------------------------
00412 
00413 
00414 /*************************************************************************
00415   Build a vector with another vector added componentwise.
00416   \param v The second vector to add
00417   \return The sum vector
00418   */
00419 template<class Scalar>
00420 inline ntlMatrix4x4<Scalar>
00421 ntlMatrix4x4<Scalar>::operator+( const ntlMatrix4x4<Scalar> &v ) const
00422 {
00423         ntlMatrix4x4<Scalar> nv;
00424         for(int i=0; i<4; i++) {
00425                 for(int j=0; j<4; j++) {
00426                 nv[i][j] = value[i][j] + v.value[i][j];
00427                 }
00428         }
00429   return nv;
00430 }
00431 
00432 
00433 /*************************************************************************
00434   Build a vector with a Scalar value added to each component.
00435   \param s The Scalar value to add
00436   \return The sum vector
00437   */
00438 template<class Scalar>
00439 inline ntlMatrix4x4<Scalar>
00440 ntlMatrix4x4<Scalar>::operator+(Scalar s) const
00441 {
00442         ntlMatrix4x4<Scalar> nv;
00443         for(int i=0; i<4; i++) {
00444                 for(int j=0; j<4; j++) {
00445                 nv[i][j] = value[i][j] + s;
00446                 }
00447         }
00448   return nv;
00449 }
00450 
00451 
00452 /*************************************************************************
00453   Build a vector with another vector subtracted componentwise.
00454   \param v The second vector to subtract
00455   \return The difference vector
00456   */
00457 template<class Scalar>
00458 inline ntlMatrix4x4<Scalar>
00459 ntlMatrix4x4<Scalar>::operator-( const ntlMatrix4x4<Scalar> &v ) const
00460 {
00461         ntlMatrix4x4<Scalar> nv;
00462         for(int i=0; i<4; i++) {
00463                 for(int j=0; j<4; j++) {
00464                 nv[i][j] = value[i][j] - v.value[i][j];
00465                 }
00466         }
00467   return nv;
00468 }
00469 
00470 
00471 /*************************************************************************
00472   Build a vector with a Scalar value subtracted componentwise.
00473   \param s The Scalar value to subtract
00474   \return The difference vector
00475   */
00476 template<class Scalar>
00477 inline ntlMatrix4x4<Scalar>
00478 ntlMatrix4x4<Scalar>::operator-(Scalar s ) const
00479 {
00480         ntlMatrix4x4<Scalar> nv;
00481         for(int i=0; i<4; i++) {
00482                 for(int j=0; j<4; j++) {
00483                 nv[i][j] = value[i][j] - s;
00484                 }
00485         }
00486   return nv;
00487 }
00488 
00489 
00490 
00491 /*************************************************************************
00492   Build a ntlMatrix4x4 with a Scalar value multiplied to each component.
00493   \param s The Scalar value to multiply with
00494   \return The product vector
00495   */
00496 template<class Scalar>
00497 inline ntlMatrix4x4<Scalar>
00498 ntlMatrix4x4<Scalar>::operator*(Scalar s) const
00499 {
00500         ntlMatrix4x4<Scalar> nv;
00501         for(int i=0; i<4; i++) {
00502                 for(int j=0; j<4; j++) {
00503                 nv[i][j] = value[i][j] * s;
00504                 }
00505         }
00506   return nv;
00507 }
00508 
00509 
00510 
00511 
00512 /*************************************************************************
00513   Build a vector divided componentwise by a Scalar value.
00514   \param s The Scalar value to divide by
00515   \return The ratio vector
00516   */
00517 template<class Scalar>
00518 inline ntlMatrix4x4<Scalar>
00519 ntlMatrix4x4<Scalar>::operator/(Scalar s) const
00520 {
00521         ntlMatrix4x4<Scalar> nv;
00522         for(int i=0; i<4; i++) {
00523                 for(int j=0; j<4; j++) {
00524                 nv[i][j] = value[i][j] / s;
00525                 }
00526         }
00527   return nv;
00528 }
00529 
00530 
00531 
00532 
00533 
00534 /*************************************************************************
00535   Build a vector with another vector multiplied by componentwise.
00536   \param v The second vector to muliply with
00537   \return The product vector
00538   */
00539 template<class Scalar>
00540 inline ntlMatrix4x4<Scalar>
00541 ntlMatrix4x4<Scalar>::operator*( const ntlMatrix4x4<Scalar>& v) const
00542 {
00543         ntlMatrix4x4<Scalar> nv(0.0);
00544         for(int i=0; i<4; i++) {
00545                 for(int j=0; j<4; j++) {
00546 
00547                         for(int k=0;k<4;k++)
00548                                 nv.value[i][j] += (value[i][k] * v.value[k][j]);
00549                 }
00550         }
00551   return nv;
00552 }
00553 
00554 
00555 template<class Scalar>
00556 inline ntlVector3Dim<Scalar>
00557 ntlMatrix4x4<Scalar>::operator*( const ntlVector3Dim<Scalar>& v) const
00558 {
00559         ntlVector3Dim<Scalar> nvec(0.0);
00560         for(int i=0; i<3; i++) {
00561                 for(int j=0; j<3; j++) {
00562                         nvec[i] += (v[j] * value[i][j]);
00563                 }
00564         }
00565         // assume normalized w coord
00566         for(int i=0; i<3; i++) {
00567                 nvec[i] += (1.0 * value[i][3]);
00568         }
00569   return nvec;
00570 }
00571 
00572 
00573 
00574 //------------------------------------------------------------------------------
00575 // Other helper functions
00576 //------------------------------------------------------------------------------
00577 
00579 template<class Scalar>
00580 inline void ntlMatrix4x4<Scalar>::initId()
00581 {
00582         (*this) = (Scalar)(0.0);
00583         value[0][0] = 
00584         value[1][1] = 
00585         value[2][2] = 
00586         value[3][3] = (Scalar)(1.0);
00587 }
00588 
00590 template<class Scalar>
00591 inline void ntlMatrix4x4<Scalar>::initTranslation(Scalar x, Scalar y, Scalar z)
00592 {
00593         //(*this) = (Scalar)(0.0);
00594         this->initId();
00595         value[0][3] = x;
00596         value[1][3] = y;
00597         value[2][3] = z;
00598 }
00599 
00601 template<class Scalar>
00602 inline void 
00603 ntlMatrix4x4<Scalar>::initRotationX(Scalar rot)
00604 {
00605         double drot = (double)(rot/360.0*2.0*M_PI);
00606         //? while(drot < 0.0) drot += (M_PI*2.0);
00607 
00608         this->initId();
00609         value[1][1] = (Scalar)  cos(drot);
00610         value[1][2] = (Scalar)  sin(drot);
00611         value[2][1] = (Scalar)(-sin(drot));
00612         value[2][2] = (Scalar)  cos(drot);
00613 }
00614 template<class Scalar>
00615 inline void 
00616 ntlMatrix4x4<Scalar>::initRotationY(Scalar rot)
00617 {
00618         double drot = (double)(rot/360.0*2.0*M_PI);
00619         //? while(drot < 0.0) drot += (M_PI*2.0);
00620 
00621         this->initId();
00622         value[0][0] = (Scalar)  cos(drot);
00623         value[0][2] = (Scalar)(-sin(drot));
00624         value[2][0] = (Scalar)  sin(drot);
00625         value[2][2] = (Scalar)  cos(drot);
00626 }
00627 template<class Scalar>
00628 inline void 
00629 ntlMatrix4x4<Scalar>::initRotationZ(Scalar rot)
00630 {
00631         double drot = (double)(rot/360.0*2.0*M_PI);
00632         //? while(drot < 0.0) drot += (M_PI*2.0);
00633 
00634         this->initId();
00635         value[0][0] = (Scalar)  cos(drot);
00636         value[0][1] = (Scalar)  sin(drot);
00637         value[1][0] = (Scalar)(-sin(drot));
00638         value[1][1] = (Scalar)  cos(drot);
00639 }
00640 template<class Scalar>
00641 inline void 
00642 ntlMatrix4x4<Scalar>::initRotationXYZ( Scalar rotx, Scalar roty, Scalar rotz)
00643 {
00644         ntlMatrix4x4<Scalar> val;
00645         ntlMatrix4x4<Scalar> rot;
00646         this->initId();
00647 
00648         // org
00649         /*rot.initRotationX(rotx);
00650         (*this) *= rot;
00651         rot.initRotationY(roty);
00652         (*this) *= rot;
00653         rot.initRotationZ(rotz);
00654         (*this) *= rot;
00655         // org */
00656 
00657         // blender
00658         rot.initRotationZ(rotz);
00659         (*this) *= rot;
00660         rot.initRotationY(roty);
00661         (*this) *= rot;
00662         rot.initRotationX(rotx);
00663         (*this) *= rot;
00664         // blender */
00665 }
00666 
00668 template<class Scalar>
00669 inline void 
00670 ntlMatrix4x4<Scalar>::initScaling(Scalar scale)
00671 {
00672         this->initId();
00673         value[0][0] = scale;
00674         value[1][1] = scale;
00675         value[2][2] = scale;
00676 }
00678 template<class Scalar>
00679 inline void 
00680 ntlMatrix4x4<Scalar>::initScaling(Scalar x, Scalar y, Scalar z)
00681 {
00682         this->initId();
00683         value[0][0] = x;
00684         value[1][1] = y;
00685         value[2][2] = z;
00686 }
00687 
00688 
00690 template<class Scalar>
00691 inline void 
00692 ntlMatrix4x4<Scalar>::initArrayCheck(Scalar *array)
00693 {
00694         bool allZero = true;
00695         for(int i=0; i<4; i++) {
00696                 for(int j=0; j<4; j++) {
00697                         value[i][j] = array[i*4+j];
00698                         if(array[i*4+j]!=0.0) allZero=false;
00699                 }
00700         }
00701         if(allZero) this->initId();
00702 }
00703 
00705 template<class Scalar>
00706 void 
00707 ntlMatrix4x4<Scalar>::decompose(ntlVector3Dim<Scalar> &trans,ntlVector3Dim<Scalar> &scale,ntlVector3Dim<Scalar> &rot,ntlVector3Dim<Scalar> &shear) {
00708         ntlVec3Gfx row[3],temp;
00709 
00710         for(int i = 0; i < 3; i++) {
00711                 trans[i] = this->value[3][i];
00712         }
00713 
00714         for(int i = 0; i < 3; i++) {
00715                 row[i][0] = this->value[i][0];
00716                 row[i][1] = this->value[i][1];
00717                 row[i][2] = this->value[i][2];
00718         }
00719 
00720         scale[0] = norm(row[0]);
00721         normalize (row[0]);
00722 
00723         shear[0] = dot(row[0], row[1]);
00724         row[1][0] = row[1][0] - shear[0]*row[0][0];
00725         row[1][1] = row[1][1] - shear[0]*row[0][1];
00726         row[1][2] = row[1][2] - shear[0]*row[0][2];
00727 
00728         scale[1] = norm(row[1]);
00729         normalize (row[1]);
00730 
00731         if(scale[1] != 0.0)
00732                 shear[0] /= scale[1];
00733 
00734         shear[1] = dot(row[0], row[2]);
00735         row[2][0] = row[2][0] - shear[1]*row[0][0];
00736         row[2][1] = row[2][1] - shear[1]*row[0][1];
00737         row[2][2] = row[2][2] - shear[1]*row[0][2];
00738 
00739         shear[2] = dot(row[1], row[2]);
00740         row[2][0] = row[2][0] - shear[2]*row[1][0];
00741         row[2][1] = row[2][1] - shear[2]*row[1][1];
00742         row[2][2] = row[2][2] - shear[2]*row[1][2];
00743 
00744         scale[2] = norm(row[2]);
00745         normalize (row[2]);
00746 
00747         if(scale[2] != 0.0) {
00748                 shear[1] /= scale[2];
00749                 shear[2] /= scale[2];
00750         }
00751 
00752         temp = cross(row[1], row[2]);
00753         if(dot(row[0], temp) < 0.0) {
00754                 for(int i = 0; i < 3; i++) {
00755                         scale[i]  *= -1.0;
00756                         row[i][0] *= -1.0;
00757                         row[i][1] *= -1.0;
00758                         row[i][2] *= -1.0;
00759                 }
00760         }
00761 
00762         if(row[0][2] < -1.0) row[0][2] = -1.0;
00763         if(row[0][2] > +1.0) row[0][2] = +1.0;
00764 
00765         rot[1] = asin(-row[0][2]);
00766 
00767         if(fabs(cos(rot[1])) > VECTOR_EPSILON) {
00768                 rot[0] = atan2 (row[1][2], row[2][2]);
00769                 rot[2] = atan2 (row[0][1], row[0][0]);
00770         }
00771         else {
00772                 rot[0] = atan2 (row[1][0], row[1][1]);
00773                 rot[2] = 0.0;
00774         }
00775 
00776         rot[0] = (180.0/M_PI)*rot[0];
00777         rot[1] = (180.0/M_PI)*rot[1];
00778         rot[2] = (180.0/M_PI)*rot[2];
00779 } 
00780 
00781 #define NTL_MATRICES_H
00782 #endif
00783