diff --git a/src/camera.cpp b/src/camera.cpp index e0028f480..62acbe26d 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -458,7 +458,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, f32 tool_r } 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(); @@ -550,7 +550,8 @@ void Camera::updateViewingRange() { 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); diff --git a/src/clientiface.cpp b/src/clientiface.cpp index bf0bdade0..8e469cafb 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -196,6 +196,20 @@ void RemoteClient::GetNextBlocks ( 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); @@ -204,19 +218,6 @@ void RemoteClient::GetNextBlocks ( // 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; diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp index ebc81185f..12c91be91 100644 --- a/src/util/numeric.cpp +++ b/src/util/numeric.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "noise.h" // PseudoRandom, PcgRandom #include "threading/mutex_auto_lock.h" #include +#include // myrand @@ -161,3 +162,16 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, 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)))); +} diff --git a/src/util/numeric.h b/src/util/numeric.h index 347e7a49e..8ee2d585c 100644 --- a/src/util/numeric.h +++ b/src/util/numeric.h @@ -232,6 +232,8 @@ 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=NULL); +s16 adjustDist(s16 dist, float zoom_fov); + /* Returns nearest 32-bit integer for given floating point number. and in VC++ don't provide round().