forked from Mirrorlandia_minetest/minetest
Remove unused light updating code
Also remove the unit test that tests the removed algorithms.
This commit is contained in:
parent
cf0bcebc76
commit
735fc2a1f2
192
src/mapblock.cpp
192
src/mapblock.cpp
@ -132,198 +132,6 @@ std::string MapBlock::getModifiedReasonString()
|
||||
return reason;
|
||||
}
|
||||
|
||||
/*
|
||||
Propagates sunlight down through the block.
|
||||
Doesn't modify nodes that are not affected by sunlight.
|
||||
|
||||
Returns false if sunlight at bottom block is invalid.
|
||||
Returns true if sunlight at bottom block is valid.
|
||||
Returns true if bottom block doesn't exist.
|
||||
|
||||
If there is a block above, continues from it.
|
||||
If there is no block above, assumes there is sunlight, unless
|
||||
is_underground is set or highest node is water.
|
||||
|
||||
All sunlighted nodes are added to light_sources.
|
||||
|
||||
if remove_light==true, sets non-sunlighted nodes black.
|
||||
|
||||
if black_air_left!=NULL, it is set to true if non-sunlighted
|
||||
air is left in block.
|
||||
*/
|
||||
bool MapBlock::propagateSunlight(std::set<v3s16> & light_sources,
|
||||
bool remove_light, bool *black_air_left)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
// Whether the sunlight at the top of the bottom block is valid
|
||||
bool block_below_is_valid = true;
|
||||
|
||||
v3s16 pos_relative = getPosRelative();
|
||||
|
||||
for(s16 x=0; x<MAP_BLOCKSIZE; x++)
|
||||
{
|
||||
for(s16 z=0; z<MAP_BLOCKSIZE; z++)
|
||||
{
|
||||
#if 1
|
||||
bool no_sunlight = false;
|
||||
//bool no_top_block = false;
|
||||
|
||||
// Check if node above block has sunlight
|
||||
|
||||
bool is_valid_position;
|
||||
MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z),
|
||||
&is_valid_position);
|
||||
if (is_valid_position)
|
||||
{
|
||||
if(n.getContent() == CONTENT_IGNORE)
|
||||
{
|
||||
// Trust heuristics
|
||||
no_sunlight = is_underground;
|
||||
}
|
||||
else if(n.getLight(LIGHTBANK_DAY, m_gamedef->ndef()) != LIGHT_SUN)
|
||||
{
|
||||
no_sunlight = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//no_top_block = true;
|
||||
|
||||
// NOTE: This makes over-ground roofed places sunlighted
|
||||
// Assume sunlight, unless is_underground==true
|
||||
if(is_underground)
|
||||
{
|
||||
no_sunlight = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
MapNode n = getNodeNoEx(v3s16(x, MAP_BLOCKSIZE-1, z));
|
||||
if (!m_gamedef->ndef()->get(n).sunlight_propagates) {
|
||||
no_sunlight = true;
|
||||
}
|
||||
}
|
||||
// NOTE: As of now, this just would make everything dark.
|
||||
// No sunlight here
|
||||
//no_sunlight = true;
|
||||
}
|
||||
#endif
|
||||
#if 0 // Doesn't work; nothing gets light.
|
||||
bool no_sunlight = true;
|
||||
bool no_top_block = false;
|
||||
// Check if node above block has sunlight
|
||||
try{
|
||||
MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z));
|
||||
if(n.getLight(LIGHTBANK_DAY) == LIGHT_SUN)
|
||||
{
|
||||
no_sunlight = false;
|
||||
}
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
no_top_block = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*std::cout<<"("<<x<<","<<z<<"): "
|
||||
<<"no_top_block="<<no_top_block
|
||||
<<", is_underground="<<is_underground
|
||||
<<", no_sunlight="<<no_sunlight
|
||||
<<std::endl;*/
|
||||
|
||||
s16 y = MAP_BLOCKSIZE-1;
|
||||
|
||||
// This makes difference to diminishing in water.
|
||||
bool stopped_to_solid_object = false;
|
||||
|
||||
u8 current_light = no_sunlight ? 0 : LIGHT_SUN;
|
||||
|
||||
for(; y >= 0; y--)
|
||||
{
|
||||
v3s16 pos(x, y, z);
|
||||
MapNode &n = getNodeRef(pos);
|
||||
|
||||
if(current_light == 0)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if(current_light == LIGHT_SUN && nodemgr->get(n).sunlight_propagates)
|
||||
{
|
||||
// Do nothing: Sunlight is continued
|
||||
} else if (!nodemgr->get(n).light_propagates) {
|
||||
// A solid object is on the way.
|
||||
stopped_to_solid_object = true;
|
||||
|
||||
// Light stops.
|
||||
current_light = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Diminish light
|
||||
current_light = diminish_light(current_light);
|
||||
}
|
||||
|
||||
u8 old_light = n.getLight(LIGHTBANK_DAY, nodemgr);
|
||||
|
||||
if(current_light > old_light || remove_light)
|
||||
{
|
||||
n.setLight(LIGHTBANK_DAY, current_light, nodemgr);
|
||||
}
|
||||
|
||||
if(diminish_light(current_light) != 0)
|
||||
{
|
||||
light_sources.insert(pos_relative + pos);
|
||||
}
|
||||
|
||||
if(current_light == 0 && stopped_to_solid_object)
|
||||
{
|
||||
if(black_air_left)
|
||||
{
|
||||
*black_air_left = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Whether or not the block below should see LIGHT_SUN
|
||||
bool sunlight_should_go_down = (current_light == LIGHT_SUN);
|
||||
|
||||
/*
|
||||
If the block below hasn't already been marked invalid:
|
||||
|
||||
Check if the node below the block has proper sunlight at top.
|
||||
If not, the block below is invalid.
|
||||
|
||||
Ignore non-transparent nodes as they always have no light
|
||||
*/
|
||||
|
||||
if(block_below_is_valid)
|
||||
{
|
||||
MapNode n = getNodeParent(v3s16(x, -1, z), &is_valid_position);
|
||||
if (is_valid_position) {
|
||||
if(nodemgr->get(n).light_propagates)
|
||||
{
|
||||
if(n.getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN
|
||||
&& !sunlight_should_go_down)
|
||||
block_below_is_valid = false;
|
||||
else if(n.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN
|
||||
&& sunlight_should_go_down)
|
||||
block_below_is_valid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*std::cout<<"InvalidBlockException for bottom block node"
|
||||
<<std::endl;*/
|
||||
// Just no block below, no need to panic.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return block_below_is_valid;
|
||||
}
|
||||
|
||||
|
||||
void MapBlock::copyTo(VoxelManipulator &dst)
|
||||
{
|
||||
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
|
||||
|
@ -348,10 +348,6 @@ public:
|
||||
setNode(x0 + x, y0 + y, z0 + z, node);
|
||||
}
|
||||
|
||||
// See comments in mapblock.cpp
|
||||
bool propagateSunlight(std::set<v3s16> &light_sources,
|
||||
bool remove_light=false, bool *black_air_left=NULL);
|
||||
|
||||
// Copies data to VoxelManipulator to getPosRelative()
|
||||
void copyTo(VoxelManipulator &dst);
|
||||
|
||||
|
@ -30,8 +30,6 @@ public:
|
||||
|
||||
void runTests(IGameDef *gamedef);
|
||||
|
||||
void testPropogateSunlight(INodeDefManager *ndef);
|
||||
void testClearLightAndCollectSources(INodeDefManager *ndef);
|
||||
void testVoxelLineIterator(INodeDefManager *ndef);
|
||||
};
|
||||
|
||||
@ -41,171 +39,11 @@ void TestVoxelAlgorithms::runTests(IGameDef *gamedef)
|
||||
{
|
||||
INodeDefManager *ndef = gamedef->getNodeDefManager();
|
||||
|
||||
TEST(testPropogateSunlight, ndef);
|
||||
TEST(testClearLightAndCollectSources, ndef);
|
||||
TEST(testVoxelLineIterator, ndef);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TestVoxelAlgorithms::testPropogateSunlight(INodeDefManager *ndef)
|
||||
{
|
||||
VoxelManipulator v;
|
||||
|
||||
for (u16 z = 0; z < 3; z++)
|
||||
for (u16 y = 0; y < 3; y++)
|
||||
for (u16 x = 0; x < 3; x++) {
|
||||
v3s16 p(x,y,z);
|
||||
v.setNodeNoRef(p, MapNode(CONTENT_AIR));
|
||||
}
|
||||
|
||||
VoxelArea a(v3s16(0,0,0), v3s16(2,2,2));
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
voxalgo::setLight(v, a, 0, ndef);
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
v, a, true, light_sources, ndef);
|
||||
//v.print(dstream, ndef, VOXELPRINT_LIGHT_DAY);
|
||||
UASSERT(res.bottom_sunlight_valid == true);
|
||||
UASSERT(v.getNode(v3s16(1,1,1)).getLight(LIGHTBANK_DAY, ndef)
|
||||
== LIGHT_SUN);
|
||||
}
|
||||
|
||||
v.setNodeNoRef(v3s16(0,0,0), MapNode(t_CONTENT_STONE));
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
voxalgo::setLight(v, a, 0, ndef);
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
v, a, true, light_sources, ndef);
|
||||
UASSERT(res.bottom_sunlight_valid == true);
|
||||
UASSERT(v.getNode(v3s16(1,1,1)).getLight(LIGHTBANK_DAY, ndef)
|
||||
== LIGHT_SUN);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
voxalgo::setLight(v, a, 0, ndef);
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
v, a, false, light_sources, ndef);
|
||||
UASSERT(res.bottom_sunlight_valid == true);
|
||||
UASSERT(v.getNode(v3s16(2,0,2)).getLight(LIGHTBANK_DAY, ndef)
|
||||
== 0);
|
||||
}
|
||||
|
||||
v.setNodeNoRef(v3s16(1,3,2), MapNode(t_CONTENT_STONE));
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
voxalgo::setLight(v, a, 0, ndef);
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
v, a, true, light_sources, ndef);
|
||||
UASSERT(res.bottom_sunlight_valid == true);
|
||||
UASSERT(v.getNode(v3s16(1,1,2)).getLight(LIGHTBANK_DAY, ndef)
|
||||
== 0);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
voxalgo::setLight(v, a, 0, ndef);
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
v, a, false, light_sources, ndef);
|
||||
UASSERT(res.bottom_sunlight_valid == true);
|
||||
UASSERT(v.getNode(v3s16(1,0,2)).getLight(LIGHTBANK_DAY, ndef)
|
||||
== 0);
|
||||
}
|
||||
|
||||
{
|
||||
MapNode n(CONTENT_AIR);
|
||||
n.setLight(LIGHTBANK_DAY, 10, ndef);
|
||||
v.setNodeNoRef(v3s16(1,-1,2), n);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
voxalgo::setLight(v, a, 0, ndef);
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
v, a, true, light_sources, ndef);
|
||||
UASSERT(res.bottom_sunlight_valid == true);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
voxalgo::setLight(v, a, 0, ndef);
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
v, a, false, light_sources, ndef);
|
||||
UASSERT(res.bottom_sunlight_valid == true);
|
||||
}
|
||||
|
||||
{
|
||||
MapNode n(CONTENT_AIR);
|
||||
n.setLight(LIGHTBANK_DAY, LIGHT_SUN, ndef);
|
||||
v.setNodeNoRef(v3s16(1,-1,2), n);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
voxalgo::setLight(v, a, 0, ndef);
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
v, a, true, light_sources, ndef);
|
||||
UASSERT(res.bottom_sunlight_valid == false);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
voxalgo::setLight(v, a, 0, ndef);
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
v, a, false, light_sources, ndef);
|
||||
UASSERT(res.bottom_sunlight_valid == false);
|
||||
}
|
||||
|
||||
v.setNodeNoRef(v3s16(1,3,2), MapNode(CONTENT_IGNORE));
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
voxalgo::setLight(v, a, 0, ndef);
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
v, a, true, light_sources, ndef);
|
||||
UASSERT(res.bottom_sunlight_valid == true);
|
||||
}
|
||||
}
|
||||
|
||||
void TestVoxelAlgorithms::testClearLightAndCollectSources(INodeDefManager *ndef)
|
||||
{
|
||||
VoxelManipulator v;
|
||||
|
||||
for (u16 z = 0; z < 3; z++)
|
||||
for (u16 y = 0; y < 3; y++)
|
||||
for (u16 x = 0; x < 3; x++) {
|
||||
v3s16 p(x,y,z);
|
||||
v.setNode(p, MapNode(CONTENT_AIR));
|
||||
}
|
||||
|
||||
VoxelArea a(v3s16(0,0,0), v3s16(2,2,2));
|
||||
v.setNodeNoRef(v3s16(0,0,0), MapNode(t_CONTENT_STONE));
|
||||
v.setNodeNoRef(v3s16(1,1,1), MapNode(t_CONTENT_TORCH));
|
||||
|
||||
{
|
||||
MapNode n(CONTENT_AIR);
|
||||
n.setLight(LIGHTBANK_DAY, 1, ndef);
|
||||
v.setNode(v3s16(1,1,2), n);
|
||||
}
|
||||
|
||||
{
|
||||
std::set<v3s16> light_sources;
|
||||
std::map<v3s16, u8> unlight_from;
|
||||
voxalgo::clearLightAndCollectSources(v, a, LIGHTBANK_DAY,
|
||||
ndef, light_sources, unlight_from);
|
||||
//v.print(dstream, ndef, VOXELPRINT_LIGHT_DAY);
|
||||
UASSERT(v.getNode(v3s16(0,1,1)).getLight(LIGHTBANK_DAY, ndef) == 0);
|
||||
UASSERT(light_sources.find(v3s16(1,1,1)) != light_sources.end());
|
||||
UASSERT(light_sources.size() == 1);
|
||||
UASSERT(unlight_from.find(v3s16(1,1,2)) != unlight_from.end());
|
||||
UASSERT(unlight_from.size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
void TestVoxelAlgorithms::testVoxelLineIterator(INodeDefManager *ndef)
|
||||
{
|
||||
// Test some lines
|
||||
|
188
src/voxel.cpp
188
src/voxel.cpp
@ -315,194 +315,6 @@ void VoxelManipulator::clearFlag(u8 flags)
|
||||
<<volume<<" nodes"<<std::endl;*/
|
||||
}
|
||||
|
||||
void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
|
||||
std::set<v3s16> & light_sources, INodeDefManager *nodemgr)
|
||||
{
|
||||
VoxelArea voxel_area(p - v3s16(1,1,1), p + v3s16(1,1,1));
|
||||
addArea(voxel_area);
|
||||
|
||||
// Loop through 6 neighbors
|
||||
for (const v3s16 &dir : g_6dirs) {
|
||||
// Get the position of the neighbor node
|
||||
v3s16 n2pos = p + dir;
|
||||
|
||||
u32 n2i = m_area.index(n2pos);
|
||||
|
||||
if(m_flags[n2i] & VOXELFLAG_NO_DATA)
|
||||
continue;
|
||||
|
||||
MapNode &n2 = m_data[n2i];
|
||||
|
||||
/*
|
||||
If the neighbor is dimmer than what was specified
|
||||
as oldlight (the light of the previous node)
|
||||
*/
|
||||
u8 light2 = n2.getLight(bank, nodemgr);
|
||||
if(light2 < oldlight)
|
||||
{
|
||||
/*
|
||||
And the neighbor is transparent and it has some light
|
||||
*/
|
||||
if(nodemgr->get(n2).light_propagates && light2 != 0)
|
||||
{
|
||||
/*
|
||||
Set light to 0 and add to queue
|
||||
*/
|
||||
|
||||
n2.setLight(bank, 0, nodemgr);
|
||||
|
||||
unspreadLight(bank, n2pos, light2, light_sources, nodemgr);
|
||||
|
||||
/*
|
||||
Remove from light_sources if it is there
|
||||
NOTE: This doesn't happen nearly at all
|
||||
*/
|
||||
/*if(light_sources.find(n2pos))
|
||||
{
|
||||
std::cout<<"Removed from light_sources"<<std::endl;
|
||||
light_sources.remove(n2pos);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
else{
|
||||
light_sources.insert(n2pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p,
|
||||
INodeDefManager *nodemgr)
|
||||
{
|
||||
VoxelArea voxel_area(p - v3s16(1,1,1), p + v3s16(1,1,1));
|
||||
addArea(voxel_area);
|
||||
|
||||
u32 i = m_area.index(p);
|
||||
|
||||
if(m_flags[i] & VOXELFLAG_NO_DATA)
|
||||
return;
|
||||
|
||||
MapNode &n = m_data[i];
|
||||
|
||||
u8 oldlight = n.getLight(bank, nodemgr);
|
||||
u8 newlight = diminish_light(oldlight);
|
||||
|
||||
// Loop through 6 neighbors
|
||||
for (const auto &dir : g_6dirs) {
|
||||
// Get the position of the neighbor node
|
||||
v3s16 n2pos = p + dir;
|
||||
|
||||
u32 n2i = m_area.index(n2pos);
|
||||
|
||||
if(m_flags[n2i] & VOXELFLAG_NO_DATA)
|
||||
continue;
|
||||
|
||||
MapNode &n2 = m_data[n2i];
|
||||
|
||||
u8 light2 = n2.getLight(bank, nodemgr);
|
||||
|
||||
/*
|
||||
If the neighbor is brighter than the current node,
|
||||
add to list (it will light up this node on its turn)
|
||||
*/
|
||||
if(light2 > undiminish_light(oldlight))
|
||||
{
|
||||
spreadLight(bank, n2pos, nodemgr);
|
||||
}
|
||||
/*
|
||||
If the neighbor is dimmer than how much light this node
|
||||
would spread on it, add to list
|
||||
*/
|
||||
if(light2 < newlight)
|
||||
{
|
||||
if(nodemgr->get(n2).light_propagates)
|
||||
{
|
||||
n2.setLight(bank, newlight, nodemgr);
|
||||
spreadLight(bank, n2pos, nodemgr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const MapNode VoxelManipulator::ContentIgnoreNode = MapNode(CONTENT_IGNORE);
|
||||
|
||||
/*
|
||||
Lights neighbors of from_nodes, collects all them and then
|
||||
goes on recursively.
|
||||
*/
|
||||
void VoxelManipulator::spreadLight(enum LightBank bank,
|
||||
std::set<v3s16> & from_nodes, INodeDefManager *nodemgr)
|
||||
{
|
||||
if(from_nodes.empty())
|
||||
return;
|
||||
|
||||
std::set<v3s16> lighted_nodes;
|
||||
|
||||
for (const v3s16 &pos : from_nodes) {
|
||||
VoxelArea voxel_area(pos - v3s16(1,1,1), pos + v3s16(1,1,1));
|
||||
addArea(voxel_area);
|
||||
|
||||
u32 i = m_area.index(pos);
|
||||
|
||||
if(m_flags[i] & VOXELFLAG_NO_DATA)
|
||||
continue;
|
||||
|
||||
MapNode &n = m_data[i];
|
||||
|
||||
u8 oldlight = n.getLight(bank, nodemgr);
|
||||
u8 newlight = diminish_light(oldlight);
|
||||
|
||||
// Loop through 6 neighbors
|
||||
for (const v3s16 &dir : g_6dirs) {
|
||||
// Get the position of the neighbor node
|
||||
v3s16 n2pos = pos + dir;
|
||||
|
||||
try
|
||||
{
|
||||
u32 n2i = m_area.index(n2pos);
|
||||
|
||||
if(m_flags[n2i] & VOXELFLAG_NO_DATA)
|
||||
continue;
|
||||
|
||||
MapNode &n2 = m_data[n2i];
|
||||
|
||||
u8 light2 = n2.getLight(bank, nodemgr);
|
||||
|
||||
/*
|
||||
If the neighbor is brighter than the current node,
|
||||
add to list (it will light up this node on its turn)
|
||||
*/
|
||||
if(light2 > undiminish_light(oldlight))
|
||||
{
|
||||
lighted_nodes.insert(n2pos);
|
||||
}
|
||||
/*
|
||||
If the neighbor is dimmer than how much light this node
|
||||
would spread on it, add to list
|
||||
*/
|
||||
if(light2 < newlight)
|
||||
{
|
||||
if(nodemgr->get(n2).light_propagates)
|
||||
{
|
||||
n2.setLight(bank, newlight, nodemgr);
|
||||
lighted_nodes.insert(n2pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*dstream<<"spreadLight(): Changed block "
|
||||
<<blockchangecount<<" times"
|
||||
<<" for "<<from_nodes.size()<<" nodes"
|
||||
<<std::endl;*/
|
||||
|
||||
if(!lighted_nodes.empty())
|
||||
spreadLight(bank, lighted_nodes, nodemgr);
|
||||
}
|
||||
|
||||
//END
|
||||
|
@ -471,15 +471,6 @@ public:
|
||||
|
||||
void clearFlag(u8 flag);
|
||||
|
||||
// TODO: Move to voxelalgorithms.h
|
||||
|
||||
void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
|
||||
std::set<v3s16> & light_sources, INodeDefManager *nodemgr);
|
||||
|
||||
void spreadLight(enum LightBank bank, v3s16 p, INodeDefManager *nodemgr);
|
||||
void spreadLight(enum LightBank bank,
|
||||
std::set<v3s16> & from_nodes, INodeDefManager *nodemgr);
|
||||
|
||||
/*
|
||||
Member variables
|
||||
*/
|
||||
|
@ -25,136 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
namespace voxalgo
|
||||
{
|
||||
|
||||
void setLight(VoxelManipulator &v, VoxelArea a, u8 light,
|
||||
INodeDefManager *ndef)
|
||||
{
|
||||
for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++)
|
||||
for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++)
|
||||
for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++)
|
||||
{
|
||||
v3s16 p(x,y,z);
|
||||
MapNode &n = v.getNodeRefUnsafe(p);
|
||||
n.setLight(LIGHTBANK_DAY, light, ndef);
|
||||
n.setLight(LIGHTBANK_NIGHT, light, ndef);
|
||||
}
|
||||
}
|
||||
|
||||
void clearLightAndCollectSources(VoxelManipulator &v, VoxelArea a,
|
||||
enum LightBank bank, INodeDefManager *ndef,
|
||||
std::set<v3s16> & light_sources,
|
||||
std::map<v3s16, u8> & unlight_from)
|
||||
{
|
||||
// The full area we shall touch
|
||||
VoxelArea required_a = a;
|
||||
required_a.pad(v3s16(0,0,0));
|
||||
// Make sure we have access to it
|
||||
v.addArea(a);
|
||||
|
||||
for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++)
|
||||
for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++)
|
||||
for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++)
|
||||
{
|
||||
v3s16 p(x,y,z);
|
||||
MapNode &n = v.getNodeRefUnsafe(p);
|
||||
u8 oldlight = n.getLight(bank, ndef);
|
||||
n.setLight(bank, 0, ndef);
|
||||
|
||||
// If node sources light, add to list
|
||||
u8 source = ndef->get(n).light_source;
|
||||
if(source != 0)
|
||||
light_sources.insert(p);
|
||||
|
||||
// Collect borders for unlighting
|
||||
if((x==a.MinEdge.X || x == a.MaxEdge.X
|
||||
|| y==a.MinEdge.Y || y == a.MaxEdge.Y
|
||||
|| z==a.MinEdge.Z || z == a.MaxEdge.Z)
|
||||
&& oldlight != 0)
|
||||
{
|
||||
unlight_from[p] = oldlight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SunlightPropagateResult propagateSunlight(VoxelManipulator &v, VoxelArea a,
|
||||
bool inexistent_top_provides_sunlight,
|
||||
std::set<v3s16> & light_sources,
|
||||
INodeDefManager *ndef)
|
||||
{
|
||||
// Return values
|
||||
bool bottom_sunlight_valid = true;
|
||||
|
||||
// The full area we shall touch extends one extra at top and bottom
|
||||
VoxelArea required_a = a;
|
||||
required_a.pad(v3s16(0,1,0));
|
||||
// Make sure we have access to it
|
||||
v.addArea(a);
|
||||
|
||||
s16 max_y = a.MaxEdge.Y;
|
||||
s16 min_y = a.MinEdge.Y;
|
||||
|
||||
for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++)
|
||||
for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++)
|
||||
{
|
||||
v3s16 p_overtop(x, max_y+1, z);
|
||||
bool overtop_has_sunlight = false;
|
||||
// If overtop node does not exist, trust heuristics
|
||||
if(!v.exists(p_overtop))
|
||||
overtop_has_sunlight = inexistent_top_provides_sunlight;
|
||||
else if(v.getNodeRefUnsafe(p_overtop).getContent() == CONTENT_IGNORE)
|
||||
overtop_has_sunlight = inexistent_top_provides_sunlight;
|
||||
// Otherwise refer to it's light value
|
||||
else
|
||||
overtop_has_sunlight = (v.getNodeRefUnsafe(p_overtop).getLight(
|
||||
LIGHTBANK_DAY, ndef) == LIGHT_SUN);
|
||||
|
||||
// Copy overtop's sunlight all over the place
|
||||
u8 incoming_light = overtop_has_sunlight ? LIGHT_SUN : 0;
|
||||
for(s32 y=max_y; y>=min_y; y--)
|
||||
{
|
||||
v3s16 p(x,y,z);
|
||||
MapNode &n = v.getNodeRefUnsafe(p);
|
||||
if(incoming_light == 0){
|
||||
// Do nothing
|
||||
} else if(incoming_light == LIGHT_SUN &&
|
||||
ndef->get(n).sunlight_propagates){
|
||||
// Do nothing
|
||||
} else if(!ndef->get(n).sunlight_propagates){
|
||||
incoming_light = 0;
|
||||
} else {
|
||||
incoming_light = diminish_light(incoming_light);
|
||||
}
|
||||
u8 old_light = n.getLight(LIGHTBANK_DAY, ndef);
|
||||
|
||||
if(incoming_light > old_light)
|
||||
n.setLight(LIGHTBANK_DAY, incoming_light, ndef);
|
||||
|
||||
if(diminish_light(incoming_light) != 0)
|
||||
light_sources.insert(p);
|
||||
}
|
||||
|
||||
// Check validity of sunlight at top of block below if it
|
||||
// hasn't already been proven invalid
|
||||
if(bottom_sunlight_valid)
|
||||
{
|
||||
bool sunlight_should_continue_down = (incoming_light == LIGHT_SUN);
|
||||
v3s16 p_overbottom(x, min_y-1, z);
|
||||
if(!v.exists(p_overbottom) ||
|
||||
v.getNodeRefUnsafe(p_overbottom
|
||||
).getContent() == CONTENT_IGNORE){
|
||||
// Is not known, cannot compare
|
||||
} else {
|
||||
bool overbottom_has_sunlight = (v.getNodeRefUnsafe(p_overbottom
|
||||
).getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN);
|
||||
if(sunlight_should_continue_down != overbottom_has_sunlight){
|
||||
bottom_sunlight_valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {bottom_sunlight_valid};
|
||||
}
|
||||
|
||||
/*!
|
||||
* A direction.
|
||||
* 0=X+
|
||||
|
@ -31,30 +31,6 @@ class MMVManip;
|
||||
namespace voxalgo
|
||||
{
|
||||
|
||||
// TODO: Move unspreadLight and spreadLight from VoxelManipulator to here
|
||||
|
||||
void setLight(VoxelManipulator &v, VoxelArea a, u8 light,
|
||||
INodeDefManager *ndef);
|
||||
|
||||
void clearLightAndCollectSources(VoxelManipulator &v, VoxelArea a,
|
||||
enum LightBank bank, INodeDefManager *ndef,
|
||||
std::set<v3s16> & light_sources,
|
||||
std::map<v3s16, u8> & unlight_from);
|
||||
|
||||
struct SunlightPropagateResult
|
||||
{
|
||||
bool bottom_sunlight_valid;
|
||||
|
||||
SunlightPropagateResult(bool bottom_sunlight_valid_):
|
||||
bottom_sunlight_valid(bottom_sunlight_valid_)
|
||||
{}
|
||||
};
|
||||
|
||||
SunlightPropagateResult propagateSunlight(VoxelManipulator &v, VoxelArea a,
|
||||
bool inexistent_top_provides_sunlight,
|
||||
std::set<v3s16> & light_sources,
|
||||
INodeDefManager *ndef);
|
||||
|
||||
/*!
|
||||
* Updates the lighting on the map.
|
||||
* The result will be correct only if
|
||||
|
Loading…
Reference in New Issue
Block a user