Stellarium 0.15.0
Planet.hpp
1 /*
2  * Stellarium
3  * Copyright (C) 2002 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  */
19 
20 #ifndef _PLANET_HPP_
21 #define _PLANET_HPP_
22 
23 #include "StelObject.hpp"
24 #include "StelProjector.hpp"
25 #include "VecMath.hpp"
26 #include "StelFader.hpp"
27 #include "StelTextureTypes.hpp"
28 #include "StelProjectorType.hpp"
29 
30 #include <QString>
31 
32 // The callback type for the external position computation function
33 // The last variable is the userData pointer.
34 typedef void (*posFuncType)(double, double*, void*);
35 
36 typedef void (OsculatingFunctType)(double jde0,double jde,double xyz[3]);
37 
38 // epoch J2000: 12 UT on 1 Jan 2000
39 #define J2000 2451545.0
40 #define ORBIT_SEGMENTS 360
41 
42 class StelFont;
43 class StelPainter;
44 class StelTranslator;
45 class QOpenGLShaderProgram;
46 
47 // Class used to store rotational elements, i.e. axis orientation for the planetary body.
49 {
50 public:
51  RotationElements(void) : period(1.), offset(0.), epoch(J2000), obliquity(0.), ascendingNode(0.), precessionRate(0.), siderealPeriod(0.) {}
52  float period; // (sidereal) rotation period [earth days]
53  float offset; // rotation at epoch [degrees]
54  double epoch; // JDE (JD TT) of epoch for these elements
55  float obliquity; // tilt of rotation axis w.r.t. ecliptic [radians]
56  float ascendingNode; // long. of ascending node of equator on the ecliptic [radians]
57  float precessionRate; // rate of precession of rotation axis in [rads/JulianCentury(36525d)]
58  double siderealPeriod; // sidereal period (Planet year in earth days) [earth days]
59 };
60 
61 // Class to manage rings for planets like saturn
62 class Ring
63 {
64 public:
65  Ring(float radiusMin, float radiusMax,const QString &texname);
66  double getSize(void) const {return radiusMax;}
67  const float radiusMin;
68  const float radiusMax;
69  StelTextureSP tex;
70 };
71 
72 
73 class Planet : public StelObject
74 {
75 public:
76  friend class SolarSystem;
77 
78  Q_ENUMS(PlanetType)
79  Q_ENUMS(ApparentMagnitudeAlgorithm)
81  // GZ: Until 0.13 QStrings were used for types.
82  // GZ: Enums are slightly faster than string comparisons in time-critical comparisons.
83  // GZ: If other types are introduced, add here and the string in init().
85  {
86  isStar, // ssystem.ini: type="star"
87  isPlanet, // ssystem.ini: type="planet"
88  isMoon, // ssystem.ini: type="moon"
89  isAsteroid, // ssystem.ini: type="asteroid"
90  isPlutino, // ssystem.ini: type="plutino"
91  isComet, // ssystem.ini: type="comet"
92  isDwarfPlanet, // ssystem.ini: type="dwarf planet"
93  isCubewano, // ssystem.ini: type="cubewano"
94  isSDO, // ssystem.ini: type="sdo"
95  isOCO, // ssystem.ini: type="oco"
96  isUNDEFINED // ssystem.ini: type=<anything else>
97  };
98 
99  enum ApparentMagnitudeAlgorithm
100  {
101  Planesas, // Algorithm provided by Pere Planesas (Observatorio Astronomico Nacional)
102  Mueller, // G. Mueller, based on visual observations 1877-91. [Expl.Suppl.1961]
103  Harris, // Astronomical Almanac 1984 and later. These give V (instrumental) magnitudes (D.L. Harris)
104  UndefinedAlgorithm,
105  Generic // Visual magnitude based on phase angle and albedo
106  };
107 
108  Planet(const QString& englishName,
109  int flagLighting,
110  double radius,
111  double oblateness,
112  Vec3f halocolor,
113  float albedo,
114  const QString& texMapName,
115  const QString& normalMapName,
116  posFuncType _coordFunc,
117  void* userDataPtr,
118  OsculatingFunctType *osculatingFunc,
119  bool closeOrbit,
120  bool hidden,
121  bool hasAtmosphere,
122  bool hasHalo,
123  const QString &pTypeStr);
124 
125  virtual ~Planet();
126 
128  // Currently ensured by SolarSystem::init()
129  static void init();
130 
132  // Methods inherited from StelObject
146  virtual QString getInfoString(const StelCore *core, const InfoStringGroup& flags) const;
147  virtual double getCloseViewFov(const StelCore* core) const;
148  virtual double getSatellitesFov(const StelCore* core) const;
149  virtual double getParentSatellitesFov(const StelCore* core) const;
150  virtual float getVMagnitude(const StelCore* core) const;
151  virtual float getSelectPriority(const StelCore* core) const;
152  virtual Vec3f getInfoColor(void) const;
153  virtual QString getType(void) const {return "Planet";}
154  virtual Vec3d getJ2000EquatorialPos(const StelCore *core) const;
155  virtual QString getEnglishName(void) const;
156  virtual QString getNameI18n(void) const;
157  virtual double getAngularSize(const StelCore* core) const;
158  virtual bool hasAtmosphere(void) {return atmosphere;}
159  virtual bool hasHalo(void) {return halo;}
160 
162  // Methods of SolarSystem object
164  virtual void translateName(const StelTranslator &trans);
165 
166  // Draw the Planet
167  // GZ Made that virtual to allow comets having their own draw().
168  virtual void draw(StelCore* core, float maxMagLabels, const QFont& planetNameFont);
169 
171  // Methods specific to Planet
174  double getRadius(void) const {return radius;}
176  double getOneMinusOblateness(void) const {return oneMinusOblateness;}
178  double getSiderealDay(void) const {return re.period;}
180  // must be virtual for Comets.
181  virtual double getSiderealPeriod(void) const { return re.siderealPeriod; }
183  double getMeanSolarDay(void) const;
184 
185  const QString& getTextMapName() const {return texMapName;}
186  const QString getPlanetTypeString() const {return pTypeMap.value(pType);}
187  PlanetType getPlanetType() const {return pType;}
188 
189  void setNativeName(QString planet) { nativeName = planet; }
190 
191  ApparentMagnitudeAlgorithm getApparentMagnitudeAlgorithm() const { return vMagAlgorithm; }
192  const QString getApparentMagnitudeAlgorithmString() const { return vMagAlgorithmMap.value(vMagAlgorithm); }
193  void setApparentMagnitudeAlgorithm(QString algorithm);
194 
198  double getSiderealTime(double JD, double JDE) const;
199  Mat4d getRotEquatorialToVsop87(void) const;
200  void setRotEquatorialToVsop87(const Mat4d &m);
201 
202  const RotationElements &getRotationElements(void) const {return re;}
203 
204  // Compute the position in the parent Planet coordinate system
205  void computePositionWithoutOrbits(const double dateJDE);
206  void computePosition(const double dateJDE);
207 
208  // Compute the transformation matrix from the local Planet coordinate to the parent Planet coordinate.
209  // This requires both flavours of JD in cases involving Earth.
210  void computeTransMatrix(double JD, double JDE);
211 
212  // Get the phase angle (rad) for an observer at pos obsPos in heliocentric coordinates (in AU)
213  double getPhaseAngle(const Vec3d& obsPos) const;
214  // Get the elongation angle (rad) for an observer at pos obsPos in heliocentric coordinates (in AU)
215  double getElongation(const Vec3d& obsPos) const;
216  // Get the angular size of the spheroid of the planet (i.e. without the rings)
217  double getSpheroidAngularSize(const StelCore* core) const;
218  // Get the planet phase for an observer at pos obsPos in heliocentric coordinates (in AU)
219  float getPhase(const Vec3d& obsPos) const;
220 
221  // Set the orbital elements
222  void setRotationElements(float _period, float _offset, double _epoch,
223  float _obliquity, float _ascendingNode,
224  float _precessionRate, double _siderealPeriod);
225  double getRotAscendingnode(void) const {return re.ascendingNode;}
226  // return angle between axis and normal of ecliptic plane (or, for a moon, equatorial/reference plane defined by parent).
227  // TODO: decide if this is always angle between axis and J2000 ecliptic, or should be axis//current ecliptic!
228  double getRotObliquity(double JDE) const;
229 
231  Vec3d getEclipticPos() const;
232 
233  // Return the heliocentric ecliptical position
234  Vec3d getHeliocentricEclipticPos() const {return getHeliocentricPos(eclipticPos);}
235 
236  // Return the heliocentric transformation for local coordinate
237  Vec3d getHeliocentricPos(Vec3d) const;
238  void setHeliocentricEclipticPos(const Vec3d &pos);
239 
240  // Compute the distance to the given position in heliocentric coordinate (in AU)
241  double computeDistance(const Vec3d& obsHelioPos);
242  double getDistance(void) const {return distance;}
243 
244  void setRings(Ring* r) {rings = r;}
245 
246  void setSphereScale(float s) {sphereScale = s;}
247  float getSphereScale(void) const {return sphereScale;}
248 
249  const QSharedPointer<Planet> getParent(void) const {return parent;}
250 
251  static void setLabelColor(const Vec3f& lc) {labelColor = lc;}
252  static const Vec3f& getLabelColor(void) {return labelColor;}
253 
254  // update displayed elements. @param deltaTime: ms (since last call)
255  virtual void update(int deltaTime);
256 
257  void setFlagHints(bool b){hintFader = b;}
258  bool getFlagHints(void) const {return hintFader;}
259 
260  void setFlagLabels(bool b){flagLabels = b;}
261  bool getFlagLabels(void) const {return flagLabels;}
262 
263  bool flagNativeName;
264  void setFlagNativeName(bool b) { flagNativeName = b; }
265  bool getFlagNativeName(void) { return flagNativeName; }
266 
267  bool flagTranslatedName;
268  void setFlagTranslatedName(bool b) { flagTranslatedName = b; }
269  bool getFlagTranslatedName(void) { return flagTranslatedName; }
270 
272  // DEPRECATED
274  // Should move to an OrbitPath class which works on a SolarSystemObject, not a Planet
275  void setFlagOrbits(bool b){orbitFader = b;}
276  bool getFlagOrbits(void) const {return orbitFader;}
277  LinearFader orbitFader;
278  // draw orbital path of Planet
279  void drawOrbit(const StelCore*);
280  Vec3d orbit[ORBIT_SEGMENTS+1]; // store heliocentric coordinates for drawing the orbit
281  Vec3d orbitP[ORBIT_SEGMENTS+1]; // store local coordinate for orbit
282  double lastOrbitJDE;
283  double deltaJDE; // time difference between positional updates.
284  double deltaOrbitJDE;
285  bool orbitCached; // whether orbit calculations are cached for drawing orbit yet
286  bool closeOrbit; // whether to connect the beginning of the orbit line to
287  // the end: good for elliptical orbits, bad for parabolic
288  // and hyperbolic orbits
289 
290  static Vec3f orbitColor;
291  static void setOrbitColor(const Vec3f& oc) {orbitColor = oc;}
292  static const Vec3f& getOrbitColor() {return orbitColor;}
293 
294  static bool permanentDrawingOrbits;
295 
297  QVector<const Planet*> getCandidatesForShadow() const;
298 
299 protected:
300  static StelTextureSP texEarthShadow; // for lunar eclipses
301 
302  void computeModelMatrix(Mat4d &result) const;
303 
304  // Return the information string "ready to print" :)
305  QString getSkyLabel(const StelCore* core) const;
306 
307  // Draw the 3d model. Call the proper functions if there are rings etc..
308  void draw3dModel(StelCore* core, StelProjector::ModelViewTranformP transfo, float screenSz, bool drawOnlyRing=false);
309 
310  // Draw the 3D sphere
311  void drawSphere(StelPainter* painter, float screenSz, bool drawOnlyRing=false);
312 
313  // Draw the circle and name of the Planet
314  void drawHints(const StelCore* core, const QFont& planetNameFont);
315 
316  QString englishName; // english planet name
317  QString nameI18; // International translated name
318  QString nativeName; // Can be used in a skyculture
319  QString texMapName; // Texture file path
320  QString normalMapName; // Texture file path
321  int flagLighting; // Set whether light computation has to be proceed
322  RotationElements re; // Rotation param
323  double radius; // Planet radius in AU
324  double oneMinusOblateness; // (polar radius)/(equatorial radius)
325  Vec3d eclipticPos; // Position in AU in the rectangular ecliptic coordinate system
326  // centered on the parent Planet
327  Vec3d screenPos; // Used to store temporarily the 2D position on screen
328  Vec3d previousScreenPos; // The position of this planet in the previous frame.
329  Vec3f haloColor; // exclusively used for drawing the planet halo
330 
331  float albedo; // Planet albedo. Used for magnitude computation (but formula dubious!)
332  Mat4d rotLocalToParent; // GZ2015: was undocumented.
333  // Apparently this is the axis orientation with respect to the parent body. For planets, this is axis orientation w.r.t. VSOP87A/J2000 ecliptical system.
334  float axisRotation; // Rotation angle of the Planet on its axis.
335  // For Earth, this should be Greenwich Mean Sidereal Time GMST.
336  StelTextureSP texMap; // Planet map texture
337  StelTextureSP normalMap; // Planet normal map texture
338 
339  Ring* rings; // Planet rings
340  double distance; // Temporary variable used to store the distance to a given point
341  // it is used for sorting while drawing
342  float sphereScale; // Artificial scaling for better viewing
343  double lastJDE; // caches JDE of last positional computation
344  // The callback for the calculation of the equatorial rect heliocentric position at time JDE.
345  posFuncType coordFunc;
346  void* userDataPtr; // this is always used with an Orbit object.
347 
348  OsculatingFunctType *const osculatingFunc;
349  QSharedPointer<Planet> parent; // Planet parent i.e. sun for earth
350  QList<QSharedPointer<Planet> > satellites; // satellites of the Planet
351  LinearFader hintFader;
352  LinearFader labelsFader; // Store the current state of the label for this planet
353  bool flagLabels; // Define whether labels should be displayed
354  bool hidden; // useful for fake planets used as observation positions - not drawn or labeled
355  bool atmosphere; // Does the planet have an atmosphere?
356  bool halo; // Does the planet have a halo?
357  PlanetType pType; // Type of body
358 
359  ApparentMagnitudeAlgorithm vMagAlgorithm;
360 
361  static Vec3f labelColor;
362  static StelTextureSP hintCircleTex;
363  static QMap<PlanetType, QString> pTypeMap; // Maps fast type to english name.
364  static QMap<ApparentMagnitudeAlgorithm, QString> vMagAlgorithmMap;
365 
366  static bool flagCustomGrsSettings; // Is enabled usage of custom settings for calculation of position of Great Red Spot?
367  static double customGrsJD; // Initial JD for calculation of position of Great Red Spot
368  static int customGrsLongitude; // Longitude of Great Red Spot (System II, degrees)
369  static double customGrsDrift; // Annual drift of Great Red Spot position (degrees)
370 
371  // Shader-related variables
373  int projectionMatrix;
374  int texCoord;
375  int unprojectedVertex;
376  int vertex;
377  int texture;
378  int lightDirection;
379  int eyeDirection;
380  int diffuseLight;
381  int ambientLight;
382  int shadowCount;
383  int shadowData;
384  int sunInfo;
385  int skyBrightness;
386 
387  void initLocations(QOpenGLShaderProgram*);
388  };
389  static PlanetShaderVars planetShaderVars;
390  static QOpenGLShaderProgram* planetShaderProgram;
391 
392  // Shader-related variables
394  // Rings-specific variables
395  int isRing;
396  int ring;
397  int outerRadius;
398  int innerRadius;
399  int ringS;
400  };
401  static RingPlanetShaderVars ringPlanetShaderVars;
402  static QOpenGLShaderProgram* ringPlanetShaderProgram;
403 
405  // Moon-specific variables
406  int earthShadow;
407  int normalMap;
408  };
409  static MoonShaderVars moonShaderVars;
410  static QOpenGLShaderProgram* moonShaderProgram;
411 
412  static void initShader();
413  static void deinitShader();
414 };
415 
416 #endif // _PLANET_HPP_
417 
QVector< const Planet * > getCandidatesForShadow() const
Return the list of planets which project some shadow on this planet.
virtual void update(double deltaTime)
Update time-varying components.
void setFlagOrbits(bool b)
Set flag which determines if planet orbits are drawn or hidden.
double getMeanSolarDay(void) const
Get duration of mean solar day.
virtual double getSiderealPeriod(void) const
Get duration of sidereal year.
Definition: Planet.hpp:181
Class used to translate strings to any language.
Implementation of StelFader which implements a linear transition.
Definition: StelFader.hpp:77
The base abstract class for sky objects used in Stellarium like Stars, Planets, Constellations etc...
Definition: StelObject.hpp:36
virtual QString getNameI18n(void) const
Return translated object's name.
Define the StelTextureSP type.
PlanetType
numeric typecodes for the type descriptions in ssystem.ini
Definition: Planet.hpp:84
virtual double getAngularSize(const StelCore *core) const
Return the angular radius of a circle containing the object as seen from the observer with the circle...
virtual Vec3f getInfoColor(void) const
Get a color used to display info about the object.
Main class for Stellarium core processing.
Definition: StelCore.hpp:48
void setFlagHints(bool b)
Set flag which determines if planet hints are drawn or hidden along labels.
void setFlagLabels(bool b)
Set flag which determines if planet labels are drawn or hidden.
bool getFlagLabels() const
Get the current value of the flag which determines if planet labels are drawn or hidden.
double getRadius(void) const
Get the radius of the planet in AU.
Definition: Planet.hpp:174
virtual QString getEnglishName(void) const
Return object's name in english.
This StelObjectModule derivative is used to model SolarSystem bodies.
Definition: SolarSystem.hpp:47
virtual QString getInfoString(const StelCore *core, const InfoStringGroup &flags) const
Get a string with data about the Planet.
Definition: Planet.hpp:62
virtual double getCloseViewFov(const StelCore *core) const
Return the best FOV in degree to use for a close view of the object.
double getSiderealDay(void) const
Get duration of sidereal day.
Definition: Planet.hpp:178
virtual double getSatellitesFov(const StelCore *core) const
Return the best FOV in degree to use for a global view of the object satellite system (if there are s...
virtual Vec3d getJ2000EquatorialPos(const StelCore *core) const
Get observer-centered equatorial coordinates at equinox J2000.
Provides functions for performing openGL drawing operations.
Definition: StelPainter.hpp:40
virtual void translateName(const StelTranslator &trans)
Translate planet name using the passed translator.
double getSiderealTime(double JD, double JDE) const
Compute the z rotation to use from equatorial to geographic coordinates.
virtual float getVMagnitude(const StelCore *core) const
Return object's apparent V magnitude as seen from observer, without including extinction.
QSharedPointer< ModelViewTranform > ModelViewTranformP
Shared pointer on a ModelViewTranform instance (implement reference counting)
double getOneMinusOblateness(void) const
Get the value (1-f) for oblateness f.
Definition: Planet.hpp:176
bool getFlagOrbits() const
Get the current value of the flag which determines if planet orbits are drawn or hidden.
static void init()
Initializes static vars. Must be called before creating first planet.
Define the StelProjectorP type.
virtual QString getType(void) const
Return object's type. It should be the name of the class.
Definition: Planet.hpp:153
Vec3d getEclipticPos() const
Get the Planet position in the parent Planet ecliptic coordinate in AU.
QSharedPointer< StelTexture > StelTextureSP
Use shared pointer to simplify memory managment.
bool getFlagHints() const
Get the current value of the flag which determines if planet hints are drawn or hidden along labels...
QString getPlanetType(QString planetName) const
Get type for Solar system bodies from scripts.
virtual float getSelectPriority(const StelCore *core) const
Return a priority value which is used to discriminate objects by priority As for magnitudes, the lower is the higher priority.
virtual void draw(StelCore *core)
Draw SolarSystem objects (planets).