aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2012-12-02 18:02:04 +0200
committerPerttu Ahola <celeron55@gmail.com>2012-12-02 18:02:45 +0200
commit804a7875a2018f3d8cb3fbe917c11ecc1666d25a (patch)
tree8f730c91a9461d512e785e76a3a5f99e52e910d3
parent041585a78e7eeabd23d92435a8dd6fd39d329b07 (diff)
downloadminetest-804a7875a2018f3d8cb3fbe917c11ecc1666d25a.tar.gz
minetest-804a7875a2018f3d8cb3fbe917c11ecc1666d25a.tar.bz2
minetest-804a7875a2018f3d8cb3fbe917c11ecc1666d25a.zip
Smooth day-night transitions
-rw-r--r--src/camera.cpp2
-rw-r--r--src/daynightratio.h56
-rw-r--r--src/environment.cpp9
-rw-r--r--src/game.cpp3
-rw-r--r--src/light.h28
-rw-r--r--src/mapnode.h10
-rw-r--r--src/scriptapi.cpp2
7 files changed, 87 insertions, 23 deletions
diff --git a/src/camera.cpp b/src/camera.cpp
index ca2a6eb53..1b9a8c763 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -544,7 +544,7 @@ void Camera::wield(const ItemStack &item)
void Camera::drawWieldedTool()
{
// Set vertex colors of wield mesh according to light level
- u8 li = decode_light(m_wieldlight);
+ u8 li = m_wieldlight;
video::SColor color(255,li,li,li);
setMeshColor(m_wieldnode->getMesh(), color);
diff --git a/src/daynightratio.h b/src/daynightratio.h
index 9b31ecddd..96c6729eb 100644
--- a/src/daynightratio.h
+++ b/src/daynightratio.h
@@ -20,23 +20,49 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef DAYNIGHTRATIO_HEADER
#define DAYNIGHTRATIO_HEADER
-inline u32 time_to_daynight_ratio(u32 time_of_day)
+inline u32 time_to_daynight_ratio(float time_of_day, bool smooth)
{
- s32 t = time_of_day%24000;
- if(t < 4500 || t >= 19500)
- return 150;
- else if(t < 4750 || t >= 19250)
- return 250;
- else if(t < 5000 || t >= 19000)
- return 350;
- else if(t < 5250 || t >= 18750)
- return 500;
- else if(t < 5500 || t >= 18500)
- return 675;
- else if(t < 5750 || t >= 18250)
- return 875;
- else
+ float t = time_of_day;
+ if(t < 0)
+ t += ((int)(-t)/24000)*24000;
+ if(t >= 24000)
+ t -= ((int)(t)/24000)*24000;
+ if(t > 12000)
+ t = 24000 - t;
+ float values[][2] = {
+ {4250+125, 150},
+ {4500+125, 150},
+ {4750+125, 250},
+ {5000+125, 350},
+ {5250+125, 500},
+ {5500+125, 675},
+ {5750+125, 875},
+ {6000+125, 1000},
+ {6250+125, 1000},
+ };
+ if(!smooth){
+ float lastt = values[0][0];
+ for(u32 i=1; i<sizeof(values)/sizeof(*values); i++){
+ float t0 = values[i][0];
+ float switch_t = (t0 + lastt) / 2;
+ lastt = t0;
+ if(switch_t <= t)
+ continue;
+ return values[i][1];
+ }
return 1000;
+ } else {
+ for(u32 i=0; i<sizeof(values)/sizeof(*values); i++){
+ if(values[i][0] <= t)
+ continue;
+ if(i == 0)
+ return values[i][1];
+ float td0 = values[i][0] - values[i-1][0];
+ float f = (t - values[i-1][0]) / td0;
+ return f * values[i][1] + (1.0 - f) * values[i-1][1];
+ }
+ return 1000;
+ }
}
#endif
diff --git a/src/environment.cpp b/src/environment.cpp
index e70cb39b7..5bf127a17 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -203,7 +203,8 @@ void Environment::printPlayers(std::ostream &o)
u32 Environment::getDayNightRatio()
{
- return time_to_daynight_ratio(m_time_of_day);
+ bool smooth = (g_settings->getS32("enable_shaders") != 0);
+ return time_to_daynight_ratio(m_time_of_day_f*24000, smooth);
}
void Environment::stepTimeOfDay(float dtime)
@@ -2132,15 +2133,15 @@ void ClientEnvironment::step(float dtime)
}
// Update lighting on all players on client
- u8 light = LIGHT_MAX;
+ float light = 1.0;
try{
// Get node at head
v3s16 p = player->getLightPosition();
MapNode n = m_map->getNode(p);
- light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
+ light = n.getLightBlendF1((float)getDayNightRatio()/1000, m_gamedef->ndef());
}
catch(InvalidPositionException &e){
- light = blend_light(getDayNightRatio(), LIGHT_SUN, 0);
+ light = blend_light_f1((float)getDayNightRatio()/1000, LIGHT_SUN, 0);
}
player->light = light;
}
diff --git a/src/game.cpp b/src/game.cpp
index fc780a808..5c3805c3b 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -2505,8 +2505,7 @@ void the_game(
Calculate general brightness
*/
u32 daynight_ratio = client.getEnv().getDayNightRatio();
- float time_brightness = (float)decode_light(
- (daynight_ratio * LIGHT_SUN) / 1000) / 255.0;
+ float time_brightness = decode_light_f((float)daynight_ratio/1000.0);
float direct_brightness = 0;
bool sunlight_seen = false;
if(g_settings->getBool("free_move")){
diff --git a/src/light.h b/src/light.h
index 218af348e..f1c458ad8 100644
--- a/src/light.h
+++ b/src/light.h
@@ -85,6 +85,24 @@ inline u8 decode_light(u8 light)
return light_decode_table[light];
}
+// 0.0 <= light <= 1.0
+// 0.0 <= return value <= 1.0
+inline float decode_light_f(float light_f)
+{
+ s32 i = (u32)(light_f * LIGHT_MAX + 0.5);
+
+ if(i <= 0)
+ return (float)light_decode_table[0] / 255.0;
+ if(i >= LIGHT_MAX)
+ return (float)light_decode_table[LIGHT_MAX] / 255.0;
+
+ float v1 = (float)light_decode_table[i-1] / 255.0;
+ float v2 = (float)light_decode_table[i] / 255.0;
+ float f0 = (float)i - 0.5;
+ float f = light_f * LIGHT_MAX - f0;
+ return f * v2 + (1.0 - f) * v1;
+}
+
// 0 <= daylight_factor <= 1000
// 0 <= lightday, lightnight <= LIGHT_SUN
// 0 <= return value <= LIGHT_SUN
@@ -97,5 +115,15 @@ inline u8 blend_light(u32 daylight_factor, u8 lightday, u8 lightnight)
return l;
}
+// 0.0 <= daylight_factor <= 1.0
+// 0 <= lightday, lightnight <= LIGHT_SUN
+// 0 <= return value <= 255
+inline u8 blend_light_f1(float daylight_factor, u8 lightday, u8 lightnight)
+{
+ u8 l = ((daylight_factor * decode_light(lightday) +
+ (1.0-daylight_factor) * decode_light(lightnight)));
+ return l;
+}
+
#endif
diff --git a/src/mapnode.h b/src/mapnode.h
index a95497ef5..de2529e4d 100644
--- a/src/mapnode.h
+++ b/src/mapnode.h
@@ -163,6 +163,16 @@ struct MapNode
return blend_light(daylight_factor, lightday, lightnight);
}
+ // 0.0 <= daylight_factor <= 1.0
+ // 0 <= return value <= LIGHT_SUN
+ u8 getLightBlendF1(float daylight_factor, INodeDefManager *nodemgr) const
+ {
+ u8 lightday = 0;
+ u8 lightnight = 0;
+ getLightBanks(lightday, lightnight, nodemgr);
+ return blend_light_f1(daylight_factor, lightday, lightnight);
+ }
+
u8 getFaceDir(INodeDefManager *nodemgr) const;
u8 getWallMounted(INodeDefManager *nodemgr) const;
v3s16 getWallMountedDir(INodeDefManager *nodemgr) const;
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index e5815c462..e26e880a9 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -3604,7 +3604,7 @@ private:
if(lua_isnumber(L, 3))
time_of_day = 24000.0 * lua_tonumber(L, 3);
time_of_day %= 24000;
- u32 dnr = time_to_daynight_ratio(time_of_day);
+ u32 dnr = time_to_daynight_ratio(time_of_day, true);
MapNode n = env->getMap().getNodeNoEx(pos);
try{
MapNode n = env->getMap().getNode(pos);