PenalityContactForceField.inl
Go to the documentation of this file.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_PENALITYCONTACTFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_PENALITYCONTACTFORCEFIELD_INL
00027
00028 #include <sofa/core/componentmodel/behavior/ForceField.inl>
00029 #include <sofa/component/forcefield/PenalityContactForceField.h>
00030 #include <sofa/helper/system/config.h>
00031 #include <assert.h>
00032 #include <sofa/helper/gl/template.h>
00033 #include <iostream>
00034 using std::cerr;
00035 using std::endl;
00036
00037 namespace sofa
00038 {
00039
00040 namespace component
00041 {
00042
00043 namespace forcefield
00044 {
00045
00046 template<class DataTypes>
00047 void PenalityContactForceField<DataTypes>::clear(int reserve)
00048 {
00049 prevContacts.swap(*contacts.beginEdit());
00050 contacts.beginEdit()->clear();
00051 if (reserve)
00052 contacts.beginEdit()->reserve(reserve);
00053 contacts.endEdit();
00054 }
00055
00056 template<class DataTypes>
00057 void PenalityContactForceField<DataTypes>::addContact(int m1, int m2, int index1, int index2, const Deriv& norm, Real dist, Real ks, Real mu_s, Real mu_v, int oldIndex)
00058 {
00059 int i = contacts.getValue().size();
00060 contacts.beginEdit()->resize(i+1);
00061 Contact& c = (*contacts.beginEdit())[i];
00062 c.m1 = m1;
00063 c.m2 = m2;
00064 c.index1 = index1;
00065 c.index2 = index2;
00066 c.norm = norm;
00067 c.dist = dist;
00068 c.ks = ks;
00069 c.mu_s = mu_s;
00070 c.mu_v = mu_v;
00071 c.pen = 0;
00072 if (oldIndex > 0 && oldIndex <= (int)prevContacts.size())
00073 {
00074 c.age = prevContacts[oldIndex-1].age+1;
00075 }
00076 else
00077 {
00078 c.age = 0;
00079 }
00080 contacts.endEdit();
00081 }
00082
00083 template<class DataTypes>
00084 void PenalityContactForceField<DataTypes>::addForce(VecDeriv& f1, VecDeriv& f2, const VecCoord& x1, const VecCoord& x2, const VecDeriv& , const VecDeriv& )
00085 {
00086 f1.resize(x1.size());
00087 f2.resize(x2.size());
00088 for (unsigned int i=0; i<contacts.getValue().size(); i++)
00089 {
00090 Contact& c = (*contacts.beginEdit())[i];
00091 Coord u = x2[c.m2]-x1[c.m1];
00092 c.pen = c.dist - u*c.norm;
00093 if (c.pen > 0)
00094 {
00095 Real fN = c.ks * c.pen;
00096 Deriv force = -c.norm*fN;
00097 f1[c.m1]+=force;
00098 f2[c.m2]-=force;
00099 }
00100 }
00101 contacts.endEdit();
00102 }
00103
00104 template<class DataTypes>
00105 void PenalityContactForceField<DataTypes>::addDForce(VecDeriv& df1, VecDeriv& df2, const VecDeriv& dx1, const VecDeriv& dx2, double kFactor, double )
00106 {
00107 df1.resize(dx1.size());
00108 df2.resize(dx2.size());
00109 for (unsigned int i=0; i<contacts.getValue().size(); i++)
00110 {
00111 const Contact& c = contacts.getValue()[i];
00112 if (c.pen > 0)
00113 {
00114 Coord du = dx2[c.m2]-dx1[c.m1];
00115 Real dpen = - du*c.norm;
00116
00117 Real dfN = c.ks * dpen * (Real)kFactor;
00118 Deriv dforce = -c.norm*dfN;
00119 df1[c.m1]+=dforce;
00120 df2[c.m2]-=dforce;
00121 }
00122 }
00123 }
00124
00125 template <class DataTypes>
00126 double PenalityContactForceField<DataTypes>::getPotentialEnergy(const VecCoord&, const VecCoord&)
00127 {
00128 cerr<<"PenalityContactForceField::getPotentialEnergy-not-implemented !!!"<<endl;
00129 return 0;
00130 }
00131
00132 template<class DataTypes>
00133 void PenalityContactForceField<DataTypes>::draw()
00134 {
00135 if (!((this->mstate1 == this->mstate2)?getContext()->getShowForceFields():getContext()->getShowInteractionForceFields())) return;
00136 const VecCoord& p1 = *this->mstate1->getX();
00137 const VecCoord& p2 = *this->mstate2->getX();
00138 glDisable(GL_LIGHTING);
00139
00140 glBegin(GL_LINES);
00141 for (unsigned int i=0; i<contacts.getValue().size(); i++)
00142 {
00143 const Contact& c = contacts.getValue()[i];
00144 Real d = c.dist - (p2[c.m2]-p1[c.m1])*c.norm;
00145 if (c.age > 10)
00146 if (d > 0)
00147 glColor4f(1,0,1,1);
00148 else
00149 glColor4f(0,1,1,1);
00150 else
00151 if (d > 0)
00152 glColor4f(1,0,0,1);
00153 else
00154 glColor4f(0,1,0,1);
00155 helper::gl::glVertexT(p1[c.m1]);
00156 helper::gl::glVertexT(p2[c.m2]);
00157 }
00158 glEnd();
00159
00160 if (getContext()->getShowNormals())
00161 {
00162 glColor4f(1,1,0,1);
00163 glBegin(GL_LINES);
00164 for (unsigned int i=0; i<contacts.getValue().size(); i++)
00165 {
00166 const Contact& c = contacts.getValue()[i];
00167 Coord p = p1[c.m1] - c.norm;
00168 helper::gl::glVertexT(p1[c.m1]);
00169 helper::gl::glVertexT(p);
00170 p = p2[c.m2] + c.norm;
00171 helper::gl::glVertexT(p2[c.m2]);
00172 helper::gl::glVertexT(p);
00173 }
00174 glEnd();
00175 }
00176 }
00177
00178
00179 template<class DataTypes>
00180 void PenalityContactForceField<DataTypes>::grabPoint(
00181 const core::componentmodel::behavior::MechanicalState<defaulttype::Vec3Types> *tool,
00182 const helper::vector< unsigned int > &index,
00183 helper::vector< std::pair< core::objectmodel::BaseObject*, defaulttype::Vec3f> > &result,
00184 helper::vector< unsigned int > &triangle,
00185 helper::vector< unsigned int > &index_point)
00186 {
00187 if (static_cast< core::objectmodel::BaseObject *>(this->mstate1) == static_cast< const core::objectmodel::BaseObject *>(tool))
00188 {
00189 for (unsigned int i=0;i<contacts.getValue().size();i++)
00190 {
00191 for (unsigned int j=0;j<index.size();j++)
00192 {
00193 if (contacts.getValue()[i].m1 == (int)index[j])
00194 {
00195 result.push_back(std::make_pair(static_cast< core::objectmodel::BaseObject *>(this),
00196 (*this->mstate2->getX())[contacts.getValue()[i].m2])
00197 );
00198 triangle.push_back(contacts.getValue()[i].index2);
00199 index_point.push_back(index[j]);
00200 }
00201 }
00202 }
00203 }
00204 else if (static_cast< core::objectmodel::BaseObject *>(this->mstate2) == static_cast< const core::objectmodel::BaseObject *>(tool))
00205 {
00206
00207 for (unsigned int i=0;i<contacts.getValue().size();i++)
00208 {
00209 for (unsigned int j=0;j<index.size();j++)
00210 {
00211 if (contacts.getValue()[i].m2 == (int)index[j])
00212 {
00213 result.push_back(std::make_pair(static_cast< core::objectmodel::BaseObject *>(this),
00214 (*this->mstate1->getX())[contacts.getValue()[i].m1])
00215 );
00216
00217 triangle.push_back(contacts.getValue()[i].index1);
00218 index_point.push_back(index[j]);
00219 }
00220 }
00221 }
00222 }
00223
00224
00225 }
00226
00227
00228 }
00229
00230 }
00231
00232 }
00233
00234 #endif