LCOV - code coverage report
Current view: top level - src - sky.cpp (source / functions) Hit Total Coverage
Test: report Lines: 247 417 59.2 %
Date: 2015-07-11 18:23:49 Functions: 6 8 75.0 %

          Line data    Source code
       1             : #include "sky.h"
       2             : #include "IVideoDriver.h"
       3             : #include "ISceneManager.h"
       4             : #include "ICameraSceneNode.h"
       5             : #include "S3DVertex.h"
       6             : #include "client/tile.h"
       7             : #include "noise.h"            // easeCurve
       8             : #include "profiler.h"
       9             : #include "util/numeric.h"
      10             : #include <cmath>
      11             : #include "settings.h"
      12             : #include "camera.h"           // CameraModes
      13             : 
      14             : //! constructor
      15           1 : Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
      16             :                 ITextureSource *tsrc):
      17             :                 scene::ISceneNode(parent, mgr, id),
      18             :                 m_visible(true),
      19             :                 m_fallback_bg_color(255,255,255,255),
      20             :                 m_first_update(true),
      21             :                 m_brightness(0.5),
      22             :                 m_cloud_brightness(0.5),
      23             :                 m_bgcolor_bright_f(1,1,1,1),
      24             :                 m_skycolor_bright_f(1,1,1,1),
      25           1 :                 m_cloudcolor_bright_f(1,1,1,1)
      26             : {
      27           1 :         setAutomaticCulling(scene::EAC_OFF);
      28           1 :         Box.MaxEdge.set(0,0,0);
      29           1 :         Box.MinEdge.set(0,0,0);
      30             : 
      31             :         // create material
      32             : 
      33           2 :         video::SMaterial mat;
      34           1 :         mat.Lighting = false;
      35           1 :         mat.ZBuffer = video::ECFN_NEVER;
      36           1 :         mat.ZWriteEnable = false;
      37           1 :         mat.AntiAliasing=0;
      38           1 :         mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
      39           1 :         mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
      40           1 :         mat.BackfaceCulling = false;
      41             : 
      42           1 :         m_materials[0] = mat;
      43             : 
      44           1 :         m_materials[1] = mat;
      45             :         //m_materials[1].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
      46           1 :         m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
      47             : 
      48           1 :         m_materials[2] = mat;
      49           1 :         m_materials[2].setTexture(0, tsrc->getTextureForMesh("sunrisebg.png"));
      50           1 :         m_materials[2].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
      51             :         //m_materials[2].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
      52             : 
      53           2 :         m_sun_texture = tsrc->isKnownSourceImage("sun.png") ?
      54           1 :                 tsrc->getTextureForMesh("sun.png") : NULL;
      55           2 :         m_moon_texture = tsrc->isKnownSourceImage("moon.png") ?
      56           1 :                 tsrc->getTextureForMesh("moon.png") : NULL;
      57           2 :         m_sun_tonemap = tsrc->isKnownSourceImage("sun_tonemap.png") ?
      58           1 :                 tsrc->getTexture("sun_tonemap.png") : NULL;
      59           2 :         m_moon_tonemap = tsrc->isKnownSourceImage("moon_tonemap.png") ?
      60           1 :                 tsrc->getTexture("moon_tonemap.png") : NULL;
      61             : 
      62           1 :         if (m_sun_texture){
      63           0 :                 m_materials[3] = mat;
      64           0 :                 m_materials[3].setTexture(0, m_sun_texture);
      65           0 :                 m_materials[3].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
      66           0 :                 if (m_sun_tonemap)
      67           0 :                         m_materials[3].Lighting = true;
      68             :         }
      69           1 :         if (m_moon_texture){
      70           0 :                 m_materials[4] = mat;
      71           0 :                 m_materials[4].setTexture(0, m_moon_texture);
      72           0 :                 m_materials[4].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
      73           0 :                 if (m_moon_tonemap)
      74           0 :                         m_materials[4].Lighting = true;
      75             :         }
      76             : 
      77         201 :         for(u32 i=0; i<SKY_STAR_COUNT; i++){
      78         800 :                 m_stars[i] = v3f(
      79         200 :                         myrand_range(-10000,10000),
      80         200 :                         myrand_range(-10000,10000),
      81         200 :                         myrand_range(-10000,10000)
      82         200 :                 );
      83         200 :                 m_stars[i].normalize();
      84             :         }
      85             : 
      86           1 :         m_directional_colored_fog = g_settings->getBool("directional_colored_fog");
      87           1 : }
      88             : 
      89        1166 : void Sky::OnRegisterSceneNode()
      90             : {
      91        1166 :         if (IsVisible)
      92        1166 :                 SceneManager->registerNodeForRendering(this, scene::ESNRP_SKY_BOX);
      93             : 
      94        1166 :         scene::ISceneNode::OnRegisterSceneNode();
      95        1166 : }
      96             : 
      97           0 : const core::aabbox3d<f32>& Sky::getBoundingBox() const
      98             : {
      99           0 :         return Box;
     100             : }
     101             : 
     102             : //! renders the node.
     103        1166 : void Sky::render()
     104             : {
     105        1166 :         if(!m_visible)
     106           0 :                 return;
     107             : 
     108        1166 :         video::IVideoDriver* driver = SceneManager->getVideoDriver();
     109        1166 :         scene::ICameraSceneNode* camera = SceneManager->getActiveCamera();
     110             : 
     111        1166 :         if (!camera || !driver)
     112           0 :                 return;
     113             :         
     114        2332 :         ScopeProfiler sp(g_profiler, "Sky::render()", SPT_AVG);
     115             : 
     116             :         // draw perspective skybox
     117             : 
     118        1166 :         core::matrix4 translate(AbsoluteTransformation);
     119        1166 :         translate.setTranslation(camera->getAbsolutePosition());
     120             : 
     121             :         // Draw the sky box between the near and far clip plane
     122        1166 :         const f32 viewDistance = (camera->getNearValue() + camera->getFarValue()) * 0.5f;
     123        1166 :         core::matrix4 scale;
     124        1166 :         scale.setScale(core::vector3df(viewDistance, viewDistance, viewDistance));
     125             : 
     126        1166 :         driver->setTransform(video::ETS_WORLD, translate * scale);
     127             : 
     128        1166 :         if(m_sunlight_seen)
     129             :         {
     130        1166 :                 float sunsize = 0.07;
     131        1166 :                 video::SColorf suncolor_f(1, 1, 0, 1);
     132        1166 :                 suncolor_f.r = 1;
     133        1166 :                 suncolor_f.g = MYMAX(0.3, MYMIN(1.0, 0.7+m_time_brightness*(0.5)));
     134        1166 :                 suncolor_f.b = MYMAX(0.0, m_brightness*0.95);
     135        1166 :                 video::SColorf suncolor2_f(1, 1, 1, 1);
     136        1166 :                 suncolor_f.r = 1;
     137        1166 :                 suncolor_f.g = MYMAX(0.3, MYMIN(1.0, 0.85+m_time_brightness*(0.5)));
     138        1166 :                 suncolor_f.b = MYMAX(0.0, m_brightness);
     139             : 
     140        1166 :                 float moonsize = 0.04;
     141        1166 :                 video::SColorf mooncolor_f(0.50, 0.57, 0.65, 1);
     142        1166 :                 video::SColorf mooncolor2_f(0.85, 0.875, 0.9, 1);
     143             :                 
     144        1166 :                 float nightlength = 0.415;
     145        1166 :                 float wn = nightlength / 2;
     146        1166 :                 float wicked_time_of_day = 0;
     147        1166 :                 if(m_time_of_day > wn && m_time_of_day < 1.0 - wn)
     148        1166 :                         wicked_time_of_day = (m_time_of_day - wn)/(1.0-wn*2)*0.5 + 0.25;
     149           0 :                 else if(m_time_of_day < 0.5)
     150           0 :                         wicked_time_of_day = m_time_of_day / wn * 0.25;
     151             :                 else
     152           0 :                         wicked_time_of_day = 1.0 - ((1.0-m_time_of_day) / wn * 0.25);
     153             :                 /*std::cerr<<"time_of_day="<<m_time_of_day<<" -> "
     154             :                                 <<"wicked_time_of_day="<<wicked_time_of_day<<std::endl;*/
     155             : 
     156        1166 :                 video::SColor suncolor = suncolor_f.toSColor();
     157        1166 :                 video::SColor suncolor2 = suncolor2_f.toSColor();
     158        1166 :                 video::SColor mooncolor = mooncolor_f.toSColor();
     159        1166 :                 video::SColor mooncolor2 = mooncolor2_f.toSColor();
     160             : 
     161             :                 // Calculate offset normalized to the X dimension of a 512x1 px tonemap
     162        1166 :                 float offset=(1.0-fabs(sin((m_time_of_day - 0.5)*irr::core::PI)))*511;
     163             : 
     164        1166 :                 if (m_sun_tonemap){
     165           0 :                         u8 * texels = (u8 *)m_sun_tonemap->lock();
     166           0 :                         video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4);
     167           0 :                         video::SColor texel_color (255,texel->getRed(),texel->getGreen(), texel->getBlue());
     168           0 :                         m_sun_tonemap->unlock();
     169           0 :                         m_materials[3].EmissiveColor = texel_color;
     170             :                 }
     171        1166 :                 if (m_moon_tonemap){
     172           0 :                         u8 * texels = (u8 *)m_moon_tonemap->lock();
     173           0 :                         video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4);
     174           0 :                         video::SColor texel_color (255,texel->getRed(),texel->getGreen(), texel->getBlue());
     175           0 :                         m_moon_tonemap->unlock();
     176           0 :                         m_materials[4].EmissiveColor = texel_color;
     177             :                 }
     178             : 
     179        1166 :                 const f32 t = 1.0f;
     180        1166 :                 const f32 o = 0.0f;
     181             :                 static const u16 indices[4] = {0,1,2,3};
     182        1166 :                 video::S3DVertex vertices[4];
     183             :                 
     184        1166 :                 driver->setMaterial(m_materials[1]);
     185             :                 
     186             :                 //video::SColor cloudyfogcolor(255,255,255,255);
     187        1166 :                 video::SColor cloudyfogcolor = m_bgcolor;
     188             :                 //video::SColor cloudyfogcolor = m_bgcolor.getInterpolated(m_skycolor, 0.5);
     189             :                 
     190             :                 // Draw far cloudy fog thing
     191        5830 :                 for(u32 j=0; j<4; j++)
     192             :                 {
     193        4664 :                         video::SColor c = cloudyfogcolor.getInterpolated(m_skycolor, 0.45);
     194        4664 :                         vertices[0] = video::S3DVertex(-1, 0.08,-1, 0,0,1, c, t, t);
     195        4664 :                         vertices[1] = video::S3DVertex( 1, 0.08,-1, 0,0,1, c, o, t);
     196        4664 :                         vertices[2] = video::S3DVertex( 1, 0.12,-1, 0,0,1, c, o, o);
     197        4664 :                         vertices[3] = video::S3DVertex(-1, 0.12,-1, 0,0,1, c, t, o);
     198       23320 :                         for(u32 i=0; i<4; i++){
     199       18656 :                                 if(j==0)
     200             :                                         // Don't switch
     201             :                                         {}
     202       13992 :                                 else if(j==1)
     203             :                                         // Switch from -Z (south) to +X (east)
     204        4664 :                                         vertices[i].Pos.rotateXZBy(90);
     205        9328 :                                 else if(j==2)
     206             :                                         // Switch from -Z (south) to -X (west)
     207        4664 :                                         vertices[i].Pos.rotateXZBy(-90);
     208             :                                 else
     209             :                                         // Switch from -Z (south) to -Z (north)
     210        4664 :                                         vertices[i].Pos.rotateXZBy(-180);
     211             :                         }
     212        4664 :                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     213             :                 }
     214        5830 :                 for(u32 j=0; j<4; j++)
     215             :                 {
     216        4664 :                         video::SColor c = cloudyfogcolor;
     217        4664 :                         vertices[0] = video::S3DVertex(-1,-1.0,-1, 0,0,1, c, t, t);
     218        4664 :                         vertices[1] = video::S3DVertex( 1,-1.0,-1, 0,0,1, c, o, t);
     219        4664 :                         vertices[2] = video::S3DVertex( 1, 0.08,-1, 0,0,1, c, o, o);
     220        4664 :                         vertices[3] = video::S3DVertex(-1, 0.08,-1, 0,0,1, c, t, o);
     221       23320 :                         for(u32 i=0; i<4; i++){
     222       18656 :                                 if(j==0)
     223             :                                         // Don't switch
     224             :                                         {}
     225       13992 :                                 else if(j==1)
     226             :                                         // Switch from -Z (south) to +X (east)
     227        4664 :                                         vertices[i].Pos.rotateXZBy(90);
     228        9328 :                                 else if(j==2)
     229             :                                         // Switch from -Z (south) to -X (west)
     230        4664 :                                         vertices[i].Pos.rotateXZBy(-90);
     231             :                                 else
     232             :                                         // Switch from -Z (south) to -Z (north)
     233        4664 :                                         vertices[i].Pos.rotateXZBy(-180);
     234             :                         }
     235        4664 :                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     236             :                 }
     237             : 
     238        1166 :                 driver->setMaterial(m_materials[2]);
     239             : 
     240             :                 {
     241        1166 :                         float mid1 = 0.25;
     242        1166 :                         float mid = (wicked_time_of_day < 0.5 ? mid1 : (1.0 - mid1));
     243        1166 :                         float a_ = 1.0 - fabs(wicked_time_of_day - mid) * 35.0;
     244        1166 :                         float a = easeCurve(MYMAX(0, MYMIN(1, a_)));
     245             :                         //std::cerr<<"a_="<<a_<<" a="<<a<<std::endl;
     246        1166 :                         video::SColor c(255,255,255,255);
     247        1166 :                         float y = -(1.0 - a) * 0.2;
     248        1166 :                         vertices[0] = video::S3DVertex(-1,-0.05+y,-1, 0,0,1, c, t, t);
     249        1166 :                         vertices[1] = video::S3DVertex( 1,-0.05+y,-1, 0,0,1, c, o, t);
     250        1166 :                         vertices[2] = video::S3DVertex( 1, 0.2+y,-1, 0,0,1, c, o, o);
     251        1166 :                         vertices[3] = video::S3DVertex(-1, 0.2+y,-1, 0,0,1, c, t, o);
     252        5830 :                         for(u32 i=0; i<4; i++){
     253        4664 :                                 if(wicked_time_of_day < 0.5)
     254             :                                         // Switch from -Z (south) to +X (east)
     255        4664 :                                         vertices[i].Pos.rotateXZBy(90);
     256             :                                 else
     257             :                                         // Switch from -Z (south) to -X (west)
     258           0 :                                         vertices[i].Pos.rotateXZBy(-90);
     259             :                         }
     260        1166 :                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     261             :                 }
     262             : 
     263             :                 // Draw sun
     264        1166 :                 if(wicked_time_of_day > 0.15 && wicked_time_of_day < 0.85){
     265        1166 :                         if (!m_sun_texture){
     266        1166 :                                 driver->setMaterial(m_materials[1]);
     267        1166 :                                 float d = sunsize * 1.7;
     268        1166 :                                 video::SColor c = suncolor;
     269        1166 :                                 c.setAlpha(0.05*255);
     270        1166 :                                 vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, c, t, t);
     271        1166 :                                 vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, c, o, t);
     272        1166 :                                 vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, c, o, o);
     273        1166 :                                 vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, c, t, o);
     274        5830 :                                 for(u32 i=0; i<4; i++){
     275             :                                         // Switch from -Z (south) to +X (east)
     276        4664 :                                         vertices[i].Pos.rotateXZBy(90);
     277        4664 :                                         vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
     278             :                                 }
     279        1166 :                                 driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     280             : 
     281        1166 :                                 d = sunsize * 1.2;
     282        1166 :                                 c = suncolor;
     283        1166 :                                 c.setAlpha(0.15*255);
     284        1166 :                                 vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, c, t, t);
     285        1166 :                                 vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, c, o, t);
     286        1166 :                                 vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, c, o, o);
     287        1166 :                                 vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, c, t, o);
     288        5830 :                                 for(u32 i=0; i<4; i++){
     289             :                                         // Switch from -Z (south) to +X (east)
     290        4664 :                                         vertices[i].Pos.rotateXZBy(90);
     291        4664 :                                         vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
     292             :                                 }
     293        1166 :                                 driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     294             : 
     295        1166 :                                 d = sunsize;
     296        1166 :                                 vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, suncolor, t, t);
     297        1166 :                                 vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, suncolor, o, t);
     298        1166 :                                 vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, suncolor, o, o);
     299        1166 :                                 vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, suncolor, t, o);
     300        5830 :                                 for(u32 i=0; i<4; i++){
     301             :                                         // Switch from -Z (south) to +X (east)
     302        4664 :                                         vertices[i].Pos.rotateXZBy(90);
     303        4664 :                                         vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
     304             :                                 }
     305        1166 :                                 driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     306             : 
     307        1166 :                                 d = sunsize * 0.7;
     308        1166 :                                 vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, suncolor2, t, t);
     309        1166 :                                 vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, suncolor2, o, t);
     310        1166 :                                 vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, suncolor2, o, o);
     311        1166 :                                 vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, suncolor2, t, o);
     312        5830 :                                 for(u32 i=0; i<4; i++){
     313             :                                         // Switch from -Z (south) to +X (east)
     314        4664 :                                         vertices[i].Pos.rotateXZBy(90);
     315        4664 :                                         vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
     316             :                                 }
     317        1166 :                                 driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     318             :                         } else {
     319           0 :                                 driver->setMaterial(m_materials[3]);
     320           0 :                                 float d = sunsize * 1.7;
     321           0 :                                 video::SColor c;
     322           0 :                                 if (m_sun_tonemap)
     323           0 :                                         c = video::SColor (0,0,0,0);
     324             :                                 else
     325           0 :                                         c = video::SColor (255,255,255,255);
     326           0 :                                 vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, c, t, t);
     327           0 :                                 vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, c, o, t);
     328           0 :                                 vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, c, o, o);
     329           0 :                                 vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, c, t, o);
     330           0 :                                 for(u32 i=0; i<4; i++){
     331             :                                         // Switch from -Z (south) to +X (east)
     332           0 :                                         vertices[i].Pos.rotateXZBy(90);
     333           0 :                                         vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
     334             :                                 }
     335           0 :                                 driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     336             :                         }
     337             :                 }
     338             : 
     339             :                 // Draw moon
     340        1166 :                 if(wicked_time_of_day < 0.3 || wicked_time_of_day > 0.7)
     341             :                 {
     342           0 :                         if (!m_moon_texture){
     343           0 :                                 driver->setMaterial(m_materials[1]);
     344           0 :                                 float d = moonsize * 1.9;
     345           0 :                                 video::SColor c = mooncolor;
     346           0 :                                 c.setAlpha(0.05*255);
     347           0 :                                 vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, c, t, t);
     348           0 :                                 vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, c, o, t);
     349           0 :                                 vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, c, o, o);
     350           0 :                                 vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, c, t, o);
     351           0 :                                 for(u32 i=0; i<4; i++){
     352             :                                         // Switch from -Z (south) to -X (west)
     353           0 :                                         vertices[i].Pos.rotateXZBy(-90);
     354           0 :                                         vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
     355             :                                 }
     356           0 :                                 driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     357             :                         
     358           0 :                                 d = moonsize * 1.3;
     359           0 :                                 c = mooncolor;
     360           0 :                                 c.setAlpha(0.15*255);
     361           0 :                                 vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, c, t, t);
     362           0 :                                 vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, c, o, t);
     363           0 :                                 vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, c, o, o);
     364           0 :                                 vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, c, t, o);
     365           0 :                                 for(u32 i=0; i<4; i++){
     366             :                                         // Switch from -Z (south) to -X (west)
     367           0 :                                         vertices[i].Pos.rotateXZBy(-90);
     368           0 :                                         vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
     369             :                                 }
     370           0 :                                 driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     371             : 
     372           0 :                                 d = moonsize;
     373           0 :                                 vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, mooncolor, t, t);
     374           0 :                                 vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, mooncolor, o, t);
     375           0 :                                 vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, mooncolor, o, o);
     376           0 :                                 vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, mooncolor, t, o);
     377           0 :                                 for(u32 i=0; i<4; i++){
     378             :                                         // Switch from -Z (south) to -X (west)
     379           0 :                                         vertices[i].Pos.rotateXZBy(-90);
     380           0 :                                         vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
     381             :                                 }
     382           0 :                                 driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     383             : 
     384           0 :                                 float d2 = moonsize * 0.6;
     385           0 :                                 vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, mooncolor2, t, t);
     386           0 :                                 vertices[1] = video::S3DVertex( d2,-d,-1, 0,0,1, mooncolor2, o, t);
     387           0 :                                 vertices[2] = video::S3DVertex( d2, d2,-1, 0,0,1, mooncolor2, o, o);
     388           0 :                                 vertices[3] = video::S3DVertex(-d, d2,-1, 0,0,1, mooncolor2, t, o);
     389           0 :                                 for(u32 i=0; i<4; i++){
     390             :                                         // Switch from -Z (south) to -X (west)
     391           0 :                                         vertices[i].Pos.rotateXZBy(-90);
     392           0 :                                         vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
     393             :                                 }
     394           0 :                                 driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     395             :                         } else {
     396           0 :                                 driver->setMaterial(m_materials[4]);
     397           0 :                                 float d = moonsize * 1.9;
     398           0 :                                 video::SColor c;
     399           0 :                                 if (m_moon_tonemap)
     400           0 :                                         c = video::SColor (0,0,0,0);
     401             :                                 else
     402           0 :                                         c = video::SColor (255,255,255,255);
     403           0 :                                 vertices[0] = video::S3DVertex(-d,-d,-1, 0,0,1, c, t, t);
     404           0 :                                 vertices[1] = video::S3DVertex( d,-d,-1, 0,0,1, c, o, t);
     405           0 :                                 vertices[2] = video::S3DVertex( d, d,-1, 0,0,1, c, o, o);
     406           0 :                                 vertices[3] = video::S3DVertex(-d, d,-1, 0,0,1, c, t, o);
     407           0 :                                 for(u32 i=0; i<4; i++){
     408             :                                         // Switch from -Z (south) to -X (west)
     409           0 :                                         vertices[i].Pos.rotateXZBy(-90);
     410           0 :                                         vertices[i].Pos.rotateXYBy(wicked_time_of_day * 360 - 90);
     411             :                                 }
     412           0 :                                 driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     413             :                         }
     414             :                 }
     415             : 
     416             :                 // Stars
     417        1166 :                 driver->setMaterial(m_materials[1]);
     418             :                 do{
     419        1166 :                         float starbrightness = MYMAX(0, MYMIN(1,
     420             :                                         (0.285 - fabs(wicked_time_of_day < 0.5 ?
     421             :                                         wicked_time_of_day : (1.0 - wicked_time_of_day))) * 10));
     422        1166 :                         float f = starbrightness;
     423        1166 :                         float d = 0.007;
     424        1166 :                         video::SColor starcolor(255, f*90,f*90,f*90);
     425        1166 :                         if(starcolor.getBlue() < m_skycolor.getBlue())
     426        1166 :                                 break;
     427             :                         u16 indices[SKY_STAR_COUNT*4];
     428           0 :                         video::S3DVertex vertices[SKY_STAR_COUNT*4];
     429           0 :                         for(u32 i=0; i<SKY_STAR_COUNT; i++){
     430           0 :                                 indices[i*4+0] = i*4+0;
     431           0 :                                 indices[i*4+1] = i*4+1;
     432           0 :                                 indices[i*4+2] = i*4+2;
     433           0 :                                 indices[i*4+3] = i*4+3;
     434           0 :                                 v3f p = m_stars[i];
     435           0 :                                 core::CMatrix4<f32> a;
     436           0 :                                 a.buildRotateFromTo(v3f(0,1,0), v3f(d,1+d/2,0));
     437           0 :                                 v3f p1 = p;
     438           0 :                                 a.rotateVect(p1);
     439           0 :                                 a.buildRotateFromTo(v3f(0,1,0), v3f(d,1,d));
     440           0 :                                 v3f p2 = p;
     441           0 :                                 a.rotateVect(p2);
     442           0 :                                 a.buildRotateFromTo(v3f(0,1,0), v3f(0,1-d/2,d));
     443           0 :                                 v3f p3 = p;
     444           0 :                                 a.rotateVect(p3);
     445           0 :                                 p.rotateXYBy(wicked_time_of_day * 360 - 90);
     446           0 :                                 p1.rotateXYBy(wicked_time_of_day * 360 - 90);
     447           0 :                                 p2.rotateXYBy(wicked_time_of_day * 360 - 90);
     448           0 :                                 p3.rotateXYBy(wicked_time_of_day * 360 - 90);
     449           0 :                                 vertices[i*4+0].Pos = p;
     450           0 :                                 vertices[i*4+0].Color = starcolor;
     451           0 :                                 vertices[i*4+1].Pos = p1;
     452           0 :                                 vertices[i*4+1].Color = starcolor;
     453           0 :                                 vertices[i*4+2].Pos = p2;
     454           0 :                                 vertices[i*4+2].Color = starcolor;
     455           0 :                                 vertices[i*4+3].Pos = p3;
     456           0 :                                 vertices[i*4+3].Color = starcolor;
     457             :                         }
     458             :                         driver->drawVertexPrimitiveList(vertices, SKY_STAR_COUNT*4,
     459             :                                         indices, SKY_STAR_COUNT, video::EVT_STANDARD,
     460           0 :                                         scene::EPT_QUADS, video::EIT_16BIT);
     461             :                 }while(0);
     462             :                 
     463        3498 :                 for(u32 j=0; j<2; j++)
     464             :                 {
     465             :                         //video::SColor c = m_skycolor;
     466        2332 :                         video::SColor c = cloudyfogcolor;
     467        2332 :                         vertices[0] = video::S3DVertex(-1,-1.0,-1, 0,0,1, c, t, t);
     468        2332 :                         vertices[1] = video::S3DVertex( 1,-1.0,-1, 0,0,1, c, o, t);
     469        2332 :                         vertices[2] = video::S3DVertex( 1,-0.02,-1, 0,0,1, c, o, o);
     470        2332 :                         vertices[3] = video::S3DVertex(-1,-0.02,-1, 0,0,1, c, t, o);
     471       11660 :                         for(u32 i=0; i<4; i++){
     472             :                                 //if(wicked_time_of_day < 0.5)
     473        9328 :                                 if(j==0)
     474             :                                         // Switch from -Z (south) to +X (east)
     475        4664 :                                         vertices[i].Pos.rotateXZBy(90);
     476             :                                 else
     477             :                                         // Switch from -Z (south) to -X (west)
     478        4664 :                                         vertices[i].Pos.rotateXZBy(-90);
     479             :                         }
     480        2332 :                         driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2);
     481             :                 }
     482             :         }
     483             : }
     484             : 
     485        1266 : void Sky::update(float time_of_day, float time_brightness,
     486             :                 float direct_brightness, bool sunlight_seen,
     487             :                 CameraMode cam_mode, float yaw, float pitch)
     488             : {
     489             :         // Stabilize initial brightness and color values by flooding updates
     490        1266 :         if(m_first_update){
     491             :                 /*dstream<<"First update with time_of_day="<<time_of_day
     492             :                                 <<" time_brightness="<<time_brightness
     493             :                                 <<" direct_brightness="<<direct_brightness
     494             :                                 <<" sunlight_seen="<<sunlight_seen<<std::endl;*/
     495           1 :                 m_first_update = false;
     496         101 :                 for(u32 i=0; i<100; i++){
     497         100 :                         update(time_of_day, time_brightness, direct_brightness,
     498         100 :                                         sunlight_seen, cam_mode, yaw, pitch);
     499             :                 }
     500           2 :                 return;
     501             :         }
     502             : 
     503        1265 :         m_time_of_day = time_of_day;
     504        1265 :         m_time_brightness = time_brightness;
     505        1265 :         m_sunlight_seen = sunlight_seen;
     506             :         
     507        1265 :         bool is_dawn = (time_brightness >= 0.20 && time_brightness < 0.35);
     508             : 
     509             :         //video::SColorf bgcolor_bright_normal_f(170./255,200./255,230./255, 1.0);
     510        1265 :         video::SColorf bgcolor_bright_normal_f(155./255,193./255,240./255, 1.0);
     511        1265 :         video::SColorf bgcolor_bright_indoor_f(100./255,100./255,100./255, 1.0);
     512             :         //video::SColorf bgcolor_bright_dawn_f(0.666,200./255*0.7,230./255*0.5,1.0);
     513             :         //video::SColorf bgcolor_bright_dawn_f(0.666,0.549,0.220,1.0);
     514             :         //video::SColorf bgcolor_bright_dawn_f(0.666*1.2,0.549*1.0,0.220*1.0, 1.0);
     515             :         //video::SColorf bgcolor_bright_dawn_f(0.666*1.2,0.549*1.0,0.220*1.2,1.0);
     516             :         video::SColorf bgcolor_bright_dawn_f
     517        1265 :                         (155./255*1.2,193./255,240./255, 1.0);
     518             : 
     519             :         video::SColorf skycolor_bright_normal_f =
     520        1265 :                         video::SColor(255, 140, 186, 250);
     521             :         video::SColorf skycolor_bright_dawn_f =
     522        1265 :                         video::SColor(255, 180, 186, 250);
     523             :         
     524             :         video::SColorf cloudcolor_bright_normal_f =
     525        1265 :                         video::SColor(255, 240,240,255);
     526             :         //video::SColorf cloudcolor_bright_dawn_f(1.0, 0.591, 0.4);
     527             :         //video::SColorf cloudcolor_bright_dawn_f(1.0, 0.65, 0.44);
     528             :         //video::SColorf cloudcolor_bright_dawn_f(1.0, 0.7, 0.5);
     529        1265 :         video::SColorf cloudcolor_bright_dawn_f(1.0, 0.875, 0.75);
     530             : 
     531        1265 :         float cloud_color_change_fraction = 0.95;
     532        1265 :         if(sunlight_seen){
     533        1265 :                 if(fabs(time_brightness - m_brightness) < 0.2){
     534        1260 :                         m_brightness = m_brightness * 0.95 + time_brightness * 0.05;
     535             :                 } else {
     536           5 :                         m_brightness = m_brightness * 0.80 + time_brightness * 0.20;
     537           5 :                         cloud_color_change_fraction = 0.0;
     538             :                 }
     539             :         }
     540             :         else{
     541           0 :                 if(direct_brightness < m_brightness)
     542           0 :                         m_brightness = m_brightness * 0.95 + direct_brightness * 0.05;
     543             :                 else
     544           0 :                         m_brightness = m_brightness * 0.98 + direct_brightness * 0.02;
     545             :         }
     546             :         
     547        1265 :         m_clouds_visible = true;
     548        1265 :         float color_change_fraction = 0.98;
     549        1265 :         if(sunlight_seen){
     550        1265 :                 if(is_dawn){
     551             :                         m_bgcolor_bright_f = m_bgcolor_bright_f.getInterpolated(
     552           0 :                                         bgcolor_bright_dawn_f, color_change_fraction);
     553             :                         m_skycolor_bright_f = m_skycolor_bright_f.getInterpolated(
     554           0 :                                         skycolor_bright_dawn_f, color_change_fraction);
     555             :                         m_cloudcolor_bright_f = m_cloudcolor_bright_f.getInterpolated(
     556           0 :                                         cloudcolor_bright_dawn_f, color_change_fraction);
     557             :                 } else {
     558             :                         m_bgcolor_bright_f = m_bgcolor_bright_f.getInterpolated(
     559        1265 :                                         bgcolor_bright_normal_f, color_change_fraction);
     560             :                         m_skycolor_bright_f = m_skycolor_bright_f.getInterpolated(
     561        1265 :                                         skycolor_bright_normal_f, color_change_fraction);
     562             :                         m_cloudcolor_bright_f = m_cloudcolor_bright_f.getInterpolated(
     563        1265 :                                         cloudcolor_bright_normal_f, color_change_fraction);
     564             :                 }
     565             :         } else {
     566             :                 m_bgcolor_bright_f = m_bgcolor_bright_f.getInterpolated(
     567           0 :                                 bgcolor_bright_indoor_f, color_change_fraction);
     568             :                 m_skycolor_bright_f = m_skycolor_bright_f.getInterpolated(
     569           0 :                                 bgcolor_bright_indoor_f, color_change_fraction);
     570             :                 m_cloudcolor_bright_f = m_cloudcolor_bright_f.getInterpolated(
     571           0 :                                 cloudcolor_bright_normal_f, color_change_fraction);
     572           0 :                 m_clouds_visible = false;
     573             :         }
     574             : 
     575        1265 :         video::SColor bgcolor_bright = m_bgcolor_bright_f.toSColor();
     576             :         m_bgcolor = video::SColor(
     577             :                 255,
     578        1265 :                 bgcolor_bright.getRed() * m_brightness,
     579        1265 :                 bgcolor_bright.getGreen() * m_brightness,
     580        3795 :                 bgcolor_bright.getBlue() * m_brightness);
     581             : 
     582        1265 :         video::SColor skycolor_bright = m_skycolor_bright_f.toSColor();
     583             :         m_skycolor = video::SColor(
     584             :                 255,
     585        1265 :                 skycolor_bright.getRed() * m_brightness,
     586        1265 :                 skycolor_bright.getGreen() * m_brightness,
     587        3795 :                 skycolor_bright.getBlue() * m_brightness);
     588             : 
     589             :         // Horizon coloring based on sun and moon direction during sunset and sunrise
     590        1265 :         video::SColor pointcolor = video::SColor(255, 255, 255, m_bgcolor.getAlpha());
     591        1265 :         if (m_directional_colored_fog) {
     592        1265 :                 if (m_horizon_blend() != 0)
     593             :                 {
     594             :                         // calculate hemisphere value from yaw, (inverted in third person front view)
     595           0 :                         s8 dir_factor = 1;
     596           0 :                         if (cam_mode > CAMERA_MODE_THIRD)
     597           0 :                                 dir_factor = -1;
     598           0 :                         f32 pointcolor_blend = wrapDegrees_0_360( yaw*dir_factor + 90);
     599           0 :                         if (pointcolor_blend > 180)
     600           0 :                                 pointcolor_blend = 360 - pointcolor_blend;
     601           0 :                         pointcolor_blend /= 180;
     602             :                         // bound view angle to determine where transition starts and ends
     603           0 :                         pointcolor_blend = rangelim(1 - pointcolor_blend * 1.375, 0, 1 / 1.375) * 1.375;
     604             :                         // combine the colors when looking up or down, otherwise turning looks weird
     605           0 :                         pointcolor_blend += (0.5 - pointcolor_blend) * (1 - MYMIN((90 - std::abs(pitch)) / 90 * 1.5, 1));
     606             :                         // invert direction to match where the sun and moon are rising
     607           0 :                         if (m_time_of_day > 0.5)
     608           0 :                                 pointcolor_blend = 1 - pointcolor_blend;
     609             :                         // horizon colors of sun and moon
     610           0 :                         f32 pointcolor_light = rangelim(m_time_brightness * 3, 0.2, 1);
     611             : 
     612           0 :                         video::SColorf pointcolor_sun_f(1, 1, 1, 1);
     613           0 :                         if (m_sun_tonemap)
     614             :                         {
     615           0 :                                 pointcolor_sun_f.r = pointcolor_light * (float)m_materials[3].EmissiveColor.getRed() / 255;
     616           0 :                                 pointcolor_sun_f.b = pointcolor_light * (float)m_materials[3].EmissiveColor.getBlue() / 255;
     617           0 :                                 pointcolor_sun_f.g = pointcolor_light * (float)m_materials[3].EmissiveColor.getGreen() / 255;
     618             :                         }
     619             :                         else
     620             :                         {
     621           0 :                                 pointcolor_sun_f.r = pointcolor_light * 1;
     622           0 :                                 pointcolor_sun_f.b = pointcolor_light * (0.25 + (rangelim(m_time_brightness, 0.25, 0.75) - 0.25) * 2 * 0.75);
     623           0 :                                 pointcolor_sun_f.g = pointcolor_light * (pointcolor_sun_f.b * 0.375 + (rangelim(m_time_brightness, 0.05, 0.15) - 0.05) * 10 * 0.625);
     624             :                         }
     625             : 
     626           0 :                         video::SColorf pointcolor_moon_f(0.5 * pointcolor_light, 0.6 * pointcolor_light, 0.8 * pointcolor_light, 1);
     627           0 :                         if (m_moon_tonemap)
     628             :                         {
     629           0 :                                 pointcolor_moon_f.r = pointcolor_light * (float)m_materials[4].EmissiveColor.getRed() / 255;
     630           0 :                                 pointcolor_moon_f.b = pointcolor_light * (float)m_materials[4].EmissiveColor.getBlue() / 255;
     631           0 :                                 pointcolor_moon_f.g = pointcolor_light * (float)m_materials[4].EmissiveColor.getGreen() / 255;
     632             :                         }
     633             : 
     634           0 :                         video::SColor pointcolor_sun = pointcolor_sun_f.toSColor();
     635           0 :                         video::SColor pointcolor_moon = pointcolor_moon_f.toSColor();
     636             :                         // calculate the blend color
     637           0 :                         pointcolor = m_mix_scolor(pointcolor_moon, pointcolor_sun, pointcolor_blend);
     638             :                 }
     639        1265 :                 m_bgcolor = m_mix_scolor(m_bgcolor, pointcolor, m_horizon_blend() * 0.5);
     640        1265 :                 m_skycolor = m_mix_scolor(m_skycolor, pointcolor, m_horizon_blend() * 0.25);
     641             :         }
     642             : 
     643        1265 :         float cloud_direct_brightness = 0;
     644        1265 :         if(sunlight_seen) {
     645        1265 :                 if (!m_directional_colored_fog) {
     646           0 :                         cloud_direct_brightness = time_brightness;
     647           0 :                         if(time_brightness >= 0.2 && time_brightness < 0.7)
     648           0 :                                 cloud_direct_brightness *= 1.3;
     649             :                 }
     650             :                 else {
     651        1265 :                         cloud_direct_brightness = MYMIN(m_horizon_blend() * 0.15 + m_time_brightness, 1);
     652             :                 }
     653             :         } else {
     654           0 :                 cloud_direct_brightness = direct_brightness;
     655             :         }
     656        2530 :         m_cloud_brightness = m_cloud_brightness * cloud_color_change_fraction +
     657        2530 :                         cloud_direct_brightness * (1.0 - cloud_color_change_fraction);
     658             :         m_cloudcolor_f = video::SColorf(
     659        1265 :                         m_cloudcolor_bright_f.r * m_cloud_brightness,
     660        1265 :                         m_cloudcolor_bright_f.g * m_cloud_brightness,
     661        1265 :                         m_cloudcolor_bright_f.b * m_cloud_brightness,
     662        3795 :                         1.0);
     663        1265 :         if (m_directional_colored_fog) {
     664        1265 :                 m_cloudcolor_f = m_mix_scolorf(m_cloudcolor_f, video::SColorf(pointcolor), m_horizon_blend() * 0.25);
     665             :         }
     666             : 
     667           3 : }
     668             : 
     669             : 

Generated by: LCOV version 1.11