PlaneForceField.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_INTERACTIONFORCEFIELD_PLANEFORCEFIELD_INL
00026 #define SOFA_COMPONENT_INTERACTIONFORCEFIELD_PLANEFORCEFIELD_INL
00027
00028
00029 #include "PlaneForceField.h"
00030 #include <sofa/helper/system/config.h>
00031 #include <sofa/defaulttype/VecTypes.h>
00032 #include <sofa/helper/gl/template.h>
00033 #include <assert.h>
00034 #include <iostream>
00035 using std::cerr;
00036 using std::endl;
00037
00038 namespace sofa
00039 {
00040
00041 namespace component
00042 {
00043
00044 namespace forcefield
00045 {
00046
00047
00048 template<class DataTypes>
00049 void PlaneForceField<DataTypes>::addForce(VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1)
00050 {
00051
00052 this->contacts.clear();
00053 f1.resize(p1.size());
00054 for (unsigned int i=0; i<p1.size(); i++)
00055 {
00056 Real d = p1[i]*planeNormal.getValue()-planeD.getValue();
00057 if (d<0)
00058 {
00059
00060 Real forceIntensity = -this->stiffness.getValue()*d;
00061
00062 Real dampingIntensity = -this->damping.getValue()*d;
00063
00064 Deriv force = planeNormal.getValue()*forceIntensity - v1[i]*dampingIntensity;
00065
00066 f1[i]+=force;
00067
00068 this->contacts.push_back(i);
00069 }
00070 }
00071 }
00072
00073 template<class DataTypes>
00074 void PlaneForceField<DataTypes>::addDForce(VecDeriv& f1, const VecDeriv& dx1, double kFactor, double )
00075 {
00076 f1.resize(dx1.size());
00077 const Real fact = (Real)(-this->stiffness.getValue()*kFactor);
00078 for (unsigned int i=0; i<this->contacts.size(); i++)
00079 {
00080 unsigned int p = this->contacts[i];
00081 assert(p<dx1.size());
00082 f1[p] += planeNormal.getValue() * (fact * (dx1[p]*planeNormal.getValue()));
00083 }
00084 }
00085
00086 template<class DataTypes>
00087 void PlaneForceField<DataTypes>::updateStiffness( const VecCoord& x )
00088 {
00089 this->contacts.clear();
00090 for (unsigned int i=0; i<x.size(); i++)
00091 {
00092 Real d = x[i]*planeNormal.getValue()-planeD.getValue();
00093 if (d<0)
00094 {
00095 this->contacts.push_back(i);
00096 }
00097 }
00098 }
00099
00100
00101 template <class DataTypes>
00102 double PlaneForceField<DataTypes>::getPotentialEnergy(const VecCoord&)
00103 {
00104 std::cerr<<"PlaneForceField::getPotentialEnergy-not-implemented !!!"<<std::endl;
00105 return 0;
00106 }
00107
00108
00109
00110 template<class DataTypes>
00111 void PlaneForceField<DataTypes>::rotate( Deriv axe, Real angle )
00112 {
00113 defaulttype::Vec3d axe3d(1,1,1); axe3d = axe;
00114 defaulttype::Vec3d normal3d; normal3d = planeNormal.getValue();
00115 defaulttype::Vec3d v = normal3d.cross(axe3d);
00116 v.normalize();
00117 v = normal3d * cos ( angle ) + v * sin ( angle );
00118 *planeNormal.beginEdit() = v;
00119 planeNormal.endEdit();
00120 }
00121
00122
00123 template<class DataTypes>
00124 void PlaneForceField<DataTypes>::draw()
00125 {
00126 if (!getContext()->getShowForceFields()) return;
00127 drawPlane();
00128 }
00129
00130
00131 template<class DataTypes>
00132 void PlaneForceField<DataTypes>::drawPlane(float size)
00133 {
00134 const VecCoord& p1 = *this->mstate->getX();
00135
00136 defaulttype::Vec3d normal; normal = planeNormal.getValue();
00137
00138
00139 defaulttype::Vec3d v1;
00140 if( 0.0 != normal[0] ) v1 = defaulttype::Vec3d(-normal[1]/normal[0], 1.0, 0.0);
00141 else if ( 0.0 != normal[1] ) v1 = defaulttype::Vec3d(1.0, -normal[0]/normal[1],0.0);
00142 else if ( 0.0 != normal[2] ) v1 = defaulttype::Vec3d(1.0, 0.0, -normal[0]/normal[2]);
00143 v1.normalize();
00144
00145 defaulttype::Vec3d v2;
00146 v2 = v1.cross(normal);
00147 v2.normalize();
00148
00149 defaulttype::Vec3d center = normal*planeD.getValue();
00150 defaulttype::Vec3d corners[4];
00151 corners[0] = center-v1*size-v2*size;
00152 corners[1] = center+v1*size-v2*size;
00153 corners[2] = center+v1*size+v2*size;
00154 corners[3] = center-v1*size+v2*size;
00155
00156
00157 glEnable(GL_CULL_FACE);
00158 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00159 glCullFace(GL_FRONT);
00160
00161 glColor3f(color.getValue()[0],color.getValue()[1],color.getValue()[2]);
00162
00163 glBegin(GL_QUADS);
00164 helper::gl::glVertexT(corners[0]);
00165 helper::gl::glVertexT(corners[1]);
00166 helper::gl::glVertexT(corners[2]);
00167 helper::gl::glVertexT(corners[3]);
00168 glEnd();
00169
00170 glDisable(GL_CULL_FACE);
00171
00172 glColor4f(1,0,0,1);
00173 glDisable(GL_LIGHTING);
00174
00175 glBegin(GL_LINES);
00176 for (unsigned int i=0; i<p1.size(); i++)
00177 {
00178 Real d = p1[i]*planeNormal.getValue()-planeD.getValue();
00179 Coord p2 = p1[i];
00180 p2 += planeNormal.getValue()*(-d);
00181 if (d<0)
00182 {
00183 helper::gl::glVertexT(p1[i]);
00184 helper::gl::glVertexT(p2);
00185 }
00186 }
00187 glEnd();
00188 }
00189
00190 template <class DataTypes>
00191 bool PlaneForceField<DataTypes>::addBBox(double* minBBox, double* maxBBox)
00192 {
00193 if (!bDraw.getValue()) return false;
00194
00195 defaulttype::Vec3d normal; normal = planeNormal.getValue();
00196 double size=10.0;
00197
00198
00199 defaulttype::Vec3d v1;
00200 if( 0.0 != normal[0] ) v1 = defaulttype::Vec3d(-normal[1]/normal[0], 1.0, 0.0);
00201 else if ( 0.0 != normal[1] ) v1 = defaulttype::Vec3d(1.0, -normal[0]/normal[1],0.0);
00202 else if ( 0.0 != normal[2] ) v1 = defaulttype::Vec3d(1.0, 0.0, -normal[0]/normal[2]);
00203 v1.normalize();
00204
00205 defaulttype::Vec3d v2;
00206 v2 = v1.cross(normal);
00207 v2.normalize();
00208
00209 defaulttype::Vec3d center = normal*planeD.getValue();
00210 defaulttype::Vec3d corners[4];
00211 corners[0] = center-v1*size-v2*size;
00212 corners[1] = center+v1*size-v2*size;
00213 corners[2] = center+v1*size+v2*size;
00214 corners[3] = center-v1*size+v2*size;
00215
00216 for (unsigned int i=0; i<4; i++)
00217 {
00218 for (int c=0;c<3;c++)
00219 {
00220 if (corners[i][c] > maxBBox[c]) maxBBox[c] = corners[i][c];
00221 if (corners[i][c] < minBBox[c]) minBBox[c] = corners[i][c];
00222 }
00223 }
00224 return true;
00225 }
00226
00227 }
00228
00229 }
00230
00231 }
00232
00233 #endif