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;
|
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)
|
void MapBlock::copyTo(VoxelManipulator &dst)
|
||||||
{
|
{
|
||||||
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
|
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
|
||||||
|
@ -348,10 +348,6 @@ public:
|
|||||||
setNode(x0 + x, y0 + y, z0 + z, node);
|
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()
|
// Copies data to VoxelManipulator to getPosRelative()
|
||||||
void copyTo(VoxelManipulator &dst);
|
void copyTo(VoxelManipulator &dst);
|
||||||
|
|
||||||
|
@ -30,8 +30,6 @@ public:
|
|||||||
|
|
||||||
void runTests(IGameDef *gamedef);
|
void runTests(IGameDef *gamedef);
|
||||||
|
|
||||||
void testPropogateSunlight(INodeDefManager *ndef);
|
|
||||||
void testClearLightAndCollectSources(INodeDefManager *ndef);
|
|
||||||
void testVoxelLineIterator(INodeDefManager *ndef);
|
void testVoxelLineIterator(INodeDefManager *ndef);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,171 +39,11 @@ void TestVoxelAlgorithms::runTests(IGameDef *gamedef)
|
|||||||
{
|
{
|
||||||
INodeDefManager *ndef = gamedef->getNodeDefManager();
|
INodeDefManager *ndef = gamedef->getNodeDefManager();
|
||||||
|
|
||||||
TEST(testPropogateSunlight, ndef);
|
|
||||||
TEST(testClearLightAndCollectSources, ndef);
|
|
||||||
TEST(testVoxelLineIterator, 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)
|
void TestVoxelAlgorithms::testVoxelLineIterator(INodeDefManager *ndef)
|
||||||
{
|
{
|
||||||
// Test some lines
|
// Test some lines
|
||||||
|
188
src/voxel.cpp
188
src/voxel.cpp
@ -315,194 +315,6 @@ void VoxelManipulator::clearFlag(u8 flags)
|
|||||||
<<volume<<" nodes"<<std::endl;*/
|
<<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);
|
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
|
//END
|
||||||
|
@ -471,15 +471,6 @@ public:
|
|||||||
|
|
||||||
void clearFlag(u8 flag);
|
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
|
Member variables
|
||||||
*/
|
*/
|
||||||
|
@ -25,136 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
namespace voxalgo
|
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.
|
* A direction.
|
||||||
* 0=X+
|
* 0=X+
|
||||||
|
@ -31,30 +31,6 @@ class MMVManip;
|
|||||||
namespace voxalgo
|
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.
|
* Updates the lighting on the map.
|
||||||
* The result will be correct only if
|
* The result will be correct only if
|
||||||
|
Loading…
Reference in New Issue
Block a user