EllipsoidForceField.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_ELLIPSOIDFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_ELLIPSOIDFORCEFIELD_INL
00027
00028 #include <sofa/core/componentmodel/behavior/ForceField.inl>
00029 #include "EllipsoidForceField.h"
00030 #include <sofa/helper/system/config.h>
00031 #include <sofa/helper/rmath.h>
00032 #include <sofa/helper/system/gl.h>
00033 #include <sofa/helper/system/glut.h>
00034 #include <assert.h>
00035 #include <iostream>
00036
00037 namespace sofa
00038 {
00039
00040 namespace component
00041 {
00042
00043 namespace forcefield
00044 {
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 template<class DataTypes>
00069 void EllipsoidForceField<DataTypes>::addForce(VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1)
00070 {
00071 const Coord center = this->center.getValue();
00072 const Coord r = this->vradius.getValue();
00073 const Real stiffness = this->stiffness.getValue();
00074 const Real stiffabs = helper::rabs(stiffness);
00075
00076 Coord inv_r2;
00077 for (int j=0; j<N; j++) inv_r2[j] = 1/(r[j]*r[j]);
00078 sofa::helper::vector<Contact>* contacts = this->contacts.beginEdit();
00079 contacts->clear();
00080 f1.resize(p1.size());
00081 for (unsigned int i=0; i<p1.size(); i++)
00082 {
00083 Coord dp = p1[i] - center;
00084 Real norm2 = 0;
00085 for (int j=0; j<N; j++) norm2 += (dp[j]*dp[j])*inv_r2[j];
00086
00087 if ((norm2-1)*stiffness<0)
00088 {
00089 Real norm = helper::rsqrt(norm2);
00090 Real v = norm-1;
00091 Coord grad;
00092 for (int j=0; j<N; j++) grad[j] = dp[j]*inv_r2[j];
00093 Real gnorm2 = grad.norm2();
00094 Real gnorm = helper::rsqrt(gnorm2);
00095
00096 Real forceIntensity = -stiffabs*v/gnorm;
00097 Real dampingIntensity = this->damping.getValue()*helper::rabs(v);
00098 Deriv force = forceIntensity*grad - v1[i]*dampingIntensity;
00099 f1[i]+=force;
00100 Contact c;
00101 c.index = i;
00102 Real fact1 = -stiffabs / (norm * gnorm);
00103 Real fact2 = -stiffabs*v / gnorm;
00104 Real fact3 = -stiffabs*v / gnorm2;
00105 for (int ci = 0; ci < N; ++ci)
00106 {
00107 for (int cj = 0; cj < N; ++cj)
00108 c.m[ci][cj] = grad[ci]*grad[cj] * (fact1 + fact3*inv_r2[cj]);
00109 c.m[ci][ci] += fact2*inv_r2[ci];
00110 }
00111 contacts->push_back(c);
00112 }
00113 }
00114 this->contacts.endEdit();
00115 }
00116
00117 template<class DataTypes>
00118 void EllipsoidForceField<DataTypes>::addDForce(VecDeriv& df1, const VecDeriv& dx1, double kFactor, double )
00119 {
00120 df1.resize(dx1.size());
00121 const sofa::helper::vector<Contact>& contacts = this->contacts.getValue();
00122 for (unsigned int i=0; i<contacts.size(); i++)
00123 {
00124 const Contact& c = contacts[i];
00125 assert((unsigned)c.index<dx1.size());
00126 Deriv du = dx1[c.index];
00127 Deriv dforce = c.m * du;
00128 dforce *= kFactor;
00129 df1[c.index] += dforce;
00130 }
00131 }
00132
00133 template <class DataTypes>
00134 double EllipsoidForceField<DataTypes>::getPotentialEnergy(const VecCoord&)
00135 {
00136 std::cerr<<"EllipsoidForceField::getPotentialEnergy-not-implemented !!!"<<std::endl;
00137 return 0;
00138 }
00139
00140 template<class DataTypes>
00141 void EllipsoidForceField<DataTypes>::draw()
00142 {
00143 if (!getContext()->getShowForceFields()) return;
00144 if (!bDraw.getValue()) return;
00145
00146 Real cx=0, cy=0, cz=0;
00147 DataTypes::get(cx, cy, cz, center.getValue());
00148 Real rx=1, ry=1, rz=1;
00149 DataTypes::get(rx, ry, rz, vradius.getValue());
00150 glEnable(GL_CULL_FACE);
00151 glEnable(GL_LIGHTING);
00152 glEnable(GL_COLOR_MATERIAL);
00153 glColor3f(color.getValue()[0],color.getValue()[1],color.getValue()[2]);
00154 glPushMatrix();
00155 glTranslated(cx, cy, cz);
00156 glScaled(rx, ry, (stiffness.getValue()>0?rz:-rz));
00157 glutSolidSphere(1,32,16);
00158 glPopMatrix();
00159 glDisable(GL_CULL_FACE);
00160 glDisable(GL_LIGHTING);
00161 glDisable(GL_COLOR_MATERIAL);
00162 }
00163
00164
00165 }
00166
00167 }
00168
00169 }
00170
00171 #endif