1 /*
2  * Stellarium
3  * Copyright (C) 2007 Fabien Chereau
4  * Copyright (C) 2015 Georg Zotti (offset view adaptations, Up vector fix for zenithal views)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
19  */
20 
21 #ifndef STELMOVEMENTMGR_HPP
22 #define STELMOVEMENTMGR_HPP
23 
24 #include "StelModule.hpp"
25 #include "StelProjector.hpp"
26 #include "StelObjectType.hpp"
27 #include <QTimeLine>
28 #include <QTimer>
29 #include <QCursor>
30 #include <QEasingCurve>
31 
32 //! @class Smoother
33 //! Compute smooth animation for a given float value.
34 //! Used to smooth out the fov animations.
35 class Smoother
36 {
37 public:
38 	double getValue() const;
getAim() const39 	double getAim() const { return aim; }
40 	void setTarget(double start, double aim, double duration);
41 	void update(double dt);
42 	bool finished() const;
43 
44 private:
45 	QEasingCurve easingCurve;
46 	double start;
47 	double aim;
48 	double duration;
49 	double progress;
50 };
51 
52 //! @class StelMovementMgr
53 //! Manages the head movements and zoom operations.
54 class StelMovementMgr : public StelModule
55 {
56 	Q_OBJECT
57 	Q_PROPERTY(bool equatorialMount
58 		   READ getEquatorialMount
59 		   WRITE setEquatorialMount
60 		   NOTIFY equatorialMountChanged)
61 	Q_PROPERTY(bool tracking
62 		   READ getFlagTracking
63 		   WRITE setFlagTracking
64 		   NOTIFY flagTrackingChanged)
65 	Q_PROPERTY(bool flagIndicationMountMode
66 		   READ getFlagIndicationMountMode
67 		   WRITE setFlagIndicationMountMode
68 		   NOTIFY flagIndicationMountModeChanged)
69 	//The targets of viewport offset animation
70 	Q_PROPERTY(double viewportHorizontalOffsetTarget
71 		   READ getViewportHorizontalOffsetTarget
72 		   WRITE setViewportHorizontalOffsetTarget
73 		   NOTIFY viewportHorizontalOffsetTargetChanged)
74 	Q_PROPERTY(double viewportVerticalOffsetTarget
75 		   READ getViewportVerticalOffsetTarget
76 		   WRITE setViewportVerticalOffsetTarget
77 		   NOTIFY viewportVerticalOffsetTargetChanged)
78 	Q_PROPERTY(bool flagAutoZoomOutResetsDirection
79 		   READ getFlagAutoZoomOutResetsDirection
80 		   WRITE setFlagAutoZoomOutResetsDirection
81 		   NOTIFY flagAutoZoomOutResetsDirectionChanged)
82 	Q_PROPERTY(bool flagEnableMouseNavigation
83 		   READ getFlagEnableMouseNavigation
84 		   WRITE setFlagEnableMouseNavigation
85 		   NOTIFY flagEnableMouseNavigationChanged)
86 	Q_PROPERTY(bool flagEnableMouseZooming
87 		   READ getFlagEnableMouseZooming
88 		   WRITE setFlagEnableMouseZooming
89 		   NOTIFY flagEnableMouseZoomingChanged)
90 	Q_PROPERTY(bool flagEnableMoveKeys
91 		   READ getFlagEnableMoveKeys
92 		   WRITE setFlagEnableMoveKeys
93 		   NOTIFY flagEnableMoveKeysChanged)
94 	Q_PROPERTY(bool flagEnableZoomKeys
95 		   READ getFlagEnableZoomKeys
96 		   WRITE setFlagEnableZoomKeys
97 		   NOTIFY flagEnableZoomKeysChanged)
98 	Q_PROPERTY(double userMaxFov
99 		   READ getUserMaxFov
100 		   WRITE setUserMaxFov
101 		   NOTIFY userMaxFovChanged)
102 public:
103 	//! Possible mount modes defining the reference frame in which head movements occur.
104 	//! MountGalactic and MountSupergalactic is currently only available via scripting API: core.clear("galactic") and core.clear("supergalactic")
105 	// TODO: add others: MountEcliptical, MountEq2000, MountEcliptical2000 and implement proper variants.
106 	enum MountMode { MountAltAzimuthal, MountEquinoxEquatorial, MountGalactic, MountSupergalactic};
107 	Q_ENUM(MountMode)
108 
109 	//! Named constants for zoom operations.
110 	enum ZoomingMode { ZoomOut=-1, ZoomNone=0, ZoomIn=1};
111 	Q_ENUM(ZoomingMode)
112 
113 	StelMovementMgr(StelCore* core);
114 	virtual ~StelMovementMgr() Q_DECL_OVERRIDE;
115 
116 	///////////////////////////////////////////////////////////////////////////
117 	// Methods defined in the StelModule class
118 	//! Initializes the object based on the application settings
119 	//! Includes:
120 	//! - Enabling/disabling the movement keys
121 	//! - Enabling/disabling the zoom keys
122 	//! - Enabling/disabling the mouse zoom
123 	//! - Enabling/disabling the mouse movement
124 	//! - Sets the zoom and movement speeds
125 	//! - Sets the auto-zoom duration and mode.
126 	virtual void init() Q_DECL_OVERRIDE;
127 
128 	//! Update time-dependent things (triggers a time dragging record if required)
update(double)129 	virtual void update(double) Q_DECL_OVERRIDE
130 	{
131 		if (dragTimeMode)
132 			addTimeDragPoint(QCursor::pos().x(), QCursor::pos().y());
133 	}
134 	//! Implement required draw function.  Does nothing.
draw(StelCore *)135 	virtual void draw(StelCore*) Q_DECL_OVERRIDE {;}
136 	//! Handle keyboard events.
137 	virtual void handleKeys(QKeyEvent* event) Q_DECL_OVERRIDE;
138 	//! Handle mouse movement events.
139 	virtual bool handleMouseMoves(int x, int y, Qt::MouseButtons b) Q_DECL_OVERRIDE;
140 	//! Handle mouse wheel events.
141 	virtual void handleMouseWheel(class QWheelEvent* event) Q_DECL_OVERRIDE;
142 	//! Handle mouse click events.
143 	virtual void handleMouseClicks(class QMouseEvent* event) Q_DECL_OVERRIDE;
144 	// allow some keypress interaction by plugins.
145 	virtual double getCallOrder(StelModuleActionName actionName) const Q_DECL_OVERRIDE;
146 	//! Handle pinch gesture.
147 	virtual bool handlePinch(qreal scale, bool started) Q_DECL_OVERRIDE;
148 
149 	///////////////////////////////////////////////////////////////////////////
150 	// Methods specific to StelMovementMgr
151 
152 	//! Increment/decrement smoothly the vision field and position. Called in StelCore.update().
153 	void updateMotion(double deltaTime);
154 
155 	//! Get the zoom speed
156 	// TODO: what are the units?
getZoomSpeed() const157 	double getZoomSpeed() const {return static_cast<double>(keyZoomSpeed);}
158 
159 	//! Return the current up view vector in J2000 coordinates.
160 	Vec3d getViewUpVectorJ2000() const;
161 	// You can set an upVector in J2000 coordinates which is translated to current mount mode. Important when viewing into the pole of the current mount mode coordinates.
162 	void setViewUpVectorJ2000(const Vec3d& up);
163 	// Set vector directly. This is set in the current mountmode, but will be translated to J2000 internally
164 	// We need this only when viewing to the poles of current coordinate system where the view vector would else be parallel to the up vector.
165 	void setViewUpVector(const Vec3d& up);
166 
setMovementSpeedFactor(float s)167 	void setMovementSpeedFactor(float s) {movementsSpeedFactor=s;}
getMovementSpeedFactor() const168 	float getMovementSpeedFactor() const {return movementsSpeedFactor;}
169 
setDragTriggerDistance(float d)170 	void setDragTriggerDistance(float d) {dragTriggerDistance=d;}
171 
172 	Vec3d j2000ToMountFrame(const Vec3d& v) const;
173 	Vec3d mountFrameToJ2000(const Vec3d& v) const;
174 
175 	void moveToObject(const StelObjectP& target, float moveDuration = 1., ZoomingMode zooming = ZoomNone);
176 
177 public slots:
178 	// UNUSED!
179 	//! Toggle current mount mode between equatorial and altazimuthal
toggleMountMode()180 	void toggleMountMode() {if (getMountMode()==MountAltAzimuthal) setMountMode(MountEquinoxEquatorial); else setMountMode(MountAltAzimuthal);}
181 	//! Define whether we should use equatorial mount or altazimuthal
182 	void setEquatorialMount(bool b);
183 
184 	//! Set object tracking on/off and go to selected object
185 	void setFlagTracking(bool b=true);
186 	//! Get current object tracking status.
getFlagTracking(void) const187 	bool getFlagTracking(void) const {return flagTracking;}
188 
189 	//! Set whether sky position is to be locked.
190 	void setFlagLockEquPos(bool b);
191 	//! Get whether sky position is locked.
getFlagLockEquPos(void) const192 	bool getFlagLockEquPos(void) const {return flagLockEquPos;}
193 
194 	//! Move view in alt/az (or equatorial if in that mode) coordinates.
195 	//! Changes to viewing direction are instantaneous.
196 	//! @param deltaAz change in azimuth angle in radians
197 	//! @param deltaAlt change in altitude angle in radians
198 	void panView(const double deltaAz, const double deltaAlt);
199 
200 	//! Set automove duration in seconds
201 	//! @param f the number of seconds it takes for an auto-move operation to complete.
setAutoMoveDuration(float f)202 	void setAutoMoveDuration(float f) {autoMoveDuration = f;}
203 	//! Get automove duration in seconds
204 	//! @return the number of seconds it takes for an auto-move operation to complete.
getAutoMoveDuration(void) const205 	float getAutoMoveDuration(void) const {return autoMoveDuration;}
206 
207 	//! Set whether auto zoom out will reset the viewing direction to the inital value
setFlagAutoZoomOutResetsDirection(bool b)208 	void setFlagAutoZoomOutResetsDirection(bool b) {if (flagAutoZoomOutResetsDirection != b) { flagAutoZoomOutResetsDirection = b; emit flagAutoZoomOutResetsDirectionChanged(b);}}
209 	//! Get whether auto zoom out will reset the viewing direction to the inital value
getFlagAutoZoomOutResetsDirection(void) const210 	bool getFlagAutoZoomOutResetsDirection(void) const {return flagAutoZoomOutResetsDirection;}
211 
212 	//! Get whether keys can control zoom
getFlagEnableZoomKeys() const213 	bool getFlagEnableZoomKeys() const {return flagEnableZoomKeys;}
214 	//! Set whether keys can control zoom
setFlagEnableZoomKeys(bool b)215 	void setFlagEnableZoomKeys(bool b) {flagEnableZoomKeys=b; emit flagEnableZoomKeysChanged(b);}
216 
217 	//! Get whether keys can control movement
getFlagEnableMoveKeys() const218 	bool getFlagEnableMoveKeys() const {return flagEnableMoveKeys;}
219 	//! Set whether keys can control movement
setFlagEnableMoveKeys(bool b)220 	void setFlagEnableMoveKeys(bool b) {flagEnableMoveKeys=b; emit flagEnableMoveKeysChanged(b); }
221 
222 	//! Get whether being at the edge of the screen activates movement
getFlagEnableMoveAtScreenEdge() const223 	bool getFlagEnableMoveAtScreenEdge() const {return flagEnableMoveAtScreenEdge;}
224 	//! Set whether being at the edge of the screen activates movement
setFlagEnableMoveAtScreenEdge(bool b)225 	void setFlagEnableMoveAtScreenEdge(bool b) {flagEnableMoveAtScreenEdge=b;}
226 
227 	//! Get whether mouse can control movement
getFlagEnableMouseNavigation() const228 	bool getFlagEnableMouseNavigation() const {return flagEnableMouseNavigation;}
229 	//! Set whether mouse can control movement
setFlagEnableMouseNavigation(bool b)230 	void setFlagEnableMouseNavigation(bool b) {flagEnableMouseNavigation=b; emit flagEnableMouseNavigationChanged(b); }
231 
232 	//! Get whether mouse can control zooming
getFlagEnableMouseZooming() const233 	bool getFlagEnableMouseZooming() const {return flagEnableMouseZooming;}
234 	//! Set whether mouse can control zooming
setFlagEnableMouseZooming(bool b)235 	void setFlagEnableMouseZooming(bool b) {flagEnableMouseZooming=b; emit flagEnableMouseZoomingChanged(b); }
236 
237 	//! Get the state of flag for indication of mount mode
getFlagIndicationMountMode() const238 	bool getFlagIndicationMountMode() const {return flagIndicationMountMode;}
239 	//! Set the state of flag for indication of mount mode
setFlagIndicationMountMode(bool b)240 	void setFlagIndicationMountMode(bool b) { flagIndicationMountMode=b; emit flagIndicationMountModeChanged(b); }
241 
242 	//! Move the view to a specified J2000 position.
243 	//! @param aim The position to move to expressed as a vector.
244 	//! @param aimUp Up vector. Can be usually (0/0/1) but may have to be exact for looking into the zenith/pole
245 	//! @param moveDuration The time it takes for the move to complete.
246 	//! @param zooming you want to zoom in, out or not (just center).
247 	//! @code
248 	//! // You can use the following code most of the times to find a valid aimUp vector:
249 	//! StelMovementMgr* mvmgr = GETSTELMODULE(StelMovementMgr);
250 	//! mvmgr->moveToJ2000(pos, mvmgr->mountFrameToJ2000(Vec3d(0., 0., 1.)), mvmgr->getAutoMoveDuration());
251 	//! @endcode
252 	//! @note core::moveToRaDecJ2000 provides a simpler signature for the same function.
253 	//! @note Objects of class Vec3d are 3-dimensional vectors in a rectangular coordinate system. For
254 	//!       J2000 positions, the x-axis points to 0h,0°, the y-axis to 6h,0° and the z-axis points to the
255 	//!       celestial pole. You may use a constructor defining three components (x,y,z) or the
256 	//!       format with just two angles, e.g., Vec3d("0h","0d").
257 	void moveToJ2000(const Vec3d& aim, const Vec3d &aimUp, float moveDuration = 1., ZoomingMode zooming = ZoomNone);
258 
259 	//! Move the view to a specified AltAzimuthal position.
260 	//! @param aim The position to move to expressed as a vector in AltAz frame.
261 	//! @param aimUp Up vector in AltAz coordinates. Can be usually (0/0/1) but may have to be exact for looking into the zenith/pole
262 	//! @param moveDuration The time it takes for the move to complete.
263 	//! @param zooming you want to zoom in, out or not (just center).
264 	//! @code
265 	//! // You can use the following code most of the times to find a valid aimUp vector:
266 	//! StelMovementMgr* mvmgr = GETSTELMODULE(StelMovementMgr);
267 	//! mvmgr->moveToAltAzi(pos, Vec3d(0., 0., 1.), mvmgr->getAutoMoveDuration());
268 	//! @endcode
269 	//! @note core::moveToAltAzi provides a simpler signature for the same function.
270 	//! @note Objects of class Vec3d are 3-dimensional vectors in a right-handed (!) rectangular coordinate system.
271 	//!       For positions in the horizontal coordinate system, the axes point south, east and to the
272 	//!       zenith, irrespective of the setting of the "Azimuth from south" option in the "Tools" tab of the
273 	//!       "Configuration" window. You may use a constructor defining three components (x,y,z) or the
274 	//!       format with just two angles, e.g., Vec3d("0d","0d") points south, Vec3d("90d","0d") points east,
275 	//!       with azimuth angles running counter-clockwise, i.e., against the usual orientation.
276 	//! @note Panic function made March 2016. It turned out that using moveToJ2000 for alt-az-based moves behaves odd for long moves during fast timelapse: end vector is linked to the sky!
277 	//! As of March 2016: This call does nothing when mount frame is not AltAzi!
278 	void moveToAltAzi(const Vec3d& aim, const Vec3d &aimUp, float moveDuration = 1.f, ZoomingMode zooming = ZoomNone);
279 
280 	//! Change the zoom level.
281 	//! @param aimFov The desired field of view in degrees.
282 	//! @param zoomDuration The time that the operation should take to complete. [seconds]
283 	void zoomTo(double aimFov, float zoomDuration = 1.f);
284 	//! Get the current Field Of View in degrees
getCurrentFov() const285 	double getCurrentFov() const {return currentFov;}
286 
287 	//! Return the initial default FOV in degree.
getInitFov() const288 	double getInitFov() const {return initFov;}
289 	//! Set the initial Field Of View in degree.
290 	void setInitFov(double fov);
291 
292 	//! Return the initial viewing direction in altazimuthal coordinates.
293 	//! See StelMovementMgr::moveToAltAzi for an explanation of the return value.
getInitViewingDirection() const294 	const Vec3d getInitViewingDirection() const {return initViewPos;}
295 	//! Sets the initial direction of view to the current altitude and azimuth.
296 	//! Note: Updates the configuration file.
297 	void setInitViewDirectionToCurrent();
298 
299 	//! Return the current viewing direction in the equatorial J2000 frame.
300 	//! See StelMovementMgr::moveToJ2000 for an explanation of the return value.
getViewDirectionJ2000() const301 	Vec3d getViewDirectionJ2000() const {return viewDirectionJ2000;}
302 	//! Set the current viewing direction in the equatorial J2000 frame.
303 	void setViewDirectionJ2000(const Vec3d& v);
304 
305 	//! Set the maximum field of View in degrees.
306 	void setMaxFov(double max);
307 	//! Get the maximum field of View in degrees.
getMaxFov(void) const308 	double getMaxFov(void) const {return maxFov;}
309 
310 	//! Get the minimum field of View in degrees.
getMinFov(void) const311 	double getMinFov(void) const {return minFov;}
312 
313 	//! Go and zoom to the selected object. A later call to autoZoomOut will come back to the previous zoom level.
314 	void autoZoomIn(float moveDuration = 1.f, bool allowManualZoom = 1);
315 	//! Unzoom to the previous position.
316 	void autoZoomOut(float moveDuration = 1.f, bool full = 0);
317 
318 	//! Deselect the selected object
319 	void deselection(void);
320 
321 	//! If currently zooming, return the target FOV, otherwise return current FOV in degree.
322 	double getAimFov(void) const;
323 
324 	//! With true, starts turning the direction of view to the right, with an unspecified speed, according to the
325 	//! current mount mode (i.e., increasing azimuth, decreasing rectascension). Turning stops only
326 	//! due to a call to turnRight with false (or to turnLeft with any value) ; it does not stop when the script
327 	//! is terminated.
328 	//! @param s - true move, false stop
329 	//! @code
330 	//! // You can use the following code to turn the direction of the view
331 	//! // "a little" to the right, by an un predictable amount.
332 	//! StelMovementMgr.turnRight(true);
333 	//! core.wait(0.42);
334 	//! StelMovementMgr.turnRight(false);
335 	//! @endcode
336 	//! @note Use StelMovementMgr.panView for precise control of view movements.
337 	void turnRight(bool s);
338 
339 	//! With true, starts turning the direction of view to the left, with an unspecified speed, and according to the
340 	//! current mount mode (i.e., decreasing azimuth, increasing rectascension). Turning stops only
341 	//! due to a call to turnLeft with false (or to turnRight with any value); it does not stop when the script
342 	//! is terminated.
343 	//! @param s - true move, false stop
344 	//! @code
345 	//! // You can use the following code to turn the direction of the view
346 	//! // "a little" to the left, by an unpredictable amount.
347 	//! StelMovementMgr.turnLeft(true);
348 	//! core.wait(0.42);
349 	//! StelMovementMgr.turnLeft(false);
350 	//! @endcode
351 	//! @note Use StelMovementMgr.panView for precise control of view movements.
352 	void turnLeft(bool s);
353 
354 	//! With true, starts moving the direction of the view up, with an unspecified speed, and according to the
355 	//! current mount mode (i.e., towards the zenith or the celestial north pole). Movement halts when the
356 	//! goal is reached, but the command remains active until turnUp is called with false, or turnDown with
357 	//! any value. While this command is active, other movement commands or mouse or keyboard operations will be
358 	//! countermanded by the still pending turnUp command.
359 	//! @param s - true move, false stop
360 	//! @note Use StelMovementMgr.panView for precise control of view movements.
361 	void turnUp(bool s);
362 
363 	//! With true, starts moving the direction of the view down, with an unspecified speed, and according to the
364 	//! current mount mode (i.e., towards the nadir or the celestial south pole). Movement halts when the
365 	//! goal is reached, but the command remains active until turnDown is called with false, or turnUp with
366 	//! any value. While this command is active, other movement commands or mouse or keyboard operations will be
367 	//! countermanded by the still pending turnDown command.
368 	//! @param s - true move, false stop
369 	//! @note Use StelMovementMgr.panView for precise control of view movements.
370 	void turnDown(bool s);
371 
moveSlow(bool b)372 	void moveSlow(bool b) {flagMoveSlow=b;}
373 
374 	//! With true, starts zooming in, with an unspecified ratio of degrees per second, either until zooming
375 	//! is stopped with a zoomIn call with false (or a zoomOut call). Zooming pauses when the field of view limit
376 	//! (5 arc seconds) is reached, but the command remains active until zoomIn is called with false, or zoomOut
377 	//! with any value. While this command is active, other movement commands or mouse or keyboard operations
378 	//! will be countermanded by the still pending zoomIn command.
379 	//! @param s - true zoom, false stop
380 	void zoomIn(bool s);
381 
382 	//! With true, starts zooming out, with an unspecified ratio of degrees per second, either until zooming
383 	//! is stopped with a zoomIn call with false (or a zoomOut call). Zooming pauses when the field of view limit
384 	//! (235 degrees) is reached, but the command remains active until zoomOut is called with false, or zoomIn
385 	//! with any value. While this command is active, other movement commands or mouse or keyboard operations
386 	//! will be countermanded by the still pending zoomOut command.
387 	//! @param s - true zoom, false stop
388 	void zoomOut(bool s);
389 
390 	//! Smooth panning a predetermined amount
391 	//! @note a speed (degrees per seconds) is defined for both scales as deltaX/ptime and deltaY/ptime.
392 	//! @param deltaX - delta for scale X, in degrees
393 	//! @param deltaY - delta for scale Y, in degrees
394 	//! @param ptime - time for doing one step of delta, in seconds
395 	//! @param s - flag to enable panning
396 	void smoothPan(double deltaX, double deltaY, double ptime, bool s);
397 
398 	//! Look immediately towards East.
399 	//! @param zero true to center on horizon, false to keep altitude, or when looking to the zenith already, turn eastern horizon to screen bottom.
400 	void lookEast(bool zero=false);
401 	//! Look immediately towards West.
402 	//! @param zero true to center on horizon, false to keep altitude, or when looking to the zenith already, turn western horizon to screen bottom.
403 	void lookWest(bool zero=false);
404 	//! Look immediately towards North.
405 	//! @param zero true to center on horizon, false to keep altitude, or when looking to the zenith already, turn northern horizon to screen bottom.
406 	void lookNorth(bool zero=false);
407 	//! Look immediately towards South.
408 	//! @param zero true to center on horizon, false to keep altitude, or when looking to the zenith already, turn southern horizon to screen bottom.
409 	void lookSouth(bool zero=false);
410 	//! Look immediately towards Zenith, turning southern horizon to screen bottom.
411 	void lookZenith(void);
412 	//! Look immediately towards Nadir, turning southern horizon to screen top.
413 	void lookNadir(void);
414 	//! Look immediately towards North Celestial pole.
415 	void lookTowardsNCP(void);
416 	//! Look immediately towards South Celestial pole.
417 	void lookTowardsSCP(void);
418 
419 	//! set or start animated move of the viewport offset.
420 	//! This can be used e.g. in wide cylindrical panorama screens to push the horizon down and see more of the sky.
421 	//! Also helpful in stereographic projection to push the horizon down and see more of the sky.
422 	//! @param offsetX new horizontal viewport offset, percent. clamped to [-50...50]. Probably not very useful.
423 	//! @param offsetY new horizontal viewport offset, percent. clamped to [-50...50]. This is also available in the GUI.
424 	//! @param duration animation duration, seconds. Optional.
425 	//! @note Only vertical viewport is really meaningful.
426 	void moveViewport(double offsetX, double offsetY, const float duration=0.f);
427 
428 	//! Set current mount type defining the reference frame in which head movements occur.
429 	void setMountMode(MountMode m);
430 	//! Get current mount type defining the reference frame in which head movements occur.
getMountMode(void) const431 	MountMode getMountMode(void) const {return mountMode;}
getEquatorialMount(void) const432 	bool getEquatorialMount(void) const {return mountMode == MountEquinoxEquatorial;}
433 
434 	//! Function designed only for scripting context. Put the function into the startup.ssc of your planetarium setup,
435 	//! this will avoid any unwanted tracking.
setInhibitAllAutomoves(bool inhibit)436 	void setInhibitAllAutomoves(bool inhibit) { flagInhibitAllAutomoves=inhibit;}
437 
438 	//! Returns the targetted value of the viewport offset
getViewportOffsetTarget() const439 	Vec2d getViewportOffsetTarget() const { return targetViewportOffset; }
getViewportHorizontalOffsetTarget() const440 	double getViewportHorizontalOffsetTarget() const { return targetViewportOffset[0]; }
getViewportVerticalOffsetTarget() const441 	double getViewportVerticalOffsetTarget() const { return targetViewportOffset[1]; }
442 
setViewportHorizontalOffsetTarget(double f)443 	void setViewportHorizontalOffsetTarget(double f) { moveViewport(f,getViewportVerticalOffsetTarget()); }
setViewportVerticalOffsetTarget(double f)444 	void setViewportVerticalOffsetTarget(double f) { moveViewport(getViewportHorizontalOffsetTarget(),f); }
445 
446 	//! Set a hard limit for any fov change. Useful in the context of a planetarium with dome
447 	//! where a presenter never ever wants to set more than 180° even if the projection would allow it.
448 	void setUserMaxFov(double max);
getUserMaxFov() const449 	double getUserMaxFov() const {return userMaxFov; }
450 
451 signals:
452 	//! Emitted when the tracking property changes
453 	void flagTrackingChanged(bool b);
454 	void equatorialMountChanged(bool b);
455 	void flagIndicationMountModeChanged(bool b);
456 	void flagAutoZoomOutResetsDirectionChanged(bool b);
457 	void viewportHorizontalOffsetTargetChanged(double f);
458 	void viewportVerticalOffsetTargetChanged(double f);
459 	void flagEnableMouseNavigationChanged(bool b);
460 	void flagEnableMouseZoomingChanged(bool b);
461 	void flagEnableMoveKeysChanged(bool b);
462 	void flagEnableZoomKeysChanged(bool b);
463 	void userMaxFovChanged(double fov);
464 
465 private slots:
466 	//! Called when the selected object changes.
467 	void selectedObjectChange(StelModule::StelModuleSelectAction action);
468 
469 	//! Connected to the viewportOffsetTimeLine, does the actual viewport shift.
470 	void handleViewportOffsetMovement(qreal value);
471 
472 	void setFOVDeg(float fov);
473 	void bindingFOVActions();
474 
475 private:
476 	double currentFov; // The current FOV in degrees
477 	double initFov;    // The FOV at startup
478 	double minFov;     // Minimum FOV in degrees
479 	double maxFov;     // Maximum FOV in degrees. Depends on projection.
480 	double userMaxFov; // Custom setting. Can be useful in a planetarium context.
481 	double deltaFov;   // requested change of FOV (degrees) used during zooming.
setFov(double f)482 	void setFov(double f)
483 	{
484 		currentFov=qBound(minFov, f, maxFov);
485 	}
486 	// immediately add deltaFov argument to FOV - does not change private var.
487 	void changeFov(double deltaFov);
488 
489 	// Move (a bit) to selected/tracked object until move.coef reaches 1, or auto-follow (track) selected object.
490 	// Does nothing if flagInhibitAllAutomoves=true
491 	void updateVisionVector(double deltaTime);
492 	void updateAutoZoom(double deltaTime); // Update autoZoom if activated
493 
494 	//! Make the first screen position correspond to the second (useful for mouse dragging and also time dragging.)
495 	void dragView(int x1, int y1, int x2, int y2);
496 
497 	StelCore* core;          // The core on which the movement are applied
498 	QSettings* conf;
499 	class StelObjectMgr* objectMgr;
500 	bool flagLockEquPos;     // Define if the equatorial position is locked
501 	bool flagTracking;       // Define if the selected object is followed
502 	bool flagInhibitAllAutomoves; // Required for special installations: If true, there is no automatic centering etc.
503 
504 	// Flags for mouse movements
505 	bool isMouseMovingHoriz;
506 	bool isMouseMovingVert;
507 
508 	bool flagEnableMoveAtScreenEdge; // allow mouse at edge of screen to move view
509 	bool flagEnableMouseNavigation;
510 	bool flagEnableMouseZooming;
511 	double mouseZoomSpeed;
512 
513 	bool flagEnableZoomKeys;
514 	bool flagEnableMoveKeys;
515 	double keyMoveSpeed;              // Speed of keys movement
516 	double keyZoomSpeed;              // Speed of keys zoom
517 	bool flagMoveSlow;
518 
519 	//flag to enable panning a predetermined amount
520 	bool flagCustomPan;
521 	double rateX;
522 	double rateY;
523 
524 	// Speed factor for real life time movements, used for fast forward when playing scripts.
525 	float movementsSpeedFactor;
526 
527 	//! @internal
528 	//! Store data for auto-move
529 	struct AutoMove
530 	{
531 		Vec3d start;
532 		Vec3d aim;
533 		Vec3d startUp; // The Up vector at start time
534 		Vec3d aimUp;   // The Up vector at end time of move
535 		float speed;   // set to 1/duration[ms] during automove setup.
536 		float coef;    // Set to 0 at begin of an automove, runs up to 1.
537 		// If not null, move to the object instead of the aim.
538 		StelObjectP targetObject;
539 		MountMode mountMode; // In which frame we shall move. This may be different from the frame the display is set to!
540 		// The start and aim vectors are given in those coordinates, and are interpolated in the respective reference frames,
541 		// then the view vector is derived from the current coef.
542 		// AzAlt moves should be set to AltAz mode, else they will move towards the RA/Dec at begin of move which may have moved.
543 		// It is an error to move in J2000 or Eq frame with fast timelapse!
544 		// This is a March 2016 GZ hack. TODO: This class should be thought over a bit.
545 	};
546 
547 	AutoMove move;          // Current auto movement. 2016-03: During setup, decide upon the frame for motion!
548 	bool flagAutoMove;       // Define if automove is on or off
549 	ZoomingMode zoomingMode;
550 
551 	double deltaAlt,deltaAz; // View movement
552 
553 	bool flagManualZoom;     // Define whether auto zoom can go further
554 	float autoMoveDuration; // Duration of movement for the auto move to a selected object in seconds
555 
556 	// Mouse control options
557 	bool isDragging, hasDragged;
558 	int previousX, previousY;
559 
560 	// Contains the last N real time / JD times pairs associated with the last N mouse move events at screen coordinates x/y
561 	struct DragHistoryEntry
562 	{
563 		double runTime;
564 		double jd;
565 		int x;
566 		int y;
567 	};
568 	QList<DragHistoryEntry> timeDragHistory; // list of max 3 entries.
569 	void addTimeDragPoint(int x, int y);
570 	double beforeTimeDragTimeRate;
571 
572 	// Time mouse control
573 	bool dragTimeMode; // Internal flag, true during mouse time motion. This is set true when mouse is moving with ctrl pressed. Set false when releasing ctrl.
574 
575 	// Internal state for smooth zoom animation.
576 	Smoother zoomMove;
577 
578 	bool flagAutoZoom; // Define if autozoom is on or off
579 	bool flagAutoZoomOutResetsDirection;
580 
581 	// defines if view corrects for horizon, or uses equatorial coordinates
582 	MountMode mountMode;
583 
584 	Vec3d initViewPos;        // Default viewing direction
585 	Vec3d initViewUp;         // original up vector. Usually 0/0/1, but maybe something else in rare setups (e.g. Planetarium dome upwards fisheye projection).
586 
587 	// Viewing direction in equatorial J2000 coordinates
588 	Vec3d viewDirectionJ2000;
589 	// Viewing direction in the mount reference frame.
590 	Vec3d viewDirectionMountFrame;
591 
592 	// Up vector (in OpenGL terms) in the mount reference frame.
593 	// This can usually be just 0/0/1, but must be set to something useful when viewDirectionMountFrame is parallel, i.e. looks into a pole.
594 	Vec3d upVectorMountFrame;
595 
596 	// TODO: Docfix?
597 	float dragTriggerDistance;
598 
599 	// Viewport shifting. This animates a property belonging to StelCore. But the shift itself is likely best placed here.
600 	QTimeLine *viewportOffsetTimeline;
601 	// Those two are used during viewport offset animation transitions. Both are set by moveViewport(), and irrelevant after the transition.
602 	Vec2d oldViewportOffset;
603 	Vec2d targetViewportOffset;
604 
605 	bool flagIndicationMountMode; // state of mount mode
606 
607 	//! @name Screen message infrastructure
608 	//@{
609 	int lastMessageID;
610 	//@}
611 };
612 
613 #endif // STELMOVEMENTMGR_HPP
614 
615