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)));
+ }
}
}