} else {
fov_degrees = m_cache_fov;
}
- fov_degrees = rangelim(fov_degrees, 7.0, 160.0);
+ fov_degrees = rangelim(fov_degrees, 1.0, 160.0);
// FOV and aspect ratio
const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
{
f32 viewing_range = g_settings->getFloat("viewing_range");
f32 near_plane = g_settings->getFloat("near_plane");
- m_draw_control.wanted_range = viewing_range;
+
+ m_draw_control.wanted_range = std::fmin(adjustDist(viewing_range, getFovMax()), 4000);
m_cameranode->setNearValue(rangelim(near_plane, 0.0f, 0.5f) * BS);
if (m_draw_control.range_all) {
m_cameranode->setFarValue(100000.0);
s16 wanted_range = sao->getWantedRange() + 1;
float camera_fov = sao->getFov();
+ const s16 full_d_max = std::min(adjustDist(m_max_send_distance, camera_fov), wanted_range);
+ const s16 d_opt = std::min(adjustDist(m_block_optimize_distance, camera_fov), wanted_range);
+ const s16 d_blocks_in_sight = full_d_max * BS * MAP_BLOCKSIZE;
+ infostream << "Fov from client " << camera_fov << " full_d_max " << full_d_max << std::endl;
+
+ s16 d_max = full_d_max;
+ s16 d_max_gen = std::min(adjustDist(m_max_gen_distance, camera_fov), wanted_range);
+
+ // Don't loop very much at a time, adjust with distance,
+ // do more work per RTT with greater distances.
+ s16 max_d_increment_at_time = full_d_max / 9 + 1;
+ if (d_max > d_start + max_d_increment_at_time)
+ d_max = d_start + max_d_increment_at_time;
+
// cos(angle between velocity and camera) * |velocity|
// Limit to 0.0f in case player moves backwards.
f32 dot = rangelim(camera_dir.dotProduct(playerspeed), 0.0f, 300.0f);
// limit max fov effect to 50%, 60% at 20n/s fly speed
camera_fov = camera_fov / (1 + dot / 300.0f);
- const s16 full_d_max = std::min(m_max_send_distance, wanted_range);
- const s16 d_opt = std::min(m_block_optimize_distance, wanted_range);
- const s16 d_blocks_in_sight = full_d_max * BS * MAP_BLOCKSIZE;
- //infostream << "Fov from client " << camera_fov << " full_d_max " << full_d_max << std::endl;
-
- s16 d_max = full_d_max;
- s16 d_max_gen = std::min(m_max_gen_distance, wanted_range);
-
- // Don't loop very much at a time
- s16 max_d_increment_at_time = 2;
- if (d_max > d_start + max_d_increment_at_time)
- d_max = d_start + max_d_increment_at_time;
-
s32 nearest_emerged_d = -1;
s32 nearest_emergefull_d = -1;
s32 nearest_sent_d = -1;
#include "noise.h" // PseudoRandom, PcgRandom
#include "threading/mutex_auto_lock.h"
#include <cstring>
+#include <cmath>
// myrand
return true;
}
+
+s16 adjustDist(s16 dist, float zoom_fov)
+{
+ // 1.775 ~= 72 * PI / 180 * 1.4, the default on the client
+ const float default_fov = 1.775f;
+ // heuristic cut-off for zooming
+ if (zoom_fov > default_fov / 2.0f)
+ return dist;
+
+ // new_dist = dist * ((1 - cos(FOV / 2)) / (1-cos(zoomFOV /2))) ^ (1/3)
+ return round(dist * cbrt((1.0f - cos(default_fov / 2.0f)) /
+ (1.0f - cos(zoom_fov / 2.0f))));
+}
bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
f32 camera_fov, f32 range, f32 *distance_ptr=NULL);
+s16 adjustDist(s16 dist, float zoom_fov);
+
/*
Returns nearest 32-bit integer for given floating point number.
<cmath> and <math.h> in VC++ don't provide round().