~xalioth/stellarium/fix-fonts-gltex-fab

« back to all changes in this revision

Viewing changes to src/core/StelMovementMgr.cpp

  • Committer: matthewg42
  • Date: 2008-11-27 14:36:21 UTC
  • Revision ID: vcs-imports@canonical.com-20081127143621-fbasu1vl30kq2edv
refactor: MovementMgr -> StelMovementMgr

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Stellarium
 
3
 * Copyright (C) 2007 Fabien Chereau
 
4
 * 
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License
 
7
 * as published by the Free Software Foundation; either version 2
 
8
 * of the License, or (at your option) any later version.
 
9
 * 
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 * 
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
18
 */
 
19
 
 
20
#include "StelMovementMgr.hpp"
 
21
#include "StelObjectMgr.hpp"
 
22
#include "StelApp.hpp"
 
23
#include "StelCore.hpp"
 
24
#include "StelNavigator.hpp"
 
25
#include "StelUtils.hpp"
 
26
 
 
27
#include <QString>
 
28
#include <QTextStream>
 
29
#include <QSettings>
 
30
#include <QKeyEvent>
 
31
#include <QDebug>
 
32
 
 
33
StelMovementMgr::StelMovementMgr(StelCore* acore) : core(acore), 
 
34
        flagLockEquPos(false),
 
35
        flagTracking(false),
 
36
        isMouseMovingHoriz(false),
 
37
        isMouseMovingVert(false),
 
38
        flagEnableMouseNavigation(true),
 
39
        keyMoveSpeed(0.00025),
 
40
        flagAutoMove(0),
 
41
        deltaFov(0.),
 
42
        deltaAlt(0.),
 
43
        deltaAz(0.),
 
44
        flagAutoZoom(0),
 
45
        flagAutoZoomOutResetsDirection(0)
 
46
{
 
47
        setObjectName("StelMovementMgr");
 
48
        isDragging = false;
 
49
}
 
50
 
 
51
StelMovementMgr::~StelMovementMgr()
 
52
{
 
53
}
 
54
 
 
55
void StelMovementMgr::init()
 
56
{
 
57
        QSettings* conf = StelApp::getInstance().getSettings();
 
58
        Q_ASSERT(conf);
 
59
 
 
60
        flagEnableMoveAtScreenEdge = conf->value("navigation/flag_enable_move_at_screen_edge",false).toBool();
 
61
        mouseZoomSpeed = conf->value("navigation/mouse_zoom",30).toInt();
 
62
        flagEnableZoomKeys = conf->value("navigation/flag_enable_zoom_keys").toBool();
 
63
        flagEnableMoveKeys = conf->value("navigation/flag_enable_move_keys").toBool();
 
64
        keyMoveSpeed = conf->value("navigation/move_speed",0.0004).toDouble();
 
65
        keyZoomSpeed = conf->value("navigation/zoom_speed", 0.0004).toDouble();
 
66
        autoMoveDuration = conf->value ("navigation/auto_move_duration",1.5).toDouble();
 
67
        flagManualZoom = conf->value("navigation/flag_manual_zoom").toBool();
 
68
        flagAutoZoomOutResetsDirection = conf->value("navigation/auto_zoom_out_resets_direction", true).toBool();
 
69
        flagEnableMouseNavigation = conf->value("navigation/flag_enable_mouse_navigation",true).toBool();
 
70
        
 
71
        minFov = 0.0001;
 
72
        maxFov = 100.; 
 
73
        initFov = conf->value("navigation/init_fov",60.).toDouble();
 
74
        currentFov = initFov;
 
75
}       
 
76
        
 
77
bool StelMovementMgr::handleMouseMoves(int x, int y, Qt::MouseButtons b)
 
