RigidTypes.h

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                              SOFA :: Framework                              *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
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 // 3D Rigids
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     //template<typename real2>
00243     //void operator =(const RigidCoord<3,real2>& c)
00244     //{
00245     //    center = c.getCenter();
00246     //    orientation = c.getOrientation();
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     //  orientation += a.getOrientation();
00280     //  orientation.normalize();
00281     }
00282     
00283     template<typename real2>
00284     void operator*=(real2 a)
00285     {
00286         //std::cout << "*="<<std::endl;
00287         center *= a;
00288         //orientation *= a;
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;         // Inertia matrix of the object
00442     Mat3x3 inertiaMassMatrix;    // Inertia matrix of the object * mass of the object
00443     Mat3x3 invInertiaMatrix;      // inverse of inertiaMatrix
00444     Mat3x3 invInertiaMassMatrix; // inverse of inertiaMassMatrix
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     // operator to cast to const Real
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             // Position interpolation.
00601             c.getCenter() += ancestors[i].getCenter() * coefs[i];
00602 
00603             // Angle extraction from the orientation quaternion.
00604             helper::Quater<Real> q = ancestors[i].getOrientation();
00605             Real angle = acos(q[3]) * 2;
00606 
00607             // Axis extraction from the orientation quaternion.
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                 // The scale factor is applied to the angle
00615                 angle *= coefs[i];
00616 
00617                 // Corresponding quaternion is computed, then added to the interpolated point orientation.
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 //typedef Rigid3Mass RigidMass;
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 // 2D Rigids
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 //         std::cout << "+="<<std::endl;
00821         center += a.getCenter();
00822         orientation += a.getOrientation();
00823     }
00824 
00825     template<typename real2>
00826     void operator*=(real2 a)
00827     {
00828 //         std::cout << "*="<<std::endl;
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 += /*orientation.*/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 + /*orientation.*/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         //orientation.writeOpenGlMatrix(m);
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 /*orientation.*/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;       // Inertia matrix of the object
01007     Real inertiaMassMatrix;    // Inertia matrix of the object * mass of the object
01008     Real invInertiaMatrix;    // inverse of inertiaMatrix
01009     Real invInertiaMassMatrix; // inverse of inertiaMassMatrix
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     // operator to cast to const Real
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 } // namespace defaulttype
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& /*sv*/, const Vec& /*a*/, const M& /*m*/, const Coord& /*x*/, const Deriv& /*v*/ );
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 } // namespace behavoir
01269 
01270 } // namespace componentmodel
01271 
01272 namespace objectmodel
01273 {
01274 
01275 // Specialization of Field::getValueTypeString() method to display smaller 
01276 // The next line hides all those methods from the doxygen documentation
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 } // namespace objectmodel
01372 
01373 } // namespace core
01374 
01375 } // namespace sofa
01376 
01377 
01378 #endif

Generated on Sun Nov 23 02:29:29 2008 for Sofa by  doxygen 1.5.7.1