diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 2ed201c5dc..efa52914a7 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -115,12 +115,12 @@ [*General] # Smooths rotation of camera, also called look or mouse smoothing. 0 to disable. -camera_smoothing (Camera smoothing) float 0.0 0.0 0.99 +camera_smoothing (Camera smoothing) float 0.0 0.0 100.0 # Smooths rotation of camera when in cinematic mode, 0 to disable. Enter cinematic mode by using the key set in Controls. # # Requires: keyboard_mouse -cinematic_camera_smoothing (Camera smoothing in cinematic mode) float 0.7 0.0 0.99 +cinematic_camera_smoothing (Camera smoothing in cinematic mode) float 0.05 0.0 100.0 # If enabled, you can place nodes at the position (feet + eye level) where you stand. # This is helpful when working with nodeboxes in small areas. diff --git a/src/client/game.cpp b/src/client/game.cpp index 078ebe776e..c7b774b8eb 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -563,10 +563,22 @@ void Game::run() processUserInput(dtime); // Update camera before player movement to avoid camera lag of one frame updateCameraDirection(&cam_view_target, dtime); - cam_view.camera_yaw += (cam_view_target.camera_yaw - - cam_view.camera_yaw) * m_cache_cam_smoothing; - cam_view.camera_pitch += (cam_view_target.camera_pitch - - cam_view.camera_pitch) * m_cache_cam_smoothing; + if (m_cache_cam_smoothing <= 0.0f) { + cam_view.camera_yaw = cam_view_target.camera_yaw; + cam_view.camera_pitch = cam_view_target.camera_pitch; + } else { + f32 cam_damp_lambda = 1.0f / m_cache_cam_smoothing * dtime; + cam_view.camera_yaw = damp( + cam_view.camera_yaw, + cam_view_target.camera_yaw, + cam_damp_lambda + ); + cam_view.camera_pitch = damp( + cam_view.camera_pitch, + cam_view_target.camera_pitch, + cam_damp_lambda + ); + } updatePlayerControl(cam_view); updatePauseState(); @@ -3706,11 +3718,11 @@ void Game::readSettings() m_cache_cam_smoothing = 0; if (g_settings->getBool("cinematic")) - m_cache_cam_smoothing = 1 - g_settings->getFloat("cinematic_camera_smoothing"); + m_cache_cam_smoothing = g_settings->getFloat("cinematic_camera_smoothing"); else - m_cache_cam_smoothing = 1 - g_settings->getFloat("camera_smoothing"); + m_cache_cam_smoothing = g_settings->getFloat("camera_smoothing"); - m_cache_cam_smoothing = rangelim(m_cache_cam_smoothing, 0.01f, 1.0f); + m_cache_cam_smoothing = std::max(0.0f, m_cache_cam_smoothing); m_cache_mouse_sensitivity = rangelim(m_cache_mouse_sensitivity, 0.001, 100.0); m_invert_mouse = g_settings->getBool("invert_mouse"); diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 5d2cbb0d19..b01c141476 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -270,7 +270,7 @@ void set_default_settings() settings->setDefault("video_driver", ""); settings->setDefault("cinematic", "false"); settings->setDefault("camera_smoothing", "0.0"); - settings->setDefault("cinematic_camera_smoothing", "0.7"); + settings->setDefault("cinematic_camera_smoothing", "0.05"); settings->setDefault("view_bobbing_amount", "1.0"); settings->setDefault("enable_3d_clouds", "true"); settings->setDefault("soft_clouds", "false"); diff --git a/src/util/numeric.h b/src/util/numeric.h index d731f830a2..4eb14740f8 100644 --- a/src/util/numeric.h +++ b/src/util/numeric.h @@ -406,6 +406,11 @@ private: float m_accumulator = 0.0f; }; +// For details about how framerate independent lerping works, see: +// https://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ +inline f32 damp(f32 a, f32 b, f32 lambda) { + return core::lerp(a, b, 1.0f - std::exp(-lambda)); +} constexpr inline bool is_power_of_two(u32 n) {