forked from Mirrorlandia_minetest/minetest
Corrections to loops and BFS cullers (#13375)
* Reset usage timers in loops culler * Correctly touch map blocks when using bfs culler * Align use of variables * Report statistics when using loop culler
This commit is contained in:
parent
819e9fc615
commit
6c0a6925fc
@ -269,6 +269,10 @@ void ClientMap::updateDrawList()
|
|||||||
|
|
||||||
const v3s16 cam_pos_nodes = floatToInt(m_camera_position, BS);
|
const v3s16 cam_pos_nodes = floatToInt(m_camera_position, BS);
|
||||||
|
|
||||||
|
v3s16 p_blocks_min;
|
||||||
|
v3s16 p_blocks_max;
|
||||||
|
getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max);
|
||||||
|
|
||||||
// Number of blocks occlusion culled
|
// Number of blocks occlusion culled
|
||||||
u32 blocks_occlusion_culled = 0;
|
u32 blocks_occlusion_culled = 0;
|
||||||
// Number of blocks frustum culled
|
// Number of blocks frustum culled
|
||||||
@ -304,12 +308,23 @@ void ClientMap::updateDrawList()
|
|||||||
frustum and display them.
|
frustum and display them.
|
||||||
*/
|
*/
|
||||||
if (m_control.range_all || m_loops_occlusion_culler) {
|
if (m_control.range_all || m_loops_occlusion_culler) {
|
||||||
|
// Number of blocks currently loaded by the client
|
||||||
|
u32 blocks_loaded = 0;
|
||||||
|
// Number of blocks with mesh in rendering range
|
||||||
|
u32 blocks_in_range_with_mesh = 0;
|
||||||
|
|
||||||
MapBlockVect sectorblocks;
|
MapBlockVect sectorblocks;
|
||||||
|
|
||||||
for (auto §or_it : m_sectors) {
|
for (auto §or_it : m_sectors) {
|
||||||
MapSector *sector = sector_it.second;
|
MapSector *sector = sector_it.second;
|
||||||
if (!sector)
|
v2s16 sp = sector->getPos();
|
||||||
|
|
||||||
|
blocks_loaded += sector->size();
|
||||||
|
if (!m_control.range_all) {
|
||||||
|
if (sp.X < p_blocks_min.X || sp.X > p_blocks_max.X ||
|
||||||
|
sp.Y < p_blocks_min.Z || sp.Y > p_blocks_max.Z)
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
sectorblocks.clear();
|
sectorblocks.clear();
|
||||||
sector->getBlocks(sectorblocks);
|
sector->getBlocks(sectorblocks);
|
||||||
@ -334,6 +349,16 @@ void ClientMap::updateDrawList()
|
|||||||
mesh_sphere_radius = 0.0f;
|
mesh_sphere_radius = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First, perform a simple distance check.
|
||||||
|
if (!m_control.range_all &&
|
||||||
|
mesh_sphere_center.getDistanceFrom(m_camera_position) >
|
||||||
|
m_control.wanted_range * BS + mesh_sphere_radius)
|
||||||
|
continue; // Out of range, skip.
|
||||||
|
|
||||||
|
// Keep the block alive as long as it is in range.
|
||||||
|
block->resetUsageTimer();
|
||||||
|
blocks_in_range_with_mesh++;
|
||||||
|
|
||||||
// Frustum culling
|
// Frustum culling
|
||||||
// Only do coarse culling here, to account for fast camera movement.
|
// Only do coarse culling here, to account for fast camera movement.
|
||||||
// This is needed because this function is not called every frame.
|
// This is needed because this function is not called every frame.
|
||||||
@ -345,7 +370,7 @@ void ClientMap::updateDrawList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Raytraced occlusion culling - send rays from the camera to the block's corners
|
// Raytraced occlusion culling - send rays from the camera to the block's corners
|
||||||
if (occlusion_culling_enabled && m_enable_raytraced_culling &&
|
if (!m_control.range_all && occlusion_culling_enabled && m_enable_raytraced_culling &&
|
||||||
mesh &&
|
mesh &&
|
||||||
isMeshOccluded(block, mesh_grid.cell_size, cam_pos_nodes)) {
|
isMeshOccluded(block, mesh_grid.cell_size, cam_pos_nodes)) {
|
||||||
blocks_occlusion_culled++;
|
blocks_occlusion_culled++;
|
||||||
@ -367,16 +392,15 @@ void ClientMap::updateDrawList()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_profiler->avg("MapBlock meshes in range [#]", blocks_in_range_with_mesh);
|
||||||
|
g_profiler->avg("MapBlocks loaded [#]", blocks_loaded);
|
||||||
} else {
|
} else {
|
||||||
// Blocks visited by the algorithm
|
// Blocks visited by the algorithm
|
||||||
u32 blocks_visited = 0;
|
u32 blocks_visited = 0;
|
||||||
// Block sides that were not traversed
|
// Block sides that were not traversed
|
||||||
u32 sides_skipped = 0;
|
u32 sides_skipped = 0;
|
||||||
|
|
||||||
v3s16 p_blocks_min;
|
|
||||||
v3s16 p_blocks_max;
|
|
||||||
getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max);
|
|
||||||
|
|
||||||
std::queue<v3s16> blocks_to_consider;
|
std::queue<v3s16> blocks_to_consider;
|
||||||
|
|
||||||
v3s16 camera_mesh = mesh_grid.getMeshPos(camera_block);
|
v3s16 camera_mesh = mesh_grid.getMeshPos(camera_block);
|
||||||
@ -595,7 +619,7 @@ void ClientMap::updateDrawList()
|
|||||||
|
|
||||||
void ClientMap::touchMapBlocks()
|
void ClientMap::touchMapBlocks()
|
||||||
{
|
{
|
||||||
if (!m_loops_occlusion_culler)
|
if (m_control.range_all || m_loops_occlusion_culler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v3s16 cam_pos_nodes = floatToInt(m_camera_position, BS);
|
v3s16 cam_pos_nodes = floatToInt(m_camera_position, BS);
|
||||||
@ -609,8 +633,6 @@ void ClientMap::touchMapBlocks()
|
|||||||
// Number of blocks with mesh in rendering range
|
// Number of blocks with mesh in rendering range
|
||||||
u32 blocks_in_range_with_mesh = 0;
|
u32 blocks_in_range_with_mesh = 0;
|
||||||
|
|
||||||
v3f cam_pos_f = intToFloat(cam_pos_nodes, BS);
|
|
||||||
|
|
||||||
for (const auto §or_it : m_sectors) {
|
for (const auto §or_it : m_sectors) {
|
||||||
MapSector *sector = sector_it.second;
|
MapSector *sector = sector_it.second;
|
||||||
v2s16 sp = sector->getPos();
|
v2s16 sp = sector->getPos();
|
||||||
@ -630,23 +652,27 @@ void ClientMap::touchMapBlocks()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
for (MapBlock *block : sectorblocks) {
|
for (MapBlock *block : sectorblocks) {
|
||||||
/*
|
MapBlockMesh *mesh = block->mesh;
|
||||||
Compare block position to camera position, skip
|
|
||||||
if not seen on display
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!block->mesh) {
|
// Calculate the coordinates for range and frustum culling
|
||||||
// Ignore if mesh doesn't exist
|
v3f mesh_sphere_center;
|
||||||
continue;
|
f32 mesh_sphere_radius;
|
||||||
|
|
||||||
|
v3s16 block_pos_nodes = block->getPos() * MAP_BLOCKSIZE;
|
||||||
|
|
||||||
|
if (mesh) {
|
||||||
|
mesh_sphere_center = intToFloat(block_pos_nodes, BS)
|
||||||
|
+ mesh->getBoundingSphereCenter();
|
||||||
|
mesh_sphere_radius = mesh->getBoundingRadius();
|
||||||
|
} else {
|
||||||
|
mesh_sphere_center = intToFloat(block_pos_nodes, BS)
|
||||||
|
+ v3f((MAP_BLOCKSIZE * 0.5f - 0.5f) * BS);
|
||||||
|
mesh_sphere_radius = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
v3f mesh_sphere_center = intToFloat(block->getPosRelative(), BS)
|
|
||||||
+ block->mesh->getBoundingSphereCenter();
|
|
||||||
f32 mesh_sphere_radius = block->mesh->getBoundingRadius();
|
|
||||||
|
|
||||||
// First, perform a simple distance check.
|
// First, perform a simple distance check.
|
||||||
if (!m_control.range_all &&
|
if (!m_control.range_all &&
|
||||||
mesh_sphere_center.getDistanceFrom(cam_pos_f) >
|
mesh_sphere_center.getDistanceFrom(m_camera_position) >
|
||||||
m_control.wanted_range * BS + mesh_sphere_radius)
|
m_control.wanted_range * BS + mesh_sphere_radius)
|
||||||
continue; // Out of range, skip.
|
continue; // Out of range, skip.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user