~ubuntu-branches/ubuntu/precise/stellarium/precise

« back to all changes in this revision

Viewing changes to src/core/StelNavigator.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Howard
  • Date: 2010-02-15 20:48:39 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20100215204839-u3qgbv60rho997yk
Tags: 0.10.3-0ubuntu1
* New upstream release.
  - fixes intel rendering bug (LP: #480553)

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include "Planet.hpp"
26
26
#include "StelObjectMgr.hpp"
27
27
#include "StelCore.hpp"
 
28
#include "StelLocation.hpp"
28
29
#include "StelLocationMgr.hpp"
29
30
#include "StelModuleMgr.hpp"
30
31
#include "StelMovementMgr.hpp"
38
39
// See vsop87.doc:
39
40
const Mat4d StelNavigator::matJ2000ToVsop87(Mat4d::xrotation(-23.4392803055555555556*(M_PI/180)) * Mat4d::zrotation(0.0000275*(M_PI/180)));
40
41
const Mat4d StelNavigator::matVsop87ToJ2000(matJ2000ToVsop87.transpose());
 
42
const Mat4d StelNavigator::matJ2000ToGalactic(-0.054875539726, 0.494109453312, -0.867666135858, 0, -0.873437108010, -0.444829589425, -0.198076386122, 0, -0.483834985808, 0.746982251810, 0.455983795705, 0, 0, 0, 0, 1);
 
43
const Mat4d StelNavigator::matGalacticToJ2000(matJ2000ToGalactic.transpose());
41
44
 
42
45
////////////////////////////////////////////////////////////////////////////////
43
46
StelNavigator::StelNavigator() : timeSpeed(JD_SECOND), JDay(0.), position(NULL)
44
47
{
45
 
        altAzVisionDirection=Vec3d(1.,0.,0.);
46
 
        earthEquVisionDirection=Vec3d(1.,0.,0.);
47
 
        J2000EquVisionDirection=Vec3d(1.,0.,0.);  // not correct yet...
48
 
        viewingMode = ViewHorizon;  // default
49
48
}
50
49
 
51
50
StelNavigator::~StelNavigator()
54
53
        position=NULL;
55
54
}
56
55
 
57
 
const Planet *StelNavigator::getHomePlanet(void) const
58
 
{
59
 
        return position->getHomePlanet();
60
 
}
61
 
 
62
56
void StelNavigator::init()
63
57
{
64
58
        QSettings* conf = StelApp::getInstance().getSettings();
66
60
 
67
61
        defaultLocationID = conf->value("init_location/location","Paris, Paris, France").toString();
68
62
        position = new StelObserver(StelApp::getInstance().getLocationMgr().locationForSmallString(defaultLocationID));
69
 
        
 
63
 
70
64
        setTimeNow();
71
 
        setAltAzVisionDirection(Vec3f(1,1e-05,0.2));
72
65
        // Compute transform matrices between coordinates systems
73
66
        updateTransformMatrices();
74
 
        updateModelViewMat();
75
 
        QString tmpstr = conf->value("navigation/viewing_mode", "horizon").toString();
76
 
        if (tmpstr=="equator")
77
 
                setViewingMode(StelNavigator::ViewEquator);
78
 
        else
79
 
        {
80
 
                if (tmpstr=="horizon")
81
 
                        setViewingMode(StelNavigator::ViewHorizon);
82
 
                else
83
 
                {
84
 
                        qDebug() << "ERROR : Unknown viewing mode type : " << tmpstr;
85
 
                        Q_ASSERT(0);
86
 
                }
87
 
        }
88
 
        
89
 
        initViewPos = StelUtils::strToVec3f(conf->value("navigation/init_view_pos").toString());
90
 
        setAltAzVisionDirection(initViewPos);
91
 
        
 
67
 
92
68
        // we want to be able to handle the old style preset time, recorded as a double
93
69
        // jday, or as a more human readable string...
94
70
        bool ok;
111
87
        else if (startupTimeMode=="today")
112
88
                setTodayTime(getInitTodayTime());
113
89
 
114
 
        // we previously set the time to "now" already, so we don't need to 
 
90
        // we previously set the time to "now" already, so we don't need to
115
91
        // explicitly do it if the startupTimeMode=="now".
116
92
}
117
93
 
