add directBlendState by mix value, bypassing setting inputs fixes https://github.com/rive-app/rive/issues/5039 lets you set integer values as input https://user-images.githubusercontent.com/1216025/228241518-2d08812d-c283-4a15-a94d-9bb72544ecc3.mp4 todo (leaving because i want feedback first): - [x] add tests - [x] update cpp runtime - [x] run `generate_core_runtime.sh` - [x] run `generate_core.sh` for cpp Diffs= 6df791fe4 add directBlendState by mix value, bypassing setting inputs (#5053)
diff --git a/.rive_head b/.rive_head index afbd3bf..044102c 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -d9952ae77c4024134bbd067f53cc04c698c02dda +6df791fe4cbf6f70dc026314400d88ce3fec0a79
diff --git a/dev/defs/animation/blend_animation_direct.json b/dev/defs/animation/blend_animation_direct.json index af3601b..b15dfbb 100644 --- a/dev/defs/animation/blend_animation_direct.json +++ b/dev/defs/animation/blend_animation_direct.json
@@ -16,6 +16,24 @@ "string": "inputid" }, "description": "Id of the input that drives the direct mix value for this animation." + }, + "mixValue": { + "type": "double", + "initialValue": "1", + "key": { + "int": 297, + "string": "mixvalue" + }, + "description": "Direct mix value for this animation." + }, + "blendSource": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 298, + "string": "blendsource" + }, + "description": "Source to use when establishing the mix value for the animation. 0 means look at the input, 1 look at the mixValue." } } -} \ No newline at end of file +}
diff --git a/include/rive/animation/blend_animation_direct.hpp b/include/rive/animation/blend_animation_direct.hpp index 97355cd..f631ed5 100644 --- a/include/rive/animation/blend_animation_direct.hpp +++ b/include/rive/animation/blend_animation_direct.hpp
@@ -4,6 +4,13 @@ #include <stdio.h> namespace rive { + +enum class DirectBlendSource : unsigned int +{ + inputId = 0, + mixValue = 1, +}; + class BlendAnimationDirect : public BlendAnimationDirectBase { public:
diff --git a/include/rive/generated/animation/blend_animation_direct_base.hpp b/include/rive/generated/animation/blend_animation_direct_base.hpp index 74ce655..cb0f7bd 100644 --- a/include/rive/generated/animation/blend_animation_direct_base.hpp +++ b/include/rive/generated/animation/blend_animation_direct_base.hpp
@@ -1,6 +1,7 @@ #ifndef _RIVE_BLEND_ANIMATION_DIRECT_BASE_HPP_ #define _RIVE_BLEND_ANIMATION_DIRECT_BASE_HPP_ #include "rive/animation/blend_animation.hpp" +#include "rive/core/field_types/core_double_type.hpp" #include "rive/core/field_types/core_uint_type.hpp" namespace rive { @@ -29,9 +30,13 @@ uint16_t coreType() const override { return typeKey; } static const uint16_t inputIdPropertyKey = 168; + static const uint16_t mixValuePropertyKey = 297; + static const uint16_t blendSourcePropertyKey = 298; private: uint32_t m_InputId = -1; + float m_MixValue = 1.0f; + uint32_t m_BlendSource = 0; public: inline uint32_t inputId() const { return m_InputId; } @@ -45,10 +50,34 @@ inputIdChanged(); } + inline float mixValue() const { return m_MixValue; } + void mixValue(float value) + { + if (m_MixValue == value) + { + return; + } + m_MixValue = value; + mixValueChanged(); + } + + inline uint32_t blendSource() const { return m_BlendSource; } + void blendSource(uint32_t value) + { + if (m_BlendSource == value) + { + return; + } + m_BlendSource = value; + blendSourceChanged(); + } + Core* clone() const override; void copy(const BlendAnimationDirectBase& object) { m_InputId = object.m_InputId; + m_MixValue = object.m_MixValue; + m_BlendSource = object.m_BlendSource; BlendAnimation::copy(object); } @@ -59,12 +88,20 @@ case inputIdPropertyKey: m_InputId = CoreUintType::deserialize(reader); return true; + case mixValuePropertyKey: + m_MixValue = CoreDoubleType::deserialize(reader); + return true; + case blendSourcePropertyKey: + m_BlendSource = CoreUintType::deserialize(reader); + return true; } return BlendAnimation::deserialize(propertyKey, reader); } protected: virtual void inputIdChanged() {} + virtual void mixValueChanged() {} + virtual void blendSourceChanged() {} }; } // namespace rive
diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index d6f5af6..4688e77 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp
@@ -406,6 +406,9 @@ case BlendAnimationDirectBase::inputIdPropertyKey: object->as<BlendAnimationDirectBase>()->inputId(value); break; + case BlendAnimationDirectBase::blendSourcePropertyKey: + object->as<BlendAnimationDirectBase>()->blendSource(value); + break; case TransitionConditionBase::inputIdPropertyKey: object->as<TransitionConditionBase>()->inputId(value); break; @@ -604,6 +607,9 @@ case AdvanceableStateBase::speedPropertyKey: object->as<AdvanceableStateBase>()->speed(value); break; + case BlendAnimationDirectBase::mixValuePropertyKey: + object->as<BlendAnimationDirectBase>()->mixValue(value); + break; case StateMachineNumberBase::valuePropertyKey: object->as<StateMachineNumberBase>()->value(value); break; @@ -966,6 +972,8 @@ return object->as<BlendAnimationBase>()->animationId(); case BlendAnimationDirectBase::inputIdPropertyKey: return object->as<BlendAnimationDirectBase>()->inputId(); + case BlendAnimationDirectBase::blendSourcePropertyKey: + return object->as<BlendAnimationDirectBase>()->blendSource(); case TransitionConditionBase::inputIdPropertyKey: return object->as<TransitionConditionBase>()->inputId(); case KeyedPropertyBase::propertyKeyPropertyKey: @@ -1101,6 +1109,8 @@ return object->as<NestedSimpleAnimationBase>()->speed(); case AdvanceableStateBase::speedPropertyKey: return object->as<AdvanceableStateBase>()->speed(); + case BlendAnimationDirectBase::mixValuePropertyKey: + return object->as<BlendAnimationDirectBase>()->mixValue(); case StateMachineNumberBase::valuePropertyKey: return object->as<StateMachineNumberBase>()->value(); case CubicInterpolatorBase::x1PropertyKey: @@ -1339,6 +1349,7 @@ case KeyedObjectBase::objectIdPropertyKey: case BlendAnimationBase::animationIdPropertyKey: case BlendAnimationDirectBase::inputIdPropertyKey: + case BlendAnimationDirectBase::blendSourcePropertyKey: case TransitionConditionBase::inputIdPropertyKey: case KeyedPropertyBase::propertyKeyPropertyKey: case StateMachineListenerBase::targetIdPropertyKey: @@ -1404,6 +1415,7 @@ case NestedLinearAnimationBase::mixPropertyKey: case NestedSimpleAnimationBase::speedPropertyKey: case AdvanceableStateBase::speedPropertyKey: + case BlendAnimationDirectBase::mixValuePropertyKey: case StateMachineNumberBase::valuePropertyKey: case CubicInterpolatorBase::x1PropertyKey: case CubicInterpolatorBase::y1PropertyKey:
diff --git a/src/animation/blend_animation_direct.cpp b/src/animation/blend_animation_direct.cpp index 98861a9..a9c175b 100644 --- a/src/animation/blend_animation_direct.cpp +++ b/src/animation/blend_animation_direct.cpp
@@ -18,14 +18,17 @@ } // Make sure the inputId doesn't overflow the input buffer. - if ((size_t)inputId() >= stateMachineImporter->stateMachine()->inputCount()) + if (blendSource() == static_cast<int>(DirectBlendSource::inputId)) { - return StatusCode::InvalidObject; - } - auto input = stateMachineImporter->stateMachine()->input((size_t)inputId()); - if (input == nullptr || !input->is<StateMachineNumber>()) - { - return StatusCode::InvalidObject; + if ((size_t)inputId() >= stateMachineImporter->stateMachine()->inputCount()) + { + return StatusCode::InvalidObject; + } + auto input = stateMachineImporter->stateMachine()->input((size_t)inputId()); + if (input == nullptr || !input->is<StateMachineNumber>()) + { + return StatusCode::InvalidObject; + } } return Super::import(importStack); }
diff --git a/src/animation/blend_state_direct_instance.cpp b/src/animation/blend_state_direct_instance.cpp index 09784b5..be42eaf 100644 --- a/src/animation/blend_state_direct_instance.cpp +++ b/src/animation/blend_state_direct_instance.cpp
@@ -1,5 +1,8 @@ + +#include "rive/animation/blend_animation_direct.hpp" #include "rive/animation/blend_state_direct_instance.hpp" #include "rive/animation/state_machine_input_instance.hpp" +#include <iostream> using namespace rive; @@ -13,10 +16,18 @@ BlendStateInstance<BlendStateDirect, BlendAnimationDirect>::advance(seconds, inputs); for (auto& animation : m_AnimationInstances) { - auto inputInstance = inputs[animation.blendAnimation()->inputId()]; - - auto numberInput = static_cast<const SMINumber*>(inputInstance); - auto value = numberInput->value(); - animation.mix(std::min(1.0f, std::max(0.0f, value / 100.0f))); + if (animation.blendAnimation()->blendSource() == + static_cast<int>(DirectBlendSource::mixValue)) + { + auto value = animation.blendAnimation()->mixValue(); + animation.mix(std::min(1.0f, std::max(0.0f, value / 100.0f))); + } + else + { + auto inputInstance = inputs[animation.blendAnimation()->inputId()]; + auto numberInput = static_cast<const SMINumber*>(inputInstance); + auto value = numberInput->value(); + animation.mix(std::min(1.0f, std::max(0.0f, value / 100.0f))); + } } }