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_COLLISION_RAYPICKINTERACTOR_INL
00026 #define SOFA_COMPONENT_COLLISION_RAYPICKINTERACTOR_INL
00027
00028 #include <sofa/component/collision/RayPickInteractor.h>
00029 #include <sofa/component/collision/RayContact.h>
00030 #include <sofa/component/collision/SphereModel.h>
00031 #include <sofa/component/collision/TriangleModel.h>
00032 #include <sofa/component/collision/TetrahedronModel.h>
00033 #include <sofa/component/collision/SphereTreeModel.h>
00034 #include <sofa/component/collision/DistanceGridCollisionModel.h>
00035 #include <sofa/component/mapping/BarycentricMapping.h>
00036 #include <sofa/component/mapping/RigidMapping.h>
00037 #include <sofa/component/mapping/SkinningMapping.h>
00038 #include <sofa/component/forcefield/StiffSpringForceField.h>
00039 #include <sofa/component/forcefield/VectorSpringForceField.h>
00040 #include <sofa/component/MechanicalObject.h>
00041 #include <sofa/core/componentmodel/behavior/MechanicalState.h>
00042
00043 #include <sofa/helper/system/gl.h>
00044
00045 namespace sofa
00046 {
00047
00048 namespace component
00049 {
00050
00051 namespace collision
00052 {
00053
00054 typedef mapping::SkinningMapping<core::componentmodel::behavior::MechanicalMapping<core::componentmodel::behavior::MechanicalState<defaulttype::Rigid3Types>, core::componentmodel::behavior::MechanicalState<defaulttype::Vec3Types> > > MySkinningMapping;
00055
00056 using namespace sofa::defaulttype;
00057
00058 template<class DataTypes, class ContactForceField>
00059 DefaultPickingManager<DataTypes,ContactForceField>::DefaultPickingManager()
00060 : button( initData( &button, 0, "button", "mouse button which this manager responds to (0 = Left, 1 = Right)" ) )
00061 , mechanicalObject(NULL)
00062 {
00063 }
00064
00065 template<class DataTypes, class ContactForceField>
00066 void DefaultPickingManager<DataTypes,ContactForceField>::release()
00067 {
00068
00069 for (unsigned int i=0; i<forcefields.size(); i++)
00070 {
00071 std::cout << "DefaultPickingManager: Deleting "<<forcefields[i]->getClassName()<<" "<<forcefields[i]->getName()<<std::endl;
00072 forcefields[i]->cleanup();
00073 forcefields[i]->getContext()->removeObject(forcefields[i]);
00074 delete forcefields[i];
00075 }
00076 forcefields.clear();
00077 for (unsigned int i=0;i<mappers.size();i++)
00078 {
00079 mappers[i]->cleanup();
00080 delete mappers[i];
00081 }
00082 mappers.clear();
00083 attachedPoints.clear();
00084 }
00085
00086 template<class DataTypes, class ContactForceField>
00087 void DefaultPickingManager<DataTypes,ContactForceField>::update()
00088 {
00089 if (mechanicalObject!=NULL && !attachedPoints.empty())
00090 {
00091 typename DataTypes::VecCoord& x = *mechanicalObject->getX();
00092 for (unsigned int i=0;i<attachedPoints.size();i++)
00093 {
00094 Ray& ray = attachedPoints[i].first;
00095 x[i] = ray.origin()+ray.direction()*attachedPoints[i].second;
00096 }
00097 }
00098 }
00099
00100 template<class DataTypes, class ContactForceField>
00101 void DefaultPickingManager<DataTypes,ContactForceField>::draw()
00102 {
00103 if (!forcefields.empty())
00104 {
00105 glColor4f(1,1,1,1);
00106 glLineWidth(3);
00107 for (unsigned int i=0;i<forcefields.size();i++)
00108 {
00109 if (forcefields[i] != NULL && forcefields[i]->getContext() != NULL)
00110 {
00111
00112 bool b = forcefields[i]->getContext()->getShowInteractionForceFields();
00113 forcefields[i]->getContext()->setShowInteractionForceFields(true);
00114 forcefields[i]->draw();
00115 forcefields[i]->getContext()->setShowInteractionForceFields(b);
00116 }
00117 }
00118 glLineWidth(1);
00119 }
00120 }
00121
00122 template<class DataTypes, class ContactForceField>
00123 component::MechanicalObject<DataTypes>* DefaultPickingManager<DataTypes,ContactForceField>::getMState(core::objectmodel::BaseContext* context)
00124 {
00125 if (mechanicalObject == NULL)
00126 {
00127 mechanicalObject = new component::MechanicalObject<DataTypes>();
00128 simulation::tree::GNode* parent = dynamic_cast<simulation::tree::GNode*>(context);
00129 if (parent != NULL)
00130 {
00131 std::string name = "contactMouse";
00132 name += DataTypes::Name();
00133 simulation::tree::GNode* child = new simulation::tree::GNode(name);
00134 parent->addChild(child);
00135 child->updateContext();
00136 child->addObject(mechanicalObject);
00137 }
00138 else
00139 {
00140 context->addObject(mechanicalObject);
00141
00142 }
00143 mechanicalObject->init();
00144 }
00145 return mechanicalObject;
00146 }
00147
00148 template<class DataTypes, class ContactForceField>
00149 bool DefaultPickingManager<DataTypes,ContactForceField>::attach(core::CollisionElementIterator elem1, core::CollisionElementIterator elem2, double dist, Vector3 p1, Vector3 p2)
00150 {
00151 core::CollisionModel* model1 = elem1.getCollisionModel();
00152 core::CollisionModel* model2 = elem2.getCollisionModel();
00153 RayModel* rayModel = dynamic_cast<RayModel*>(model1);
00154 if (rayModel == NULL) return false;
00155 BaseContactMapper<DataTypes>* mapper2 = BaseContactMapper<DataTypes>::Create(model2);
00156 if (mapper2 == NULL)
00157 {
00158 std::cerr << "DefaultPickingManager: ContactMapper from "<<model2->getClassName()<<"<"<<model2->getTemplateName()<<"> to "<<DataTypes::Name()<<" not found."<<std::endl;
00159
00160 return false;
00161 }
00162 component::MechanicalObject<DataTypes>* mstate1 = getMState(rayModel->getContext());
00163 std::string name = "contactMouse";
00164 name += DataTypes::Name();
00165 MechanicalState<DataTypes>* mstate2 = mapper2->createMapping(name.c_str());
00166 ContactForceField* ff = new ContactForceField(mstate1, mstate2);
00167 name = this->getName();
00168 name += "-";
00169 name += model2->getClassName();
00170 ff->setName(name);
00171 ff->clear(1);
00172 mapper2->resize(1);
00173 int index1 = attachedPoints.size();
00174 mstate1->resize(index1+1);
00175 int index2 = elem2.getIndex();
00176 Real r1 = 0.0;
00177 Real r2 = 0.0;
00178
00179 Coord p; p = p2;
00180 index2 = mapper2->addPoint(p, index2, r2);
00181 mapper2->update();
00182 p2 = (*mstate2->getX())[index2];
00183 double stiffness = (elem1.getContactStiffness() * elem2.getContactStiffness());
00184 double mu_v = (elem1.getContactFriction() + elem2.getContactFriction());
00185 addContact(ff, index1, index2, stiffness, mu_v, r1+r2, p1, p2);
00186 mstate2->getContext()->addObject(ff);
00187 ff->init();
00188 forcefields.push_back(ff);
00189 mappers.push_back(mapper2);
00190 attachedPoints.push_back(std::make_pair(Ray(rayModel,elem1.getIndex()), dist));
00191 return true;
00192 }
00193
00194 template<>
00195 void DefaultPickingManager<defaulttype::Vec3Types,forcefield::VectorSpringForceField<defaulttype::Vec3Types> >::addContact(forcefield::VectorSpringForceField<defaulttype::Vec3Types>* ff, int index1, int index2, double stiffness, double mu_v, double , const Vector3& p1, const Vector3& p2);
00196
00197 template<>
00198 void DefaultPickingManager<defaulttype::Vec3Types,forcefield::StiffSpringForceField<defaulttype::Vec3Types> >::addContact(forcefield::StiffSpringForceField<defaulttype::Vec3Types>* ff, int index1, int index2, double stiffness, double mu_v, double length, const Vector3& , const Vector3& );
00199
00200 }
00201
00202 }
00203
00204 }
00205
00206 #endif