diff --git a/Source/Core/Core/FreeLookManager.cpp b/Source/Core/Core/FreeLookManager.cpp index 39d1f47278..ac0206ced9 100644 --- a/Source/Core/Core/FreeLookManager.cpp +++ b/Source/Core/Core/FreeLookManager.cpp @@ -216,6 +216,15 @@ void FreeLookController::Update() if (!g_freelook_camera.IsActive()) return; + auto* camera_controller = g_freelook_camera.GetController(); + if (camera_controller->SupportsInput()) + { + UpdateInput(static_cast(camera_controller)); + } +} + +void FreeLookController::UpdateInput(CameraControllerInput* camera_controller) +{ const auto lock = GetStateLock(); float dt = 1.0; @@ -239,48 +248,48 @@ void FreeLookController::Update() const auto gyro_motion_quat = Common::Quaternion::RotateXYZ(gyro_motion_rad_velocity_converted * dt); - g_freelook_camera.Rotate(gyro_motion_quat); + camera_controller->Rotate(gyro_motion_quat); if (m_move_buttons->controls[MoveButtons::Up]->GetState()) - g_freelook_camera.MoveVertical(-g_freelook_camera.GetSpeed() * dt); + camera_controller->MoveVertical(-camera_controller->GetSpeed() * dt); if (m_move_buttons->controls[MoveButtons::Down]->GetState()) - g_freelook_camera.MoveVertical(g_freelook_camera.GetSpeed() * dt); + camera_controller->MoveVertical(camera_controller->GetSpeed() * dt); if (m_move_buttons->controls[MoveButtons::Left]->GetState()) - g_freelook_camera.MoveHorizontal(g_freelook_camera.GetSpeed() * dt); + camera_controller->MoveHorizontal(camera_controller->GetSpeed() * dt); if (m_move_buttons->controls[MoveButtons::Right]->GetState()) - g_freelook_camera.MoveHorizontal(-g_freelook_camera.GetSpeed() * dt); + camera_controller->MoveHorizontal(-camera_controller->GetSpeed() * dt); if (m_move_buttons->controls[MoveButtons::Forward]->GetState()) - g_freelook_camera.MoveForward(g_freelook_camera.GetSpeed() * dt); + camera_controller->MoveForward(camera_controller->GetSpeed() * dt); if (m_move_buttons->controls[MoveButtons::Backward]->GetState()) - g_freelook_camera.MoveForward(-g_freelook_camera.GetSpeed() * dt); + camera_controller->MoveForward(-camera_controller->GetSpeed() * dt); if (m_fov_buttons->controls[FieldOfViewButtons::IncreaseX]->GetState()) - g_freelook_camera.IncreaseFovX(g_freelook_camera.GetFovStepSize() * dt); + camera_controller->IncreaseFovX(camera_controller->GetFovStepSize() * dt); if (m_fov_buttons->controls[FieldOfViewButtons::DecreaseX]->GetState()) - g_freelook_camera.IncreaseFovX(-1.0f * g_freelook_camera.GetFovStepSize() * dt); + camera_controller->IncreaseFovX(-1.0f * camera_controller->GetFovStepSize() * dt); if (m_fov_buttons->controls[FieldOfViewButtons::IncreaseY]->GetState()) - g_freelook_camera.IncreaseFovY(g_freelook_camera.GetFovStepSize() * dt); + camera_controller->IncreaseFovY(camera_controller->GetFovStepSize() * dt); if (m_fov_buttons->controls[FieldOfViewButtons::DecreaseY]->GetState()) - g_freelook_camera.IncreaseFovY(-1.0f * g_freelook_camera.GetFovStepSize() * dt); + camera_controller->IncreaseFovY(-1.0f * camera_controller->GetFovStepSize() * dt); if (m_speed_buttons->controls[SpeedButtons::Decrease]->GetState()) - g_freelook_camera.ModifySpeed(g_freelook_camera.GetSpeed() * -0.9 * dt); + camera_controller->ModifySpeed(camera_controller->GetSpeed() * -0.9 * dt); if (m_speed_buttons->controls[SpeedButtons::Increase]->GetState()) - g_freelook_camera.ModifySpeed(g_freelook_camera.GetSpeed() * 1.1 * dt); + camera_controller->ModifySpeed(camera_controller->GetSpeed() * 1.1 * dt); if (m_speed_buttons->controls[SpeedButtons::Reset]->GetState()) - g_freelook_camera.ResetSpeed(); + camera_controller->ResetSpeed(); if (m_other_buttons->controls[OtherButtons::ResetView]->GetState()) - g_freelook_camera.Reset(); + camera_controller->Reset(); } namespace FreeLook diff --git a/Source/Core/Core/FreeLookManager.h b/Source/Core/Core/FreeLookManager.h index 87ed4c694b..16cfe909e0 100644 --- a/Source/Core/Core/FreeLookManager.h +++ b/Source/Core/Core/FreeLookManager.h @@ -9,6 +9,7 @@ #include "Common/CommonTypes.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" +class CameraControllerInput; class InputConfig; namespace ControllerEmu @@ -52,6 +53,7 @@ public: void Update(); private: + void UpdateInput(CameraControllerInput* camera_controller); ControllerEmu::Buttons* m_move_buttons; ControllerEmu::Buttons* m_speed_buttons; ControllerEmu::Buttons* m_fov_buttons; diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 1a34e4919b..7283424abc 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -73,7 +73,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 137; // Last changed in PR 9803 +constexpr u32 STATE_VERSION = 138; // Last changed in PR 9670 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list, diff --git a/Source/Core/VideoCommon/FreeLookCamera.cpp b/Source/Core/VideoCommon/FreeLookCamera.cpp index 9c2987717b..55d86d9d27 100644 --- a/Source/Core/VideoCommon/FreeLookCamera.cpp +++ b/Source/Core/VideoCommon/FreeLookCamera.cpp @@ -35,12 +35,12 @@ std::string to_string(FreeLook::ControlType type) return ""; } -class SixAxisController final : public CameraController +class SixAxisController final : public CameraControllerInput { public: SixAxisController() = default; - Common::Matrix44 GetView() override { return m_mat; } + Common::Matrix44 GetView() const override { return m_mat; } void MoveVertical(float amt) override { @@ -64,18 +64,26 @@ public: m_mat = Common::Matrix44::FromQuaternion(quat) * m_mat; } - void Reset() override { m_mat = Common::Matrix44::Identity(); } + void Reset() override + { + CameraControllerInput::Reset(); + m_mat = Common::Matrix44::Identity(); + } - void DoState(PointerWrap& p) override { p.Do(m_mat); } + void DoState(PointerWrap& p) override + { + CameraControllerInput::DoState(p); + p.Do(m_mat); + } private: Common::Matrix44 m_mat = Common::Matrix44::Identity(); }; -class FPSController final : public CameraController +class FPSController final : public CameraControllerInput { public: - Common::Matrix44 GetView() override + Common::Matrix44 GetView() const override { return Common::Matrix44::FromQuaternion(m_rotate_quat) * Common::Matrix44::Translate(m_position); @@ -118,6 +126,7 @@ public: void Reset() override { + CameraControllerInput::Reset(); m_position = Common::Vec3{}; m_rotation = Common::Vec3{}; m_rotate_quat = Common::Quaternion::Identity(); @@ -125,6 +134,7 @@ public: void DoState(PointerWrap& p) override { + CameraControllerInput::DoState(p); p.Do(m_rotation); p.Do(m_rotate_quat); p.Do(m_position); @@ -136,10 +146,10 @@ private: Common::Vec3 m_position = Common::Vec3{}; }; -class OrbitalController final : public CameraController +class OrbitalController final : public CameraControllerInput { public: - Common::Matrix44 GetView() override + Common::Matrix44 GetView() const override { return Common::Matrix44::Translate(Common::Vec3{0, 0, -m_distance}) * Common::Matrix44::FromQuaternion(m_rotate_quat); @@ -152,7 +162,7 @@ public: void MoveForward(float amt) override { m_distance += -1 * amt; - m_distance = std::clamp(m_distance, 0.0f, m_distance); + m_distance = std::max(m_distance, MIN_DISTANCE); } void Rotate(const Common::Vec3& amt) override @@ -174,25 +184,80 @@ public: void Reset() override { + CameraControllerInput::Reset(); m_rotation = Common::Vec3{}; m_rotate_quat = Common::Quaternion::Identity(); - m_distance = 0; + m_distance = MIN_DISTANCE; } void DoState(PointerWrap& p) override { + CameraControllerInput::DoState(p); p.Do(m_rotation); p.Do(m_rotate_quat); p.Do(m_distance); } private: - float m_distance = 0; + static constexpr float MIN_DISTANCE = 0.0f; + float m_distance = MIN_DISTANCE; Common::Vec3 m_rotation = Common::Vec3{}; Common::Quaternion m_rotate_quat = Common::Quaternion::Identity(); }; } // namespace +Common::Vec2 CameraControllerInput::GetFieldOfViewMultiplier() const +{ + return Common::Vec2{m_fov_x_multiplier, m_fov_y_multiplier}; +} + +void CameraControllerInput::DoState(PointerWrap& p) +{ + p.Do(m_speed); + p.Do(m_fov_x_multiplier); + p.Do(m_fov_y_multiplier); +} + +void CameraControllerInput::IncreaseFovX(float fov) +{ + m_fov_x_multiplier += fov; + m_fov_x_multiplier = std::max(m_fov_x_multiplier, MIN_FOV_MULTIPLIER); +} + +void CameraControllerInput::IncreaseFovY(float fov) +{ + m_fov_y_multiplier += fov; + m_fov_y_multiplier = std::max(m_fov_y_multiplier, MIN_FOV_MULTIPLIER); +} + +float CameraControllerInput::GetFovStepSize() const +{ + return 1.5f; +} + +void CameraControllerInput::Reset() +{ + m_fov_x_multiplier = DEFAULT_FOV_MULTIPLIER; + m_fov_y_multiplier = DEFAULT_FOV_MULTIPLIER; + m_dirty = true; +} + +void CameraControllerInput::ModifySpeed(float amt) +{ + m_speed += amt; + m_speed = std::max(m_speed, 0.0f); +} + +void CameraControllerInput::ResetSpeed() +{ + m_speed = DEFAULT_SPEED; +} + +float CameraControllerInput::GetSpeed() const +{ + return m_speed; +} + FreeLookCamera::FreeLookCamera() { SetControlType(FreeLook::ControlType::SixAxis); @@ -221,95 +286,21 @@ void FreeLookCamera::SetControlType(FreeLook::ControlType type) m_current_type = type; } -Common::Matrix44 FreeLookCamera::GetView() +Common::Matrix44 FreeLookCamera::GetView() const { return m_camera_controller->GetView(); } -Common::Vec2 FreeLookCamera::GetFieldOfView() const +Common::Vec2 FreeLookCamera::GetFieldOfViewMultiplier() const { - return Common::Vec2{m_fov_x, m_fov_y}; -} - -void FreeLookCamera::MoveVertical(float amt) -{ - m_camera_controller->MoveVertical(amt); - m_dirty = true; -} - -void FreeLookCamera::MoveHorizontal(float amt) -{ - m_camera_controller->MoveHorizontal(amt); - m_dirty = true; -} - -void FreeLookCamera::MoveForward(float amt) -{ - m_camera_controller->MoveForward(amt); - m_dirty = true; -} - -void FreeLookCamera::Rotate(const Common::Vec3& amt) -{ - m_camera_controller->Rotate(amt); - m_dirty = true; -} - -void FreeLookCamera::Rotate(const Common::Quaternion& amt) -{ - m_camera_controller->Rotate(amt); - m_dirty = true; -} - -void FreeLookCamera::IncreaseFovX(float fov) -{ - m_fov_x += fov; - m_fov_x = std::clamp(m_fov_x, m_min_fov_multiplier, m_fov_x); -} - -void FreeLookCamera::IncreaseFovY(float fov) -{ - m_fov_y += fov; - m_fov_y = std::clamp(m_fov_y, m_min_fov_multiplier, m_fov_y); -} - -float FreeLookCamera::GetFovStepSize() const -{ - return 1.5f; -} - -void FreeLookCamera::Reset() -{ - m_camera_controller->Reset(); - m_fov_x = 1.0f; - m_fov_y = 1.0f; - m_dirty = true; -} - -void FreeLookCamera::ModifySpeed(float amt) -{ - m_speed += amt; - m_speed = std::clamp(m_speed, 0.0f, m_speed); -} - -void FreeLookCamera::ResetSpeed() -{ - m_speed = 60.0f; -} - -float FreeLookCamera::GetSpeed() const -{ - return m_speed; + return m_camera_controller->GetFieldOfViewMultiplier(); } void FreeLookCamera::DoState(PointerWrap& p) { if (p.mode == PointerWrap::MODE_WRITE || p.mode == PointerWrap::MODE_MEASURE) { - p.Do(m_speed); p.Do(m_current_type); - p.Do(m_fov_x); - p.Do(m_fov_y); if (m_camera_controller) { m_camera_controller->DoState(p); @@ -318,10 +309,7 @@ void FreeLookCamera::DoState(PointerWrap& p) else { const auto old_type = m_current_type; - p.Do(m_speed); p.Do(m_current_type); - p.Do(m_fov_x); - p.Do(m_fov_y); if (old_type == m_current_type) { m_camera_controller->DoState(p); @@ -340,17 +328,12 @@ void FreeLookCamera::DoState(PointerWrap& p) } } -bool FreeLookCamera::IsDirty() const -{ - return m_dirty; -} - -void FreeLookCamera::SetClean() -{ - m_dirty = false; -} - bool FreeLookCamera::IsActive() const { return FreeLook::GetActiveConfig().enabled; } + +CameraController* FreeLookCamera::GetController() const +{ + return m_camera_controller.get(); +} diff --git a/Source/Core/VideoCommon/FreeLookCamera.h b/Source/Core/VideoCommon/FreeLookCamera.h index cd04ff69cd..fa62742bd2 100644 --- a/Source/Core/VideoCommon/FreeLookCamera.h +++ b/Source/Core/VideoCommon/FreeLookCamera.h @@ -23,7 +23,28 @@ public: CameraController(CameraController&&) = delete; CameraController& operator=(CameraController&&) = delete; - virtual Common::Matrix44 GetView() = 0; + virtual Common::Matrix44 GetView() const = 0; + virtual Common::Vec2 GetFieldOfViewMultiplier() const = 0; + + virtual void DoState(PointerWrap& p) = 0; + + virtual bool IsDirty() const = 0; + virtual void SetClean() = 0; + + virtual bool SupportsInput() const = 0; +}; + +class CameraControllerInput : public CameraController +{ +public: + Common::Vec2 GetFieldOfViewMultiplier() const final override; + + void DoState(PointerWrap& p) override; + + bool IsDirty() const final override { return m_dirty; } + void SetClean() final override { m_dirty = false; } + + bool SupportsInput() const final override { return true; } virtual void MoveVertical(float amt) = 0; virtual void MoveHorizontal(float amt) = 0; @@ -35,7 +56,23 @@ public: virtual void Reset() = 0; - virtual void DoState(PointerWrap& p) = 0; + void IncreaseFovX(float fov); + void IncreaseFovY(float fov); + float GetFovStepSize() const; + + void ModifySpeed(float multiplier); + void ResetSpeed(); + float GetSpeed() const; + +private: + static constexpr float MIN_FOV_MULTIPLIER = 0.025f; + static constexpr float DEFAULT_SPEED = 60.0f; + static constexpr float DEFAULT_FOV_MULTIPLIER = 1.0f; + + float m_fov_x_multiplier = DEFAULT_FOV_MULTIPLIER; + float m_fov_y_multiplier = DEFAULT_FOV_MULTIPLIER; + float m_speed = DEFAULT_SPEED; + bool m_dirty = false; }; class FreeLookCamera @@ -43,42 +80,18 @@ class FreeLookCamera public: FreeLookCamera(); void SetControlType(FreeLook::ControlType type); - Common::Matrix44 GetView(); - Common::Vec2 GetFieldOfView() const; - - void MoveVertical(float amt); - void MoveHorizontal(float amt); - void MoveForward(float amt); - - void Rotate(const Common::Vec3& amt); - void Rotate(const Common::Quaternion& amt); - - void IncreaseFovX(float fov); - void IncreaseFovY(float fov); - float GetFovStepSize() const; - - void Reset(); + Common::Matrix44 GetView() const; + Common::Vec2 GetFieldOfViewMultiplier() const; void DoState(PointerWrap& p); - bool IsDirty() const; - void SetClean(); - - void ModifySpeed(float multiplier); - void ResetSpeed(); - float GetSpeed() const; - bool IsActive() const; + CameraController* GetController() const; + private: - bool m_dirty = false; - float m_fov_x = 1.0f; - float m_fov_y = 1.0f; std::optional m_current_type; std::unique_ptr m_camera_controller; - - float m_min_fov_multiplier = 0.025f; - float m_speed = 60.0f; }; extern FreeLookCamera g_freelook_camera; diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 88c6806326..1b0bf55de7 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -356,7 +356,7 @@ void VertexShaderManager::SetConstants() } } - if (bProjectionChanged || g_freelook_camera.IsDirty()) + if (bProjectionChanged || g_freelook_camera.GetController()->IsDirty()) { bProjectionChanged = false; @@ -366,16 +366,21 @@ void VertexShaderManager::SetConstants() { case ProjectionType::Perspective: { - const Common::Vec2 fov = - g_freelook_camera.IsActive() ? g_freelook_camera.GetFieldOfView() : Common::Vec2{1, 1}; - g_fProjectionMatrix[0] = rawProjection[0] * g_ActiveConfig.fAspectRatioHackW * fov.x; + const Common::Vec2 fov_multiplier = g_freelook_camera.IsActive() ? + g_freelook_camera.GetFieldOfViewMultiplier() : + Common::Vec2{1, 1}; + g_fProjectionMatrix[0] = + rawProjection[0] * g_ActiveConfig.fAspectRatioHackW * fov_multiplier.x; g_fProjectionMatrix[1] = 0.0f; - g_fProjectionMatrix[2] = rawProjection[1] * g_ActiveConfig.fAspectRatioHackW * fov.x; + g_fProjectionMatrix[2] = + rawProjection[1] * g_ActiveConfig.fAspectRatioHackW * fov_multiplier.x; g_fProjectionMatrix[3] = 0.0f; g_fProjectionMatrix[4] = 0.0f; - g_fProjectionMatrix[5] = rawProjection[2] * g_ActiveConfig.fAspectRatioHackH * fov.y; - g_fProjectionMatrix[6] = rawProjection[3] * g_ActiveConfig.fAspectRatioHackH * fov.y; + g_fProjectionMatrix[5] = + rawProjection[2] * g_ActiveConfig.fAspectRatioHackH * fov_multiplier.y; + g_fProjectionMatrix[6] = + rawProjection[3] * g_ActiveConfig.fAspectRatioHackH * fov_multiplier.y; g_fProjectionMatrix[7] = 0.0f; g_fProjectionMatrix[8] = 0.0f; @@ -435,7 +440,7 @@ void VertexShaderManager::SetConstants() memcpy(constants.projection.data(), corrected_matrix.data.data(), 4 * sizeof(float4)); - g_freelook_camera.SetClean(); + g_freelook_camera.GetController()->SetClean(); dirty = true; }