DiagonalMass.cpp

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 :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #include <sofa/component/mass/DiagonalMass.inl>
00026 #include <sofa/core/ObjectFactory.h>
00027 #include <sofa/defaulttype/Vec3Types.h>
00028 #include <sofa/defaulttype/RigidTypes.h>
00029 #include <sofa/helper/gl/Axis.h>
00030 
00031 namespace sofa
00032 {
00033 
00034 namespace component
00035 {
00036 
00037 namespace mass
00038 {
00039 
00040 using namespace sofa::defaulttype;
00041 
00042 #ifndef SOFA_FLOAT
00043 template <>
00044     double DiagonalMass<Rigid3dTypes, Rigid3dMass>::getPotentialEnergy( const VecCoord& x )
00045 {
00046   double e = 0;
00047   const MassVector &masses= f_mass.getValue();
00048     // gravity
00049   Vec3d g ( this->getContext()->getLocalGravity() );
00050   Deriv theGravity;
00051   DataTypes::set
00052       ( theGravity, g[0], g[1], g[2]);
00053   for (unsigned int i=0;i<x.size();i++)
00054   {
00055     e -= theGravity.getVCenter()*masses[i].mass*x[i].getCenter();
00056   }
00057   return e;
00058 }
00059 
00060 template <>
00061     double DiagonalMass<Rigid2dTypes, Rigid2dMass>::getPotentialEnergy( const VecCoord& x )
00062 {
00063   double e = 0;
00064   const MassVector &masses= f_mass.getValue();
00065     // gravity
00066   Vec3d g ( this->getContext()->getLocalGravity() );
00067   Deriv theGravity;
00068   DataTypes::set
00069       ( theGravity, g[0], g[1], g[2]);
00070   for (unsigned int i=0;i<x.size();i++)
00071   {
00072     e -= theGravity.getVCenter()*masses[i].mass*x[i].getCenter();
00073   }
00074   return e;
00075 }
00076 
00077 
00078 template <>
00079     double DiagonalMass<Rigid3dTypes, Rigid3dMass>::getElementMass(unsigned int index)
00080 {
00081   return (f_mass.getValue()[index].mass);
00082 }
00083 
00084   template <>
00085       double DiagonalMass<Rigid2dTypes, Rigid2dMass>::getElementMass(unsigned int index)
00086   {
00087     return (f_mass.getValue()[index].mass);
00088   }
00089 
00090 /*
00091   template <>
00092   void MassEdgeDestroyFunction<Rigid3dTypes, Rigid3dMass>(const sofa::helper::vector<unsigned int> &, 
00093                               void* , vector<Rigid3dMass> &){
00094   }
00095 
00096   template <>
00097   void MassEdgeCreationFunction<Rigid3dTypes, Rigid3dMass>(const sofa::helper::vector<unsigned int> &, 
00098                                void* , vector<Rigid3dMass> &){
00099   }*/
00100 
00101   template <>
00102   void DiagonalMass<Rigid3dTypes, Rigid3dMass>::draw()
00103 
00104   {
00105     const MassVector &masses= f_mass.getValue();
00106     if (!getContext()->getShowBehaviorModels()) return;
00107     VecCoord& x = *mstate->getX();
00108     Real totalMass=0;
00109     RigidTypes::Vec3 gravityCenter;
00110     for (unsigned int i=0; i<x.size(); i++)
00111       {
00112     const Quat& orient = x[i].getOrientation();
00113         //orient[3] = -orient[3];
00114     const RigidTypes::Vec3& center = x[i].getCenter();
00115     RigidTypes::Vec3 len;
00116         // The moment of inertia of a box is:
00117         //   m->_I(0,0) = M/REAL(12.0) * (ly*ly + lz*lz);
00118         //   m->_I(1,1) = M/REAL(12.0) * (lx*lx + lz*lz);
00119         //   m->_I(2,2) = M/REAL(12.0) * (lx*lx + ly*ly);
00120         // So to get lx,ly,lz back we need to do
00121         //   lx = sqrt(12/M * (m->_I(1,1)+m->_I(2,2)-m->_I(0,0)))
00122         // Note that RigidMass inertiaMatrix is already divided by M
00123     double m00 = masses[i].inertiaMatrix[0][0];
00124     double m11 = masses[i].inertiaMatrix[1][1];
00125     double m22 = masses[i].inertiaMatrix[2][2];
00126     len[0] = sqrt(m11+m22-m00);
00127     len[1] = sqrt(m00+m22-m11);
00128     len[2] = sqrt(m00+m11-m22);
00129 
00130     helper::gl::Axis::draw(center, orient, len*showAxisSize.getValue());
00131 
00132     gravityCenter += (center * masses[i].mass);
00133     totalMass += masses[i].mass;
00134       }
00135 
00136     if(showCenterOfGravity.getValue()){
00137       glColor3f (1,1,0);
00138       glBegin (GL_LINES);
00139       gravityCenter /= totalMass;
00140       helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(showAxisSize.getValue(),0,0) );
00141       helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(showAxisSize.getValue(),0,0) );
00142       helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(0,showAxisSize.getValue(),0) );
00143       helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(0,showAxisSize.getValue(),0) );
00144       helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(0,0,showAxisSize.getValue()) );
00145       helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(0,0,showAxisSize.getValue()) );
00146       glEnd();
00147     }
00148   }
00149     
00150   template <>
00151       void DiagonalMass<Rigid3dTypes, Rigid3dMass>::reinit(){
00152     Inherited::reinit();
00153       }
00154     
00155       template <>
00156           void DiagonalMass<Rigid2dTypes, Rigid2dMass>::reinit(){
00157         Inherited::reinit();
00158           }
00159 
00160   template <>
00161   void DiagonalMass<Rigid3dTypes, Rigid3dMass>::init(){
00162     Inherited::init();
00163   }
00164     
00165   template <>
00166   void DiagonalMass<Rigid2dTypes, Rigid2dMass>::init(){
00167     Inherited::init();
00168   }
00169 
00170   template <>
00171   void DiagonalMass<Rigid2dTypes, Rigid2dMass>::draw()
00172   {
00173     const MassVector &masses= f_mass.getValue();
00174     if (!getContext()->getShowBehaviorModels()) return;
00175     VecCoord& x = *mstate->getX();
00176     for (unsigned int i=0; i<x.size(); i++)
00177       {
00178     Vec3d len;
00179     len[0] = len[1] = sqrt(masses[i].inertiaMatrix);
00180     len[2] = 0;
00181         
00182     Quat orient(Vec3d(0,0,1), x[i].getOrientation());
00183     Vec3d center; center = x[i].getCenter();
00184     helper::gl::Axis::draw(center, orient, len);
00185       }
00186   }
00187 
00188         
00189 #endif
00190 #ifndef SOFA_DOUBLE
00191   template <>
00192       double DiagonalMass<Rigid3fTypes, Rigid3fMass>::getPotentialEnergy( const VecCoord& x )
00193   {
00194     double e = 0;
00195     const MassVector &masses= f_mass.getValue();
00196     // gravity
00197     Vec3d g ( this->getContext()->getLocalGravity() );
00198     Deriv theGravity;
00199     DataTypes::set
00200       ( theGravity, g[0], g[1], g[2]);
00201     for (unsigned int i=0;i<x.size();i++)
00202       {
00203     e -= theGravity.getVCenter()*masses[i].mass*x[i].getCenter();
00204       }
00205     return e;
00206   }
00207 
00208   template <>
00209       double DiagonalMass<Rigid2fTypes, Rigid2fMass>::getPotentialEnergy( const VecCoord& x )
00210   {
00211     double e = 0;
00212 
00213     const MassVector &masses= f_mass.getValue();
00214     // gravity
00215     Vec3d g ( this->getContext()->getLocalGravity() );
00216     Deriv theGravity;
00217     DataTypes::set
00218       ( theGravity, g[0], g[1], g[2]);
00219     for (unsigned int i=0;i<x.size();i++)
00220       {
00221     e -= theGravity.getVCenter()*masses[i].mass*x[i].getCenter();
00222       }
00223     return e;
00224   }
00225 
00226 
00227     
00228   template <>
00229       double DiagonalMass<Rigid3fTypes, Rigid3fMass>::getElementMass(unsigned int index)
00230   {
00231     return (double)(f_mass.getValue()[index].mass);
00232   }
00233 
00234 
00235   template <>
00236       double DiagonalMass<Rigid2fTypes, Rigid2fMass>::getElementMass(unsigned int index)
00237   {
00238     return (double)(f_mass.getValue()[index].mass);
00239   }
00240 
00241 
00242 
00243 
00244   template <>
00245   void DiagonalMass<Rigid3fTypes, Rigid3fMass>::draw()
00246 
00247   {
00248     const MassVector &masses= f_mass.getValue();
00249     if (!getContext()->getShowBehaviorModels()) return;
00250     VecCoord& x = *mstate->getX();
00251     Real totalMass=0;
00252     RigidTypes::Vec3 gravityCenter;
00253     for (unsigned int i=0; i<x.size(); i++)
00254       {
00255     const Quat& orient = x[i].getOrientation();
00256         //orient[3] = -orient[3];
00257     const RigidTypes::Vec3& center = x[i].getCenter();
00258     RigidTypes::Vec3 len;
00259         // The moment of inertia of a box is:
00260         //   m->_I(0,0) = M/REAL(12.0) * (ly*ly + lz*lz);
00261         //   m->_I(1,1) = M/REAL(12.0) * (lx*lx + lz*lz);
00262         //   m->_I(2,2) = M/REAL(12.0) * (lx*lx + ly*ly);
00263         // So to get lx,ly,lz back we need to do
00264         //   lx = sqrt(12/M * (m->_I(1,1)+m->_I(2,2)-m->_I(0,0)))
00265         // Note that RigidMass inertiaMatrix is already divided by M
00266     double m00 = masses[i].inertiaMatrix[0][0];
00267     double m11 = masses[i].inertiaMatrix[1][1];
00268     double m22 = masses[i].inertiaMatrix[2][2];
00269     len[0] = sqrt(m11+m22-m00);
00270     len[1] = sqrt(m00+m22-m11);
00271     len[2] = sqrt(m00+m11-m22);
00272 
00273     helper::gl::Axis::draw(center, orient, len*showAxisSize.getValue());
00274 
00275     gravityCenter += (center * masses[i].mass);
00276     totalMass += masses[i].mass;
00277       }
00278 
00279     if(showCenterOfGravity.getValue()){
00280       glColor3f (1,1,0);
00281       glBegin (GL_LINES);
00282       gravityCenter /= totalMass;
00283       helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(showAxisSize.getValue(),0,0) );
00284       helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(showAxisSize.getValue(),0,0) );
00285       helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(0,showAxisSize.getValue(),0) );
00286       helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(0,showAxisSize.getValue(),0) );
00287       helper::gl::glVertexT(gravityCenter - RigidTypes::Vec3(0,0,showAxisSize.getValue()) );
00288       helper::gl::glVertexT(gravityCenter + RigidTypes::Vec3(0,0,showAxisSize.getValue()) );
00289       glEnd();
00290     }
00291   }
00292   template <>
00293       void DiagonalMass<Rigid3fTypes, Rigid3fMass>::reinit(){
00294     Inherited::init();
00295       }
00296   
00297       template <>
00298           void DiagonalMass<Rigid2fTypes, Rigid2fMass>::reinit(){
00299         Inherited::init();
00300           }
00301 
00302   template <>
00303   void DiagonalMass<Rigid3fTypes, Rigid3fMass>::init(){
00304     Inherited::init();
00305   }
00306   
00307   template <>
00308       void DiagonalMass<Rigid2fTypes, Rigid2fMass>::init(){
00309     Inherited::init();
00310       }
00311 
00312 
00313       template <>
00314       void DiagonalMass<Rigid2fTypes, Rigid2fMass>::draw()
00315       {
00316     const MassVector &masses= f_mass.getValue();
00317     if (!getContext()->getShowBehaviorModels()) return;
00318     VecCoord& x = *mstate->getX();
00319     for (unsigned int i=0; i<x.size(); i++)
00320     {
00321       Vec3d len;
00322       len[0] = len[1] = sqrt(masses[i].inertiaMatrix);
00323       len[2] = 0;
00324         
00325       Quat orient(Vec3d(0,0,1), x[i].getOrientation());
00326       Vec3d center; center = x[i].getCenter();
00327       helper::gl::Axis::draw(center, orient, len);
00328     }
00329       }
00330 
00331   
00332   
00333 #endif
00334 
00335 
00336 
00337 
00338 
00339   SOFA_DECL_CLASS(DiagonalMass)
00340 
00341   // Register in the Factory
00342   int DiagonalMassClass = core::RegisterObject("Define a specific mass for each particle") 
00343 #ifndef SOFA_FLOAT
00344     .add< DiagonalMass<Vec3dTypes,double> >()
00345     .add< DiagonalMass<Vec2dTypes,double> >()
00346     .add< DiagonalMass<Vec1dTypes,double> >()
00347     .add< DiagonalMass<Rigid3dTypes,Rigid3dMass> >()
00348     .add< DiagonalMass<Rigid2dTypes,Rigid2dMass> >()
00349 #endif
00350 #ifndef SOFA_DOUBLE
00351     .add< DiagonalMass<Vec3fTypes,float> >()
00352     .add< DiagonalMass<Vec2fTypes,float> >()
00353     .add< DiagonalMass<Vec1fTypes,float> >()
00354     .add< DiagonalMass<Rigid3fTypes,Rigid3fMass> >()
00355     .add< DiagonalMass<Rigid2fTypes,Rigid2fMass> >()
00356 #endif
00357     ;
00358 
00359 #ifndef SOFA_FLOAT
00360   template class DiagonalMass<Vec3dTypes,double>;
00361   template class DiagonalMass<Vec2dTypes,double>;
00362   template class DiagonalMass<Vec1dTypes,double>;
00363   template class DiagonalMass<Rigid3dTypes,Rigid3dMass>;
00364   template class DiagonalMass<Rigid2dTypes,Rigid2dMass>;
00365 #endif
00366 #ifndef SOFA_DOUBLE
00367   template class DiagonalMass<Vec3fTypes,float>;
00368   template class DiagonalMass<Vec2fTypes,float>;
00369   template class DiagonalMass<Vec1fTypes,float>;
00370   template class DiagonalMass<Rigid3fTypes,Rigid3fMass>;
00371   template class DiagonalMass<Rigid2fTypes,Rigid2fMass>;
00372 #endif
00373 
00374 
00375 } // namespace mass
00376 
00377 } // namespace component
00378 
00379 } // namespace sofa
00380 

Generated on Sun Nov 23 03:35:42 2008 for Sofa by  doxygen 1.5.7.1