From 8fdf59def6fefc9ecfa0a63551d49d82134fef14 Mon Sep 17 00:00:00 2001 From: Petr Ohlidal Date: Mon, 11 Mar 2024 04:24:10 +0100 Subject: [PATCH] :video_game: Added cvar `gfx_camera_speed` + top menu UI slider Changes: * cvar `gfx_camera_speed` replaces `CameraManager::m_cam_ratio` which was used/updated chaotically and didn't always account frame time. Default value is 4.0 like before. * New `smoothXXX()` helpers to CameraManager, replacing copypasted smoothing code. * Clarified staticcam fov exponent smoothing: Removed `Cameramanager::m_staticcam_fov_exponent` which just duplicated `gfx_static_cam_fov_exp`. Added `Cameramanager::m_staticcam_fov_exp_current` which replaces `static fovExp` (CameraManager.cpp, line 789). Comments clearly indicate what is what. --- source/main/Application.cpp | 1 + source/main/Application.h | 1 + source/main/gfx/camera/CameraManager.cpp | 64 +++++++++++------------ source/main/gfx/camera/CameraManager.h | 8 +-- source/main/gui/panels/GUI_TopMenubar.cpp | 2 + source/main/system/CVar.cpp | 1 + 6 files changed, 42 insertions(+), 35 deletions(-) diff --git a/source/main/Application.cpp b/source/main/Application.cpp index 23ddfd63d9..2c6207bcb1 100644 --- a/source/main/Application.cpp +++ b/source/main/Application.cpp @@ -234,6 +234,7 @@ CVar* gfx_shadow_quality; CVar* gfx_skidmarks_mode; CVar* gfx_sight_range; CVar* gfx_camera_height; +CVar* gfx_camera_speed; CVar* gfx_fov_external; CVar* gfx_fov_external_default; CVar* gfx_fov_internal; diff --git a/source/main/Application.h b/source/main/Application.h index 1df323f50e..01a58c1ba5 100644 --- a/source/main/Application.h +++ b/source/main/Application.h @@ -446,6 +446,7 @@ extern CVar* gfx_shadow_quality; extern CVar* gfx_skidmarks_mode; extern CVar* gfx_sight_range; extern CVar* gfx_camera_height; +extern CVar* gfx_camera_speed; extern CVar* gfx_fov_external; extern CVar* gfx_fov_external_default; extern CVar* gfx_fov_internal; diff --git a/source/main/gfx/camera/CameraManager.cpp b/source/main/gfx/camera/CameraManager.cpp index e7be9d4f3b..964f17e7d4 100644 --- a/source/main/gfx/camera/CameraManager.cpp +++ b/source/main/gfx/camera/CameraManager.cpp @@ -96,7 +96,6 @@ CameraManager::CameraManager() : , m_splinecam_mo(0) , m_splinecam_spline_pos(0.5f) , m_staticcam_force_update(false) - , m_staticcam_fov_exponent(1.0f) , m_cam_rot_x(0.0f) , m_cam_rot_y(0.3f) , m_cam_dist(5.f) @@ -104,7 +103,6 @@ CameraManager::CameraManager() : , m_cam_dist_max(0.f) , m_cam_target_direction(0.f) , m_cam_target_pitch(0.f) - , m_cam_ratio (11.f) , m_cam_look_at(Ogre::Vector3::ZERO) , m_cam_look_at_last(Ogre::Vector3::ZERO) , m_cam_look_at_smooth(Ogre::Vector3::ZERO) @@ -199,7 +197,6 @@ void CameraManager::UpdateCurrentBehavior() } case CAMERA_BEHAVIOR_STATIC: - m_staticcam_fov_exponent = App::gfx_static_cam_fov_exp->getFloat(); this->UpdateCameraBehaviorStatic(); return; @@ -335,13 +332,11 @@ void CameraManager::ResetCurrentBehavior() { m_cam_rot_y = 0.1f; m_cam_dist = 0.1f; - m_cam_ratio = 0.0f; } else { m_cam_rot_y = 0.3f; m_cam_dist = 5.0f; - m_cam_ratio = 11.0f; } m_cam_dist_min = 0; m_cam_target_pitch = 0.0f; @@ -349,7 +344,7 @@ void CameraManager::ResetCurrentBehavior() } case CAMERA_BEHAVIOR_STATIC: - m_staticcam_fov_exponent = 1.0f; + m_staticcam_fov_exp_current = 1.0f; App::gfx_static_cam_fov_exp->setVal(1.0f); return; @@ -564,7 +559,24 @@ bool CameraManager::mouseMoved(const OIS::MouseEvent& _arg) return CameraManager::CameraBehaviorOrbitMouseMoved(_arg); } - case CAMERA_BEHAVIOR_STATIC: return CameraBehaviorStaticMouseMoved(_arg); + case CAMERA_BEHAVIOR_STATIC: + { + const OIS::MouseState ms = _arg.state; + + if (ms.buttonDown(OIS::MB_Right)) + { + // Note: `gfx_static_cam_fov_exp` is the desired (target) value; current (smooth) value is `m_staticcam_fov_exp_current` + + float scale = RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LMENU) ? 0.00002f : 0.0002f; + float exp = App::gfx_static_cam_fov_exp->getFloat(); + exp += ms.Z.rel * scale; + exp = Math::Clamp(exp, 0.8f, 1.50f); + App::gfx_static_cam_fov_exp->setVal(exp); + return true; + } + + return false; + } case CAMERA_BEHAVIOR_VEHICLE: return CameraBehaviorOrbitMouseMoved(_arg); case CAMERA_BEHAVIOR_VEHICLE_SPLINE: return this->CameraBehaviorVehicleSplineMouseMoved(_arg); case CAMERA_BEHAVIOR_VEHICLE_CINECAM: return CameraBehaviorOrbitMouseMoved(_arg); @@ -786,9 +798,7 @@ void CameraManager::UpdateCameraBehaviorStatic() } } - static float fovExp = m_staticcam_fov_exponent; - fovExp = (1.0f / (m_cam_ratio + 1.0f)) * m_staticcam_fov_exponent + (m_cam_ratio / (m_cam_ratio + 1.0f)) * fovExp; - + float fovExp = this->smoothFloat(m_staticcam_fov_exp_current, App::gfx_static_cam_fov_exp->getFloat(), m_cct_dt, App::gfx_camera_speed->getFloat()); float camDist = m_staticcam_position.distance(m_staticcam_look_at); float fov = atan2(20.0f, std::pow(camDist, fovExp)); @@ -797,22 +807,6 @@ void CameraManager::UpdateCameraBehaviorStatic() App::GetCameraManager()->GetCamera()->setFOVy(Radian(fov)); } -bool CameraManager::CameraBehaviorStaticMouseMoved(const OIS::MouseEvent& _arg) -{ - const OIS::MouseState ms = _arg.state; - - if (ms.buttonDown(OIS::MB_Right)) - { - float scale = RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LMENU) ? 0.00002f : 0.0002f; - m_staticcam_fov_exponent += ms.Z.rel * scale; - m_staticcam_fov_exponent = Math::Clamp(m_staticcam_fov_exponent, 0.8f, 1.50f); - App::gfx_static_cam_fov_exp->setVal(m_staticcam_fov_exponent); - return true; - } - - return false; -} - void CameraManager::CameraBehaviorOrbitUpdate() { if (RoR::App::GetInputEngine()->getEventBoolValueBounce(EV_CAMERA_LOOKBACK)) @@ -916,7 +910,7 @@ void CameraManager::CameraBehaviorOrbitUpdate() Vector3 precedingLookAt = m_cam_look_at_smooth_last + camDisplacement; Vector3 precedingPosition = this->GetCameraNode()->getPosition() + camDisplacement; - Vector3 camPosition = (1.0f / (m_cam_ratio + 1.0f)) * desiredPosition + (m_cam_ratio / (m_cam_ratio + 1.0f)) * precedingPosition; + Vector3 camPosition = this->smoothVector3(precedingPosition, desiredPosition, m_cct_dt, App::gfx_camera_speed->getFloat()); if (App::GetGameContext()->GetTerrain()->GetCollisions() && App::GetGameContext()->GetTerrain()->GetCollisions()->forcecam) { @@ -931,7 +925,7 @@ void CameraManager::CameraBehaviorOrbitUpdate() this->GetCameraNode()->setPosition(camPosition); } - m_cam_look_at_smooth = (1.0f / (m_cam_ratio + 1.0f)) * m_cam_look_at + (m_cam_ratio / (m_cam_ratio + 1.0f)) * precedingLookAt; + m_cam_look_at_smooth = this->smoothVector3(precedingLookAt, m_cam_look_at, m_cct_dt, App::gfx_camera_speed->getFloat()); m_cam_look_at_last = m_cam_look_at; m_cam_look_at_smooth_last = m_cam_look_at_smooth; @@ -1068,8 +1062,6 @@ void CameraManager::UpdateCameraBehaviorVehicle() m_cam_target_pitch = -asin(dir.dotProduct(Vector3::UNIT_Y)); } - m_cam_ratio = 1.0f / (m_cct_dt * 4.0f); - m_cam_dist_min = std::min(m_cct_player_actor->getMinimalCameraRadius() * 2.0f, 33.0f); m_cam_look_at = m_cct_player_actor->getPosition(); @@ -1185,8 +1177,6 @@ bool CameraManager::CameraBehaviorVehicleSplineMouseMoved( const OIS::MouseEven { const OIS::MouseState ms = _arg.state; - m_cam_ratio = 1.0f / (m_cct_dt * 4.0f); - if (RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LCONTROL) && ms.buttonDown(OIS::MB_Right)) { Real splinePosDiff = ms.X.rel * std::max(0.00005f, m_splinecam_spline_len * 0.0000001f); @@ -1390,6 +1380,16 @@ void CameraManager::switchDirectlyToBehavior(CameraBehaviors new_behavior, int i } } +float CameraManager::smoothFloat(float current, float target, float dt, float speed) const +{ + return current + (target - current) * speed * dt; +} + +Ogre::Vector3 CameraManager::smoothVector3(const Ogre::Vector3& current, const Ogre::Vector3& target, float dt, float speed) const +{ + return current + (target - current) * speed * dt; +} + std::string RoR::ToLocalizedString(CameraManager::CameraBehaviors behavior) { switch (behavior) diff --git a/source/main/gfx/camera/CameraManager.h b/source/main/gfx/camera/CameraManager.h index 4b34745eec..7d15c9d732 100644 --- a/source/main/gfx/camera/CameraManager.h +++ b/source/main/gfx/camera/CameraManager.h @@ -90,7 +90,6 @@ class CameraManager void ResetCurrentBehavior(); void DeactivateCurrentBehavior(); void UpdateCameraBehaviorStatic(); - bool CameraBehaviorStaticMouseMoved(const OIS::MouseEvent& _arg); void UpdateCameraBehaviorFree(); void UpdateCameraBehaviorFixed(); void UpdateCameraBehaviorVehicle(); @@ -104,6 +103,10 @@ class CameraManager void CameraBehaviorVehicleSplineUpdateSplineDisplay(); void CreateCameraNode(); + // Helper functions + float smoothFloat(float current, float target, float dt, float speed) const; + Ogre::Vector3 smoothVector3(const Ogre::Vector3& current, const Ogre::Vector3& target, float dt, float speed) const; + Ogre::Camera* m_camera; Ogre::SceneNode* m_camera_node; @@ -124,7 +127,6 @@ class CameraManager float m_cam_dist; float m_cam_dist_min; float m_cam_dist_max; - float m_cam_ratio; Ogre::Vector3 m_cam_look_at; bool m_cam_limit_movement; Ogre::Vector3 m_cam_look_at_last; @@ -132,7 +134,7 @@ class CameraManager Ogre::Vector3 m_cam_look_at_smooth_last; // Static cam attributes bool m_staticcam_force_update; - float m_staticcam_fov_exponent; + float m_staticcam_fov_exp_current = 1.f; //!< Smoothed value; target is cvar `gfx_static_cam_fox_exp` Ogre::Radian m_staticcam_previous_fov; Ogre::Vector3 m_staticcam_look_at; Ogre::Vector3 m_staticcam_position; diff --git a/source/main/gui/panels/GUI_TopMenubar.cpp b/source/main/gui/panels/GUI_TopMenubar.cpp index 7a6f8d75ee..65d5d385a4 100644 --- a/source/main/gui/panels/GUI_TopMenubar.cpp +++ b/source/main/gui/panels/GUI_TopMenubar.cpp @@ -2464,6 +2464,8 @@ void TopMenubar::DrawCameraContextSensitiveBox() // * `gfx_fov_external` (int) ~ FOV of exterior cameras (3rd person, free cam, freefixed cam), adjustable by hotkeys EV_COMMON_FOV_{LESS/MORE/RESET}. // ------------------------------------------------------------------------------------------------- + DrawGFloatSlider(App::gfx_camera_speed, _LC("TopMenubar", "Speed"), 1.0f, 10.0f); + switch (App::GetCameraManager()->GetCurrentBehavior()) { case CameraManager::CAMERA_BEHAVIOR_STATIC: diff --git a/source/main/system/CVar.cpp b/source/main/system/CVar.cpp index 476a9810d7..3813da8373 100644 --- a/source/main/system/CVar.cpp +++ b/source/main/system/CVar.cpp @@ -176,6 +176,7 @@ void Console::cVarSetupBuiltins() App::gfx_skidmarks_mode = this->cVarCreate("gfx_skidmarks_mode", "Skidmarks", CVAR_ARCHIVE | CVAR_TYPE_INT, "0"); App::gfx_sight_range = this->cVarCreate("gfx_sight_range", "SightRange", CVAR_ARCHIVE | CVAR_TYPE_INT, "5000"); App::gfx_camera_height = this->cVarCreate("gfx_camera_height", "Static camera height", CVAR_ARCHIVE | CVAR_TYPE_INT, "5"); + App::gfx_camera_speed = this->cVarCreate("gfx_camera_speed", "Camera smoothing speed", CVAR_ARCHIVE | CVAR_TYPE_FLOAT, "4.0"); App::gfx_fov_external = this->cVarCreate("gfx_fov_external", "", CVAR_TYPE_INT, "60"); App::gfx_fov_external_default= this->cVarCreate("gfx_fov_external_default","FOV External", CVAR_ARCHIVE | CVAR_TYPE_INT, "60"); App::gfx_fov_internal = this->cVarCreate("gfx_fov_internal", "", CVAR_TYPE_INT, "75");