| #ifndef _RIVE_STATE_TRANSITION_HPP_ |
| #define _RIVE_STATE_TRANSITION_HPP_ |
| #include "rive/animation/state_transition_flags.hpp" |
| #include "rive/generated/animation/state_transition_base.hpp" |
| #include <stdio.h> |
| #include <vector> |
| |
| namespace rive |
| { |
| class LayerState; |
| class StateMachineLayerImporter; |
| class StateTransitionImporter; |
| class TransitionCondition; |
| class StateInstance; |
| class SMIInput; |
| class LinearAnimation; |
| class LinearAnimationInstance; |
| |
| enum class AllowTransition : unsigned char |
| { |
| no, |
| waitingForExit, |
| yes |
| }; |
| |
| class StateTransition : public StateTransitionBase |
| { |
| friend class StateMachineLayerImporter; |
| friend class StateTransitionImporter; |
| |
| private: |
| StateTransitionFlags transitionFlags() const |
| { |
| return static_cast<StateTransitionFlags>(flags()); |
| } |
| LayerState* m_StateTo = nullptr; |
| |
| std::vector<TransitionCondition*> m_Conditions; |
| void addCondition(TransitionCondition* condition); |
| |
| public: |
| ~StateTransition(); |
| const LayerState* stateTo() const { return m_StateTo; } |
| |
| StatusCode onAddedDirty(CoreContext* context) override; |
| StatusCode onAddedClean(CoreContext* context) override; |
| |
| /// Whether the transition is marked disabled (usually done in the |
| /// editor). |
| bool isDisabled() const |
| { |
| return (transitionFlags() & StateTransitionFlags::Disabled) == |
| StateTransitionFlags::Disabled; |
| } |
| |
| /// Returns AllowTransition::yes when this transition can be taken from |
| /// stateFrom with the given inputs. |
| AllowTransition allowed(StateInstance* stateFrom, |
| SMIInput** inputs, |
| bool ignoreTriggers) const; |
| |
| /// Whether the animation is held at exit or if it keeps advancing |
| /// during mixing. |
| bool pauseOnExit() const |
| { |
| return (transitionFlags() & StateTransitionFlags::PauseOnExit) == |
| StateTransitionFlags::PauseOnExit; |
| } |
| |
| /// Whether exit time is enabled. All other conditions still apply, the |
| /// exit time is effectively an AND with the rest of the conditions. |
| bool enableExitTime() const |
| { |
| return (transitionFlags() & StateTransitionFlags::EnableExitTime) == |
| StateTransitionFlags::EnableExitTime; |
| } |
| |
| StatusCode import(ImportStack& importStack) override; |
| |
| size_t conditionCount() const { return m_Conditions.size(); } |
| TransitionCondition* condition(size_t index) const |
| { |
| if (index < m_Conditions.size()) |
| { |
| return m_Conditions[index]; |
| } |
| return nullptr; |
| } |
| |
| /// The amount of time to mix the outgoing animation onto the incoming |
| /// one when changing state. Only applies when going out from an |
| /// AnimationState. |
| float mixTime(const LayerState* stateFrom) const; |
| |
| /// Computes the exit time in seconds of the stateFrom. Set absolute to |
| /// true if you want the returned time to be relative to the entire |
| /// animation. Set absolute to false if you want it relative to the work |
| /// area. |
| float exitTimeSeconds(const LayerState* stateFrom, |
| bool absolute = false) const; |
| |
| /// Provide the animation instance to use for computing percentage |
| /// durations for exit time. |
| virtual const LinearAnimationInstance* |
| exitTimeAnimationInstance(const StateInstance* from) const; |
| |
| /// Provide the animation to use for computing percentage durations for |
| /// exit time. |
| virtual const LinearAnimation* |
| exitTimeAnimation(const LayerState* from) const; |
| |
| /// Retruns true when we need to hold the exit time, also applies the |
| /// correct time to the animation instance in the stateFrom, when |
| /// applicable (when it's an AnimationState). |
| bool applyExitCondition(StateInstance* stateFrom) const; |
| }; |
| } // namespace rive |
| |
| #endif |