78
{
 
79
        // Turn if the mouse is at the edge of the screen unless config asks otherwise
 
80
        if (flagEnableMoveAtScreenEdge)
 
81
        {
 
82
                if (x <= 1)
 
83
                {
 
84
                        turnLeft(1);
 
85
                        isMouseMovingHoriz = true;
 
86
                }
 
87
                else if (x >= core->getProjection2d()->getViewportWidth() - 2)
 
88
                {
 
89
                        turnRight(1);
 
90
                        isMouseMovingHoriz = true;
 
91
                }
 
92
                else if (isMouseMovingHoriz)
 
93
                {
 
94
                        turnLeft(0);
 
95
                        isMouseMovingHoriz = false;
 
96
                }
 
97
 
 
98
                if (y <= 1)
 
99
                {
 
100
                        turnUp(1);
 
101
                        isMouseMovingVert = true;
 
102
                }
 
103
                else if (y >= core->getProjection2d()->getViewportHeight() - 2)
 
104
                {
 
105
                        turnDown(1);
 
106
                        isMouseMovingVert = true;
 
107
                }
 
108
                else if (isMouseMovingVert)
 
109
                {
 
110
                        turnUp(0);
 
111
                        isMouseMovingVert = false;
 
112
                }
 
113
        }
 
114
        
 
115
        if (isDragging && flagEnableMouseNavigation)
 
116
        {
 
117
                if (hasDragged || (std::sqrt((double)((x-previousX)*(x-previousX) +(y-previousY)*(y-previousY)))>4.))
 
118
                {
 
119
                        hasDragged = true;
 
120
                        setFlagTracking(false);
 
121
                        dragView(previousX, previousY, x, y);
 
122
                        previousX = x;
 
123
                        previousY = y;
 
124
                        return true;
 
125
                }
 
126
        }
 
127
        return false;
 
128
}
 
129
 
 
130
 
 
131
void StelMovementMgr::handleKeys(QKeyEvent* event)
 
132
{
 
133
        if (event->type() == QEvent::KeyPress)
 
134
        {
 
135
                // Direction and zoom deplacements
 
136
                switch (event->key())
 
137
                {
 
138
                        case Qt::Key_Left:
 
139
                                turnLeft(true); break;
 
140
                        case Qt::Key_Right:
 
141
                                turnRight(true); break;
 
142
                        case Qt::Key_Up:
 
143
                                if (event->modifiers().testFlag(Qt::ControlModifier)) zoomIn(true);
 
144
                                else turnUp(true);
 
145
                                break;
 
146
                        case Qt::Key_Down:
 
147
                                if (event->modifiers().testFlag(Qt::ControlModifier)) zoomOut(true);
 
148
                                else turnDown(true);
 
149
                                break;
 
150
                        case Qt::Key_PageUp:
 
151
                                zoomIn(true); break;
 
152
                        case Qt::Key_PageDown:
 
153
                                zoomOut(true); break;
 
154
                        default:
 
155
                                return;
 
156
                }
 
157
        }
 
158
        else
 
159
        {
 
160
                // When a deplacement key is released stop mooving
 
161
                switch (event->key())
 
162
                {
 
163
                        case Qt::Key_Left:
 
164
                                turnLeft(false); break;
 
165
                        case Qt::Key_Right:
 
166
                                turnRight(false); break;
 
167
                        case Qt::Key_Up:
 
168
                                zoomIn(false);
 
169
                                turnUp(false);
 
170
                                break;
 
171
                        case Qt::Key_Down:
 
172
                                zoomOut(false);
 
173
                                turnDown(false);
 
174
                                break;
 
175
                        case Qt::Key_PageUp:
 
176
                                zoomIn(false); break;
 
177
                        case Qt::Key_PageDown:
 
178
                                zoomOut(false); break;
 
179
                        default:
 
180
                                return;
 
181
                }
 
182
        }
 
183
        event->accept();
 
184
}
 
185
 
 
186
//! Handle mouse wheel events.
 
187
void StelMovementMgr::handleMouseWheel(QWheelEvent* event)
 
188
{
 
189
        if (flagEnableMouseNavigation==false)
 
190
                return;
 
191
        int numDegrees = event->delta() / 8;
 
192
        int numSteps = numDegrees / 15;
 
193
        zoomTo(getAimFov()-mouseZoomSpeed*numSteps*getAimFov()/60., 0.2);
 
194
        event->accept();
 
195
}
 
196
 
 
197
void StelMovementMgr::handleMouseClicks(QMouseEvent* event)
 
