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 #ifndef SOFA_DEFAULTTYPE_RIGIDTYPES_H
00028 #define SOFA_DEFAULTTYPE_RIGIDTYPES_H
00029
00030 #include <sofa/defaulttype/Vec.h>
00031 #include <sofa/defaulttype/Mat.h>
00032 #include <sofa/defaulttype/Quat.h>
00033 #include <sofa/core/objectmodel/BaseContext.h>
00034 #include <sofa/core/componentmodel/behavior/Mass.h>
00035 #include <sofa/helper/vector.h>
00036 #include <sofa/helper/rmath.h>
00037 #include <iostream>
00038 using std::endl;
00039
00040 namespace sofa
00041 {
00042
00043 namespace defaulttype
00044 {
00045
00046 using sofa::helper::vector;
00047
00048 template<int N, typename real>
00049 class RigidDeriv;
00050
00051 template<int N, typename real>
00052 class RigidCoord;
00053
00054 template<int N, typename real>
00055 class RigidMass;
00056
00057 template<int N, typename real>
00058 class StdRigidTypes;
00059
00060
00061
00062
00063
00066 template<typename real>
00067 class RigidDeriv<3, real>
00068 {
00069 public:
00070 typedef real value_type;
00071 typedef real Real;
00072 typedef Vec<3,Real> Vec3;
00073 typedef helper::Quater<Real> Quat;
00074
00075 protected:
00076 Vec3 vCenter;
00077 Vec3 vOrientation;
00078 public:
00079 friend class RigidCoord<3,real>;
00080
00081 RigidDeriv(const Vec3 &velCenter, const Vec3 &velOrient)
00082 : vCenter(velCenter), vOrientation(velOrient) {}
00083 RigidDeriv() { clear(); }
00084
00085 template<typename real2>
00086 RigidDeriv(const RigidDeriv<3,real2>& c)
00087 : vCenter(c.getVCenter()), vOrientation(c.getVOrientation())
00088 {
00089 }
00090
00091 void clear() { vCenter.clear(); vOrientation.clear(); }
00092
00093 template<typename real2>
00094 void operator =(const RigidDeriv<3,real2>& c)
00095 {
00096 vCenter = c.getVCenter();
00097 vOrientation = c.getVOrientation();
00098 }
00099
00100 void operator +=(const RigidDeriv& a)
00101 {
00102 vCenter += a.vCenter;
00103 vOrientation += a.vOrientation;
00104 }
00105
00106 void operator -=(const RigidDeriv& a)
00107 {
00108 vCenter -= a.vCenter;
00109 vOrientation -= a.vOrientation;
00110 }
00111
00112 RigidDeriv<3,real> operator + (const RigidDeriv<3,real>& a) const
00113 {
00114 RigidDeriv d;
00115 d.vCenter = vCenter + a.vCenter;
00116 d.vOrientation = vOrientation + a.vOrientation;
00117 return d;
00118 }
00119
00120 template<typename real2>
00121 void operator*=(real2 a)
00122 {
00123 vCenter *= a;
00124 vOrientation *= a;
00125 }
00126
00127 RigidDeriv<3,real> operator*(float a) const
00128 {
00129 RigidDeriv r = *this;
00130 r*=a;
00131 return r;
00132 }
00133
00134 RigidDeriv<3,real> operator*(double a) const
00135 {
00136 RigidDeriv r = *this;
00137 r*=a;
00138 return r;
00139 }
00140
00141 RigidDeriv<3,real> operator - () const
00142 {
00143 return RigidDeriv(-vCenter, -vOrientation);
00144 }
00145
00146 RigidDeriv<3,real> operator - (const RigidDeriv<3,real>& a) const
00147 {
00148 return RigidDeriv<3,real>(this->vCenter - a.vCenter, this->vOrientation-a.vOrientation);
00149 }
00150
00151
00153 Real operator*(const RigidDeriv<3,real>& a) const
00154 {
00155 return vCenter[0]*a.vCenter[0]+vCenter[1]*a.vCenter[1]+vCenter[2]*a.vCenter[2]
00156 +vOrientation[0]*a.vOrientation[0]+vOrientation[1]*a.vOrientation[1]
00157 +vOrientation[2]*a.vOrientation[2];
00158 }
00159
00160 Vec3& getVCenter (void) { return vCenter; }
00161 Vec3& getVOrientation (void) { return vOrientation; }
00162 const Vec3& getVCenter (void) const { return vCenter; }
00163 const Vec3& getVOrientation (void) const { return vOrientation; }
00164
00165 Vec3& getLinear () { return vCenter; }
00166 const Vec3& getLinear () const { return vCenter; }
00167 Vec3& getAngular () { return vOrientation; }
00168 const Vec3& getAngular () const { return vOrientation; }
00169
00170
00171
00173 inline friend std::ostream& operator << ( std::ostream& out, const RigidDeriv<3,real>& v ){
00174 out<<v.vCenter<<" "<<v.vOrientation;
00175 return out;
00176 }
00178 inline friend std::istream& operator >> ( std::istream& in, RigidDeriv<3,real>& v ){
00179 in>>v.vCenter>>v.vOrientation;
00180 return in;
00181 }
00182
00183 enum { static_size = 3 };
00184
00185 real* ptr() { return vCenter.ptr(); }
00186 const real* ptr() const { return vCenter.ptr(); }
00187
00188 static unsigned int size(){return 6;}
00189
00191 real& operator[](int i)
00192 {
00193 if (i<3)
00194 return this->vCenter(i);
00195 else
00196 return this->vOrientation(i-3);
00197 }
00198
00200 const real& operator[](int i) const
00201 {
00202 if (i<3)
00203 return this->vCenter(i);
00204 else
00205 return this->vOrientation(i-3);
00206 }
00207 };
00208
00209 template<typename real>
00210 class RigidCoord<3,real>
00211 {
00212 public:
00213 typedef real value_type;
00214 typedef real Real;
00215 typedef Vec<3,Real> Vec3;
00216 typedef helper::Quater<Real> Quat;
00217
00218 protected:
00219 Vec3 center;
00220 Quat orientation;
00221 public:
00222 RigidCoord (const Vec3 &posCenter, const Quat &orient)
00223 : center(posCenter), orientation(orient) {}
00224 RigidCoord () { clear(); }
00225
00226 template<typename real2>
00227 RigidCoord(const RigidCoord<3,real2>& c)
00228 : center(c.getCenter()), orientation(c.getOrientation())
00229 {
00230 }
00231
00232
00233 void clear() { center.clear(); orientation.clear(); }
00234
00235 template<typename real2>
00236 void operator =(const RigidCoord<3,real2>& c)
00237 {
00238 center = c.getCenter();
00239 orientation = c.getOrientation();
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249 void operator +=(const RigidDeriv<3,real>& a)
00250 {
00251 center += a.getVCenter();
00252 orientation.normalize();
00253 Quat qDot = orientation.vectQuatMult(a.getVOrientation());
00254 for (int i = 0; i < 4; i++)
00255 orientation[i] += qDot[i] * 0.5f;
00256 orientation.normalize();
00257 }
00258
00259 RigidCoord<3,real> operator + (const RigidDeriv<3,real>& a) const
00260 {
00261 RigidCoord c = *this;
00262 c.center += a.getVCenter();
00263 c.orientation.normalize();
00264 Quat qDot = c.orientation.vectQuatMult(a.getVOrientation());
00265 for (int i = 0; i < 4; i++)
00266 c.orientation[i] += qDot[i] * 0.5f;
00267 c.orientation.normalize();
00268 return c;
00269 }
00270
00271 RigidCoord<3,real> operator -(const RigidCoord<3,real>& a) const
00272 {
00273 return RigidCoord<3,real>(this->center - a.getCenter(), a.orientation.inverse() * this->orientation);
00274 }
00275
00276 void operator +=(const RigidCoord<3,real>& a)
00277 {
00278 center += a.getCenter();
00279
00280
00281 }
00282
00283 template<typename real2>
00284 void operator*=(real2 a)
00285 {
00286
00287 center *= a;
00288
00289 }
00290
00291 template<typename real2>
00292 RigidCoord<3,real> operator*(real2 a) const
00293 {
00294 RigidCoord r = *this;
00295 r*=a;
00296 return r;
00297 }
00298
00299
00300
00301
00302
00304 Real operator*(const RigidCoord<3,real>& a) const
00305 {
00306 return center[0]*a.center[0]+center[1]*a.center[1]+center[2]*a.center[2]
00307 +orientation[0]*a.orientation[0]+orientation[1]*a.orientation[1]
00308 +orientation[2]*a.orientation[2]+orientation[3]*a.orientation[3];
00309 }
00310
00312 real norm2() const
00313 {
00314 real r = (this->center).elems[0]*(this->center).elems[0];
00315 for (int i=1;i<3;i++)
00316 r += (this->center).elems[i]*(this->center).elems[i];
00317 return r;
00318 }
00319
00321 real norm() const
00322 {
00323 return helper::rsqrt(norm2());
00324 }
00325
00326
00327 Vec3& getCenter () { return center; }
00328 Quat& getOrientation () { return orientation; }
00329 const Vec3& getCenter () const { return center; }
00330 const Quat& getOrientation () const { return orientation; }
00331
00332 static RigidCoord<3,real> identity() {
00333 RigidCoord c;
00334 return c;
00335 }
00336
00338 void multRight( const RigidCoord<3,real>& c )
00339 {
00340 center += orientation.rotate(c.getCenter());
00341 orientation = orientation * c.getOrientation();
00342 }
00343
00345 RigidCoord<3,real> mult( const RigidCoord<3,real>& c ) const {
00346 RigidCoord r;
00347 r.center = center + orientation.rotate( c.center );
00348 r.orientation = orientation * c.getOrientation();
00349 return r;
00350 }
00351
00353 template<class Mat>
00354 void fromMatrix(const Mat& m) const
00355 {
00356 center[0] = m[0][3];
00357 center[1] = m[1][3];
00358 center[2] = m[2][3];
00359 Mat3x3d rot; rot = m;
00360 orientation.fromMatrix(rot);
00361 }
00362
00364 template<class Mat>
00365 void toMatrix( Mat& m) const
00366 {
00367 m.identity();
00368 orientation.toMatrix(m);
00369 m[0][3] = center[0];
00370 m[1][3] = center[1];
00371 m[2][3] = center[2];
00372 }
00373
00374 template<class Mat>
00375 void writeRotationMatrix( Mat& m) const
00376 {
00377 orientation.toMatrix(m);
00378 }
00379
00381 void writeOpenGlMatrix( float m[16] ) const {
00382 orientation.writeOpenGlMatrix(m);
00383 m[12] = (float)center[0];
00384 m[13] = (float)center[1];
00385 m[14] = (float)center[2];
00386 }
00387
00389 Vec3 vectorToChild( const Vec3& v ) const {
00390 return orientation.inverseRotate(v);
00391 }
00392
00394 inline friend std::ostream& operator << ( std::ostream& out, const RigidCoord<3,real>& v ){
00395 out<<v.center<<" "<<v.orientation;
00396 return out;
00397 }
00399 inline friend std::istream& operator >> ( std::istream& in, RigidCoord<3,real>& v ){
00400 in>>v.center>>v.orientation;
00401 return in;
00402 }
00403 static int max_size()
00404 {
00405 return 3;
00406 }
00407 enum { static_size = 3 };
00408
00409 real* ptr() { return center.ptr(); }
00410 const real* ptr() const { return center.ptr(); }
00411
00412 static unsigned int size(){return 7;}
00413
00415 real& operator[](int i)
00416 {
00417 if (i<3)
00418 return this->center(i);
00419 else
00420 return this->orientation[i-3];
00421 }
00422
00424 const real& operator[](int i) const
00425 {
00426 if (i<3)
00427 return this->center(i);
00428 else
00429 return this->orientation[i-3];
00430 }
00431 };
00432
00433 template<typename real>
00434 class RigidMass<3, real>
00435 {
00436 public:
00437 typedef real value_type;
00438 typedef real Real;
00439 typedef Mat<3,3,Real> Mat3x3;
00440 Real mass,volume;
00441 Mat3x3 inertiaMatrix;
00442 Mat3x3 inertiaMassMatrix;
00443 Mat3x3 invInertiaMatrix;
00444 Mat3x3 invInertiaMassMatrix;
00445 RigidMass(Real m=1)
00446 {
00447 mass = m;
00448 volume = 1;
00449 inertiaMatrix.identity();
00450 recalc();
00451 }
00452 void operator=(Real m)
00453 {
00454 mass = m;
00455 recalc();
00456 }
00457
00458 operator const Real() const
00459 {
00460 return mass;
00461 }
00462 void recalc()
00463 {
00464 inertiaMassMatrix = inertiaMatrix * mass;
00465 invInertiaMatrix.invert(inertiaMatrix);
00466 invInertiaMassMatrix.invert(inertiaMassMatrix);
00467 }
00468
00469 inline friend std::ostream& operator << (std::ostream& out, const RigidMass<3, real>& m )
00470 {
00471 out<<m.mass;
00472 out<<" "<<m.volume;
00473 out<<" "<<m.inertiaMatrix;
00474 return out;
00475 }
00476 inline friend std::istream& operator >> (std::istream& in, RigidMass<3, real>& m )
00477 {
00478 in>>m.mass;
00479 in>>m.volume;
00480 in>>m.inertiaMatrix;
00481 return in;
00482 }
00483 void operator *=(Real fact)
00484 {
00485 mass *= fact;
00486 inertiaMassMatrix *= fact;
00487 invInertiaMassMatrix /= fact;
00488 }
00489 };
00490
00491 template<int N, typename real>
00492 inline RigidDeriv<N,real> operator*(const RigidDeriv<N,real>& d, const RigidMass<N,real>& m)
00493 {
00494 RigidDeriv<N,real> res;
00495 res.getVCenter() = d.getVCenter() * m.mass;
00496 res.getVOrientation() = m.inertiaMassMatrix * d.getVOrientation();
00497 return res;
00498 }
00499
00500 template<int N, typename real>
00501 inline RigidDeriv<N, real> operator/(const RigidDeriv<N, real>& d, const RigidMass<N, real>& m)
00502 {
00503 RigidDeriv<N, real> res;
00504 res.getVCenter() = d.getVCenter() / m.mass;
00505 res.getVOrientation() = m.invInertiaMassMatrix * d.getVOrientation();
00506 return res;
00507 }
00508
00509
00510 template<typename real>
00511 class StdRigidTypes<3, real>
00512 {
00513 public:
00514 typedef real Real;
00515 typedef RigidCoord<3,real> Coord;
00516 typedef RigidDeriv<3,real> Deriv;
00517 typedef typename Coord::Vec3 Vec3;
00518 typedef typename Coord::Quat Quat;
00519
00520 template <class T>
00521 class SparseData
00522 {
00523 public:
00524 SparseData(unsigned int _index, const T& _data): index(_index), data(_data){};
00525 unsigned int index;
00526 T data;
00527 };
00528
00529 typedef SparseData<Coord> SparseCoord;
00530 typedef SparseData<Deriv> SparseDeriv;
00531
00532 typedef vector<SparseCoord> SparseVecCoord;
00533 typedef vector<SparseDeriv> SparseVecDeriv;
00534
00536 typedef vector<SparseVecDeriv> VecConst;
00537
00538 typedef vector<Coord> VecCoord;
00539 typedef vector<Deriv> VecDeriv;
00540 typedef vector<Real> VecReal;
00541
00542 template<typename T>
00543 static void set(Coord& c, T x, T y, T z)
00544 {
00545 c.getCenter()[0] = (Real)x;
00546 c.getCenter()[1] = (Real)y;
00547 c.getCenter()[2] = (Real)z;
00548 }
00549
00550 template<typename T>
00551 static void get(T& x, T& y, T& z, const Coord& c)
00552 {
00553 x = (T)c.getCenter()[0];
00554 y = (T)c.getCenter()[1];
00555 z = (T)c.getCenter()[2];
00556 }
00557
00558 template<typename T>
00559 static void add(Coord& c, T x, T y, T z)
00560 {
00561 c.getCenter()[0] += (Real)x;
00562 c.getCenter()[1] += (Real)y;
00563 c.getCenter()[2] += (Real)z;
00564 }
00565
00566 template<typename T>
00567 static void set(Deriv& c, T x, T y, T z)
00568 {
00569 c.getVCenter()[0] = (Real)x;
00570 c.getVCenter()[1] = (Real)y;
00571 c.getVCenter()[2] = (Real)z;
00572 }
00573
00574 template<typename T>
00575 static void get(T& x, T& y, T& z, const Deriv& c)
00576 {
00577 x = (T)c.getVCenter()[0];
00578 y = (T)c.getVCenter()[1];
00579 z = (T)c.getVCenter()[2];
00580 }
00581
00582 template<typename T>
00583 static void add(Deriv& c, T x, T y, T z)
00584 {
00585 c.getVCenter()[0] += (Real)x;
00586 c.getVCenter()[1] += (Real)y;
00587 c.getVCenter()[2] += (Real)z;
00588 }
00589
00590 static const char* Name();
00591
00592 static Coord interpolate(const helper::vector< Coord > & ancestors, const helper::vector< Real > & coefs)
00593 {
00594 assert(ancestors.size() == coefs.size());
00595
00596 Coord c;
00597
00598 for (unsigned int i = 0; i < ancestors.size(); i++)
00599 {
00600
00601 c.getCenter() += ancestors[i].getCenter() * coefs[i];
00602
00603
00604 helper::Quater<Real> q = ancestors[i].getOrientation();
00605 Real angle = acos(q[3]) * 2;
00606
00607
00608 defaulttype::Vec<3,Real> v(q[0], q[1], q[2]);
00609 Real norm = v.norm();
00610 if (norm > 0.0005)
00611 {
00612 v.normalize();
00613
00614
00615 angle *= coefs[i];
00616
00617
00618 q.axisToQuat(v, angle);
00619 q.normalize();
00620
00621 c.getOrientation() += q;
00622 }
00623 }
00624
00625 c.getOrientation().normalize();
00626
00627 return c;
00628 }
00629
00630 static Deriv interpolate(const helper::vector< Deriv > & ancestors, const helper::vector< Real > & coefs)
00631 {
00632 assert(ancestors.size() == coefs.size());
00633
00634 Deriv d;
00635
00636 for (unsigned int i = 0; i < ancestors.size(); i++)
00637 {
00638 d += ancestors[i] * coefs[i];
00639 }
00640
00641 return d;
00642 }
00643 };
00644
00645 typedef StdRigidTypes<3,double> Rigid3dTypes;
00646 typedef StdRigidTypes<3,float> Rigid3fTypes;
00647
00648 typedef RigidMass<3,double> Rigid3dMass;
00649 typedef RigidMass<3,float> Rigid3fMass;
00650
00651
00653 #ifdef SOFA_FLOAT
00654 template<> inline const char* Rigid3dTypes::Name() { return "Rigid3d"; }
00655 template<> inline const char* Rigid3fTypes::Name() { return "Rigid"; }
00656 #else
00657 template<> inline const char* Rigid3dTypes::Name() { return "Rigid"; }
00658 template<> inline const char* Rigid3fTypes::Name() { return "Rigid3f"; }
00659 #endif
00660
00661 #ifdef SOFA_FLOAT
00662 typedef Rigid3fTypes Rigid3Types;
00663 typedef Rigid3fMass Rigid3Mass;
00664 #else
00665 typedef Rigid3dTypes Rigid3Types;
00666 typedef Rigid3dMass Rigid3Mass;
00667 #endif
00668 typedef Rigid3Types RigidTypes;
00669
00670
00671
00672
00673 template<typename real>
00674 class RigidDeriv<2,real>
00675 {
00676 public:
00677 typedef real value_type;
00678 typedef real Real;
00679 typedef Vec<2,Real> Vec2;
00680 private:
00681 Vec2 vCenter;
00682 Real vOrientation;
00683 public:
00684 friend class RigidCoord<2,real>;
00685
00686 RigidDeriv (const Vec2 &velCenter, const Real &velOrient)
00687 : vCenter(velCenter), vOrientation(velOrient) {}
00688 RigidDeriv () { clear(); }
00689
00690 void clear() { vCenter.clear(); vOrientation=0; }
00691
00692 void operator +=(const RigidDeriv<2,real>& a)
00693 {
00694 vCenter += a.vCenter;
00695 vOrientation += a.vOrientation;
00696 }
00697
00698 RigidDeriv<2,real> operator + (const RigidDeriv<2,real>& a) const
00699 {
00700 RigidDeriv<2,real> d;
00701 d.vCenter = vCenter + a.vCenter;
00702 d.vOrientation = vOrientation + a.vOrientation;
00703 return d;
00704 }
00705
00706 template<typename real2>
00707 void operator*=(real2 a)
00708 {
00709 vCenter *= a;
00710 vOrientation *= (Real)a;
00711 }
00712
00713 RigidDeriv<2,real> operator*(float a) const
00714 {
00715 RigidDeriv<2,real> r = *this;
00716 r *= a;
00717 return r;
00718 }
00719
00720 RigidDeriv<2,real> operator*(double a) const
00721 {
00722 RigidDeriv<2,real> r = *this;
00723 r *= a;
00724 return r;
00725 }
00726
00727 RigidDeriv<2,real> operator - () const
00728 {
00729 return RigidDeriv<2,real>(-vCenter, -vOrientation);
00730 }
00731
00733 Real operator*(const RigidDeriv<2,real>& a) const
00734 {
00735 return vCenter[0]*a.vCenter[0]+vCenter[1]*a.vCenter[1]
00736 +vOrientation*a.vOrientation;
00737 }
00738
00739 Vec2& getVCenter (void) { return vCenter; }
00740 Real& getVOrientation (void) { return vOrientation; }
00741 const Vec2& getVCenter (void) const { return vCenter; }
00742 const Real& getVOrientation (void) const { return vOrientation; }
00744 inline friend std::ostream& operator << ( std::ostream& out, const RigidDeriv<2,real>& v )
00745 {
00746 out<<v.vCenter<<" "<<v.vOrientation;
00747 return out;
00748 }
00750 inline friend std::istream& operator >> ( std::istream& in, RigidDeriv<2,real>& v )
00751 {
00752 in>>v.vCenter>>v.vOrientation;
00753 return in;
00754 }
00755
00756 enum { static_size = 2 };
00757
00758 real* ptr() { return vCenter.ptr(); }
00759 const real* ptr() const { return vCenter.ptr(); }
00760
00761 static unsigned int size(){return 3;}
00762
00764 real& operator[](int i)
00765 {
00766 if (i<2)
00767 return this->vCenter(i);
00768 else
00769 return this->vOrientation;
00770 }
00771
00773 const real& operator[](int i) const
00774 {
00775 if (i<2)
00776 return this->vCenter(i);
00777 else
00778 return this->vOrientation;
00779 }
00780 };
00781
00782 template<typename real>
00783 class RigidCoord<2,real>
00784 {
00785 public:
00786 typedef real value_type;
00787 typedef real Real;
00788 typedef Vec<2,Real> Vec2;
00789 private:
00790 Vec2 center;
00791 Real orientation;
00792 public:
00793 RigidCoord (const Vec2 &posCenter, const Real &orient)
00794 : center(posCenter), orientation(orient) {}
00795 RigidCoord () { clear(); }
00796
00797 void clear() { center.clear(); orientation = 0; }
00798
00799 void operator +=(const RigidDeriv<2,real>& a)
00800 {
00801 center += a.getVCenter();
00802 orientation += a.getVOrientation();
00803 }
00804
00805 RigidCoord<2,real> operator + (const RigidDeriv<2,real>& a) const
00806 {
00807 RigidCoord<2,real> c = *this;
00808 c.center += a.getVCenter();
00809 c.orientation += a.getVOrientation();
00810 return c;
00811 }
00812
00813 RigidCoord<2,real> operator -(const RigidCoord<2,real>& a) const
00814 {
00815 return RigidCoord<2,real>(this->center - a.getCenter(), this->orientation - a.orientation);
00816 }
00817
00818 void operator +=(const RigidCoord<2,real>& a)
00819 {
00820
00821 center += a.getCenter();
00822 orientation += a.getOrientation();
00823 }
00824
00825 template<typename real2>
00826 void operator*=(real2 a)
00827 {
00828
00829 center *= a;
00830 orientation *= (Real)a;
00831 }
00832
00833 template<typename real2>
00834 RigidCoord<2,real> operator*(real2 a) const
00835 {
00836 RigidCoord<2,real> r = *this;
00837 r *= a;
00838 return r;
00839 }
00840
00842 Real operator*(const RigidCoord<2,real>& a) const
00843 {
00844 return center[0]*a.center[0]+center[1]*a.center[1]
00845 +orientation*a.orientation;
00846 }
00847
00849 real norm2() const
00850 {
00851 return center[0]*center[0]+center[1]*center[1];
00852 }
00853
00855 real norm() const
00856 {
00857 return helper::rsqrt(norm2());
00858 }
00859
00860 Vec2& getCenter () { return center; }
00861 Real& getOrientation () { return orientation; }
00862 const Vec2& getCenter () const { return center; }
00863 const Real& getOrientation () const { return orientation; }
00864
00865 Vec2 rotate(const Vec2& v) const
00866 {
00867 Real s = sin(orientation);
00868 Real c = cos(orientation);
00869 return Vec2(c*v[0]-s*v[1],
00870 s*v[0]+c*v[1]);
00871 }
00872 Vec2 inverseRotate(const Vec2& v) const
00873 {
00874 Real s = sin(-orientation);
00875 Real c = cos(-orientation);
00876 return Vec2(c*v[0]-s*v[1],
00877 s*v[0]+c*v[1]);
00878 }
00879
00880 static RigidCoord<2,real> identity()
00881 {
00882 RigidCoord<2,real> c;
00883 return c;
00884 }
00885
00887 void multRight( const RigidCoord<2,real>& c )
00888 {
00889 center += rotate(c.getCenter());
00890 orientation = orientation + c.getOrientation();
00891 }
00892
00894 RigidCoord<2,real> mult( const RigidCoord<2,real>& c ) const
00895 {
00896 RigidCoord<2,real> r;
00897 r.center = center + rotate( c.center );
00898 r.orientation = orientation + c.getOrientation();
00899 return r;
00900 }
00901
00902 template<class Mat>
00903 void writeRotationMatrix( Mat& m) const
00904 {
00905 m[0][0] = (typename Mat::Real)cos(orientation); m[0][1] = (typename Mat::Real)-sin(orientation);
00906 m[1][0] = (typename Mat::Real)sin(orientation); m[1][1] = (typename Mat::Real) cos(orientation);
00907 }
00908
00910 template<class Mat>
00911 void fromMatrix(const Mat& m) const
00912 {
00913 center[0] = m[0][2];
00914 center[1] = m[1][2];
00915 orientation = atan2(m[1][0],m[0][0]);
00916 }
00917
00919 template<class Mat>
00920 void toMatrix( Mat& m) const
00921 {
00922 m.identity();
00923 writeRotationMatrix( m );
00924 m[0][2] = center[0];
00925 m[1][2] = center[1];
00926 }
00927
00929 void writeOpenGlMatrix( float m[16] ) const
00930 {
00931
00932 m[0] = cos(orientation);
00933 m[1] = sin(orientation);
00934 m[2] = 0;
00935 m[3] = 0;
00936 m[4] = -sin(orientation);
00937 m[5] = cos(orientation);
00938 m[6] = 0;
00939 m[7] = 0;
00940 m[8] = 0;
00941 m[9] = 0;
00942 m[10] = 1;
00943 m[11] = 0;
00944 m[12] = (float)center[0];
00945 m[13] = (float)center[1];
00946 m[14] = (float)center[2];
00947 m[15] = 1;
00948 }
00949
00951 Vec2 vectorToChild( const Vec2& v ) const
00952 {
00953 return inverseRotate(v);
00954 }
00955
00957 inline friend std::ostream& operator << ( std::ostream& out, const RigidCoord<2,real>& v )
00958 {
00959 out<<v.center<<" "<<v.orientation;
00960 return out;
00961 }
00963 inline friend std::istream& operator >> ( std::istream& in, RigidCoord<2,real>& v )
00964 {
00965 in>>v.center>>v.orientation;
00966 return in;
00967 }
00968 static int max_size()
00969 {
00970 return 3;
00971 }
00972
00973 enum { static_size = 2 };
00974
00975 real* ptr() { return center.ptr(); }
00976 const real* ptr() const { return center.ptr(); }
00977
00978 static unsigned int size(){return 3;}
00979
00981 real& operator[](int i)
00982 {
00983 if (i<2)
00984 return this->center(i);
00985 else
00986 return this->orientation;
00987 }
00988
00990 const real& operator[](int i) const
00991 {
00992 if (i<2)
00993 return this->center(i);
00994 else
00995 return this->orientation;
00996 }
00997 };
00998
00999 template<class real>
01000 class RigidMass<2, real>
01001 {
01002 public:
01003 typedef real value_type;
01004 typedef real Real;
01005 Real mass,volume;
01006 Real inertiaMatrix;
01007 Real inertiaMassMatrix;
01008 Real invInertiaMatrix;
01009 Real invInertiaMassMatrix;
01010 RigidMass(Real m=1)
01011 {
01012 mass = m;
01013 volume = 1;
01014 inertiaMatrix = 1;
01015 recalc();
01016 }
01017 void operator=(Real m)
01018 {
01019 mass = m;
01020 recalc();
01021 }
01022
01023 operator const Real() const
01024 {
01025 return mass;
01026 }
01028 RigidMass(Real m, Real radius)
01029 {
01030 mass = m;
01031 volume = radius*radius*R_PI;
01032 inertiaMatrix = (radius*radius)/2;
01033 recalc();
01034 }
01036 RigidMass(Real m, Real xwidth, Real ywidth)
01037 {
01038 mass = m;
01039 volume = xwidth*xwidth + ywidth*ywidth;
01040 inertiaMatrix = volume/12;
01041 recalc();
01042 }
01043
01044 void recalc()
01045 {
01046 inertiaMassMatrix = inertiaMatrix * mass;
01047 invInertiaMatrix = 1/(inertiaMatrix);
01048 invInertiaMassMatrix = 1/(inertiaMassMatrix);
01049 }
01050 inline friend std::ostream& operator << (std::ostream& out, const RigidMass<2,Real>& m )
01051 {
01052 out<<m.mass;
01053 out<<" "<<m.volume;
01054 out<<" "<<m.inertiaMatrix;
01055 return out;
01056 }
01057 inline friend std::istream& operator >> (std::istream& in, RigidMass<2,Real>& m )
01058 {
01059 in>>m.mass;
01060 in>>m.volume;
01061 in>>m.inertiaMatrix;
01062 return in;
01063 }
01064 void operator *=(Real fact)
01065 {
01066 mass *= fact;
01067 inertiaMassMatrix *= fact;
01068 invInertiaMassMatrix /= fact;
01069 }
01070 };
01071
01074 template<typename real>
01075 class StdRigidTypes<2, real>
01076 {
01077 public:
01078 typedef real Real;
01079 typedef Vec<2,real> Vec2;
01080
01081 typedef RigidDeriv<2,Real> Deriv;
01082 typedef RigidCoord<2,Real> Coord;
01083
01084 static const char* Name();
01085
01086 typedef vector<Coord> VecCoord;
01087 typedef vector<Deriv> VecDeriv;
01088
01089
01090 template <class T>
01091 class SparseData
01092 {
01093 public:
01094 SparseData(unsigned int _index, const T& _data): index(_index), data(_data){};
01095 unsigned int index;
01096 T data;
01097 };
01098
01099 typedef SparseData<Coord> SparseCoord;
01100 typedef SparseData<Deriv> SparseDeriv;
01101 typedef vector<Real> VecReal;
01102
01103 typedef vector<SparseCoord> SparseVecCoord;
01104 typedef vector<SparseDeriv> SparseVecDeriv;
01105
01106 typedef vector<SparseVecDeriv> VecConst;
01107
01108 template<typename T>
01109 static void set(Coord& c, T x, T y, T)
01110 {
01111 c.getCenter()[0] = (Real)x;
01112 c.getCenter()[1] = (Real)y;
01113 }
01114
01115 template<typename T>
01116 static void get(T& x, T& y, T& z, const Coord& c)
01117 {
01118 x = (T)c.getCenter()[0];
01119 y = (T)c.getCenter()[1];
01120 z = (T)0;
01121 }
01122
01123 template<typename T>
01124 static void add(Coord& c, T x, T y, T)
01125 {
01126 c.getCenter()[0] += (Real)x;
01127 c.getCenter()[1] += (Real)y;
01128 }
01129
01130 template<typename T>
01131 static void set(Deriv& c, T x, T y, T)
01132 {
01133 c.getVCenter()[0] = (Real)x;
01134 c.getVCenter()[1] = (Real)y;
01135 }
01136
01137 template<typename T>
01138 static void get(T& x, T& y, T& z, const Deriv& c)
01139 {
01140 x = (T)c.getVCenter()[0];
01141 y = (T)c.getVCenter()[1];
01142 z = (T)0;
01143 }
01144
01145 template<typename T>
01146 static void add(Deriv& c, T x, T y, T)
01147 {
01148 c.getVCenter()[0] += (Real)x;
01149 c.getVCenter()[1] += (Real)y;
01150 }
01151
01152 static Coord interpolate(const helper::vector< Coord > & ancestors, const helper::vector< Real > & coefs)
01153 {
01154 assert(ancestors.size() == coefs.size());
01155
01156 Coord c;
01157
01158 for (unsigned int i = 0; i < ancestors.size(); i++)
01159 {
01160 c += ancestors[i] * coefs[i];
01161 }
01162
01163 return c;
01164 }
01165
01166 static Deriv interpolate(const helper::vector< Deriv > & ancestors, const helper::vector< Real > & coefs)
01167 {
01168 assert(ancestors.size() == coefs.size());
01169
01170 Deriv d;
01171
01172 for (unsigned int i = 0; i < ancestors.size(); i++)
01173 {
01174 d += ancestors[i] * coefs[i];
01175 }
01176
01177 return d;
01178 }
01179
01180 };
01181
01182 typedef StdRigidTypes<2,double> Rigid2dTypes;
01183 typedef StdRigidTypes<2,float> Rigid2fTypes;
01184
01185 typedef RigidMass<2,double> Rigid2dMass;
01186 typedef RigidMass<2,float> Rigid2fMass;
01187
01188 template<> inline const char* Rigid2dTypes::Name() { return "Rigid2d"; }
01189 template<> inline const char* Rigid2fTypes::Name() { return "Rigid2f"; }
01190
01191 #ifdef SOFA_FLOAT
01192 typedef Rigid2fTypes Rigid2Types;
01193 typedef Rigid2fMass Rigid2Mass;
01194 #else
01195 typedef Rigid2dTypes Rigid2Types;
01196 typedef Rigid2dMass Rigid2Mass;
01197 #endif
01198 }
01199
01200 namespace core
01201 {
01202 namespace componentmodel
01203 {
01204 namespace behavior
01205 {
01206
01215 template<class Coord, class Deriv, class Vec, class M, class SV>
01216 Deriv inertiaForce( const SV& , const Vec& , const M& , const Coord& , const Deriv& );
01217
01219 template <>
01220 inline defaulttype::RigidDeriv<3, double> inertiaForce<
01221 defaulttype::RigidCoord<3, double>,
01222 defaulttype::RigidDeriv<3, double>,
01223 objectmodel::BaseContext::Vec3,
01224 defaulttype::RigidMass<3, double>,
01225 objectmodel::BaseContext::SpatialVector
01226 >
01227 (
01228 const objectmodel::BaseContext::SpatialVector& vframe,
01229 const objectmodel::BaseContext::Vec3& aframe,
01230 const defaulttype::RigidMass<3, double>& mass,
01231 const defaulttype::RigidCoord<3, double>& x,
01232 const defaulttype::RigidDeriv<3, double>& v
01233 )
01234 {
01235 defaulttype::RigidDeriv<3, double>::Vec3 omega( vframe.lineVec[0], vframe.lineVec[1], vframe.lineVec[2] );
01236 defaulttype::RigidDeriv<3, double>::Vec3 origin = x.getCenter(), finertia, zero(0,0,0);
01237
01238 finertia = -( aframe + omega.cross( omega.cross(origin) + v.getVCenter()*2 ))*mass.mass;
01239 return defaulttype::RigidDeriv<3, double>( finertia, zero );
01241 }
01242
01244 template <>
01245 inline defaulttype::RigidDeriv<3, float> inertiaForce<
01246 defaulttype::RigidCoord<3, float>,
01247 defaulttype::RigidDeriv<3, float>,
01248 objectmodel::BaseContext::Vec3,
01249 defaulttype::RigidMass<3, float>,
01250 objectmodel::BaseContext::SpatialVector
01251 >
01252 (
01253 const objectmodel::BaseContext::SpatialVector& vframe,
01254 const objectmodel::BaseContext::Vec3& aframe,
01255 const defaulttype::RigidMass<3, float>& mass,
01256 const defaulttype::RigidCoord<3, float>& x,
01257 const defaulttype::RigidDeriv<3, float>& v
01258 )
01259 {
01260 defaulttype::RigidDeriv<3, float>::Vec3 omega( (float)vframe.lineVec[0], (float)vframe.lineVec[1], (float)vframe.lineVec[2] );
01261 defaulttype::RigidDeriv<3, float>::Vec3 origin = x.getCenter(), finertia, zero(0,0,0);
01262
01263 finertia = -( aframe + omega.cross( omega.cross(origin) + v.getVCenter()*2 ))*mass.mass;
01264 return defaulttype::RigidDeriv<3, float>( finertia, zero );
01266 }
01267
01268 }
01269
01270 }
01271
01272 namespace objectmodel
01273 {
01274
01275
01276
01278
01279 template<>
01280 inline std::string BaseData::typeName< defaulttype::Quatd >(const defaulttype::Quatd *) { return "Quatd"; }
01281
01282 template<>
01283 inline std::string BaseData::typeName< std::vector< defaulttype::Quatd > >(const std::vector< defaulttype::Quatd > *) { return "vector<Quatd>"; }
01284
01285 template<>
01286 inline std::string BaseData::typeName< helper::vector< defaulttype::Quatd > >(const helper::vector< defaulttype::Quatd > *) { return "vector<Quatd>"; }
01287
01288 template<>
01289 inline std::string BaseData::typeName< defaulttype::Quatf >(const defaulttype::Quatf *) { return "Quatf"; }
01290
01291 template<>
01292 inline std::string BaseData::typeName< std::vector< defaulttype::Quatf > >(const std::vector< defaulttype::Quatf > *) { return "vector<Quatf>"; }
01293
01294 template<>
01295 inline std::string BaseData::typeName< helper::vector< defaulttype::Quatf > >(const helper::vector< defaulttype::Quatf > *) { return "vector<Quatf>"; }
01296
01297 template<>
01298 inline std::string BaseData::typeName< defaulttype::Rigid2dTypes::Coord >(const defaulttype::Rigid2dTypes::Coord *) { return "Rigid2dTypes::Coord"; }
01299
01300 template<>
01301 inline std::string BaseData::typeName< std::vector< defaulttype::Rigid2dTypes::Coord > >(const std::vector< defaulttype::Rigid2dTypes::Coord > *) { return "vector<Rigid2dTypes::Coord>"; }
01302
01303 template<>
01304 inline std::string BaseData::typeName< helper::vector< defaulttype::Rigid2dTypes::Coord > >(const helper::vector< defaulttype::Rigid2dTypes::Coord > *) { return "vector<Rigid2dTypes::Coord>"; }
01305
01306 template<>
01307 inline std::string BaseData::typeName< defaulttype::Rigid2dTypes::Deriv >(const defaulttype::Rigid2dTypes::Deriv *) { return "Rigid2dTypes::Deriv"; }
01308
01309 template<>
01310 inline std::string BaseData::typeName< std::vector< defaulttype::Rigid2dTypes::Deriv > >(const std::vector< defaulttype::Rigid2dTypes::Deriv > *) { return "vector<Rigid2dTypes::Deriv>"; }
01311
01312 template<>
01313 inline std::string BaseData::typeName< helper::vector< defaulttype::Rigid2dTypes::Deriv > >(const helper::vector< defaulttype::Rigid2dTypes::Deriv > *) { return "vector<Rigid2dTypes::Deriv>"; }
01314
01315 template<>
01316 inline std::string BaseData::typeName< defaulttype::Rigid2fTypes::Coord >(const defaulttype::Rigid2fTypes::Coord *) { return "Rigid2fTypes::Coord"; }
01317
01318 template<>
01319 inline std::string BaseData::typeName< std::vector< defaulttype::Rigid2fTypes::Coord > >(const std::vector< defaulttype::Rigid2fTypes::Coord > *) { return "vector<Rigid2fTypes::Coord>"; }
01320
01321 template<>
01322 inline std::string BaseData::typeName< helper::vector< defaulttype::Rigid2fTypes::Coord > >(const helper::vector< defaulttype::Rigid2fTypes::Coord > *) { return "vector<Rigid2fTypes::Coord>"; }
01323
01324 template<>
01325 inline std::string BaseData::typeName< defaulttype::Rigid2fTypes::Deriv >(const defaulttype::Rigid2fTypes::Deriv *) { return "Rigid2fTypes::Deriv"; }
01326
01327 template<>
01328 inline std::string BaseData::typeName< std::vector< defaulttype::Rigid2fTypes::Deriv > >(const std::vector< defaulttype::Rigid2fTypes::Deriv > *) { return "vector<Rigid2fTypes::Deriv>"; }
01329
01330 template<>
01331 inline std::string BaseData::typeName< helper::vector< defaulttype::Rigid2fTypes::Deriv > >(const helper::vector< defaulttype::Rigid2fTypes::Deriv > *) { return "vector<Rigid2fTypes::Deriv>"; }
01332
01333 template<>
01334 inline std::string BaseData::typeName< defaulttype::Rigid3dTypes::Coord >(const defaulttype::Rigid3dTypes::Coord *) { return "Rigid3dTypes::Coord"; }
01335
01336 template<>
01337 inline std::string BaseData::typeName< std::vector< defaulttype::Rigid3dTypes::Coord > >(const std::vector< defaulttype::Rigid3dTypes::Coord > *) { return "vector<Rigid3dTypes::Coord>"; }
01338
01339 template<>
01340 inline std::string BaseData::typeName< helper::vector< defaulttype::Rigid3dTypes::Coord > >(const helper::vector< defaulttype::Rigid3dTypes::Coord > *) { return "vector<Rigid3dTypes::Coord>"; }
01341
01342 template<>
01343 inline std::string BaseData::typeName< defaulttype::Rigid3dTypes::Deriv >(const defaulttype::Rigid3dTypes::Deriv *) { return "Rigid3dTypes::Deriv"; }
01344
01345 template<>
01346 inline std::string BaseData::typeName< std::vector< defaulttype::Rigid3dTypes::Deriv > >(const std::vector< defaulttype::Rigid3dTypes::Deriv > *) { return "vector<Rigid3dTypes::Deriv>"; }
01347
01348 template<>
01349 inline std::string BaseData::typeName< helper::vector< defaulttype::Rigid3dTypes::Deriv > >(const helper::vector< defaulttype::Rigid3dTypes::Deriv > *) { return "vector<Rigid3dTypes::Deriv>"; }
01350
01351 template<>
01352 inline std::string BaseData::typeName< defaulttype::Rigid3fTypes::Coord >(const defaulttype::Rigid3fTypes::Coord *) { return "Rigid3fTypes::Coord"; }
01353
01354 template<>
01355 inline std::string BaseData::typeName< std::vector< defaulttype::Rigid3fTypes::Coord > >(const std::vector< defaulttype::Rigid3fTypes::Coord > *) { return "vector<Rigid3fTypes::Coord>"; }
01356
01357 template<>
01358 inline std::string BaseData::typeName< helper::vector< defaulttype::Rigid3fTypes::Coord > >(const helper::vector< defaulttype::Rigid3fTypes::Coord > *) { return "vector<Rigid3fTypes::Coord>"; }
01359
01360 template<>
01361 inline std::string BaseData::typeName< defaulttype::Rigid3fTypes::Deriv >(const defaulttype::Rigid3fTypes::Deriv *) { return "Rigid3fTypes::Deriv"; }
01362
01363 template<>
01364 inline std::string BaseData::typeName< std::vector< defaulttype::Rigid3fTypes::Deriv > >(const std::vector< defaulttype::Rigid3fTypes::Deriv > *) { return "vector<Rigid3fTypes::Deriv>"; }
01365
01366 template<>
01367 inline std::string BaseData::typeName< helper::vector< defaulttype::Rigid3fTypes::Deriv > >(const helper::vector< defaulttype::Rigid3fTypes::Deriv > *) { return "vector<Rigid3fTypes::Deriv>"; }
01368
01370
01371 }
01372
01373 }
01374
01375 }
01376
01377
01378 #endif