openscenegraph
SphericalManipulator
Go to the documentation of this file.
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
14#ifndef __SphericalManipulator_h__
15#define __SphericalManipulator_h__
16
17#include <osgGA/CameraManipulator>
18#include <osg/Math>
19#include <osg/Quat>
20
21namespace osgGA
22{
23
24class OSGGA_EXPORT SphericalManipulator : public CameraManipulator
25{
26 public:
27 SphericalManipulator();
28
29 virtual const char* className() const { return "Spherical Manipulator"; }
30
31 /** set the position of the matrix manipulator using a 4x4 Matrix.*/
32 virtual void setByMatrix(const osg::Matrixd& matrix);
33
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)); }
36
37 /** get the position of the manipulator as 4x4 Matrix.*/
38 virtual osg::Matrixd getMatrix() const;
39
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;
42
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; }
45
46 /** Get the FusionDistanceValue. Used by SceneView for setting up stereo convergence.*/
47 virtual float getFusionDistanceValue() const { return _distance; }
48
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*);
54
55 /** Return node if attached.*/
56 virtual const osg::Node* getNode() const;
57
58 /** Return node if attached.*/
59 virtual osg::Node* getNode();
60
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);
65
66 /** Start/restart the manipulator.*/
67 virtual void init(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
68
69 void zoomOn(const osg::BoundingSphere& bound);
70
71 /** handle events, return true if handled, false otherwise.*/
72 virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
73
74 /** Compute the home position.*/
75 virtual void computeHomePosition();
76
77 void computeViewPosition(const osg::BoundingSphere& bound,double& scale,double& distance,osg::Vec3d& center);
78
79 void setCenter(const osg::Vec3d& center) {_center=center;}
80 const osg::Vec3d& getCenter() const {return _center;}
81
82 bool setDistance(double distance);
83 double getDistance() const { return _distance; }
84
85 double getHomeDistance() const { return _homeDistance; }
86
87 void setHeading(double azimuth) { _heading = azimuth; }
88 double getHeading() const {return _heading;}
89
90 void setElevation(double elevation) { _elevation = elevation; }
91 double getElevtion() const {return _elevation;}
92
93
94 /** get the minimum distance (as ratio) the eye point can be zoomed in */
95 double getMinimumZoomScale() const { return _minimumZoomScale; }
96
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;}
100
101
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; }
105
106 /** get the mouse scroll wheel zoom delta. */
107 double getScroolWheelZoomDelta() const { return _zoomDelta; }
108
109
110 /** Get the keyboard and mouse usage of this manipulator.*/
111 virtual void getUsage(osg::ApplicationUsage& usage) const;
112
113 enum RotationMode
114 {
115 ELEVATION_HEADING=0,
116 HEADING,
117 ELEVATION,
118 MAP
119 };
120
121 RotationMode getRotationMode() const {return _rotationMode;}
122 void setRotationMode(RotationMode mode);
123
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; }
128
129 protected:
130
131 virtual ~SphericalManipulator();
132
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);
137
138 /** For the give mouse movement calculate the movement of the camera.
139 Return true is camera has moved and a redraw is required.*/
140 bool calcMovement();
141
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();
145
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;
149
150 osg::observer_ptr<osg::Node> _node;
151
152 double _modelScale;
153 double _minimumZoomScale;
154
155 bool _thrown;
156 bool _allowThrow;
157
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.
161 */
162 double _delta_frame_time;
163
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.
166 */
167 double _last_frame_time;
168
169 RotationMode _rotationMode;
170 osg::Vec3d _center;
171 double _distance;
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;
175 double _zoomDelta;
176};
177}
178#endif