From 6fcc4fa7c936162a11c513aac192995c2a9a6d82 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Sat, 20 Apr 2024 00:43:05 +0000 Subject: [PATCH] Xxxx randomization updates part 2 Diffs= 99d28e1ac Xxxx randomization updates part 2 (#7097) Co-authored-by: Alex Gibson Co-authored-by: hernan --- .rive_head | 2 +- .../rive/animation/state_machine_instance.hpp | 4 ++ src/animation/state_machine_instance.cpp | 64 +++++++++++++++---- 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/.rive_head b/.rive_head index 64395e4d..efc3ff2c 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a0004fa72b5b3c4f040b7807b186560703334dc4 +99d28e1ac65672076b08f3a044218ec60268c4ae diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index 1232b113..4618a82f 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -5,6 +5,8 @@ #include #include #include "rive/animation/linear_animation_instance.hpp" +#include "rive/animation/state_instance.hpp" +#include "rive/animation/state_transition.hpp" #include "rive/core/field_types/core_callback_type.hpp" #include "rive/hit_result.hpp" #include "rive/listener_type.hpp" @@ -55,6 +57,8 @@ class StateMachineInstance : public Scene void notifyEventListeners(const std::vector& events, NestedArtboard* source); void sortHitComponents(); double randomValue(); + StateTransition* findRandomTransition(StateInstance* stateFromInstance, bool ignoreTriggers); + StateTransition* findAllowedTransition(StateInstance* stateFromInstance, bool ignoreTriggers); public: StateMachineInstance(const StateMachine* machine, ArtboardInstance* instance); diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 3617c648..9434dd45 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -172,15 +172,11 @@ class StateMachineLayerInstance return true; } - bool tryChangeState(StateInstance* stateFromInstance, bool ignoreTriggers) + StateTransition* findRandomTransition(StateInstance* stateFromInstance, bool ignoreTriggers) { - if (stateFromInstance == nullptr) - { - return false; - } - auto stateFrom = stateFromInstance->state(); - auto outState = m_currentState; uint32_t totalWeight = 0; + auto stateFrom = stateFromInstance->state(); + // printf("stateFrom->transitionCount(): %zu\n", stateFrom->transitionCount()); for (size_t i = 0, length = stateFrom->transitionCount(); i < length; i++) { auto transition = stateFrom->transition(i); @@ -190,11 +186,6 @@ class StateMachineLayerInstance { transition->evaluatedRandomWeight(transition->randomWeight()); totalWeight += transition->randomWeight(); - if ((static_cast(stateFromInstance->state()->flags()) & - LayerStateFlags::Random) != LayerStateFlags::Random) - { - break; - } } else { @@ -207,7 +198,6 @@ class StateMachineLayerInstance } if (totalWeight > 0) { - double randomWeight = randomValue() * totalWeight * 1.0; float currentWeight = 0; size_t index = 0; @@ -218,11 +208,57 @@ class StateMachineLayerInstance auto transitionWeight = transition->evaluatedRandomWeight(); if (currentWeight + transitionWeight > randomWeight) { - break; + return transition; } currentWeight += transitionWeight; index++; } + } + return nullptr; + } + + StateTransition* findAllowedTransition(StateInstance* stateFromInstance, bool ignoreTriggers) + { + auto stateFrom = stateFromInstance->state(); + // If it should randomize + if ((static_cast(stateFrom->flags()) & LayerStateFlags::Random) == + LayerStateFlags::Random) + { + return findRandomTransition(stateFromInstance, ignoreTriggers); + } + // Else search the first valid transition + for (size_t i = 0, length = stateFrom->transitionCount(); i < length; i++) + { + auto transition = stateFrom->transition(i); + auto allowed = + transition->allowed(stateFromInstance, m_stateMachineInstance, ignoreTriggers); + if (allowed == AllowTransition::yes && canChangeState(transition->stateTo())) + { + transition->evaluatedRandomWeight(transition->randomWeight()); + return transition; + } + else + { + transition->evaluatedRandomWeight(0); + if (allowed == AllowTransition::waitingForExit) + { + m_waitingForExit = true; + } + } + } + return nullptr; + } + + bool tryChangeState(StateInstance* stateFromInstance, bool ignoreTriggers) + { + if (stateFromInstance == nullptr) + { + return false; + } + auto outState = m_currentState; + auto transition = findAllowedTransition(stateFromInstance, ignoreTriggers); + if (transition != nullptr) + { changeState(transition->stateTo()); m_stateMachineChangedOnAdvance = true; // state actually has changed