Skip to content

Commit

Permalink
add time based converter interpolator
Browse files Browse the repository at this point in the history
new time based interpolator converter.
This is the first type of converter that holds state and also is dependent on time.
So this PR does 3 things:
- makes converters advanceable
- clones converters when assigned to data binds
- adds support for the time based interpolator

Diffs=
c23d37a730 add time based converter interpolator (#8936)
86f65a5bb7 Fix text rendering with overflow clip (#8933)

Co-authored-by: Philip Chung <[email protected]>
Co-authored-by: hernan <[email protected]>
  • Loading branch information
3 people committed Jan 30, 2025
1 parent c486b7e commit 6764397
Show file tree
Hide file tree
Showing 17 changed files with 470 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .rive_head
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3dd8f44cf2d303d43c1aea514be6b0382a0c4bb9
c23d37a730a0496a4923bd85b8ffe0af90b738d7
40 changes: 40 additions & 0 deletions dev/defs/data_bind/converters/data_converter_interpolator.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "DataConverterInterpolator",
"key": {
"int": 534,
"string": "dataconverterinterpolator"
},
"extends": "data_bind/converters/data_converter.json",
"properties": {
"interpolationType": {
"type": "uint",
"initialValue": "1",
"key": {
"int": 757,
"string": "interpolationtype"
},
"description": "The type of interpolation index in KeyframeInterpolation applied to this layout."
},
"interpolatorId": {
"type": "Id",
"typeRuntime": "uint",
"initialValue": "Core.missingId",
"initialValueRuntime": "-1",
"key": {
"int": 758,
"string": "interpolatorid"
},
"description": "The id of the custom interpolator used when interpolation is Cubic."
},
"duration": {
"type": "double",
"initialValue": "1",
"key": {
"int": 756,
"string": "duration"
},
"description": "Duration of the interpolation",
"bindable": true
}
}
}
1 change: 1 addition & 0 deletions include/rive/data_bind/converters/data_converter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class DataConverter : public DataConverterBase
void addDirt(ComponentDirt dirt);
virtual void update();
void copy(const DataConverter& object);
virtual bool advance(float elapsedTime);

private:
std::vector<DataBind*> m_dataBinds;
Expand Down
1 change: 1 addition & 0 deletions include/rive/data_bind/converters/data_converter_group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class DataConverterGroup : public DataConverterGroupBase
Core* clone() const override;
void bindFromContext(DataContext* dataContext, DataBind* dataBind) override;
void update() override;
bool advance(float elapsedSeconds) override;

private:
std::vector<DataConverterGroupItem*> m_items;
Expand Down
52 changes: 52 additions & 0 deletions include/rive/data_bind/converters/data_converter_interpolator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef _RIVE_DATA_CONVERTER_INTERPOLATOR_HPP_
#define _RIVE_DATA_CONVERTER_INTERPOLATOR_HPP_
#include "rive/generated/data_bind/converters/data_converter_interpolator_base.hpp"
#include "rive/data_bind/data_values/data_value_number.hpp"
#include "rive/data_bind/data_values/data_value.hpp"
#include "rive/animation/keyframe_interpolator.hpp"
#include <stdio.h>
namespace rive
{

struct InterpolatorAnimationData
{
float elapsedSeconds = 0.0f;
float from;
float to;
float interpolate(float f) const
{
float fi = 1.0f - f;
return to * f + from * fi;
}
void copy(const InterpolatorAnimationData& source);
};
class DataConverterInterpolator : public DataConverterInterpolatorBase
{
protected:
KeyFrameInterpolator* m_interpolator = nullptr;

public:
void interpolator(KeyFrameInterpolator* interpolator);
KeyFrameInterpolator* interpolator() const { return m_interpolator; };
DataType outputType() override { return DataType::number; };
DataValue* convert(DataValue* value, DataBind* dataBind) override;
DataValue* reverseConvert(DataValue* value, DataBind* dataBind) override;
bool advance(float elapsedTime) override;
void copy(const DataConverterInterpolatorBase& object);

private:
DataValueNumber m_output;
float m_currentValue;
bool m_isFirstRun = true;

InterpolatorAnimationData m_animationDataA;
InterpolatorAnimationData m_animationDataB;
bool m_isSmoothingAnimation = false;
InterpolatorAnimationData* currentAnimationData();
void advanceAnimationData(float elapsedTime);

public:
};
} // namespace rive

#endif
1 change: 1 addition & 0 deletions include/rive/data_bind/data_bind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class DataBind : public DataBindBase
ViewModelInstanceValue* source() const { return m_Source; };
bool toSource();
bool toTarget();
bool advance(float elapsedTime);

protected:
ComponentDirt m_Dirt = ComponentDirt::Filthy;
Expand Down
31 changes: 31 additions & 0 deletions include/rive/generated/core_registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
#include "rive/data_bind/converters/data_converter.hpp"
#include "rive/data_bind/converters/data_converter_group.hpp"
#include "rive/data_bind/converters/data_converter_group_item.hpp"
#include "rive/data_bind/converters/data_converter_interpolator.hpp"
#include "rive/data_bind/converters/data_converter_operation.hpp"
#include "rive/data_bind/converters/data_converter_operation_value.hpp"
#include "rive/data_bind/converters/data_converter_operation_viewmodel.hpp"
Expand Down Expand Up @@ -549,6 +550,8 @@ class CoreRegistry
return new DataConverterSystemDegsToRads();
case DataConverterRangeMapperBase::typeKey:
return new DataConverterRangeMapper();
case DataConverterInterpolatorBase::typeKey:
return new DataConverterInterpolator();
case DataConverterSystemNormalizerBase::typeKey:
return new DataConverterSystemNormalizer();
case DataConverterGroupItemBase::typeKey:
Expand Down Expand Up @@ -1262,6 +1265,14 @@ class CoreRegistry
case DataConverterRangeMapperBase::flagsPropertyKey:
object->as<DataConverterRangeMapperBase>()->flags(value);
break;
case DataConverterInterpolatorBase::interpolationTypePropertyKey:
object->as<DataConverterInterpolatorBase>()->interpolationType(
value);
break;
case DataConverterInterpolatorBase::interpolatorIdPropertyKey:
object->as<DataConverterInterpolatorBase>()->interpolatorId(
value);
break;
case DataConverterGroupItemBase::converterIdPropertyKey:
object->as<DataConverterGroupItemBase>()->converterId(value);
break;
Expand Down Expand Up @@ -1891,6 +1902,9 @@ class CoreRegistry
case DataConverterRangeMapperBase::maxOutputPropertyKey:
object->as<DataConverterRangeMapperBase>()->maxOutput(value);
break;
case DataConverterInterpolatorBase::durationPropertyKey:
object->as<DataConverterInterpolatorBase>()->duration(value);
break;
case BindablePropertyNumberBase::propertyValuePropertyKey:
object->as<BindablePropertyNumberBase>()->propertyValue(value);
break;
Expand Down Expand Up @@ -2501,6 +2515,12 @@ class CoreRegistry
->interpolatorId();
case DataConverterRangeMapperBase::flagsPropertyKey:
return object->as<DataConverterRangeMapperBase>()->flags();
case DataConverterInterpolatorBase::interpolationTypePropertyKey:
return object->as<DataConverterInterpolatorBase>()
->interpolationType();
case DataConverterInterpolatorBase::interpolatorIdPropertyKey:
return object->as<DataConverterInterpolatorBase>()
->interpolatorId();
case DataConverterGroupItemBase::converterIdPropertyKey:
return object->as<DataConverterGroupItemBase>()->converterId();
case DataConverterRounderBase::decimalsPropertyKey:
Expand Down Expand Up @@ -2942,6 +2962,8 @@ class CoreRegistry
return object->as<DataConverterRangeMapperBase>()->minOutput();
case DataConverterRangeMapperBase::maxOutputPropertyKey:
return object->as<DataConverterRangeMapperBase>()->maxOutput();
case DataConverterInterpolatorBase::durationPropertyKey:
return object->as<DataConverterInterpolatorBase>()->duration();
case BindablePropertyNumberBase::propertyValuePropertyKey:
return object->as<BindablePropertyNumberBase>()
->propertyValue();
Expand Down Expand Up @@ -3232,6 +3254,8 @@ class CoreRegistry
case DataConverterRangeMapperBase::interpolationTypePropertyKey:
case DataConverterRangeMapperBase::interpolatorIdPropertyKey:
case DataConverterRangeMapperBase::flagsPropertyKey:
case DataConverterInterpolatorBase::interpolationTypePropertyKey:
case DataConverterInterpolatorBase::interpolatorIdPropertyKey:
case DataConverterGroupItemBase::converterIdPropertyKey:
case DataConverterRounderBase::decimalsPropertyKey:
case DataConverterStringPadBase::lengthPropertyKey:
Expand Down Expand Up @@ -3438,6 +3462,7 @@ class CoreRegistry
case DataConverterRangeMapperBase::maxInputPropertyKey:
case DataConverterRangeMapperBase::minOutputPropertyKey:
case DataConverterRangeMapperBase::maxOutputPropertyKey:
case DataConverterInterpolatorBase::durationPropertyKey:
case BindablePropertyNumberBase::propertyValuePropertyKey:
case NestedArtboardLeafBase::alignmentXPropertyKey:
case NestedArtboardLeafBase::alignmentYPropertyKey:
Expand Down Expand Up @@ -3890,6 +3915,10 @@ class CoreRegistry
return object->is<DataConverterRangeMapperBase>();
case DataConverterRangeMapperBase::flagsPropertyKey:
return object->is<DataConverterRangeMapperBase>();
case DataConverterInterpolatorBase::interpolationTypePropertyKey:
return object->is<DataConverterInterpolatorBase>();
case DataConverterInterpolatorBase::interpolatorIdPropertyKey:
return object->is<DataConverterInterpolatorBase>();
case DataConverterGroupItemBase::converterIdPropertyKey:
return object->is<DataConverterGroupItemBase>();
case DataConverterRounderBase::decimalsPropertyKey:
Expand Down Expand Up @@ -4294,6 +4323,8 @@ class CoreRegistry
return object->is<DataConverterRangeMapperBase>();
case DataConverterRangeMapperBase::maxOutputPropertyKey:
return object->is<DataConverterRangeMapperBase>();
case DataConverterInterpolatorBase::durationPropertyKey:
return object->is<DataConverterInterpolatorBase>();
case BindablePropertyNumberBase::propertyValuePropertyKey:
return object->is<BindablePropertyNumberBase>();
case NestedArtboardLeafBase::alignmentXPropertyKey:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#ifndef _RIVE_DATA_CONVERTER_INTERPOLATOR_BASE_HPP_
#define _RIVE_DATA_CONVERTER_INTERPOLATOR_BASE_HPP_
#include "rive/core/field_types/core_double_type.hpp"
#include "rive/core/field_types/core_uint_type.hpp"
#include "rive/data_bind/converters/data_converter.hpp"
namespace rive
{
class DataConverterInterpolatorBase : public DataConverter
{
protected:
typedef DataConverter Super;

public:
static const uint16_t typeKey = 534;

/// Helper to quickly determine if a core object extends another without
/// RTTI at runtime.
bool isTypeOf(uint16_t typeKey) const override
{
switch (typeKey)
{
case DataConverterInterpolatorBase::typeKey:
case DataConverterBase::typeKey:
return true;
default:
return false;
}
}

uint16_t coreType() const override { return typeKey; }

static const uint16_t interpolationTypePropertyKey = 757;
static const uint16_t interpolatorIdPropertyKey = 758;
static const uint16_t durationPropertyKey = 756;

protected:
uint32_t m_InterpolationType = 1;
uint32_t m_InterpolatorId = -1;
float m_Duration = 1.0f;

public:
inline uint32_t interpolationType() const { return m_InterpolationType; }
void interpolationType(uint32_t value)
{
if (m_InterpolationType == value)
{
return;
}
m_InterpolationType = value;
interpolationTypeChanged();
}

inline uint32_t interpolatorId() const { return m_InterpolatorId; }
void interpolatorId(uint32_t value)
{
if (m_InterpolatorId == value)
{
return;
}
m_InterpolatorId = value;
interpolatorIdChanged();
}

inline float duration() const { return m_Duration; }
void duration(float value)
{
if (m_Duration == value)
{
return;
}
m_Duration = value;
durationChanged();
}

Core* clone() const override;
void copy(const DataConverterInterpolatorBase& object)
{
m_InterpolationType = object.m_InterpolationType;
m_InterpolatorId = object.m_InterpolatorId;
m_Duration = object.m_Duration;
DataConverter::copy(object);
}

bool deserialize(uint16_t propertyKey, BinaryReader& reader) override
{
switch (propertyKey)
{
case interpolationTypePropertyKey:
m_InterpolationType = CoreUintType::deserialize(reader);
return true;
case interpolatorIdPropertyKey:
m_InterpolatorId = CoreUintType::deserialize(reader);
return true;
case durationPropertyKey:
m_Duration = CoreDoubleType::deserialize(reader);
return true;
}
return DataConverter::deserialize(propertyKey, reader);
}

protected:
virtual void interpolationTypeChanged() {}
virtual void interpolatorIdChanged() {}
virtual void durationChanged() {}
};
} // namespace rive

#endif
7 changes: 7 additions & 0 deletions src/artboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,13 @@ bool Artboard::advanceInternal(float elapsedSeconds, AdvanceFlags flags)
didUpdate = true;
}
}
for (auto dataBind : m_AllDataBinds)
{
if (dataBind->advance(elapsedSeconds))
{
didUpdate = true;
}
}

return didUpdate;
}
Expand Down
4 changes: 3 additions & 1 deletion src/data_bind/converters/data_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,6 @@ void DataConverter::copy(const DataConverter& object)
addDataBind(dataBindClone);
}
DataConverterBase::copy(object);
}
}

bool DataConverter::advance(float elapsedTime) { return false; }
Loading

0 comments on commit 6764397

Please sign in to comment.