124
100
        Q_ASSERT(conf);
125
101
        conf->setValue("init_location/location", id);
126
102
}
127
 
        
 
103
 
128
104
//! Set stellarium time to current real world time
129
105
void StelNavigator::setTimeNow()
130
106
{
168
144
 
169
145
void StelNavigator::addSiderealDays(double d)
170
146
{
171
 
        const Planet* home = position->getHomePlanet();
 
147
        const PlanetP& home = position->getHomePlanet();
172
148
        if (home->getEnglishName() != "Solar System StelObserver")
173
149
                d *= home->getSiderealDay();
174
150
        setJDay(getJDay() + d);
180
156
        Q_ASSERT(objmgr);
181
157
        if (objmgr->getWasSelected())
182
158
        {
183
 
                Planet* pl = dynamic_cast<Planet*>(objmgr->getSelectedObject()[0].get());
 
159
                Planet* pl = dynamic_cast<Planet*>(objmgr->getSelectedObject()[0].data());
184
160
                if (pl)
185
161
                {
186
162
                        // We need to move to the selected planet. Try to generate a location from the current one
211
187
                SpaceShipObserver* newObs = new SpaceShipObserver(getCurrentLocation(), target, d);
212
188
                delete position;
213
189
                position = newObs;
 
190
                newObs->update(0);
214
191
        }
215
192
        else
216
193
        {
217
194
                delete position;
218
195
                position = new StelObserver(target);
219
196
        }
 
197
        emit(locationChanged(target));
220
198
}
221
199
 
222
200
// Get the sideral time shifted by the observer longitude
225
203
        return (position->getHomePlanet()->getSiderealTime(JDay)+position->getCurrentLocation().longitude)*M_PI/180.;
226
204
}
227
205
 
228
 
void StelNavigator::setInitViewDirectionToCurrent(void)
 
206
//! Get the duration of a sideral day for the current observer in day.
 
207
double StelNavigator::getLocalSideralDayLength() const
229
208
{
230
 
        initViewPos = altAzVisionDirection;
231
 
        QString dirStr = QString("%1,%2,%3").arg(altAzVisionDirection[0]).arg(altAzVisionDirection[1]).arg(altAzVisionDirection[2]);
232
 
        StelApp::getInstance().getSettings()->setValue("navigation/init_view_pos", dirStr);
 
209
        return position->getHomePlanet()->getSiderealDay();
233
210
}
234
211
 
235
212
//! Increase the time speed
253
230
        else if (s>0. && s<=JD_SECOND) s=0.;
254
231
        setTimeRate(s);
255
232
}
256
 
        
257
 
////////////////////////////////////////////////////////////////////////////////
258
 
void StelNavigator::setAltAzVisionDirection(const Vec3d& _pos)
259
 
{
260
 
        altAzVisionDirection = _pos;
261
 
        earthEquVisionDirection=altAzToEquinoxEqu(altAzVisionDirection);
262
 
        J2000EquVisionDirection = matEquinoxEquToJ2000*earthEquVisionDirection;
263
 
        updateModelViewMat();
264
 
}
265
 
 
266
 
////////////////////////////////////////////////////////////////////////////////
267
 
void StelNavigator::setEquinoxEquVisionDirection(const Vec3d& _pos)
268
 
{
269
 
        earthEquVisionDirection = _pos;
270
 
        J2000EquVisionDirection = matEquinoxEquToJ2000*earthEquVisionDirection;
271
 
        altAzVisionDirection = equinoxEquToAltAz(earthEquVisionDirection);
272
 
        updateModelViewMat();
273
 
}
274
 
 
275
 
////////////////////////////////////////////////////////////////////////////////
276
 
