Dragger 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. //osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
  14. #ifndef OSGMANIPULATOR_DRAGGER
  15. #define OSGMANIPULATOR_DRAGGER 1
  16. #include <osgManipulator/Constraint>
  17. #include <osgManipulator/Command>
  18. #include <osg/BoundingSphere>
  19. #include <osg/MatrixTransform>
  20. #include <osgUtil/SceneView>
  21. #include <osgGA/GUIEventAdapter>
  22. #include <osgGA/GUIActionAdapter>
  23. namespace osgManipulator
  24. {
  25. class CompositeDragger;
  26. class MotionCommand;
  27. class TranslateInLineCommand;
  28. class TranslateInPlaneCommand;
  29. class Scale1DCommand;
  30. class Scale2DCommand;
  31. class ScaleUniformCommand;
  32. class Rotate3DCommand;
  33. /** Computes the nodepath from the given node all the way up to the root. */
  34. extern OSGMANIPULATOR_EXPORT void computeNodePathToRoot(osg::Node& node, osg::NodePath& np);
  35. class OSGMANIPULATOR_EXPORT DraggerTransformCallback : public DraggerCallback
  36. {
  37. public:
  38. enum HandleCommandMask
  39. {
  40. HANDLE_TRANSLATE_IN_LINE = 1<<0,
  41. HANDLE_TRANSLATE_IN_PLANE = 1<<1,
  42. HANDLE_SCALED_1D = 1<<2,
  43. HANDLE_SCALED_2D = 1<<3,
  44. HANDLE_SCALED_UNIFORM = 1<<4,
  45. HANDLE_ROTATE_3D = 1<<5,
  46. HANDLE_ALL = 0x8ffffff
  47. };
  48. DraggerTransformCallback(osg::MatrixTransform* transform, int handleCommandMask = HANDLE_ALL);
  49. virtual bool receive(const MotionCommand&);
  50. virtual bool receive(const TranslateInLineCommand& command);
  51. virtual bool receive(const TranslateInPlaneCommand& command);
  52. virtual bool receive(const Scale1DCommand& command);
  53. virtual bool receive(const Scale2DCommand& command);
  54. virtual bool receive(const ScaleUniformCommand& command);
  55. virtual bool receive(const Rotate3DCommand& command);
  56. osg::MatrixTransform* getTransform() { return _transform.get(); }
  57. const osg::MatrixTransform* getTransform() const { return _transform.get(); }
  58. protected:
  59. unsigned int _handleCommandMask;
  60. osg::observer_ptr<osg::MatrixTransform> _transform;
  61. osg::Matrix _startMotionMatrix;
  62. osg::Matrix _localToWorld;
  63. osg::Matrix _worldToLocal;
  64. };
  65. class OSGMANIPULATOR_EXPORT PointerInfo
  66. {
  67. public:
  68. PointerInfo();
  69. PointerInfo(const PointerInfo& rhs):
  70. _hitList(rhs._hitList),
  71. _nearPoint(rhs._nearPoint),
  72. _farPoint(rhs._farPoint),
  73. _eyeDir(rhs._eyeDir)
  74. {
  75. _hitIter = _hitList.begin();
  76. }
  77. void reset()
  78. {
  79. _hitList.clear();
  80. _hitIter = _hitList.begin();
  81. setCamera(0);
  82. }
  83. bool completed() const { return _hitIter==_hitList.end(); }
  84. void next()
  85. {
  86. if (!completed()) ++_hitIter;
  87. }
  88. typedef std::pair<osg::NodePath, osg::Vec3d> NodePathIntersectionPair;
  89. typedef std::list< NodePathIntersectionPair> IntersectionList;
  90. osg::Vec3d getLocalIntersectPoint() const { return _hitIter->second; }
  91. void setNearFarPoints (osg::Vec3d nearPoint, osg::Vec3d farPoint) {
  92. _nearPoint = nearPoint;
  93. _farPoint=farPoint;
  94. _eyeDir = farPoint - nearPoint;
  95. }
  96. const osg::Vec3d& getEyeDir() const {return _eyeDir;}
  97. void getNearFarPoints( osg::Vec3d& nearPoint, osg::Vec3d& farPoint) const {
  98. nearPoint = _nearPoint;
  99. farPoint = _farPoint;
  100. }
  101. bool contains(const osg::Node* node) const;
  102. void setCamera(osg::Camera* camera)
  103. {
  104. if (camera)
  105. {
  106. _MVPW = camera->getViewMatrix() * camera->getProjectionMatrix();
  107. if (camera->getViewport()) _MVPW.postMult(camera->getViewport()->computeWindowMatrix());
  108. _inverseMVPW.invert(_MVPW);
  109. osg::Vec3d eye, center, up;
  110. camera->getViewMatrix().getLookAt(eye, center, up);
  111. _eyeDir = eye - center;
  112. }
  113. else
  114. {
  115. _MVPW.makeIdentity();
  116. _inverseMVPW.makeIdentity();
  117. _eyeDir = osg::Vec3d(0,0,1);
  118. }
  119. }
  120. void addIntersection(const osg::NodePath& nodePath, const osg::Vec3d& intersectionPoint)
  121. {
  122. bool needToResetHitIter = _hitList.empty();
  123. _hitList.push_back(NodePathIntersectionPair(nodePath, intersectionPoint));
  124. if (needToResetHitIter) _hitIter = _hitList.begin();
  125. }
  126. void setMousePosition(float pixel_x, float pixel_y)
  127. {
  128. projectWindowXYIntoObject(osg::Vec2d(pixel_x, pixel_y), _nearPoint, _farPoint);
  129. }
  130. protected:
  131. bool projectWindowXYIntoObject(const osg::Vec2d& windowCoord, osg::Vec3d& nearPoint, osg::Vec3d& farPoint) const;
  132. public:
  133. IntersectionList _hitList;
  134. IntersectionList::const_iterator _hitIter;
  135. protected:
  136. osg::Vec3d _nearPoint,_farPoint;
  137. osg::Vec3d _eyeDir;
  138. osg::Matrix _MVPW;
  139. osg::Matrix _inverseMVPW;
  140. };
  141. /**
  142. * Base class for draggers. Concrete draggers implement the pick event handler
  143. * and generate motion commands (translate, rotate, ...) and sends these
  144. * command to all the DraggerCallbacks & Transforms that are connected to the Dragger that generates the
  145. * commands.
  146. */
  147. class OSGMANIPULATOR_EXPORT Dragger : public osg::MatrixTransform
  148. {
  149. public:
  150. META_Node(osgManipulator,Dragger);
  151. /**
  152. * Set/Get parent dragger. For simple draggers parent points to itself.
  153. * For composite draggers parent points to the parent dragger that uses
  154. * this dragger.
  155. */
  156. virtual void setParentDragger(Dragger* parent) { _parentDragger = parent; }
  157. Dragger* getParentDragger() { return _parentDragger; }
  158. const Dragger* getParentDragger() const { return _parentDragger; }
  159. /** Returns 0 if this Dragger is not a CompositeDragger. */
  160. virtual const CompositeDragger* getComposite() const { return 0; }
  161. /** Returns 0 if this Dragger is not a CompositeDragger. */
  162. virtual CompositeDragger* getComposite() { return 0; }
  163. void setHandleEvents(bool flag);
  164. bool getHandleEvents() const { return _handleEvents; }
  165. void setActivationModKeyMask(unsigned int mask) { _activationModKeyMask = mask; }
  166. unsigned int getActivationModKeyMask() const { return _activationModKeyMask; }
  167. void setActivationMouseButtonMask(unsigned int mask) { _activationMouseButtonMask = mask; }
  168. unsigned int getActivationMouseButtonMask() const { return _activationMouseButtonMask; }
  169. void setActivationKeyEvent(int key) { _activationKeyEvent = key; }
  170. int getActivationKeyEvent() const { return _activationKeyEvent; }
  171. virtual void traverse(osg::NodeVisitor& nv);
  172. virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
  173. virtual bool handle(const PointerInfo&, const osgGA::GUIEventAdapter&, osgGA::GUIActionAdapter&) { return false; }
  174. typedef std::vector< osg::ref_ptr<Constraint> > Constraints;
  175. void addConstraint(Constraint* constraint);
  176. template<class T> void addConstraint(const osg::ref_ptr<T>& c) { addConstraint(c.get()); }
  177. void removeConstraint(Constraint* constraint);
  178. template<class T> void removeConstraint(const osg::ref_ptr<T>& c) { removeConstraint(c.get()); }
  179. Constraints& getConstraints() { return _constraints; }
  180. const Constraints& getConstraints() const { return _constraints; }
  181. typedef std::vector< osg::ref_ptr<DraggerCallback> > DraggerCallbacks;
  182. void addDraggerCallback(DraggerCallback* dc);
  183. template<class T> void addDraggerCallback(const osg::ref_ptr<T>& dc) { addDraggerCallback(dc.get()); }
  184. void removeDraggerCallback(DraggerCallback* dc);
  185. template<class T> void removeDraggerCallback(const osg::ref_ptr<T>& dc) { removeDraggerCallback(dc.get()); }
  186. DraggerCallbacks& getDraggerCallbacks() { return _draggerCallbacks; }
  187. const DraggerCallbacks& getDraggerCallbacks() const { return _draggerCallbacks; }
  188. void addTransformUpdating(MatrixTransform* transform, int handleCommandMask = DraggerTransformCallback::HANDLE_ALL);
  189. void removeTransformUpdating(MatrixTransform* transform);
  190. /** Setup default geometry for dragger. */
  191. virtual void setupDefaultGeometry() {}
  192. virtual bool receive(const MotionCommand& command);
  193. virtual void dispatch(MotionCommand& command);
  194. void setDraggerActive(bool active) { _draggerActive = active; }
  195. bool getDraggerActive() const { return _draggerActive; }
  196. /**
  197. * Set/Get the traversal mask used by this dragger when looking for intersections during event handling.
  198. * This is useful to "hide" some geometry during event handling.
  199. */
  200. virtual void setIntersectionMask(osg::Node::NodeMask intersectionMask) { _intersectionMask = intersectionMask; }
  201. osg::Node::NodeMask getIntersectionMask() const { return _intersectionMask; }
  202. /** Return true if the axis of the Locator are inverted requiring the faces of any cubes used from rendering to be flipped to ensure the correct front/back face is used.*/
  203. bool inverted() const;
  204. /** apply the appropriate FrontFace setting to provided StateSet to ensure that the rendering of hull of the volume is the correct orientation.*/
  205. void applyAppropriateFrontFace(osg::StateSet* ss) const;
  206. protected:
  207. Dragger();
  208. Dragger(const Dragger& rhs, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
  209. virtual ~Dragger();
  210. bool _handleEvents;
  211. bool _draggerActive;
  212. unsigned int _activationModKeyMask;
  213. unsigned int _activationMouseButtonMask;
  214. int _activationKeyEvent;
  215. bool _activationPermittedByModKeyMask;
  216. bool _activationPermittedByMouseButtonMask;
  217. bool _activationPermittedByKeyEvent;
  218. osgManipulator::PointerInfo _pointer;
  219. Dragger* _parentDragger;
  220. osg::ref_ptr<DraggerCallback> _selfUpdater;
  221. Constraints _constraints;
  222. DraggerCallbacks _draggerCallbacks;
  223. osg::Node::NodeMask _intersectionMask;
  224. };
  225. /**
  226. * CompositeDragger allows to create complex draggers that are composed of a
  227. * hierarchy of Draggers.
  228. */
  229. class OSGMANIPULATOR_EXPORT CompositeDragger : public Dragger
  230. {
  231. public:
  232. META_Node(osgManipulator,CompositeDragger);
  233. typedef std::vector< osg::ref_ptr<Dragger> > DraggerList;
  234. virtual const CompositeDragger* getComposite() const { return this; }
  235. virtual CompositeDragger* getComposite() { return this; }
  236. virtual void setParentDragger(Dragger* parent);
  237. virtual bool handle(const PointerInfo& pi, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
  238. // Composite-specific methods below
  239. virtual bool addDragger(Dragger* dragger);
  240. template<class T> bool addDragger(const osg::ref_ptr<T>& dc) { return addDragger(dc.get()); }
  241. virtual bool removeDragger(Dragger* dragger);
  242. template<class T> bool removeDragger(const osg::ref_ptr<T>& dc) { return removeDragger(dc.get()); }
  243. unsigned int getNumDraggers() const { return _draggerList.size(); }
  244. Dragger* getDragger(unsigned int i) { return _draggerList[i].get(); }
  245. const Dragger* getDragger(unsigned int i) const { return _draggerList[i].get(); }
  246. bool containsDragger(const Dragger* dragger) const;
  247. template<class T> bool containsDragger(const osg::ref_ptr<T>& dc) const { return containsDragger(dc.get()); }
  248. DraggerList::iterator findDragger(const Dragger* dragger);
  249. virtual void setIntersectionMask(osg::Node::NodeMask intersectionMask);
  250. protected:
  251. CompositeDragger() {}
  252. CompositeDragger(const CompositeDragger& rhs, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
  253. virtual ~CompositeDragger() {}
  254. DraggerList _draggerList;
  255. };
  256. /**
  257. * Culls the drawable all the time. Used by draggers to have invisible geometry
  258. * around lines and points so that they can be picked. For example, a dragger
  259. * could have a line with an invisible cylinder around it to enable picking on
  260. * that line.
  261. */
  262. void OSGMANIPULATOR_EXPORT setDrawableToAlwaysCull(osg::Drawable& drawable);
  263. /**
  264. * Convenience function for setting the material color on a node.
  265. */
  266. void OSGMANIPULATOR_EXPORT setMaterialColor(const osg::Vec4& color, osg::Node& node);
  267. }
  268. #endif