From 1f0d042377ed506ad460067495e5911b2fc2aacc Mon Sep 17 00:00:00 2001 From: lhofhansl Date: Sun, 5 Mar 2023 21:33:41 -0800 Subject: [PATCH] Reduce server CPU consumed by occlusion culling. (#13260) Cache blocks already occluded at a specific distance. The RemoteClient typically visits the same distance multiple time - especially at larger distances, so this saves significant CPU from recalculating the occlusion state of blocks. --- src/clientiface.cpp | 12 +++++++++++- src/clientiface.h | 15 ++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/clientiface.cpp b/src/clientiface.cpp index bb25a4265..49b668cf0 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -328,8 +328,15 @@ void RemoteClient::GetNextBlocks ( continue; } + /* + Check occlusion cache first. + */ + if (m_blocks_occ.find(p) != m_blocks_occ.end()) + continue; + if (m_occ_cull && !block_not_found && env->getMap().isBlockOccluded(block, cam_pos_nodes)) { + m_blocks_occ.insert(p); continue; } } @@ -395,8 +402,11 @@ queue_full_break: } } - if (new_nearest_unsent_d != -1) + if (new_nearest_unsent_d != -1 && m_nearest_unsent_d != new_nearest_unsent_d) { m_nearest_unsent_d = new_nearest_unsent_d; + // if the distance has changed, clear the occlusion cache + m_blocks_occ.clear(); + } } void RemoteClient::GotBlock(v3s16 p) diff --git a/src/clientiface.h b/src/clientiface.h index cda01650b..261c09fce 100644 --- a/src/clientiface.h +++ b/src/clientiface.h @@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #include #include @@ -379,7 +380,15 @@ private: List of block positions. No MapBlock* is stored here because the blocks can get deleted. */ - std::set m_blocks_sent; + std::unordered_set m_blocks_sent; + + /* + Cache of blocks that have been occlusion culled at the current distance. + As GetNextBlocks traverses the same distance multiple times, this saves + significant CPU time. + */ + std::unordered_set m_blocks_occ; + s16 m_nearest_unsent_d = 0; v3s16 m_last_center; v3f m_last_camera_dir; @@ -399,7 +408,7 @@ private: Block is removed when GOTBLOCKS is received. Value is time from sending. (not used at the moment) */ - std::map m_blocks_sending; + std::unordered_map m_blocks_sending; /* Blocks that have been modified since blocks were @@ -409,7 +418,7 @@ private: List of block positions. */ - std::set m_blocks_modified; + std::unordered_set m_blocks_modified; /* Count of excess GotBlocks().