diff --git a/openVulkanoCpp/Controller/ArCameraController.cpp b/openVulkanoCpp/Controller/ArCameraController.cpp new file mode 100644 index 0000000..f1e6db3 --- /dev/null +++ b/openVulkanoCpp/Controller/ArCameraController.cpp @@ -0,0 +1,101 @@ +/* + * 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 "ArCameraController.hpp" +#include "AR/ArSession.hpp" +#include "Base/Logger.hpp" +#include "Scene/Camera.hpp" + +namespace openVulkanoCpp +{ + ArCameraController::ArCameraController() : m_camera(nullptr) + {} + + ArCameraController::ArCameraController(Scene::Camera* camera, const std::shared_ptr& session, const Math::Matrix4f& registration) + : m_arSession(session), m_camera(camera), m_registration(registration), m_updated(false) + { + Init(); + } + + ArCameraController::~ArCameraController() + { + if (m_arSession) Close(); + } + + void ArCameraController::Init() + { + //m_registration = Math::Utils::translate(Math::Vector3f_SIMD(0.0f, 0.0f, -2.5f)) * Math::Utils::rotate(Math::Matrix4f(1), M_PI_2f, {0,1,0}); + if (m_arSession) + { + if (!m_arSession->IsRunning()) + { + Logger::AR->warn("AR session is not yet running. Starting it before registering ArCameraController."); + m_arSession->Start(); + } + } + else + { + if (AR::ArSession::IsNativeArAvailable()) + { + auto createResult = AR::ArSession::Create(); + if (createResult.IsSuccess()) + { + m_arSession = createResult.session; + m_arSession->Start(); + } + else + { + Logger::AR->critical("Failed to create AR session for ArCameraController! Error: " + createResult.statusMessage); + m_camera = nullptr; + return; + } + } + else + { + Logger::AR->critical("No native AR implementation available! Can't start ArCameraController."); + m_camera = nullptr; + return; + } + } + + m_updated = false; + m_arSession->OnNewCameraViewMatrix += EventHandler(this, &ArCameraController::UpdateCameraTransformation); + } + + void ArCameraController::Init(Scene::Camera* camera, const std::shared_ptr& session, const Math::Matrix4f& registration) + { + if (m_camera) return; + m_arSession = session; + m_camera = camera; + m_registration = registration; + Init(); + } + + void ArCameraController::Tick() + { + if (!m_camera || !m_updated) return; + std::unique_lock lock(m_mutex); + + Math::Matrix4f mat = m_registration * Math::Utils::inverse(m_matrixToUpdate); + m_camera->SetMatrix(mat); + m_updated = false; + } + + void ArCameraController::Close() + { + if (!m_camera) return; + m_arSession->OnNewCameraViewMatrix -= EventHandler(this, &ArCameraController::UpdateCameraTransformation); + m_camera = nullptr; + m_arSession = nullptr; + } + + void ArCameraController::UpdateCameraTransformation(const Math::Matrix4f& transform) + { + std::unique_lock lock(m_mutex); + m_matrixToUpdate = transform; + m_updated = true; + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Controller/ArCameraController.hpp b/openVulkanoCpp/Controller/ArCameraController.hpp new file mode 100644 index 0000000..896fcd0 --- /dev/null +++ b/openVulkanoCpp/Controller/ArCameraController.hpp @@ -0,0 +1,57 @@ +/* + * 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 "Base/ITickable.hpp" +#include "Base/ICloseable.hpp" +#include "Math/Math.hpp" +#include +#include +#include + +namespace openVulkanoCpp +{ + namespace AR + { + class ArSession; + } + + namespace Scene + { + class Camera; + } + + class ArCameraController final : public ITickable, public ICloseable + { + std::shared_ptr m_arSession; + Scene::Camera* m_camera; + Math::Matrix4f m_registration; + Math::Matrix4f m_matrixToUpdate; + std::mutex m_mutex; + std::atomic m_updated; + + public: + ArCameraController(); + + ArCameraController(Scene::Camera* camera, const std::shared_ptr& session = nullptr, const Math::Matrix4f& registration = Math::Matrix4f (1)); + + ~ArCameraController() override; + + void Init(Scene::Camera* camera, const std::shared_ptr& session = nullptr, const Math::Matrix4f& registration = Math::Matrix4f (1)); + + void Tick() override; + + void Close() override; + + [[nodiscard]] std::shared_ptr GetArSession() const { return m_arSession; } + + private: + void Init(); + + void UpdateCameraTransformation(const Math::Matrix4f& transform); + }; +} \ No newline at end of file