forked from Mirrorlandia_minetest/minetest
Detect air-only blocks instead of day/night differences (#14264)
* Detect air-only blocks instead day/night differences * Write !is_air into the former day-night-diff bit on disk, so that old server can still read maps written by new servers * Only set is_air bit when reading from disk
This commit is contained in:
parent
0d30a3071a
commit
0d4b489545
@ -2091,8 +2091,7 @@ liquid_update (Liquid update tick) float 1.0 0.001
|
|||||||
# At this distance the server will aggressively optimize which blocks are sent to
|
# At this distance the server will aggressively optimize which blocks are sent to
|
||||||
# clients.
|
# clients.
|
||||||
# Small values potentially improve performance a lot, at the expense of visible
|
# Small values potentially improve performance a lot, at the expense of visible
|
||||||
# rendering glitches (some blocks will not be rendered under water and in caves,
|
# rendering glitches (some blocks might not be rendered correctly in caves).
|
||||||
# as well as sometimes on land).
|
|
||||||
# Setting this to a value greater than max_block_send_distance disables this
|
# Setting this to a value greater than max_block_send_distance disables this
|
||||||
# optimization.
|
# optimization.
|
||||||
# Stated in MapBlocks (16 nodes).
|
# Stated in MapBlocks (16 nodes).
|
||||||
|
15
src/map.cpp
15
src/map.cpp
@ -228,12 +228,12 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
|||||||
std::vector<std::pair<v3s16, MapNode> > oldnodes;
|
std::vector<std::pair<v3s16, MapNode> > oldnodes;
|
||||||
oldnodes.emplace_back(p, oldnode);
|
oldnodes.emplace_back(p, oldnode);
|
||||||
voxalgo::update_lighting_nodes(this, oldnodes, modified_blocks);
|
voxalgo::update_lighting_nodes(this, oldnodes, modified_blocks);
|
||||||
|
|
||||||
for (auto &modified_block : modified_blocks) {
|
|
||||||
modified_block.second->expireDayNightDiff();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n.getContent() != oldnode.getContent() &&
|
||||||
|
(oldnode.getContent() == CONTENT_AIR || n.getContent() == CONTENT_AIR))
|
||||||
|
block->expireIsAirCache();
|
||||||
|
|
||||||
// Report for rollback
|
// Report for rollback
|
||||||
if(m_gamedef->rollback())
|
if(m_gamedef->rollback())
|
||||||
{
|
{
|
||||||
@ -1462,14 +1462,14 @@ void ServerMap::finishBlockMake(BlockMakeData *data,
|
|||||||
if (!block)
|
if (!block)
|
||||||
continue;
|
continue;
|
||||||
/*
|
/*
|
||||||
Update day/night difference cache of the MapBlocks
|
Update is air cache of the MapBlocks
|
||||||
*/
|
*/
|
||||||
block->expireDayNightDiff();
|
block->expireIsAirCache();
|
||||||
/*
|
/*
|
||||||
Set block as modified
|
Set block as modified
|
||||||
*/
|
*/
|
||||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
||||||
MOD_REASON_EXPIRE_DAYNIGHTDIFF);
|
MOD_REASON_EXPIRE_IS_AIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2064,6 +2064,7 @@ void MMVManip::blitBackAll(std::map<v3s16, MapBlock*> *modified_blocks,
|
|||||||
|
|
||||||
block->copyFrom(*this);
|
block->copyFrom(*this);
|
||||||
block->raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_VMANIP);
|
block->raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_VMANIP);
|
||||||
|
block->expireIsAirCache();
|
||||||
|
|
||||||
if(modified_blocks)
|
if(modified_blocks)
|
||||||
(*modified_blocks)[p] = block;
|
(*modified_blocks)[p] = block;
|
||||||
|
@ -186,57 +186,27 @@ void MapBlock::copyFrom(VoxelManipulator &dst)
|
|||||||
getPosRelative(), data_size);
|
getPosRelative(), data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapBlock::actuallyUpdateDayNightDiff()
|
void MapBlock::actuallyUpdateIsAir()
|
||||||
{
|
{
|
||||||
const NodeDefManager *nodemgr = m_gamedef->ndef();
|
// Running this function un-expires m_is_air
|
||||||
|
m_is_air_expired = false;
|
||||||
|
|
||||||
// Running this function un-expires m_day_night_differs
|
bool only_air = true;
|
||||||
m_day_night_differs_expired = false;
|
|
||||||
|
|
||||||
bool differs = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Check if any lighting value differs
|
|
||||||
*/
|
|
||||||
|
|
||||||
MapNode previous_n(CONTENT_IGNORE);
|
|
||||||
for (u32 i = 0; i < nodecount; i++) {
|
for (u32 i = 0; i < nodecount; i++) {
|
||||||
MapNode n = data[i];
|
MapNode &n = data[i];
|
||||||
|
if (n.getContent() != CONTENT_AIR) {
|
||||||
// If node is identical to previous node, don't verify if it differs
|
only_air = false;
|
||||||
if (n == previous_n)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
differs = !n.isLightDayNightEq(nodemgr->getLightingFlags(n));
|
|
||||||
if (differs)
|
|
||||||
break;
|
break;
|
||||||
previous_n = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
If some lighting values differ, check if the whole thing is
|
|
||||||
just air. If it is just air, differs = false
|
|
||||||
*/
|
|
||||||
if (differs) {
|
|
||||||
bool only_air = true;
|
|
||||||
for (u32 i = 0; i < nodecount; i++) {
|
|
||||||
MapNode &n = data[i];
|
|
||||||
if (n.getContent() != CONTENT_AIR) {
|
|
||||||
only_air = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (only_air)
|
|
||||||
differs = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set member variable
|
// Set member variable
|
||||||
m_day_night_differs = differs;
|
m_is_air = only_air;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapBlock::expireDayNightDiff()
|
void MapBlock::expireIsAirCache()
|
||||||
{
|
{
|
||||||
m_day_night_differs_expired = true;
|
m_is_air_expired = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -369,7 +339,12 @@ void MapBlock::serialize(std::ostream &os_compressed, u8 version, bool disk, int
|
|||||||
u8 flags = 0;
|
u8 flags = 0;
|
||||||
if(is_underground)
|
if(is_underground)
|
||||||
flags |= 0x01;
|
flags |= 0x01;
|
||||||
if(getDayNightDiff())
|
// This flag used to be day-night-differs, and it is no longer used.
|
||||||
|
// We write it anyway so that old servers can still use this.
|
||||||
|
// Above ground isAir implies !day-night-differs, !isAir is good enough for old servers
|
||||||
|
// to check whether above ground blocks should be sent.
|
||||||
|
// See RemoteClient::getNextBlocks(...)
|
||||||
|
if(!isAir())
|
||||||
flags |= 0x02;
|
flags |= 0x02;
|
||||||
if (!m_generated)
|
if (!m_generated)
|
||||||
flags |= 0x08;
|
flags |= 0x08;
|
||||||
@ -473,7 +448,7 @@ void MapBlock::deSerialize(std::istream &in_compressed, u8 version, bool disk)
|
|||||||
|
|
||||||
TRACESTREAM(<<"MapBlock::deSerialize "<<getPos()<<std::endl);
|
TRACESTREAM(<<"MapBlock::deSerialize "<<getPos()<<std::endl);
|
||||||
|
|
||||||
m_day_night_differs_expired = false;
|
m_is_air_expired = true;
|
||||||
|
|
||||||
if(version <= 21)
|
if(version <= 21)
|
||||||
{
|
{
|
||||||
@ -489,7 +464,9 @@ void MapBlock::deSerialize(std::istream &in_compressed, u8 version, bool disk)
|
|||||||
|
|
||||||
u8 flags = readU8(is);
|
u8 flags = readU8(is);
|
||||||
is_underground = (flags & 0x01) != 0;
|
is_underground = (flags & 0x01) != 0;
|
||||||
m_day_night_differs = (flags & 0x02) != 0;
|
// IMPORTANT: when the version is bumped to 30 we can read m_is_air from here
|
||||||
|
// m_is_air = (flags & 0x02) == 0;
|
||||||
|
|
||||||
if (version < 27)
|
if (version < 27)
|
||||||
m_lighting_complete = 0xFFFF;
|
m_lighting_complete = 0xFFFF;
|
||||||
else
|
else
|
||||||
@ -599,6 +576,10 @@ void MapBlock::deSerialize(std::istream &in_compressed, u8 version, bool disk)
|
|||||||
<<": Node timers (ver>=25)"<<std::endl);
|
<<": Node timers (ver>=25)"<<std::endl);
|
||||||
m_node_timers.deSerialize(is, version);
|
m_node_timers.deSerialize(is, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 dummy;
|
||||||
|
m_is_air = nimap.size() == 1 && nimap.getId("air", dummy);
|
||||||
|
m_is_air_expired = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACESTREAM(<<"MapBlock::deSerialize "<<getPos()
|
TRACESTREAM(<<"MapBlock::deSerialize "<<getPos()
|
||||||
@ -647,7 +628,7 @@ void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk)
|
|||||||
{
|
{
|
||||||
// Initialize default flags
|
// Initialize default flags
|
||||||
is_underground = false;
|
is_underground = false;
|
||||||
m_day_night_differs = false;
|
m_is_air = false;
|
||||||
m_lighting_complete = 0xFFFF;
|
m_lighting_complete = 0xFFFF;
|
||||||
m_generated = true;
|
m_generated = true;
|
||||||
|
|
||||||
@ -713,7 +694,6 @@ void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk)
|
|||||||
u8 flags;
|
u8 flags;
|
||||||
is.read((char*)&flags, 1);
|
is.read((char*)&flags, 1);
|
||||||
is_underground = (flags & 0x01) != 0;
|
is_underground = (flags & 0x01) != 0;
|
||||||
m_day_night_differs = (flags & 0x02) != 0;
|
|
||||||
if (version >= 18)
|
if (version >= 18)
|
||||||
m_generated = (flags & 0x08) == 0;
|
m_generated = (flags & 0x08) == 0;
|
||||||
|
|
||||||
@ -798,9 +778,13 @@ void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk)
|
|||||||
// If supported, read node definition id mapping
|
// If supported, read node definition id mapping
|
||||||
if (version >= 21) {
|
if (version >= 21) {
|
||||||
nimap.deSerialize(is);
|
nimap.deSerialize(is);
|
||||||
|
u16 dummy;
|
||||||
|
m_is_air = nimap.size() == 1 && nimap.getId("air", dummy);
|
||||||
// Else set the legacy mapping
|
// Else set the legacy mapping
|
||||||
} else {
|
} else {
|
||||||
content_mapnode_get_name_id_mapping(&nimap);
|
content_mapnode_get_name_id_mapping(&nimap);
|
||||||
|
m_is_air = false;
|
||||||
|
m_is_air_expired = true;
|
||||||
}
|
}
|
||||||
correctBlockNodeIds(&nimap, data, m_gamedef);
|
correctBlockNodeIds(&nimap, data, m_gamedef);
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ enum ModReason : u32 {
|
|||||||
MOD_REASON_STATIC_DATA_ADDED = 1 << 13,
|
MOD_REASON_STATIC_DATA_ADDED = 1 << 13,
|
||||||
MOD_REASON_STATIC_DATA_REMOVED = 1 << 14,
|
MOD_REASON_STATIC_DATA_REMOVED = 1 << 14,
|
||||||
MOD_REASON_STATIC_DATA_CHANGED = 1 << 15,
|
MOD_REASON_STATIC_DATA_CHANGED = 1 << 15,
|
||||||
MOD_REASON_EXPIRE_DAYNIGHTDIFF = 1 << 16,
|
MOD_REASON_EXPIRE_IS_AIR = 1 << 16,
|
||||||
MOD_REASON_VMANIP = 1 << 17,
|
MOD_REASON_VMANIP = 1 << 17,
|
||||||
MOD_REASON_UNKNOWN = 1 << 18,
|
MOD_REASON_UNKNOWN = 1 << 18,
|
||||||
};
|
};
|
||||||
@ -310,20 +310,19 @@ public:
|
|||||||
// Copies data from VoxelManipulator getPosRelative()
|
// Copies data from VoxelManipulator getPosRelative()
|
||||||
void copyFrom(VoxelManipulator &dst);
|
void copyFrom(VoxelManipulator &dst);
|
||||||
|
|
||||||
// Update day-night lighting difference flag.
|
// Update is air flag.
|
||||||
// Sets m_day_night_differs to appropriate value.
|
// Sets m_is_air to appropriate value.
|
||||||
// These methods don't care about neighboring blocks.
|
void actuallyUpdateIsAir();
|
||||||
void actuallyUpdateDayNightDiff();
|
|
||||||
|
|
||||||
// Call this to schedule what the previous function does to be done
|
// Call this to schedule what the previous function does to be done
|
||||||
// when the value is actually needed.
|
// when the value is actually needed.
|
||||||
void expireDayNightDiff();
|
void expireIsAirCache();
|
||||||
|
|
||||||
inline bool getDayNightDiff()
|
inline bool isAir()
|
||||||
{
|
{
|
||||||
if (m_day_night_differs_expired)
|
if (m_is_air_expired)
|
||||||
actuallyUpdateDayNightDiff();
|
actuallyUpdateIsAir();
|
||||||
return m_day_night_differs;
|
return m_is_air;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool onObjectsActivation();
|
bool onObjectsActivation();
|
||||||
@ -517,8 +516,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Whether day and night lighting differs
|
// Whether day and night lighting differs
|
||||||
bool m_day_night_differs = false;
|
bool m_is_air = false;
|
||||||
bool m_day_night_differs_expired = true;
|
bool m_is_air_expired = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
- On the server, this is used for telling whether the
|
- On the server, this is used for telling whether the
|
||||||
|
@ -354,18 +354,12 @@ void RemoteClient::GetNextBlocks (
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If block is not close, don't send it unless it is near
|
If block is not close, don't send it if it
|
||||||
ground level.
|
consists of air only.
|
||||||
|
|
||||||
Block is near ground level if night-time mesh
|
|
||||||
differs from day-time mesh.
|
|
||||||
*/
|
*/
|
||||||
if (d >= d_opt) {
|
if (d >= d_opt && block->isAir())
|
||||||
if (!block->getIsUnderground() && !block->getDayNightDiff())
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check occlusion cache first.
|
Check occlusion cache first.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user