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
u32 blocks_occlusion_culled = 0;
// Number of blocks frustum culled
frustum and display them.
*/
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;
for (auto §or_it : m_sectors) {
MapSector *sector = sector_it.second;
- if (!sector)
- continue;
+ 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;
+ }
sectorblocks.clear();
sector->getBlocks(sectorblocks);
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
// Only do coarse culling here, to account for fast camera movement.
// This is needed because this function is not called every frame.
}
// 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 &&
isMeshOccluded(block, mesh_grid.cell_size, cam_pos_nodes)) {
blocks_occlusion_culled++;
}
}
}
+
+ g_profiler->avg("MapBlock meshes in range [#]", blocks_in_range_with_mesh);
+ g_profiler->avg("MapBlocks loaded [#]", blocks_loaded);
} else {
// Blocks visited by the algorithm
u32 blocks_visited = 0;
// Block sides that were not traversed
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;
v3s16 camera_mesh = mesh_grid.getMeshPos(camera_block);
void ClientMap::touchMapBlocks()
{
- if (!m_loops_occlusion_culler)
+ if (m_control.range_all || m_loops_occlusion_culler)
return;
v3s16 cam_pos_nodes = floatToInt(m_camera_position, BS);
// Number of blocks with mesh in rendering range
u32 blocks_in_range_with_mesh = 0;
- v3f cam_pos_f = intToFloat(cam_pos_nodes, BS);
-
for (const auto §or_it : m_sectors) {
MapSector *sector = sector_it.second;
v2s16 sp = sector->getPos();
*/
for (MapBlock *block : sectorblocks) {
- /*
- Compare block position to camera position, skip
- if not seen on display
- */
+ MapBlockMesh *mesh = block->mesh;
- if (!block->mesh) {
- // Ignore if mesh doesn't exist
- continue;
- }
+ // Calculate the coordinates for range and frustum culling
+ v3f mesh_sphere_center;
+ f32 mesh_sphere_radius;
+
+ v3s16 block_pos_nodes = block->getPos() * MAP_BLOCKSIZE;
- v3f mesh_sphere_center = intToFloat(block->getPosRelative(), BS)
- + block->mesh->getBoundingSphereCenter();
- f32 mesh_sphere_radius = block->mesh->getBoundingRadius();
+ 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;
+ }
// First, perform a simple distance check.
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)
continue; // Out of range, skip.