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_INTERACTION_ELLIPSOIDFORCEFIELD_H
00026 #define SOFA_COMPONENT_FORCEFIELD_INTERACTION_ELLIPSOIDFORCEFIELD_H
00027
00028 #include <sofa/core/componentmodel/behavior/MixedInteractionForceField.h>
00029 #include <sofa/core/componentmodel/behavior/MechanicalState.h>
00030 #include <sofa/core/objectmodel/Data.h>
00031 #include <sofa/defaulttype/RigidTypes.h>
00032
00033
00034
00035 namespace sofa
00036 {
00037
00038 namespace component
00039 {
00040
00041 namespace interactionforcefield
00042 {
00043 using namespace sofa::defaulttype;
00044
00046 template<class DataTypes1, class DataTypes2>
00047 class InteractionEllipsoidForceFieldInternalData
00048 {
00049 public:
00050 };
00051
00052 template<class DataTypes1, class DataTypes2>
00053 class InteractionEllipsoidForceField : public core::componentmodel::behavior::MixedInteractionForceField<DataTypes1, DataTypes2>, public virtual core::objectmodel::BaseObject
00054 {
00055 public:
00056 typedef core::componentmodel::behavior::MixedInteractionForceField<DataTypes1, DataTypes2> Inherit;
00057 typedef typename DataTypes1::VecCoord VecCoord1;
00058 typedef typename DataTypes1::VecDeriv VecDeriv1;
00059 typedef typename DataTypes1::Coord Coord1;
00060 typedef typename DataTypes1::Deriv Deriv1;
00061 typedef typename Coord1::value_type Real1;
00062 typedef typename DataTypes2::VecCoord VecCoord2;
00063 typedef typename DataTypes2::VecDeriv VecDeriv2;
00064 typedef typename DataTypes2::Coord Coord2;
00065 typedef typename DataTypes2::Deriv Deriv2;
00066 typedef typename Coord2::value_type Real2;
00067
00068 enum { N=Coord1::static_size };
00069 typedef defaulttype::Mat<N,N,Real1> Mat;
00070 protected:
00071 class Contact
00072 {
00073 public:
00074 int index;
00075 Deriv1 pos;
00076 Vec<3,SReal> bras_levier;
00077 Mat m;
00078 Contact( int index=0, const Mat& m=Mat())
00079 : index(index), m(m)
00080 {
00081 }
00082
00083 inline friend std::istream& operator >> ( std::istream& in, Contact& c ){
00084 in>>c.index>>c.m;
00085 return in;
00086 }
00087
00088 inline friend std::ostream& operator << ( std::ostream& out, const Contact& c ){
00089 out << c.index << " " << c.m ;
00090 return out;
00091 }
00092
00093 };
00094
00095 Data<sofa::helper::vector<Contact> > contacts;
00096
00097 InteractionEllipsoidForceFieldInternalData<DataTypes1, DataTypes2> data;
00098
00099 bool calcF(const Coord1& p1, const Deriv1 &v1, Deriv1& f1,Mat& dfdx);
00100 void initCalcF();
00101
00102 public:
00103
00104 Data<Coord1> center;
00105 Data<Coord1> vradius;
00106 Data<Real1> stiffness;
00107 Data<Real1> damping;
00108 Data<defaulttype::Vec3f> color;
00109 Data<bool> bDraw;
00110 Data<int> object2_dof_index;
00111
00112 InteractionEllipsoidForceField()
00113 : contacts(initData(&contacts,"contacts", "Contacts"))
00114 , center(initData(¢er, "center", "ellipsoid center"))
00115 , vradius(initData(&vradius, "vradius", "ellipsoid radius"))
00116 , stiffness(initData(&stiffness, (Real1)500, "stiffness", "force stiffness (positive to repulse outward, negative inward)"))
00117 , damping(initData(&damping, (Real1)5, "damping", "force damping"))
00118 , color(initData(&color, defaulttype::Vec3f(0.0f,0.5f,1.0f), "color", "ellipsoid color"))
00119 , bDraw(initData(&bDraw, true, "draw", "enable/disable drawing of the ellipsoid"))
00120 , object2_dof_index(initData(&object2_dof_index, (int)0, "object2_dof_index", "Dof index of object 2 where the forcefield is attached"))
00121 {
00122 _update_pos_relative = true;
00123 vars.center =center.getValue();
00124
00125 _orientation.clear();
00126 }
00127
00128 void setStiffness(Real1 stiff)
00129 {
00130 stiffness.setValue( stiff );
00131 }
00132
00133 void setDamping(Real1 damp)
00134 {
00135 damping.setValue( damp );
00136 }
00137
00138 virtual void addForce(VecDeriv1& f1, VecDeriv2& f2, const VecCoord1& p1, const VecCoord2& p2, const VecDeriv1& v1, const VecDeriv2& v2);
00139
00140 virtual void addForce2(VecDeriv1& f1, VecDeriv2& f2, const VecCoord1& p1, const VecCoord2& p2, const VecDeriv1& v1, const VecDeriv2& v2);
00141
00142 virtual void addDForce(VecDeriv1& df1, VecDeriv2& df2, const VecDeriv1& dx1, const VecDeriv2& dx2);
00143
00144 virtual double getPotentialEnergy(const VecCoord1& x1, const VecCoord2& x2);
00145
00146 void reinit() {_update_pos_relative = true;}
00147
00148 void draw();
00149
00150 protected:
00151 struct TempVars {
00152 Coord1 center;
00153 Coord1 r;
00154 Real1 stiffness;
00155 Real1 stiffabs;
00156 Coord1 inv_r2;
00157 Coord2 pos6D;
00158 } vars;
00159
00160 bool _update_pos_relative;
00161 VecCoord1 X1;
00162 VecCoord2 X2;
00163 Quat _orientation;
00164 };
00165
00166 }
00167
00168 }
00169
00170 }
00171
00172
00173 #endif