1 /*
2  * Stellarium
3  * Copyright (C) 2006 Fabien Chereau
4  * Copyright (C) 2010 Bogdan Marinov (add/remove landscapes feature)
5  * Copyright (C) 2012 Timothy Reaves
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
20  */
21 
22 #ifndef LANDSCAPEMGR_HPP
23 #define LANDSCAPEMGR_HPP
24 
25 #include "StelModule.hpp"
26 #include "StelUtils.hpp"
27 #include "Landscape.hpp"
28 
29 #include <QMap>
30 #include <QStringList>
31 #include <QCache>
32 
33 class Atmosphere;
34 class QSettings;
35 
36 
37 //! @class Cardinals manages the display of cardinal points
38 class Cardinals
39 {
40     Q_GADGET
41 public:
42     enum CompassDirection
43     {
44 	// Cardinals (4-wind compass rose)
45 	dN	=  1,	// north
46 	dS	=  2,	// south
47 	dE	=  3,	// east
48 	dW	=  4,	// west
49 	// Intercardinals (or ordinals) (8-wind compass rose)
50 	dNE	=  5,	// northeast
51 	dSE	=  6,	// southeast
52 	dNW	=  7,	// northwest
53 	dSW	=  8,	// southwest
54 	// Secondary Intercardinals (16-wind compass rose)
55 	dNNE	=  9,	// north-northeast
56 	dENE	= 10,	// east-northeast
57 	dESE	= 11,	// east-southeast
58 	dSSE	= 12,	// south-southeast
59 	dSSW	= 13,	// south-southwest
60 	dWSW	= 14,	// west-southwest
61 	dWNW	= 15,	// west-northwest
62 	dNNW	= 16	// north-northwest
63     };
64     Q_ENUM(CompassDirection)
65 
66     Cardinals();
67     virtual ~Cardinals();
68     void draw(const StelCore* core, double latitude) const;
setColor(const Vec3f & c)69     void setColor(const Vec3f& c) {color = c;}
getColor() const70     Vec3f getColor() const {return color;}
71     void updateI18n();
72     void update(double deltaTime);
73     void setFadeDuration(float duration);
setFlagShowCardinals(bool b)74     void setFlagShowCardinals(bool b) { fader4WCR = b; }
getFlagShowCardinals() const75     bool getFlagShowCardinals() const { return fader4WCR; }
76 
setFlagShow4WCRLabels(bool b)77     void setFlagShow4WCRLabels(bool b) { fader4WCR = b; }
getFlagShow4WCRLabels() const78     bool getFlagShow4WCRLabels() const { return fader4WCR; }
setFlagShow8WCRLabels(bool b)79     void setFlagShow8WCRLabels(bool b) { fader8WCR = b; }
getFlagShow8WCRLabels() const80     bool getFlagShow8WCRLabels() const { return fader8WCR; }
setFlagShow16WCRLabels(bool b)81     void setFlagShow16WCRLabels(bool b) { fader16WCR = b; }
getFlagShow16WCRLabels() const82     bool getFlagShow16WCRLabels() const { return fader16WCR; }
83 private:
84     class StelPropertyMgr* propMgr;
85     QFont font4WCR, font8WCR, font16WCR;
86     Vec3f color;
87     QMap<Cardinals::CompassDirection, Vec3f> rose4winds, rose8winds, rose16winds;
88     QMap<Cardinals::CompassDirection, QString> labels;
89     LinearFader fader4WCR, fader8WCR, fader16WCR;
90     int screenFontSize;
91 };
92 
93 //! @class LandscapeMgr
94 //! Manages all the rendering at the level of the observer's surroundings.
95 //! This includes landscape textures, fog, atmosphere and cardinal points.
96 //! I decided to put all these elements together in a single class because they are
97 //! inherently linked, especially when we start moving the observer in altitude.
98 //! \note
99 //! The Bortle scale index setting was removed from this class, because it was duplicated
100 //! from StelSkyDrawer, complicating code that changes it.
101 //! It is now only in StelSkyDrawer and can be accessed
102 //! with \link StelSkyDrawer::getBortleScaleIndex getBortleScaleIndex \endlink
103 //! and \link StelSkyDrawer::setBortleScaleIndex setBortleScaleIndex \endlink.
104 //! Slots setAtmosphereBortleLightPollution and getAtmosphereBortleLightPollution
105 //! in this class have been removed/made private.
106 //! If script access is desired, use
107 //! \link StelMainScriptAPI::getBortleScaleIndex StelMainScriptAPI::get \endlink/\link StelMainScriptAPI::setBortleScaleIndex setBortleScaleIndex \endlink
108 class LandscapeMgr : public StelModule
109 {
110 	Q_OBJECT
111 	Q_PROPERTY(bool atmosphereDisplayed
112 		   READ getFlagAtmosphere
113 		   WRITE setFlagAtmosphere
114 		   NOTIFY atmosphereDisplayedChanged)
115 	Q_PROPERTY(bool cardinalsPointsDisplayed
116 		   READ getFlagCardinalsPoints
117 		   WRITE setFlagCardinalsPoints
118 		   NOTIFY cardinalsPointsDisplayedChanged)
119 	Q_PROPERTY(bool ordinalsPointsDisplayed
120 		   READ getFlagOrdinalsPoints
121 		   WRITE setFlagOrdinalsPoints
122 		   NOTIFY ordinalsPointsDisplayedChanged)
123 	Q_PROPERTY(bool ordinals16WRPointsDisplayed
124 		   READ getFlagOrdinals16WRPoints
125 		   WRITE setFlagOrdinals16WRPoints
126 		   NOTIFY ordinals16WRPointsDisplayedChanged)
127 	Q_PROPERTY(Vec3f cardinalsPointsColor
128 		   READ getColorCardinalPoints
129 		   WRITE setColorCardinalPoints
130 		   NOTIFY cardinalsPointsColorChanged)
131 	Q_PROPERTY(bool fogDisplayed
132 		   READ getFlagFog
133 		   WRITE setFlagFog
134 		   NOTIFY fogDisplayedChanged)
135 	Q_PROPERTY(bool landscapeDisplayed
136 		   READ getFlagLandscape
137 		   WRITE setFlagLandscape
138 		   NOTIFY landscapeDisplayedChanged)
139 	Q_PROPERTY(bool illuminationDisplayed
140 		   READ getFlagIllumination
141 		   WRITE setFlagIllumination
142 		   NOTIFY illuminationDisplayedChanged)
143 	Q_PROPERTY(bool labelsDisplayed
144 		   READ getFlagLabels
145 		   WRITE setFlagLabels
146 		   NOTIFY labelsDisplayedChanged)
147 	Q_PROPERTY(bool flagPolyLineDisplayedOnly
148 		   READ getFlagPolyLineDisplayed
149 		   WRITE setFlagPolyLineDisplayed
150 		   NOTIFY flagPolyLineDisplayedChanged)
151 	Q_PROPERTY(int polyLineThickness
152 		   READ getPolyLineThickness
153 		   WRITE setPolyLineThickness
154 		   NOTIFY polyLineThicknessChanged)
155 	Q_PROPERTY(bool flagUseLightPollutionFromDatabase
156 		   READ getFlagUseLightPollutionFromDatabase
157 		   WRITE setFlagUseLightPollutionFromDatabase
158 		   NOTIFY flagUseLightPollutionFromDatabaseChanged)
159 	Q_PROPERTY(bool flagLandscapeAutoSelection
160 		   READ getFlagLandscapeAutoSelection
161 		   WRITE setFlagLandscapeAutoSelection
162 		   NOTIFY flagLandscapeAutoSelectionChanged)
163 	Q_PROPERTY(bool flagLandscapeSetsLocation
164 		   READ getFlagLandscapeSetsLocation
165 		   WRITE setFlagLandscapeSetsLocation
166 		   NOTIFY flagLandscapeSetsLocationChanged)
167 	Q_PROPERTY(bool flagLandscapeUseMinimalBrightness
168 		   READ getFlagLandscapeUseMinimalBrightness
169 		   WRITE setFlagLandscapeUseMinimalBrightness
170 		   NOTIFY flagLandscapeUseMinimalBrightnessChanged)
171 	Q_PROPERTY(bool flagLandscapeSetsMinimalBrightness
172 		   READ getFlagLandscapeSetsMinimalBrightness
173 		   WRITE setFlagLandscapeSetsMinimalBrightness
174 		   NOTIFY flagLandscapeSetsMinimalBrightnessChanged)
175 	Q_PROPERTY(double defaultMinimalBrightness
176 		   READ getDefaultMinimalBrightness
177 		   WRITE setDefaultMinimalBrightness
178 		   NOTIFY defaultMinimalBrightnessChanged)
179 	Q_PROPERTY(bool flagEnvironmentAutoEnabling
180 		   READ getFlagEnvironmentAutoEnable
181 		   WRITE setFlagEnvironmentAutoEnable
182 		   NOTIFY setFlagEnvironmentAutoEnableChanged)
183 	Q_PROPERTY(QString currentLandscapeID
184 		   READ getCurrentLandscapeID
185 		   WRITE setCurrentLandscapeID
186 		   NOTIFY currentLandscapeChanged)
187 	Q_PROPERTY(QStringList allLandscapeNames
188 		   READ getAllLandscapeNames)
189 	Q_PROPERTY(QString currentLandscapeName
190 		   READ getCurrentLandscapeName
191 		   WRITE setCurrentLandscapeName
192 		   NOTIFY currentLandscapeChanged)
193 	Q_PROPERTY(QString currentLandscapeHtmlDescription
194 		   READ getCurrentLandscapeHtmlDescription
195 		   NOTIFY currentLandscapeChanged)
196 	Q_PROPERTY(QString defaultLandscapeID
197 		   READ getDefaultLandscapeID
198 		   WRITE setDefaultLandscapeID
199 		   NOTIFY defaultLandscapeChanged)
200 
201 public:
202 	LandscapeMgr();
203 	virtual ~LandscapeMgr();
204 
205 	///////////////////////////////////////////////////////////////////////////
206 	// Methods defined in the StelModule class
207 	//! Initialize the LandscapeManager class.
208 	//! Operations performed:
209 	//! - Load the default landscape as specified in the application configuration
210 	//! - Set up landscape-related display flags from ini parser object
211 	virtual void init();
212 
213 	//! Draw the atmosphere, landscape graphics, and cardinal points.
214 	virtual void draw(StelCore* core);
215 	//! Draw landscape graphics and cardinal points. This only will redraw a polygonal line (if defined), the gazetteer and the Cardinal points.
216 	//! This can be called outside the usual call order, if any foreground has to be overdrawn, e.g. 3D sceneries.
217 	void drawPolylineOnly(StelCore* core);
218 
219 	//! Update time-dependent state.
220 	//! Includes:
221 	//! - Landscape, atmosphere and cardinal point on/off fading.
222 	//! - Atmophere colour calculation based on location, position of sun
223 	//!   and moon.
224 	//! - updates adaptation luminescence based on visible bright objects.
225 	//! - Landscape and lightscape brightness computations based on sun position and whether atmosphere is on or off.
226 	virtual void update(double deltaTime);
227 
228 	//! Get the order in which this module will draw its objects relative to other modules.
229 	virtual double getCallOrder(StelModuleActionName actionName) const;
230 
231 	///////////////////////////////////////////////////////////////////////////
232 	// Methods specific to the landscape manager
233 
234 	// Load a landscape based on a hash of parameters mirroring the landscape.ini
235 	// file and make it the current landscape.
236 	// GZ: This was declared, but not implemented(?)
237 	//bool loadLandscape(QMap<QString, QString>& param);
238 
239 	//! Create a new landscape from the files which describe it.
240 	//! Reads a landscape.ini file which is passed as the first parameter, determines
241 	//! the landscape type, and creates a new object for the landscape of the proper
242 	//! type.  The load member is then called, passing both parameters.
243 	//! @param landscapeFile This is the path to a landscape.ini file.
244 	//! @param landscapeId This is the landscape ID, which is also the name of the
245 	//! directory in which the files (textures and so on) for the landscape reside.
246 	//! @return A pointer to the newly created landscape object.
247 	Landscape* createFromFile(const QString& landscapeFile, const QString& landscapeId);
248 
249 	// GZ: implement StelModule's method. For test purposes only, we implement a manual transparency sampler.
250 	// TODO: comment this away for final builds. Please leave it in until this feature is finished.
251 	// virtual void handleMouseClicks(class QMouseEvent*);
252 
253 public slots:
254 	///////////////////////////////////////////////////////////////////////////
255 	// Methods callable from scripts and GUI
256 	//! Return the global landscape luminance [0..1], for being used e.g for setting eye adaptation.
257 	//! It returns 1 if atmosphere drawing is on and no eclipse underway, 0 if atmosphere is switched off.
258 	//! The actual brightness is of no concern here. You may use getAtmosphereAverageLuminance() for this.
259 	float getLuminance() const;
260 	//! return average luminance [cd/m^2] of atmosphere. Expect 10 at sunset, 6400 in daylight, >0 in dark night.
261 	float getAtmosphereAverageLuminance() const;
262 
263 	//! Override autocomputed value and set average luminance [cd/m^2] of atmosphere.  This is around 10 at sunset, 6400 in daylight, >0 in dark night.
264 	//! Usually there is no need to call this, the luminance is properly computed. This is a function which can be
265 	//! useful in rare cases, e.g. in scripts when you want to create images of adjacent sky regions with the same brightness setting,
266 	//! or for creation of a virtual camera which can deliberately show over- or underexposure.
267 	//! For these cases, it is advisable to first center the brightest luminary (sun or moon), call getAtmosphereAverageLuminance() and then set
268 	//! this value explicitly to freeze it during image export. To unfreeze, call this again with any negative value.
269 	void setAtmosphereAverageLuminance(const float overrideLuminance);
270 
271 	//! Return a map of landscape names to landscape IDs (directory names).
272 	static QMap<QString,QString> getNameToDirMap();
273 
274 	//! Retrieve a list of the names of all the available landscapes in
275 	//! the file search path sub-directories of the landscape area
276 	//! @return the names of the landscapes, which are the values of the name parameter in the landscape.ini files
277 	QStringList getAllLandscapeNames() const;
278 
279 	//! Retrieve a list of the identifiers of all the available landscapes in
280 	//! the file search path sub-directories of the landscape area
281 	//! @return the identifiers of the landscapes, which are the names of the directories containing the landscapes' files
282 	QStringList getAllLandscapeIDs() const;
283 
284 	//! Retrieve a list of the identifiers of all user-installed landscapes.
285 	//! Effectively, this returns the results of getAllLandscapeIDs() without
286 	//! the landscapes specified in the #packagedLandscapeIDs list.
287 	QStringList getUserLandscapeIDs() const;
288 
289 	//! Get the current landscape ID.
getCurrentLandscapeID() const290 	const QString getCurrentLandscapeID() const {return currentLandscapeID;}
291 	//! Change the current landscape to the landscape with the ID specified.
292 	//! Emits currentLandscapeChanged() if the landscape changed (true returned)
293 	//! @param id the ID of the new landscape
294 	//! @param changeLocationDuration the duration of the transition animation
295 	//! @return false if the new landscape could not be set (e.g. no landscape of that ID was found).
296 	bool setCurrentLandscapeID(const QString& id, const double changeLocationDuration = 1.0);
297 
298 	//! Get the current landscape name.
299 	QString getCurrentLandscapeName() const;
300 	//! Change the current landscape to the landscape with the name specified.
301 	//! Emits currentLandscapeChanged() if the landscape changed (true returned)
302 	//! @param name the name of the new landscape, as found in the landscape:name key of the landscape.ini file.
303 	//! @param changeLocationDuration the duration of the transition animation
304 	bool setCurrentLandscapeName(const QString& name, const double changeLocationDuration = 1.0);
305 
306 	//! Get the current landscape or lightscape brightness (0..1)
307 	//! @param light true to retrieve the light layer brightness value.
getCurrentLandscapeBrightness(const bool light=false) const308 	float getCurrentLandscapeBrightness(const bool light=false) const {return static_cast<float>(light? landscape->getLightscapeBrightness() : landscape->getBrightness());}
309 
310 	//! Preload a landscape into cache.
311 	//! @param id the ID of a landscape
312 	//! @param replace true if existing landscape entry should be replaced (useful during development to reload after edit)
313 	//! @return false if landscape could not be found, or if it already existed in cache and replace was false.
314 	bool precacheLandscape(const QString& id, const bool replace=true);
315 	//! Remove a landscape from the cache of landscapes.
316 	//! @param id the ID of a landscape
317 	//! @return false if landscape could not be found
318 	bool removeCachedLandscape(const QString& id);
319 	//! Set size of the landscape cache, in MB.
320 	//! Default size is 100MB, or configured as [landscape/cache_size_mb] from config.ini.
321 	//! The landscape sizes returned in Landscape::getMemorySize() are only approximate, but include image and texture sizes.
322 	//! A big landscape may well take 150MB or more.
323 	//! On a 32bit system, keep this rather small. On 64bit with 16GB RAM and no other tasks, 4GB is no problem.
324 	//! Modern GPUs may have 4 or even 8GB of dedicated texture memory. Most of this may be filled with landscape textures.
325 	//! Example: a museum installation with 20 large (16384x2048) old_style landscapes can require up to 3.5GB. Allow 4GB cache,
326 	//! and the system will never have to load a landscape during the show when all have been preloaded.
setCacheSize(int mb)327 	void setCacheSize(int mb) { landscapeCache.setMaxCost(mb);}
328 	//! Retrieve total size of cache (MB).
getCacheSize() const329 	int getCacheSize() const {return landscapeCache.maxCost();}
330 	//! Retrieve sum of currently used memory in cache (MB, approximate)
getCacheFilledSize() const331 	int getCacheFilledSize() const {return landscapeCache.totalCost();}
332 	//! Return number of landscapes already in the cache.
getCacheCount() const333 	int getCacheCount() const {return landscapeCache.count();}
334 
335 	//! Get the current landscape object.
getCurrentLandscape() const336 	Landscape* getCurrentLandscape() const { return landscape; }
337 
338 	//! Get the default landscape ID.
getDefaultLandscapeID() const339 	const QString getDefaultLandscapeID() const {return defaultLandscapeID;}
340 	//! Change the default landscape to the landscape with the ID specified.
341 	//! @param id the ID of the landscape to use by default
342 	//! @return false if the new landscape could not be set (e.g. no landscape of that ID was found). True on success.
343 	bool setDefaultLandscapeID(const QString& id);
344 
345 	//! Return a pseudo HTML formatted string with all informations on the current landscape
346 	QString getCurrentLandscapeHtmlDescription() const;
347 
348 	//! Return a pseudo HTML formatted string with information from description or ini file
349 	QString getDescription() const;
350 
351 	//! Get flag for displaying Landscape.
352 	bool getFlagLandscape() const;
353 	//! Set flag for displaying Landscape.
354 	void setFlagLandscape(const bool displayed);
355 
356 	//! Get whether the landscape is currently visible. If true, objects below landscape's limiting altitude limit can be omitted.
357 	bool getIsLandscapeFullyVisible() const;
358 	//! Get the sine of current landscape's minimal altitude. Useful to construct bounding caps.
359 	double getLandscapeSinMinAltitudeLimit() const;
360 
361 	//! Get flag for displaying Fog.
362 	bool getFlagFog() const;
363 	//! Set flag for displaying Fog.
364 	void setFlagFog(const bool displayed);
365 	//! Get flag for displaying illumination layer
366 	bool getFlagIllumination() const;
367 	//! Set flag for displaying illumination layer
368 	void setFlagIllumination(const bool on);
369 	//! Get flag for displaying landscape labels
370 	bool getFlagLabels() const;
371 	//! Set flag for displaying landscape labels
372 	void setFlagLabels(const bool on);
373 
374 	//! Retrieve flag for rendering polygonal line (if one is defined)
getFlagPolyLineDisplayed() const375 	bool getFlagPolyLineDisplayed() const {return flagPolyLineDisplayedOnly;}
376 	//! Set flag for rendering polygonal line (if one is defined)
setFlagPolyLineDisplayed(bool b)377 	void setFlagPolyLineDisplayed(bool b) {if(b!=flagPolyLineDisplayedOnly){ flagPolyLineDisplayedOnly=b; emit flagPolyLineDisplayedChanged(b);}}
378 	//! Retrieve thickness for rendering polygonal line (if one is defined)
getPolyLineThickness() const379 	int getPolyLineThickness() const {return polyLineThickness;}
380 	//! Set thickness for rendering polygonal line (if one is defined)
setPolyLineThickness(int thickness)381 	void setPolyLineThickness(int thickness) {polyLineThickness=thickness; emit polyLineThicknessChanged(thickness);}
382 
383 	//! Return the value of the flag determining if a change of landscape will update the observer location.
getFlagLandscapeSetsLocation() const384 	bool getFlagLandscapeSetsLocation() const {return flagLandscapeSetsLocation;}
385 	//! Set the value of the flag determining if a change of landscape will update the observer location.
setFlagLandscapeSetsLocation(bool b)386 	void setFlagLandscapeSetsLocation(bool b) {if(b!=flagLandscapeSetsLocation){ flagLandscapeSetsLocation=b; emit flagLandscapeSetsLocationChanged(b);}}
387 
388 	//! Return the value of the flag determining if a minimal brightness should be used to keep landscape visible.
getFlagLandscapeUseMinimalBrightness() const389 	bool getFlagLandscapeUseMinimalBrightness() const {return flagLandscapeUseMinimalBrightness; }
390 	//! Set the value of the flag determining if a minimal brightness should be used to keep landscape visible.
setFlagLandscapeUseMinimalBrightness(bool b)391 	void setFlagLandscapeUseMinimalBrightness(bool b) {if(b!=flagLandscapeUseMinimalBrightness){ flagLandscapeUseMinimalBrightness=b; emit flagLandscapeUseMinimalBrightnessChanged(b);}}
392 	//! Return the value of the flag determining if the minimal brightness should be taken from landscape.ini
getFlagLandscapeSetsMinimalBrightness() const393 	bool getFlagLandscapeSetsMinimalBrightness() const {return flagLandscapeSetsMinimalBrightness;}
394 	//! Sets the value of the flag determining if the minimal brightness should be taken from landscape.ini
setFlagLandscapeSetsMinimalBrightness(bool b)395 	void setFlagLandscapeSetsMinimalBrightness(bool b) {if(b!=flagLandscapeSetsMinimalBrightness){ flagLandscapeSetsMinimalBrightness=b; emit flagLandscapeSetsMinimalBrightnessChanged(b);}}
396 	//! Return the minimal brightness value of the landscape
getDefaultMinimalBrightness() const397 	double getDefaultMinimalBrightness() const {return defaultMinimalBrightness;}
398 	//! Set the minimal brightness value of the landscape.
setDefaultMinimalBrightness(const double b)399 	void setDefaultMinimalBrightness(const double b) {if(fabs(b-defaultMinimalBrightness)>0.0){ defaultMinimalBrightness=b; emit defaultMinimalBrightnessChanged(b);}}
400 	//! Sets the value of the flag usage light pollution (and bortle index) from locations database.
401 	void setFlagUseLightPollutionFromDatabase(const bool usage);
402 	//! Return the value of flag usage light pollution (and bortle index) from locations database.
403 	bool getFlagUseLightPollutionFromDatabase() const;
404 
405 	//! Get flag for displaying cardinal points (4-wind compass rose directions)
406 	bool getFlagCardinalsPoints() const;
407 	//! Set flag for displaying cardinal points (4-wind compass rose directions)
408 	void setFlagCardinalsPoints(const bool displayed);
409 
410 	//! Get flag for displaying intercardinal (or ordinal) points (8-wind compass rose directions).
411 	bool getFlagOrdinalsPoints() const;
412 	//! Set flag for displaying intercardinal (or ordinal) points (8-wind compass rose directions).
413 	void setFlagOrdinalsPoints(const bool displayed);
414 
415 	//! Get flag for displaying intercardinal (or ordinal) points (16-wind compass rose directions).
416 	bool getFlagOrdinals16WRPoints() const;
417 	//! Set flag for displaying intercardinal (or ordinal) points (16-wind compass rose directions).
418 	void setFlagOrdinals16WRPoints(const bool displayed);
419 
420 	//! Get Cardinals Points color.
421 	Vec3f getColorCardinalPoints() const;
422 	//! Set Cardinals Points color.
423 	void setColorCardinalPoints(const Vec3f& v);
424 
425 	//! Get flag for displaying Atmosphere.
426 	bool getFlagAtmosphere() const;
427 	//! Set flag for displaying Atmosphere.
428 	void setFlagAtmosphere(const bool displayed);
429 
430 	//! Get current display intensity of atmosphere ([0..1], for smoother transitions)
431 	float getAtmosphereFadeIntensity() const;
432 
433 	//! Get atmosphere fade duration in s.
434 	float getAtmosphereFadeDuration() const;
435 	//! Set atmosphere fade duration in s.
436 	void setAtmosphereFadeDuration(const float f);
437 
438 	/*
439 	//This method has been removed, use StelSkyDrawer::getBortleScaleIndex instead, or StelMainScriptAPI::getBortleScaleIndex in scripts
440 	//Also, if required, please use StelSkyDrawer::setBortleScaleIndex or StelMainScriptAPI::setBortleScaleIndex instead of LandscapeMgr::setAtmosphereBortleLightPollution
441 	int getAtmosphereBortleLightPollution() const;
442 	*/
443 
444 	//! Set the rotation of the landscape about the z-axis.
445 	//! This is intended for special uses such as when the landscape consists of
446 	//! a vehicle which might change orientation over time (e.g. a ship).
447 	//! @param d the rotation angle in degrees as an offset from the originally loaded value.
448 	void setZRotation(const float d);
449 
450 	//! Install a landscape from a ZIP archive.
451 	//! This function searches for a file named "landscape.ini" in the root
452 	//! directory of the archive. If it is not found there, the function
453 	//! searches inside the topmost sub-directories (if any), but no deeper.
454 	//! If a landscape configuration file is found:
455 	//!  - if a "landscapes" directory does not exist in the user data
456 	//! directory, it is created;
457 	//!  - inside it, a sub-directory is created with the landscape identifier
458 	//! for a name;
459 	//!  - all files in the archive directory that contains the "landscape.ini"
460 	//! file are extracted to the new sub-directory of "landscapes";
461 	//!  - all sub-directories of that archive directory will be skipped along
462 	//! with any other files or directories in the archive.
463 	//!
464 	//! The landscape identifier is either:
465 	//!  - the name of the folder in the archive that contains "landscape.ini",
466 	//!  - or the first 65 (or less) characters of the archive name, if the
467 	//! "landscape.ini" file is in the nameless root directory of the archive.
468 	//!
469 	//! The landscape identifier must be unique.
470 	//! @param pathToSourceArchive path to the source archive file.
471 	//! @param display If true, the landscape will be set to be the current
472 	//! landscape after installation.
473 	//! @param forAllUsers If true, this function will try to install the
474 	//! landscape in a way that meakes it is available to all users of this
475 	//! computer. May require running Stellarium as an administrator (root)
476 	//! on some Windows or *nix systems. (NOT IMPLEMENTED!)
477 	//! @returns the installed landscape's identifier, or
478 	//! an empty string on failure.
479 	//! @todo Find a better way to pass error messages.
480 	QString installLandscapeFromArchive(QString pathToSourceArchive, const bool display = false, const bool forAllUsers = false);
481 
482 	/* GZ: leaving doc without the method confuses Doxygen. Commenting out completely.
483 	//! Install a landscape from a directory.
484 	//! Expected directory structure: the name of the directory that contains
485 	//! a landscape.ini file is assumed to be the landscape ID and should be
486 	//! unique.
487 	//! This directory and all files in it will be installed, but its
488 	//! subdirectories will be skipped along with any other files or
489 	//! directories in the archive.
490 	//! @param pathToSourceLandscapeIni path to a landscape.ini file. Its parent
491 	//! directory is assumed to be the landscape source directory.
492 	//! @param display If true, the landscape will be set to be the current
493 	//! landscape after installation.
494 	//! @param forAllUsers If true, this function will try to install the
495 	//! landscape in a way that meakes it is available to all users of this
496 	//! computer. May require running Stellarium as an administrator (root)
497 	//! on some Windows or *nix systems. (NOT IMPLEMENTED!)
498 	//! @returns the installed landscape's identifier (the folder name), or
499 	//! an empty string on failure.
500 	//QString installLandscapeFromDirectory(QString pathToSourceLandscapeIni, bool display = false, bool forAllUsers = false);
501 	*/
502 
503 	//! This function removes a landscape from the user data directory.
504 	//! It tries to recursively delete all files in the landscape directory
505 	//! and then remove it from the list of available landscapes.
506 	//! If the function encounters any file that can't be deleted
507 	//! it aborts the operation (previously deleted files are not restored).
508 	//! Landscapes that were packaged with Stellarium can't be removed,
509 	//! thanks to the #packagedLandscapeIDs list.
510 	//! @param landscapeID an installed landscape's identifier (the folder name)
511 	//! @todo Find a better way to pass error messages.
512 	bool removeLandscape(const QString landscapeID);
513 
514 	//! This function reads a landscape's name from its configuration file.
515 	//! @param landscapeID an installed landscape's identifier (the folder name)
516 	//! @returns an empty string if there is no such landscape or some other
517 	//! error occurs
518 	QString loadLandscapeName(const QString landscapeID);
519 
520 	//! This function calculates and returns a landscape's disc size in bytes.
521 	//! It adds up the sizes of all files in the landscape's folder. It assumes
522 	//! that there are no sub-directories. (There shouldn't be any anyway.)
523 	//! @param landscapeID an installed landscape's identifier (the folder name)
524 	quint64 loadLandscapeSize(const QString landscapeID) const;
525 
526 	//! Get flag for autoselect of landscapes for planets.
527 	bool getFlagLandscapeAutoSelection() const;
528 	//! Set flag for autoselect of landscapes for planets.
529 	void setFlagLandscapeAutoSelection(bool enableAutoSelect);
530 
531 	//! Get flag for auto-enable of atmospheres and landscapes for planets.
532 	bool getFlagEnvironmentAutoEnable() const;
533 	//! Set flag for auto-enable atmosphere and landscape for planets with atmospheres in location window
534 	void setFlagEnvironmentAutoEnable(bool b);
535 
536 	//! Forward opacity query to current landscape.
537 	//! @param azalt direction of view line to sample in azaltimuth coordinates.
getLandscapeOpacity(Vec3d azalt) const538 	float getLandscapeOpacity(Vec3d azalt) const {return landscape->getOpacity(azalt);}
539 	// This variant is required for scripting!
getLandscapeOpacity(Vec3f azalt) const540 	float getLandscapeOpacity(Vec3f azalt) const {return landscape->getOpacity(azalt.toVec3d());}
541 	//! Forward opacity query to current landscape.
542 	//! @param azimuth in degrees
543 	//! @param altitude in degrees
getLandscapeOpacity(float azimuth,float altitude) const544 	float getLandscapeOpacity(float azimuth, float altitude) const {
545 		Vec3d azalt;
546 		StelUtils::spheToRect((180.0f-azimuth)*M_PI_180f, altitude*M_PI_180f, azalt);
547 		return landscape->getOpacity(azalt);
548 	}
549 
550 signals:
551 	void atmosphereDisplayedChanged(const bool displayed);
552 	void cardinalsPointsDisplayedChanged(const bool displayed);
553 	void ordinalsPointsDisplayedChanged(const bool displayed);
554 	void ordinals16WRPointsDisplayedChanged(const bool displayed);
555 	void cardinalsPointsColorChanged(const Vec3f & newColor) const;
556 	void fogDisplayedChanged(const bool displayed);
557 	void landscapeDisplayedChanged(const bool displayed);
558 	void illuminationDisplayedChanged(const bool displayed);
559 	void labelsDisplayedChanged(const bool displayed);
560 	void flagPolyLineDisplayedChanged(const bool enabled);
561 	void polyLineThicknessChanged(const int thickness);
562 	void flagUseLightPollutionFromDatabaseChanged(const bool usage);
563 	void flagLandscapeAutoSelectionChanged(const bool value);
564 	void flagLandscapeSetsLocationChanged(const bool value);
565 	void flagLandscapeUseMinimalBrightnessChanged(const bool value);
566 	void flagLandscapeSetsMinimalBrightnessChanged(const bool value);
567 	void defaultMinimalBrightnessChanged(const double value);
568 	void setFlagEnvironmentAutoEnableChanged(const bool enabled);
569 
570 	//! Emitted whenever the default landscape is changed
571 	//! @param id the landscape id of the new default landscape
572 	void defaultLandscapeChanged(const QString& id);
573 
574 	//! Emitted when a landscape has been installed or un-installed.
575 	//! For example, it is used to update the list of landscapes in
576 	//! the Sky and viewing options window (the ViewDialog class)
577 	void landscapesChanged();
578 
579 	//! Emitted when installLandscapeFromArchive() can't read from, write to or
580 	//! create a file or a directory.
581 	//! (A way of moving the need for translatable error messages to the GUI.)
582 	//! \param path path to the file or directory
583 	void errorUnableToOpen(QString path);
584 	//! Emitted when the file passed to installLandscapeFromArchive() is not a
585 	//! ZIP archive or does not contain a valid landscape.
586 	//! (A way of moving the need for translatable error messages to the GUI.)
587 	void errorNotArchive();
588 	//! Emitted when installLandscapeFromArchive() tries to install a landscape
589 	//! with the same name or identifier as an already installed one.
590 	//! (A way of moving the need for translatable error messages to the GUI.)
591 	//! \param nameOrID the name or the identifier of the landscape
592 	void errorNotUnique(QString nameOrID);
593 	//! Emitted when removeLandscape() is unable to remove all the files of
594 	//! a landscape.
595 	//! (A way of moving the need for translatable error messages to the GUI.)
596 	//! \param path the path to the landscape's directory
597 	void errorRemoveManually(QString path);
598 
599 	//! Emitted when the current landscape was changed
600 	//! \param currentLandscapeID the ID of the new landscape
601 	//! \param currentLandscapeName the name of the new landscape
602 	void currentLandscapeChanged(QString currentLandscapeID,QString currentLandscapeName);
603 
604 private slots:
605 	//! Set the light pollution following the Bortle Scale.
606 	//! This should not be called from script code, use StelMainScriptAPI::setBortleScaleIndex if you want to change the light pollution.
607 	void setAtmosphereBortleLightPollution(const int bIndex);
608 
609 	//! Reacts to StelCore::locationChanged.
610 	void onLocationChanged(const StelLocation &loc);
611 	void onTargetLocationChanged(const StelLocation &loc);
612 
613 	//! Translate labels to new language settings.
614 	void updateI18n();
615 
616 	void increaseLightPollution();
617 	void reduceLightPollution();
618 	void cyclicChangeLightPollution();
619 
620 private:
621 	//! Get light pollution luminance level.
622 	float getAtmosphereLightPollutionLuminance() const;
623 	//! Set light pollution luminance level.
624 	void setAtmosphereLightPollutionLuminance(const float f);
625 
626 
627 	//! For a given landscape name, return the landscape ID.
628 	//! This takes a name of the landscape, as described in the landscape:name item in the
629 	//! landscape.ini, and returns the landscape ID which corresponds to that name.
630 	static QString nameToID(const QString& name);
631 
632 	//! Returns the path to an installed landscape's directory.
633 	//! It uses StelFileMgr to look for it in the possible directories.
634 	//! @param landscapeID an installed landscape's identifier (the folder name)
635 	//! @returns an empty string, if no such landscape was found.
636 	static QString getLandscapePath(const QString landscapeID);
637 
638 	Atmosphere* atmosphere;			// Atmosphere
639 	Cardinals* cardinalsPoints;		// Cardinals points
640 	Landscape* landscape;			// The landscape i.e. the fog, the ground and "decor"
641 	Landscape* oldLandscape;		// Used only during transitions to newly loaded landscape.
642 
643 	// Define whether the observer location is to be updated when the landscape is updated.
644 	bool flagLandscapeSetsLocation;
645 
646 	bool flagLandscapeAutoSelection;
647 
648 	bool flagLightPollutionFromDatabase;
649 
650 	//! control drawing of a Polygonal line, if one is defined.
651 	bool flagPolyLineDisplayedOnly;
652 	//! thickness of polygonal horizon line
653 	int polyLineThickness;
654 
655 	//! Indicate use of the default minimal brightness value specified in config.ini.
656 	bool flagLandscapeUseMinimalBrightness;
657 	//! A minimal brightness value to keep landscape visible.
658 	double defaultMinimalBrightness;
659 	//! Indicate use of the minimal brightness value specified in the current landscape.ini, if present.
660 	bool flagLandscapeSetsMinimalBrightness;
661 	//! Indicate auto-enable atmosphere and landscape for planets with atmospheres in location window
662 	bool flagEnvironmentAutoEnabling;
663 
664 	//! The ID of the currently loaded landscape
665 	QString currentLandscapeID;
666 
667 	//! The ID of the default landscape
668 	QString defaultLandscapeID;
669 
670 	//! List of the IDs of the landscapes packaged by default with Stellarium.
671 	//! (So that they can't be removed.)
672 	QStringList packagedLandscapeIDs;
673 
674 	//! QCache of landscapes kept in memory for faster access, esp. when frequently switching between several big landscapes.
675 	//! Example: a 16384-size old_style landscape takes about 10 seconds to load. Kept in cache, it is back instantly.
676 	//! Of course, this requires lots of RAM and GPU texture memory, but in the age of 64bit CPUs and 4GB and more GPU
677 	//! texture memory, it is no problem to keep even 20 or more landscapes.
678 	//! This is esp. useful in a context of automated setup (museum show or such) where a list of landscapes is preloaded
679 	//! at system start (e.g. in the startup.ssc script) and then retrieved while script is running.
680 	//! The key is just the LandscapeID.
681 	QCache<QString,Landscape> landscapeCache;
682 
683 	//! Core current planet name, used to react to planet change.
684 	QString currentPlanetName;
685 };
686 
687 #endif // LANDSCAPEMGR_HPP
688