]> git.lizzy.rs Git - minetest.git/commitdiff
Keep mapblocks in memory if they're in range (#10714)
authorhecks <42101236+hecktest@users.noreply.github.com>
Fri, 26 Feb 2021 20:23:46 +0000 (21:23 +0100)
committerGitHub <noreply@github.com>
Fri, 26 Feb 2021 20:23:46 +0000 (21:23 +0100)
Some other minor parts of clientmap.cpp have been cleaned up along the way

src/client/clientmap.cpp
src/util/numeric.cpp
src/util/numeric.h

index b9e0cc2ce4320e852790a6c0b27b7d1795762886..be83430092be438a5394b2c07452a1bc55b16497 100644 (file)
@@ -165,6 +165,9 @@ void ClientMap::updateDrawList()
        v3s16 p_blocks_max;
        getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max);
 
+       // Read the vision range, unless unlimited range is enabled.
+       float range = m_control.range_all ? 1e7 : m_control.wanted_range;
+
        // Number of blocks currently loaded by the client
        u32 blocks_loaded = 0;
        // Number of blocks with mesh in rendering range
@@ -182,6 +185,7 @@ void ClientMap::updateDrawList()
                        occlusion_culling_enabled = false;
        }
 
+
        // Uncomment to debug occluded blocks in the wireframe mode
        // TODO: Include this as a flag for an extended debugging setting
        //if (occlusion_culling_enabled && m_control.show_wireframe)
@@ -218,32 +222,34 @@ void ClientMap::updateDrawList()
                                continue;
                        }
 
-                       float range = 100000 * BS;
-                       if (!m_control.range_all)
-                               range = m_control.wanted_range * BS;
+                       v3s16 block_coord = block->getPos();
+                       v3s16 block_position = block->getPosRelative() + MAP_BLOCKSIZE / 2;
 
-                       float d = 0.0;
-                       if (!isBlockInSight(block->getPos(), camera_position,
-                                       camera_direction, camera_fov, range, &d))
-                               continue;
+                       // First, perform a simple distance check, with a padding of one extra block.
+                       if (!m_control.range_all &&
+                                       block_position.getDistanceFrom(cam_pos_nodes) > range + MAP_BLOCKSIZE)
+                               continue; // Out of range, skip.
 
+                       // Keep the block alive as long as it is in range.
+                       block->resetUsageTimer();
                        blocks_in_range_with_mesh++;
 
-                       /*
-                               Occlusion culling
-                       */
+                       // Frustum culling
+                       float d = 0.0;
+                       if (!isBlockInSight(block_coord, camera_position,
+                                       camera_direction, camera_fov, range * BS, &d))
+                               continue;
+
+                       // Occlusion culling
                        if ((!m_control.range_all && d > m_control.wanted_range * BS) ||
                                        (occlusion_culling_enabled && isBlockOccluded(block, cam_pos_nodes))) {
                                blocks_occlusion_culled++;
                                continue;
                        }
 
-                       // This block is in range. Reset usage timer.
-                       block->resetUsageTimer();
-
                        // Add to set
                        block->refGrab();
-                       m_drawlist[block->getPos()] = block;
+                       m_drawlist[block_coord] = block;
 
                        sector_blocks_drawn++;
                } // foreach sectorblocks
@@ -282,8 +288,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
        const u32 daynight_ratio = m_client->getEnv().getDayNightRatio();
 
        const v3f camera_position = m_camera_position;
-       const v3f camera_direction = m_camera_direction;
-       const f32 camera_fov = m_camera_fov;
 
        /*
                Get all blocks and draw all visible ones
@@ -310,11 +314,10 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                if (!block->mesh)
                        continue;
 
-               float d = 0.0;
-               if (!isBlockInSight(block->getPos(), camera_position,
-                               camera_direction, camera_fov, 100000 * BS, &d))
-                       continue;
-
+               v3f block_pos_r = intToFloat(block->getPosRelative() + MAP_BLOCKSIZE / 2, BS);
+               float d = camera_position.getDistanceFrom(block_pos_r);
+               d = MYMAX(0,d - BLOCK_MAX_RADIUS);
+               
                // Mesh animation
                if (pass == scene::ESNRP_SOLID) {
                        //MutexAutoLock lock(block->mesh_mutex);
index 1af3f66be8df9f096737e8a4809cf497688e905c..99e4cfb5ce24d5804b4342058aa6bd8fecca272a 100644 (file)
@@ -106,10 +106,6 @@ u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed)
 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
                f32 camera_fov, f32 range, f32 *distance_ptr)
 {
-       // Maximum radius of a block.  The magic number is
-       // sqrt(3.0) / 2.0 in literal form.
-       static constexpr const f32 block_max_radius = 0.866025403784f * MAP_BLOCKSIZE * BS;
-
        v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE;
 
        // Block center position
@@ -123,7 +119,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
        v3f blockpos_relative = blockpos - camera_pos;
 
        // Total distance
-       f32 d = MYMAX(0, blockpos_relative.getLength() - block_max_radius);
+       f32 d = MYMAX(0, blockpos_relative.getLength() - BLOCK_MAX_RADIUS);
 
        if (distance_ptr)
                *distance_ptr = d;
@@ -141,7 +137,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
        // such that a block that has any portion visible with the
        // current camera position will have the center visible at the
        // adjusted postion
-       f32 adjdist = block_max_radius / cos((M_PI - camera_fov) / 2);
+       f32 adjdist = BLOCK_MAX_RADIUS / cos((M_PI - camera_fov) / 2);
 
        // Block position relative to adjusted camera
        v3f blockpos_adj = blockpos - (camera_pos - camera_dir * adjdist);
index 864ab754369be02c5c524de2b1e5ab687eb60e9e..32a6f4312b04abc975a96021912fff965f8502de 100644 (file)
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #pragma once
 
 #include "basic_macros.h"
+#include "constants.h"
 #include "irrlichttypes.h"
 #include "irr_v2d.h"
 #include "irr_v3d.h"
@@ -36,6 +37,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        y = temp; \
 } while (0)
 
+// Maximum radius of a block.  The magic number is
+// sqrt(3.0) / 2.0 in literal form.
+static constexpr const f32 BLOCK_MAX_RADIUS = 0.866025403784f * MAP_BLOCKSIZE * BS;
 
 inline s16 getContainerPos(s16 p, s16 d)
 {