void StelNavigator::setJ2000EquVisionDirection(const Vec3d& _pos)
277
 
{
278
 
        J2000EquVisionDirection = _pos;
279
 
        earthEquVisionDirection = matJ2000ToEquinoxEqu*J2000EquVisionDirection;
280
 
        altAzVisionDirection = equinoxEquToAltAz(earthEquVisionDirection);
281
 
        updateModelViewMat();
 
233
 
 
234
void StelNavigator::increaseTimeSpeedLess()
 
235
{
 
236
        double s = getTimeRate();
 
237
        if (s>=JD_SECOND) s*=2.;
 
238
        else if (s<-JD_SECOND) s/=2.;
 
239
        else if (s>=0. && s<JD_SECOND) s=JD_SECOND;
 
240
        else if (s>=-JD_SECOND && s<0.) s=0.;
 
241
        setTimeRate(s);
 
242
}
 
243
 
 
244
void StelNavigator::decreaseTimeSpeedLess()
 
245
{
 
246
        double s = getTimeRate();
 
247
        if (s>JD_SECOND) s/=2.;
 
248
        else if (s<=-JD_SECOND) s*=2.;
 
249
        else if (s>-JD_SECOND && s<=0.) s=-JD_SECOND;
 
250
        else if (s>0. && s<=JD_SECOND) s=0.;
 
251
        setTimeRate(s);
 
252
}
 
253
 
 
254
////////////////////////////////////////////////////////////////////////////////
 
255
void StelNavigator::lookAtJ2000(const Vec3d& pos, const Vec3d& aup)
 
256
{
 
257
        Vec3d f(j2000ToAltAz(pos));
 
258
        Vec3d up(j2000ToAltAz(aup));
 
259
        f.normalize();
 
260
        up.normalize();
 
261
 
 
262
        // Update the model view matrix
 
263
        Vec3d s(f^up);  // y vector
 
264
        s.normalize();
 
265
        Vec3d u(s^f);   // Up vector in AltAz coordinates
 
266
        u.normalize();
 
267
        matAltAzModelView.set(s[0],u[0],-f[0],0.,
 
268
                                                 s[1],u[1],-f[1],0.,
 
269
                                                 s[2],u[2],-f[2],0.,
 
270
                                                 0.,0.,0.,1.);
282
271
}
283
272
 
284
273
////////////////////////////////////////////////////////////////////////////////
290
279
        // Fix time limits to -100000 to +100000 to prevent bugs
291
280
        if (JDay>38245309.499988) JDay = 38245309.499988;
292
281
        if (JDay<-34803211.500012) JDay = -34803211.500012;
293
 
        
 
282
 
294
283
        if (position->isObserverLifeOver())
295
284
        {
296
285
                // Unselect if the new home planet is the previously selected object
297
286
                StelObjectMgr* objmgr = GETSTELMODULE(StelObjectMgr);
298
287
                Q_ASSERT(objmgr);
299
 
                if (objmgr->getWasSelected() && objmgr->getSelectedObject()[0].get()==position->getHomePlanet())
 
288
                if (objmgr->getWasSelected() && objmgr->getSelectedObject()[0].data()==position->getHomePlanet())
300
289
                {
301
290
                        objmgr->unSelect();
302
291
                }
305
294
                position = newObs;
306
295
        }
307
296
        position->update(deltaTime);
 
297
 
 
298
        // Position of sun and all the satellites (ie planets)
 
299
        SolarSystem* solsystem = (SolarSystem*)StelApp::getInstance().getModuleMgr().getModule("SolarSystem");
 
300
        solsystem->computePositions(getJDay(), position->getHomePlanet()->getHeliocentricEclipticPos());
308
301
}
309
302
 
310
303
////////////////////////////////////////////////////////////////////////////////
317
310
        matEquinoxEquToJ2000 = matVsop87ToJ2000 * position->getRotEquatorialToVsop87();
318
311
        matJ2000ToEquinoxEqu = matEquinoxEquToJ2000.transpose();
