Optimize swapping nodes with equivalent lighting

master
Jude Melton-Houghton 2022-03-29 12:06:44 -04:00 committed by GitHub
parent 8d387433b1
commit 11aab4198b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 21 deletions

View File

@ -165,22 +165,30 @@ MapNode Map::getNode(v3s16 p, bool *is_valid_position)
return node;
}
static void set_node_in_block(MapBlock *block, v3s16 relpos, MapNode n)
{
// Never allow placing CONTENT_IGNORE, it causes problems
if(n.getContent() == CONTENT_IGNORE){
const NodeDefManager *nodedef = block->getParent()->getNodeDefManager();
v3s16 blockpos = block->getPos();
v3s16 p = blockpos * MAP_BLOCKSIZE + relpos;
bool temp_bool;
errorstream<<"Not allowing to place CONTENT_IGNORE"
<<" while trying to replace \""
<<nodedef->get(block->getNodeNoCheck(relpos, &temp_bool)).name
<<"\" at "<<PP(p)<<" (block "<<PP(blockpos)<<")"<<std::endl;
return;
}
block->setNodeNoCheck(relpos, n);
}
// throws InvalidPositionException if not found
void Map::setNode(v3s16 p, MapNode & n)
{
v3s16 blockpos = getNodeBlockPos(p);
MapBlock *block = getBlockNoCreate(blockpos);
v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
// Never allow placing CONTENT_IGNORE, it causes problems
if(n.getContent() == CONTENT_IGNORE){
bool temp_bool;
errorstream<<"Map::setNode(): Not allowing to place CONTENT_IGNORE"
<<" while trying to replace \""
<<m_nodedef->get(block->getNodeNoCheck(relpos, &temp_bool)).name
<<"\" at "<<PP(p)<<" (block "<<PP(blockpos)<<")"<<std::endl;
return;
}
block->setNodeNoCheck(relpos, n);
set_node_in_block(block, relpos, n);
}
void Map::addNodeAndUpdate(v3s16 p, MapNode n,
@ -190,8 +198,14 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
// Collect old node for rollback
RollbackNode rollback_oldnode(this, p, m_gamedef);
v3s16 blockpos = getNodeBlockPos(p);
MapBlock *block = getBlockNoCreate(blockpos);
if (block->isDummy())
throw InvalidPositionException();
v3s16 relpos = p - blockpos * MAP_BLOCKSIZE;
// This is needed for updating the lighting
MapNode oldnode = getNode(p);
MapNode oldnode = block->getNodeUnsafe(relpos);
// Remove node metadata
if (remove_metadata) {
@ -199,18 +213,29 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
}
// Set the node on the map
// Ignore light (because calling voxalgo::update_lighting_nodes)
n.setLight(LIGHTBANK_DAY, 0, m_nodedef);
n.setLight(LIGHTBANK_NIGHT, 0, m_nodedef);
setNode(p, n);
const ContentFeatures &cf = m_nodedef->get(n);
const ContentFeatures &oldcf = m_nodedef->get(oldnode);
if (cf.lightingEquivalent(oldcf)) {
// No light update needed, just copy over the old light.
n.setLight(LIGHTBANK_DAY, oldnode.getLightRaw(LIGHTBANK_DAY, oldcf), cf);
n.setLight(LIGHTBANK_NIGHT, oldnode.getLightRaw(LIGHTBANK_NIGHT, oldcf), cf);
set_node_in_block(block, relpos, n);
// Update lighting
std::vector<std::pair<v3s16, MapNode> > oldnodes;
oldnodes.emplace_back(p, oldnode);
voxalgo::update_lighting_nodes(this, oldnodes, modified_blocks);
modified_blocks[blockpos] = block;
} else {
// Ignore light (because calling voxalgo::update_lighting_nodes)
n.setLight(LIGHTBANK_DAY, 0, cf);
n.setLight(LIGHTBANK_NIGHT, 0, cf);
set_node_in_block(block, relpos, n);
for (auto &modified_block : modified_blocks) {
modified_block.second->expireDayNightDiff();
// Update lighting
std::vector<std::pair<v3s16, MapNode> > oldnodes;
oldnodes.emplace_back(p, oldnode);
voxalgo::update_lighting_nodes(this, oldnodes, modified_blocks);
for (auto &modified_block : modified_blocks) {
modified_block.second->expireDayNightDiff();
}
}
// Report for rollback

View File

@ -478,6 +478,12 @@ struct ContentFeatures
return (liquid_alternative_flowing_id == f.liquid_alternative_flowing_id);
}
bool lightingEquivalent(const ContentFeatures &other) const {
return light_propagates == other.light_propagates
&& sunlight_propagates == other.sunlight_propagates
&& light_source == other.light_source;
}
int getGroup(const std::string &group) const
{
return itemgroup_get(groups, group);