1 /*
2  * Stellarium Scenery3d Plug-in
3  *
4  * Copyright (C) 2011-16 Simon Parzer, Peter Neubauer, Georg Zotti, Andrei Borza, Florian Schaukowitsch
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 S3DSCENE_HPP
22 #define S3DSCENE_HPP
23 
24 #include "StelOBJ.hpp"
25 #include "StelTextureTypes.hpp"
26 #include "StelOpenGLArray.hpp"
27 #include "SceneInfo.hpp"
28 #include "Heightmap.hpp"
29 
30 #include <cfloat>
31 
32 Q_DECLARE_LOGGING_CATEGORY(s3dscene)
33 
34 class S3DScene
35 {
36 public:
37 	//! Extension of StelOBJ::Material which provides Scenery3d specific stuff
38 	struct Material : public StelOBJ::Material
39 	{
MaterialS3DScene::Material40 		Material() : traits(), bAlphatest(false), bBackface(false), fAlphaThreshold(0.5),
41 			     vis_fadeIn(-DBL_MAX, -DBL_MAX),vis_fadeOut(DBL_MAX,DBL_MAX),vis_fadeValue(1.0)
42 		{
43 		}
44 
MaterialS3DScene::Material45 		Material(const StelOBJ::Material& stelMat)
46 			: StelOBJ::Material(stelMat), traits(), bAlphatest(false), bBackface(false), fAlphaThreshold(0.5),
47 			  vis_fadeIn(-DBL_MAX, -DBL_MAX),vis_fadeOut(DBL_MAX,DBL_MAX),vis_fadeValue(1.0)
48 		{
49 			if(additionalParams.contains("bAlphatest"))
50 				parseBool(additionalParams.value("bAlphatest"), bAlphatest);
51 			if(additionalParams.contains("bBackface"))
52 				parseBool(additionalParams.value("bBackface"), bBackface);
53 			if(additionalParams.contains("fAlphaThreshold"))
54 				parseFloat(additionalParams.value("fAlphaThreshold"), fAlphaThreshold);
55 			if(additionalParams.contains("vis_fadeIn"))
56 			{
57 				traits.hasTimeFade = true;
58 				parseVec2d(additionalParams.value("vis_fadeIn"), vis_fadeIn);
59 			}
60 			if(additionalParams.contains("vis_fadeOut"))
61 			{
62 				traits.hasTimeFade = true;
63 				parseVec2d(additionalParams.value("vis_fadeOut"), vis_fadeOut);
64 			}
65 		}
66 
67 		struct Traits
68 		{
69 			//bool hasAmbientTexture; //! True when tex_Ka is a valid texture
70 			bool hasDiffuseTexture; //! True when tex_Kd is a valid texture
71 			//bool hasSpecularTexture; //! True when tex_Ks is a valid texture
72 			bool hasEmissiveTexture; //! True when tex_Ke is a valid texture
73 			bool hasBumpTexture; //! True when tex_bump is a valid texture
74 			bool hasHeightTexture; //! True when tex_height is a valid texture
75 			bool hasSpecularity; //! True when both Ks and Ns are non-zero
76 			bool hasTransparency; //! True when the material exhibits "true" transparency, that is when the tex_Kd has an alpha channel or the d value is smaller than 1
77 			bool hasTimeFade; //! True when the material has time-dependent display
78 			bool isFullyTransparent; //! True when the material is (currently) completely invisible
79 			bool isFading; //! True while the material is currently fading
80 		} traits;
81 
82 		//the actual texture instances
83 		StelTextureSP tex_Kd;
84 		StelTextureSP tex_Ke;
85 		StelTextureSP tex_bump;
86 		StelTextureSP tex_height;
87 
88 		bool bAlphatest;
89 		bool bBackface;
90 		float fAlphaThreshold;
91 
92 		Vec2d vis_fadeIn;  // JD of begin of first visibility and begin of full visibility.
93 		Vec2d vis_fadeOut; // JD of end of full visibility and end of last visibility.
94 		//! Updated by S3DRenderer when necessary, otherwise always 1.0
95 		float vis_fadeValue;
96 
97 		//! Starts loading the textures in this material asynchronously
98 		void loadTexturesAsync();
99 		//! Re-calculates the material traits, and sets invalid material fields to valid values.
100 		//! This requires all textures to be fully loaded.
101 		void fixup();
102 		//! Re-calculates time fade info, returns true if the object should be rendered
103 		bool updateFadeInfo(double currentJD);
104 	};
105 
106 	typedef QVector<Material> MaterialList;
107 	//for now, this does not use custom extensions...
108 	typedef StelOBJ::ObjectList ObjectList;
109 
110 	explicit S3DScene(const SceneInfo& info);
111 
112 	void setModel(const StelOBJ& model);
113 	void setGround(const StelOBJ& ground);
114 
getSceneInfo() const115 	const SceneInfo& getSceneInfo() const { return info; }
116 
getMaterialList()117 	MaterialList& getMaterialList() { return materials; }
getMaterial(int index) const118 	const Material& getMaterial(int index) const { return materials.at(index); }
getObjects() const119 	const ObjectList& getObjects() const { return objects; }
120 
121 	//! Moves the viewer according to the given move vector
122 	//!  (which is specified relative to the view direction and current position)
123 	//! The 3rd component of the vector specifies the eye height change.
124 	//! The foot height is set to the heightmap position.
125 	void moveViewer(const Vec3d& moveView);
126 
127 	//! Sets the viewer (foot) position
128 	void setViewerPosition(const Vec3d& pos);
129 	//! Sets the viewer foot position on the given x/y point on the heightmap
130 	void setViewerPositionOnHeightmap(const Vec2d& pos);
131 	//! Get current viewer foot position
getViewerPosition() const132 	inline const Vec3d& getViewerPosition() const { return position; }
133 	//! Returns the viewer foot position, without the height
getViewer2DPosition() const134 	inline Vec2d getViewer2DPosition() const { return Vec2d(position[0], position[1]); }
135 	//! Get current eye position (= foot position + eye height)
getEyePosition() const136 	inline const Vec3d& getEyePosition() const { return eyePosition; }
getEyeHeight() const137 	inline double getEyeHeight() const { return eye_height; }
setEyeHeight(double height)138 	inline void setEyeHeight(double height) { eye_height = height; recalcEyePos();}
getSceneAABB() const139 	inline const AABBox& getSceneAABB() const { return sceneAABB; }
140 	float getGroundHeightAtViewer() const;
setViewDirection(const Vec3d & viewDir)141 	inline void setViewDirection(const Vec3d& viewDir) { viewDirection = viewDir; }
getViewDirection() const142 	inline const Vec3d& getViewDirection() const { return viewDirection; }
143 
144 	Vec3d getGridPosition() const;
145 	void setGridPosition(const Vec3d& gridPos);
146 
147 	//! Makes the scene ready for GL rendering. Needs a valid GL context
148 	bool glLoad();
149 	//! Returns true if the scene is ready for GL rendering (glLoad succeded)
isGLReady() const150 	bool isGLReady() const { return glReady; }
151 	// Basic wrappers alround StelOpenGLArray
glBind()152 	inline void glBind() { glArray.bind(); }
glRelease()153 	inline void glRelease() { glArray.release(); }
glDraw(int offset,int count) const154 	inline void glDraw(int offset, int count) const { glArray.draw(offset,count); }
155 
156 private:
recalcEyePos()157 	inline void recalcEyePos() { eyePosition = position; eyePosition[2]+=eye_height; }
158 	MaterialList materials;
159 	ObjectList objects;
160 
161 
162 	bool glReady;
163 
164 	SceneInfo info;
165 	QMatrix4x4 zRot2Grid;
166 
167 	AABBox sceneAABB;
168 
169 	// current view direction vector
170 	Vec3d viewDirection;
171 	// current foot position in model
172 	Vec3d position;
173 	// current eye height (relative to foot position)
174 	double eye_height;
175 	// current eye position in model (stored to avoid repeated re-calculations)
176 	Vec3d eyePosition;
177 
178 	//the model data is only retained before loaded into GL
179 	StelOBJ modelData;
180 	Heightmap heightmap;
181 	StelOpenGLArray glArray;
182 
183 	static void finalizeTexture(StelTextureSP& tex);
184 };
185 
186 #endif // S3DSCENE_HPP
187