Blender V2.61 - r43446

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