198
{
 
199
        switch (event->button())
 
200
        {
 
201
                case Qt::RightButton : break;
 
202
                case Qt::LeftButton :
 
203
                        if (event->type()==QEvent::MouseButtonPress)
 
204
                        {
 
205
                                isDragging = true;
 
206
                                hasDragged = false;
 
207
                                previousX = event->x();
 
208
                                previousY = event->y();
 
209
                                event->accept();
 
210
                                return;
 
211
                        }
 
212
                        else
 
213
                        {
 
214
                                if (isDragging)
 
215
                                {
 
216
                                        isDragging = false;
 
217
                                        if (hasDragged)
 
218
                                        {
 
219
                                                event->accept();
 
220
                                                return;
 
221
                                        }
 
222
                                        else
 
223
                                                return;
 
224
                                }
 
225
                        }
 
226
                        break;
 
227
                case Qt::MidButton :
 
228
                        if (event->type()==QEvent::MouseButtonRelease)
 
229
                        {
 
230
                                if (StelApp::getInstance().getStelObjectMgr().getWasSelected())
 
231
                                {
 
232
                                        moveTo(StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0]->getEquinoxEquatorialPos(core->getNavigator()),autoMoveDuration);
 
233
                                        setFlagTracking(true);
 
234
                                }
 
235
                        }
 
236
                        break;
 
237
                default: break;
 
238
        }
 
239
        return;
 
240
}
 
241
 
 
242
/*************************************************************************
 
243
 The selected objects changed, follow it it we were already following another one
 
244
*************************************************************************/ 
 
245
void StelMovementMgr::selectedObjectChangeCallBack(StelModuleSelectAction action)
 
246
{
 
247
        // If an object was selected keep the earth following
 
248
        if (StelApp::getInstance().getStelObjectMgr().getWasSelected())
 
249
        {
 
250
                if (getFlagTracking())
 
251
                        setFlagLockEquPos(true);
 
252
                setFlagTracking(false);
 
253
        }
 
254
}
 
255
 
 
256
void StelMovementMgr::turnRight(bool s)
 
257
{
 
258
        if (s && flagEnableMoveKeys)
 
259
        {
 
260
                deltaAz = 1;
 
261
                setFlagTracking(false);
 
262
                setFlagLockEquPos(false);
 
263
        }
 
264
        else
 
265
                deltaAz = 0;
 
266
}
 
267
 
 
268
void StelMovementMgr::turnLeft(bool s)
 
269
{
 
270
        if (s && flagEnableMoveKeys)
 
271
        {
 
272
                deltaAz = -1;
 
273
                setFlagTracking(false);
 
274
                setFlagLockEquPos(false);
 
275
        }
 
276
        else
 
277
                deltaAz = 0;
 
278
}
 
279
 
 
280
void StelMovementMgr::turnUp(bool s)
 
281
{
 
282
        if (s && flagEnableMoveKeys)
 
283
        {
 
284
                deltaAlt = 1;
 
285
                setFlagTracking(false);
 
286
                setFlagLockEquPos(false);
 
287
        }
 
288
        else
 
289
                deltaAlt = 0;
 
290
}
 
291
 
 
292
void StelMovementMgr::turnDown(bool s)
 
293
{
 
294
        if (s && flagEnableMoveKeys)
 
295
        {
 
296
                deltaAlt = -1;
 
297
                setFlagTracking(false);
 
298
                setFlagLockEquPos(false);
 
299
        }
 
300
        else
 
301
                deltaAlt = 0;
 
302
}
 
303
 
 
304
 
 
305
void StelMovementMgr::zoomIn(bool s)
 
306
{
 
307
        if (flagEnableZoomKeys)
 
308
                deltaFov = -1*(s!=0);
 
309
}
 
310
 
 
311
void StelMovementMgr::zoomOut(bool s)
 
312
{
 
313
        if (flagEnableZoomKeys)
 
314
                deltaFov = (s!=0);
 
315
}
 
316
 
 
317
 
 
318
// Increment/decrement smoothly the vision field and position
 
319
void StelMovementMgr::updateMotion(double deltaTime)
 
