SphereForceField.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_SPHEREFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_SPHEREFORCEFIELD_INL
00027
00028 #include <sofa/core/componentmodel/behavior/ForceField.inl>
00029 #include "SphereForceField.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 template<class DataTypes>
00063 void SphereForceField<DataTypes>::addForce(VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1)
00064 {
00065 const Coord center = sphereCenter.getValue();
00066 const Real r = sphereRadius.getValue();
00067 const Real r2 = r*r;
00068 this->contacts.beginEdit()->clear();
00069 f1.resize(p1.size());
00070 for (unsigned int i=0; i<p1.size(); i++)
00071 {
00072 Coord dp = p1[i] - center;
00073 Real norm2 = dp.norm2();
00074 if (norm2<r2)
00075 {
00076 Real norm = helper::rsqrt(norm2);
00077 Real d = norm - r;
00078 Real forceIntensity = -this->stiffness.getValue()*d;
00079 Real dampingIntensity = -this->damping.getValue()*d;
00080 Deriv force = dp*(forceIntensity/norm) - v1[i]*dampingIntensity;
00081 f1[i]+=force;
00082 Contact c;
00083 c.index = i;
00084 c.normal = dp / norm;
00085 c.fact = r / norm;
00086 this->contacts.beginEdit()->push_back(c);
00087 }
00088 }
00089 this->contacts.endEdit();
00090 }
00091
00092 template<class DataTypes>
00093 void SphereForceField<DataTypes>::addDForce(VecDeriv& df1, const VecDeriv& dx1, double kFactor, double )
00094 {
00095 df1.resize(dx1.size());
00096 const Real fact = (Real)(-this->stiffness.getValue()*kFactor);
00097 for (unsigned int i=0; i<this->contacts.getValue().size(); i++)
00098 {
00099 const Contact& c = (this->contacts.getValue())[i];
00100 assert((unsigned)c.index<dx1.size());
00101 Deriv du = dx1[c.index];
00102 Deriv dforce; dforce = fact*(c.normal * ((du*c.normal)*c.fact) + du * (1 - c.fact));
00103 df1[c.index] += dforce;
00104 }
00105 }
00106
00107 template<class DataTypes>
00108 void SphereForceField<DataTypes>::updateStiffness( const VecCoord& x )
00109 {
00110 const Coord center = sphereCenter.getValue();
00111 const Real r = sphereRadius.getValue();
00112 const Real r2 = r*r;
00113 this->contacts.beginEdit()->clear();
00114 for (unsigned int i=0; i<x.size(); i++)
00115 {
00116 Coord dp = x[i] - center;
00117 Real norm2 = dp.norm2();
00118 if (norm2<r2)
00119 {
00120 Real norm = helper::rsqrt(norm2);
00121 Contact c;
00122 c.index = i;
00123 c.normal = dp / norm;
00124 c.fact = r / norm;
00125 this->contacts.beginEdit()->push_back(c);
00126 }
00127 }
00128 this->contacts.endEdit();
00129 }
00130
00131 template <class DataTypes>
00132 double SphereForceField<DataTypes>::getPotentialEnergy(const VecCoord&)
00133 {
00134 std::cerr<<"SphereForceField::getPotentialEnergy-not-implemented !!!"<<std::endl;
00135 return 0;
00136 }
00137
00138 template<class DataTypes>
00139 void SphereForceField<DataTypes>::draw()
00140 {
00141 if (!getContext()->getShowForceFields()) return;
00142 if (!bDraw.getValue()) return;
00143
00144 const Coord center = sphereCenter.getValue();
00145 const Real r = sphereRadius.getValue();
00146
00147 glEnable(GL_LIGHTING);
00148 glEnable(GL_COLOR_MATERIAL);
00149 glColor3f(color.getValue()[0],color.getValue()[1],color.getValue()[2]);
00150 glPushMatrix();
00151 glTranslated(center[0], center[1], center[2]);
00152 glutSolidSphere(r*0.99,32,16);
00153 glPopMatrix();
00154 glDisable(GL_LIGHTING);
00155 glDisable(GL_COLOR_MATERIAL);
00156 }
00157
00158
00159 }
00160
00161 }
00162
00163 }
00164
00165 #endif