Skip to content

Commit 225e690

Browse files
authoredFeb 26, 2021
Keep mapblocks in memory if they're in range (#10714)
Some other minor parts of clientmap.cpp have been cleaned up along the way
1 parent 3edb1dd commit 225e690

File tree

3 files changed

+30
-27
lines changed

3 files changed

+30
-27
lines changed
 

Diff for: ‎src/client/clientmap.cpp

+24-21
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ void ClientMap::updateDrawList()
165165
v3s16 p_blocks_max;
166166
getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max);
167167

168+
// Read the vision range, unless unlimited range is enabled.
169+
float range = m_control.range_all ? 1e7 : m_control.wanted_range;
170+
168171
// Number of blocks currently loaded by the client
169172
u32 blocks_loaded = 0;
170173
// Number of blocks with mesh in rendering range
@@ -182,6 +185,7 @@ void ClientMap::updateDrawList()
182185
occlusion_culling_enabled = false;
183186
}
184187

188+
185189
// Uncomment to debug occluded blocks in the wireframe mode
186190
// TODO: Include this as a flag for an extended debugging setting
187191
//if (occlusion_culling_enabled && m_control.show_wireframe)
@@ -218,32 +222,34 @@ void ClientMap::updateDrawList()
218222
continue;
219223
}
220224

221-
float range = 100000 * BS;
222-
if (!m_control.range_all)
223-
range = m_control.wanted_range * BS;
225+
v3s16 block_coord = block->getPos();
226+
v3s16 block_position = block->getPosRelative() + MAP_BLOCKSIZE / 2;
224227

225-
float d = 0.0;
226-
if (!isBlockInSight(block->getPos(), camera_position,
227-
camera_direction, camera_fov, range, &d))
228-
continue;
228+
// First, perform a simple distance check, with a padding of one extra block.
229+
if (!m_control.range_all &&
230+
block_position.getDistanceFrom(cam_pos_nodes) > range + MAP_BLOCKSIZE)
231+
continue; // Out of range, skip.
229232

233+
// Keep the block alive as long as it is in range.
234+
block->resetUsageTimer();
230235
blocks_in_range_with_mesh++;
231236

232-
/*
233-
Occlusion culling
234-
*/
237+
// Frustum culling
238+
float d = 0.0;
239+
if (!isBlockInSight(block_coord, camera_position,
240+
camera_direction, camera_fov, range * BS, &d))
241+
continue;
242+
243+
// Occlusion culling
235244
if ((!m_control.range_all && d > m_control.wanted_range * BS) ||
236245
(occlusion_culling_enabled && isBlockOccluded(block, cam_pos_nodes))) {
237246
blocks_occlusion_culled++;
238247
continue;
239248
}
240249

241-
// This block is in range. Reset usage timer.
242-
block->resetUsageTimer();
243-
244250
// Add to set
245251
block->refGrab();
246-
m_drawlist[block->getPos()] = block;
252+
m_drawlist[block_coord] = block;
247253

248254
sector_blocks_drawn++;
249255
} // foreach sectorblocks
@@ -282,8 +288,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
282288
const u32 daynight_ratio = m_client->getEnv().getDayNightRatio();
283289

284290
const v3f camera_position = m_camera_position;
285-
const v3f camera_direction = m_camera_direction;
286-
const f32 camera_fov = m_camera_fov;
287291

288292
/*
289293
Get all blocks and draw all visible ones
@@ -310,11 +314,10 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
310314
if (!block->mesh)
311315
continue;
312316

313-
float d = 0.0;
314-
if (!isBlockInSight(block->getPos(), camera_position,
315-
camera_direction, camera_fov, 100000 * BS, &d))
316-
continue;
317-
317+
v3f block_pos_r = intToFloat(block->getPosRelative() + MAP_BLOCKSIZE / 2, BS);
318+
float d = camera_position.getDistanceFrom(block_pos_r);
319+
d = MYMAX(0,d - BLOCK_MAX_RADIUS);
320+
318321
// Mesh animation
319322
if (pass == scene::ESNRP_SOLID) {
320323
//MutexAutoLock lock(block->mesh_mutex);

Diff for: ‎src/util/numeric.cpp

+2-6
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,6 @@ u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed)
106106
bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
107107
f32 camera_fov, f32 range, f32 *distance_ptr)
108108
{
109-
// Maximum radius of a block. The magic number is
110-
// sqrt(3.0) / 2.0 in literal form.
111-
static constexpr const f32 block_max_radius = 0.866025403784f * MAP_BLOCKSIZE * BS;
112-
113109
v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE;
114110

115111
// Block center position
@@ -123,7 +119,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
123119
v3f blockpos_relative = blockpos - camera_pos;
124120

125121
// Total distance
126-
f32 d = MYMAX(0, blockpos_relative.getLength() - block_max_radius);
122+
f32 d = MYMAX(0, blockpos_relative.getLength() - BLOCK_MAX_RADIUS);
127123

128124
if (distance_ptr)
129125
*distance_ptr = d;
@@ -141,7 +137,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
141137
// such that a block that has any portion visible with the
142138
// current camera position will have the center visible at the
143139
// adjusted postion
144-
f32 adjdist = block_max_radius / cos((M_PI - camera_fov) / 2);
140+
f32 adjdist = BLOCK_MAX_RADIUS / cos((M_PI - camera_fov) / 2);
145141

146142
// Block position relative to adjusted camera
147143
v3f blockpos_adj = blockpos - (camera_pos - camera_dir * adjdist);

Diff for: ‎src/util/numeric.h

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2020
#pragma once
2121

2222
#include "basic_macros.h"
23+
#include "constants.h"
2324
#include "irrlichttypes.h"
2425
#include "irr_v2d.h"
2526
#include "irr_v3d.h"
@@ -36,6 +37,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3637
y = temp; \
3738
} while (0)
3839

40+
// Maximum radius of a block. The magic number is
41+
// sqrt(3.0) / 2.0 in literal form.
42+
static constexpr const f32 BLOCK_MAX_RADIUS = 0.866025403784f * MAP_BLOCKSIZE * BS;
3943

4044
inline s16 getContainerPos(s16 p, s16 d)
4145
{

0 commit comments

Comments
 (0)
Please sign in to comment.