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_FORCEFIELD_FRAMESPRINGFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_FRAMESPRINGFORCEFIELD_INL
00027
00028 #include <sofa/component/forcefield/FrameSpringForceField.h>
00029 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00030 #include <sofa/helper/io/MassSpringLoader.h>
00031 #include <sofa/helper/gl/template.h>
00032 #include <sofa/helper/gl/Cylinder.h>
00033 #include <sofa/helper/gl/Axis.h>
00034 #include <sofa/helper/system/config.h>
00035 #include <assert.h>
00036 #include <iostream>
00037
00038 using std::cerr;
00039 using std::endl;
00040
00041 namespace sofa
00042 {
00043
00044 namespace component
00045 {
00046
00047 namespace forcefield
00048 {
00049
00050
00051 template<class DataTypes>
00052 FrameSpringForceField<DataTypes>::FrameSpringForceField ( MechanicalState* object1, MechanicalState* object2 )
00053 : Inherit ( object1, object2 )
00054 , springs ( initData ( &springs,"spring","pairs of indices, stiffness, damping, rest length" ) )
00055 , showLawfulTorsion ( initData ( &showLawfulTorsion, false, "show lawful Torsion", "dislpay the lawful part of the joint rotation" ) )
00056 , showExtraTorsion ( initData ( &showExtraTorsion, false, "show illicit Torsion", "dislpay the illicit part of the joint rotation" ) )
00057 {
00058 }
00059
00060 template<class DataTypes>
00061 FrameSpringForceField<DataTypes>::FrameSpringForceField()
00062 : springs ( initData ( &springs,"spring","pairs of indices, stiffness, damping, rest length" ) )
00063 , showLawfulTorsion ( initData ( &showLawfulTorsion, false, "show lawful Torsion", "dislpay the lawful part of the joint rotation" ) )
00064 , showExtraTorsion ( initData ( &showExtraTorsion, false, "show illicit Torsion", "dislpay the illicit part of the joint rotation" ) )
00065 {
00066 }
00067
00068
00069 template <class DataTypes>
00070 void FrameSpringForceField<DataTypes>::init()
00071 {
00072 this->Inherit::init();
00073 }
00074
00075 template<class DataTypes>
00076 void FrameSpringForceField<DataTypes>::addSpringForce ( double& , VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1, VecDeriv& f2, const VecCoord& p2, const VecDeriv& v2, int , Spring& spring )
00077 {
00078 int a = spring.m1;
00079 int b = spring.m2;
00080
00081 Mat Mr01, Mr10, Mr02, Mr20;
00082 p1[a].writeRotationMatrix ( Mr01 );
00083 invertMatrix ( Mr10, Mr01 );
00084 p2[b].writeRotationMatrix ( Mr02 );
00085 invertMatrix ( Mr20, Mr02 );
00086
00087 Deriv Vp1p2 = v2[b] - v1[a];
00088
00089 VecN damping ( spring.kd, spring.kd, spring.kd );
00090 VecN kst ( spring.stiffnessTrans, spring.stiffnessTrans, spring.stiffnessTrans );
00091 VecN ksr ( spring.stiffnessRot, spring.stiffnessRot, spring.stiffnessRot );
00092
00093
00094 springRef[a] = p1[a];
00095
00096 VecN fT = kst.linearProduct( ( p2[b].getCenter() + Mr02 * ( spring.vec2)) - ( p1[a].getCenter() + Mr01 * ( spring.vec1))) + damping.linearProduct ( Vp1p2.getVCenter());
00097 VecN fR = ksr.linearProduct( ( p1[a].getOrientation().inverse() * p2[b].getOrientation()).toEulerVector());
00098
00099 VecN C1 = fR + cross( Mr01 * ( spring.vec1), fT) + damping.linearProduct ( Vp1p2.getVOrientation() );
00100 VecN C2 = fR + cross( Mr02 * ( spring.vec2), fT) + damping.linearProduct ( -Vp1p2.getVOrientation() );
00101
00102 f1[a] += Deriv ( fT, C1);
00103 f2[b] -= Deriv ( fT, C2);
00104
00105
00106
00107
00108
00109 }
00110
00111 template<class DataTypes>
00112 void FrameSpringForceField<DataTypes>::addSpringDForce ( VecDeriv& f1, const VecDeriv& dx1, VecDeriv& f2, const VecDeriv& dx2, int , Spring& spring )
00113 {
00114 const int a = spring.m1;
00115 const int b = spring.m2;
00116 const Deriv Mdx1dx2 = dx2[b] - dx1[a];
00117
00118 Mat Mr01, Mr10;
00119 springRef[a].writeRotationMatrix ( Mr01 );
00120 invertMatrix ( Mr10, Mr01 );
00121
00122 VecN kst ( spring.stiffnessTrans, spring.stiffnessTrans, spring.stiffnessTrans );
00123 VecN ksr ( spring.stiffnessRot, spring.stiffnessRot, spring.stiffnessRot );
00124
00125
00126 VecN df0 = Mr01 * ( kst.linearProduct ( Mr10*Mdx1dx2.getVCenter() ) );
00127
00128 VecN dR0 = Mr01 * ( ksr.linearProduct ( Mr10* Mdx1dx2.getVOrientation() ) );
00129
00130 const Deriv dforce ( df0,dR0);
00131
00132 f1[a] += dforce;
00133 f2[b] -= dforce;
00134 }
00135
00136 template<class DataTypes>
00137 void FrameSpringForceField<DataTypes>::addForce ( VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& v1, const VecDeriv& v2 )
00138 {
00139 helper::vector<Spring>& springs = *this->springs.beginEdit();
00140
00141 springRef.resize ( x1.size() );
00142
00143 f1.resize ( x1.size() );
00144 f2.resize ( x2.size() );
00145 m_potentialEnergy = 0;
00146 for ( unsigned int i=0; i<springs.size(); i++ )
00147 {
00148 this->addSpringForce ( m_potentialEnergy,f1,x1,v1,f2,x2,v2, i, springs[i] );
00149 }
00150 this->springs.endEdit();
00151 }
00152
00153 template<class DataTypes>
00154 void FrameSpringForceField<DataTypes>::addDForce ( VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2 )
00155 {
00156 df1.resize ( dx1.size() );
00157 df2.resize ( dx2.size() );
00158
00159
00160 helper::vector<Spring>& springs = *this->springs.beginEdit();
00161 for ( unsigned int i=0; i<springs.size(); i++ )
00162 {
00163 this->addSpringDForce ( df1,dx1,df2,dx2, i, springs[i] );
00164 }
00165 this->springs.endEdit();
00166 }
00167
00168 template<class DataTypes>
00169 void FrameSpringForceField<DataTypes>::draw()
00170 {
00171 if ( ! ( ( this->mstate1 == this->mstate2 ) ?getContext()->getShowForceFields() :getContext()->getShowInteractionForceFields() ) ) return;
00172 const VecCoord& p1 = *this->mstate1->getX();
00173 const VecCoord& p2 = *this->mstate2->getX();
00174
00175 glDisable ( GL_LIGHTING );
00176 bool external = ( this->mstate1!=this->mstate2 );
00177 const helper::vector<Spring>& springs = this->springs.getValue();
00178
00179 for ( unsigned int i=0; i<springs.size(); i++ )
00180 {
00181 double restLength = (springs[i].vec1.norm() + springs[i].vec2.norm());
00182 Real d = ( p2[springs[i].m2].getCenter()-p1[springs[i].m1].getCenter()).norm();
00183 if ( external )
00184 {
00185 if ( d < restLength *0.9999 )
00186 glColor4f ( 1,0,0,1 );
00187 else
00188 glColor4f ( 0,1,0,1 );
00189 }
00190 else
00191 {
00192 if ( d < restLength *0.9999 )
00193 glColor4f ( 1,0.5f,0,1 );
00194 else
00195 glColor4f ( 0,1,0.5f,1 );
00196 }
00197 glBegin ( GL_LINES );
00198 helper::gl::glVertexT ( p1[springs[i].m1].getCenter() );
00199 helper::gl::glVertexT ( p2[springs[i].m2].getCenter() );
00200
00201
00202
00203
00204
00205
00206
00207 glEnd();
00208 }
00209 }
00210
00211
00212 template<class DataTypes>
00213 void FrameSpringForceField<DataTypes>::clear ( int reserve )
00214 {
00215 helper::vector<Spring>& springs = *this->springs.beginEdit();
00216 springs.clear();
00217 if ( reserve ) springs.reserve ( reserve );
00218 this->springs.endEdit();
00219 }
00220
00221 template<class DataTypes>
00222 void FrameSpringForceField<DataTypes>::addSpring ( const Spring& s )
00223 {
00224 springs.beginEdit()->push_back ( s );
00225 springs.endEdit();
00226 }
00227
00228
00229 template<class DataTypes>
00230 void FrameSpringForceField<DataTypes>::addSpring ( int m1, int m2, Real softKst, Real softKsr, Real kd )
00231 {
00232 Spring s ( m1,m2,softKst,softKsr, kd );
00233
00234
00235 springs.beginEdit()->push_back ( s );
00236 springs.endEdit();
00237 }
00238
00239 }
00240
00241 }
00242
00243 }
00244
00245 #endif
00246