RayPickInteractor.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_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)" ) ) //", 2 = Middle" has been removed as, in the current state, middle is hard coded for cutting
00061 , mechanicalObject(NULL)
00062 {
00063 }
00064 
00065 template<class DataTypes, class ContactForceField>
00066 void DefaultPickingManager<DataTypes,ContactForceField>::release()
00067 {
00068     // release the attached body
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         // Hack to make forcefields visible
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             //mechanicalObject->setContext(context);
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     //sofa::helper::printFactoryLog();
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     // Create mapping for second point
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 /*length*/, 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& /*p1*/, const Vector3& /*p2*/);
00199 
00200 } // namespace collision
00201 
00202 } // namespace component
00203 
00204 } // namespace sofa
00205 
00206 #endif

Generated on Sun Nov 23 02:35:10 2008 for Sofa by  doxygen 1.5.7.1