before daynight mesh cache

This commit is contained in:
Perttu Ahola 2010-12-18 17:46:00 +02:00
parent 15a43c5ed0
commit 240499dc2c
13 changed files with 442 additions and 216 deletions

@ -81,7 +81,9 @@ Client::Client(IrrlichtDevice *device,
camera_direction(0,0,1), camera_direction(0,0,1),
m_server_ser_ver(SER_FMT_VER_INVALID), m_server_ser_ver(SER_FMT_VER_INVALID),
m_step_dtime(0.0), m_step_dtime(0.0),
m_inventory_updated(false) m_inventory_updated(false),
m_time(0),
m_time_counter(0.0)
{ {
//m_fetchblock_mutex.Init(); //m_fetchblock_mutex.Init();
m_incoming_queue_mutex.Init(); m_incoming_queue_mutex.Init();
@ -142,6 +144,29 @@ void Client::step(float dtime)
if(dtime > 2.0) if(dtime > 2.0)
dtime = 2.0; dtime = 2.0;
/*
Day/night
*/
{
m_time_counter += dtime;
int seconds = (int)m_time_counter;
m_time_counter -= (float)seconds;
m_time += seconds;
if(seconds > 0)
{
dstream<<"m_time="<<m_time<<std::endl;
JMutexAutoLock envlock(m_env_mutex);
u32 dr = 500+500*sin((float)((m_time/10)%7)/7.*2.*PI);
if(dr != m_env.getDaylightRatio())
{
dstream<<"dr="<<dr<<std::endl;
m_env.setDaylightRatio(dr);
m_env.expireMeshes();
}
}
}
//dstream<<"Client steps "<<dtime<<std::endl; //dstream<<"Client steps "<<dtime<<std::endl;
{ {
@ -1755,4 +1780,9 @@ void Client::printDebugInfo(std::ostream &os)
<<std::endl; <<std::endl;
} }
float Client::getDaylightRatio()
{
JMutexAutoLock envlock(m_env_mutex);
return m_env.getDaylightRatio();
}

@ -133,7 +133,7 @@ public:
i.atEnd() == false; i++) i.atEnd() == false; i++)
{ {
v3s16 p = i.getNode()->getKey(); v3s16 p = i.getNode()->getKey();
m_env->getMap().updateMeshes(p); m_env->updateMeshes(p);
} }
m_blocks.clear(); m_blocks.clear();
} }
@ -237,6 +237,8 @@ public:
// Prints a line or two of info // Prints a line or two of info
void printDebugInfo(std::ostream &os); void printDebugInfo(std::ostream &os);
float getDaylightRatio();
private: private:
// Virtual methods from con::PeerHandler // Virtual methods from con::PeerHandler
@ -284,6 +286,10 @@ private:
core::map<v3s16, bool> m_active_blocks; core::map<v3s16, bool> m_active_blocks;
PacketCounter m_packetcounter; PacketCounter m_packetcounter;
// Access these only in main thread.
u32 m_time;
float m_time_counter;
}; };
#endif #endif

@ -24,6 +24,7 @@ Environment::Environment(Map *map, std::ostream &dout):
m_dout(dout) m_dout(dout)
{ {
m_map = map; m_map = map;
m_daylight_ratio = 0.2;
} }
Environment::~Environment() Environment::~Environment()
@ -152,7 +153,7 @@ void Environment::step(float dtime)
{ {
v3s16 p_blocks = getNodeBlockPos(bottompos); v3s16 p_blocks = getNodeBlockPos(bottompos);
MapBlock *b = m_map->getBlockNoCreate(p_blocks); MapBlock *b = m_map->getBlockNoCreate(p_blocks);
b->updateMesh(); b->updateMesh(m_daylight_ratio);
} }
} }
} }
@ -240,3 +241,23 @@ void Environment::printPlayers(std::ostream &o)
} }
} }
void Environment::updateMeshes(v3s16 blockpos)
{
m_map->updateMeshes(blockpos, m_daylight_ratio);
}
void Environment::expireMeshes()
{
m_map->expireMeshes();
}
void Environment::setDaylightRatio(u32 r)
{
m_daylight_ratio = r;
}
u32 Environment::getDaylightRatio()
{
return m_daylight_ratio;
}

@ -49,6 +49,7 @@ public:
void step(f32 dtime); void step(f32 dtime);
Map & getMap(); Map & getMap();
/* /*
Environment deallocates players after use. Environment deallocates players after use.
*/ */
@ -58,11 +59,18 @@ public:
Player * getPlayer(u16 peer_id); Player * getPlayer(u16 peer_id);
core::list<Player*> getPlayers(); core::list<Player*> getPlayers();
void printPlayers(std::ostream &o); void printPlayers(std::ostream &o);
void updateMeshes(v3s16 blockpos);
void expireMeshes();
void setDaylightRatio(u32 r);
u32 getDaylightRatio();
private: private:
Map *m_map; Map *m_map;
core::list<Player*> m_players; core::list<Player*> m_players;
// Debug output goes here // Debug output goes here
std::ostream &m_dout; std::ostream &m_dout;
u32 m_daylight_ratio;
}; };
#endif #endif

@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "light.h" #include "light.h"
// LIGHT_MAX is 15, 0-15 is 16 values // LIGHT_MAX is 14, 0-14 is 15 values
/*u8 light_decode_table[LIGHT_MAX+1] = /*u8 light_decode_table[LIGHT_MAX+1] =
{ {
0, 0,

@ -22,6 +22,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h" #include "common_irrlicht.h"
/*
Lower level lighting stuff
*/
// This directly sets the range of light // This directly sets the range of light
#define LIGHT_MAX 14 #define LIGHT_MAX 14
// Light is stored as 4 bits, thus 15 is the maximum. // Light is stored as 4 bits, thus 15 is the maximum.

