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 #ifndef SOFA_COMPONENT_MASS_UNIFORMMASS_INL
00026 #define SOFA_COMPONENT_MASS_UNIFORMMASS_INL
00027
00028 #include <sofa/component/mass/UniformMass.h>
00029 #include <sofa/core/componentmodel/behavior/Mass.inl>
00030 #include <sofa/core/objectmodel/Context.h>
00031 #include <sofa/helper/gl/template.h>
00032 #include <sofa/defaulttype/RigidTypes.h>
00033 #include <sofa/defaulttype/DataTypeInfo.h>
00034 #include <sofa/component/mass/AddMToMatrixFunctor.h>
00035 #include <iostream>
00036 #include <string.h>
00037
00038 using std::cerr;
00039 using std::endl;
00040
00041 namespace sofa
00042 {
00043
00044 namespace component
00045 {
00046
00047 namespace mass
00048 {
00049
00050 using namespace sofa::defaulttype;
00051
00052
00053 template <class DataTypes, class MassType>
00054 UniformMass<DataTypes, MassType>::UniformMass()
00055 : mass( initData(&mass, MassType(1.0f), "mass", "Mass of each particle") )
00056 , totalMass( initData(&totalMass, 0.0, "totalmass", "Sum of the particles' masses") )
00057 , showCenterOfGravity( initData(&showCenterOfGravity, false, "showGravityCenter", "display the center of gravity of the system" ) )
00058 , showAxisSize( initData(&showAxisSize, 1.0f, "showAxisSizeFactor", "factor length of the axis displayed (only used for rigids)" ) )
00059 {}
00060
00061 template <class DataTypes, class MassType>
00062 UniformMass<DataTypes, MassType>::~UniformMass()
00063 {}
00064
00065 template <class DataTypes, class MassType>
00066 void UniformMass<DataTypes, MassType>::setMass(const MassType& m)
00067 {
00068 this->mass.setValue(m);
00069 }
00070
00071 template <class DataTypes, class MassType>
00072 void UniformMass<DataTypes, MassType>::setTotalMass(double m)
00073 {
00074 this->totalMass.setValue(m);
00075 }
00076
00077 template <class DataTypes, class MassType>
00078 void UniformMass<DataTypes, MassType>::init()
00079 {
00080 this->core::componentmodel::behavior::Mass<DataTypes>::init();
00081 if (this->totalMass.getValue()>0 && this->mstate!=NULL)
00082 {
00083 MassType* m = this->mass.beginEdit();
00084 *m = ((typename DataTypes::Real)this->totalMass.getValue() / this->mstate->getX()->size());
00085 this->mass.endEdit();
00086 }
00087 }
00088
00089
00090 template <class DataTypes, class MassType>
00091 void UniformMass<DataTypes, MassType>::addMDx(VecDeriv& res, const VecDeriv& dx, double factor)
00092 {
00093 MassType m = mass.getValue();
00094 if (factor != 1.0)
00095 m *= (typename DataTypes::Real)factor;
00096 for (unsigned int i=0;i<dx.size();i++)
00097 {
00098 res[i] += dx[i] * m;
00099 }
00100 }
00101
00102 template <class DataTypes, class MassType>
00103 void UniformMass<DataTypes, MassType>::accFromF(VecDeriv& a, const VecDeriv& f)
00104 {
00105 const MassType& m = mass.getValue();
00106 for (unsigned int i=0;i<f.size();i++)
00107 {
00108 a[i] = f[i] / m;
00109 }
00110 }
00111
00112
00113 template <class DataTypes, class MassType>
00114 void UniformMass<DataTypes, MassType>::addMDxToVector(defaulttype::BaseVector * , const VecDeriv* , SReal , unsigned int& )
00115 {
00116
00117 }
00118
00119 template <class DataTypes, class MassType>
00120 void UniformMass<DataTypes, MassType>::addGravityToV(double dt)
00121 {
00122 if (this->mstate){
00123 VecDeriv& v = *this->mstate->getV();
00124 const SReal* g = this->getContext()->getLocalGravity().ptr();
00125 Deriv theGravity;
00126 DataTypes::set( theGravity, g[0], g[1], g[2]);
00127 Deriv hg = theGravity * (Real)dt;
00128 if (this->f_printLog.getValue())
00129 std::cerr << "UniformMass::addGravityToV hg = "<<theGravity<<"*"<<dt<<"="<<hg<<std::endl;
00130 for (unsigned int i=0;i<v.size();i++) {
00131 v[i] += hg;
00132 }
00133 }
00134 }
00135
00136 template <class DataTypes, class MassType>
00137 #ifdef SOFA_SUPPORT_MOVING_FRAMES
00138 void UniformMass<DataTypes, MassType>::addForce(VecDeriv& f, const VecCoord& x, const VecDeriv& v)
00139 #else
00140 void UniformMass<DataTypes, MassType>::addForce(VecDeriv& f, const VecCoord& , const VecDeriv& )
00141 #endif
00142 {
00143
00144 if(this->m_separateGravity.getValue())
00145 return;
00146
00147
00148 const SReal* g = this->getContext()->getLocalGravity().ptr();
00149 Deriv theGravity;
00150 DataTypes::set
00151 ( theGravity, g[0], g[1], g[2]);
00152 const MassType& m = mass.getValue();
00153 Deriv mg = theGravity * m;
00154 if (this->f_printLog.getValue())
00155 cerr<<"UniformMass::addForce, mg = "<<mass<<" * "<<theGravity<<" = "<<mg<<endl;
00156
00157 #ifdef SOFA_SUPPORT_MOVING_FRAMES
00158
00159 core::objectmodel::BaseContext::SpatialVector vframe = getContext()->getVelocityInWorld();
00160 core::objectmodel::BaseContext::Vec3 aframe = getContext()->getVelocityBasedLinearAccelerationInWorld() ;
00161
00162
00163
00164
00165
00166 vframe = getContext()->getPositionInWorld() / vframe;
00167 aframe = getContext()->getPositionInWorld().backProjectVector( aframe );
00168
00169
00170
00171 #endif
00172
00173
00174 for (unsigned int i=0;i<f.size();i++)
00175 {
00176 #ifdef SOFA_SUPPORT_MOVING_FRAMES
00177 f[i] += mg + core::componentmodel::behavior::inertiaForce(vframe,aframe,m,x[i],v[i]);
00178 #else
00179 f[i] += mg;
00180 #endif
00181
00182
00183 }
00184
00185 }
00186
00187 template <class DataTypes, class MassType>
00188 double UniformMass<DataTypes, MassType>::getKineticEnergy( const VecDeriv& v )
00189 {
00190 double e=0;
00191 const MassType& m = mass.getValue();
00192 for (unsigned int i=0;i<v.size();i++)
00193 {
00194 e+= v[i]*m*v[i];
00195 }
00196
00197 return e/2;
00198 }
00199
00200 template <class DataTypes, class MassType>
00201 double UniformMass<DataTypes, MassType>::getPotentialEnergy( const VecCoord& x )
00202 {
00203 double e = 0;
00204 const MassType& m = mass.getValue();
00205
00206 Vec3d g ( this->getContext()->getLocalGravity() );
00207 Deriv theGravity;
00208 DataTypes::set
00209 ( theGravity, g[0], g[1], g[2]);
00210 Deriv mg = theGravity * m;
00211
00212 for (unsigned int i=0;i<x.size();i++)
00213 {
00214
00215
00216
00217 e -= mg*x[i];
00218 }
00219 return e;
00220 }
00221
00223 template <class DataTypes, class MassType>
00224 void UniformMass<DataTypes, MassType>::addMToMatrix(defaulttype::BaseMatrix * mat, double mFact, unsigned int &offset)
00225 {
00226 const MassType& m = mass.getValue();
00227 const int N = defaulttype::DataTypeInfo<Deriv>::size();
00228 const unsigned int size = this->mstate->getSize();
00229 AddMToMatrixFunctor<Deriv,MassType> calc;
00230 for (unsigned int i=0;i<size;i++)
00231 calc(mat, m, offset + N*i, mFact);
00232 }
00233
00234
00235 template <class DataTypes, class MassType>
00236 double UniformMass<DataTypes, MassType>::getElementMass(unsigned int )
00237 {
00238 return (double)(mass.getValue());
00239 }
00240
00241
00242 template <class DataTypes, class MassType>
00243 void UniformMass<DataTypes, MassType>::draw()
00244 {
00245 if (!getContext()->getShowBehaviorModels())
00246 return;
00247 const VecCoord& x = *this->mstate->getX();
00248
00249 Coord gravityCenter;
00250 glDisable (GL_LIGHTING);
00251 glPointSize(2);
00252 glColor4f (1,1,1,1);
00253 glBegin (GL_POINTS);
00254 for (unsigned int i=0; i<x.size(); i++)
00255 {
00256 helper::gl::glVertexT(x[i]);
00257 gravityCenter += x[i];
00258 }
00259 glEnd();
00260
00261 if(showCenterOfGravity.getValue()){
00262 glBegin (GL_LINES);
00263 glColor4f (1,1,0,1);
00264 gravityCenter /= x.size();
00265 for(unsigned int i=0 ; i<Coord::static_size ; i++){
00266 Coord v;
00267 v[i] = showAxisSize.getValue();
00268 helper::gl::glVertexT(gravityCenter-v);
00269 helper::gl::glVertexT(gravityCenter+v);
00270 }
00271 glEnd();
00272 }
00273 }
00274
00275 template <class DataTypes, class MassType>
00276 bool UniformMass<DataTypes, MassType>::addBBox(double* minBBox, double* maxBBox)
00277 {
00278 const VecCoord& x = *this->mstate->getX();
00279 for (unsigned int i=0; i<x.size(); i++)
00280 {
00281
00282 Real p[3] = {0.0, 0.0, 0.0};
00283 DataTypes::get(p[0],p[1],p[2],x[i]);
00284 for (int c=0;c<3;c++)
00285 {
00286 if (p[c] > maxBBox[c]) maxBBox[c] = p[c];
00287 if (p[c] < minBBox[c]) minBBox[c] = p[c];
00288 }
00289 }
00290 return true;
00291 }
00292
00293 template<class DataTypes, class MassType>
00294 void UniformMass<DataTypes, MassType>::parse(core::objectmodel::BaseObjectDescription* arg)
00295 {
00296 Inherited::parse(arg);
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 }
00308
00309
00310
00311 #ifndef SOFA_FLOAT
00312
00313 template<>
00314 void UniformMass<Rigid3dTypes, Rigid3dMass>::parse(core::objectmodel::BaseObjectDescription* arg);
00315 template <>
00316 void UniformMass<Rigid3dTypes, Rigid3dMass>::draw();
00317 template <>
00318 void UniformMass<Rigid2dTypes, Rigid2dMass>::draw();
00319 template <>
00320 double UniformMass<Rigid3dTypes,Rigid3dMass>::getPotentialEnergy( const VecCoord& x );
00321 template <>
00322 double UniformMass<Rigid2dTypes,Rigid2dMass>::getPotentialEnergy( const VecCoord& x );
00323 template <>
00324 void UniformMass<Vec6dTypes,double>::draw();
00325 #endif
00326 #ifndef SOFA_DOUBLE
00327 template<>
00328 void UniformMass<Rigid3fTypes, Rigid3fMass>::parse(core::objectmodel::BaseObjectDescription* arg);
00329 template <>
00330 void UniformMass<Rigid3fTypes, Rigid3fMass>::draw();
00331 template <>
00332 void UniformMass<Rigid2fTypes, Rigid2fMass>::draw();
00333 template <>
00334 double UniformMass<Rigid3fTypes,Rigid3fMass>::getPotentialEnergy( const VecCoord& x );
00335 template <>
00336 double UniformMass<Rigid2fTypes,Rigid2fMass>::getPotentialEnergy( const VecCoord& x );
00337 template <>
00338 void UniformMass<Vec6fTypes,float>::draw();
00339 #endif
00340
00341
00342
00343 }
00344
00345 }
00346
00347 }
00348
00349 #endif
00350
00351
00352