PlaneForceField.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #ifndef SOFA_COMPONENT_INTERACTIONFORCEFIELD_PLANEFORCEFIELD_INL
00026 #define SOFA_COMPONENT_INTERACTIONFORCEFIELD_PLANEFORCEFIELD_INL
00027 
00028 //#include <sofa/core/componentmodel/behavior/ForceField.inl>
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     //this->dfdd.resize(p1.size());
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                   //cerr<<"PlaneForceField<DataTypes>::addForce, d = "<<d<<endl;    
00060                   Real forceIntensity = -this->stiffness.getValue()*d;
00061                   //cerr<<"PlaneForceField<DataTypes>::addForce, stiffness = "<<stiffness.getValue()<<endl; 
00062                   Real dampingIntensity = -this->damping.getValue()*d;
00063                   //cerr<<"PlaneForceField<DataTypes>::addForce, dampingIntensity = "<<dampingIntensity<<endl;  
00064                   Deriv force = planeNormal.getValue()*forceIntensity - v1[i]*dampingIntensity;
00065                   //cerr<<"PlaneForceField<DataTypes>::addForce, force = "<<force<<endl;    
00066                   f1[i]+=force;
00067             //this->dfdd[i] = -this->stiffness;
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 /*bFactor*/)
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 // Rotate the plane. Note that the rotation is only applied on the 3 first coordinates
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     // find a first vector inside the plane
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     // find a second vector inside the plane and orthogonal to the first
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     // glEnable(GL_LIGHTING);
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     // lines for points penetrating the plane
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     // find a first vector inside the plane
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     // find a second vector inside the plane and orthogonal to the first
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 } // namespace forcefield
00228 
00229 } // namespace component
00230 
00231 } // namespace sofa
00232 
00233 #endif

Generated on Sun Nov 23 03:03:32 2008 for Sofa by  doxygen 1.5.7.1