/* * 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 "ArcballCameraController.hpp" #include "Scene/Camera.hpp" #include "Input/InputManager.hpp" #include "Input/InputKey.hpp" #include "Base/FrameMetadata.hpp" namespace OpenVulkano { void ArcballCameraController::SetupInputActions() { auto input = Input::InputManager::GetInstance(); 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"); } void ArcballCameraController::Tick() { if (!GetCamera()) return; Input::InputManager* input = Input::InputManager::GetInstance(); float inYaw = (lockYaw) ? 0 : input->GetAxis(m_actionLookSide); float inPitch = (lockPitch) ? 0 : input->GetAxis(m_actionLookUp); Math::Vector4f_SIMD position = GetCamera()->GetPosition(); bool updated = false; if (inYaw != 0 || inPitch != 0) { yaw += inYaw; pitch = std::min(1.5f, std::max(-1.5f, pitch + inPitch)); Math::Matrix4f rotateY = Math::Utils::rotate(yaw, Math::Vector3f_SIMD(0, 1, 0)); Math::Vector4f x = rotateY * Math::Vector4f(1, 0, 0, 0); Math::Matrix4f rotateX = Math::Utils::rotate(pitch, Math::Vector3f_SIMD(x)); position = rotateX * rotateY * Math::Vector4f_SIMD(0, 0, 3, 0); position += m_pivotPoint; updated = true; } // Move the camera and the pivot point Math::Vector3f_SIMD vec(input->GetAxis(m_actionSide), input->GetAxis(m_actionUp), -input->GetAxis(m_actionForward)); if (vec != Math::Vector3f_SIMD (0)) { if (Math::Utils::length2(vec) > 1.0f) { vec = Math::Utils::normalize(vec); } const float timeScale = CURRENT_FRAME.frameTime; //TODO vec = vec * timeScale * 3.0f; // scale vector vec = GetCamera()->GetRotationMatrix() * Math::Vector3f(vec); const Math::Vector4f_SIMD movement(vec, 0); position += movement; m_pivotPoint += movement; updated = true; } if (updated) { // Update the camera view GetCamera()->SetViewMatrix(Math::Utils::lookAt(reinterpret_cast(position), reinterpret_cast(m_pivotPoint), Math::Vector3f_SIMD(0, 1, 0))); CURRENT_FRAME.needsRedraw = true; } } void ArcballCameraController::SetActive() { Math::Vector3f viewDir = Math::Utils::normalize(GetCamera()->GetViewDirection()); m_pivotPoint = GetCamera()->GetPosition() + Math::Vector4f(viewDir * 3.0f, 0); pitch = Math::Utils::asin(viewDir.y); yaw = Math::Utils::atan(-viewDir.x, -viewDir.z); } void ArcballCameraController::SetDefaultKeybindings() { 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_PINCH, 0.2f); 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.03f); m_actionUp->BindAxisButtons(Input::InputKey::Keyboard::KEY_SPACE, Input::InputKey::Keyboard::KEY_LEFT_CONTROL); m_actionUp->BindKey(Input::InputKey::Touch::AXIS_PAN_TWO_FINGERS_Y, 0.03f); 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.001f); 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.001f); m_actionLookUp->BindKey(Input::InputKey::Mouse::AXIS_Y); m_actionLookSide->BindKey(Input::InputKey::Mouse::AXIS_X); } }