00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef SOFA_DEFAULTTYPE_SOLIDTYPES_INL
00039 #define SOFA_DEFAULTTYPE_SOLIDTYPES_INL
00040
00041 #include <sofa/defaulttype/SolidTypes.h>
00042 #include <sofa/helper/system/gl.h>
00043 #include <iostream>
00044 using std::cerr;
00045 using std::endl;
00046
00047 namespace sofa
00048 {
00049
00050 namespace defaulttype
00051 {
00052
00053 template<class R>
00054 SolidTypes<R>::SpatialVector::SpatialVector()
00055 {}
00056
00057 template<class R>
00058 SolidTypes<R>::SpatialVector::SpatialVector( const Vec& l, const Vec& f ):lineVec(l),freeVec(f)
00059 {}
00060
00061 template<class R>
00062 void SolidTypes<R>::SpatialVector::clear()
00063 {
00064 lineVec = freeVec = Vec(0,0,0);
00065 }
00066
00067 template<class R>
00068 typename SolidTypes<R>::SpatialVector& SolidTypes<R>::SpatialVector::operator += (const SpatialVector& v)
00069 {
00070 lineVec += v.lineVec;
00071 freeVec += v.freeVec;
00072 return *this;
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 template<class R>
00089 typename SolidTypes<R>::SpatialVector SolidTypes<R>::SpatialVector::operator + ( const SpatialVector& v ) const
00090 {
00091 return SpatialVector(lineVec+v.lineVec,freeVec+v.freeVec);
00092 }
00093
00094 template<class R>
00095 typename SolidTypes<R>::SpatialVector SolidTypes<R>::SpatialVector::operator - ( const SpatialVector& v ) const
00096 {
00097 return SpatialVector(lineVec-v.lineVec,freeVec-v.freeVec);
00098 }
00099
00100 template<class R>
00101 typename SolidTypes<R>::SpatialVector SolidTypes<R>::SpatialVector::operator - ( ) const
00102 {
00103 return SpatialVector(-lineVec,-freeVec);
00104 }
00105
00107 template<class R>
00108 typename SolidTypes<R>::Real SolidTypes<R>::SpatialVector::operator * ( const SpatialVector& v ) const
00109 {
00110
00111 return lineVec * v.freeVec + freeVec * v.lineVec;
00112 }
00113
00115 template<class R>
00116 typename SolidTypes<R>::SpatialVector SolidTypes<R>::SpatialVector::cross( const SpatialVector& v ) const
00117 {
00118 return SpatialVector(
00119 defaulttype::cross(lineVec,v.lineVec),
00120 defaulttype::cross(freeVec,v.lineVec) + defaulttype::cross(lineVec,v.freeVec)
00121 );
00122 }
00123
00124 template<class R>
00125 typename SolidTypes<R>::SpatialVector SolidTypes<R>::SpatialVector::operator * (const Mat66& m) const
00126 {
00127 SpatialVector result;
00128 for( int i=0; i<3; i++ )
00129 {
00130 result.lineVec[i]=0;
00131 result.freeVec[i]=0;
00132 for( int j=0; j<3; j++ )
00133 {
00134 result.lineVec[i] += lineVec[j]*m[i][j] + freeVec[j]*m[i][j+3];
00135 result.freeVec[i] += lineVec[j]*m[i+3][j] + freeVec[j]*m[i+3][j+3];
00136 }
00137 }
00138 return result;
00139 }
00140
00141
00142 template<class R>
00143 SolidTypes<R>::Transform::Transform()
00144 {
00145 *this = this->identity();
00146 }
00147
00149 template<class R>
00150 SolidTypes<R>::Transform::Transform( const Rot& q, const Vec& o ):orientation_(q),origin_(o)
00151 {}
00152
00154 template<class R>
00155 SolidTypes<R>::Transform::Transform( const Vec& t, const Rot& q )
00156 :orientation_(q),origin_(-(q.inverseRotate(t)))
00157 {}
00158
00160 template<class R>
00161 void SolidTypes<R>::Transform::set
00162 ( const Vec& t, const Rot& q )
00163 {
00164 orientation_ =q, origin_ = -(q.inverseRotate(t));
00165 }
00166
00168
00169
00170
00171
00172
00173
00174
00175
00176 template<class R>
00177 typename SolidTypes<R>::Transform SolidTypes<R>::Transform::identity()
00178 {
00179 return Transform( Rot::identity(), Vec(0,0,0) );
00180 }
00181
00183 template<class R>
00184 SolidTypes<R>::Transform::Transform( const SpatialVector& v )
00185 {
00186
00187 orientation_ = Rot::createFromRotationVector( v.lineVec );
00188 origin_ = - orientation_.inverseRotate( v.freeVec );
00189
00190 }
00191
00192 template<class R>
00193 const typename SolidTypes<R>::Vec& SolidTypes<R>::Transform::getOriginOfParentInChild() const
00194 {
00195 return origin_;
00196 }
00197
00198 template<class R>
00199 typename SolidTypes<R>::Vec SolidTypes<R>::Transform::getOrigin() const
00200 {
00201 return -orientation_.rotate(origin_);
00202 }
00203
00204 template<class R>
00205 void SolidTypes<R>::Transform::setOrigin( const Vec& op )
00206 {
00207 origin_ = -orientation_.inverseRotate(op);
00208 }
00209
00210 template<class R>
00211 const typename SolidTypes<R>::Rot& SolidTypes<R>::Transform::getOrientation() const
00212 {
00213 return orientation_;
00214 }
00215
00216 template<class R>
00217 void SolidTypes<R>::Transform::setOrientation( const Rot& q )
00218 {
00219 orientation_=q;
00220 }
00221
00222 template<class R>
00223 typename SolidTypes<R>::Vec SolidTypes<R>::Transform::projectVector( const Vec& v ) const
00224 {
00225 return orientation_.rotate( v );
00226 }
00227
00228 template<class R>
00229 typename SolidTypes<R>::Vec SolidTypes<R>::Transform::projectPoint( const Vec& p ) const
00230 {
00231 return orientation_.rotate( p - origin_ );
00232 }
00233
00234 template<class R>
00235 typename SolidTypes<R>::Vec SolidTypes<R>::Transform::backProjectVector( const Vec& v ) const
00236 {
00237 return orientation_.inverseRotate( v );
00238 }
00239
00240 template<class R>
00241 typename SolidTypes<R>::Vec SolidTypes<R>::Transform::backProjectPoint( const Vec& p ) const
00242 {
00243 return orientation_.inverseRotate( p ) + origin_;
00244 }
00245
00246 template<class R>
00247 typename SolidTypes<R>::Mat SolidTypes<R>::Transform::getRotationMatrix() const
00248 {
00249 Mat m;
00250 m[0][0] = (1.0f - 2.0f * (orientation_[1] * orientation_[1] + orientation_[2] * orientation_[2]));
00251 m[0][1] = (2.0f * (orientation_[0] * orientation_[1] - orientation_[2] * orientation_[3]));
00252 m[0][2] = (2.0f * (orientation_[2] * orientation_[0] + orientation_[1] * orientation_[3]));
00253
00254 m[1][0] = (2.0f * (orientation_[0] * orientation_[1] + orientation_[2] * orientation_[3]));
00255 m[1][1] = (1.0f - 2.0f * (orientation_[2] * orientation_[2] + orientation_[0] * orientation_[0]));
00256 m[1][2] = (2.0f * (orientation_[1] * orientation_[2] - orientation_[0] * orientation_[3]));
00257
00258 m[2][0] = (2.0f * (orientation_[2] * orientation_[0] - orientation_[1] * orientation_[3]));
00259 m[2][1] = (2.0f * (orientation_[1] * orientation_[2] + orientation_[0] * orientation_[3]));
00260 m[2][2] = (1.0f - 2.0f * (orientation_[1] * orientation_[1] + orientation_[0] * orientation_[0]));
00261 return m;
00262 }
00263
00264 template<class R>
00265 void SolidTypes<R>::Transform::clear()
00266 {
00267 orientation_.clear();
00268 origin_=Vec(0,0,0);
00269 }
00270
00271 template<class R>
00272 typename SolidTypes<R>::Transform SolidTypes<R>::Transform::operator * (const Transform& f2) const
00273 {
00274
00275 return Transform( orientation_ * f2.getOrientation(), f2.getOriginOfParentInChild() + f2.getOrientation().inverseRotate(origin_)) ;
00276 }
00277
00278 template<class R>
00279 typename SolidTypes<R>::Transform& SolidTypes<R>::Transform::operator *= (const Transform& f2)
00280 {
00281 orientation_ *= f2.getOrientation();
00282 origin_ = f2.getOriginOfParentInChild() + f2.getOrientation().inverseRotate(origin_);
00283 return (*this);
00284 }
00285
00286 template<class R>
00287 typename SolidTypes<R>::SpatialVector SolidTypes<R>::Transform::operator * (const SpatialVector& sv ) const
00288 {
00289 return SpatialVector(
00290 orientation_.rotate(sv.lineVec),
00291 orientation_.rotate(sv.freeVec - cross( origin_, sv.lineVec) )
00292 );
00293 }
00294
00295 template<class R>
00296 typename SolidTypes<R>::SpatialVector SolidTypes<R>::Transform::operator / (const SpatialVector& sv ) const
00297 {
00298 return inversed()*sv;
00299 }
00300
00301
00302
00303
00304 template<class R>
00305 typename SolidTypes<R>::Transform SolidTypes<R>::Transform::inversed() const
00306 {
00307
00308 return Transform( orientation_.inverse(), -(orientation_.rotate(origin_)) );
00309 }
00310
00311 template<class R>
00312 void SolidTypes<R>::Transform::writeOpenGlMatrix( double *m ) const
00313 {
00314
00315
00316 orientation_.writeOpenGlMatrix(m);
00317 Vec t = getOrigin();
00318
00319 m[12] = t[0];
00320 m[13] = t[1];
00321 m[14] = t[2];
00322 }
00323
00324 template<class R>
00325 void SolidTypes<R>::Transform::glDraw() const
00326 {
00327 glPushAttrib( GL_COLOR_BUFFER_BIT );
00328 glColor3f(1,0,0);
00329 glVertex3f( 0,0,0 );
00330 glVertex3f( 1,0,0 );
00331 glColor3f(0,1,0);
00332 glVertex3f( 0,0,0 );
00333 glVertex3f( 0,1,0 );
00334 glColor3f(0,0,1);
00335 glVertex3f( 0,0,0 );
00336 glVertex3f( 0,0,1 );
00337 glPopAttrib();
00338 }
00339
00340 template<class R>
00341 void SolidTypes<R>::Transform::printInternal( std::ostream& out ) const
00342 {
00343 out<<"internal t= "<<origin_<<std::endl;
00344 out<<"E= "<<orientation_<<std::endl;
00345 }
00346
00347
00348 template<class R>
00349 typename SolidTypes<R>::Transform& SolidTypes<R>::Transform::operator += (const SpatialVector& v)
00350 {
00351
00352 *this *= Transform(v);
00353 return *this;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 template<class R>
00378 typename SolidTypes<R>::Transform& SolidTypes<R>::Transform::operator +=(const Transform& a)
00379 {
00380 std::cerr << "SolidTypes<R>::Transform::operator +="<<std::endl;
00381 origin_ += a.getOriginOfParentInChild();
00382
00383
00384 orientation_ += a.getOrientation();
00385 orientation_.normalize();
00386
00387 return *this;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 template<class R>
00413 SolidTypes<R>::RigidInertia::RigidInertia()
00414 {}
00415
00416 template<class R>
00417 SolidTypes<R>::RigidInertia::RigidInertia( Real m, const Vec& h, const Mat& I ):m(m),h(h),I(I)
00418 {}
00419
00420 template<class R>
00421 typename SolidTypes<R>::SpatialVector SolidTypes<R>::RigidInertia::operator * (const SpatialVector& v ) const
00422 {
00423 return SpatialVector(
00424 cross(v.lineVec,h)+v.freeVec*m,
00425 mult(I,v.lineVec) + cross( h, v.freeVec )
00426 );
00427 }
00428
00429 template<class R>
00430 typename SolidTypes<R>::RigidInertia SolidTypes<R>::RigidInertia::operator * ( const Transform& t ) const
00431 {
00432 Vec h_mr = h - t.getOriginOfParentInChild() * m;
00433 Mat E = t.getRotationMatrix();
00434 return RigidInertia(
00435 m, E*h_mr,
00436 E*(I+crossM(t.getOriginOfParentInChild())*crossM(h)+crossM(h_mr)*crossM(t.getOriginOfParentInChild()))*(E.transposed()) );
00437 }
00438
00439
00440
00441
00442 template<class R>
00443 SolidTypes<R>::ArticulatedInertia::ArticulatedInertia()
00444 {}
00445
00446 template<class R>
00447 SolidTypes<R>::ArticulatedInertia::ArticulatedInertia( const Mat& M, const Mat& H, const Mat& I ):M(M),H(H),I(I)
00448 {}
00449
00450 template<class R>
00451 typename SolidTypes<R>::SpatialVector SolidTypes<R>::ArticulatedInertia::operator * (const SpatialVector& v ) const
00452 {
00453 return SpatialVector(
00454 multTrans(H,v.lineVec) + mult(M,v.freeVec),
00455 mult(I,v.lineVec) + mult(H,v.freeVec)
00456 );
00457
00458 }
00459 template<class R>
00460 typename SolidTypes<R>::ArticulatedInertia SolidTypes<R>::ArticulatedInertia::operator * ( Real r ) const
00461 {
00462 return ArticulatedInertia( M*r, H*r, I*r );
00463
00464 }
00465 template<class R>
00466 typename SolidTypes<R>::ArticulatedInertia& SolidTypes<R>::ArticulatedInertia::operator = (const RigidInertia& Ri )
00467 {
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 H = crossM( Ri.h );
00478
00479 for( int i=0; i<3; i++ )
00480 for( int j=0; j<3; j++ )
00481 M[i][j]= i==j ? Ri.m : 0;
00482
00483 I=Ri.I;
00484 return *this;
00485 }
00486
00487 template<class R>
00488 typename SolidTypes<R>::ArticulatedInertia& SolidTypes<R>::ArticulatedInertia::operator += (const ArticulatedInertia& Ai )
00489 {
00490 H += Ai.H;
00491 M += Ai.M;
00492 I += Ai.I;
00493 return *this;
00494 }
00495
00496 template<class R>
00497 typename SolidTypes<R>::ArticulatedInertia SolidTypes<R>::ArticulatedInertia::operator + (const ArticulatedInertia& Ai ) const
00498 {
00499 return ArticulatedInertia(M+Ai.M, H+Ai.H, I+Ai.I);
00500 }
00501
00502 template<class R>
00503 typename SolidTypes<R>::ArticulatedInertia SolidTypes<R>::ArticulatedInertia::operator - (const ArticulatedInertia& Ai ) const
00504 {
00505 return ArticulatedInertia(M-Ai.M, H-Ai.H, I-Ai.I);
00506 }
00507
00508 template<class R>
00509 void SolidTypes<R>::ArticulatedInertia::copyTo( Mat66& m ) const
00510 {
00511 for( int i=0; i<3; i++ )
00512 {
00513 for( int j=0; j<3; j++ )
00514 {
00515 m[i][j] = H[j][i];
00516 m[i][j+3] = M[i][j];
00517 m[i+3][j] = I[i][j];
00518 m[i+3][j+3] = H[i][j];
00519 }
00520 }
00521 }
00522
00523
00524
00525
00526
00527 template<class R>
00528 typename SolidTypes<R>::Vec SolidTypes<R>::mult( const typename SolidTypes<R>::Mat& m, const typename SolidTypes<R>::Vec& v )
00529 {
00530 typename SolidTypes<R>::Vec r;
00531 for( int i=0; i<3; ++i )
00532 {
00533 r[i]=0;
00534 for( int j=0; j<3; ++j )
00535 r[i]+=m[i][j] * v[j];
00536 }
00537 return r;
00538 }
00539
00540 template<class R>
00541 typename SolidTypes<R>::Vec SolidTypes<R>::multTrans( const typename SolidTypes<R>::Mat& m, const typename SolidTypes<R>::Vec& v )
00542 {
00543 typename SolidTypes<R>::Vec r;
00544 for( int i=0; i<3; ++i )
00545 {
00546 r[i]=0;
00547 for( int j=0; j<3; ++j )
00548 r[i]+=m[j][i] * v[j];
00549 }
00550 return r;
00551 }
00552
00554 template<class R>
00555 typename SolidTypes<R>::Mat SolidTypes<R>::crossM( const typename SolidTypes<R>::Vec& v )
00556 {
00557 typename SolidTypes<R>::Mat m;
00558 m[0][0]=0;
00559 m[0][1]=-v[2];
00560 m[0][2]= v[1];
00561 m[1][0]= v[2];
00562 m[1][1]=0;
00563 m[1][2]=-v[0];
00564 m[2][0]=-v[1];
00565 m[2][1]= v[0];
00566 m[2][2]=0;
00567 return m;
00568 }
00569
00570
00571 template<class R>
00572 typename SolidTypes<R>::ArticulatedInertia SolidTypes<R>::dyad( const SpatialVector& u, const SpatialVector& v )
00573 {
00574
00575 return ArticulatedInertia(dyad(u.lineVec, v.lineVec), dyad(u.freeVec, v.lineVec), dyad(u.freeVec, v.freeVec));
00576 }
00577
00578 template<class R>
00579 typename SolidTypes<R>::Mat SolidTypes<R>::dyad( const Vec& u, const Vec& v )
00580 {
00581 Mat m;
00582 for( int i=0; i<3; i++ )
00583 for( int j=0; j<3; j++ )
00584 m[i][j] = u[i]*v[j];
00585 return m;
00586 }
00587
00588
00589 }
00590
00591 }
00592
00593 #endif