mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 08:03:45 +01:00
before daynight mesh cache
This commit is contained in:
parent
15a43c5ed0
commit
240499dc2c
@ -81,7 +81,9 @@ Client::Client(IrrlichtDevice *device,
|
||||
camera_direction(0,0,1),
|
||||
m_server_ser_ver(SER_FMT_VER_INVALID),
|
||||
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_incoming_queue_mutex.Init();
|
||||
@ -142,6 +144,29 @@ void Client::step(float dtime)
|
||||
if(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;
|
||||
|
||||
{
|
||||
@ -1755,4 +1780,9 @@ void Client::printDebugInfo(std::ostream &os)
|
||||
<<std::endl;
|
||||
}
|
||||
|
||||
float Client::getDaylightRatio()
|
||||
{
|
||||
JMutexAutoLock envlock(m_env_mutex);
|
||||
return m_env.getDaylightRatio();
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ public:
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
v3s16 p = i.getNode()->getKey();
|
||||
m_env->getMap().updateMeshes(p);
|
||||
m_env->updateMeshes(p);
|
||||
}
|
||||
m_blocks.clear();
|
||||
}
|
||||
@ -236,6 +236,8 @@ public:
|
||||
|
||||
// Prints a line or two of info
|
||||
void printDebugInfo(std::ostream &os);
|
||||
|
||||
float getDaylightRatio();
|
||||
|
||||
private:
|
||||
|
||||
@ -284,6 +286,10 @@ private:
|
||||
core::map<v3s16, bool> m_active_blocks;
|
||||
|
||||
PacketCounter m_packetcounter;
|
||||
|
||||
// Access these only in main thread.
|
||||
u32 m_time;
|
||||
float m_time_counter;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -24,6 +24,7 @@ Environment::Environment(Map *map, std::ostream &dout):
|
||||
m_dout(dout)
|
||||
{
|
||||
m_map = map;
|
||||
m_daylight_ratio = 0.2;
|
||||
}
|
||||
|
||||
Environment::~Environment()
|
||||
@ -152,7 +153,7 @@ void Environment::step(float dtime)
|
||||
{
|
||||
v3s16 p_blocks = getNodeBlockPos(bottompos);
|
||||
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);
|
||||
|
||||
Map & getMap();
|
||||
|
||||
/*
|
||||
Environment deallocates players after use.
|
||||
*/
|
||||
@ -58,11 +59,18 @@ public:
|
||||
Player * getPlayer(u16 peer_id);
|
||||
core::list<Player*> getPlayers();
|
||||
void printPlayers(std::ostream &o);
|
||||
|
||||
void updateMeshes(v3s16 blockpos);
|
||||
void expireMeshes();
|
||||
void setDaylightRatio(u32 r);
|
||||
u32 getDaylightRatio();
|
||||
|
||||
private:
|
||||
Map *m_map;
|
||||
core::list<Player*> m_players;
|
||||
// Debug output goes here
|
||||
std::ostream &m_dout;
|
||||
u32 m_daylight_ratio;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#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] =
|
||||
{
|
||||
0,
|
||||
|
@ -22,6 +22,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include "common_irrlicht.h"
|
||||
|
||||
/*
|
||||
Lower level lighting stuff
|
||||
*/
|
||||
|
||||
// This directly sets the range of light
|
||||
#define LIGHT_MAX 14
|
||||
// Light is stored as 4 bits, thus 15 is the maximum.
|
||||
|
364
src/map.cpp
364
src/map.cpp
@ -210,7 +210,8 @@ bool Map::isNodeUnderground(v3s16 p)
|
||||
|
||||
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, 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
|
||||
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
|
||||
*/
|
||||
if(n2.light_propagates() && n2.getLight() != 0)
|
||||
if(n2.light_propagates() && n2.getLight(bank) != 0)
|
||||
{
|
||||
/*
|
||||
Set light to 0 and add to queue
|
||||
*/
|
||||
|
||||
u8 current_light = n2.getLight();
|
||||
n2.setLight(0);
|
||||
u8 current_light = n2.getLight(bank);
|
||||
n2.setLight(bank, 0);
|
||||
block->setNode(relpos, n2);
|
||||
|
||||
unlighted_nodes.insert(n2pos, current_light);
|
||||
@ -371,27 +372,29 @@ void Map::unspreadLight(core::map<v3s16, u8> & from_nodes,
|
||||
<<std::endl;*/
|
||||
|
||||
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
|
||||
*/
|
||||
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, MapBlock*> & modified_blocks)
|
||||
{
|
||||
core::map<v3s16, u8> from_nodes;
|
||||
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
|
||||
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)
|
||||
{
|
||||
const v3s16 dirs[6] = {
|
||||
@ -452,7 +455,7 @@ void Map::spreadLight(core::map<v3s16, bool> & from_nodes,
|
||||
// Get node straight from the block
|
||||
MapNode n = block->getNode(relpos);
|
||||
|
||||
u8 oldlight = n.getLight();
|
||||
u8 oldlight = n.getLight(bank);
|
||||
u8 newlight = diminish_light(oldlight);
|
||||
|
||||
// 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,
|
||||
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.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
|
||||
would spread on it, add to list
|
||||
*/
|
||||
if(n2.getLight() < newlight)
|
||||
if(n2.getLight(bank) < newlight)
|
||||
{
|
||||
if(n2.light_propagates())
|
||||
{
|
||||
n2.setLight(newlight);
|
||||
n2.setLight(bank, newlight);
|
||||
block->setNode(relpos, n2);
|
||||
lighted_nodes.insert(n2pos, true);
|
||||
//lighted_nodes.push_back(n2pos);
|
||||
@ -536,21 +539,22 @@ void Map::spreadLight(core::map<v3s16, bool> & from_nodes,
|
||||
<<std::endl;*/
|
||||
|
||||
if(lighted_nodes.size() > 0)
|
||||
spreadLight(lighted_nodes, modified_blocks);
|
||||
spreadLight(bank, lighted_nodes, modified_blocks);
|
||||
}
|
||||
|
||||
/*
|
||||
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, bool> from_nodes;
|
||||
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(0,0,1), // back
|
||||
@ -577,8 +581,8 @@ v3s16 Map::getBrightestNeighbour(v3s16 p)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(n2.getLight() > brightest_light || found_something == false){
|
||||
brightest_light = n2.getLight();
|
||||
if(n2.getLight(bank) > brightest_light || found_something == false){
|
||||
brightest_light = n2.getLight(bank);
|
||||
brightest_pos = n2pos;
|
||||
found_something = true;
|
||||
}
|
||||
@ -619,7 +623,7 @@ s16 Map::propagateSunlight(v3s16 start,
|
||||
|
||||
if(n.sunlight_propagates())
|
||||
{
|
||||
n.setLight(LIGHT_SUN);
|
||||
n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
|
||||
block->setNode(relpos, n);
|
||||
|
||||
modified_blocks.insert(blockpos, block);
|
||||
@ -631,7 +635,8 @@ s16 Map::propagateSunlight(v3s16 start,
|
||||
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)
|
||||
{
|
||||
/*m_dout<<DTIME<<"Map::updateLighting(): "
|
||||
@ -671,8 +676,8 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
|
||||
try{
|
||||
v3s16 p(x,y,z);
|
||||
MapNode n = block->getNode(v3s16(x,y,z));
|
||||
u8 oldlight = n.getLight();
|
||||
n.setLight(0);
|
||||
u8 oldlight = n.getLight(bank);
|
||||
n.setLight(bank, 0);
|
||||
block->setNode(v3s16(x,y,z), n);
|
||||
|
||||
// Collect borders for unlighting
|
||||
@ -699,11 +704,22 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
|
||||
}
|
||||
}
|
||||
|
||||
bool bottom_valid = block->propagateSunlight(light_sources);
|
||||
if(bank == LIGHTBANK_DAY)
|
||||
{
|
||||
bool bottom_valid = block->propagateSunlight(light_sources);
|
||||
|
||||
// If bottom is valid, we're done.
|
||||
if(bottom_valid)
|
||||
// If bottom is valid, we're done.
|
||||
if(bottom_valid)
|
||||
break;
|
||||
}
|
||||
else if(bank == LIGHTBANK_NIGHT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*dstream<<"Bottom for sunlight-propagated block ("
|
||||
<<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);
|
||||
unspreadLight(unlight_from, light_sources, modified_blocks);
|
||||
unspreadLight(bank, unlight_from, light_sources, modified_blocks);
|
||||
}
|
||||
|
||||
if(debug)
|
||||
@ -744,7 +760,7 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
|
||||
|
||||
{
|
||||
//TimeTaker timer("spreadLight", g_device);
|
||||
spreadLight(light_sources, modified_blocks);
|
||||
spreadLight(bank, light_sources, modified_blocks);
|
||||
}
|
||||
|
||||
if(debug)
|
||||
@ -757,6 +773,13 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
|
||||
//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.
|
||||
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=("
|
||||
<<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:
|
||||
If lighting is sunlight (1.0), unlight neighbours and
|
||||
@ -784,10 +801,11 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
Else discontinue.
|
||||
*/
|
||||
|
||||
bool node_under_sunlight = true;
|
||||
|
||||
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,
|
||||
there has not been any sunlight going down.
|
||||
@ -797,36 +815,51 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
try{
|
||||
MapNode topnode = getNode(toppos);
|
||||
|
||||
if(topnode.getLight() != LIGHT_SUN)
|
||||
if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
|
||||
node_under_sunlight = false;
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
}
|
||||
|
||||
// Add the block of the added node to modified_blocks
|
||||
v3s16 blockpos = getNodeBlockPos(p);
|
||||
MapBlock * block = getBlockNoCreate(blockpos);
|
||||
assert(block != NULL);
|
||||
modified_blocks.insert(blockpos, block);
|
||||
|
||||
if(isValidPosition(p) == false)
|
||||
throw;
|
||||
|
||||
// Unlight neighbours of node.
|
||||
// This means setting light of all consequent dimmer nodes
|
||||
// to 0.
|
||||
// This also collects the nodes at the border which will spread
|
||||
// light again into this.
|
||||
unLightNeighbors(p, lightwas, light_sources, modified_blocks);
|
||||
enum LightBank banks[] =
|
||||
{
|
||||
LIGHTBANK_DAY,
|
||||
LIGHTBANK_NIGHT
|
||||
};
|
||||
for(s32 i=0; i<2; i++)
|
||||
{
|
||||
enum LightBank bank = banks[i];
|
||||
|
||||
n.setLight(0);
|
||||
u8 lightwas = getNode(p).getLight(bank);
|
||||
|
||||
// Add the block of the added node to modified_blocks
|
||||
v3s16 blockpos = getNodeBlockPos(p);
|
||||
MapBlock * block = getBlockNoCreate(blockpos);
|
||||
assert(block != NULL);
|
||||
modified_blocks.insert(blockpos, block);
|
||||
|
||||
if(isValidPosition(p) == false)
|
||||
throw;
|
||||
|
||||
// Unlight neighbours of node.
|
||||
// This means setting light of all consequent dimmer nodes
|
||||
// to 0.
|
||||
// This also collects the nodes at the border which will spread
|
||||
// light again into this.
|
||||
unLightNeighbors(bank, p, lightwas, light_sources, modified_blocks);
|
||||
|
||||
n.setLight(bank, 0);
|
||||
}
|
||||
|
||||
setNode(p, n);
|
||||
|
||||
/*
|
||||
If node is under sunlight, take all sunlighted nodes under
|
||||
it and clear light from them and from where the light has
|
||||
been spread.
|
||||
TODO: This could be optimized by mass-unlighting instead
|
||||
of looping
|
||||
*/
|
||||
if(node_under_sunlight)
|
||||
{
|
||||
@ -844,11 +877,13 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
break;
|
||||
}
|
||||
|
||||
if(n2.getLight() == LIGHT_SUN)
|
||||
if(n2.getLight(LIGHTBANK_DAY) == LIGHT_SUN)
|
||||
{
|
||||
//m_dout<<DTIME<<"doing"<<std::endl;
|
||||
unLightNeighbors(n2pos, n2.getLight(), light_sources, modified_blocks);
|
||||
n2.setLight(0);
|
||||
unLightNeighbors(LIGHTBANK_DAY,
|
||||
n2pos, n2.getLight(LIGHTBANK_DAY),
|
||||
light_sources, modified_blocks);
|
||||
n2.setLight(LIGHTBANK_DAY, 0);
|
||||
setNode(n2pos, n2);
|
||||
}
|
||||
else
|
||||
@ -856,11 +891,16 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Spread light from all nodes that might be capable of doing so
|
||||
TODO: Convert to spreadLight
|
||||
*/
|
||||
spreadLight(light_sources, modified_blocks);
|
||||
for(s32 i=0; i<2; i++)
|
||||
{
|
||||
enum LightBank bank = banks[i];
|
||||
|
||||
/*
|
||||
Spread light from all nodes that might be capable of doing so
|
||||
TODO: Convert to spreadLight
|
||||
*/
|
||||
spreadLight(bank, light_sources, modified_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -879,67 +919,6 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
||||
// Node will be replaced with this
|
||||
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,
|
||||
there will be no sunlight going down.
|
||||
@ -947,33 +926,50 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
||||
try{
|
||||
MapNode topnode = getNode(toppos);
|
||||
|
||||
if(topnode.getLight() != LIGHT_SUN)
|
||||
if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
|
||||
node_under_sunlight = false;
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Unlight neighbors (in case the node is a light source)
|
||||
*/
|
||||
//core::list<v3s16> light_sources;
|
||||
core::map<v3s16, bool> light_sources;
|
||||
unLightNeighbors(p, getNode(p).getLight(),
|
||||
light_sources, modified_blocks);
|
||||
|
||||
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)
|
||||
*/
|
||||
unLightNeighbors(bank, p,
|
||||
getNode(p).getLight(bank),
|
||||
light_sources, modified_blocks);
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the node
|
||||
Remove the node.
|
||||
This also clears the lighting.
|
||||
*/
|
||||
|
||||
MapNode n;
|
||||
n.d = replace_material;
|
||||
n.setLight(0);
|
||||
setNode(p, n);
|
||||
|
||||
/*
|
||||
Recalculate lighting
|
||||
*/
|
||||
spreadLight(light_sources, modified_blocks);
|
||||
for(s32 i=0; i<2; i++)
|
||||
{
|
||||
enum LightBank bank = banks[i];
|
||||
|
||||
/*
|
||||
Recalculate lighting
|
||||
*/
|
||||
spreadLight(bank, light_sources, modified_blocks);
|
||||
}
|
||||
|
||||
// Add the block of the removed node to modified_blocks
|
||||
v3s16 blockpos = getNodeBlockPos(p);
|
||||
@ -999,15 +995,16 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
||||
/*m_dout<<DTIME<<"lighting neighbors of node ("
|
||||
<<p2.X<<","<<p2.Y<<","<<p2.Z<<")"
|
||||
<<std::endl;*/
|
||||
lightNeighbors(p2, modified_blocks);
|
||||
lightNeighbors(LIGHTBANK_DAY, p2, modified_blocks);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the lighting of this node to 0
|
||||
// TODO: Is this needed? Lighting is cleared up there already.
|
||||
try{
|
||||
MapNode n = getNode(p);
|
||||
n.setLight(0);
|
||||
n.setLight(LIGHTBANK_DAY, 0);
|
||||
setNode(p, n);
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
@ -1016,43 +1013,78 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
||||
}
|
||||
}
|
||||
|
||||
// Get the brightest neighbour node and propagate light from it
|
||||
v3s16 n2p = getBrightestNeighbour(p);
|
||||
try{
|
||||
MapNode n2 = getNode(n2p);
|
||||
lightNeighbors(n2p, modified_blocks);
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
for(s32 i=0; i<2; i++)
|
||||
{
|
||||
enum LightBank bank = banks[i];
|
||||
|
||||
// Get the brightest neighbour node and propagate light from it
|
||||
v3s16 n2p = getBrightestNeighbour(bank, p);
|
||||
try{
|
||||
MapNode n2 = getNode(n2p);
|
||||
lightNeighbors(bank, n2p, modified_blocks);
|
||||
}
|
||||
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);
|
||||
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,0,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh();
|
||||
b->updateMesh(daylight_factor);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(-1,0,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh();
|
||||
b->updateMesh(daylight_factor);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,-1,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh();
|
||||
b->updateMesh(daylight_factor);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,0,-1);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh();
|
||||
b->updateMesh(daylight_factor);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
}
|
||||
@ -1691,7 +1723,7 @@ MapBlock * ServerMap::emergeBlock(
|
||||
newly created block, they won't be taken into account.
|
||||
*/
|
||||
if(real_y > surface_y)
|
||||
n.setLight(LIGHT_SUN);
|
||||
n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
|
||||
|
||||
/*
|
||||
Calculate material
|
||||
@ -1751,7 +1783,8 @@ MapBlock * ServerMap::emergeBlock(
|
||||
if(real_y < WATER_LEVEL)
|
||||
{
|
||||
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
|
||||
@ -2732,11 +2765,13 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
|
||||
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
|
||||
// because it'd cause too much delays
|
||||
|
||||
core::map<v2s16, MapSector*>::Iterator si;
|
||||
si = m_sectors.getIterator();
|
||||
for(; si.atEnd() == false; si++)
|
||||
{
|
||||
@ -2837,11 +2872,34 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
/*
|
||||
Draw the faces of the block
|
||||
*/
|
||||
|
||||
bool mesh_expired = false;
|
||||
|
||||
{
|
||||
JMutexAutoLock lock(block->mesh_mutex);
|
||||
|
||||
// Cancel if block has no mesh
|
||||
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);
|
||||
|
||||
if(block->mesh == NULL)
|
||||
continue;
|
||||
|
||||
|
22
src/map.h
22
src/map.h
@ -333,25 +333,33 @@ public:
|
||||
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, 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, 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);
|
||||
|
||||
void lightNeighbors(v3s16 pos,
|
||||
void lightNeighbors(enum LightBank bank,
|
||||
v3s16 pos,
|
||||
core::map<v3s16, MapBlock*> & modified_blocks);
|
||||
|
||||
v3s16 getBrightestNeighbour(v3s16 p);
|
||||
v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p);
|
||||
|
||||
s16 propagateSunlight(v3s16 start,
|
||||
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,
|
||||
core::map<v3s16, MapBlock*> & modified_blocks);
|
||||
|
||||
@ -367,7 +375,9 @@ public:
|
||||
Updates the faces of the given block and blocks on the
|
||||
leading edge.
|
||||
*/
|
||||
void updateMeshes(v3s16 blockpos);
|
||||
void updateMeshes(v3s16 blockpos, u32 daylight_factor);
|
||||
|
||||
void expireMeshes();
|
||||
|
||||
//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.
|
||||
*/
|
||||
u8 MapBlock::getFaceLight(v3s16 p, v3s16 face_dir)
|
||||
u8 MapBlock::getFaceLight(u32 daylight_factor, v3s16 p, v3s16 face_dir)
|
||||
{
|
||||
try{
|
||||
MapNode n = getNodeParent(p);
|
||||
MapNode n2 = getNodeParent(p + face_dir);
|
||||
u8 light;
|
||||
/*if(n.solidness() < n2.solidness())
|
||||
light = n.getLight();
|
||||
u8 l1 = n.getLightBlend(daylight_factor);
|
||||
u8 l2 = n2.getLightBlend(daylight_factor);
|
||||
if(l1 > l2)
|
||||
light = l1;
|
||||
else
|
||||
light = n2.getLight();*/
|
||||
if(n.getLight() > n2.getLight())
|
||||
light = n.getLight();
|
||||
else
|
||||
light = n2.getLight();
|
||||
light = l2;
|
||||
|
||||
// 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
|
||||
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,
|
||||
v3s16 translate_dir,
|
||||
v3s16 face_dir,
|
||||
@ -292,7 +292,7 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
|
||||
/*
|
||||
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;
|
||||
|
||||
@ -312,7 +312,7 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
|
||||
p_next = p + translate_dir;
|
||||
tile0_next = getNodeTile(p_next, 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
|
||||
&& tile1_next == tile1
|
||||
@ -474,12 +474,13 @@ private:
|
||||
core::array<PreMeshBuffer> m_prebuffers;
|
||||
};
|
||||
|
||||
void MapBlock::updateMesh()
|
||||
void MapBlock::updateMesh(u32 daylight_factor)
|
||||
{
|
||||
/*v3s16 p = getPosRelative();
|
||||
std::cout<<"MapBlock("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||
<<"::updateMesh(): ";*/
|
||||
//<<"::updateMesh()"<<std::endl;
|
||||
TimeTaker timer1("updateMesh()", g_device);
|
||||
|
||||
/*
|
||||
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.
|
||||
This means that when something changes, the caller must
|
||||
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=-1; y<MAP_BLOCKSIZE; y++){
|
||||
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(0,1,0),
|
||||
*fastfaces_new);
|
||||
@ -512,7 +517,8 @@ void MapBlock::updateMesh()
|
||||
for(s16 x=0; x<MAP_BLOCKSIZE; x++){
|
||||
//for(s16 x=-1; x<MAP_BLOCKSIZE; x++){
|
||||
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(1,0,0),
|
||||
*fastfaces_new);
|
||||
@ -524,7 +530,8 @@ void MapBlock::updateMesh()
|
||||
for(s16 z=0; z<MAP_BLOCKSIZE; z++){
|
||||
//for(s16 z=-1; z<MAP_BLOCKSIZE; z++){
|
||||
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(0,0,1),
|
||||
*fastfaces_new);
|
||||
@ -568,7 +575,7 @@ void MapBlock::updateMesh()
|
||||
<<"and uses "<<mesh_new->getMeshBufferCount()
|
||||
<<" materials (meshbuffers)"<<std::endl;*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Clear temporary FastFaces
|
||||
*/
|
||||
@ -667,7 +674,7 @@ void MapBlock::updateMesh()
|
||||
buf->drop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Do some stuff to the mesh
|
||||
*/
|
||||
@ -693,6 +700,7 @@ void MapBlock::updateMesh()
|
||||
scene::SMesh *mesh_old = mesh;
|
||||
|
||||
mesh = mesh_new;
|
||||
setMeshExpired(false);
|
||||
|
||||
if(mesh_old != NULL)
|
||||
{
|
||||
@ -743,7 +751,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
|
||||
// Check if node above block has sunlight
|
||||
try{
|
||||
MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z));
|
||||
if(n.getLight() != LIGHT_SUN)
|
||||
if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
|
||||
{
|
||||
/*if(is_underground)
|
||||
{
|
||||
@ -789,7 +797,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
|
||||
|
||||
if(n.sunlight_propagates())
|
||||
{
|
||||
n.setLight(LIGHT_SUN);
|
||||
n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
|
||||
|
||||
light_sources.insert(pos_relative + pos, true);
|
||||
}
|
||||
@ -809,7 +817,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
|
||||
|
||||
if(n.light_propagates())
|
||||
{
|
||||
n.setLight(0);
|
||||
n.setLight(LIGHTBANK_DAY, 0);
|
||||
}
|
||||
else{
|
||||
break;
|
||||
@ -831,10 +839,10 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
|
||||
MapNode n = getNodeParent(v3s16(x, -1, z));
|
||||
if(n.light_propagates())
|
||||
{
|
||||
if(n.getLight() == LIGHT_SUN
|
||||
if(n.getLight(LIGHTBANK_DAY) == LIGHT_SUN
|
||||
&& sunlight_should_go_down == 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)
|
||||
block_below_is_valid = false;
|
||||
}
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
m_pos(pos),
|
||||
changed(true),
|
||||
is_underground(false),
|
||||
m_mesh_expired(false),
|
||||
m_objects(this)
|
||||
//is_incomplete(false)
|
||||
{
|
||||
@ -170,6 +171,16 @@ public:
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void setMeshExpired(bool expired)
|
||||
{
|
||||
m_mesh_expired = expired;
|
||||
}
|
||||
|
||||
bool getMeshExpired()
|
||||
{
|
||||
return m_mesh_expired;
|
||||
}
|
||||
|
||||
v3s16 getPos()
|
||||
{
|
||||
return m_pos;
|
||||
@ -303,7 +314,7 @@ public:
|
||||
static FastFace * makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||
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);
|
||||
u8 getNodeContent(v3s16 p);
|
||||
@ -313,13 +324,15 @@ public:
|
||||
translate_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,
|
||||
v3s16 translate_dir,
|
||||
v3s16 face_dir,
|
||||
core::list<FastFace*> &dest);
|
||||
|
||||
void updateMesh();
|
||||
void updateMesh(u32 daylight_factor);
|
||||
|
||||
bool propagateSunlight(core::map<v3s16, bool> & light_sources);
|
||||
|
||||
@ -464,6 +477,8 @@ private:
|
||||
At least /has been/ used. 8)
|
||||
*/
|
||||
bool is_underground;
|
||||
|
||||
bool m_mesh_expired;
|
||||
|
||||
MapBlockObjectList m_objects;
|
||||
|
||||
|
@ -280,6 +280,12 @@ inline u16 content_tile(u8 c, v3s16 dir)
|
||||
return g_content_tiles[c][dir_i];
|
||||
}
|
||||
|
||||
enum LightBank
|
||||
{
|
||||
LIGHTBANK_DAY,
|
||||
LIGHTBANK_NIGHT
|
||||
};
|
||||
|
||||
struct MapNode
|
||||
{
|
||||
// Content
|
||||
@ -352,24 +358,77 @@ struct MapNode
|
||||
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]
|
||||
u8 light = 0;
|
||||
if(light_propagates())
|
||||
light = param & 0x0f;
|
||||
{
|
||||
if(bank == LIGHTBANK_DAY)
|
||||
light = param & 0x0f;
|
||||
else if(bank == LIGHTBANK_NIGHT)
|
||||
light = (param>>4)&0x0f;
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
if(light_source() > light)
|
||||
light = light_source();
|
||||
return 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(u8 a_light)
|
||||
void setLight(enum LightBank bank, u8 a_light)
|
||||
{
|
||||
// If not transparent, can't set light
|
||||
if(light_propagates() == false)
|
||||
return;
|
||||
param &= 0xf0;
|
||||
param |= a_light;
|
||||
if(bank == LIGHTBANK_DAY)
|
||||
{
|
||||
param &= 0xf0;
|
||||
param |= a_light & 0x0f;
|
||||
}
|
||||
else if(bank == LIGHTBANK_NIGHT)
|
||||
{
|
||||
param &= 0x0f;
|
||||
param |= (a_light & 0x0f)<<4;
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
u16 getTile(v3s16 dir)
|
||||
|
49
src/test.cpp
49
src/test.cpp
@ -194,7 +194,8 @@ struct TestMapNode
|
||||
|
||||
// Default values
|
||||
assert(n.d == CONTENT_AIR);
|
||||
assert(n.getLight() == 0);
|
||||
assert(n.getLight(LIGHTBANK_DAY) == 0);
|
||||
assert(n.getLight(LIGHTBANK_NIGHT) == 0);
|
||||
|
||||
// Transparency
|
||||
n.d = CONTENT_AIR;
|
||||
@ -431,11 +432,13 @@ struct TestMapBlock
|
||||
// All nodes should have been set to
|
||||
// .d=CONTENT_AIR and .getLight() = 0
|
||||
for(u16 z=0; z<MAP_BLOCKSIZE; z++)
|
||||
for(u16 y=0; y<MAP_BLOCKSIZE; y++)
|
||||
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)).getLight() == 0);
|
||||
}
|
||||
for(u16 y=0; y<MAP_BLOCKSIZE; y++)
|
||||
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)).getLight(LIGHTBANK_DAY) == 0);
|
||||
assert(b.getNode(v3s16(x,y,z)).getLight(LIGHTBANK_NIGHT) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
Parent fetch functions
|
||||
@ -496,7 +499,8 @@ struct TestMapBlock
|
||||
for(u16 y=0; y<MAP_BLOCKSIZE; y++){
|
||||
for(u16 x=0; x<MAP_BLOCKSIZE; x++){
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -508,22 +512,25 @@ struct TestMapBlock
|
||||
parent.position_valid = true;
|
||||
b.setIsUnderground(false);
|
||||
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;
|
||||
// The bottom block is invalid, because we have a shadowing node
|
||||
assert(b.propagateSunlight(light_sources) == false);
|
||||
assert(b.getNode(v3s16(1,4,0)).getLight() == LIGHT_SUN);
|
||||
assert(b.getNode(v3s16(1,3,0)).getLight() == LIGHT_SUN);
|
||||
assert(b.getNode(v3s16(1,2,0)).getLight() == 0);
|
||||
assert(b.getNode(v3s16(1,1,0)).getLight() == 0);
|
||||
assert(b.getNode(v3s16(1,0,0)).getLight() == 0);
|
||||
assert(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN);
|
||||
assert(b.getFaceLight(p, v3s16(0,1,0)) == LIGHT_SUN);
|
||||
assert(b.getFaceLight(p, v3s16(0,-1,0)) == 0);
|
||||
assert(b.getNode(v3s16(1,4,0)).getLight(LIGHTBANK_DAY) == LIGHT_SUN);
|
||||
assert(b.getNode(v3s16(1,3,0)).getLight(LIGHTBANK_DAY) == LIGHT_SUN);
|
||||
assert(b.getNode(v3s16(1,2,0)).getLight(LIGHTBANK_DAY) == 0);
|
||||
assert(b.getNode(v3s16(1,1,0)).getLight(LIGHTBANK_DAY) == 0);
|
||||
assert(b.getNode(v3s16(1,0,0)).getLight(LIGHTBANK_DAY) == 0);
|
||||
assert(b.getNode(v3s16(1,2,3)).getLight(LIGHTBANK_DAY) == LIGHT_SUN);
|
||||
assert(b.getFaceLight(1000, p, v3s16(0,1,0)) == LIGHT_SUN);
|
||||
assert(b.getFaceLight(1000, p, v3s16(0,-1,0)) == 0);
|
||||
assert(b.getFaceLight(0, p, v3s16(0,-1,0)) == 0);
|
||||
// According to MapBlock::getFaceLight,
|
||||
// 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(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
|
||||
@ -533,7 +540,7 @@ struct TestMapBlock
|
||||
// Make neighbours to exist and set some non-sunlight to them
|
||||
parent.position_valid = true;
|
||||
b.setIsUnderground(true);
|
||||
parent.node.setLight(LIGHT_MAX/2);
|
||||
parent.node.setLight(LIGHTBANK_DAY, LIGHT_MAX/2);
|
||||
core::map<v3s16, bool> light_sources;
|
||||
// The block below should be valid because there shouldn't be
|
||||
// sunlight in there either
|
||||
@ -541,7 +548,7 @@ struct TestMapBlock
|
||||
// Should not touch nodes that are not affected (that is, all of them)
|
||||
//assert(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN);
|
||||
// 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:
|
||||
@ -560,7 +567,7 @@ struct TestMapBlock
|
||||
for(u16 x=0; x<MAP_BLOCKSIZE; x++){
|
||||
MapNode n;
|
||||
n.d = CONTENT_AIR;
|
||||
n.setLight(0);
|
||||
n.setLight(LIGHTBANK_DAY, 0);
|
||||
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));
|
||||
}
|
||||
// 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;
|
||||
// Bottom block is not valid
|
||||
assert(b.propagateSunlight(light_sources) == false);
|
||||
|
@ -734,12 +734,12 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
||||
correctly. Otherwise unspreadLight will fuck up when water
|
||||
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_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
|
||||
// unspreadLight will clear all light that came from this node.
|
||||
|
Loading…
Reference in New Issue
Block a user