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
Documentation generated on Mon Jun 9 11:45:57 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |