| #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 |