RayPickInteractor.h

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_H
00026 #define SOFA_COMPONENT_COLLISION_RAYPICKINTERACTOR_H
00027 
00028 #include <sofa/component/collision/RayModel.h>
00029 #include <sofa/core/BehaviorModel.h>
00030 
00031 #include <sofa/component/MechanicalObject.h>
00032 #include <sofa/simulation/tree/GNode.h>
00033 #include <sofa/component/collision/BarycentricContactMapper.h>
00034 
00035 
00036 #include <sofa/defaulttype/Vec.h>
00037 #include <sofa/defaulttype/Mat.h>
00038 #include <sofa/defaulttype/Quat.h>
00039 #include <sofa/core/componentmodel/collision/DetectionOutput.h>
00040 
00041 #include <sofa/component/collision/TopologicalChangeManager.h>
00042 
00043 #include <sofa/helper/Factory.h>
00044 
00045 namespace sofa
00046 {
00047 namespace component
00048 {
00049 namespace collision
00050 {
00051 using namespace sofa::defaulttype;
00052 
00053 class BasePickingManager : public virtual sofa::core::objectmodel::BaseObject
00054 {
00055 public:
00056     virtual ~BasePickingManager();
00057     virtual bool attach(int button, core::CollisionElementIterator elem1, core::CollisionElementIterator elem2, double dist, Vector3 p1, Vector3 p2) = 0;
00058     virtual bool isAttached() = 0;
00059     virtual void release() = 0;
00060     virtual void update() = 0;
00061 
00062     typedef helper::Factory<std::string, BasePickingManager, core::objectmodel::BaseContext*> PickingManagerFactory;
00063 
00064     static BasePickingManager* Create(std::string name, core::objectmodel::BaseContext* context);
00065     static int CreateAll(std::vector<BasePickingManager*>& instances, core::objectmodel::BaseContext* context);
00066 
00067     template <class RealObject>
00068     static bool canCreate( RealObject*& /*obj*/, core::objectmodel::BaseContext* /*context*/)
00069     {
00070     return true;
00071     }
00072 
00073     template <class RealObject>
00074     static void create( RealObject*& obj, core::objectmodel::BaseContext* context)
00075     {
00076     if (RealObject::canCreate(obj, context))
00077     {
00078         obj = new RealObject;
00079         //if (context != NULL)
00080         //    context->addObject(obj);
00081     }
00082     }
00083 };
00084 
00085 class RayPickInteractor : public RayModel, public core::BehaviorModel
00086 {
00087 public:
00088     RayPickInteractor();
00089     ~RayPickInteractor();
00090     
00091     virtual void init();
00092     
00093     virtual bool isActive();
00094     
00096     virtual void updatePosition(double dt);
00097     
00099     virtual void newPosition(const Vector3& translation, const Quat& rotation, const Mat4x4d& transformation);
00100     virtual void newEvent(const std::string& command);
00101     
00102     virtual void draw();
00103 
00104     virtual bool isAttached();
00105 
00106 
00107 protected:
00108     void pickBody();
00109     void releaseBody();
00110 
00111     core::componentmodel::collision::DetectionOutput* findFirstCollision(const Ray& ray, double* dist);
00112 
00113     // TODO: remove the FIRST_INPUT, SECOND_INPUT, IS_CUT states
00114     enum { DISABLED, PRESENT, ACTIVE, ATTACHED, FIRST_INPUT, SECOND_INPUT, IS_CUT } state; // FIRST_INPUT and SECOND_INPUT are states to control inputs points for incision in a triangular mesh
00115     int button; // index of activated button (only valid in ACTIVE state)
00116     Mat4x4d transform;
00117 
00118     helper::vector<BasePickingManager*> pickManagers;
00119 
00120     // TopologicalChangeManager object to handle topological changes
00121     TopologicalChangeManager topo_changeManager;
00122 
00123 };
00124 
00125 
00126 template<class TDataTypes, class ContactForceField>
00127 class DefaultPickingManager : public BasePickingManager
00128 {
00129 public:
00130     typedef TDataTypes DataTypes;
00131     typedef typename DataTypes::Real Real;
00132     typedef typename DataTypes::Coord Coord;
00133 
00134     Data<int> button;
00135 
00136     DefaultPickingManager();
00137 
00138     virtual bool attach(int button, core::CollisionElementIterator elem1, core::CollisionElementIterator elem2, double dist, Vector3 p1, Vector3 p2)
00139     {
00140         if (button == this->button.getValue())
00141             return attach(elem1, elem2, dist, p1, p2);
00142     return false;
00143     }
00144     virtual bool isAttached()
00145     {
00146         return !attachedPoints.empty();
00147     }
00148     virtual void release();
00149     virtual void update();
00150     virtual void draw();
00151 
00152     template <class RealObject>
00153     static bool canCreate( RealObject*& obj, core::objectmodel::BaseContext* context)
00154     {
00155     if (context != NULL)
00156     {
00157         core::componentmodel::behavior::MechanicalState<DataTypes>* p = NULL;
00158         context->get(p, core::objectmodel::BaseContext::SearchRoot);
00159         if (p == NULL)
00160         return false;
00161     }
00162     return BasePickingManager::canCreate(obj, context);
00163     }
00164 
00165 protected:
00166 
00167     virtual component::MechanicalObject<DataTypes>* getMState(core::objectmodel::BaseContext* context);
00168 
00169     virtual bool attach(core::CollisionElementIterator elem1, core::CollisionElementIterator elem2, double dist, Vector3 p1, Vector3 p2);
00170 
00171     virtual void addContact(ContactForceField* ff, int index1, int index2, double stiffness, double mu_v, double length, const Vector3& p1, const Vector3& p2);
00172 
00173     sofa::helper::vector< std::pair<Ray,double> > attachedPoints;
00174     component::MechanicalObject<DataTypes>* mechanicalObject;
00175     sofa::helper::vector<core::componentmodel::behavior::BaseForceField*> forcefields;
00176     sofa::helper::vector<BaseContactMapper<DataTypes>*> mappers;
00177 };
00178 
00179 } // namespace collision
00180 
00181 } // namespace component
00182 
00183 } // namespace sofa
00184 
00185 #endif

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