@ -210,7 +210,8 @@ bool Map::isNodeUnderground(v3s16 p)
values of from_nodes are lighting values. values of from_nodes are lighting values.
*/ */
void Map::unspreadLight(core::map<v3s16, u8> & from_nodes, void Map::unspreadLight(enum LightBank bank,
core::map<v3s16, u8> & from_nodes,
core::map<v3s16, bool> & light_sources, core::map<v3s16, bool> & light_sources,
core::map<v3s16, MapBlock*> & modified_blocks) core::map<v3s16, MapBlock*> & modified_blocks)
{ {
@ -310,19 +311,19 @@ void Map::unspreadLight(core::map<v3s16, u8> & from_nodes,
If the neighbor is dimmer than what was specified If the neighbor is dimmer than what was specified
as oldlight (the light of the previous node) as oldlight (the light of the previous node)
*/ */
if(n2.getLight() < oldlight) if(n2.getLight(bank) < oldlight)
{ {
/* /*
And the neighbor is transparent and it has some light And the neighbor is transparent and it has some light
*/ */
if(n2.light_propagates() && n2.getLight() != 0) if(n2.light_propagates() && n2.getLight(bank) != 0)
{ {
/* /*
Set light to 0 and add to queue Set light to 0 and add to queue
*/ */
u8 current_light = n2.getLight(); u8 current_light = n2.getLight(bank);
n2.setLight(0); n2.setLight(bank, 0);
block->setNode(relpos, n2); block->setNode(relpos, n2);
unlighted_nodes.insert(n2pos, current_light); unlighted_nodes.insert(n2pos, current_light);
@ -371,27 +372,29 @@ void Map::unspreadLight(core::map<v3s16, u8> & from_nodes,
<<std::endl;*/ <<std::endl;*/
if(unlighted_nodes.size() > 0) if(unlighted_nodes.size() > 0)
unspreadLight(unlighted_nodes, light_sources, modified_blocks); unspreadLight(bank, unlighted_nodes, light_sources, modified_blocks);
} }
/* /*
A single-node wrapper of the above A single-node wrapper of the above
*/ */
void Map::unLightNeighbors(v3s16 pos, u8 lightwas, void Map::unLightNeighbors(enum LightBank bank,
v3s16 pos, u8 lightwas,
core::map<v3s16, bool> & light_sources, core::map<v3s16, bool> & light_sources,
core::map<v3s16, MapBlock*> & modified_blocks) core::map<v3s16, MapBlock*> & modified_blocks)
{ {
core::map<v3s16, u8> from_nodes; core::map<v3s16, u8> from_nodes;
from_nodes.insert(pos, lightwas); from_nodes.insert(pos, lightwas);
unspreadLight(from_nodes, light_sources, modified_blocks); unspreadLight(bank, from_nodes, light_sources, modified_blocks);
} }
/* /*
Lights neighbors of from_nodes, collects all them and then Lights neighbors of from_nodes, collects all them and then
goes on recursively. goes on recursively.
*/ */
void Map::spreadLight(core::map<v3s16, bool> & from_nodes, void Map::spreadLight(enum LightBank bank,
core::map<v3s16, bool> & from_nodes,
core::map<v3s16, MapBlock*> & modified_blocks) core::map<v3s16, MapBlock*> & modified_blocks)
{ {
const v3s16 dirs[6] = { const v3s16 dirs[6] = {
@ -452,7 +455,7 @@ void Map::spreadLight(core::map<v3s16, bool> & from_nodes,
// Get node straight from the block // Get node straight from the block
MapNode n = block->getNode(relpos); MapNode n = block->getNode(relpos);
u8 oldlight = n.getLight(); u8 oldlight = n.getLight(bank);
u8 newlight = diminish_light(oldlight); u8 newlight = diminish_light(oldlight);
// Loop through 6 neighbors // Loop through 6 neighbors
@ -490,7 +493,7 @@ void Map::spreadLight(core::map<v3s16, bool> & from_nodes,
If the neighbor is brighter than the current node, If the neighbor is brighter than the current node,
add to list (it will light up this node on its turn) add to list (it will light up this node on its turn)
*/ */
if(n2.getLight() > undiminish_light(oldlight)) if(n2.getLight(bank) > undiminish_light(oldlight))
{ {
lighted_nodes.insert(n2pos, true); lighted_nodes.insert(n2pos, true);
//lighted_nodes.push_back(n2pos); //lighted_nodes.push_back(n2pos);
@ -500,11 +503,11 @@ void Map::spreadLight(core::map<v3s16, bool> & from_nodes,
If the neighbor is dimmer than how much light this node If the neighbor is dimmer than how much light this node
would spread on it, add to list would spread on it, add to list
*/ */
if(n2.getLight() < newlight) if(n2.getLight(bank) < newlight)
{ {
if(n2.light_propagates()) if(n2.light_propagates())
{ {
n2.setLight(newlight); n2.setLight(bank, newlight);
block->setNode(relpos, n2); block->setNode(relpos, n2);
lighted_nodes.insert(n2pos, true); lighted_nodes.insert(n2pos, true);
//lighted_nodes.push_back(n2pos); //lighted_nodes.push_back(n2pos);
@ -536,21 +539,22 @@ void Map::spreadLight(core::map<v3s16, bool> & from_nodes,
<<std::endl;*/ <<std::endl;*/
if(lighted_nodes.size() > 0) if(lighted_nodes.size() > 0)
spreadLight(lighted_nodes, modified_blocks); spreadLight(bank, lighted_nodes, modified_blocks);
} }
/* /*
A single-node source variation of the above. A single-node source variation of the above.
*/ */
void Map::lightNeighbors(v3s16 pos, void Map::lightNeighbors(enum LightBank bank,
v3s16 pos,
core::map<v3s16, MapBlock*> & modified_blocks) core::map<v3s16, MapBlock*> & modified_blocks)
{ {
core::map<v3s16, bool> from_nodes; core::map<v3s16, bool> from_nodes;
from_nodes.insert(pos, true); from_nodes.insert(pos, true);
spreadLight(from_nodes, modified_blocks); spreadLight(bank, from_nodes, modified_blocks);
} }
v3s16 Map::getBrightestNeighbour(v3s16 p) v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
{ {
v3s16 dirs[6] = { v3s16 dirs[6] = {
v3s16(0,0,1), // back v3s16(0,0,1), // back
@ -577,8 +581,8 @@ v3s16 Map::getBrightestNeighbour(v3s16 p)
{ {
continue; continue;
} }
if(n2.getLight() > brightest_light || found_something == false){ if(n2.getLight(bank) > brightest_light || found_something == false){
brightest_light = n2.getLight(); brightest_light = n2.getLight(bank);
brightest_pos = n2pos; brightest_pos = n2pos;
found_something = true; found_something = true;
} }
@ -619,7 +623,7 @@ s16 Map::propagateSunlight(v3s16 start,
if(n.sunlight_propagates()) if(n.sunlight_propagates())
{ {
n.setLight(LIGHT_SUN); n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
block->setNode(relpos, n); block->setNode(relpos, n);
modified_blocks.insert(blockpos, block); modified_blocks.insert(blockpos, block);
@ -631,7 +635,8 @@ s16 Map::propagateSunlight(v3s16 start,
return y + 1; return y + 1;
} }
void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks, void Map::updateLighting(enum LightBank bank,
core::map<v3s16, MapBlock*> & a_blocks,
core::map<v3s16, MapBlock*> & modified_blocks) core::map<v3s16, MapBlock*> & modified_blocks)
{ {
/*m_dout<<DTIME<<"Map::updateLighting(): " /*m_dout<<DTIME<<"Map::updateLighting(): "
@ -671,8 +676,8 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
try{ try{
v3s16 p(x,y,z); v3s16 p(x,y,z);
MapNode n = block->getNode(v3s16(x,y,z)); MapNode n = block->getNode(v3s16(x,y,z));
u8 oldlight = n.getLight(); u8 oldlight = n.getLight(bank);
n.setLight(0); n.setLight(bank, 0);
block->setNode(v3s16(x,y,z), n); block->setNode(v3s16(x,y,z), n);
// Collect borders for unlighting // Collect borders for unlighting
@ -699,11 +704,22 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
} }
} }
if(bank == LIGHTBANK_DAY)
{
bool bottom_valid = block->propagateSunlight(light_sources); bool bottom_valid = block->propagateSunlight(light_sources);
// If bottom is valid, we're done. // If bottom is valid, we're done.
if(bottom_valid) if(bottom_valid)
break; break;
}
else if(bank == LIGHTBANK_NIGHT)
{
break;
}
else
{
assert(0);
}
/*dstream<<"Bottom for sunlight-propagated block (" /*dstream<<"Bottom for sunlight-propagated block ("
<<pos.X<<","<<pos.Y<<","<<pos.Z<<") not valid" <<pos.X<<","<<pos.Y<<","<<pos.Z<<") not valid"
@ -725,7 +741,7 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
{ {
//TimeTaker timer("unspreadLight", g_device); //TimeTaker timer("unspreadLight", g_device);
unspreadLight(unlight_from, light_sources, modified_blocks); unspreadLight(bank, unlight_from, light_sources, modified_blocks);
} }
if(debug) if(debug)
@ -744,7 +760,7 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
{ {
//TimeTaker timer("spreadLight", g_device); //TimeTaker timer("spreadLight", g_device);
spreadLight(light_sources, modified_blocks); spreadLight(bank, light_sources, modified_blocks);
} }
if(debug) if(debug)
@ -757,6 +773,13 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
//m_dout<<"Done ("<<getTimestamp()<<")"<<std::endl; //m_dout<<"Done ("<<getTimestamp()<<")"<<std::endl;
} }
void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
core::map<v3s16, MapBlock*> & modified_blocks)
{
updateLighting(LIGHTBANK_DAY, a_blocks, modified_blocks);
updateLighting(LIGHTBANK_NIGHT, a_blocks, modified_blocks);
}
/* /*
This is called after changing a node from transparent to opaque. This is called after changing a node from transparent to opaque.
The lighting value of the node should be left as-is after changing The lighting value of the node should be left as-is after changing
@ -771,12 +794,6 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
m_dout<<DTIME<<"Map::nodeAddedUpdate(): p=(" m_dout<<DTIME<<"Map::nodeAddedUpdate(): p=("
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/ <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
u8 lightwas = getNode(p).getLight();
//core::list<v3s16> light_sources;
core::map<v3s16, bool> light_sources;
//MapNode n = getNode(p);
/* /*
From this node to nodes underneath: From this node to nodes underneath:
If lighting is sunlight (1.0), unlight neighbours and If lighting is sunlight (1.0), unlight neighbours and
@ -784,10 +801,11 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
Else discontinue. Else discontinue.
*/ */
bool node_under_sunlight = true;
v3s16 toppos = p + v3s16(0,1,0); v3s16 toppos = p + v3s16(0,1,0);
bool node_under_sunlight = true;
core::map<v3s16, bool> light_sources;
/* /*
If there is a node at top and it doesn't have sunlight, If there is a node at top and it doesn't have sunlight,
there has not been any sunlight going down. there has not been any sunlight going down.
@ -797,13 +815,24 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
try{ try{
MapNode topnode = getNode(toppos); MapNode topnode = getNode(toppos);
if(topnode.getLight() != LIGHT_SUN) if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
node_under_sunlight = false; node_under_sunlight = false;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
{ {
} }
enum LightBank banks[] =
{
LIGHTBANK_DAY,
LIGHTBANK_NIGHT
};
for(s32 i=0; i<2; i++)
{
enum LightBank bank = banks[i];
u8 lightwas = getNode(p).getLight(bank);
// Add the block of the added node to modified_blocks // Add the block of the added node to modified_blocks
v3s16 blockpos = getNodeBlockPos(p); v3s16 blockpos = getNodeBlockPos(p);
MapBlock * block = getBlockNoCreate(blockpos); MapBlock * block = getBlockNoCreate(blockpos);
@ -818,15 +847,19 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
// to 0. // to 0.
// This also collects the nodes at the border which will spread // This also collects the nodes at the border which will spread
// light again into this. // light again into this.
unLightNeighbors(p, lightwas, light_sources, modified_blocks); unLightNeighbors(bank, p, lightwas, light_sources, modified_blocks);
n.setLight(bank, 0);
}
n.setLight(0);
setNode(p, n); setNode(p, n);
/* /*
If node is under sunlight, take all sunlighted nodes under If node is under sunlight, take all sunlighted nodes under
it and clear light from them and from where the light has it and clear light from them and from where the light has
been spread. been spread.
TODO: This could be optimized by mass-unlighting instead
of looping
*/ */
if(node_under_sunlight) if(node_under_sunlight)
{ {
@ -844,11 +877,13 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
break; break;
} }
if(n2.getLight() == LIGHT_SUN) if(n2.getLight(LIGHTBANK_DAY) == LIGHT_SUN)
{ {
//m_dout<<DTIME<<"doing"<<std::endl; //m_dout<<DTIME<<"doing"<<std::endl;
unLightNeighbors(n2pos, n2.getLight(), light_sources, modified_blocks); unLightNeighbors(LIGHTBANK_DAY,
n2.setLight(0); n2pos, n2.getLight(LIGHTBANK_DAY),
light_sources, modified_blocks);
n2.setLight(LIGHTBANK_DAY, 0);
setNode(n2pos, n2); setNode(n2pos, n2);
} }
else else
@ -856,11 +891,16 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
} }
} }
for(s32 i=0; i<2; i++)
{
enum LightBank bank = banks[i];
/* /*
Spread light from all nodes that might be capable of doing so Spread light from all nodes that might be capable of doing so
TODO: Convert to spreadLight TODO: Convert to spreadLight
*/ */
spreadLight(light_sources, modified_blocks); spreadLight(bank, light_sources, modified_blocks);
}
} }
/* /*
@ -879,67 +919,6 @@ void Map::removeNodeAndUpdate(v3s16 p,
// Node will be replaced with this // Node will be replaced with this
u8 replace_material = CONTENT_AIR; u8 replace_material = CONTENT_AIR;
// NOTE: Water is now managed elsewhere
#if 0
{
/*
Find out with what material the node will be replaced.
It will be replaced with the mostly seen buildable_to.
*/
v3s16 dirs[6] = {
v3s16(0,0,1), // back
v3s16(0,1,0), // top
v3s16(1,0,0), // right
v3s16(0,0,-1), // front
v3s16(0,-1,0), // bottom
v3s16(-1,0,0), // left
};
core::map<u8, u16> neighbor_rankings;
for(u32 i=0; i<sizeof(dirs)/sizeof(dirs[0]); i++)
{
try{
MapNode n2 = getNode(p + dirs[i]);
if(material_buildable_to(n2.d))
{
if(neighbor_rankings.find(n2.d) == NULL)
neighbor_rankings[n2.d] = 1;
else
neighbor_rankings[n2.d]
= neighbor_rankings[n2.d] + 1;
}
}
catch(InvalidPositionException &e)
{
}
}
u16 highest_ranking = 0;
for(core::map<u8, u16>::Iterator
i = neighbor_rankings.getIterator();
i.atEnd() == false; i++)
{
u8 m = i.getNode()->getKey();
u8 c = i.getNode()->getValue();
if(
c > highest_ranking ||
// Prefer something else than air
(c >= highest_ranking && m != CONTENT_AIR)
)
{
replace_material = m;
highest_ranking = c;
}
}
}
#endif
/* /*
If there is a node at top and it doesn't have sunlight, If there is a node at top and it doesn't have sunlight,
there will be no sunlight going down. there will be no sunlight going down.
@ -947,33 +926,50 @@ void Map::removeNodeAndUpdate(v3s16 p,
try{ try{
MapNode topnode = getNode(toppos); MapNode topnode = getNode(toppos);
if(topnode.getLight() != LIGHT_SUN) if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
node_under_sunlight = false; node_under_sunlight = false;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
{ {
} }
core::map<v3s16, bool> light_sources;
enum LightBank banks[] =
{
LIGHTBANK_DAY,
LIGHTBANK_NIGHT
};
for(s32 i=0; i<2; i++)
{
enum LightBank bank = banks[i];
/* /*
Unlight neighbors (in case the node is a light source) Unlight neighbors (in case the node is a light source)
*/ */
//core::list<v3s16> light_sources; unLightNeighbors(bank, p,
core::map<v3s16, bool> light_sources; getNode(p).getLight(bank),
unLightNeighbors(p, getNode(p).getLight(),
light_sources, modified_blocks); light_sources, modified_blocks);
}
/* /*
Remove the node Remove the node.
This also clears the lighting.
*/ */
MapNode n; MapNode n;
n.d = replace_material; n.d = replace_material;
n.setLight(0);
setNode(p, n); setNode(p, n);
for(s32 i=0; i<2; i++)
{
enum LightBank bank = banks[i];
/* /*
Recalculate lighting Recalculate lighting
*/ */
spreadLight(light_sources, modified_blocks); spreadLight(bank, light_sources, modified_blocks);
}
// Add the block of the removed node to modified_blocks // Add the block of the removed node to modified_blocks
v3s16 blockpos = getNodeBlockPos(p); v3s16 blockpos = getNodeBlockPos(p);
@ -999,15 +995,16 @@ void Map::removeNodeAndUpdate(v3s16 p,
/*m_dout<<DTIME<<"lighting neighbors of node (" /*m_dout<<DTIME<<"lighting neighbors of node ("
<<p2.X<<","<<p2.Y<<","<<p2.Z<<")" <<p2.X<<","<<p2.Y<<","<<p2.Z<<")"
<<std::endl;*/ <<std::endl;*/
lightNeighbors(p2, modified_blocks); lightNeighbors(LIGHTBANK_DAY, p2, modified_blocks);
} }
} }
else else
{ {
// Set the lighting of this node to 0 // Set the lighting of this node to 0
// TODO: Is this needed? Lighting is cleared up there already.
try{ try{
MapNode n = getNode(p); MapNode n = getNode(p);
n.setLight(0); n.setLight(LIGHTBANK_DAY, 0);
setNode(p, n); setNode(p, n);
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
@ -1016,43 +1013,78 @@ void Map::removeNodeAndUpdate(v3s16 p,
} }
} }
for(s32 i=0; i<2; i++)
{
enum LightBank bank = banks[i];
// Get the brightest neighbour node and propagate light from it // Get the brightest neighbour node and propagate light from it
v3s16 n2p = getBrightestNeighbour(p); v3s16 n2p = getBrightestNeighbour(bank, p);
try{ try{
MapNode n2 = getNode(n2p); MapNode n2 = getNode(n2p);
lightNeighbors(n2p, modified_blocks); lightNeighbors(bank, n2p, modified_blocks);
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
{ {
} }
}
} }
void Map::updateMeshes(v3s16 blockpos) void Map::expireMeshes()
{
TimeTaker timer("expireMeshes()", g_device);
core::map<v2s16, MapSector*>::Iterator si;
si = m_sectors.getIterator();
for(; si.atEnd() == false; si++)
{
MapSector *sector = si.getNode()->getValue();
core::list< MapBlock * > sectorblocks;
sector->getBlocks(sectorblocks);
core::list< MapBlock * >::Iterator i;
for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
{
MapBlock *block = *i;
{
JMutexAutoLock lock(block->mesh_mutex);
if(block->mesh != NULL)
{
//block->mesh->drop();
//block->mesh = NULL;
block->setMeshExpired(true);
}
}
}
}
}
void Map::updateMeshes(v3s16 blockpos, u32 daylight_factor)
{ {
assert(mapType() == MAPTYPE_CLIENT); assert(mapType() == MAPTYPE_CLIENT);
try{ try{
v3s16 p = blockpos + v3s16(0,0,0); v3s16 p = blockpos + v3s16(0,0,0);
MapBlock *b = getBlockNoCreate(p); MapBlock *b = getBlockNoCreate(p);
b->updateMesh(); b->updateMesh(daylight_factor);
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}
try{ try{
v3s16 p = blockpos + v3s16(-1,0,0); v3s16 p = blockpos + v3s16(-1,0,0);
MapBlock *b = getBlockNoCreate(p); MapBlock *b = getBlockNoCreate(p);
b->updateMesh(); b->updateMesh(daylight_factor);
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}
try{ try{
v3s16 p = blockpos + v3s16(0,-1,0); v3s16 p = blockpos + v3s16(0,-1,0);
MapBlock *b = getBlockNoCreate(p); MapBlock *b = getBlockNoCreate(p);
b->updateMesh(); b->updateMesh(daylight_factor);
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}
try{ try{
v3s16 p = blockpos + v3s16(0,0,-1); v3s16 p = blockpos + v3s16(0,0,-1);
MapBlock *b = getBlockNoCreate(p); MapBlock *b = getBlockNoCreate(p);
b->updateMesh(); b->updateMesh(daylight_factor);
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}
} }
@ -1691,7 +1723,7 @@ MapBlock * ServerMap::emergeBlock(
newly created block, they won't be taken into account. newly created block, they won't be taken into account.
*/ */
if(real_y > surface_y) if(real_y > surface_y)
n.setLight(LIGHT_SUN); n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
/* /*
Calculate material Calculate material
@ -1751,7 +1783,8 @@ MapBlock * ServerMap::emergeBlock(
if(real_y < WATER_LEVEL) if(real_y < WATER_LEVEL)
{ {
n.d = water_material; n.d = water_material;
n.setLight(diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1)); n.setLight(LIGHTBANK_DAY,
diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
} }
// else air // else air
else else
@ -2732,11 +2765,13 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
u32 vertex_count = 0; u32 vertex_count = 0;
core::map<v2s16, MapSector*>::Iterator si; // For limiting number of mesh updates per frame
u32 mesh_update_count = 0;
//NOTE: The sectors map should be locked but we're not doing it //NOTE: The sectors map should be locked but we're not doing it
// because it'd cause too much delays // because it'd cause too much delays
core::map<v2s16, MapSector*>::Iterator si;
si = m_sectors.getIterator(); si = m_sectors.getIterator();
for(; si.atEnd() == false; si++) for(; si.atEnd() == false; si++)
{ {
@ -2838,10 +2873,33 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
Draw the faces of the block Draw the faces of the block
*/ */
bool mesh_expired = false;
{
JMutexAutoLock lock(block->mesh_mutex);
mesh_expired = block->getMeshExpired();
// Mesh has not been expired and there is no mesh:
// block has no content
if(block->mesh == NULL && mesh_expired == false)
continue;
}
/*
This has to be done with the mesh_mutex unlocked
*/
if(mesh_expired && mesh_update_count < 1)
{
mesh_update_count++;
// Mesh has been expired: generate new mesh
block->updateMesh(m_client->getDaylightRatio());
}
{ {
JMutexAutoLock lock(block->mesh_mutex); JMutexAutoLock lock(block->mesh_mutex);
// Cancel if block has no mesh
if(block->mesh == NULL) if(block->mesh == NULL)
continue; continue;

@ -333,25 +333,33 @@ public:
blockref->setNode(relpos, n); blockref->setNode(relpos, n);
}*/ }*/
void unspreadLight(core::map<v3s16, u8> & from_nodes, void unspreadLight(enum LightBank bank,
core::map<v3s16, u8> & from_nodes,
core::map<v3s16, bool> & light_sources, core::map<v3s16, bool> & light_sources,
core::map<v3s16, MapBlock*> & modified_blocks); core::map<v3s16, MapBlock*> & modified_blocks);
void unLightNeighbors(v3s16 pos, u8 lightwas, void unLightNeighbors(enum LightBank bank,
v3s16 pos, u8 lightwas,
core::map<v3s16, bool> & light_sources, core::map<v3s16, bool> & light_sources,
core::map<v3s16, MapBlock*> & modified_blocks); core::map<v3s16, MapBlock*> & modified_blocks);
void spreadLight(core::map<v3s16, bool> & from_nodes, void spreadLight(enum LightBank bank,
core::map<v3s16, bool> & from_nodes,
core::map<v3s16, MapBlock*> & modified_blocks); core::map<v3s16, MapBlock*> & modified_blocks);
void lightNeighbors(v3s16 pos, void lightNeighbors(enum LightBank bank,
v3s16 pos,
core::map<v3s16, MapBlock*> & modified_blocks); core::map<v3s16, MapBlock*> & modified_blocks);
v3s16 getBrightestNeighbour(v3s16 p); v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
s16 propagateSunlight(v3s16 start, s16 propagateSunlight(v3s16 start,
core::map<v3s16, MapBlock*> & modified_blocks); core::map<v3s16, MapBlock*> & modified_blocks);
void updateLighting(enum LightBank bank,
core::map<v3s16, MapBlock*> & a_blocks,
core::map<v3s16, MapBlock*> & modified_blocks);
void updateLighting(core::map<v3s16, MapBlock*> & a_blocks, void updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
core::map<v3s16, MapBlock*> & modified_blocks); core::map<v3s16, MapBlock*> & modified_blocks);
@ -367,7 +375,9 @@ public:
Updates the faces of the given block and blocks on the Updates the faces of the given block and blocks on the
leading edge. leading edge.
*/ */
void updateMeshes(v3s16 blockpos); void updateMeshes(v3s16 blockpos, u32 daylight_factor);
void expireMeshes();
//core::aabbox3d<s16> getDisplayedBlockArea(); //core::aabbox3d<s16> getDisplayedBlockArea();

@ -147,20 +147,18 @@ FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
If either of the nodes doesn't exist, light is 0. If either of the nodes doesn't exist, light is 0.
*/ */
u8 MapBlock::getFaceLight(v3s16 p, v3s16 face_dir) u8 MapBlock::getFaceLight(u32 daylight_factor, v3s16 p, v3s16 face_dir)
{ {
try{ try{
MapNode n = getNodeParent(p); MapNode n = getNodeParent(p);
MapNode n2 = getNodeParent(p + face_dir); MapNode n2 = getNodeParent(p + face_dir);
u8 light; u8 light;
/*if(n.solidness() < n2.solidness()) u8 l1 = n.getLightBlend(daylight_factor);
light = n.getLight(); u8 l2 = n2.getLightBlend(daylight_factor);
if(l1 > l2)
light = l1;
else else
light = n2.getLight();*/ light = l2;
if(n.getLight() > n2.getLight())
light = n.getLight();
else
light = n2.getLight();
// Make some nice difference to different sides // Make some nice difference to different sides
@ -272,7 +270,9 @@ u8 MapBlock::getNodeContent(v3s16 p)
translate_dir: unit vector with only one of x, y or z translate_dir: unit vector with only one of x, y or z
face_dir: unit vector with only one of x, y or z face_dir: unit vector with only one of x, y or z
*/ */
void MapBlock::updateFastFaceRow(v3s16 startpos, void MapBlock::updateFastFaceRow(
u32 daylight_factor,
v3s16 startpos,
u16 length, u16 length,
v3s16 translate_dir, v3s16 translate_dir,
v3s16 face_dir, v3s16 face_dir,
@ -292,7 +292,7 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
/* /*
Get face light at starting position Get face light at starting position
*/ */
u8 light = getFaceLight(p, face_dir); u8 light = getFaceLight(daylight_factor, p, face_dir);
u16 continuous_tiles_count = 0; u16 continuous_tiles_count = 0;
@ -312,7 +312,7 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
p_next = p + translate_dir; p_next = p + translate_dir;
tile0_next = getNodeTile(p_next, face_dir); tile0_next = getNodeTile(p_next, face_dir);
tile1_next = getNodeTile(p_next + face_dir, -face_dir); tile1_next = getNodeTile(p_next + face_dir, -face_dir);
light_next = getFaceLight(p_next, face_dir); light_next = getFaceLight(daylight_factor, p_next, face_dir);
if(tile0_next == tile0 if(tile0_next == tile0
&& tile1_next == tile1 && tile1_next == tile1
@ -474,12 +474,13 @@ private:
core::array<PreMeshBuffer> m_prebuffers; core::array<PreMeshBuffer> m_prebuffers;
}; };
void MapBlock::updateMesh() void MapBlock::updateMesh(u32 daylight_factor)
{ {
/*v3s16 p = getPosRelative(); /*v3s16 p = getPosRelative();
std::cout<<"MapBlock("<<p.X<<","<<p.Y<<","<<p.Z<<")" std::cout<<"MapBlock("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<"::updateMesh(): ";*/ <<"::updateMesh(): ";*/
//<<"::updateMesh()"<<std::endl; //<<"::updateMesh()"<<std::endl;
TimeTaker timer1("updateMesh()", g_device);
/* /*
TODO: Change this to directly generate the mesh (and get rid TODO: Change this to directly generate the mesh (and get rid
@ -492,6 +493,9 @@ void MapBlock::updateMesh()
We are including the faces of the trailing edges of the block. We are including the faces of the trailing edges of the block.
This means that when something changes, the caller must This means that when something changes, the caller must
also update the meshes of the blocks at the leading edges. also update the meshes of the blocks at the leading edges.
NOTE: This is the slowest part of this method. The other parts
take around 0ms, this takes around 15-70ms.
*/ */
/* /*
@ -500,7 +504,8 @@ void MapBlock::updateMesh()
for(s16 y=0; y<MAP_BLOCKSIZE; y++){ for(s16 y=0; y<MAP_BLOCKSIZE; y++){
//for(s16 y=-1; y<MAP_BLOCKSIZE; y++){ //for(s16 y=-1; y<MAP_BLOCKSIZE; y++){
for(s16 z=0; z<MAP_BLOCKSIZE; z++){ for(s16 z=0; z<MAP_BLOCKSIZE; z++){
updateFastFaceRow(v3s16(0,y,z), MAP_BLOCKSIZE, updateFastFaceRow(daylight_factor,
v3s16(0,y,z), MAP_BLOCKSIZE,
v3s16(1,0,0), v3s16(1,0,0),
v3s16(0,1,0), v3s16(0,1,0),
*fastfaces_new); *fastfaces_new);
@ -512,7 +517,8 @@ void MapBlock::updateMesh()
for(s16 x=0; x<MAP_BLOCKSIZE; x++){ for(s16 x=0; x<MAP_BLOCKSIZE; x++){
//for(s16 x=-1; x<MAP_BLOCKSIZE; x++){ //for(s16 x=-1; x<MAP_BLOCKSIZE; x++){
for(s16 y=0; y<MAP_BLOCKSIZE; y++){ for(s16 y=0; y<MAP_BLOCKSIZE; y++){
updateFastFaceRow(v3s16(x,y,0), MAP_BLOCKSIZE, updateFastFaceRow(daylight_factor,
v3s16(x,y,0), MAP_BLOCKSIZE,
v3s16(0,0,1), v3s16(0,0,1),
v3s16(1,0,0), v3s16(1,0,0),
*fastfaces_new); *fastfaces_new);
@ -524,7 +530,8 @@ void MapBlock::updateMesh()
for(s16 z=0; z<MAP_BLOCKSIZE; z++){ for(s16 z=0; z<MAP_BLOCKSIZE; z++){
//for(s16 z=-1; z<MAP_BLOCKSIZE; z++){ //for(s16 z=-1; z<MAP_BLOCKSIZE; z++){
for(s16 y=0; y<MAP_BLOCKSIZE; y++){ for(s16 y=0; y<MAP_BLOCKSIZE; y++){
updateFastFaceRow(v3s16(0,y,z), MAP_BLOCKSIZE, updateFastFaceRow(daylight_factor,
v3s16(0,y,z), MAP_BLOCKSIZE,
v3s16(1,0,0), v3s16(1,0,0),
v3s16(0,0,1), v3s16(0,0,1),
*fastfaces_new); *fastfaces_new);
@ -693,6 +700,7 @@ void MapBlock::updateMesh()
scene::SMesh *mesh_old = mesh; scene::SMesh *mesh_old = mesh;
mesh = mesh_new; mesh = mesh_new;
setMeshExpired(false);
if(mesh_old != NULL) if(mesh_old != NULL)
{ {
@ -743,7 +751,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
// Check if node above block has sunlight // Check if node above block has sunlight
try{ try{
MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z)); MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z));
if(n.getLight() != LIGHT_SUN) if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
{ {
/*if(is_underground) /*if(is_underground)
{ {
@ -789,7 +797,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
if(n.sunlight_propagates()) if(n.sunlight_propagates())
{ {
n.setLight(LIGHT_SUN); n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
light_sources.insert(pos_relative + pos, true); light_sources.insert(pos_relative + pos, true);
} }
@ -809,7 +817,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
if(n.light_propagates()) if(n.light_propagates())
{ {
n.setLight(0); n.setLight(LIGHTBANK_DAY, 0);
} }
else{ else{
break; break;
@ -831,10 +839,10 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
MapNode n = getNodeParent(v3s16(x, -1, z)); MapNode n = getNodeParent(v3s16(x, -1, z));
if(n.light_propagates()) if(n.light_propagates())
{ {
if(n.getLight() == LIGHT_SUN if(n.getLight(LIGHTBANK_DAY) == LIGHT_SUN
&& sunlight_should_go_down == false) && sunlight_should_go_down == false)
block_below_is_valid = false; block_below_is_valid = false;
else if(n.getLight() != LIGHT_SUN else if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN
&& sunlight_should_go_down == true) && sunlight_should_go_down == true)
block_below_is_valid = false; block_below_is_valid = false;
} }

@ -108,6 +108,7 @@ public:
m_pos(pos), m_pos(pos),
changed(true), changed(true),
is_underground(false), is_underground(false),
m_mesh_expired(false),
m_objects(this) m_objects(this)
//is_incomplete(false) //is_incomplete(false)
{ {
@ -170,6 +171,16 @@ public:
changed = true; changed = true;
} }
void setMeshExpired(bool expired)
{
m_mesh_expired = expired;
}
bool getMeshExpired()
{
return m_mesh_expired;
}
v3s16 getPos() v3s16 getPos()
{ {
return m_pos; return m_pos;
@ -303,7 +314,7 @@ public:
static FastFace * makeFastFace(TileSpec tile, u8 light, v3f p, static FastFace * makeFastFace(TileSpec tile, u8 light, v3f p,
v3s16 dir, v3f scale, v3f posRelative_f); v3s16 dir, v3f scale, v3f posRelative_f);
u8 getFaceLight(v3s16 p, v3s16 face_dir); u8 getFaceLight(u32 daylight_factor, v3s16 p, v3s16 face_dir);
TileSpec getNodeTile(v3s16 p, v3s16 face_dir); TileSpec getNodeTile(v3s16 p, v3s16 face_dir);
u8 getNodeContent(v3s16 p); u8 getNodeContent(v3s16 p);
@ -313,13 +324,15 @@ public:
translate_dir: unit vector with only one of x, y or z translate_dir: unit vector with only one of x, y or z
face_dir: unit vector with only one of x, y or z face_dir: unit vector with only one of x, y or z
*/ */
void updateFastFaceRow(v3s16 startpos, void updateFastFaceRow(
u32 daylight_factor,
v3s16 startpos,
u16 length, u16 length,
v3s16 translate_dir, v3s16 translate_dir,
v3s16 face_dir, v3s16 face_dir,
core::list<FastFace*> &dest); core::list<FastFace*> &dest);
void updateMesh(); void updateMesh(u32 daylight_factor);
bool propagateSunlight(core::map<v3s16, bool> & light_sources); bool propagateSunlight(core::map<v3s16, bool> & light_sources);
@ -465,6 +478,8 @@ private:
*/ */
bool is_underground; bool is_underground;
bool m_mesh_expired;
MapBlockObjectList m_objects; MapBlockObjectList m_objects;
// Temporary modifications to nodes // Temporary modifications to nodes

@ -280,6 +280,12 @@ inline u16 content_tile(u8 c, v3s16 dir)
return g_content_tiles[c][dir_i]; return g_content_tiles[c][dir_i];
} }
enum LightBank
{
LIGHTBANK_DAY,
LIGHTBANK_NIGHT
};
struct MapNode struct MapNode
{ {
// Content // Content
@ -352,24 +358,77 @@ struct MapNode
return 0; return 0;
} }
u8 getLight() u8 getLightBanksWithSource()
{
// Select the brightest of [light source, propagated light]
u8 lightday = 0;
u8 lightnight = 0;
if(light_propagates())
{
lightday = param & 0x0f;
lightnight = (param>>4)&0x0f;
}
if(light_source() > lightday)
lightday = light_source();
if(light_source() > lightnight)
lightnight = light_source();
return (lightday&0x0f) | ((lightnight<<4)&0xf0);
}
void setLightBanks(u8 a_light)
{
param = a_light;
}
u8 getLight(enum LightBank bank)
{ {
// Select the brightest of [light source, propagated light] // Select the brightest of [light source, propagated light]
u8 light = 0; u8 light = 0;
if(light_propagates()) if(light_propagates())
{
if(bank == LIGHTBANK_DAY)
light = param & 0x0f; light = param & 0x0f;
else if(bank == LIGHTBANK_NIGHT)
light = (param>>4)&0x0f;
else
assert(0);
}
if(light_source() > light) if(light_source() > light)
light = light_source(); light = light_source();
return light; return light;
} }
void setLight(u8 a_light) // 0 <= daylight_factor <= 1000
u8 getLightBlend(u32 daylight_factor)
{
u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY)
+ (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT))
)/1000;
u8 max = LIGHT_MAX;
if(getLight(LIGHTBANK_DAY) == LIGHT_SUN)
max = LIGHT_SUN;
if(l > max)
l = max;
return l;
}
void setLight(enum LightBank bank, u8 a_light)
{ {
// If not transparent, can't set light // If not transparent, can't set light
if(light_propagates() == false) if(light_propagates() == false)
return; return;
if(bank == LIGHTBANK_DAY)
{
param &= 0xf0; param &= 0xf0;
param |= a_light; param |= a_light & 0x0f;
}
else if(bank == LIGHTBANK_NIGHT)
{
param &= 0x0f;
param |= (a_light & 0x0f)<<4;
}
else
assert(0);
} }
u16 getTile(v3s16 dir) u16 getTile(v3s16 dir)

@ -194,7 +194,8 @@ struct TestMapNode
// Default values // Default values
assert(n.d == CONTENT_AIR); assert(n.d == CONTENT_AIR);
assert(n.getLight() == 0); assert(n.getLight(LIGHTBANK_DAY) == 0);
assert(n.getLight(LIGHTBANK_NIGHT) == 0);
// Transparency // Transparency
n.d = CONTENT_AIR; n.d = CONTENT_AIR;
@ -432,9 +433,11 @@ struct TestMapBlock
// .d=CONTENT_AIR and .getLight() = 0 // .d=CONTENT_AIR and .getLight() = 0
for(u16 z=0; z<MAP_BLOCKSIZE; z++) for(u16 z=0; z<MAP_BLOCKSIZE; z++)
for(u16 y=0; y<MAP_BLOCKSIZE; y++) for(u16 y=0; y<MAP_BLOCKSIZE; y++)
for(u16 x=0; x<MAP_BLOCKSIZE; x++){ for(u16 x=0; x<MAP_BLOCKSIZE; x++)
{
assert(b.getNode(v3s16(x,y,z)).d == CONTENT_AIR); assert(b.getNode(v3s16(x,y,z)).d == CONTENT_AIR);
assert(b.getNode(v3s16(x,y,z)).getLight() == 0); assert(b.getNode(v3s16(x,y,z)).getLight(LIGHTBANK_DAY) == 0);
assert(b.getNode(v3s16(x,y,z)).getLight(LIGHTBANK_NIGHT) == 0);
} }
/* /*
@ -496,7 +499,8 @@ struct TestMapBlock
for(u16 y=0; y<MAP_BLOCKSIZE; y++){ for(u16 y=0; y<MAP_BLOCKSIZE; y++){
for(u16 x=0; x<MAP_BLOCKSIZE; x++){ for(u16 x=0; x<MAP_BLOCKSIZE; x++){
MapNode n = b.getNode(v3s16(x,y,z)); MapNode n = b.getNode(v3s16(x,y,z));
n.setLight(0); n.setLight(LIGHTBANK_DAY, 0);
n.setLight(LIGHTBANK_NIGHT, 0);
b.setNode(v3s16(x,y,z), n); b.setNode(v3s16(x,y,z), n);
} }
} }
@ -508,22 +512,25 @@ struct TestMapBlock
parent.position_valid = true; parent.position_valid = true;
b.setIsUnderground(false); b.setIsUnderground(false);
parent.node.d = CONTENT_AIR; parent.node.d = CONTENT_AIR;
parent.node.setLight(LIGHT_SUN); parent.node.setLight(LIGHTBANK_DAY, LIGHT_SUN);
parent.node.setLight(LIGHTBANK_NIGHT, 0);
core::map<v3s16, bool> light_sources; core::map<v3s16, bool> light_sources;
// The bottom block is invalid, because we have a shadowing node // The bottom block is invalid, because we have a shadowing node
assert(b.propagateSunlight(light_sources) == false); assert(b.propagateSunlight(light_sources) == false);
assert(b.getNode(v3s16(1,4,0)).getLight() == LIGHT_SUN); assert(b.getNode(v3s16(1,4,0)).getLight(LIGHTBANK_DAY) == LIGHT_SUN);
assert(b.getNode(v3s16(1,3,0)).getLight() == LIGHT_SUN); assert(b.getNode(v3s16(1,3,0)).getLight(LIGHTBANK_DAY) == LIGHT_SUN);
assert(b.getNode(v3s16(1,2,0)).getLight() == 0); assert(b.getNode(v3s16(1,2,0)).getLight(LIGHTBANK_DAY) == 0);
assert(b.getNode(v3s16(1,1,0)).getLight() == 0); assert(b.getNode(v3s16(1,1,0)).getLight(LIGHTBANK_DAY) == 0);
assert(b.getNode(v3s16(1,0,0)).getLight() == 0); assert(b.getNode(v3s16(1,0,0)).getLight(LIGHTBANK_DAY) == 0);
assert(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN); assert(b.getNode(v3s16(1,2,3)).getLight(LIGHTBANK_DAY) == LIGHT_SUN);
assert(b.getFaceLight(p, v3s16(0,1,0)) == LIGHT_SUN); assert(b.getFaceLight(1000, p, v3s16(0,1,0)) == LIGHT_SUN);
assert(b.getFaceLight(p, v3s16(0,-1,0)) == 0); assert(b.getFaceLight(1000, p, v3s16(0,-1,0)) == 0);
assert(b.getFaceLight(0, p, v3s16(0,-1,0)) == 0);
// According to MapBlock::getFaceLight, // According to MapBlock::getFaceLight,
// The face on the z+ side should have double-diminished light // The face on the z+ side should have double-diminished light
//assert(b.getFaceLight(p, v3s16(0,0,1)) == diminish_light(diminish_light(LIGHT_MAX))); //assert(b.getFaceLight(p, v3s16(0,0,1)) == diminish_light(diminish_light(LIGHT_MAX)));
assert(b.getFaceLight(p, v3s16(0,0,1)) == diminish_light(LIGHT_MAX)); // The face on the z+ side should have diminished light
assert(b.getFaceLight(1000, p, v3s16(0,0,1)) == diminish_light(LIGHT_MAX));
} }
/* /*
Check how the block handles being in between blocks with some non-sunlight Check how the block handles being in between blocks with some non-sunlight
@ -533,7 +540,7 @@ struct TestMapBlock
// Make neighbours to exist and set some non-sunlight to them // Make neighbours to exist and set some non-sunlight to them
parent.position_valid = true; parent.position_valid = true;
b.setIsUnderground(true); b.setIsUnderground(true);
parent.node.setLight(LIGHT_MAX/2); parent.node.setLight(LIGHTBANK_DAY, LIGHT_MAX/2);
core::map<v3s16, bool> light_sources; core::map<v3s16, bool> light_sources;
// The block below should be valid because there shouldn't be // The block below should be valid because there shouldn't be
// sunlight in there either // sunlight in there either
@ -541,7 +548,7 @@ struct TestMapBlock
// Should not touch nodes that are not affected (that is, all of them) // Should not touch nodes that are not affected (that is, all of them)
//assert(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN); //assert(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN);
// Should set light of non-sunlighted blocks to 0. // Should set light of non-sunlighted blocks to 0.
assert(b.getNode(v3s16(1,2,3)).getLight() == 0); assert(b.getNode(v3s16(1,2,3)).getLight(LIGHTBANK_DAY) == 0);
} }
/* /*
Set up a situation where: Set up a situation where:
@ -560,7 +567,7 @@ struct TestMapBlock
for(u16 x=0; x<MAP_BLOCKSIZE; x++){ for(u16 x=0; x<MAP_BLOCKSIZE; x++){
MapNode n; MapNode n;
n.d = CONTENT_AIR; n.d = CONTENT_AIR;
n.setLight(0); n.setLight(LIGHTBANK_DAY, 0);
b.setNode(v3s16(x,y,z), n); b.setNode(v3s16(x,y,z), n);
} }
} }
@ -574,7 +581,7 @@ struct TestMapBlock
parent.validity_exceptions.push_back(v3s16(MAP_BLOCKSIZE+x, MAP_BLOCKSIZE-1, MAP_BLOCKSIZE+z)); parent.validity_exceptions.push_back(v3s16(MAP_BLOCKSIZE+x, MAP_BLOCKSIZE-1, MAP_BLOCKSIZE+z));
} }
// Lighting value for the valid nodes // Lighting value for the valid nodes
parent.node.setLight(LIGHT_MAX/2); parent.node.setLight(LIGHTBANK_DAY, LIGHT_MAX/2);
core::map<v3s16, bool> light_sources; core::map<v3s16, bool> light_sources;
// Bottom block is not valid // Bottom block is not valid
assert(b.propagateSunlight(light_sources) == false); assert(b.propagateSunlight(light_sources) == false);

@ -734,12 +734,12 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
correctly. Otherwise unspreadLight will fuck up when water correctly. Otherwise unspreadLight will fuck up when water
has replaced a light source. has replaced a light source.
*/ */
u8 light = m_data[m_area.index(removed_pos)].getLight(); u8 light = m_data[m_area.index(removed_pos)].getLightBanksWithSource();
m_data[m_area.index(removed_pos)].d = m; m_data[m_area.index(removed_pos)].d = m;
m_flags[m_area.index(removed_pos)] = f; m_flags[m_area.index(removed_pos)] = f;
m_data[m_area.index(removed_pos)].setLight(light); m_data[m_area.index(removed_pos)].setLightBanks(light);
/*// NOTE: HACK: This has to be set to LIGHT_MAX so that /*// NOTE: HACK: This has to be set to LIGHT_MAX so that
// unspreadLight will clear all light that came from this node. // unspreadLight will clear all light that came from this node.