OMKTransform.cpp

Go to the documentation of this file.
00001 /************************************************************************/
00002 /* This file is part of openMask(c) INRIA, CNRS, Universite de Rennes 1 */
00003 /* 1993-2002, thereinafter the Software                                 */
00004 /*                                                                      */
00005 /* The Software has been developped within the Siames Project.          */
00006 /* INRIA, the University of Rennes 1 and CNRS jointly hold intellectual */
00007 /* property rights                                                      */
00008 /*                                                                      */
00009 /* The Software has been registered with the Agence pour la Protection  */
00010 /* des Programmes (APP) under registration number                       */
00011 /* IDDN.FR.001.510008.00.S.P.2001.000.41200                             */
00012 /*                                                                      */
00013 /* This file may be distributed under the terms of the Q Public License */
00014 /* version 1.0 as defined by Trolltech AS of Norway and appearing in    */
00015 /* the file LICENSE.QPL included in the packaging of this file.         */
00016 /*                                                                      */
00017 /* Licensees holding valid specific licenses issued by INRIA, CNRS or   */
00018 /* Universite Rennes 1 for the software may use this file in            */
00019 /* acordance with that specific license                                 */
00020 /************************************************************************/
00021 #include "OMKTransform.h" 
00022 #include "OMKTransformType.h"
00023 
00024 using namespace OMK ;
00025 using namespace OMK::Type ;
00026 
00027 const Transform Transform::sk_identity;
00028 
00029 //-------------------------------------------------------------------------
00030 // constructor
00031 //-------------------------------------------------------------------------
00032 // default transform is the identity transformation
00033 Transform::Transform()
00034 : _matrix   ( 1.0f, 0.0f, 0.0f, 
00035               0.0f, 1.0f, 0.0f, 
00036               0.0f, 0.0f, 1.0f ),
00037   _translate( 0.0f, 0.0f, 0.0f ),
00038   _scale    ( 1.0f, 1.0f, 1.0f ),
00039   _identity    ( true ),
00040   _uniformScale( true )
00041 {
00042 } 
00043 
00044 //-------------------------------------------------------------------------
00045 // constructor
00046 //-------------------------------------------------------------------------
00047 Transform::Transform( const Wm4::Vector3f& translate, 
00048                       const Wm4::Matrix3f& rotate,// = Wm4::Matrix3f( 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f ), 
00049                       float scale ) // = 1.0f )
00050 : _matrix   ( rotate              ),
00051   _translate( translate           ),
00052   _scale    ( scale, scale, scale ),
00053   _identity    ( false     ),
00054   _uniformScale( true      )
00055 {
00056   OMASSERTM( scale != 0.0f, "scale cannot be null" ) ;
00057   updateFlags() ;
00058 } 
00059 
00060 //-------------------------------------------------------------------------
00061 // constructor
00062 //-------------------------------------------------------------------------
00063 Transform::Transform( const Wm4::Vector3f& translate,
00064                       const Wm4::Quaternionf& rotate, 
00065                       float scale ) // = 1.0f )
00066 : _matrix   (),
00067   _translate( translate           ),
00068   _scale    ( scale, scale, scale ),
00069   _identity    ( false     ),
00070   _uniformScale( true      )
00071 {
00072   rotate.ToRotationMatrix( _matrix ) ;
00073   OMASSERTM( scale != 0.0f, "scale cannot be null" ) ;
00074   updateFlags() ;
00075 } 
00076    
00077 //-------------------------------------------------------------------------
00078 // constructor
00079 //-------------------------------------------------------------------------
00080 Transform::Transform( const Wm4::Vector3f& translate, 
00081                       const Wm4::Matrix3f& rotate, 
00082                       const Wm4::Vector3f& scale ) 
00083 : _matrix   ( rotate           ),
00084   _translate( translate        ),
00085   _scale    ( scale            ),
00086   _identity    ( false     ),
00087   _uniformScale( false     )
00088 {                
00089   OMASSERTM( ( scale.X() != 0.0f 
00090             && scale.Y() != 0.0f
00091             && scale.Z() != 0.0f ), "scale cannot be a null vector" ) ;
00092   updateFlags() ;
00093 } 
00094 
00095 //-------------------------------------------------------------------------
00096 // constructor
00097 //-------------------------------------------------------------------------
00098 Transform::Transform( const Wm4::Vector3f& translate, 
00099                       const Wm4::Quaternionf& rotate, 
00100                       const Wm4::Vector3f& scale ) 
00101 : _matrix   (),
00102   _translate( translate        ),
00103   _scale    ( scale            ),
00104   _identity    ( false     ),
00105   _uniformScale( false     )
00106 {         
00107   rotate.ToRotationMatrix( _matrix ) ;
00108   OMASSERTM( ( scale.X() != 0.0f 
00109             && scale.Y() != 0.0f
00110             && scale.Z() != 0.0f ), "scale cannot be a null vector" ) ;
00111   updateFlags() ;
00112 } 
00113 
00114 //-------------------------------------------------------------------------
00115 // destructor
00116 //-------------------------------------------------------------------------
00117 Transform::~Transform()
00118 {
00119 }
00120 
00121 //-------------------------------------------------------------------------
00122 // resetUnitScale
00123 //-------------------------------------------------------------------------
00124 void 
00125 Transform::resetUnitScale ()
00126 {
00127   _scale = Wm4::Vector3f( 1.0f, 1.0f, 1.0f );
00128   _uniformScale = true;
00129 }
00130 
00131 //-------------------------------------------------------------------------
00132 // getNorm
00133 //-------------------------------------------------------------------------
00134 float 
00135 Transform::getNorm() const
00136 {
00137   float sX = (float)::fabs( _scale.X() ) ;
00138   float sY = (float)::fabs( _scale.Y() ) ;
00139   float sZ = (float)::fabs( _scale.Z() ) ;
00140   return sX < sY ? ( sY < sZ ? sZ : sY ) : ( sX < sZ ? sZ : sX ) ;
00141 }
00142 
00143 //-------------------------------------------------------------------------
00144 // setTranslate
00145 //-------------------------------------------------------------------------
00146 void 
00147 Transform::setTranslate( const Wm4::Vector3f& translate )
00148 {
00149     _translate = translate ;
00150     _identity  = false     ;
00151 }
00152 
00153 //-------------------------------------------------------------------------
00154 // setRotate
00155 //-------------------------------------------------------------------------
00156 void 
00157 Transform::setRotate( const Wm4::Matrix3f& rotate )
00158 {
00159   _matrix   = rotate ;
00160   _identity = false  ;
00161 }
00162 
00163 //-------------------------------------------------------------------------
00164 // setRotate
00165 //-------------------------------------------------------------------------
00166 void 
00167 Transform::setRotate( const Wm4::Quaternionf& rotate )
00168 {
00169   rotate.ToRotationMatrix( _matrix ) ;
00170   _identity = false  ;
00171 }
00172 
00173 //-------------------------------------------------------------------------
00174 // setScale
00175 //-------------------------------------------------------------------------
00176 void 
00177 Transform::setScale( const Wm4::Vector3f& scale )
00178 {
00179   OMASSERTM( ( scale.X() != 0.0f 
00180             && scale.Y() != 0.0f
00181             && scale.Z() != 0.0f ), "The scale vector cannot be null" ) ;
00182   _scale        = scale ;
00183   _identity     = false ;
00184   _uniformScale = false ;
00185 }
00186 
00187 //-------------------------------------------------------------------------
00188 // setUniformScale
00189 //-------------------------------------------------------------------------
00190 void 
00191 Transform::setUniformScale( float scale )
00192 {
00193   OMASSERTM( scale != 0.0f, "The scale cannot be null" );
00194   _scale        = Wm4::Vector3f( scale, scale, scale ) ;
00195   _identity     = false ;
00196   _uniformScale = true  ;
00197 }
00198 
00199 //-------------------------------------------------------------------------
00200 // applyForward
00201 //-------------------------------------------------------------------------
00202 Wm4::Vector3f 
00203 Transform::applyForward( const Wm4::Vector3f& input ) const
00204 {
00205   Wm4::Vector3f output ;
00206   if( isIdentity() )
00207   { // Y = X
00208     output = input;
00209   }
00210   else
00211   {
00212     // Y = R*S*X + T
00213     output = Wm4::Vector3f( _scale.X() * input.X(), 
00214                             _scale.Y() * input.Y(),
00215                             _scale.Z() * input.Z() );
00216     output = _matrix * output + _translate;
00217   }
00218   return output;
00219 }
00220 
00221 //-------------------------------------------------------------------------
00222 // applyForward
00223 //-------------------------------------------------------------------------
00224 std::vector<Wm4::Vector3f> 
00225 Transform::applyForward( const std::vector<Wm4::Vector3f>& input ) const
00226 {
00227   std::vector<Wm4::Vector3f> output ;
00228   if ( isIdentity() )
00229   {
00230     // Y = X
00231     output = input ;
00232   }
00233   else
00234   {
00235     // Y = R*S*X + T
00236     output.resize( input.size() ) ;
00237     for( unsigned int i( 0 ) ; i < input.size() ; ++i )
00238   {
00239         output[i].X() = _scale.X() * input[i].X() ;
00240         output[i].Y() = _scale.Y() * input[i].Y() ;
00241         output[i].Z() = _scale.Z() * input[i].Z() ;
00242         output[i] = _matrix * output[i] + _translate;
00243     }
00244   }
00245   return output ;
00246 }
00247 
00248 //-------------------------------------------------------------------------
00249 // applyInverse
00250 //-------------------------------------------------------------------------
00251 Wm4::Vector3f 
00252 Transform::applyInverse( const Wm4::Vector3f& input ) const
00253 {
00254     Wm4::Vector3f output ;
00255     if (_identity)
00256     {
00257       // X = Y
00258       output = input;
00259     }
00260     else
00261     {
00262       output = input - _translate ;
00263       // X = S^{-1}*R^t*(Y - T)
00264       output = output * _matrix;
00265       if( isUniformScale() )
00266       {
00267         output /= getUniformScale();
00268       }
00269       else
00270       {
00271         // The direct inverse scaling is
00272         //   output.X() /= _scale.X();
00273         //   output.Y() /= _scale.Y();
00274         //   output.Z() /= _scale.Z();
00275         // When division is much more expensive than multiplication,
00276         // three divisions are replaced by one division and ten
00277         // multiplications.
00278         float SXY = _scale.X() * _scale.Y() ;
00279         float SXZ = _scale.X() * _scale.Z() ;
00280         float SYZ = _scale.Y() * _scale.Z() ;
00281         float invDet = 1.0f / ( SXY * _scale.Z() ) ;
00282         output.X() *= invDet * SYZ ;
00283         output.Y() *= invDet * SXZ ;
00284         output.Z() *= invDet * SXY ;
00285       }
00286     }
00287     return output;
00288 }
00289 
00290 //-------------------------------------------------------------------------
00291 // applyInverse
00292 //-------------------------------------------------------------------------
00293 std::vector<Wm4::Vector3f> 
00294 Transform::applyInverse( const std::vector<Wm4::Vector3f>& input ) const
00295 {
00296   std::vector<Wm4::Vector3f> output ;
00297   if (_identity)
00298   {
00299     output = input ;
00300   }
00301   else
00302   {
00303     Wm4::Vector3f diff;
00304     // X = S^{-1}*R^t*(Y - T)
00305     if ( isUniformScale() )
00306     {
00307       float invScale = 1.0f / getUniformScale() ;
00308       for( unsigned int i( 0 ) ; i < input.size() ; ++i )
00309       {
00310         output.push_back( invScale * ( ( input[i] - _translate ) * _matrix ) );
00311       }
00312     }
00313     else
00314     {
00315       // The direct inverse scaling is
00316       //   invXScale = 1.0f/_scale.X();
00317       //   invYScale = 1.0f/_scale.Y();
00318       //   invZScale = 1.0f/_scale.Z();
00319       // When division is much more expensive than multiplication, three
00320       // divisions are replaced by one division and ten multiplications.
00321       float SXY = _scale.X() * _scale.Y() ;
00322       float SXZ = _scale.X() * _scale.Z() ;
00323       float SYZ = _scale.Y() * _scale.Z() ;
00324       float invDet = 1.0f / ( SXY * _scale.Z() ) ;
00325       float invXScale = invDet * SYZ ;
00326       float invYScale = invDet * SXZ ;
00327       float invZScale = invDet * SXY ;
00328       for( unsigned int i( 0 ) ; i < input.size() ; ++i )
00329       {
00330         output.push_back( ( input[i] - _translate ) * _matrix );
00331         output[i].X() *= invXScale;
00332         output[i].Y() *= invYScale;
00333         output[i].Z() *= invZScale;
00334       }
00335     }
00336   }
00337   return output ;
00338 }
00339 
00340 //-------------------------------------------------------------------------
00341 // invertVector
00342 //-------------------------------------------------------------------------
00343 Wm4::Vector3f 
00344 Transform::invertVector( const Wm4::Vector3f& input ) const
00345 {
00346   Wm4::Vector3f output;
00347   if( isIdentity() )
00348   {
00349     // X = Y
00350     output = input ;
00351   }
00352   else
00353   {
00354     // X = S^{-1}*R^t*Y
00355     output = input * _matrix ;
00356     if ( isUniformScale() )
00357     {
00358       output /= getUniformScale() ;
00359     }
00360     else
00361     {
00362       // The direct inverse scaling is
00363       //   output.X() /= _scale.X();
00364       //   output.Y() /= _scale.Y();
00365       //   output.Z() /= _scale.Z();
00366       // When division is much more expensive than multiplication,
00367       // three divisions are replaced by one division and ten
00368       // multiplications.
00369       float SXY = _scale.X() * _scale.Y() ;
00370       float SXZ = _scale.X() * _scale.Z() ;
00371       float SYZ = _scale.Y() * _scale.Z() ;
00372       float invDet = 1.0f/( SXY * _scale.Z() ) ;
00373       output.X() *= invDet * SYZ ;
00374       output.Y() *= invDet * SXZ ;
00375       output.Z() *= invDet * SXY ;
00376     }
00377   }
00378   return output;
00379 }
00380 
00381 //-------------------------------------------------------------------------
00382 // applyForward
00383 //-------------------------------------------------------------------------
00384 Wm4::Plane3f 
00385 Transform::applyForward( const Wm4::Plane3f& input ) const
00386 {
00387   Wm4::Plane3f output ;
00388   if( isIdentity() )
00389   {
00390     output = input;
00391   }
00392   // Let X represent points in model space and Y = R*S*X+T represent
00393   // points in world space where S are the world scales, R is the world
00394   // rotation, and T is the world translation.  The inverse transform is
00395   // X = S^{-1}*R^t*(Y-T).  The model plane is Dot(N0,X) = C0.
00396   // Replacing the formula for X in it and applying some algebra leads
00397   // to the world plane Dot(N1,Y) = C1 where N1 = R*S^{-1}*N0 and
00398   // C1 = C0+Dot(N1,T).  If S is not the identity, then N1 is not unit
00399   // length.  We need to normalize N1 and adjust C1:  N1' = N1/|N1| and
00400   // C1' = C1/|N1|.
00401   else if ( isUniformScale() )
00402   {
00403     output.Normal   = _matrix * input.Normal ;
00404     output.Constant = getUniformScale() * input.Constant +
00405                       output.Normal.Dot( _translate );
00406   }
00407   else 
00408   {
00409     output.Normal = input.Normal ;
00410 
00411     // The direct inverse scaling is
00412     //   output.X() /= _scale.X();
00413     //   output.Y() /= _scale.Y();
00414     //   output.Z() /= _scale.Z();
00415     // When division is much more expensive than multiplication,
00416     // three divisions are replaced by one division and ten
00417     // multiplications.
00418     float SXY = _scale.X() * _scale.Y() ;
00419     float SXZ = _scale.X() * _scale.Z() ;
00420     float SYZ = _scale.Y() * _scale.Z() ;
00421     float invDet = 1.0f / ( SXY * _scale.Z() ) ;
00422     output.Normal.X() *= invDet * SYZ;
00423     output.Normal.Y() *= invDet * SXZ;
00424     output.Normal.Z() *= invDet * SXY;
00425     output.Normal = _matrix * output.Normal;
00426   
00427     float fInvLength = 1.0f / output.Normal.Length() ;
00428     output.Normal *= fInvLength ;
00429     output.Constant = fInvLength * input.Constant +
00430                       output.Normal.Dot( _translate );
00431   }
00432   return output;
00433 }
00434 
00435 //-------------------------------------------------------------------------
00436 // product
00437 //-------------------------------------------------------------------------
00438 Transform 
00439 OMK::Type::product( const Transform& A, const Transform& B )
00440 {
00441   Transform output ;
00442   if( A.isIdentity() )
00443   {
00444     output = B ;
00445   }
00446   else if( B.isIdentity() )
00447   {
00448     output = A ;
00449   }
00450   else
00451   {
00452     if( !A.isUniformScale() )
00453     {
00454       // set correctly "_uniformScale" boolean in A if needed
00455       const_cast< Transform& >( A )._uniformScale = ( A._scale[0] == A._scale[1] && A._scale[1] == A._scale[2] ) ;
00456     }
00457 
00458     output.setRotate( A._matrix * B._matrix ) ;
00459 
00460     if( A.isUniformScale() )
00461     {
00462       output.setTranslate( A.getUniformScale() * ( A._matrix * B._translate ) + A._translate ) ;
00463 
00464       if ( B.isUniformScale() )
00465       {
00466         output.setUniformScale( A.getUniformScale() * B.getUniformScale() ) ;
00467       }
00468       else
00469       {
00470         output.setScale( A.getUniformScale() * B.getScale() ) ;
00471       }
00472     }
00473     else
00474     {
00475       Wm4::Vector3f v0_translate( A._matrix * B._translate ) ;
00476       Wm4::Vector3f v1_translate( A.getScale()[0] * v0_translate[0],
00477                                   A.getScale()[1] * v0_translate[1],
00478                                   A.getScale()[2] * v0_translate[2] ) ;
00479       output.setTranslate( v1_translate + A._translate ) ;
00480 
00481       if ( B.isUniformScale() )
00482       {
00483         output.setScale( A.getScale() * B.getUniformScale() ) ;
00484       }
00485       else
00486       {
00487         Wm4::Vector3f v0_scale( A._matrix * B._scale ) ;
00488         Wm4::Vector3f v1_scale( A.getScale()[0] * v0_scale[0],
00489                                 A.getScale()[1] * v0_scale[1],
00490                                 A.getScale()[2] * v0_scale[2] ) ;
00491         output.setScale( v1_scale ) ;
00492       }
00493     }
00494   }
00495   return output ;
00496 }
00497 
00498 //-------------------------------------------------------------------------
00499 // inverse
00500 //-------------------------------------------------------------------------
00501 Transform 
00502 Transform::inverse() const
00503 { 
00504   Transform inverse ;
00505   if( _identity )
00506   {
00507     inverse = *this;
00508   }
00509   else 
00510   {
00511     if( _uniformScale )
00512     {
00513       inverse._matrix = getRotate().Transpose() / _scale[0];
00514       inverse._uniformScale = _scale[0] != 1.0 ;
00515     }
00516     else
00517     {
00518       Wm4::Matrix3f RS = _matrix.TimesDiagonal( _scale ) ;
00519       inverse._matrix = RS.Inverse() ;
00520       inverse._uniformScale = false;
00521     }
00522 
00523     inverse._translate = -( inverse._matrix * _translate );
00524     inverse._identity     = false;
00525   }
00526   return inverse ;
00527 }
00528 
00529 //-------------------------------------------------------------------------
00530 // updateFlags
00531 //-------------------------------------------------------------------------
00532 void Transform::updateFlags() 
00533 {
00534   if( !_identity )
00535   { // Not declared identity
00536     if( ( _matrix == Wm4::Matrix3f::IDENTITY ) 
00537      && ( _translate == Wm4::Vector3f::ZERO )
00538      && ( _scale == Wm4::Vector3f::ONE ) )
00539     { // Test identity
00540       _identity = true ;
00541       _uniformScale = true ;
00542     }
00543     else
00544     {
00545 #if !defined NDEBUG      
00546       // is it a pure rotation
00547       if( ( ( _matrix != Wm4::Matrix3f::IDENTITY ) 
00548         && ( ( _matrix * _matrix.Transpose() != Wm4::Matrix3f::IDENTITY )
00549           || ( _matrix.Determinant() != 1.0f ) ) ) )
00550       {
00551         Wm4::Matrix3f m( _matrix * _matrix.Transpose() ) ;
00552         OMTRACEID( OMK_DEBUG_OMK_TYPE,
00553                    "This transform is not a pure RS one, may be you will encounter some problem with it" << std::endl << *this ) ;
00554       }
00555 #endif 
00556       // is it a uniform scale
00557       _uniformScale = ( _scale[0] == _scale[1] && _scale[1] == _scale[2] ) ;
00558     }
00559   }
00560 }
00561 
00562 //-------------------------------------------------------------------------
00563 // getHomogeneous
00564 //-------------------------------------------------------------------------
00565 Wm4::Matrix4f 
00566 Transform::getHomogeneous() const
00567 {
00568   Wm4::Matrix4f hMatrix ;
00569   hMatrix[0][0] = _scale[0] * _matrix[0][0] ;
00570   hMatrix[0][1] = _scale[0] * _matrix[1][0] ;
00571   hMatrix[0][2] = _scale[0] * _matrix[2][0] ;
00572   hMatrix[0][3] = 0.0f ;
00573   hMatrix[1][0] = _scale[1] * _matrix[0][1] ;
00574   hMatrix[1][1] = _scale[1] * _matrix[1][1] ;
00575   hMatrix[1][2] = _scale[1] * _matrix[2][1] ;
00576   hMatrix[1][3] = 0.0f ;
00577   hMatrix[2][0] = _scale[2] * _matrix[0][2] ;
00578   hMatrix[2][1] = _scale[2] * _matrix[1][2] ;
00579   hMatrix[2][2] = _scale[2] * _matrix[2][2] ;
00580   hMatrix[2][3] = 0.0f ;
00581   hMatrix[3][0] = _translate[0] ;
00582   hMatrix[3][1] = _translate[1] ;
00583   hMatrix[3][2] = _translate[2] ;
00584   hMatrix[3][3] = 1.0f ;
00585   
00586   return hMatrix ;
00587 }
00588 
00589 //-------------------------------------------------------------------------
00590 // operator ==
00591 //-------------------------------------------------------------------------
00592 bool
00593 OMK::Type::operator == ( const Transform& t0, const Transform& t1 )
00594 {
00595   return (  t0._identity == t1._identity &&
00596             t0._uniformScale == t1._uniformScale && 
00597             t0._translate == t1._translate && 
00598             t0._scale == t1._scale && 
00599             t0._matrix == t1._matrix ) ;
00600 }
00601 
00602 //-------------------------------------------------------------------------
00603 // operator !=
00604 //-------------------------------------------------------------------------
00605 bool
00606 OMK::Type::operator != ( const Transform& t0, const Transform& t1 )
00607 {
00608   return !( t0 == t1 ) ;
00609 }
00610 //-------------------------------------------------------------------------
00611 // operator <<
00612 //-------------------------------------------------------------------------
00613 std::ostream& operator << ( std::ostream& out, const Transform& q )
00614 {
00615   out << q.isIdentity() << " " ;
00616   if( !q.isIdentity() )
00617   {
00618     out << q.isUniformScale()    << " "
00619         << q.getTranslate().X()  << " "
00620         << q.getTranslate().Y()  << " "
00621         << q.getTranslate().Z()  << " "
00622         << q.getRotate()( 0, 0 ) << " "
00623         << q.getRotate()( 0, 1 ) << " "
00624         << q.getRotate()( 0, 2 ) << " "
00625         << q.getRotate()( 1, 0 ) << " "
00626         << q.getRotate()( 1, 1 ) << " "
00627         << q.getRotate()( 1, 2 ) << " "
00628         << q.getRotate()( 2, 0 ) << " "
00629         << q.getRotate()( 2, 1 ) << " "
00630         << q.getRotate()( 2, 2 ) << " "
00631         << q.getScale().X()      << " "
00632         << q.getScale().Y()      << " "
00633         << q.getScale().Z()      << " "  ;
00634   }
00635   out << " " ;
00636   return out;
00637 }
00638 
00639 //-------------------------------------------------------------------------
00640 // operator >>
00641 //-------------------------------------------------------------------------
00642 std::istream& operator >> ( std::istream& in, Transform& q ) 
00643 {
00644   bool isIdentity = false ;
00645   in >> isIdentity ;
00646   if( isIdentity )
00647   {
00648     q.resetToIdentity() ;
00649   }
00650   else
00651   {
00652     bool isUniformScale ;
00653     Wm4::Vector3f translate ;
00654     Wm4::Matrix3f matrix ;
00655     Wm4::Vector3f scale ;
00656     in >> isUniformScale 
00657        >> translate.X()
00658        >> translate.Y()
00659        >> translate.Z() 
00660        >> matrix( 0, 0 ) 
00661        >> matrix( 0, 1 ) 
00662        >> matrix( 0, 2 ) 
00663        >> matrix( 1, 0 ) 
00664        >> matrix( 1, 1 ) 
00665        >> matrix( 1, 2 ) 
00666        >> matrix( 2, 0 ) 
00667        >> matrix( 2, 1 ) 
00668        >> matrix( 2, 2 ) 
00669        >> scale.X()  
00670        >> scale.Y()  
00671        >> scale.Z() ;
00672     q.setTranslate( translate ) ;
00673     q.setRotate( matrix ) ;
00674     if( isUniformScale ) q.setUniformScale( scale.X() ) ; else q.setScale( scale ) ;
00675   }
00676   return in;
00677 }
00678 
00679 //-------------------------------------------------------------------------
00680 // operator <<
00681 //-------------------------------------------------------------------------
00682 OutgoingSynchronisationMessage& operator << ( OutgoingSynchronisationMessage& out, const Transform& q ) 
00683 {
00684   out << q.isIdentity() ;
00685   if( !q.isIdentity() )
00686   {
00687     out << q.isUniformScale()    
00688         << q.getTranslate().X()  
00689         << q.getTranslate().Y()  
00690         << q.getTranslate().Z()  
00691         << q.getRotate()( 0, 0 ) 
00692         << q.getRotate()( 0, 1 ) 
00693         << q.getRotate()( 0, 2 ) 
00694         << q.getRotate()( 1, 0 ) 
00695         << q.getRotate()( 1, 1 ) 
00696         << q.getRotate()( 1, 2 ) 
00697         << q.getRotate()( 2, 0 ) 
00698         << q.getRotate()( 2, 1 ) 
00699         << q.getRotate()( 2, 2 ) 
00700         << q.getScale().X()      
00701         << q.getScale().Y()      
00702         << q.getScale().Z()      ;
00703   }
00704   return out;
00705 }
00706 
00707 //-------------------------------------------------------------------------
00708 // operator >>
00709 //-------------------------------------------------------------------------
00710 IncomingSynchronisationMessage& operator >> ( IncomingSynchronisationMessage& in, Transform& q ) 
00711 {
00712   bool isIdentity = false ;
00713   in >> isIdentity ;
00714   if( isIdentity )
00715   {
00716     q.resetToIdentity() ;
00717   }
00718   else
00719   {
00720     bool isUniformScale ;
00721     Wm4::Vector3f translate ;
00722     Wm4::Matrix3f matrix ;
00723     Wm4::Vector3f scale ;
00724     in >> isUniformScale 
00725        >> translate.X()
00726        >> translate.Y()
00727        >> translate.Z() 
00728        >> matrix( 0, 0 ) 
00729        >> matrix( 0, 1 ) 
00730        >> matrix( 0, 2 ) 
00731        >> matrix( 1, 0 ) 
00732        >> matrix( 1, 1 ) 
00733        >> matrix( 1, 2 ) 
00734        >> matrix( 2, 0 ) 
00735        >> matrix( 2, 1 ) 
00736        >> matrix( 2, 2 ) 
00737        >> scale.X()  
00738        >> scale.Y()  
00739        >> scale.Z() ;
00740     q.setTranslate( translate ) ;
00741     q.setRotate( matrix ) ;
00742     if( isUniformScale ) q.setUniformScale( scale.X() ) ; else q.setScale( scale ) ;
00743   }
00744   return in;
00745 }
00746 

logo OpenMask

Documentation generated on Mon Jun 9 11:45:57 2008

Generated with doxygen by Dimitri van Heesch ,   1997-2007