From 4dabb2b5191bb83c0efb379d76415f3c9a766c1f Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Tue, 25 Jun 2024 22:05:34 +0300 Subject: [PATCH] MorphableCameraController class --- .../Scene/MorphableCameraController.cpp | 109 ++++++++++++++++++ .../Scene/MorphableCameraController.hpp | 46 ++++++++ 2 files changed, 155 insertions(+) create mode 100644 openVulkanoCpp/Scene/MorphableCameraController.cpp create mode 100644 openVulkanoCpp/Scene/MorphableCameraController.hpp diff --git a/openVulkanoCpp/Scene/MorphableCameraController.cpp b/openVulkanoCpp/Scene/MorphableCameraController.cpp new file mode 100644 index 0000000..cfce8fa --- /dev/null +++ b/openVulkanoCpp/Scene/MorphableCameraController.cpp @@ -0,0 +1,109 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "MorphableCameraController.hpp" +#include "Input/InputManager.hpp" +#include "Input/InputKey.hpp" +#include "Base/FrameMetadata.hpp" +#include "Scene/Camera.hpp" + +namespace OpenVulkano::Scene +{ + MorphableCameraController::MorphableCameraController(MorphableCamera* camera) + : CameraController(camera) + , m_animationDuration(1.0f) + , m_currentTime(0.0f) + , m_isMorphing(false) + , m_targetMorphState(false) + { + auto input = OpenVulkano::Input::InputManager::GetInstance(); + m_actionMorph = input->GetAction("morph"); + m_actionForward = input->GetAction("forward"); + m_actionSide = input->GetAction("side"); + m_actionUp = input->GetAction("up"); + m_actionLookUp = input->GetAction("look up"); + m_actionLookSide = input->GetAction("look side"); + m_actionBoost = input->GetAction("boost"); + } + + void MorphableCameraController::Init(MorphableCamera* camera) + { + CameraController::Init(camera); + SetDefaultKeybindings(); + } + + void MorphableCameraController::Tick() + { + auto input = OpenVulkano::Input::InputManager::GetInstance(); + + bool isMorphingDown = input->GetButton(m_actionMorph); + if (!m_wasMorphingKeyDown && isMorphingDown) + { + m_isMorphing = true; + m_currentTime = 0.0f; + m_targetMorphState = !m_targetMorphState; + } + m_wasMorphingKeyDown = isMorphingDown; + + if (m_isMorphing) + { + m_currentTime += CURRENT_FRAME.frameTime; + if (m_currentTime > m_animationDuration) m_currentTime = m_animationDuration; + float t = m_currentTime / m_animationDuration; + if (t >= 1.0f) + { + t = 1.0f; + m_isMorphing = false; + } + float newState = m_targetMorphState ? t : (1.0f - t); + static_cast(GetCamera())->SetMorphState(newState); + } + + // Movement logic + const float MOVEMENT_SPEED = 3.0f; + const float BOOST_MULT = 2.0f; + + Math::Vector3f_SIMD vec(input->GetAxis(m_actionSide), input->GetAxis(m_actionUp), + -input->GetAxis(m_actionForward)); + if (Math::Utils::length2(vec) > 1.0f) { vec = Math::Utils::normalize(vec); } + + float dt = CURRENT_FRAME.frameTime; + vec = vec * dt * MOVEMENT_SPEED; + if (input->GetButton(m_actionBoost)) { vec *= BOOST_MULT; } + + m_yaw -= input->GetAxis(m_actionLookSide) * dt / 2.0f; + m_pitch -= input->GetAxis(m_actionLookUp) * dt / 2.0f; + m_pitch = std::min(1.4f, std::max(-1.4f, m_pitch)); + + const Math::QuaternionF rot(Math::Vector3f(m_pitch, m_yaw, 0)); + m_position += rot * vec; + Math::Matrix4f camTransformation = Math::Utils::toMat4(rot); + camTransformation[3] = Math::Vector4f(m_position, 1); + GetCamera()->SetMatrix(camTransformation); + } + + void MorphableCameraController::SetDefaultKeybindings() + { + m_actionMorph->BindKey(Input::InputKey::Keyboard::KEY_P); + + m_actionForward->BindKey(Input::InputKey::Controller::AXIS_LEFT_Y); + m_actionForward->BindAxisButtons(Input::InputKey::Keyboard::KEY_W, Input::InputKey::Keyboard::KEY_S); + m_actionForward->BindKey(Input::InputKey::Touch::AXIS_PAN_TWO_FINGERS_Y, -0.0025f); + m_actionSide->BindKey(Input::InputKey::Controller::AXIS_LEFT_X); + m_actionSide->BindAxisButtons(Input::InputKey::Keyboard::KEY_D, Input::InputKey::Keyboard::KEY_A); + m_actionSide->BindKey(Input::InputKey::Touch::AXIS_PAN_TWO_FINGERS_X, 0.0025f); + m_actionLookUp->BindKey(Input::InputKey::Controller::AXIS_RIGHT_Y); + m_actionLookUp->BindAxisButtons(Input::InputKey::Keyboard::KEY_DOWN, Input::InputKey::Keyboard::KEY_UP); + m_actionLookUp->BindKey(Input::InputKey::Touch::AXIS_PAN_Y, 0.10f); + m_actionLookSide->BindKey(Input::InputKey::Controller::AXIS_RIGHT_X); + m_actionLookSide->BindAxisButtons(Input::InputKey::Keyboard::KEY_RIGHT, Input::InputKey::Keyboard::KEY_LEFT); + m_actionLookSide->BindKey(Input::InputKey::Touch::AXIS_PAN_X, 0.10f); + m_actionLookUp->BindKey(Input::InputKey::Mouse::AXIS_Y); + m_actionLookSide->BindKey(Input::InputKey::Mouse::AXIS_X); + m_actionUp->BindAxisButtons(Input::InputKey::Keyboard::KEY_SPACE, Input::InputKey::Keyboard::KEY_LEFT_CONTROL); + m_actionBoost->BindKey(Input::InputKey::Keyboard::KEY_LEFT_SHIFT); + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Scene/MorphableCameraController.hpp b/openVulkanoCpp/Scene/MorphableCameraController.hpp new file mode 100644 index 0000000..77f403c --- /dev/null +++ b/openVulkanoCpp/Scene/MorphableCameraController.hpp @@ -0,0 +1,46 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include "MorphableCamera.hpp" +#include "Controller/CameraController.hpp" +#include "Input/InputManager.hpp" +#include "Input/InputKey.hpp" +#include "Math/Math.hpp" + +namespace OpenVulkano::Scene +{ + class MorphableCameraController final : public CameraController + { + double m_animationDuration; + double m_currentTime; + bool m_isMorphing; + bool m_targetMorphState; // true for perspective, false for orthographic + + float m_yaw = 0, m_pitch = 0, m_boostFactor = 2; + Math::Vector3f_SIMD m_position = { 0, 0, 0 }; + + Input::InputAction* m_actionForward; + Input::InputAction* m_actionSide; + Input::InputAction* m_actionUp; + Input::InputAction* m_actionLookUp; + Input::InputAction* m_actionLookSide; + Input::InputAction* m_actionBoost; + Input::InputAction* m_actionMorph; + bool m_wasMorphingKeyDown = false; + + public: + MorphableCameraController(MorphableCamera* camera = nullptr); + + void Init(MorphableCamera* camera); + void Tick() override; + void SetDefaultKeybindings(); + + void SetDuration(double duration) { m_animationDuration = duration; } + double GetDuration() { return m_animationDuration; } + void Reset() { m_currentTime = 0; } + }; +} \ No newline at end of file