Re-add jungles, apple trees
[oweals/minetest.git] / src / sky.cpp
1 #include "sky.h"
2 #include "IVideoDriver.h"
3 #include "ISceneManager.h"
4 #include "ICameraSceneNode.h"
5 #include "S3DVertex.h"
6 #include "tile.h" // getTexturePath
7 #include "noise.h" // easeCurve
8 #include "main.h" // g_profiler
9 #include "profiler.h"
10 #include "util/numeric.h" // MYMIN
11
12 //! constructor
13 Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id):
14                 scene::ISceneNode(parent, mgr, id),
15                 m_first_update(true),
16                 m_brightness(0.5),
17                 m_cloud_brightness(0.5),
18                 m_bgcolor_bright_f(1,1,1,1),
19                 m_skycolor_bright_f(1,1,1,1),
20                 m_cloudcolor_bright_f(1,1,1,1)
21 {
22         setAutomaticCulling(scene::EAC_OFF);
23         Box.MaxEdge.set(0,0,0);
24         Box.MinEdge.set(0,0,0);
25
26         // create material
27
28         video::SMaterial mat;
29         mat.Lighting = false;
30         mat.ZBuffer = video::ECFN_NEVER;
31         mat.ZWriteEnable = false;
32         mat.AntiAliasing=0;
33         mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
34         mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
35         mat.BackfaceCulling = false;
36
37         m_materials[0] = mat;
38
39         m_materials[1] = mat;
40         //m_materials[1].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
41         m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
42
43         m_materials[2] = mat;
44         m_materials[2].setTexture(0, mgr->getVideoDriver()->getTexture(
45                         getTexturePath("sunrisebg.png").c_str()));
46         m_materials[2].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
47         //m_materials[2].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
48
49         for(u32 i=0; i<SKY_STAR_COUNT; i++){
50                 m_stars[i] = v3f(
51                         myrand_range(-10000,10000),
52                         myrand_range(-10000,10000),
53                         myrand_range(-10000,10000)
54                 );
55                 m_stars[i].normalize();
56         }
57 }
58
59 void Sky::OnRegisterSceneNode()
60 {
61         if (IsVisible)
62                 SceneManager->registerNodeForRendering(this, scene::ESNRP_SKY_BOX);
63
64         scene::ISceneNode::OnRegisterSceneNode();
65 }
66
67 const core::aabbox3d<f32>& Sky::getBoundingBox() const
68 {
69         return Box;
70 }
71
72 //! renders the node.
73 void Sky::render()
74 {
75         video::IVideoDriver* driver = SceneManager->getVideoDriver();
76         scene::ICameraSceneNode* camera = SceneManager->getActiveCamera();
77
78         if (!camera || !driver)
79                 return;
80         
81         ScopeProfiler sp(g_profiler, "Sky::render()", SPT_AVG);
82
83         // draw perspective skybox
84
85         core::matrix4 translate(AbsoluteTransformation);
86         translate.setTranslation(camera->getAbsolutePosition());
87
88         // Draw the sky box between the near and far clip plane
89         const f32 viewDistance = (camera->getNearValue() + camera->getFarValue()) * 0.5f;
90         core::matrix4 scale;
91         scale.setScale(core::vector3df(viewDistance, viewDistance, viewDistance));
92
93         driver->setTransform(video::ETS_WORLD, translate * scale);
94
95         if(m_sunlight_seen)
96         {
97                 float sunsize = 0.07;
98                 video::SColorf suncolor_f(1, 1, 0, 1);
99                 suncolor_f.r = 1;
100                 suncolor_f.g = MYMAX(0.3, MYMIN(1.0, 0.7+m_time_brightness*(0.5)));
101                 suncolor_f.b = MYMAX(0.0, m_brightness*0.95);
102                 video::SColorf suncolor2_f(1, 1, 1, 1);
103                 suncolor_f.r = 1;
104                 suncolor_f.g = MYMAX(0.3, MYMIN(1.0, 0.85+m_time_brightness*(0.5)));
105                 suncolor_f.b = MYMAX(0.0, m_brightness);
106
107                 float moonsize = 0.04;
108                 video::SColorf mooncolor_f(0.50, 0.57, 0.65, 1);
109                 video::SColorf mooncolor2_f(0.85, 0.875, 0.9, 1);
110                 
111                 float nightlength = 0.415;
112                 float wn = nightlength / 2;
113                 float wicked_time_of_day = 0;
114                 if(m_time_of_day > wn && m_time_of_day < 1.0 - wn)
115                         wicked_time_of_day = (m_time_of_day - wn)/(1.0-wn*2)*0.5 + 0.25;
116                 else if(m_time_of_day < 0.5)
117                         wicked_time_of_day = m_time_of_day / wn * 0.25;
118                 else
119                         wicked_time_of_day = 1.0 - ((1.0-m_time_of_day) / wn * 0.25);
120                 /*std::cerr<<"time_of_day="<<m_time_of_day<<" -> "
121                                 <<"wicked_time_of_day="<<wicked_time_of_day<<std::endl;*/
122
123                 video::SColor suncolor = suncolor_f.toSColor();
124                 video::SColor suncolor2 = suncolor2_f.toSColor();
125                 video::SColor mooncolor = mooncolor_f.toSColor();
126                 video::SColor mooncolor2 = mooncolor2_f.toSColor();
127
128                 const f32 t = 1.0f;
129                 const f32 o = 0.0f;
130                 static const u16 indices[4] = {0,1,2,3};
131                 video::S3DVertex vertices[4];
132                 
133                 driver->setMaterial(m_materials[1]);
134                 
135                 //video::SColor cloudyfogcolor(255,255,255,255);
136                 video::SColor cloudyfogcolor = m_bgcolor;
137                 //video::SColor cloudyfogcolor = m_bgcolor.getInterpolated(m_skycolor, 0.5);
138                 
139                 // Draw far cloudy fog thing
140                 for(u32 j=0; j<4; j++)
141                 {
142                         video::SColor c = cloudyfogcolor.getInterpolated(m_skycolor, 0.45);
143                         vertices[0] = video::S3DVertex(-1, 0.08,-1, 0,0,1, c, t, t);
144                         vertices[1] = video::S3DVertex( 1, 0.08,-1, 0,0,1, c, o, t);
145                         vertices[2] = video::S3DVertex( 1, 0.12,-1, 0,0,1, c, o, o);
146                         vertices[3] = video::S3DVertex(-1, 0.12,-1, 0,0,1, c, t, o);
147                         for(u32 i=0; i<4; i++){
148                                 if(j==0)
149                                         // Don't switch
150                                         {}
151                                 else if(j==1)
152                                         // Switch from -Z (south) to +X (east)
153                                         vertices[i].Pos.rotateXZBy(90);
154                                 else if(j==2)
155                                         // Switch from -Z (south) to -X (west)
156                                         vertices[i].Pos.rotateXZBy(-90);
157                                 else
158                                         // Switch from -Z (south) to -Z (north)
159                                         vertices[i].Pos.rotateXZBy(-180);
160                         }
161                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
162                 }
163                 for(u32 j=0; j<4; j++)
164                 {
165                         video::SColor c = cloudyfogcolor;
166                         vertices[0] = video::S3DVertex(-1,-1.0,-1, 0,0,1, c, t, t);
167                         vertices[1] = video::S3DVertex( 1,-1.0,-1, 0,0,1, c, o, t);
168                         vertices[2] = video::S3DVertex( 1, 0.08,-1, 0,0,1, c, o, o);
169                         vertices[3] = video::S3DVertex(-1, 0.08,-1, 0,0,1, c, t, o);
170                         for(u32 i=0; i<4; i++){
171                                 if(j==0)
172                                         // Don't switch
173                                         {}
174                                 else if(j==1)
175                                         // Switch from -Z (south) to +X (east)
176                                         vertices[i].Pos.rotateXZBy(90);
177                                 else if(j==2)
178                                         // Switch from -Z (south) to -X (west)
179                                         vertices[i].Pos.rotateXZBy(-90);
180                                 else
181                                         // Switch from -Z (south) to -Z (north)
182                                         vertices[i].Pos.rotateXZBy(-180);
183                         }
184                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
185                 }
186
187                 driver->setMaterial(m_materials[2]);
188
189                 {
190                         float mid1 = 0.25;
191                         float mid = (wicked_time_of_day < 0.5 ? mid1 : (1.0 - mid1));
192                         float a_ = 1.0 - fabs(wicked_time_of_day - mid) * 35.0;
193                         float a = easeCurve(MYMAX(0, MYMIN(1, a_)));
194                         //std::cerr<<"a_="<<a_<<" a="<<a<<std::endl;
195                         video::SColor c(255,255,255,255);
196                         float y = -(1.0 - a) * 0.2;
197                         vertices[0] = video::S3DVertex(-1,-0.05+y,-1, 0,0,1, c, t, t);
198                         vertices[1] = video::S3DVertex( 1,-0.05+y,-1, 0,0,1, c, o, t);
199                         vertices[2] = video::S3DVertex( 1, 0.2+y,-1, 0,0,1, c, o, o);
200                         vertices[3] = video::S3DVertex(-1, 0.2+y,-1, 0,0,1, c, t, o);
201                         for(u32 i=0; i<4; i++){
202                                 if(wicked_time_of_day < 0.5)
203                                         // Switch from -Z (south) to +X (east)
204                                         vertices[i].Pos.rotateXZBy(90);
205                                 else
206                                         // Switch from -Z (south) to -X (west)
207                                         vertices[i].Pos.rotateXZBy(-90);
208                         }
209                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
210                 }
211
212                 driver->setMaterial(m_materials[1]);
213                 
214                 // Draw sun
215                 if(wicked_time_of_day > 0.15 && wicked_time_of_day < 0.85)
216                 {
217                         float d = sunsize * 1.7;
218                         video::SColor c = suncolor;
219                         c.setAlpha(0.05*255);
220                         vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, c, t, t);
221                         vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, c, o, t);
222                         vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, c, o, o);
223                         vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, c, t, o);
224                         for(u32 i=0; i<4; i++){
225                                 // Switch from -Z (south) to +X (east)
226                                 vertices[i].Pos.rotateXZBy(90);
227                                 vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
228                         }
229                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
230
231                         d = sunsize * 1.2;
232                         c = suncolor;
233                         c.setAlpha(0.15*255);
234                         vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, c, t, t);
235                         vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, c, o, t);
236                         vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, c, o, o);
237                         vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, c, t, o);
238                         for(u32 i=0; i<4; i++){
239                                 // Switch from -Z (south) to +X (east)
240                                 vertices[i].Pos.rotateXZBy(90);
241                                 vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
242                         }
243                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
244
245                         d = sunsize;
246                         vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, suncolor, t, t);
247                         vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, suncolor, o, t);
248                         vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, suncolor, o, o);
249                         vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, suncolor, t, o);
250                         for(u32 i=0; i<4; i++){
251                                 // Switch from -Z (south) to +X (east)
252                                 vertices[i].Pos.rotateXZBy(90);
253                                 vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
254                         }
255                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
256
257                         d = sunsize * 0.7;
258                         vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, suncolor2, t, t);
259                         vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, suncolor2, o, t);
260                         vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, suncolor2, o, o);
261                         vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, suncolor2, t, o);
262                         for(u32 i=0; i<4; i++){
263                                 // Switch from -Z (south) to +X (east)
264                                 vertices[i].Pos.rotateXZBy(90);
265                                 vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
266                         }
267                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
268                 }
269                 // Draw moon
270                 if(wicked_time_of_day < 0.3 || wicked_time_of_day > 0.7)
271                 {
272                         float d = moonsize * 1.9;
273                         video::SColor c = mooncolor;
274                         c.setAlpha(0.05*255);
275                         vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, c, t, t);
276                         vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, c, o, t);
277                         vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, c, o, o);
278                         vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, c, t, o);
279                         for(u32 i=0; i<4; i++){
280                                 // Switch from -Z (south) to -X (west)
281                                 vertices[i].Pos.rotateXZBy(-90);
282                                 vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
283                         }
284                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
285                         
286                         d = moonsize * 1.3;
287                         c = mooncolor;
288                         c.setAlpha(0.15*255);
289                         vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, c, t, t);
290                         vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, c, o, t);
291                         vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, c, o, o);
292                         vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, c, t, o);
293                         for(u32 i=0; i<4; i++){
294                                 // Switch from -Z (south) to -X (west)
295                                 vertices[i].Pos.rotateXZBy(-90);
296                                 vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
297                         }
298                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
299                         
300                         d = moonsize;
301                         vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, mooncolor, t, t);
302                         vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, mooncolor, o, t);
303                         vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, mooncolor, o, o);
304                         vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, mooncolor, t, o);
305                         for(u32 i=0; i<4; i++){
306                                 // Switch from -Z (south) to -X (west)
307                                 vertices[i].Pos.rotateXZBy(-90);
308                                 vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
309                         }
310                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
311                         
312                         float d2 = moonsize * 0.6;
313                         vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, mooncolor2, t, t);
314                         vertices[1] = video::S3DVertex( d2,-d,-1, 0,0,1, mooncolor2, o, t);
315                         vertices[2] = video::S3DVertex( d2, d2,-1, 0,0,1, mooncolor2, o, o);
316                         vertices[3] = video::S3DVertex(-d, d2,-1, 0,0,1, mooncolor2, t, o);
317                         for(u32 i=0; i<4; i++){
318                                 // Switch from -Z (south) to -X (west)
319                                 vertices[i].Pos.rotateXZBy(-90);
320                                 vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
321                         }
322                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
323                 }
324                 // Stars
325                 do{
326                         float starbrightness = MYMAX(0, MYMIN(1,
327                                         (0.285 - fabs(wicked_time_of_day < 0.5 ?
328                                         wicked_time_of_day : (1.0 - wicked_time_of_day))) * 10));
329                         float f = starbrightness;
330                         float d = 0.007;
331                         video::SColor starcolor(255, f*90,f*90,f*90);
332                         if(starcolor.getBlue() < m_skycolor.getBlue())
333                                 break;
334                         u16 indices[SKY_STAR_COUNT*4];
335                         video::S3DVertex vertices[SKY_STAR_COUNT*4];
336                         for(u32 i=0; i<SKY_STAR_COUNT; i++){
337                                 indices[i*4+0] = i*4+0;
338                                 indices[i*4+1] = i*4+1;
339                                 indices[i*4+2] = i*4+2;
340                                 indices[i*4+3] = i*4+3;
341                                 v3f p = m_stars[i];
342                                 core::CMatrix4<f32> a;
343                                 a.buildRotateFromTo(v3f(0,1,0), v3f(d,1+d/2,0));
344                                 v3f p1 = p;
345                                 a.rotateVect(p1);
346                                 a.buildRotateFromTo(v3f(0,1,0), v3f(d,1,d));
347                                 v3f p2 = p;
348                                 a.rotateVect(p2);
349                                 a.buildRotateFromTo(v3f(0,1,0), v3f(0,1-d/2,d));
350                                 v3f p3 = p;
351                                 a.rotateVect(p3);
352                                 p.rotateXYBy(wicked_time_of_day * 360 - 90);
353                                 p1.rotateXYBy(wicked_time_of_day * 360 - 90);
354                                 p2.rotateXYBy(wicked_time_of_day * 360 - 90);
355                                 p3.rotateXYBy(wicked_time_of_day * 360 - 90);
356                                 vertices[i*4+0].Pos = p;
357                                 vertices[i*4+0].Color = starcolor;
358                                 vertices[i*4+1].Pos = p1;
359                                 vertices[i*4+1].Color = starcolor;
360                                 vertices[i*4+2].Pos = p2;
361                                 vertices[i*4+2].Color = starcolor;
362                                 vertices[i*4+3].Pos = p3;
363                                 vertices[i*4+3].Color = starcolor;
364                         }
365                         driver->drawVertexPrimitiveList(vertices, SKY_STAR_COUNT*4,
366                                         indices, SKY_STAR_COUNT, video::EVT_STANDARD,
367                                         scene::EPT_QUADS, video::EIT_16BIT);
368                 }while(0);
369                 
370                 for(u32 j=0; j<2; j++)
371                 {
372                         //video::SColor c = m_skycolor;
373                         video::SColor c = cloudyfogcolor;
374                         vertices[0] = video::S3DVertex(-1,-1.0,-1, 0,0,1, c, t, t);
375                         vertices[1] = video::S3DVertex( 1,-1.0,-1, 0,0,1, c, o, t);
376                         vertices[2] = video::S3DVertex( 1,-0.02,-1, 0,0,1, c, o, o);
377                         vertices[3] = video::S3DVertex(-1,-0.02,-1, 0,0,1, c, t, o);
378                         for(u32 i=0; i<4; i++){
379                                 //if(wicked_time_of_day < 0.5)
380                                 if(j==0)
381                                         // Switch from -Z (south) to +X (east)
382                                         vertices[i].Pos.rotateXZBy(90);
383                                 else
384                                         // Switch from -Z (south) to -X (west)
385                                         vertices[i].Pos.rotateXZBy(-90);
386                         }
387                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
388                 }
389         }
390 }
391
392 void Sky::update(float time_of_day, float time_brightness,
393                 float direct_brightness, bool sunlight_seen)
394 {
395         // Stabilize initial brightness and color values by flooding updates
396         if(m_first_update){
397                 /*dstream<<"First update with time_of_day="<<time_of_day
398                                 <<" time_brightness="<<time_brightness
399                                 <<" direct_brightness="<<direct_brightness
400                                 <<" sunlight_seen="<<sunlight_seen<<std::endl;*/
401                 m_first_update = false;
402                 for(u32 i=0; i<100; i++){
403                         update(time_of_day, time_brightness, direct_brightness,
404                                         sunlight_seen);
405                 }
406                 return;
407         }
408
409         m_time_of_day = time_of_day;
410         m_time_brightness = time_brightness;
411         m_sunlight_seen = sunlight_seen;
412         
413         bool is_dawn = (time_brightness >= 0.20 && time_brightness < 0.35);
414
415         //video::SColorf bgcolor_bright_normal_f(170./255,200./255,230./255, 1.0);
416         video::SColorf bgcolor_bright_normal_f(155./255,193./255,240./255, 1.0);
417         video::SColorf bgcolor_bright_indoor_f(100./255,100./255,100./255, 1.0);
418         //video::SColorf bgcolor_bright_dawn_f(0.666,200./255*0.7,230./255*0.5,1.0);
419         //video::SColorf bgcolor_bright_dawn_f(0.666,0.549,0.220,1.0);
420         //video::SColorf bgcolor_bright_dawn_f(0.666*1.2,0.549*1.0,0.220*1.0, 1.0);
421         //video::SColorf bgcolor_bright_dawn_f(0.666*1.2,0.549*1.0,0.220*1.2,1.0);
422         video::SColorf bgcolor_bright_dawn_f
423                         (155./255*1.2,193./255,240./255, 1.0);
424
425         video::SColorf skycolor_bright_normal_f =
426                         video::SColor(255, 140, 186, 250);
427         video::SColorf skycolor_bright_dawn_f =
428                         video::SColor(255, 180, 186, 250);
429         
430         video::SColorf cloudcolor_bright_normal_f =
431                         video::SColor(255, 240,240,255);
432         //video::SColorf cloudcolor_bright_dawn_f(1.0, 0.591, 0.4);
433         //video::SColorf cloudcolor_bright_dawn_f(1.0, 0.65, 0.44);
434         video::SColorf cloudcolor_bright_dawn_f(1.0, 0.7, 0.5);
435
436         if(sunlight_seen){
437                 //m_brightness = m_brightness * 0.95 + direct_brightness * 0.05;
438                 m_brightness = m_brightness * 0.95 + time_brightness * 0.05;
439         }
440         else{
441                 if(direct_brightness < m_brightness)
442                         m_brightness = m_brightness * 0.95 + direct_brightness * 0.05;
443                 else
444                         m_brightness = m_brightness * 0.98 + direct_brightness * 0.02;
445         }
446         
447         m_clouds_visible = true;
448         float color_change_fraction = 0.98;
449         if(sunlight_seen){
450                 if(is_dawn){
451                         m_bgcolor_bright_f = m_bgcolor_bright_f.getInterpolated(
452                                         bgcolor_bright_dawn_f, color_change_fraction);
453                         m_skycolor_bright_f = m_skycolor_bright_f.getInterpolated(
454                                         skycolor_bright_dawn_f, color_change_fraction);
455                         m_cloudcolor_bright_f = m_cloudcolor_bright_f.getInterpolated(
456                                         cloudcolor_bright_dawn_f, color_change_fraction);
457                 } else {
458                         m_bgcolor_bright_f = m_bgcolor_bright_f.getInterpolated(
459                                         bgcolor_bright_normal_f, color_change_fraction);
460                         m_skycolor_bright_f = m_skycolor_bright_f.getInterpolated(
461                                         skycolor_bright_normal_f, color_change_fraction);
462                         m_cloudcolor_bright_f = m_cloudcolor_bright_f.getInterpolated(
463                                         cloudcolor_bright_normal_f, color_change_fraction);
464                 }
465         } else {
466                 m_bgcolor_bright_f = m_bgcolor_bright_f.getInterpolated(
467                                 bgcolor_bright_indoor_f, color_change_fraction);
468                 m_cloudcolor_bright_f = m_cloudcolor_bright_f.getInterpolated(
469                                 cloudcolor_bright_normal_f, color_change_fraction);
470                 m_skycolor_bright_f = m_skycolor_bright_f.getInterpolated(
471                                 bgcolor_bright_indoor_f, color_change_fraction);
472                 m_clouds_visible = false;
473         }
474         video::SColor bgcolor_bright = m_bgcolor_bright_f.toSColor();
475         m_bgcolor = video::SColor(
476                         255,
477                         bgcolor_bright.getRed() * m_brightness,
478                         bgcolor_bright.getGreen() * m_brightness,
479                         bgcolor_bright.getBlue() * m_brightness);
480         
481         video::SColor skycolor_bright = m_skycolor_bright_f.toSColor();
482         m_skycolor = video::SColor(
483                         255,
484                         skycolor_bright.getRed() * m_brightness,
485                         skycolor_bright.getGreen() * m_brightness,
486                         skycolor_bright.getBlue() * m_brightness);
487         
488         float cloud_direct_brightness = 0;
489         if(sunlight_seen){
490                 cloud_direct_brightness = time_brightness;
491                 if(time_brightness >= 0.2 && time_brightness < 0.7)
492                                 cloud_direct_brightness *= 1.3;
493         } else {
494                 cloud_direct_brightness = direct_brightness;
495         }
496         m_cloud_brightness = m_cloud_brightness * 0.95 +
497                         cloud_direct_brightness * (1.0 - 0.95);
498         m_cloudcolor_f = video::SColorf(
499                         m_cloudcolor_bright_f.getRed() * m_cloud_brightness,
500                         m_cloudcolor_bright_f.getGreen() * m_cloud_brightness,
501                         m_cloudcolor_bright_f.getBlue() * m_cloud_brightness,
502                         1.0);
503
504 }
505
506