forked from Mirrorlandia_minetest/minetest
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.
This commit is contained in:
parent
9ef3c8ce38
commit
1f0d042377
@ -328,8 +328,15 @@ void RemoteClient::GetNextBlocks (
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check occlusion cache first.
|
||||||
|
*/
|
||||||
|
if (m_blocks_occ.find(p) != m_blocks_occ.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (m_occ_cull && !block_not_found &&
|
if (m_occ_cull && !block_not_found &&
|
||||||
env->getMap().isBlockOccluded(block, cam_pos_nodes)) {
|
env->getMap().isBlockOccluded(block, cam_pos_nodes)) {
|
||||||
|
m_blocks_occ.insert(p);
|
||||||
continue;
|
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;
|
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)
|
void RemoteClient::GotBlock(v3s16 p)
|
||||||
|
@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <unordered_set>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
@ -379,7 +380,15 @@ private:
|
|||||||
List of block positions.
|
List of block positions.
|
||||||
No MapBlock* is stored here because the blocks can get deleted.
|
No MapBlock* is stored here because the blocks can get deleted.
|
||||||
*/
|
*/
|
||||||
std::set<v3s16> m_blocks_sent;
|
std::unordered_set<v3s16> 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<v3s16> m_blocks_occ;
|
||||||
|
|
||||||
s16 m_nearest_unsent_d = 0;
|
s16 m_nearest_unsent_d = 0;
|
||||||
v3s16 m_last_center;
|
v3s16 m_last_center;
|
||||||
v3f m_last_camera_dir;
|
v3f m_last_camera_dir;
|
||||||
@ -399,7 +408,7 @@ private:
|
|||||||
Block is removed when GOTBLOCKS is received.
|
Block is removed when GOTBLOCKS is received.
|
||||||
Value is time from sending. (not used at the moment)
|
Value is time from sending. (not used at the moment)
|
||||||
*/
|
*/
|
||||||
std::map<v3s16, float> m_blocks_sending;
|
std::unordered_map<v3s16, float> m_blocks_sending;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Blocks that have been modified since blocks were
|
Blocks that have been modified since blocks were
|
||||||
@ -409,7 +418,7 @@ private:
|
|||||||
|
|
||||||
List of block positions.
|
List of block positions.
|
||||||
*/
|
*/
|
||||||
std::set<v3s16> m_blocks_modified;
|
std::unordered_set<v3s16> m_blocks_modified;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Count of excess GotBlocks().
|
Count of excess GotBlocks().
|
||||||
|
Loading…
Reference in New Issue
Block a user