1 /*
2  * Stellarium
3  * Copyright (C) 2010 Bogdan Marinov
4  * Copyright (C) 2014 Georg Zotti (orbit fix, tails, speedup)
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 COMET_HPP
22 #define COMET_HPP
23 
24 #include "Planet.hpp"
25 
26 /*! \class Comet
27 	\author Bogdan Marinov, Georg Zotti (orbit computation enhancements, tails)
28 
29 	Some of the code in this class is re-used from the parent Planet class.
30 	\todo Implement better comet rendering (star-like objects, no physical body).
31 	\todo (Long-term) Photo realistic comet rendering, see https://blueprints.launchpad.net/stellarium/+spec/realistic-comet-rendering
32 	2013-12: GZ: New algorithms for position computation following Paul Heafner: Fundamental Ephemeris Computations (Willmann-Bell 1999).
33 	2014-01: GZ: Parabolic tails appropriately scaled/rotated. Much is currently empirical, leaving room for physics-based improvements.
34 	2014-08: GZ: speedup in case hundreds of comets are loaded.
35 	2014-11: GZ: tail extinction, better brightness balance.
36 	2017-03: GZ: added fields to infoMap
37   */
38 class Comet : public Planet
39 {
40 public:
41 	friend class SolarSystem;               // Solar System initializes static constants.
42 	Comet(const QString& englishName,
43 	      double equatorialRadius,
44 	      double oblateness,
45 	      Vec3f halocolor,
46 	      float albedo,
47 	      float roughness,
48 	      float outgas_intensity,
49 	      float outgas_falloff,
50 	      const QString& texMapName,
51 	      const QString& objModelName,
52 	      posFuncType _coordFunc,
53 	      KeplerOrbit* orbitPtr,
54 	      OsculatingFunctType *osculatingFunc,
55 	      bool closeOrbit,
56 	      bool hidden,
57 	      const QString &pTypeStr,
58 	      float dustTailWidthFact=1.5f,
59 	      float dustTailLengthFact=0.4f,
60 	      float dustTailBrightnessFact=1.5f
61 	);
62 
63 	virtual ~Comet() Q_DECL_OVERRIDE;
64 
65 	//! In addition to Planet::getInfoMap(), Comets provides estimates for
66 	//! - tail-length-km
67 	//! - coma-diameter-km
68 	//! using the formula from Guide found by the GSoC2012 initiative at http://www.projectpluto.com/update7b.htm#comet_tail_formula
69 	virtual QVariantMap getInfoMap(const StelCore *core) const Q_DECL_OVERRIDE;
70 	//The Comet class inherits the "Planet" type because the SolarSystem class
71 	//was not designed to handle different types of objects.
72 	//virtual QString getType() const {return "Comet";}
73 	//! \todo Find better sources for the g,k system
74 	virtual float getVMagnitude(const StelCore* core) const Q_DECL_OVERRIDE;
75 	//! sets the nameI18 property with the appropriate translation.
76 	//! Function overriden to handle the problem with name conflicts.
77 	virtual void translateName(const StelTranslator& trans) Q_DECL_OVERRIDE;
getEnglishName(void) const78 	virtual QString getEnglishName(void) const Q_DECL_OVERRIDE {return englishName;}
getNameI18n(void) const79 	virtual QString getNameI18n(void) const Q_DECL_OVERRIDE {return nameI18;}
80 
81 	//! \brief sets absolute magnitude and slope parameter.
82 	//! These are the parameters in the IAU's two-parameter magnitude system
83 	//! for comets. They are used to calculate the apparent magnitude at
84 	//! different distances from the Sun. They are not used in the same way
85 	//! as the same parameters in MinorPlanet.
86 	void setAbsoluteMagnitudeAndSlope(const float magnitude, const float slope);
87 
88 	//! get sidereal period for comet, days, or returns 0 if not possible (parabolic, hyperbolic orbit)
89 	virtual double getSiderealPeriod() const Q_DECL_OVERRIDE;
90 
91 	//! re-implementation of Planet's draw()
92 	virtual void draw(StelCore* core, float maxMagLabels, const QFont& planetNameFont) Q_DECL_OVERRIDE;
93 
94 	// re-implementation of Planet's update() to prepare tails (extinction etc). @param deltaTime: ms (since last call)
95 	virtual void update(int deltaTime) Q_DECL_OVERRIDE;
96 
97 protected:
98 	// components for Planet::getInfoString() that are overridden here:
99 	virtual QString getInfoStringAbsoluteMagnitude(const StelCore *core, const InfoStringGroup& flags) const Q_DECL_OVERRIDE;
100 	//! Any flag=Size information to be displayed
101 	virtual QString getInfoStringSize(const StelCore *core, const InfoStringGroup& flags) const Q_DECL_OVERRIDE;
102 	//! Any flag=Extra information to be displayed at the end
103 	virtual QString getInfoStringExtra(const StelCore *core, const InfoStringGroup& flags) const Q_DECL_OVERRIDE;
104 
105 private:
106 	//! @returns estimates for (Coma diameter [AU], gas tail length [AU]).
107 	//! Using the formula from Guide found by the GSoC2012 initiative at http://www.projectpluto.com/update7b.htm#comet_tail_formula
108 	Vec2f getComaDiameterAndTailLengthAU() const;
109 	void drawTail(StelCore* core, StelProjector::ModelViewTranformP transfo, bool gas);
110 	void drawComa(StelCore* core, StelProjector::ModelViewTranformP transfo);
111 
112 	//! compute a coma, faked as simple disk to be tilted towards the observer.
113 	//! @param diameter Diameter of Coma [AU]
114 	void computeComa(const float diameter);
115 
116 	//! compute tail shape. This is a paraboloid shell with triangular mesh (indexed vertices).
117 	//! Try to call not for every frame...
118 	//! To be more efficient, the arrays are only computed if they are empty.
119 	//! @param parameter the parameter p of the parabola. z=r²/2p (r²=x²+y²)
120 	//! @param lengthfactor The parabola will be lengthened. This shifts the visible focus, so it must be here.
121 	//! @param vertexArr vertex array, collects x0, y0, z0, x1, y1, z1, ...
122 	//! @param texCoordArr texture coordinates u0, v0, u1, v1, ...
123 	//! @param colorArr vertex colors (if not textured) r0, g0, b0, r1, g1, b1, ...
124 	//! @param indices into the former arrays (zero-starting), triplets forming triangles: t0,0, t0,1, t0,2, t1,0, t1,1, t1,2, ...
125 	//! @param xOffset for the dust tail, this may introduce a bend. Units are x per sqrt(z).
126 	void computeParabola(const float parameter, const float topradius, const float zshift, QVector<Vec3d>& vertexArr, QVector<Vec2f>& texCoordArr, QVector<unsigned short>& indices, const float xOffset=0.0f);
127 
128 	float slopeParameter;
129 	bool isCometFragment;
130 	bool nameIsProvisionalDesignation;
131 
132 	//GZ Tail additions
133 	Vec2f tailFactors; // result of latest call to getComaDiameterAndTailLengthAU(); Results cached here for infostring. [0]=Coma diameter, [1] gas tail length.
134 	bool tailActive;		//! true if there is a tail long enough to be worth drawing. Drawing tails is quite costly.
135 	bool tailBright;		//! true if tail is bright enough to draw.
136 	double deltaJDEtail;            //! like deltaJDE, but time difference between tail geometry updates.
137 	double lastJDEtail;             //! like lastJDE, but time of last tail geometry update.
138 	Mat4d gasTailRot;		//! rotation matrix for gas tail parabola
139 	Mat4d dustTailRot;		//! rotation matrix for the skewed dust tail parabola
140 	float dustTailWidthFactor;      //!< empirical individual broadening of the dust tail end, compared to the gas tail end. Actually, dust tail width=2*comaWidth*dustTailWidthFactor. Default 1.5
141 	float dustTailLengthFactor;     //!< empirical individual length of dust tail relative to gas tail. Taken from ssystem.ini, typical value 0.3..0.5, default 0.4
142 	float dustTailBrightnessFactor; //!< empirical individual brightness of dust tail relative to gas tail. Taken from ssystem.ini, default 1.5
143 	QVector<Vec3d> comaVertexArr;
144 	QVector<Vec2f> comaTexCoordArr; //  --> 2014-08: could also be declared static, but it is filled by StelPainter...
145 
146 	float intensityFovScale; // like for constellations: reduce brightness when zooming in.
147 	float intensityMinFov;
148 	float intensityMaxFov;
149 
150 
151 	// These are static to avoid having index arrays for each comet when all are equal.
152 	static bool createTailIndices;
153 	static bool createTailTextureCoords;
154 
155 	QVector<Vec3d> gastailVertexArr;  // computed frequently, describes parabolic shape (along z axis) of gas tail.
156 	QVector<Vec3d> dusttailVertexArr; // computed frequently, describes parabolic shape (along z axis) of dust tail.
157 	QVector<Vec3f> gastailColorArr;    // NEW computed for every 5 mins, modulates gas tail brightness for extinction
158 	QVector<Vec3f> dusttailColorArr;   // NEW computed for every 5 mins, modulates dust tail brightness for extinction
159 	static QVector<Vec2f> tailTexCoordArr; // computed only once for all comets!
160 	static QVector<unsigned short> tailIndices; // computed only once for all comets!
161 	static StelTextureSP comaTexture;
162 	static StelTextureSP tailTexture;      // it seems not really necessary to have different textures. gas tail is just painted blue.
163 };
164 
165 #endif //COMET_HPP
166