1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
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.
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.
14#ifndef __SphericalManipulator_h__
15#define __SphericalManipulator_h__
17#include <osgGA/CameraManipulator>
24class OSGGA_EXPORT SphericalManipulator : public CameraManipulator
27 SphericalManipulator();
29 virtual const char* className() const { return "Spherical Manipulator"; }
31 /** set the position of the matrix manipulator using a 4x4 Matrix.*/
32 virtual void setByMatrix(const osg::Matrixd& matrix);
34 /** set the position of the matrix manipulator using a 4x4 Matrix.*/
35 virtual void setByInverseMatrix(const osg::Matrixd& matrix) { setByMatrix(osg::Matrixd::inverse(matrix)); }
37 /** get the position of the manipulator as 4x4 Matrix.*/
38 virtual osg::Matrixd getMatrix() const;
40 /** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
41 virtual osg::Matrixd getInverseMatrix() const;
43 /** Get the FusionDistanceMode. Used by SceneView for setting up stereo convergence.*/
44 virtual osgUtil::SceneView::FusionDistanceMode getFusionDistanceMode() const { return osgUtil::SceneView::USE_FUSION_DISTANCE_VALUE; }
46 /** Get the FusionDistanceValue. Used by SceneView for setting up stereo convergence.*/
47 virtual float getFusionDistanceValue() const { return _distance; }
49 /** Attach a node to the manipulator.
50 Automatically detaches previously attached node.
51 setNode(NULL) detaches previously nodes.
52 Is ignored by manipulators which do not require a reference model.*/
53 virtual void setNode(osg::Node*);
55 /** Return node if attached.*/
56 virtual const osg::Node* getNode() const;
58 /** Return node if attached.*/
59 virtual osg::Node* getNode();
61 /** Move the camera to the default position.
62 May be ignored by manipulators if home functionality is not appropriate.*/
63 virtual void home(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
64 virtual void home(double);
66 /** Start/restart the manipulator.*/
67 virtual void init(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
69 void zoomOn(const osg::BoundingSphere& bound);
71 /** handle events, return true if handled, false otherwise.*/
72 virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
74 /** Compute the home position.*/
75 virtual void computeHomePosition();
77 void computeViewPosition(const osg::BoundingSphere& bound,double& scale,double& distance,osg::Vec3d& center);
79 void setCenter(const osg::Vec3d& center) {_center=center;}
80 const osg::Vec3d& getCenter() const {return _center;}
82 bool setDistance(double distance);
83 double getDistance() const { return _distance; }
85 double getHomeDistance() const { return _homeDistance; }
87 void setHeading(double azimuth) { _heading = azimuth; }
88 double getHeading() const {return _heading;}
90 void setElevation(double elevation) { _elevation = elevation; }
91 double getElevtion() const {return _elevation;}
94 /** get the minimum distance (as ratio) the eye point can be zoomed in */
95 double getMinimumZoomScale() const { return _minimumZoomScale; }
97 /** set the minimum distance (as ratio) the eye point can be zoomed in towards the
98 center before the center is pushed forward.*/
99 void setMinimumZoomScale(double minimumZoomScale) {_minimumZoomScale=minimumZoomScale;}
102 /** set the mouse scroll wheel zoom delta.
103 * Range -1.0 to +1.0, -ve value inverts wheel direction and zero switches off scroll wheel. */
104 void setScroolWheelZoomDelta(double zoomDelta) { _zoomDelta = zoomDelta; }
106 /** get the mouse scroll wheel zoom delta. */
107 double getScroolWheelZoomDelta() const { return _zoomDelta; }
110 /** Get the keyboard and mouse usage of this manipulator.*/
111 virtual void getUsage(osg::ApplicationUsage& usage) const;
121 RotationMode getRotationMode() const {return _rotationMode;}
122 void setRotationMode(RotationMode mode);
124 /** Returns true if the camera can be thrown, false otherwise. This defaults to true. */
125 bool getAllowThrow() const { return _allowThrow; }
126 /** Set the 'allow throw' flag. Releasing the mouse button while moving the camera results in a throw. */
127 void setAllowThrow(bool allowThrow) { _allowThrow = allowThrow; }
131 virtual ~SphericalManipulator();
133 /** Reset the internal GUIEvent stack.*/
134 void flushMouseEventStack();
135 /** Add the current mouse GUIEvent to internal stack.*/
136 void addMouseEvent(const osgGA::GUIEventAdapter& ea);
138 /** For the give mouse movement calculate the movement of the camera.
139 Return true is camera has moved and a redraw is required.*/
142 /** Check the speed at which the mouse is moving.
143 If speed is below a threshold then return false, otherwise return true.*/
144 bool isMouseMoving();
146 // Internal event stack comprising last two mouse events.
147 osg::ref_ptr<const osgGA::GUIEventAdapter> _ga_t1;
148 osg::ref_ptr<const osgGA::GUIEventAdapter> _ga_t0;
150 osg::observer_ptr<osg::Node> _node;
153 double _minimumZoomScale;
158 /** The approximate amount of time it is currently taking to draw a frame.
159 * This is used to compute the delta in translation/rotation during a thrown display update.
160 * It allows us to match an delta in position/rotation independent of the rendering frame rate.
162 double _delta_frame_time;
164 /** The time the last frame started.
165 * Used when _rate_sensitive is true so that we can match display update rate to rotation/translation rate.
167 double _last_frame_time;
169 RotationMode _rotationMode;
172 double _heading; // angle from x axis in xy plane
173 double _elevation; // angle from xy plane, positive upwards towards the z axis
174 double _homeDistance;