320
{
 
321
        const StelProjectorP proj = core->getProjection(StelCore::FrameJ2000);
 
322
        
 
323
        updateVisionVector(deltaTime);
 
324
        
 
325
        // the more it is zoomed, the lower the moving speed is (in angle)
 
326
        double depl=keyMoveSpeed*deltaTime*1000*currentFov;
 
327
        double deplzoom=keyZoomSpeed*deltaTime*1000*proj->deltaZoom(currentFov*(M_PI/360.0))*(360.0/M_PI);
 
328
 
 
329
        if (deltaAz<0)
 
330
        {
 
331
                deltaAz = -depl/30;
 
332
                if (deltaAz<-0.2)
 
333
                        deltaAz = -0.2;
 
334
        }
 
335
        else
 
336
        {
 
337
                if (deltaAz>0)
 
338
                {
 
339
                        deltaAz = (depl/30);
 
340
                        if (deltaAz>0.2)
 
341
                                deltaAz = 0.2;
 
342
                }
 
343
        }
 
344
        if (deltaAlt<0)
 
345
        {
 
346
                deltaAlt = -depl/30;
 
347
                if (deltaAlt<-0.2)
 
348
                        deltaAlt = -0.2;
 
349
        }
 
350
        else
 
351
        {
 
352
                if (deltaAlt>0)
 
353
                {
 
354
                        deltaAlt = depl/30;
 
355
                        if (deltaAlt>0.2)
 
356
                                deltaAlt = 0.2;
 
357
                }
 
358
        }
 
359
 
 
360
        if (deltaFov<0)
 
361
        {
 
362
                deltaFov = -deplzoom*5;
 
363
                if (deltaFov<-0.15*currentFov)
 
364
                        deltaFov = -0.15*currentFov;
 
365
        }
 
366
        else
 
367
        {
 
368
                if (deltaFov>0)
 
369
                {
 
370
                        deltaFov = deplzoom*5;
 
371
                        if (deltaFov>20)
 
372
                                deltaFov = 20;
 
373
                }
 
374
        }
 
375
 
 
376
        if (deltaFov != 0 )
 
377
        {
 
378
                changeFov(deltaFov);
 
379
        }
 
380
        panView(deltaAz, deltaAlt);
 
381
        updateAutoZoom(deltaTime);
 
382
}
 
383
 
 
384
 
 
385
// Go and zoom to the selected object.
 
386
void StelMovementMgr::autoZoomIn(float moveDuration, bool allowManualZoom)
 
387
{
 
388
        if (!StelApp::getInstance().getStelObjectMgr().getWasSelected())
 
389
                return;
 
390
                
 
391
        float manualMoveDuration;
 
392
 
 
393
        if (!getFlagTracking())
 
394
        {
 
395
                setFlagTracking(true);
 
396
                moveTo(StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0]->getEquinoxEquatorialPos(core->getNavigator()), moveDuration, false, 1);
 
397
                manualMoveDuration = moveDuration;
 
398
        }
 
399
        else
 
400
        {
 
401
                // faster zoom in manual zoom mode once object is centered
 
402
                manualMoveDuration = moveDuration*.66f;
 
403
        }
 
404
 
 
405
        if( allowManualZoom && flagManualZoom )
 
406
        {
 
407
                // if manual zoom mode, user can zoom in incrementally
 
408
                float newfov = currentFov*0.5f;
 
409
                zoomTo(newfov, manualMoveDuration);
 
410
        }
 
411
        else
 
412
        {
 
413
                float satfov = StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0]->getSatellitesFov(core->getNavigator());
 
414
 
 
415
                if (satfov>0.0 && currentFov*0.9>satfov)
 
416
                        zoomTo(satfov, moveDuration);
 
417
                else
 
418
                {
 
419
                        float closefov = StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0]->getCloseViewFov(core->getNavigator());
 
420
                        if (currentFov>closefov)
 
421
                                zoomTo(closefov, moveDuration);
 
422
                }
 
423
        }
 
424
}
 
425
 
 
426
 
 
427
// Unzoom and go to the init position
 
428
void StelMovementMgr::autoZoomOut(float moveDuration, bool full)
 
429
{
 
430
        StelNavigator* nav = core->getNavigator();
 
431
        
 
432
        if (StelApp::getInstance().getStelObjectMgr().getWasSelected() && !full)
 
433
        {
 
434
                // If the selected object has satellites, unzoom to satellites view
 
435
                // unless specified otherwise
 
436
                float satfov = StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0]->getSatellitesFov(core->getNavigator());
 
437
 
 
438
                if (satfov>0.0 && currentFov<=satfov*0.9)
 
439
                {
 
440
                        zoomTo(satfov, moveDuration);
 
441
                        return;
 
442
                }
 
443
 
 
444
                // If the selected object is part of a Planet subsystem (other than sun),
 
445
                // unzoom to subsystem view
 
446
                satfov = StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0]->getParentSatellitesFov((core->getNavigator()));
 
447
                if (satfov>0.0 && currentFov<=satfov*0.9)
 
448
                {
 
449
                        zoomTo(satfov, moveDuration);
 
450
                        return;
 
451
                }
 
452
        }
 
453
 
 
454
        zoomTo(initFov, moveDuration);
 
455
        if (flagAutoZoomOutResetsDirection) 
 
456
                moveTo(nav->getInitViewingDirection(), moveDuration, true, -1);
 
457
        setFlagTracking(false);
 
458
        setFlagLockEquPos(false);
 
459
}
 
460
 
 
461
 
 
462
void StelMovementMgr::setFlagTracking(bool b)
 
463
{
 
464
        if(!b || !StelApp::getInstance().getStelObjectMgr().getWasSelected())
 
465
        {
 
466
                flagTracking=false;
 
467
        }
 
468
        else
 
469
        {
 
470
                moveTo(StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0]->getEquinoxEquatorialPos(core->getNavigator()), getAutoMoveDuration());
 
471
                flagTracking=true;
 
472
        }
 
473
}
 
474
 
 
475
 
 
476
////////////////////////////////////////////////////////////////////////////////
 
477
// Move to the given equatorial position
 
478
void StelMovementMgr::moveTo(const Vec3d& _aim, float moveDuration, bool _localPos, int zooming)
 
479
{
 
480
        StelNavigator* nav = core->getNavigator();
 
481
        zoomingMode = zooming;
 
482
        move.aim=_aim;
 
483
        move.aim.normalize();
 
484
        move.aim*=2.;
 
485
        if (_localPos)
 
486
        {
 
487
                move.start=nav->getAltAzVisionDirection();
 
488
        }
 
489
        else
 
490
        {
 
491
                move.start=nav->getEquinoxEquVisionDirection();
 
492
        }
 
493
        move.start.normalize();
 
494
        move.speed=1.f/(moveDuration*1000);
 
495
        move.coef=0.;
 
496
        move.localPos = _localPos;
 
497
        flagAutoMove = true;
 
498
}
 
499
 
 
500
 
 
501
////////////////////////////////////////////////////////////////////////////////
 
502
void StelMovementMgr::updateVisionVector(double deltaTime)
 
503
{
 
504
        StelNavigator* nav = core->getNavigator();
 
505
        if (flagAutoMove)
 
506
        {
 
507
                double ra_aim, de_aim, ra_start, de_start, ra_now, de_now;
 
508
 
 
509
                if( zoomingMode == 1 && StelApp::getInstance().getStelObjectMgr().getWasSelected())
 
510
                {
 
511
                        // if zooming in, object may be moving so be sure to zoom to latest position
 
512
                        move.aim = StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0]->getEquinoxEquatorialPos(core->getNavigator());
 
513
                        move.aim.normalize();
 
514
                        move.aim*=2.;
 
515
                }
 
516
 
 
517
                // Use a smooth function
 
518
                float smooth = 4.f;
 
519
                double c;
 
520
 
 
521
                if (zoomingMode == 1)
 
522
                {
 
523
                        if( move.coef > .9 )
 
524
                        {
 
525
                                c = 1;
 
526
                        }
 
527
                        else
 
528
                        {
 
529
                                c = 1 - pow(1.-1.11*(move.coef),3);
 
530
                        }
 
531
                }
 
532
                else if(zoomingMode == -1)
 
533
                {
 
534
                        if( move.coef < 0.1 )
 
535
                        {
 
536
                                // keep in view at first as zoom out
 
537
                                c = 0;
 
538
 
 
539
                                /* could track as moves too, but would need to know if start was actually
 
540
                                   a zoomed in view on the object or an extraneous zoom out command
 
541
                                   if(move.localPos) {
 
542
                                   move.start=equinoxEquToAltAz(selected.getEquinoxEquatorialPos(this));
 
543
                                   } else {
 
544
                                   move.start=selected.getEquinoxEquatorialPos(this);
 
545
                                   }
 
546
                                   move.start.normalize();
 
547
                                */
 
548
 
 
549
                        }
 
550
                        else
 
551
                        {
 
552
                                c =  pow(1.11*(move.coef-.1),3);
 
553
                        }
 
554
                }
 
555
                else c = std::atan(smooth * 2.*move.coef-smooth)/std::atan(smooth)/2+0.5;
 
556
 
 
557
 
 
558
                if (move.localPos)
 
559
                {
 
560
                        StelUtils::rectToSphe(&ra_aim, &de_aim, move.aim);
 
561
                        StelUtils::rectToSphe(&ra_start, &de_start, move.start);
 
562
                }
 
563
                else
 
564
                {
 
565
                        StelUtils::rectToSphe(&ra_aim, &de_aim, nav->equinoxEquToAltAz(move.aim));
 
566
                        StelUtils::rectToSphe(&ra_start, &de_start, nav->equinoxEquToAltAz(move.start));
 
567
                }
 
568
                
 
569
                // Trick to choose the good moving direction and never travel on a distance > PI
 
570
                if (ra_aim-ra_start > M_PI)
 
571
                {
 
572
                        ra_aim -= 2.*M_PI;
 
573
                }
 
574
                else if (ra_aim-ra_start < -M_PI)
 
575
                {
 
576
                        ra_aim += 2.*M_PI;
 
577
                }
 
578
                
 
579
                de_now = de_aim*c + de_start*(1. - c);
 
580
                ra_now = ra_aim*c + ra_start*(1. - c);
 
581
                
 
582
                Vec3d tmp;
 
583
                StelUtils::spheToRect(ra_now, de_now, tmp);
 
584
                nav->setEquinoxEquVisionDirection(nav->altAzToEquinoxEqu(tmp));
 
585
 
 
586
                move.coef+=move.speed*deltaTime*1000;
 
587
                if (move.coef>=1.)
 
588
                {
 
589
                        flagAutoMove=0;
 
590
                        if (move.localPos)
 
591
                        {
 
592
                                nav->setAltAzVisionDirection(move.aim);
 
593
                        }
 
594
                        else
 
595
                        {
 
596
                                nav->setEquinoxEquVisionDirection(move.aim);
 
597
                        }
 
598
                }
 
599
        }
 
600
        else
 
601
        {
 
602
                if (flagTracking && StelApp::getInstance().getStelObjectMgr().getWasSelected()) // Equatorial vision vector locked on selected object
 
603
                {
 
604
                        nav->setEquinoxEquVisionDirection(StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0]->getEquinoxEquatorialPos(core->getNavigator()));
 
605
                }
 
606
                else
 
607
                {
 
608
                        if (flagLockEquPos) // Equatorial vision vector locked
 
609
                        {
 
610
                                // Recalc local vision vector
 
611
                                nav->setAltAzVisionDirection(nav->equinoxEquToAltAz(nav->getEquinoxEquVisionDirection()));
 
612
                        }
 
613
                        else // Local vision vector locked
 
614
                        {
 
615
                                // Recalc equatorial vision vector
 
616
                                nav->setEquinoxEquVisionDirection(nav->altAzToEquinoxEqu(nav->getAltAzVisionDirection()));
 
617
                        }
 
618
                }
 
619
        }
 
620
}
 
621
 
 
622
 
 
623
////////////////////////////////////////////////////////////////////////////////
 
624
void StelMovementMgr::panView(double deltaAz, double deltaAlt)
 
625
{
 
626
        StelNavigator* nav = core->getNavigator();
 
627
        double azVision, altVision;
 
628
 
 
629
        if( nav->getViewingMode() == StelNavigator::ViewEquator) StelUtils::rectToSphe(&azVision,&altVision,nav->getEquinoxEquVisionDirection());
 
630
        else StelUtils::rectToSphe(&azVision,&altVision,nav->getAltAzVisionDirection());
 
631
 
 
632
        // if we are moving in the Azimuthal angle (left/right)
 
633
        if (deltaAz) azVision-=deltaAz;
 
634
        if (deltaAlt)
 
635
        {
 
636
                if (altVision+deltaAlt <= M_PI_2 && altVision+deltaAlt >= -M_PI_2) altVision+=deltaAlt;
 
637
                if (altVision+deltaAlt > M_PI_2) altVision = M_PI_2 - 0.000001;         // Prevent bug
 
638
                if (altVision+deltaAlt < -M_PI_2) altVision = -M_PI_2 + 0.000001;       // Prevent bug
 
639
        }
 
640
 
 
641
        // recalc all the position variables
 
642
        if (deltaAz || deltaAlt)
 
643
        {
 
644
                setFlagTracking(false);
 
645
                if( nav->getViewingMode() == StelNavigator::ViewEquator)
 
646
                {
 
647
                        Vec3d tmp;
 
648
                        StelUtils::spheToRect(azVision, altVision, tmp);
 
649
                        nav->setAltAzVisionDirection(nav->equinoxEquToAltAz(tmp));
 
650
                }
 
651
                else
 
652
                {
 
653
                        Vec3d tmp;
 
654
                        StelUtils::spheToRect(azVision, altVision, tmp);
 
655
                        // Calc the equatorial coordinate of the direction of vision wich was in Altazimuthal coordinate
 
656
                        nav->setEquinoxEquVisionDirection(nav->altAzToEquinoxEqu(tmp));
 
657
                }
 
658
        }
 
659
}
 
660
 
 
661
 
 
662
//! Make the first screen position correspond to the second (useful for mouse dragging)
 
663
void StelMovementMgr::dragView(int x1, int y1, int x2, int y2)
 
664
{
 
665
        StelNavigator* nav = core->getNavigator();
 
666
        
 
667
        Vec3d tempvec1, tempvec2;
 
668
        double az1, alt1, az2, alt2;
 
669
        const StelProjectorP prj = nav->getViewingMode()==StelNavigator::ViewHorizon ? core->getProjection(StelCore::FrameAltAz) :
 
670
                core->getProjection(StelCore::FrameEquinoxEqu);
 
671
                
 
672
//johannes: StelApp already gives appropriate x/y coordinates
 
673
//      proj->unProject(x2,proj->getViewportHeight()-y2, tempvec2);
 
674
//      proj->unProject(x1,proj->getViewportHeight()-y1, tempvec1);
 
675
        prj->unProject(x2,y2, tempvec2);
 
676
        prj->unProject(x1,y1, tempvec1);
 
677
        StelUtils::rectToSphe(&az1, &alt1, tempvec1);
 
678
        StelUtils::rectToSphe(&az2, &alt2, tempvec2);
 
679
        panView(az2-az1, alt1-alt2);
 
680
        setFlagTracking(false);
 
681
        setFlagLockEquPos(false);
 
682
}
 
683
 
 
684
 
 
685
// Update autoZoom if activated
 
686
void StelMovementMgr::updateAutoZoom(double deltaTime)
 
687
{
 
688
        if (flagAutoZoom)
 
689
        {
 
690
                // Use a smooth function
 
691
                double c;
 
692
 
 
693
                if( zoomMove.start > zoomMove.aim )
 
694
                {
 
695
                        // slow down as approach final view
 
696
                        c = 1 - (1-zoomMove.coef)*(1-zoomMove.coef)*(1-zoomMove.coef);
 
697
                }
 
698
                else
 
699
                {
 
700
                        // speed up as leave zoom target
 
701
                        c = (zoomMove.coef)*(zoomMove.coef)*(zoomMove.coef);
 
702
                }
 
703
 
 
704
                setFov(zoomMove.start + (zoomMove.aim - zoomMove.start) * c);
 
705
                zoomMove.coef+=zoomMove.speed*deltaTime*1000;
 
706
                if (zoomMove.coef>=1.)
 
707
                {
 
708
                        flagAutoZoom = 0;
 
709
                        setFov(zoomMove.aim);
 
710
                }
 
711
        }
 
712
}
 
713
 
 
714
// Zoom to the given field of view
 
715
void StelMovementMgr::zoomTo(double aim_fov, float moveDuration)
 
716
{
 
717
        zoomMove.aim=aim_fov;
 
718
    zoomMove.start=currentFov;
 
719
    zoomMove.speed=1.f/(moveDuration*1000);
 
720
    zoomMove.coef=0.;
 
721
    flagAutoZoom = true;
 
722
}
 
723
 
 
724
void StelMovementMgr::changeFov(double deltaFov)
 
725
{
 
726
        // if we are zooming in or out
 
727
        if (deltaFov)
 
728
                setFov(currentFov + deltaFov);
 
729
}
 
730
 
 
731
double StelMovementMgr::getAimFov(void) const
 
732
{
 
733
        return (flagAutoZoom ? zoomMove.aim : currentFov);
 
734
}
 
735
 
 
736
void StelMovementMgr::setMaxFov(double max)
 
737
{
 
738
        maxFov = max;
 
739
        if (currentFov > max)
 
740
        {
 
741
                setFov(max);
 
742
        }
 
743
}