diff --git a/examples/ExampleApps/MovingCubeApp.cpp b/examples/ExampleApps/MovingCubeApp.cpp new file mode 100644 index 0000000..a1311f9 --- /dev/null +++ b/examples/ExampleApps/MovingCubeApp.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 "MovingCubeApp.hpp" +#include "Math/Math.hpp" +#include "Scene/Scene.hpp" +#include "Scene/Shader/Shader.hpp" +#include "Scene/Geometry.hpp" +#include "Scene/Material.hpp" +#include "Scene/Vertex.hpp" +#include "Scene/SimpleDrawable.hpp" +#include "Scene/Camera.hpp" +#include "Scene/SimpleAnimationController.hpp" +#include "Input/InputManager.hpp" +#include "Host/GraphicsAppManager.hpp" +#include "Base/EngineConfiguration.hpp" +#include "Controller/FreeCamCameraController.hpp" + +namespace OpenVulkano +{ + class MovingCubeAppImpl final : public MovingCubeApp + { + OpenVulkano::Scene::Scene m_scene; + OpenVulkano::Scene::PerspectiveCamera m_camera; + OpenVulkano::FreeCamCameraController m_cameraControl; + OpenVulkano::Scene::Material m_material; + OpenVulkano::Scene::Shader m_shader; + + OpenVulkano::Scene::Geometry m_geometry; + OpenVulkano::Scene::SimpleDrawable m_drawable; + OpenVulkano::Scene::Node m_node; + std::unique_ptr m_animationController; + + public: + void Init() override + { + auto engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); + m_camera.Init(70, 16, 9, 0.1, 100); + // m_camera.SetMatrix(OpenVulkano::Math::Utils::translate(OpenVulkano::Math::Matrix4f(1), OpenVulkano::Math::Vector3f_SIMD(0, 0, -50))); + + m_scene.Init(); + m_scene.SetCamera(&m_camera); + + m_shader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/basic"); + m_shader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/basic"); + m_shader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); + + m_geometry.InitCube(); + m_drawable.Init(&m_shader, &m_geometry, &m_material); + + m_node.Init(); + m_scene.GetRoot()->AddChild(&m_node); + m_node.SetUpdateFrequency(OpenVulkano::Scene::UpdateFrequency::Always); + m_node.AddDrawable(&m_drawable); + m_node.SetMatrix(OpenVulkano::Math::Matrix4f(1)); + + GetGraphicsAppManager()->GetRenderer()->SetScene(&m_scene); + m_cameraControl.Init(&m_camera); + m_cameraControl.SetDefaultKeybindings(); + + m_animationController = std::make_unique(); + m_animationController->SetNode(&m_node); + m_animationController->SetDuration(3); + + OpenVulkano::Math::Pose srcPose(OpenVulkano::Math::Quaternion(), OpenVulkano::Math::Vector3f_SIMD(-3, 0, 0)); + OpenVulkano::Math::Pose destPose(OpenVulkano::Math::Quaternion(), OpenVulkano::Math::Vector3f_SIMD(3, 0, 0)); + m_animationController->SetPoses(srcPose, destPose); + + m_animationController->m_completionEvent += EventHandler(this, &MovingCubeAppImpl::OnAnimationCompleted); + } + + void OnAnimationCompleted(OpenVulkano::Scene::SimpleAnimationController *anim) + { + anim->SwapPoses(); + anim->Reset(); + } + + void Tick() override + { + m_cameraControl.Tick(); + m_animationController->Tick(); + } + + void Close() override + { + } + }; + + IGraphicsApp* MovingCubeApp::Create() + { + return new MovingCubeAppImpl(); + } + + std::unique_ptr MovingCubeApp::CreateUnique() + { + return std::make_unique(); + } +} diff --git a/examples/ExampleApps/MovingCubeApp.hpp b/examples/ExampleApps/MovingCubeApp.hpp new file mode 100644 index 0000000..75d464e --- /dev/null +++ b/examples/ExampleApps/MovingCubeApp.hpp @@ -0,0 +1,24 @@ +/* + * 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 + +#include "Base/IGraphicsApp.hpp" + +namespace OpenVulkano +{ + class MovingCubeApp : public IGraphicsApp + { + public: + static std::unique_ptr CreateUnique(); + static IGraphicsApp* Create(); + + std::string GetAppName() const final { return "Moving Cube App"; } + OpenVulkano::Version GetAppVersion() const final { return {"v1.0"}; } + }; +} \ No newline at end of file diff --git a/examples/main.cpp b/examples/main.cpp index acc1b76..cd4dc04 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -6,12 +6,14 @@ #include "Host/GraphicsAppManager.hpp" #include "ExampleApps/CubesExampleApp.hpp" +#include "ExampleApps/MovingCubeApp.hpp" using namespace OpenVulkano; int main(int argc, char** argv) { std::unique_ptr app = CubesExampleApp::CreateUnique(); + // std::unique_ptr app = MovingCubeApp::CreateUnique(); GraphicsAppManager manager(app.get()); manager.Run(); return 0; diff --git a/openVulkanoCpp/AR/ArFrame.hpp b/openVulkanoCpp/AR/ArFrame.hpp index 2384b2a..ef68870 100644 --- a/openVulkanoCpp/AR/ArFrame.hpp +++ b/openVulkanoCpp/AR/ArFrame.hpp @@ -109,7 +109,7 @@ namespace OpenVulkano::AR [[nodiscard]] ArTrackingState GetTrackingState() const { return frameMetadata.trackingState; }; - [[nodiscard]] virtual Math::PoseF GetPose() const { return Math::PoseF({}); }; //TODO + [[nodiscard]] virtual Math::PoseF GetPose() const { return Math::PoseF(); }; //TODO [[nodiscard]] Math::Timestamp GetTimestamp() const { return frameMetadata.timestamp; }; diff --git a/openVulkanoCpp/Math/Math.hpp b/openVulkanoCpp/Math/Math.hpp index 6c4d115..cdaa1c5 100644 --- a/openVulkanoCpp/Math/Math.hpp +++ b/openVulkanoCpp/Math/Math.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/openVulkanoCpp/Math/Pose.hpp b/openVulkanoCpp/Math/Pose.hpp index 3e12ff5..6ee6506 100644 --- a/openVulkanoCpp/Math/Pose.hpp +++ b/openVulkanoCpp/Math/Pose.hpp @@ -28,6 +28,22 @@ namespace OpenVulkano::Math : m_orientation(Math::Utils::qua(eulerAngle)), m_position(position) {} + Pose(const Math::Matrix4 &matrix) + { + Math::Vector3_SIMD scale; + Math::Quaternion rotation; + Math::Vector3_SIMD translation; + Math::Vector3_SIMD skew; + Math::Vector4_SIMD perspective; + + bool decomposed = Math::Utils::decompose(matrix, scale, rotation, translation, skew, perspective); + if(decomposed) + { + m_orientation = rotation; + m_position = translation; + } + } + [[nodiscard]] Quaternion& GetOrientation() const { return m_orientation; } [[nodiscard]] Vector3_SIMD GetPosition() const { return m_position; } diff --git a/openVulkanoCpp/Scene/Node.hpp b/openVulkanoCpp/Scene/Node.hpp index 5a193b5..08ab16c 100644 --- a/openVulkanoCpp/Scene/Node.hpp +++ b/openVulkanoCpp/Scene/Node.hpp @@ -8,6 +8,7 @@ #include "Base/ICloseable.hpp" #include "Math/Math.hpp" +#include "Math/Pose.hpp" #include "Drawable.hpp" #include "UpdateFrequency.hpp" #include "Shader/DescriptorInputDescription.hpp" @@ -64,6 +65,10 @@ namespace OpenVulkano::Scene [[nodiscard]] const Math::Matrix4f& GetWorldMatrix() const { return worldMat; } + [[nodiscard]] Math::PoseF GetPose() { return Math::PoseF(GetMatrix()); } + + [[nodiscard]] Math::PoseF GetWorldPose() { return Math::PoseF(GetWorldMatrix()); } + [[nodiscard]] bool IsEnabled() const { return enabled; } void Enable() { enabled = true; } diff --git a/openVulkanoCpp/Scene/SimpleAnimationController.cpp b/openVulkanoCpp/Scene/SimpleAnimationController.cpp new file mode 100644 index 0000000..82594bd --- /dev/null +++ b/openVulkanoCpp/Scene/SimpleAnimationController.cpp @@ -0,0 +1,34 @@ +/* + * 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 "SimpleAnimationController.hpp" +#include "Base/FrameMetadata.hpp" + +namespace OpenVulkano::Scene +{ + double SimpleAnimationController::GetProgress() + { + double progress = m_elapsed / m_duration; + if(progress >= 1.0) + progress = 1; + return progress; + } + + void SimpleAnimationController::Tick() + { + if(!m_node || m_duration <= 0 || m_elapsed > m_duration) + return; + + m_elapsed += CURRENT_FRAME.frameTime; + + double progress = GetProgress(); + Math::Pose currentPose = m_initialPose.Interpolate(m_targetPose, progress); + m_node->SetMatrix(currentPose.ToMatrix()); + + if(m_elapsed > m_duration) + m_completionEvent.NotifyAll(this); + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Scene/SimpleAnimationController.hpp b/openVulkanoCpp/Scene/SimpleAnimationController.hpp new file mode 100644 index 0000000..a369f4c --- /dev/null +++ b/openVulkanoCpp/Scene/SimpleAnimationController.hpp @@ -0,0 +1,49 @@ +/* + * 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/Event.hpp" +#include "Math/Math.hpp" +#include "Math/Pose.hpp" +#include "Scene/Node.hpp" + +#include + +namespace OpenVulkano::Scene +{ + class SimpleAnimationController : public ITickable + { + Node *m_node = nullptr; + Math::PoseF m_targetPose; + Math::PoseF m_initialPose; + double m_duration = 0; + double m_elapsed = 0; + + public: + Event m_completionEvent; + + SimpleAnimationController() = default; + + void Reset() { m_elapsed = 0; } + void SwapPoses() { std::swap(m_initialPose, m_targetPose); } + + Node* GetNode() { return m_node; } + void SetNode(Node *node) { m_node = node; } + + const Math::PoseF& GetInitialPose() { return m_initialPose; } + const Math::PoseF& GetTargetPose() { return m_targetPose; } + void SetPoses(const Math::PoseF &initialPose, const Math::PoseF &targetPose) { m_initialPose = initialPose; m_targetPose = targetPose; } + + double GetDuration() { return m_duration; } + void SetDuration(double duration) { m_duration = duration; } + + double GetProgress(); + + void Tick() override; + }; +} \ No newline at end of file