/* * 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 "SequenceAnimationController.hpp" namespace OpenVulkano::Scene { SequenceAnimationController::SequenceAnimationController() { m_animationController.OnCompletion += EventHandler(this, &SequenceAnimationController::SequenceCompletedCallback); } const SequenceAnimationController::PoseDurationPair& SequenceAnimationController::GetStep(const int index) const { return m_steps[std::max(0, std::min(index, static_cast(m_steps.size() - 1)))]; } void SequenceAnimationController::SequenceCompletedCallback(SimpleAnimationController* ignored) { if(m_steps.empty()) return; if(m_currentStep < m_steps.size() - 1) { 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) { // 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 { OnSequenceCompleted.NotifyAll(this); } } } void SequenceAnimationController::Tick() { if(m_steps.empty()) return; m_animationController.Tick(); } void SequenceAnimationController::Restart() { m_currentStep = 0; if(!m_steps.empty()) { m_animationController.SetPoses(m_animationController.GetTargetPose(), m_steps[m_currentStep].first); m_animationController.SetDuration(m_steps[m_currentStep].second); } 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() > 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(const std::initializer_list poses, double duration) { 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(const 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(); } } }