From 16f7789a5278d55b7befc10a489cb8bbfbe17fd3 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 7 Jun 2024 16:09:11 +0300 Subject: [PATCH 1/6] SequenceAnimationController class --- .../Scene/SequenceAnimationController.cpp | 78 +++++++++++++++++++ .../Scene/SequenceAnimationController.hpp | 45 +++++++++++ 2 files changed, 123 insertions(+) create mode 100644 openVulkanoCpp/Scene/SequenceAnimationController.cpp create mode 100644 openVulkanoCpp/Scene/SequenceAnimationController.hpp diff --git a/openVulkanoCpp/Scene/SequenceAnimationController.cpp b/openVulkanoCpp/Scene/SequenceAnimationController.cpp new file mode 100644 index 0000000..3f0c76f --- /dev/null +++ b/openVulkanoCpp/Scene/SequenceAnimationController.cpp @@ -0,0 +1,78 @@ +/* + * 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 "Scene/SequenceAnimationController.hpp" + +namespace OpenVulkano::Scene +{ + SequenceAnimationController::SequenceAnimationController() + { + // m_animationController.m_completionEvent += EventHandler(this, &SequenceAnimationController::OnCurrentFrameFinished); + m_completionEvent += EventHandler(this, &SequenceAnimationController::OnCurrentFrameFinished); + } + + void SequenceAnimationController::AdvanceToNextStep() + { + if(m_steps.empty()) + return; + + if(m_currentStep < m_steps.size() - 1) + { + ++m_currentStep; + SetPoses(GetTargetPose(), m_steps[m_currentStep].first); + SetDuration(m_steps[m_currentStep-1].second); + SimpleAnimationController::Reset(); + } + else + { + if(m_loop) + { + m_currentStep = 0; + SetPoses(GetTargetPose(), m_steps[m_currentStep].first); + // We don't set the duration because transition from the last step to the first + // requires to use duration of the last step + SimpleAnimationController::Reset(); + } + else + { + m_sequenceCompletionEvent.NotifyAll(this); + } + } + } + + void SequenceAnimationController::Tick() + { + SimpleAnimationController::Tick(); + } + + void SequenceAnimationController::Restart() + { + m_currentStep = 0; + if(!m_steps.empty()) + { + SetPoses(GetTargetPose(), m_steps[m_currentStep].first); + SetDuration(m_steps.back().second); + } + SimpleAnimationController::Reset(); + } + + void SequenceAnimationController::AddAnimationStep(const Math::PoseF &pose, double duration) + { + m_steps.emplace_back(pose, duration); + if(m_steps.size() == 2) + { + m_currentStep = 1; + SetPoses(m_steps[0].first, m_steps[1].first); + SetDuration(m_steps[0].second); + Reset(); + } + } + + void SequenceAnimationController::OnCurrentFrameFinished(SimpleAnimationController *animationController) + { + AdvanceToNextStep(); + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Scene/SequenceAnimationController.hpp b/openVulkanoCpp/Scene/SequenceAnimationController.hpp new file mode 100644 index 0000000..0d711eb --- /dev/null +++ b/openVulkanoCpp/Scene/SequenceAnimationController.hpp @@ -0,0 +1,45 @@ +/* + * 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 "Scene/SimpleAnimationController.hpp" +#include "Base/Event.hpp" +#include "Base/ITickable.hpp" +#include "Math/Math.hpp" +#include "Math/Pose.hpp" + +#include +#include + +namespace OpenVulkano::Scene +{ + class SequenceAnimationController : public SimpleAnimationController + { + using PoseDurationPair = std::pair; + + std::vector m_steps; + int m_currentStep = 0; + bool m_loop = false; + + void AdvanceToNextStep(); + + public: + SequenceAnimationController(); + + Event m_sequenceCompletionEvent; + + void EnableLoop(bool value) { m_loop = value; } + + void Restart(); + void AddAnimationStep(const Math::PoseF &pose, double duration); + bool IsFinished() { if(m_loop) return false; return m_currentStep >= m_steps.size(); } + + void OnCurrentFrameFinished(SimpleAnimationController *animationController); + + void Tick() override; + }; +} \ No newline at end of file From f3fcd049c461bf80a44b47dc8afaa7974574b905 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 7 Jun 2024 16:09:39 +0300 Subject: [PATCH 2/6] Using SequenceAnimationController class in our MovingCubeApp --- examples/ExampleApps/MovingCubeApp.cpp | 98 +++++++++++++++++--------- 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/examples/ExampleApps/MovingCubeApp.cpp b/examples/ExampleApps/MovingCubeApp.cpp index a1311f9..a3671f2 100644 --- a/examples/ExampleApps/MovingCubeApp.cpp +++ b/examples/ExampleApps/MovingCubeApp.cpp @@ -14,74 +14,108 @@ #include "Scene/SimpleDrawable.hpp" #include "Scene/Camera.hpp" #include "Scene/SimpleAnimationController.hpp" +#include "Scene/SequenceAnimationController.hpp" #include "Input/InputManager.hpp" #include "Host/GraphicsAppManager.hpp" #include "Base/EngineConfiguration.hpp" +#include "Base/Logger.hpp" #include "Controller/FreeCamCameraController.hpp" namespace OpenVulkano { + namespace + { + struct SceneElement + { + Scene::Geometry m_geometry; + Scene::SimpleDrawable m_drawable; + Scene::Node m_node; + }; + } 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; + Scene::Scene m_scene; + Scene::PerspectiveCamera m_camera; + FreeCamCameraController m_cameraControl; + Scene::Material m_material; + Scene::Shader m_shader; - OpenVulkano::Scene::Geometry m_geometry; - OpenVulkano::Scene::SimpleDrawable m_drawable; - OpenVulkano::Scene::Node m_node; - std::unique_ptr m_animationController; + std::unique_ptr m_simpleAnimationController; + std::unique_ptr m_sequenceAnimationController; + + SceneElement m_whiteBox; + SceneElement m_redBox; + + void CreateSceneElement(SceneElement *dest, const Math::Vector4f &color, float scale) + { + dest->m_geometry.InitCube(scale, scale, scale, color); + dest->m_drawable.Init(&m_shader, &dest->m_geometry, &m_material); + + dest->m_node.Init(); + m_scene.GetRoot()->AddChild(&dest->m_node); + dest->m_node.SetUpdateFrequency(Scene::UpdateFrequency::Always); + dest->m_node.AddDrawable(&dest->m_drawable); + dest->m_node.SetMatrix(Math::Matrix4f(1)); + } public: void Init() override { - auto engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); + auto engineConfig = 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)); + m_shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/basic"); + m_shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/basic"); + m_shader.AddVertexInputDescription(Vertex::GetVertexInputDescription()); 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); + CreateSceneElement(&m_whiteBox, Math::Vector4f(1, 1, 1, 1), 1); + CreateSceneElement(&m_redBox, Math::Vector4f(1, 0.2, 0.2, 1.0), 0.3); - m_animationController->m_completionEvent += EventHandler(this, &MovingCubeAppImpl::OnAnimationCompleted); + m_simpleAnimationController = std::make_unique(); + m_simpleAnimationController->SetNode(&m_whiteBox.m_node); + m_simpleAnimationController->SetDuration(3); + Math::Pose srcPose(Math::Quaternion(), Math::Vector3f_SIMD(-3, 0, 0)); + Math::Pose destPose(Math::Quaternion(), Math::Vector3f_SIMD(3, 0, 0)); + m_simpleAnimationController->SetPoses(srcPose, destPose); + m_simpleAnimationController->m_completionEvent += EventHandler(this, &MovingCubeAppImpl::OnSimpleAnimationCompleted); + + m_sequenceAnimationController = std::make_unique(); + m_sequenceAnimationController->EnableLoop(false); + m_sequenceAnimationController->SetNode(&m_redBox.m_node); + m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(1, 0, 0, 1)), Math::Vector3f_SIMD(0, 0, 1)), 5); + m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(2, 1, 0, 1)), Math::Vector3f_SIMD(1, 1, -1)), 3); + m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(1, 1, 1, 1)), Math::Vector3f_SIMD(2, 1, -2)), 3); + m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(0, 1, 1, 0)), Math::Vector3f_SIMD(2, 1, -1)), 3); + m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(3, 2, 1, 1)), Math::Vector3f_SIMD(1, 1, -1)), 3); + m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(0, 0, 1, 1)), Math::Vector3f_SIMD(0, 1, 0)), 1); + m_sequenceAnimationController->m_sequenceCompletionEvent += EventHandler(this, &MovingCubeAppImpl::OnSequenceAnimationCompleted); } - void OnAnimationCompleted(OpenVulkano::Scene::SimpleAnimationController *anim) + void OnSimpleAnimationCompleted(Scene::SimpleAnimationController *anim) { anim->SwapPoses(); anim->Reset(); } + void OnSequenceAnimationCompleted(Scene::SequenceAnimationController *anim) + { + Logger::APP->info("Animation sequence completed - restarting..."); + m_sequenceAnimationController->Restart(); + } + void Tick() override { m_cameraControl.Tick(); - m_animationController->Tick(); + m_simpleAnimationController->Tick(); + m_sequenceAnimationController->Tick(); } void Close() override From 1311165139cdf4315fb8da59f7eeeeca202bee31 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Sat, 8 Jun 2024 17:36:03 +0300 Subject: [PATCH 3/6] Summary: - In MovingCubeApp animations are now allocated on stack - m_sequenceAnimationController now uses SetAnimationPoseResetTime() - Removed OnSequenceAnimationCompleted() - Pose::GetOrientation() now returns by value(without it my code doesn't compile) - GetStep() getter - In if(m_loop) checking for m_resetTime to be zero or last step to be equal to the first - Tick now ticks only if there are at least one element in m_steps - IsFinished() function - AddAnimationSteps() functions that take initializer_lists - Getters in SimpleAnimationController are now const --- examples/ExampleApps/MovingCubeApp.cpp | 42 ++++---- openVulkanoCpp/Math/Pose.hpp | 7 +- .../Scene/SequenceAnimationController.cpp | 96 ++++++++++++++----- .../Scene/SequenceAnimationController.hpp | 64 +++++++++---- .../Scene/SimpleAnimationController.hpp | 8 +- 5 files changed, 147 insertions(+), 70 deletions(-) diff --git a/examples/ExampleApps/MovingCubeApp.cpp b/examples/ExampleApps/MovingCubeApp.cpp index a3671f2..472583e 100644 --- a/examples/ExampleApps/MovingCubeApp.cpp +++ b/examples/ExampleApps/MovingCubeApp.cpp @@ -40,8 +40,8 @@ namespace OpenVulkano Scene::Material m_material; Scene::Shader m_shader; - std::unique_ptr m_simpleAnimationController; - std::unique_ptr m_sequenceAnimationController; + Scene::SimpleAnimationController m_simpleAnimationController; + Scene::SequenceAnimationController m_sequenceAnimationController; SceneElement m_whiteBox; SceneElement m_redBox; @@ -79,24 +79,22 @@ namespace OpenVulkano CreateSceneElement(&m_whiteBox, Math::Vector4f(1, 1, 1, 1), 1); CreateSceneElement(&m_redBox, Math::Vector4f(1, 0.2, 0.2, 1.0), 0.3); - m_simpleAnimationController = std::make_unique(); - m_simpleAnimationController->SetNode(&m_whiteBox.m_node); - m_simpleAnimationController->SetDuration(3); + m_simpleAnimationController.SetNode(&m_whiteBox.m_node); + m_simpleAnimationController.SetDuration(3); Math::Pose srcPose(Math::Quaternion(), Math::Vector3f_SIMD(-3, 0, 0)); Math::Pose destPose(Math::Quaternion(), Math::Vector3f_SIMD(3, 0, 0)); - m_simpleAnimationController->SetPoses(srcPose, destPose); - m_simpleAnimationController->m_completionEvent += EventHandler(this, &MovingCubeAppImpl::OnSimpleAnimationCompleted); + m_simpleAnimationController.SetPoses(srcPose, destPose); + m_simpleAnimationController.m_completionEvent += EventHandler(this, &MovingCubeAppImpl::OnSimpleAnimationCompleted); - m_sequenceAnimationController = std::make_unique(); - m_sequenceAnimationController->EnableLoop(false); - m_sequenceAnimationController->SetNode(&m_redBox.m_node); - m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(1, 0, 0, 1)), Math::Vector3f_SIMD(0, 0, 1)), 5); - m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(2, 1, 0, 1)), Math::Vector3f_SIMD(1, 1, -1)), 3); - m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(1, 1, 1, 1)), Math::Vector3f_SIMD(2, 1, -2)), 3); - m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(0, 1, 1, 0)), Math::Vector3f_SIMD(2, 1, -1)), 3); - m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(3, 2, 1, 1)), Math::Vector3f_SIMD(1, 1, -1)), 3); - m_sequenceAnimationController->AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(0, 0, 1, 1)), Math::Vector3f_SIMD(0, 1, 0)), 1); - m_sequenceAnimationController->m_sequenceCompletionEvent += EventHandler(this, &MovingCubeAppImpl::OnSequenceAnimationCompleted); + m_sequenceAnimationController.EnableLoop(true); + m_sequenceAnimationController.SetNode(&m_redBox.m_node); + m_sequenceAnimationController.AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(1, 0, 0, 1)), Math::Vector3f_SIMD(0, 0, 1)), 5); + m_sequenceAnimationController.AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(2, 1, 0, 1)), Math::Vector3f_SIMD(1, 1, -1)), 3); + m_sequenceAnimationController.AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(1, 1, 1, 1)), Math::Vector3f_SIMD(2, 1, -2)), 3); + m_sequenceAnimationController.AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(0, 1, 1, 0)), Math::Vector3f_SIMD(2, 1, -1)), 3); + m_sequenceAnimationController.AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(3, 2, 1, 1)), Math::Vector3f_SIMD(1, 1, -1)), 3); + m_sequenceAnimationController.AddAnimationStep(Math::PoseF(Math::Utils::normalize(Math::QuaternionF(0, 0, 1, 1)), Math::Vector3f_SIMD(0, 1, 0)), 1); + m_sequenceAnimationController.SetAnimationPoseResetTime(10); } void OnSimpleAnimationCompleted(Scene::SimpleAnimationController *anim) @@ -105,17 +103,11 @@ namespace OpenVulkano anim->Reset(); } - void OnSequenceAnimationCompleted(Scene::SequenceAnimationController *anim) - { - Logger::APP->info("Animation sequence completed - restarting..."); - m_sequenceAnimationController->Restart(); - } - void Tick() override { m_cameraControl.Tick(); - m_simpleAnimationController->Tick(); - m_sequenceAnimationController->Tick(); + m_simpleAnimationController.Tick(); + m_sequenceAnimationController.Tick(); } void Close() override diff --git a/openVulkanoCpp/Math/Pose.hpp b/openVulkanoCpp/Math/Pose.hpp index 6ee6506..56d2dbb 100644 --- a/openVulkanoCpp/Math/Pose.hpp +++ b/openVulkanoCpp/Math/Pose.hpp @@ -44,7 +44,12 @@ namespace OpenVulkano::Math } } - [[nodiscard]] Quaternion& GetOrientation() const { return m_orientation; } + bool operator==(const Math::Pose &otherPose) + { + return (GetOrientation() == otherPose.GetOrientation()) && (GetPosition() == otherPose.GetPosition()); + } + + [[nodiscard]] Quaternion GetOrientation() const { return m_orientation; } [[nodiscard]] Vector3_SIMD GetPosition() const { return m_position; } diff --git a/openVulkanoCpp/Scene/SequenceAnimationController.cpp b/openVulkanoCpp/Scene/SequenceAnimationController.cpp index 3f0c76f..b056827 100644 --- a/openVulkanoCpp/Scene/SequenceAnimationController.cpp +++ b/openVulkanoCpp/Scene/SequenceAnimationController.cpp @@ -10,31 +10,47 @@ namespace OpenVulkano::Scene { SequenceAnimationController::SequenceAnimationController() { - // m_animationController.m_completionEvent += EventHandler(this, &SequenceAnimationController::OnCurrentFrameFinished); - m_completionEvent += EventHandler(this, &SequenceAnimationController::OnCurrentFrameFinished); + m_animationController.m_completionEvent += EventHandler(this, &SequenceAnimationController::OnCurrentFrameFinished); } - void SequenceAnimationController::AdvanceToNextStep() + SequenceAnimationController::PoseDurationPair SequenceAnimationController::GetStep(int index) + { + if(index >= 0 && index < m_steps.size()) + return m_steps[index]; + return PoseDurationPair(); + } + + void SequenceAnimationController::OnCurrentFrameFinished(SimpleAnimationController *ignored) { if(m_steps.empty()) return; if(m_currentStep < m_steps.size() - 1) { - ++m_currentStep; - SetPoses(GetTargetPose(), m_steps[m_currentStep].first); - SetDuration(m_steps[m_currentStep-1].second); - SimpleAnimationController::Reset(); + m_currentStep++; + m_animationController.SetPoses(m_animationController.GetTargetPose(), m_steps[m_currentStep].first); + m_animationController.SetDuration(m_steps[m_currentStep].second); + m_animationController.Reset(); } else { if(m_loop) { - m_currentStep = 0; - SetPoses(GetTargetPose(), m_steps[m_currentStep].first); - // We don't set the duration because transition from the last step to the first - // requires to use duration of the last step - SimpleAnimationController::Reset(); + // NOTE(vb): Maybe compare steps with some epsilon value + if(m_steps.size() > 1 && ((m_steps.front().first == m_steps.back().first) || m_resetTime == 0)) + { + m_currentStep = 1; + m_animationController.SetPoses(m_steps[m_currentStep-1].first, m_steps[m_currentStep].first); + m_animationController.SetDuration(m_steps[m_currentStep].second); + m_animationController.Reset(); + } + else + { + m_currentStep = 0; + m_animationController.SetPoses(m_steps.back().first, m_steps.front().first); + m_animationController.SetDuration(m_resetTime); + m_animationController.Reset(); + } } else { @@ -45,7 +61,9 @@ namespace OpenVulkano::Scene void SequenceAnimationController::Tick() { - SimpleAnimationController::Tick(); + if(m_steps.empty()) + return; + m_animationController.Tick(); } void SequenceAnimationController::Restart() @@ -53,26 +71,60 @@ namespace OpenVulkano::Scene m_currentStep = 0; if(!m_steps.empty()) { - SetPoses(GetTargetPose(), m_steps[m_currentStep].first); - SetDuration(m_steps.back().second); + m_animationController.SetPoses(m_animationController.GetTargetPose(), m_steps[m_currentStep].first); + m_animationController.SetDuration(m_steps[m_currentStep].second); } - SimpleAnimationController::Reset(); + m_animationController.Reset(); + } + + bool SequenceAnimationController::IsFinished() const + { + if(m_loop) + return false; + return m_currentStep >= m_steps.size(); } void SequenceAnimationController::AddAnimationStep(const Math::PoseF &pose, double duration) { m_steps.emplace_back(pose, duration); - if(m_steps.size() == 2) + if(m_steps.size() > 1) { m_currentStep = 1; - SetPoses(m_steps[0].first, m_steps[1].first); - SetDuration(m_steps[0].second); - Reset(); + m_animationController.SetPoses(m_steps[0].first, m_steps[1].first); + m_animationController.SetDuration(m_steps[1].second); + m_animationController.Reset(); } } - void SequenceAnimationController::OnCurrentFrameFinished(SimpleAnimationController *animationController) + void SequenceAnimationController::AddAnimationSteps(std::initializer_list poses, double duration) { - AdvanceToNextStep(); + for(const auto& pose : poses) + { + m_steps.emplace_back(pose, duration); + } + + if(m_steps.size() > 1) + { + m_currentStep = 1; + m_animationController.SetPoses(m_steps[0].first, m_steps[1].first); + m_animationController.SetDuration(m_steps[1].second); + m_animationController.Reset(); + } + } + + void SequenceAnimationController::AddAnimationSteps(std::initializer_list steps) + { + for(const auto& step : steps) + { + m_steps.emplace_back(step); + } + + if(m_steps.size() > 1) + { + m_currentStep = 1; + m_animationController.SetPoses(m_steps[0].first, m_steps[1].first); + m_animationController.SetDuration(m_steps[1].second); + m_animationController.Reset(); + } } } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/SequenceAnimationController.hpp b/openVulkanoCpp/Scene/SequenceAnimationController.hpp index 0d711eb..3712e9c 100644 --- a/openVulkanoCpp/Scene/SequenceAnimationController.hpp +++ b/openVulkanoCpp/Scene/SequenceAnimationController.hpp @@ -14,32 +14,60 @@ #include #include +#include namespace OpenVulkano::Scene { - class SequenceAnimationController : public SimpleAnimationController + class SequenceAnimationController : public ITickable { - using PoseDurationPair = std::pair; - - std::vector m_steps; - int m_currentStep = 0; - bool m_loop = false; - - void AdvanceToNextStep(); - public: - SequenceAnimationController(); - - Event m_sequenceCompletionEvent; - - void EnableLoop(bool value) { m_loop = value; } - - void Restart(); - void AddAnimationStep(const Math::PoseF &pose, double duration); - bool IsFinished() { if(m_loop) return false; return m_currentStep >= m_steps.size(); } + using PoseDurationPair = std::pair; + + private: + SimpleAnimationController m_animationController; + std::vector m_steps; + size_t m_currentStep = 0; + bool m_loop = false; + double m_resetTime = 0; void OnCurrentFrameFinished(SimpleAnimationController *animationController); + public: + Event m_sequenceCompletionEvent; + + SequenceAnimationController(); + + /* + * Enables or disables looping of the animation sequence. + * + * When looping is enabled, the sequence will restart from the first step after the last step is completed. + * If the start and end poses of the step list are equal or the reset time is 0, the sequence will jump + * directly to the first step. Otherwise, it will animate the transition back to the first step using the + * reset time set by the user. + */ + void EnableLoop(bool value) { m_loop = value; } + + void SetNode(Node *node) { m_animationController.SetNode(node); } + Node* GetNode() const { return m_animationController.GetNode(); } + + /* + * Sets the time to transition back to the first pose when looping is enabled. + * + * If the reset time is set to 0, the sequence will jump directly to the first step. If the start and end poses + * of the step list are equal, the sequence will also jump directly to the first step regardless of the reset time. + * Otherwise, the sequence will animate the transition back to the first step using the reset time. + */ + void SetAnimationPoseResetTime(double resetTime) { m_resetTime = resetTime; } + double GetAnimationPoseResetTime() const { return m_resetTime; } + + void Restart(); + bool IsFinished() const; + + void AddAnimationStep(const Math::PoseF &pose, double duration); + void AddAnimationSteps(std::initializer_list poses, double duration); + void AddAnimationSteps(std::initializer_list steps); + PoseDurationPair GetStep(int index); + void Tick() override; }; } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/SimpleAnimationController.hpp b/openVulkanoCpp/Scene/SimpleAnimationController.hpp index a369f4c..08271b6 100644 --- a/openVulkanoCpp/Scene/SimpleAnimationController.hpp +++ b/openVulkanoCpp/Scene/SimpleAnimationController.hpp @@ -32,14 +32,14 @@ namespace OpenVulkano::Scene void Reset() { m_elapsed = 0; } void SwapPoses() { std::swap(m_initialPose, m_targetPose); } - Node* GetNode() { return m_node; } + Node* GetNode() const { return m_node; } void SetNode(Node *node) { m_node = node; } - const Math::PoseF& GetInitialPose() { return m_initialPose; } - const Math::PoseF& GetTargetPose() { return m_targetPose; } + const Math::PoseF& GetInitialPose() const { return m_initialPose; } + const Math::PoseF& GetTargetPose() const { return m_targetPose; } void SetPoses(const Math::PoseF &initialPose, const Math::PoseF &targetPose) { m_initialPose = initialPose; m_targetPose = targetPose; } - double GetDuration() { return m_duration; } + double GetDuration() const { return m_duration; } void SetDuration(double duration) { m_duration = duration; } double GetProgress(); From c708950bc6ef2059470fccb96c033e6b040b4a02 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Mon, 10 Jun 2024 12:17:00 +0300 Subject: [PATCH 4/6] Added a getter for m_steps --- openVulkanoCpp/Scene/SequenceAnimationController.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/openVulkanoCpp/Scene/SequenceAnimationController.hpp b/openVulkanoCpp/Scene/SequenceAnimationController.hpp index 3712e9c..cb8007a 100644 --- a/openVulkanoCpp/Scene/SequenceAnimationController.hpp +++ b/openVulkanoCpp/Scene/SequenceAnimationController.hpp @@ -67,6 +67,7 @@ namespace OpenVulkano::Scene void AddAnimationSteps(std::initializer_list poses, double duration); void AddAnimationSteps(std::initializer_list steps); PoseDurationPair GetStep(int index); + const std::vector &GetSteps() { return m_steps; } void Tick() override; }; From 1b9041c998f3a76b16a1795cf26b715527354af7 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Mon, 10 Jun 2024 12:49:24 +0300 Subject: [PATCH 5/6] Summary: - Added const references to GetPosition & GetOrientation - Renamed OnCurrentFrameFinished() - Added references to functions in comments --- openVulkanoCpp/Math/Pose.hpp | 6 ++--- .../Scene/SequenceAnimationController.cpp | 6 ++--- .../Scene/SequenceAnimationController.hpp | 22 ++++++++++++++----- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/openVulkanoCpp/Math/Pose.hpp b/openVulkanoCpp/Math/Pose.hpp index 56d2dbb..22fbee8 100644 --- a/openVulkanoCpp/Math/Pose.hpp +++ b/openVulkanoCpp/Math/Pose.hpp @@ -44,14 +44,14 @@ namespace OpenVulkano::Math } } - bool operator==(const Math::Pose &otherPose) + bool operator==(const Math::Pose &otherPose) const { return (GetOrientation() == otherPose.GetOrientation()) && (GetPosition() == otherPose.GetPosition()); } - [[nodiscard]] Quaternion GetOrientation() const { return m_orientation; } + [[nodiscard]] const Quaternion& GetOrientation() const { return m_orientation; } - [[nodiscard]] Vector3_SIMD GetPosition() const { return m_position; } + [[nodiscard]] const Vector3_SIMD& GetPosition() const { return m_position; } [[nodiscard]] Pose Interpolate(const Pose& otherPose, T mixFactor) const { diff --git a/openVulkanoCpp/Scene/SequenceAnimationController.cpp b/openVulkanoCpp/Scene/SequenceAnimationController.cpp index b056827..9ad4c9b 100644 --- a/openVulkanoCpp/Scene/SequenceAnimationController.cpp +++ b/openVulkanoCpp/Scene/SequenceAnimationController.cpp @@ -10,17 +10,17 @@ namespace OpenVulkano::Scene { SequenceAnimationController::SequenceAnimationController() { - m_animationController.m_completionEvent += EventHandler(this, &SequenceAnimationController::OnCurrentFrameFinished); + m_animationController.m_completionEvent += EventHandler(this, &SequenceAnimationController::OnSequenceCompleted); } - SequenceAnimationController::PoseDurationPair SequenceAnimationController::GetStep(int index) + const SequenceAnimationController::PoseDurationPair& SequenceAnimationController::GetStep(int index) const { if(index >= 0 && index < m_steps.size()) return m_steps[index]; return PoseDurationPair(); } - void SequenceAnimationController::OnCurrentFrameFinished(SimpleAnimationController *ignored) + void SequenceAnimationController::OnSequenceCompleted(SimpleAnimationController *ignored) { if(m_steps.empty()) return; diff --git a/openVulkanoCpp/Scene/SequenceAnimationController.hpp b/openVulkanoCpp/Scene/SequenceAnimationController.hpp index cb8007a..92e6451 100644 --- a/openVulkanoCpp/Scene/SequenceAnimationController.hpp +++ b/openVulkanoCpp/Scene/SequenceAnimationController.hpp @@ -30,34 +30,46 @@ namespace OpenVulkano::Scene bool m_loop = false; double m_resetTime = 0; - void OnCurrentFrameFinished(SimpleAnimationController *animationController); + void OnSequenceCompleted(SimpleAnimationController *animationController); public: Event m_sequenceCompletionEvent; SequenceAnimationController(); - /* + /** * Enables or disables looping of the animation sequence. * * When looping is enabled, the sequence will restart from the first step after the last step is completed. * If the start and end poses of the step list are equal or the reset time is 0, the sequence will jump * directly to the first step. Otherwise, it will animate the transition back to the first step using the * reset time set by the user. + * + * @param loop A boolean value to enable or disable looping. */ void EnableLoop(bool value) { m_loop = value; } void SetNode(Node *node) { m_animationController.SetNode(node); } Node* GetNode() const { return m_animationController.GetNode(); } - /* + /** * Sets the time to transition back to the first pose when looping is enabled. * * If the reset time is set to 0, the sequence will jump directly to the first step. If the start and end poses * of the step list are equal, the sequence will also jump directly to the first step regardless of the reset time. * Otherwise, the sequence will animate the transition back to the first step using the reset time. + * + * @param resetTime The time to transition back to the first pose. + * @see GetAnimationPoseResetTime */ void SetAnimationPoseResetTime(double resetTime) { m_resetTime = resetTime; } + + /** + * Gets the current reset time for transitioning back to the first pose. + * + * @return The current reset time. + * @see SetAnimationPoseResetTime + */ double GetAnimationPoseResetTime() const { return m_resetTime; } void Restart(); @@ -66,8 +78,8 @@ namespace OpenVulkano::Scene void AddAnimationStep(const Math::PoseF &pose, double duration); void AddAnimationSteps(std::initializer_list poses, double duration); void AddAnimationSteps(std::initializer_list steps); - PoseDurationPair GetStep(int index); - const std::vector &GetSteps() { return m_steps; } + const PoseDurationPair& GetStep(int index) const; + const std::vector &GetSteps() const { return m_steps; } void Tick() override; }; From 6869ae4a444dacb0d6b6f094983d6e05698c298d Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Mon, 10 Jun 2024 13:32:51 +0300 Subject: [PATCH 6/6] Renamed event in SequenceAnimationController --- openVulkanoCpp/Scene/SequenceAnimationController.cpp | 6 +++--- openVulkanoCpp/Scene/SequenceAnimationController.hpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openVulkanoCpp/Scene/SequenceAnimationController.cpp b/openVulkanoCpp/Scene/SequenceAnimationController.cpp index 9ad4c9b..989b938 100644 --- a/openVulkanoCpp/Scene/SequenceAnimationController.cpp +++ b/openVulkanoCpp/Scene/SequenceAnimationController.cpp @@ -10,7 +10,7 @@ namespace OpenVulkano::Scene { SequenceAnimationController::SequenceAnimationController() { - m_animationController.m_completionEvent += EventHandler(this, &SequenceAnimationController::OnSequenceCompleted); + m_animationController.m_completionEvent += EventHandler(this, &SequenceAnimationController::SequenceCompletedCallback); } const SequenceAnimationController::PoseDurationPair& SequenceAnimationController::GetStep(int index) const @@ -20,7 +20,7 @@ namespace OpenVulkano::Scene return PoseDurationPair(); } - void SequenceAnimationController::OnSequenceCompleted(SimpleAnimationController *ignored) + void SequenceAnimationController::SequenceCompletedCallback(SimpleAnimationController *ignored) { if(m_steps.empty()) return; @@ -54,7 +54,7 @@ namespace OpenVulkano::Scene } else { - m_sequenceCompletionEvent.NotifyAll(this); + OnSequenceCompleted.NotifyAll(this); } } } diff --git a/openVulkanoCpp/Scene/SequenceAnimationController.hpp b/openVulkanoCpp/Scene/SequenceAnimationController.hpp index 92e6451..11f7741 100644 --- a/openVulkanoCpp/Scene/SequenceAnimationController.hpp +++ b/openVulkanoCpp/Scene/SequenceAnimationController.hpp @@ -30,10 +30,10 @@ namespace OpenVulkano::Scene bool m_loop = false; double m_resetTime = 0; - void OnSequenceCompleted(SimpleAnimationController *animationController); + void SequenceCompletedCallback(SimpleAnimationController *animationController); public: - Event m_sequenceCompletionEvent; + Event OnSequenceCompleted; SequenceAnimationController();