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)
This commit is contained in:
mjtalbot
2023-03-30 14:25:22 +00:00
parent 6fa4cca892
commit a7ba0546b9
6 changed files with 117 additions and 8 deletions

View File

@ -1 +1 @@
011f9ab5813d3a8159731d9eb11a70d1afb025d3
6df791fe4cbf6f70dc026314400d88ce3fec0a79

View File

@ -36,9 +36,61 @@ abstract class BlendAnimationDirectBase extends BlendAnimation {
void inputIdChanged(int from, int to);
/// --------------------------------------------------------------------------
/// MixValue field with key 297.
static const double mixValueInitialValue = 1;
double _mixValue = mixValueInitialValue;
static const int mixValuePropertyKey = 297;
/// Direct mix value for this animation.
double get mixValue => _mixValue;
/// Change the [_mixValue] field value.
/// [mixValueChanged] will be invoked only if the field's value has changed.
set mixValue(double value) {
if (_mixValue == value) {
return;
}
double from = _mixValue;
_mixValue = value;
if (hasValidated) {
mixValueChanged(from, value);
}
}
void mixValueChanged(double from, double to);
/// --------------------------------------------------------------------------
/// BlendSource field with key 298.
static const int blendSourceInitialValue = 0;
int _blendSource = blendSourceInitialValue;
static const int blendSourcePropertyKey = 298;
/// Source to use when establishing the mix value for the animation. 0 means
/// look at the input, 1 look at the mixValue.
int get blendSource => _blendSource;
/// Change the [_blendSource] field value.
/// [blendSourceChanged] will be invoked only if the field's value has
/// changed.
set blendSource(int value) {
if (_blendSource == value) {
return;
}
int from = _blendSource;
_blendSource = value;
if (hasValidated) {
blendSourceChanged(from, value);
}
}
void blendSourceChanged(int from, int to);
@override
void copy(covariant BlendAnimationDirectBase source) {
super.copy(source);
_inputId = source._inputId;
_mixValue = source._mixValue;
_blendSource = source._blendSource;
}
}

View File

@ -606,6 +606,16 @@ class RiveCoreContext {
object.inputId = value;
}
break;
case BlendAnimationDirectBase.mixValuePropertyKey:
if (object is BlendAnimationDirectBase && value is double) {
object.mixValue = value;
}
break;
case BlendAnimationDirectBase.blendSourcePropertyKey:
if (object is BlendAnimationDirectBase && value is int) {
object.blendSource = value;
}
break;
case StateMachineComponentBase.namePropertyKey:
if (object is StateMachineComponentBase && value is String) {
object.name = value;
@ -1320,6 +1330,7 @@ class RiveCoreContext {
case KeyedObjectBase.objectIdPropertyKey:
case BlendAnimationBase.animationIdPropertyKey:
case BlendAnimationDirectBase.inputIdPropertyKey:
case BlendAnimationDirectBase.blendSourcePropertyKey:
case TransitionConditionBase.inputIdPropertyKey:
case KeyedPropertyBase.propertyKeyPropertyKey:
case StateMachineListenerBase.targetIdPropertyKey:
@ -1382,6 +1393,7 @@ class RiveCoreContext {
case NestedLinearAnimationBase.mixPropertyKey:
case NestedSimpleAnimationBase.speedPropertyKey:
case AdvanceableStateBase.speedPropertyKey:
case BlendAnimationDirectBase.mixValuePropertyKey:
case StateMachineNumberBase.valuePropertyKey:
case CubicInterpolatorBase.x1PropertyKey:
case CubicInterpolatorBase.y1PropertyKey:
@ -1560,6 +1572,8 @@ class RiveCoreContext {
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:
@ -1688,6 +1702,8 @@ class RiveCoreContext {
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:
@ -2071,6 +2087,11 @@ class RiveCoreContext {
object.inputId = value;
}
break;
case BlendAnimationDirectBase.blendSourcePropertyKey:
if (object is BlendAnimationDirectBase) {
object.blendSource = value;
}
break;
case TransitionConditionBase.inputIdPropertyKey:
if (object is TransitionConditionBase) {
object.inputId = value;
@ -2381,6 +2402,11 @@ class RiveCoreContext {
object.speed = value;
}
break;
case BlendAnimationDirectBase.mixValuePropertyKey:
if (object is BlendAnimationDirectBase) {
object.mixValue = value;
}
break;
case StateMachineNumberBase.valuePropertyKey:
if (object is StateMachineNumberBase) {
object.value = value;

View File

@ -5,6 +5,8 @@ import 'package:rive/src/rive_core/animation/state_machine_number.dart';
export 'package:rive/src/generated/animation/blend_animation_direct_base.dart';
enum DirectBlendSource { inputId, mixValue }
class BlendAnimationDirect extends BlendAnimationDirectBase {
StateMachineNumber? _input;
StateMachineNumber? get input => _input;
@ -28,4 +30,10 @@ class BlendAnimationDirect extends BlendAnimationDirectBase {
return super.import(stack);
}
@override
void blendSourceChanged(int from, int to) {}
@override
void mixValueChanged(double from, double to) {}
}

View File

@ -12,13 +12,19 @@ class BlendStateDirectInstance
void advance(double seconds, StateMachineController controller) {
super.advance(seconds, controller);
for (final animation in animationInstances) {
dynamic inputValue =
controller.getInputValue(animation.blendAnimation.inputId);
var value = (inputValue is double
? inputValue
: animation.blendAnimation.input?.value) ??
0;
animation.mix = (value / 100).clamp(0, 1);
if (animation.blendAnimation.blendSource ==
DirectBlendSource.inputId.index) {
dynamic inputValue =
controller.getInputValue(animation.blendAnimation.inputId);
var value = (inputValue is double
? inputValue
: animation.blendAnimation.input?.value) ??
0;
animation.mix = (value / 100).clamp(0, 1);
} else {
var value = animation.blendAnimation.mixValue;
animation.mix = (value / 100).clamp(0, 1);
}
}
}
}

View File

@ -13,6 +13,23 @@ class CubicAsymmetricVertex extends CubicAsymmetricVertexBase {
InternalCoreHelper.markValid(this);
}
CubicAsymmetricVertex.fromValues({
required double x,
required double y,
double? inX,
double? inY,
double? outX,
double? outY,
Vec2D? inPoint,
Vec2D? outPoint,
}) {
InternalCoreHelper.markValid(this);
this.x = x;
this.y = y;
this.inPoint = Vec2D.fromValues(inX ?? inPoint!.x, inY ?? inPoint!.y);
this.outPoint = Vec2D.fromValues(outX ?? outPoint!.x, outY ?? outPoint!.y);
}
Vec2D? _inPoint;
Vec2D? _outPoint;