319
312
        matJ2000ToAltAz = matEquinoxEquToAltAz*matJ2000ToEquinoxEqu;
320
 
        
 
313
 
321
314
        matHeliocentricEclipticToEquinoxEqu = matJ2000ToEquinoxEqu * matVsop87ToJ2000 * Mat4d::translation(-position->getCenterVsop87Pos());
322
315
 
323
316
        // These two next have to take into account the position of the observer on the earth
324
317
        Mat4d tmp = matJ2000ToVsop87 * matEquinoxEquToJ2000 * matAltAzToEquinoxEqu;
325
318
 
326
319
        matAltAzToHeliocentricEcliptic =  Mat4d::translation(position->getCenterVsop87Pos()) * tmp *
327
 
                              Mat4d::translation(Vec3d(0.,0., position->getDistanceFromCenter()));
 
320
                                                  Mat4d::translation(Vec3d(0.,0., position->getDistanceFromCenter()));
328
321
 
329
322
        matHeliocentricEclipticToAltAz =  Mat4d::translation(Vec3d(0.,0.,-position->getDistanceFromCenter())) * tmp.transpose() *
330
 
                              Mat4d::translation(-position->getCenterVsop87Pos());
 
323
                                                  Mat4d::translation(-position->getCenterVsop87Pos());
331
324
}
332
325
 
333
326
void StelNavigator::setStartupTimeMode(const QString& s)
336
329
}
337
330
 
338
331
////////////////////////////////////////////////////////////////////////////////
339
 
// Update the modelview matrices
340
 
void StelNavigator::updateModelViewMat(void)
341
 
{
342
 
        Vec3d f;
343
 
 
344
 
        if( viewingMode == ViewEquator)
345
 
        {
346
 
                // view will use equatorial coordinates, so that north is always up
347
 
                f = earthEquVisionDirection;
348
 
        }
349
 
        else
350
 
        {
351
 
                // view will correct for horizon (always down)
352
 
                f = altAzVisionDirection;
353
 
        }
354
 
 
355
 
        f.normalize();
356
 
        Vec3d s(f[1],-f[0],0.);
357
 
 
358
 
        if( viewingMode == ViewEquator)
359
 
        {
360
 
                // convert everything back to local coord
361
 
                f = altAzVisionDirection;
362
 
                f.normalize();
363
 
                s = equinoxEquToAltAz( s );
364
 
        }
365
 
 
366
 
        Vec3d u(s^f);
367
 
        s.normalize();
368
 
        u.normalize();
369
 
 
370
 
        matAltAzModelView.set(s[0],u[0],-f[0],0.,
371
 
                             s[1],u[1],-f[1],0.,
372
 
                             s[2],u[2],-f[2],0.,
373
 
                             0.,0.,0.,1.);
374
 
}
375
 
 
376
 
 
377
 
////////////////////////////////////////////////////////////////////////////////
378
332
// Return the observer heliocentric position
379
333
Vec3d StelNavigator::getObserverHeliocentricEclipticPos(void) const
380
334
{
381
 
        static const Vec3d v(0);
382
 
        return matAltAzToHeliocentricEcliptic*v;
 
335
        return Vec3d(matAltAzToHeliocentricEcliptic[12], matAltAzToHeliocentricEcliptic[13], matAltAzToHeliocentricEcliptic[14]);
383
336
}
384
337
 
385
338
void StelNavigator::setPresetSkyTime(QDateTime dt)
386
339
{
387
340
        setPresetSkyTime(StelUtils::qDateTimeToJd(dt));
388
341
}
389
 
 
390
 
////////////////////////////////////////////////////////////////////////////////
391
 
// Set type of viewing mode (align with horizon or equatorial coordinates)
392
 
void StelNavigator::setViewingMode(ViewingModeType viewMode)
393
 
{
394
 
        viewingMode = viewMode;
395
 
 
396
 
        // TODO: include some nice smoothing function trigger here to rotate between
397
 
        // the two modes
398
 
}