| #ifndef _RIVE_BLEND_STATE_INSTANCE_HPP_ | |
| #define _RIVE_BLEND_STATE_INSTANCE_HPP_ | |
| #include <string> | |
| #include <vector> | |
| #include "rive/animation/state_instance.hpp" | |
| #include "rive/animation/blend_state.hpp" | |
| #include "rive/animation/linear_animation_instance.hpp" | |
| namespace rive { | |
| class AnimationState; | |
| template <class K, class T> class BlendStateInstance; | |
| template <class T> class BlendStateAnimationInstance { | |
| template <class A, class B> friend class BlendStateInstance; | |
| private: | |
| const T* m_BlendAnimation; | |
| LinearAnimationInstance m_AnimationInstance; | |
| float m_Mix = 0.0f; | |
| public: | |
| const T* blendAnimation() const { return m_BlendAnimation; } | |
| const LinearAnimationInstance* animationInstance() const { return &m_AnimationInstance; } | |
| BlendStateAnimationInstance(const T* blendAnimation) : | |
| m_BlendAnimation(blendAnimation), m_AnimationInstance(blendAnimation->animation()) {} | |
| void mix(float value) { m_Mix = value; } | |
| }; | |
| template <class K, class T> class BlendStateInstance : public StateInstance { | |
| protected: | |
| std::vector<BlendStateAnimationInstance<T>> m_AnimationInstances; | |
| bool m_KeepGoing = true; | |
| public: | |
| BlendStateInstance(const K* blendState) : StateInstance(blendState) { | |
| for (auto blendAnimation : blendState->animations()) { | |
| m_AnimationInstances.emplace_back( | |
| BlendStateAnimationInstance<T>(static_cast<T*>(blendAnimation))); | |
| } | |
| } | |
| bool keepGoing() const override { return m_KeepGoing; } | |
| void advance(float seconds, SMIInput** inputs) override { | |
| m_KeepGoing = false; | |
| for (auto& animation : m_AnimationInstances) { | |
| if (animation.m_AnimationInstance.advance(seconds)) { | |
| m_KeepGoing = true; | |
| } | |
| } | |
| } | |
| void apply(Artboard* artboard, float mix) override { | |
| for (auto& animation : m_AnimationInstances) { | |
| float m = mix * animation.m_Mix; | |
| animation.m_AnimationInstance.apply(artboard, m); | |
| } | |
| } | |
| // Find the animationInstance that corresponds to the blendAnimation. | |
| const LinearAnimationInstance* | |
| animationInstance(const BlendAnimation* blendAnimation) const { | |
| for (auto& animation : m_AnimationInstances) { | |
| if (animation.m_BlendAnimation == blendAnimation) { | |
| return animation.animationInstance(); | |
| } | |
| } | |
| return nullptr; | |
| } | |
| }; | |
| } // namespace rive | |
| #endif |