diff --git a/CHANGELOG.md b/CHANGELOG.md index 28e5ca8..f96c401 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [0.5.1] - 2020-08-26 18:09:13 + +- Bumping version number to match the runtime file version (5.1). +- Adding support for bones. +- Adding support for bone binding (deformation). + ## [0.0.7] - 2020-08-15 15:53:17 - Adding support for clipping with Rive format version 5. diff --git a/example/pubspec.lock b/example/pubspec.lock index 938cac9..7499034 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -94,7 +94,7 @@ packages: path: ".." relative: true source: path - version: "0.0.6" + version: "0.5.1" sky_engine: dependency: transitive description: flutter diff --git a/lib/src/generated/bones/cubic_weight_base.dart b/lib/src/generated/bones/cubic_weight_base.dart new file mode 100644 index 0000000..f4b3178 --- /dev/null +++ b/lib/src/generated/bones/cubic_weight_base.dart @@ -0,0 +1,91 @@ +/// Core automatically generated lib/src/generated/bones/cubic_weight_base.dart. +/// Do not modify manually. + +import 'package:rive/src/generated/bones/weight_base.dart'; +import 'package:rive/src/generated/component_base.dart'; +import 'package:rive/src/rive_core/bones/weight.dart'; + +abstract class CubicWeightBase extends Weight { + static const int typeKey = 46; + @override + int get coreType => CubicWeightBase.typeKey; + @override + Set get coreTypes => + {CubicWeightBase.typeKey, WeightBase.typeKey, ComponentBase.typeKey}; + + /// -------------------------------------------------------------------------- + /// InValues field with key 110. + int _inValues = 255; + static const int inValuesPropertyKey = 110; + int get inValues => _inValues; + + /// Change the [_inValues] field value. + /// [inValuesChanged] will be invoked only if the field's value has changed. + set inValues(int value) { + if (_inValues == value) { + return; + } + int from = _inValues; + _inValues = value; + inValuesChanged(from, value); + } + + void inValuesChanged(int from, int to); + + /// -------------------------------------------------------------------------- + /// InIndices field with key 111. + int _inIndices = 1; + static const int inIndicesPropertyKey = 111; + int get inIndices => _inIndices; + + /// Change the [_inIndices] field value. + /// [inIndicesChanged] will be invoked only if the field's value has changed. + set inIndices(int value) { + if (_inIndices == value) { + return; + } + int from = _inIndices; + _inIndices = value; + inIndicesChanged(from, value); + } + + void inIndicesChanged(int from, int to); + + /// -------------------------------------------------------------------------- + /// OutValues field with key 112. + int _outValues = 255; + static const int outValuesPropertyKey = 112; + int get outValues => _outValues; + + /// Change the [_outValues] field value. + /// [outValuesChanged] will be invoked only if the field's value has changed. + set outValues(int value) { + if (_outValues == value) { + return; + } + int from = _outValues; + _outValues = value; + outValuesChanged(from, value); + } + + void outValuesChanged(int from, int to); + + /// -------------------------------------------------------------------------- + /// OutIndices field with key 113. + int _outIndices = 1; + static const int outIndicesPropertyKey = 113; + int get outIndices => _outIndices; + + /// Change the [_outIndices] field value. + /// [outIndicesChanged] will be invoked only if the field's value has changed. + set outIndices(int value) { + if (_outIndices == value) { + return; + } + int from = _outIndices; + _outIndices = value; + outIndicesChanged(from, value); + } + + void outIndicesChanged(int from, int to); +} diff --git a/lib/src/generated/bones/skin_base.dart b/lib/src/generated/bones/skin_base.dart new file mode 100644 index 0000000..7d3f999 --- /dev/null +++ b/lib/src/generated/bones/skin_base.dart @@ -0,0 +1,141 @@ +/// Core automatically generated lib/src/generated/bones/skin_base.dart. +/// Do not modify manually. + +import 'package:rive/src/generated/component_base.dart'; +import 'package:rive/src/generated/container_component_base.dart'; +import 'package:rive/src/rive_core/container_component.dart'; + +abstract class SkinBase extends ContainerComponent { + static const int typeKey = 43; + @override + int get coreType => SkinBase.typeKey; + @override + Set get coreTypes => + {SkinBase.typeKey, ContainerComponentBase.typeKey, ComponentBase.typeKey}; + + /// -------------------------------------------------------------------------- + /// Xx field with key 104. + double _xx = 1; + static const int xxPropertyKey = 104; + + /// x component of x unit vector in the bind transform + double get xx => _xx; + + /// Change the [_xx] field value. + /// [xxChanged] will be invoked only if the field's value has changed. + set xx(double value) { + if (_xx == value) { + return; + } + double from = _xx; + _xx = value; + xxChanged(from, value); + } + + void xxChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// Yx field with key 105. + double _yx = 0; + static const int yxPropertyKey = 105; + + /// y component of x unit vector in the bind transform + double get yx => _yx; + + /// Change the [_yx] field value. + /// [yxChanged] will be invoked only if the field's value has changed. + set yx(double value) { + if (_yx == value) { + return; + } + double from = _yx; + _yx = value; + yxChanged(from, value); + } + + void yxChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// Xy field with key 106. + double _xy = 0; + static const int xyPropertyKey = 106; + + /// x component of y unit vector in the bind transform + double get xy => _xy; + + /// Change the [_xy] field value. + /// [xyChanged] will be invoked only if the field's value has changed. + set xy(double value) { + if (_xy == value) { + return; + } + double from = _xy; + _xy = value; + xyChanged(from, value); + } + + void xyChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// Yy field with key 107. + double _yy = 1; + static const int yyPropertyKey = 107; + + /// y component of y unit vector in the bind transform + double get yy => _yy; + + /// Change the [_yy] field value. + /// [yyChanged] will be invoked only if the field's value has changed. + set yy(double value) { + if (_yy == value) { + return; + } + double from = _yy; + _yy = value; + yyChanged(from, value); + } + + void yyChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// Tx field with key 108. + double _tx = 0; + static const int txPropertyKey = 108; + + /// x position component of the bind transform + double get tx => _tx; + + /// Change the [_tx] field value. + /// [txChanged] will be invoked only if the field's value has changed. + set tx(double value) { + if (_tx == value) { + return; + } + double from = _tx; + _tx = value; + txChanged(from, value); + } + + void txChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// Ty field with key 109. + double _ty = 0; + static const int tyPropertyKey = 109; + + /// y position component of the bind transform + double get ty => _ty; + + /// Change the [_ty] field value. + /// [tyChanged] will be invoked only if the field's value has changed. + set ty(double value) { + if (_ty == value) { + return; + } + double from = _ty; + _ty = value; + tyChanged(from, value); + } + + void tyChanged(double from, double to); +} diff --git a/lib/src/generated/bones/tendon_base.dart b/lib/src/generated/bones/tendon_base.dart new file mode 100644 index 0000000..99c7700 --- /dev/null +++ b/lib/src/generated/bones/tendon_base.dart @@ -0,0 +1,160 @@ +/// Core automatically generated lib/src/generated/bones/tendon_base.dart. +/// Do not modify manually. + +import 'package:rive/src/generated/component_base.dart'; +import 'package:rive/src/rive_core/component.dart'; + +abstract class TendonBase extends Component { + static const int typeKey = 44; + @override + int get coreType => TendonBase.typeKey; + @override + Set get coreTypes => {TendonBase.typeKey, ComponentBase.typeKey}; + + /// -------------------------------------------------------------------------- + /// BoneId field with key 95. + int _boneId; + static const int boneIdPropertyKey = 95; + + /// Identifier used to track the bone this tendon connects to. + int get boneId => _boneId; + + /// Change the [_boneId] field value. + /// [boneIdChanged] will be invoked only if the field's value has changed. + set boneId(int value) { + if (_boneId == value) { + return; + } + int from = _boneId; + _boneId = value; + boneIdChanged(from, value); + } + + void boneIdChanged(int from, int to); + + /// -------------------------------------------------------------------------- + /// Xx field with key 96. + double _xx = 1; + static const int xxPropertyKey = 96; + + /// x component of x unit vector in the bind transform + double get xx => _xx; + + /// Change the [_xx] field value. + /// [xxChanged] will be invoked only if the field's value has changed. + set xx(double value) { + if (_xx == value) { + return; + } + double from = _xx; + _xx = value; + xxChanged(from, value); + } + + void xxChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// Yx field with key 97. + double _yx = 0; + static const int yxPropertyKey = 97; + + /// y component of x unit vector in the bind transform + double get yx => _yx; + + /// Change the [_yx] field value. + /// [yxChanged] will be invoked only if the field's value has changed. + set yx(double value) { + if (_yx == value) { + return; + } + double from = _yx; + _yx = value; + yxChanged(from, value); + } + + void yxChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// Xy field with key 98. + double _xy = 0; + static const int xyPropertyKey = 98; + + /// x component of y unit vector in the bind transform + double get xy => _xy; + + /// Change the [_xy] field value. + /// [xyChanged] will be invoked only if the field's value has changed. + set xy(double value) { + if (_xy == value) { + return; + } + double from = _xy; + _xy = value; + xyChanged(from, value); + } + + void xyChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// Yy field with key 99. + double _yy = 1; + static const int yyPropertyKey = 99; + + /// y component of y unit vector in the bind transform + double get yy => _yy; + + /// Change the [_yy] field value. + /// [yyChanged] will be invoked only if the field's value has changed. + set yy(double value) { + if (_yy == value) { + return; + } + double from = _yy; + _yy = value; + yyChanged(from, value); + } + + void yyChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// Tx field with key 100. + double _tx = 0; + static const int txPropertyKey = 100; + + /// x position component of the bind transform + double get tx => _tx; + + /// Change the [_tx] field value. + /// [txChanged] will be invoked only if the field's value has changed. + set tx(double value) { + if (_tx == value) { + return; + } + double from = _tx; + _tx = value; + txChanged(from, value); + } + + void txChanged(double from, double to); + + /// -------------------------------------------------------------------------- + /// Ty field with key 101. + double _ty = 0; + static const int tyPropertyKey = 101; + + /// y position component of the bind transform + double get ty => _ty; + + /// Change the [_ty] field value. + /// [tyChanged] will be invoked only if the field's value has changed. + set ty(double value) { + if (_ty == value) { + return; + } + double from = _ty; + _ty = value; + tyChanged(from, value); + } + + void tyChanged(double from, double to); +} diff --git a/lib/src/generated/bones/weight_base.dart b/lib/src/generated/bones/weight_base.dart new file mode 100644 index 0000000..3cf80e4 --- /dev/null +++ b/lib/src/generated/bones/weight_base.dart @@ -0,0 +1,51 @@ +/// Core automatically generated lib/src/generated/bones/weight_base.dart. +/// Do not modify manually. + +import 'package:rive/src/generated/component_base.dart'; +import 'package:rive/src/rive_core/component.dart'; + +abstract class WeightBase extends Component { + static const int typeKey = 45; + @override + int get coreType => WeightBase.typeKey; + @override + Set get coreTypes => {WeightBase.typeKey, ComponentBase.typeKey}; + + /// -------------------------------------------------------------------------- + /// Values field with key 102. + int _values = 255; + static const int valuesPropertyKey = 102; + int get values => _values; + + /// Change the [_values] field value. + /// [valuesChanged] will be invoked only if the field's value has changed. + set values(int value) { + if (_values == value) { + return; + } + int from = _values; + _values = value; + valuesChanged(from, value); + } + + void valuesChanged(int from, int to); + + /// -------------------------------------------------------------------------- + /// Indices field with key 103. + int _indices = 1; + static const int indicesPropertyKey = 103; + int get indices => _indices; + + /// Change the [_indices] field value. + /// [indicesChanged] will be invoked only if the field's value has changed. + set indices(int value) { + if (_indices == value) { + return; + } + int from = _indices; + _indices = value; + indicesChanged(from, value); + } + + void indicesChanged(int from, int to); +} diff --git a/lib/src/generated/rive_core_context.dart b/lib/src/generated/rive_core_context.dart index e1aed6b..660a75c 100644 --- a/lib/src/generated/rive_core_context.dart +++ b/lib/src/generated/rive_core_context.dart @@ -18,7 +18,11 @@ import 'package:rive/src/generated/animation/linear_animation_base.dart'; import 'package:rive/src/generated/artboard_base.dart'; import 'package:rive/src/generated/backboard_base.dart'; import 'package:rive/src/generated/bones/bone_base.dart'; +import 'package:rive/src/generated/bones/cubic_weight_base.dart'; import 'package:rive/src/generated/bones/root_bone_base.dart'; +import 'package:rive/src/generated/bones/skin_base.dart'; +import 'package:rive/src/generated/bones/tendon_base.dart'; +import 'package:rive/src/generated/bones/weight_base.dart'; import 'package:rive/src/generated/component_base.dart'; import 'package:rive/src/generated/drawable_base.dart'; import 'package:rive/src/generated/node_base.dart'; @@ -55,7 +59,11 @@ import 'package:rive/src/rive_core/animation/linear_animation.dart'; import 'package:rive/src/rive_core/artboard.dart'; import 'package:rive/src/rive_core/backboard.dart'; import 'package:rive/src/rive_core/bones/bone.dart'; +import 'package:rive/src/rive_core/bones/cubic_weight.dart'; import 'package:rive/src/rive_core/bones/root_bone.dart'; +import 'package:rive/src/rive_core/bones/skin.dart'; +import 'package:rive/src/rive_core/bones/tendon.dart'; +import 'package:rive/src/rive_core/bones/weight.dart'; import 'package:rive/src/rive_core/node.dart'; import 'package:rive/src/rive_core/shapes/clipping_shape.dart'; import 'package:rive/src/rive_core/shapes/cubic_asymmetric_vertex.dart'; @@ -113,8 +121,12 @@ class RiveCoreContext { return Node(); case ShapeBase.typeKey: return Shape(); + case WeightBase.typeKey: + return Weight(); case StraightVertexBase.typeKey: return StraightVertex(); + case CubicWeightBase.typeKey: + return CubicWeight(); case CubicAsymmetricVertexBase.typeKey: return CubicAsymmetricVertex(); case PointsPathBase.typeKey: @@ -141,6 +153,10 @@ class RiveCoreContext { return Bone(); case RootBoneBase.typeKey: return RootBone(); + case SkinBase.typeKey: + return Skin(); + case TendonBase.typeKey: + return Tendon(); default: return null; } @@ -387,11 +403,41 @@ class RiveCoreContext { object.y = value; } break; + case WeightBase.valuesPropertyKey: + if (object is WeightBase && value is int) { + object.values = value; + } + break; + case WeightBase.indicesPropertyKey: + if (object is WeightBase && value is int) { + object.indices = value; + } + break; case StraightVertexBase.radiusPropertyKey: if (object is StraightVertexBase && value is double) { object.radius = value; } break; + case CubicWeightBase.inValuesPropertyKey: + if (object is CubicWeightBase && value is int) { + object.inValues = value; + } + break; + case CubicWeightBase.inIndicesPropertyKey: + if (object is CubicWeightBase && value is int) { + object.inIndices = value; + } + break; + case CubicWeightBase.outValuesPropertyKey: + if (object is CubicWeightBase && value is int) { + object.outValues = value; + } + break; + case CubicWeightBase.outIndicesPropertyKey: + if (object is CubicWeightBase && value is int) { + object.outIndices = value; + } + break; case CubicAsymmetricVertexBase.rotationPropertyKey: if (object is CubicAsymmetricVertexBase && value is double) { object.rotation = value; @@ -517,6 +563,71 @@ class RiveCoreContext { object.y = value; } break; + case SkinBase.xxPropertyKey: + if (object is SkinBase && value is double) { + object.xx = value; + } + break; + case SkinBase.yxPropertyKey: + if (object is SkinBase && value is double) { + object.yx = value; + } + break; + case SkinBase.xyPropertyKey: + if (object is SkinBase && value is double) { + object.xy = value; + } + break; + case SkinBase.yyPropertyKey: + if (object is SkinBase && value is double) { + object.yy = value; + } + break; + case SkinBase.txPropertyKey: + if (object is SkinBase && value is double) { + object.tx = value; + } + break; + case SkinBase.tyPropertyKey: + if (object is SkinBase && value is double) { + object.ty = value; + } + break; + case TendonBase.boneIdPropertyKey: + if (object is TendonBase && value is int) { + object.boneId = value; + } + break; + case TendonBase.xxPropertyKey: + if (object is TendonBase && value is double) { + object.xx = value; + } + break; + case TendonBase.yxPropertyKey: + if (object is TendonBase && value is double) { + object.yx = value; + } + break; + case TendonBase.xyPropertyKey: + if (object is TendonBase && value is double) { + object.xy = value; + } + break; + case TendonBase.yyPropertyKey: + if (object is TendonBase && value is double) { + object.yy = value; + } + break; + case TendonBase.txPropertyKey: + if (object is TendonBase && value is double) { + object.tx = value; + } + break; + case TendonBase.tyPropertyKey: + if (object is TendonBase && value is double) { + object.ty = value; + } + break; } } @@ -545,8 +656,15 @@ class RiveCoreContext { case FillBase.fillRulePropertyKey: case DrawableBase.drawOrderPropertyKey: case DrawableBase.blendModeValuePropertyKey: + case WeightBase.valuesPropertyKey: + case WeightBase.indicesPropertyKey: + case CubicWeightBase.inValuesPropertyKey: + case CubicWeightBase.inIndicesPropertyKey: + case CubicWeightBase.outValuesPropertyKey: + case CubicWeightBase.outIndicesPropertyKey: case ClippingShapeBase.shapeIdPropertyKey: case ClippingShapeBase.clipOpValuePropertyKey: + case TendonBase.boneIdPropertyKey: return uintType; case AnimationBase.namePropertyKey: case ComponentBase.namePropertyKey: @@ -594,6 +712,18 @@ class RiveCoreContext { case BoneBase.lengthPropertyKey: case RootBoneBase.xPropertyKey: case RootBoneBase.yPropertyKey: + case SkinBase.xxPropertyKey: + case SkinBase.yxPropertyKey: + case SkinBase.xyPropertyKey: + case SkinBase.yyPropertyKey: + case SkinBase.txPropertyKey: + case SkinBase.tyPropertyKey: + case TendonBase.xxPropertyKey: + case TendonBase.yxPropertyKey: + case TendonBase.xyPropertyKey: + case TendonBase.yyPropertyKey: + case TendonBase.txPropertyKey: + case TendonBase.tyPropertyKey: return doubleType; case KeyFrameColorBase.valuePropertyKey: case SolidColorBase.colorValuePropertyKey: @@ -648,10 +778,24 @@ class RiveCoreContext { return (object as DrawableBase).drawOrder; case DrawableBase.blendModeValuePropertyKey: return (object as DrawableBase).blendModeValue; + case WeightBase.valuesPropertyKey: + return (object as WeightBase).values; + case WeightBase.indicesPropertyKey: + return (object as WeightBase).indices; + case CubicWeightBase.inValuesPropertyKey: + return (object as CubicWeightBase).inValues; + case CubicWeightBase.inIndicesPropertyKey: + return (object as CubicWeightBase).inIndices; + case CubicWeightBase.outValuesPropertyKey: + return (object as CubicWeightBase).outValues; + case CubicWeightBase.outIndicesPropertyKey: + return (object as CubicWeightBase).outIndices; case ClippingShapeBase.shapeIdPropertyKey: return (object as ClippingShapeBase).shapeId; case ClippingShapeBase.clipOpValuePropertyKey: return (object as ClippingShapeBase).clipOpValue; + case TendonBase.boneIdPropertyKey: + return (object as TendonBase).boneId; } return 0; } @@ -754,6 +898,30 @@ class RiveCoreContext { return (object as RootBoneBase).x; case RootBoneBase.yPropertyKey: return (object as RootBoneBase).y; + case SkinBase.xxPropertyKey: + return (object as SkinBase).xx; + case SkinBase.yxPropertyKey: + return (object as SkinBase).yx; + case SkinBase.xyPropertyKey: + return (object as SkinBase).xy; + case SkinBase.yyPropertyKey: + return (object as SkinBase).yy; + case SkinBase.txPropertyKey: + return (object as SkinBase).tx; + case SkinBase.tyPropertyKey: + return (object as SkinBase).ty; + case TendonBase.xxPropertyKey: + return (object as TendonBase).xx; + case TendonBase.yxPropertyKey: + return (object as TendonBase).yx; + case TendonBase.xyPropertyKey: + return (object as TendonBase).xy; + case TendonBase.yyPropertyKey: + return (object as TendonBase).yy; + case TendonBase.txPropertyKey: + return (object as TendonBase).tx; + case TendonBase.tyPropertyKey: + return (object as TendonBase).ty; } return 0.0; } @@ -842,12 +1010,33 @@ class RiveCoreContext { case DrawableBase.blendModeValuePropertyKey: (object as DrawableBase).blendModeValue = value; break; + case WeightBase.valuesPropertyKey: + (object as WeightBase).values = value; + break; + case WeightBase.indicesPropertyKey: + (object as WeightBase).indices = value; + break; + case CubicWeightBase.inValuesPropertyKey: + (object as CubicWeightBase).inValues = value; + break; + case CubicWeightBase.inIndicesPropertyKey: + (object as CubicWeightBase).inIndices = value; + break; + case CubicWeightBase.outValuesPropertyKey: + (object as CubicWeightBase).outValues = value; + break; + case CubicWeightBase.outIndicesPropertyKey: + (object as CubicWeightBase).outIndices = value; + break; case ClippingShapeBase.shapeIdPropertyKey: (object as ClippingShapeBase).shapeId = value; break; case ClippingShapeBase.clipOpValuePropertyKey: (object as ClippingShapeBase).clipOpValue = value; break; + case TendonBase.boneIdPropertyKey: + (object as TendonBase).boneId = value; + break; } } @@ -993,6 +1182,42 @@ class RiveCoreContext { case RootBoneBase.yPropertyKey: (object as RootBoneBase).y = value; break; + case SkinBase.xxPropertyKey: + (object as SkinBase).xx = value; + break; + case SkinBase.yxPropertyKey: + (object as SkinBase).yx = value; + break; + case SkinBase.xyPropertyKey: + (object as SkinBase).xy = value; + break; + case SkinBase.yyPropertyKey: + (object as SkinBase).yy = value; + break; + case SkinBase.txPropertyKey: + (object as SkinBase).tx = value; + break; + case SkinBase.tyPropertyKey: + (object as SkinBase).ty = value; + break; + case TendonBase.xxPropertyKey: + (object as TendonBase).xx = value; + break; + case TendonBase.yxPropertyKey: + (object as TendonBase).yx = value; + break; + case TendonBase.xyPropertyKey: + (object as TendonBase).xy = value; + break; + case TendonBase.yyPropertyKey: + (object as TendonBase).yy = value; + break; + case TendonBase.txPropertyKey: + (object as TendonBase).tx = value; + break; + case TendonBase.tyPropertyKey: + (object as TendonBase).ty = value; + break; } } diff --git a/lib/src/generated/shapes/cubic_asymmetric_vertex_base.dart b/lib/src/generated/shapes/cubic_asymmetric_vertex_base.dart index 56f21d8..0564f51 100644 --- a/lib/src/generated/shapes/cubic_asymmetric_vertex_base.dart +++ b/lib/src/generated/shapes/cubic_asymmetric_vertex_base.dart @@ -3,6 +3,7 @@ /// Do not modify manually. import 'package:rive/src/generated/component_base.dart'; +import 'package:rive/src/generated/container_component_base.dart'; import 'package:rive/src/generated/shapes/cubic_vertex_base.dart'; import 'package:rive/src/generated/shapes/path_vertex_base.dart'; import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; @@ -16,6 +17,7 @@ abstract class CubicAsymmetricVertexBase extends CubicVertex { CubicAsymmetricVertexBase.typeKey, CubicVertexBase.typeKey, PathVertexBase.typeKey, + ContainerComponentBase.typeKey, ComponentBase.typeKey }; diff --git a/lib/src/generated/shapes/cubic_detached_vertex_base.dart b/lib/src/generated/shapes/cubic_detached_vertex_base.dart index c12849b..b994bc2 100644 --- a/lib/src/generated/shapes/cubic_detached_vertex_base.dart +++ b/lib/src/generated/shapes/cubic_detached_vertex_base.dart @@ -3,6 +3,7 @@ /// Do not modify manually. import 'package:rive/src/generated/component_base.dart'; +import 'package:rive/src/generated/container_component_base.dart'; import 'package:rive/src/generated/shapes/cubic_vertex_base.dart'; import 'package:rive/src/generated/shapes/path_vertex_base.dart'; import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; @@ -16,6 +17,7 @@ abstract class CubicDetachedVertexBase extends CubicVertex { CubicDetachedVertexBase.typeKey, CubicVertexBase.typeKey, PathVertexBase.typeKey, + ContainerComponentBase.typeKey, ComponentBase.typeKey }; diff --git a/lib/src/generated/shapes/cubic_mirrored_vertex_base.dart b/lib/src/generated/shapes/cubic_mirrored_vertex_base.dart index 2dc4cda..7955178 100644 --- a/lib/src/generated/shapes/cubic_mirrored_vertex_base.dart +++ b/lib/src/generated/shapes/cubic_mirrored_vertex_base.dart @@ -3,6 +3,7 @@ /// Do not modify manually. import 'package:rive/src/generated/component_base.dart'; +import 'package:rive/src/generated/container_component_base.dart'; import 'package:rive/src/generated/shapes/cubic_vertex_base.dart'; import 'package:rive/src/generated/shapes/path_vertex_base.dart'; import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; @@ -16,6 +17,7 @@ abstract class CubicMirroredVertexBase extends CubicVertex { CubicMirroredVertexBase.typeKey, CubicVertexBase.typeKey, PathVertexBase.typeKey, + ContainerComponentBase.typeKey, ComponentBase.typeKey }; diff --git a/lib/src/generated/shapes/cubic_vertex_base.dart b/lib/src/generated/shapes/cubic_vertex_base.dart index a972f7f..b2f0339 100644 --- a/lib/src/generated/shapes/cubic_vertex_base.dart +++ b/lib/src/generated/shapes/cubic_vertex_base.dart @@ -3,14 +3,20 @@ /// Do not modify manually. import 'package:rive/src/generated/component_base.dart'; +import 'package:rive/src/generated/container_component_base.dart'; import 'package:rive/src/generated/shapes/path_vertex_base.dart'; +import 'package:rive/src/rive_core/bones/cubic_weight.dart'; import 'package:rive/src/rive_core/shapes/path_vertex.dart'; -abstract class CubicVertexBase extends PathVertex { +abstract class CubicVertexBase extends PathVertex { static const int typeKey = 36; @override int get coreType => CubicVertexBase.typeKey; @override - Set get coreTypes => - {CubicVertexBase.typeKey, PathVertexBase.typeKey, ComponentBase.typeKey}; + Set get coreTypes => { + CubicVertexBase.typeKey, + PathVertexBase.typeKey, + ContainerComponentBase.typeKey, + ComponentBase.typeKey + }; } diff --git a/lib/src/generated/shapes/path_vertex_base.dart b/lib/src/generated/shapes/path_vertex_base.dart index 8eb5027..7fabf55 100644 --- a/lib/src/generated/shapes/path_vertex_base.dart +++ b/lib/src/generated/shapes/path_vertex_base.dart @@ -2,14 +2,19 @@ /// Do not modify manually. import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/component.dart'; +import 'package:rive/src/generated/container_component_base.dart'; +import 'package:rive/src/rive_core/container_component.dart'; -abstract class PathVertexBase extends Component { +abstract class PathVertexBase extends ContainerComponent { static const int typeKey = 14; @override int get coreType => PathVertexBase.typeKey; @override - Set get coreTypes => {PathVertexBase.typeKey, ComponentBase.typeKey}; + Set get coreTypes => { + PathVertexBase.typeKey, + ContainerComponentBase.typeKey, + ComponentBase.typeKey + }; /// -------------------------------------------------------------------------- /// X field with key 24. diff --git a/lib/src/generated/shapes/straight_vertex_base.dart b/lib/src/generated/shapes/straight_vertex_base.dart index 630a73e..278a09e 100644 --- a/lib/src/generated/shapes/straight_vertex_base.dart +++ b/lib/src/generated/shapes/straight_vertex_base.dart @@ -3,10 +3,12 @@ /// Do not modify manually. import 'package:rive/src/generated/component_base.dart'; +import 'package:rive/src/generated/container_component_base.dart'; import 'package:rive/src/generated/shapes/path_vertex_base.dart'; +import 'package:rive/src/rive_core/bones/weight.dart'; import 'package:rive/src/rive_core/shapes/path_vertex.dart'; -abstract class StraightVertexBase extends PathVertex { +abstract class StraightVertexBase extends PathVertex { static const int typeKey = 5; @override int get coreType => StraightVertexBase.typeKey; @@ -14,6 +16,7 @@ abstract class StraightVertexBase extends PathVertex { Set get coreTypes => { StraightVertexBase.typeKey, PathVertexBase.typeKey, + ContainerComponentBase.typeKey, ComponentBase.typeKey }; diff --git a/lib/src/rive_core/artboard.dart b/lib/src/rive_core/artboard.dart index 813206d..81a0813 100644 --- a/lib/src/rive_core/artboard.dart +++ b/lib/src/rive_core/artboard.dart @@ -4,11 +4,9 @@ import 'package:rive/src/rive_core/animation/animation.dart'; import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/rive_core/component_dirt.dart'; import 'package:rive/src/rive_core/drawable.dart'; -import 'package:rive/src/rive_core/math/aabb.dart'; import 'package:rive/src/rive_core/math/mat2d.dart'; import 'package:rive/src/rive_core/math/vec2d.dart'; import 'package:rive/src/rive_core/rive_animation_controller.dart'; -import 'package:rive/src/rive_core/shapes/paint/fill.dart'; import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; import 'package:rive/src/utilities/dependency_sorter.dart'; @@ -81,22 +79,6 @@ class Artboard extends ArtboardBase with ShapePaintContainer { return updateComponents() || didUpdate; } - @override - void childAdded(Component child) { - super.childAdded(child); - if (child is Fill) { - addFill(child); - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - if (child is Fill) { - removeFill(child); - } - } - @override void heightChanged(double from, double to) { addDirt(ComponentDirt.worldTransform); @@ -131,8 +113,7 @@ class Artboard extends ArtboardBase with ShapePaintContainer { @override void update(int dirt) { if (dirt & ComponentDirt.worldTransform != 0) { - var bounds = worldBounds; - var rect = Rect.fromLTWH(bounds[0], bounds[1], bounds[2], bounds[3]); + var rect = Rect.fromLTWH(0, 0, width, height); path.reset(); path.addRect(rect); } @@ -196,10 +177,6 @@ class Artboard extends ArtboardBase with ShapePaintContainer { canvas.restore(); } - @override - AABB get localBounds => AABB.fromValues(0, 0, width, height); - @override - AABB get worldBounds => localBounds; @override Mat2D get worldTransform => Mat2D(); @override diff --git a/lib/src/rive_core/bones/cubic_weight.dart b/lib/src/rive_core/bones/cubic_weight.dart new file mode 100644 index 0000000..f673ec0 --- /dev/null +++ b/lib/src/rive_core/bones/cubic_weight.dart @@ -0,0 +1,16 @@ +import 'package:rive/src/rive_core/math/vec2d.dart'; +import 'package:rive/src/generated/bones/cubic_weight_base.dart'; +export 'package:rive/src/generated/bones/cubic_weight_base.dart'; + +class CubicWeight extends CubicWeightBase { + final Vec2D inTranslation = Vec2D(); + final Vec2D outTranslation = Vec2D(); + @override + void inIndicesChanged(int from, int to) {} + @override + void inValuesChanged(int from, int to) {} + @override + void outIndicesChanged(int from, int to) {} + @override + void outValuesChanged(int from, int to) {} +} diff --git a/lib/src/rive_core/bones/skin.dart b/lib/src/rive_core/bones/skin.dart new file mode 100644 index 0000000..1f70afb --- /dev/null +++ b/lib/src/rive_core/bones/skin.dart @@ -0,0 +1,138 @@ +import 'dart:typed_data'; +import 'package:rive/src/rive_core/bones/skinnable.dart'; +import 'package:rive/src/rive_core/bones/tendon.dart'; +import 'package:rive/src/rive_core/component.dart'; +import 'package:rive/src/rive_core/math/mat2d.dart'; +import 'package:rive/src/rive_core/math/transform_components.dart'; +import 'package:rive/src/rive_core/shapes/path_vertex.dart'; +import 'package:rive/src/generated/bones/skin_base.dart'; +export 'package:rive/src/generated/bones/skin_base.dart'; + +class Skin extends SkinBase { + final List _tendons = []; + List get tendons => _tendons; + Float32List _boneTransforms; + final Mat2D _worldTransform = Mat2D(); + @override + void onDirty(int mask) { + (parent as Skinnable).markSkinDirty(); + } + + @override + void update(int dirt) { + var size = (_tendons.length + 1) * 6; + if (_boneTransforms == null || _boneTransforms.length != size) { + _boneTransforms = Float32List(size); + _boneTransforms[0] = 1; + _boneTransforms[1] = 0; + _boneTransforms[2] = 0; + _boneTransforms[3] = 1; + _boneTransforms[4] = 0; + _boneTransforms[5] = 0; + } + var temp = Mat2D(); + var bidx = 6; + for (final tendon in _tendons) { + var boneWorld = tendon.bone.worldTransform; + var wt = Mat2D.multiply(temp, boneWorld, tendon.inverseBind); + var tc = TransformComponents(); + Mat2D.decompose(boneWorld, tc); + _boneTransforms[bidx++] = wt[0]; + _boneTransforms[bidx++] = wt[1]; + _boneTransforms[bidx++] = wt[2]; + _boneTransforms[bidx++] = wt[3]; + _boneTransforms[bidx++] = wt[4]; + _boneTransforms[bidx++] = wt[5]; + } + } + + void deform(List vertices) { + for (final vertex in vertices) { + vertex.deform(_worldTransform, _boneTransforms); + } + } + + @override + void onAddedDirty() { + super.onAddedDirty(); + if (parent is Skinnable) { + (parent as Skinnable).addSkin(this); + parent.markRebuildDependencies(); + } + } + + @override + void onRemoved() { + if (parent is Skinnable) { + (parent as Skinnable).removeSkin(this); + parent.markRebuildDependencies(); + } + super.onRemoved(); + } + + @override + void buildDependencies() { + super.buildDependencies(); + for (final tendon in _tendons) { + tendon.bone.addDependent(this); + } + } + + @override + void childAdded(Component child) { + super.childAdded(child); + switch (child.coreType) { + case TendonBase.typeKey: + _tendons.add(child as Tendon); + markRebuildDependencies(); + parent?.markRebuildDependencies(); + break; + } + } + + @override + void childRemoved(Component child) { + super.childRemoved(child); + switch (child.coreType) { + case TendonBase.typeKey: + _tendons.remove(child as Tendon); + if (_tendons.isEmpty) { + remove(); + } else { + markRebuildDependencies(); + } + parent?.markRebuildDependencies(); + break; + } + } + + @override + void txChanged(double from, double to) { + _worldTransform[4] = to; + } + + @override + void tyChanged(double from, double to) { + _worldTransform[5] = to; + } + + @override + void xxChanged(double from, double to) { + _worldTransform[0] = to; + } + + @override + void xyChanged(double from, double to) { + _worldTransform[1] = to; + } + + @override + void yxChanged(double from, double to) { + _worldTransform[2] = to; + } + + @override + void yyChanged(double from, double to) { + _worldTransform[3] = to; + } +} diff --git a/lib/src/rive_core/bones/skinnable.dart b/lib/src/rive_core/bones/skinnable.dart new file mode 100644 index 0000000..72cfb1d --- /dev/null +++ b/lib/src/rive_core/bones/skinnable.dart @@ -0,0 +1,22 @@ +import 'package:rive/src/rive_core/bones/skin.dart'; +import 'package:rive/src/rive_core/component.dart'; + +abstract class Skinnable { + Skin _skin; + Skin get skin => _skin; + void appendChild(Component child); + void addSkin(Skin skin) { + assert(skin != null); + _skin = skin; + markSkinDirty(); + } + + void removeSkin(Skin skin) { + if (_skin == skin) { + _skin = null; + markSkinDirty(); + } + } + + void markSkinDirty(); +} diff --git a/lib/src/rive_core/bones/tendon.dart b/lib/src/rive_core/bones/tendon.dart new file mode 100644 index 0000000..b4c23e6 --- /dev/null +++ b/lib/src/rive_core/bones/tendon.dart @@ -0,0 +1,66 @@ +import 'package:rive/src/rive_core/bones/skeletal_component.dart'; +import 'package:rive/src/rive_core/math/mat2d.dart'; +import 'package:rive/src/generated/bones/tendon_base.dart'; +export 'package:rive/src/generated/bones/tendon_base.dart'; + +class Tendon extends TendonBase { + final Mat2D _bind = Mat2D(); + Mat2D _inverseBind; + SkeletalComponent _bone; + SkeletalComponent get bone => _bone; + Mat2D get inverseBind { + if (_inverseBind == null) { + _inverseBind = Mat2D(); + Mat2D.invert(_inverseBind, _bind); + } + return _inverseBind; + } + + @override + void boneIdChanged(int from, int to) {} + @override + void onAddedDirty() { + super.onAddedDirty(); + if (boneId != null) { + _bone = context?.resolve(boneId); + } + } + + @override + void update(int dirt) {} + @override + void txChanged(double from, double to) { + _bind[4] = to; + _inverseBind = null; + } + + @override + void tyChanged(double from, double to) { + _bind[5] = to; + _inverseBind = null; + } + + @override + void xxChanged(double from, double to) { + _bind[0] = to; + _inverseBind = null; + } + + @override + void xyChanged(double from, double to) { + _bind[1] = to; + _inverseBind = null; + } + + @override + void yxChanged(double from, double to) { + _bind[2] = to; + _inverseBind = null; + } + + @override + void yyChanged(double from, double to) { + _bind[3] = to; + _inverseBind = null; + } +} diff --git a/lib/src/rive_core/bones/weight.dart b/lib/src/rive_core/bones/weight.dart new file mode 100644 index 0000000..a262d67 --- /dev/null +++ b/lib/src/rive_core/bones/weight.dart @@ -0,0 +1,42 @@ +import 'dart:typed_data'; +import 'package:rive/src/rive_core/math/mat2d.dart'; +import 'package:rive/src/rive_core/math/vec2d.dart'; +import 'package:rive/src/generated/bones/weight_base.dart'; +export 'package:rive/src/generated/bones/weight_base.dart'; + +class Weight extends WeightBase { + final Vec2D translation = Vec2D(); + @override + void indicesChanged(int from, int to) {} + @override + void update(int dirt) {} + @override + void valuesChanged(int from, int to) {} + static void deform(double x, double y, int indices, int weights, Mat2D world, + Float32List boneTransforms, Vec2D result) { + double xx = 0, xy = 0, yx = 0, yy = 0, tx = 0, ty = 0; + var rx = world[0] * x + world[2] * y + world[4]; + var ry = world[1] * x + world[3] * y + world[5]; + for (int i = 0; i < 4; i++) { + var weight = encodedWeightValue(i, weights); + if (weight == 0) { + continue; + } + double normalizedWeight = weight / 255; + var index = encodedWeightValue(i, indices); + var startBoneTransformIndex = index * 6; + xx += boneTransforms[startBoneTransformIndex++] * normalizedWeight; + xy += boneTransforms[startBoneTransformIndex++] * normalizedWeight; + yx += boneTransforms[startBoneTransformIndex++] * normalizedWeight; + yy += boneTransforms[startBoneTransformIndex++] * normalizedWeight; + tx += boneTransforms[startBoneTransformIndex++] * normalizedWeight; + ty += boneTransforms[startBoneTransformIndex++] * normalizedWeight; + } + result[0] = xx * rx + yx * ry + tx; + result[1] = xy * rx + yy * ry + ty; + } + + static int encodedWeightValue(int index, int data) { + return (data >> (index * 8)) & 0xFF; + } +} diff --git a/lib/src/rive_core/component.dart b/lib/src/rive_core/component.dart index 538cdd1..0f8ffb5 100644 --- a/lib/src/rive_core/component.dart +++ b/lib/src/rive_core/component.dart @@ -13,7 +13,7 @@ abstract class Component extends ComponentBase dynamic _userData; bool get canBeOrphaned => false; int graphOrder = 0; - int dirt = 255; + int dirt = 0xFFFF; static const int maxTreeDepth = 5000; bool addDirt(int value, {bool recurse = false}) { if ((dirt & value) == value) { diff --git a/lib/src/rive_core/math/aabb.dart b/lib/src/rive_core/math/aabb.dart index a4a5015..60586c7 100644 --- a/lib/src/rive_core/math/aabb.dart +++ b/lib/src/rive_core/math/aabb.dart @@ -44,6 +44,13 @@ class AABB { -double.maxFinite ]); } + bool get isEmpty { + return _buffer[0] == double.maxFinite && + _buffer[1] == double.maxFinite && + _buffer[2] == -double.maxFinite && + _buffer[3] == -double.maxFinite; + } + Vec2D includePoint(Vec2D point, Mat2D transform) { var transformedPoint = transform == null ? point diff --git a/lib/src/rive_core/math/circle_constant.dart b/lib/src/rive_core/math/circle_constant.dart index 67f3041..70e7187 100644 --- a/lib/src/rive_core/math/circle_constant.dart +++ b/lib/src/rive_core/math/circle_constant.dart @@ -1 +1,2 @@ const circleConstant = 0.552284749831; +const icircleConstant = 1 - circleConstant; diff --git a/lib/src/rive_core/math/transform_components.dart b/lib/src/rive_core/math/transform_components.dart index 96aca8f..bb65125 100644 --- a/lib/src/rive_core/math/transform_components.dart +++ b/lib/src/rive_core/math/transform_components.dart @@ -1,6 +1,6 @@ import 'dart:math'; -import "dart:typed_data"; -import "vec2d.dart"; +import 'dart:typed_data'; +import 'vec2d.dart'; class TransformComponents { Float32List _buffer; diff --git a/lib/src/rive_core/runtime/runtime_header.dart b/lib/src/rive_core/runtime/runtime_header.dart index 251a7fc..ca3c829 100644 --- a/lib/src/rive_core/runtime/runtime_header.dart +++ b/lib/src/rive_core/runtime/runtime_header.dart @@ -5,7 +5,7 @@ import 'exceptions/rive_format_error_exception.dart'; class RuntimeHeader { static const int majorVersion = 5; - static const int minorVersion = 0; + static const int minorVersion = 1; static const String fingerprint = 'RIVE'; final int ownerId; final int fileId; @@ -19,7 +19,8 @@ class RuntimeHeader { } int readMajorVersion = reader.readVarUint(); int readMinorVersion = reader.readVarUint(); - if (readMajorVersion > majorVersion) { + if (readMajorVersion > majorVersion || + (readMajorVersion == majorVersion && readMinorVersion > minorVersion)) { throw RiveUnsupportedVersionException( majorVersion, minorVersion, readMajorVersion, readMinorVersion); } diff --git a/lib/src/rive_core/shapes/cubic_asymmetric_vertex.dart b/lib/src/rive_core/shapes/cubic_asymmetric_vertex.dart index bad8694..0e7b284 100644 --- a/lib/src/rive_core/shapes/cubic_asymmetric_vertex.dart +++ b/lib/src/rive_core/shapes/cubic_asymmetric_vertex.dart @@ -49,7 +49,7 @@ class CubicAsymmetricVertex extends CubicAsymmetricVertexBase { @override void yChanged(double from, double to) { - super.xChanged(from, to); + super.yChanged(from, to); _outPoint = _inPoint = null; } diff --git a/lib/src/rive_core/shapes/cubic_detached_vertex.dart b/lib/src/rive_core/shapes/cubic_detached_vertex.dart index 63e4189..43631eb 100644 --- a/lib/src/rive_core/shapes/cubic_detached_vertex.dart +++ b/lib/src/rive_core/shapes/cubic_detached_vertex.dart @@ -58,7 +58,7 @@ class CubicDetachedVertex extends CubicDetachedVertexBase { @override void yChanged(double from, double to) { - super.xChanged(from, to); + super.yChanged(from, to); _outPoint = _inPoint = null; } diff --git a/lib/src/rive_core/shapes/cubic_mirrored_vertex.dart b/lib/src/rive_core/shapes/cubic_mirrored_vertex.dart index d03e9fb..8cb3c27 100644 --- a/lib/src/rive_core/shapes/cubic_mirrored_vertex.dart +++ b/lib/src/rive_core/shapes/cubic_mirrored_vertex.dart @@ -44,7 +44,7 @@ class CubicMirroredVertex extends CubicMirroredVertexBase { @override void yChanged(double from, double to) { - super.xChanged(from, to); + super.yChanged(from, to); _outPoint = _inPoint = null; } diff --git a/lib/src/rive_core/shapes/cubic_vertex.dart b/lib/src/rive_core/shapes/cubic_vertex.dart index a52e95f..c689f0e 100644 --- a/lib/src/rive_core/shapes/cubic_vertex.dart +++ b/lib/src/rive_core/shapes/cubic_vertex.dart @@ -1,9 +1,25 @@ +import 'dart:typed_data'; +import 'package:rive/src/rive_core/bones/weight.dart'; +import 'package:rive/src/rive_core/math/mat2d.dart'; import 'package:rive/src/rive_core/math/vec2d.dart'; import 'package:rive/src/generated/shapes/cubic_vertex_base.dart'; +export 'package:rive/src/generated/shapes/cubic_vertex_base.dart'; abstract class CubicVertex extends CubicVertexBase { Vec2D get outPoint; Vec2D get inPoint; set outPoint(Vec2D value); set inPoint(Vec2D value); + @override + Vec2D get renderTranslation => weight?.translation ?? super.renderTranslation; + Vec2D get renderIn => weight?.inTranslation ?? inPoint; + Vec2D get renderOut => weight?.outTranslation ?? outPoint; + @override + void deform(Mat2D world, Float32List boneTransforms) { + super.deform(world, boneTransforms); + Weight.deform(outPoint[0], outPoint[1], weight.outIndices, weight.outValues, + world, boneTransforms, weight.outTranslation); + Weight.deform(inPoint[0], inPoint[1], weight.inIndices, weight.inValues, + world, boneTransforms, weight.inTranslation); + } } diff --git a/lib/src/rive_core/shapes/paint/fill.dart b/lib/src/rive_core/shapes/paint/fill.dart index 347210d..fcc4f25 100644 --- a/lib/src/rive_core/shapes/paint/fill.dart +++ b/lib/src/rive_core/shapes/paint/fill.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:rive/src/rive_core/component_dirt.dart'; +import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; import 'package:rive/src/generated/shapes/paint/fill_base.dart'; export 'package:rive/src/generated/shapes/paint/fill_base.dart'; @@ -15,6 +16,14 @@ class Fill extends FillBase { @override void update(int dirt) {} + @override + void onAdded() { + super.onAdded(); + if (parent is ShapePaintContainer) { + (parent as ShapePaintContainer).addFill(this); + } + } + @override void draw(Canvas canvas, Path path) { if (!isVisible) { diff --git a/lib/src/rive_core/shapes/paint/stroke.dart b/lib/src/rive_core/shapes/paint/stroke.dart index b516f7f..c6923eb 100644 --- a/lib/src/rive_core/shapes/paint/stroke.dart +++ b/lib/src/rive_core/shapes/paint/stroke.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:rive/src/rive_core/component_dirt.dart'; import 'package:rive/src/rive_core/shapes/shape.dart'; +import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; import 'package:rive/src/generated/shapes/paint/stroke_base.dart'; export 'package:rive/src/generated/shapes/paint/stroke_base.dart'; @@ -43,6 +44,14 @@ class Stroke extends StrokeBase { @override void update(int dirt) {} + @override + void onAdded() { + super.onAdded(); + if (parent is ShapePaintContainer) { + (parent as ShapePaintContainer).addStroke(this); + } + } + @override void draw(Canvas canvas, Path path) { if (!isVisible) { diff --git a/lib/src/rive_core/shapes/path.dart b/lib/src/rive_core/shapes/path.dart index 280deaa..57df4bb 100644 --- a/lib/src/rive_core/shapes/path.dart +++ b/lib/src/rive_core/shapes/path.dart @@ -2,13 +2,11 @@ import 'dart:math'; import 'dart:ui' as ui; import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/math/aabb.dart'; import 'package:rive/src/rive_core/math/circle_constant.dart'; import 'package:rive/src/rive_core/math/mat2d.dart'; import 'package:rive/src/rive_core/math/vec2d.dart'; import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; import 'package:rive/src/rive_core/shapes/path_vertex.dart'; -import 'package:rive/src/rive_core/shapes/render_cubic_vertex.dart'; import 'package:rive/src/rive_core/shapes/shape.dart'; import 'package:rive/src/rive_core/shapes/straight_vertex.dart'; import 'package:rive/src/generated/shapes/path_base.dart'; @@ -16,12 +14,12 @@ export 'package:rive/src/generated/shapes/path_base.dart'; abstract class Path extends PathBase { final Mat2D _inverseWorldTransform = Mat2D(); - final ui.Path _uiPath = ui.Path(); + final RenderPath _renderPath = RenderPath(); ui.Path get uiPath { if (!_isValid) { _buildPath(); } - return _uiPath; + return _renderPath.uiPath; } bool _isValid = false; @@ -63,7 +61,7 @@ abstract class Path extends PathBase { void updateWorldTransform() { super.updateWorldTransform(); _shape?.pathChanged(this); - if (!Mat2D.invert(_inverseWorldTransform, worldTransform)) { + if (!Mat2D.invert(_inverseWorldTransform, pathTransform)) { Mat2D.identity(_inverseWorldTransform); } } @@ -79,210 +77,165 @@ abstract class Path extends PathBase { void markPathDirty() { addDirt(ComponentDirt.path); _isValid = false; - _cachedRenderVertices = null; _shape?.pathChanged(this); } List get vertices; - List _cachedRenderVertices; - List get renderVertices { - if (_cachedRenderVertices != null) { - return _cachedRenderVertices; - } - return _cachedRenderVertices = makeRenderVertices(vertices, isClosed); - } - - static List makeRenderVertices( - List pts, bool isClosed) { - if (pts == null || pts.isEmpty) { - return []; - } - List renderPoints = []; - int pl = pts.length; - const arcConstant = circleConstant; - const double iarcConstant = 1.0 - arcConstant; - PathVertex previous = isClosed ? pts[pl - 1] : null; - for (int i = 0; i < pl; i++) { - PathVertex point = pts[i]; - switch (point.coreType) { - case StraightVertexBase.typeKey: - { - StraightVertex straightPoint = point as StraightVertex; - double radius = straightPoint.radius; - if (radius != null && radius > 0) { - if (!isClosed && (i == 0 || i == pl - 1)) { - renderPoints.add(point); - previous = point; - } else { - PathVertex next = pts[(i + 1) % pl]; - Vec2D prevPoint = previous is CubicVertex - ? previous.outPoint - : previous.translation; - Vec2D nextPoint = - next is CubicVertex ? next.inPoint : next.translation; - Vec2D pos = point.translation; - Vec2D toPrev = Vec2D.subtract(Vec2D(), prevPoint, pos); - double toPrevLength = Vec2D.length(toPrev); - toPrev[0] /= toPrevLength; - toPrev[1] /= toPrevLength; - Vec2D toNext = Vec2D.subtract(Vec2D(), nextPoint, pos); - double toNextLength = Vec2D.length(toNext); - toNext[0] /= toNextLength; - toNext[1] /= toNextLength; - double renderRadius = - min(toPrevLength, min(toNextLength, radius)); - Vec2D translation = - Vec2D.scaleAndAdd(Vec2D(), pos, toPrev, renderRadius); - renderPoints.add(RenderCubicVertex() - ..translation = translation - ..inPoint = translation - ..outPoint = Vec2D.scaleAndAdd( - Vec2D(), pos, toPrev, iarcConstant * renderRadius)); - translation = - Vec2D.scaleAndAdd(Vec2D(), pos, toNext, renderRadius); - previous = RenderCubicVertex() - ..translation = translation - ..inPoint = Vec2D.scaleAndAdd( - Vec2D(), pos, toNext, iarcConstant * renderRadius) - ..outPoint = translation; - renderPoints.add(previous); - } - } else { - renderPoints.add(point); - previous = point; - } - break; - } - default: - renderPoints.add(point); - previous = point; - break; - } - } - return renderPoints; - } - bool _buildPath() { _isValid = true; - _uiPath.reset(); - List pts = vertices; - if (pts == null || pts.isEmpty) { + _renderPath.reset(); + List vertices = this.vertices; + var length = vertices.length; + if (vertices == null || length < 2) { return false; } - var renderPoints = makeRenderVertices(pts, isClosed); - PathVertex firstPoint = renderPoints[0]; - _uiPath.moveTo(firstPoint.translation[0], firstPoint.translation[1]); - for (int i = 0, - l = isClosed ? renderPoints.length : renderPoints.length - 1, - pl = renderPoints.length; - i < l; - i++) { - PathVertex point = renderPoints[i]; - PathVertex nextPoint = renderPoints[(i + 1) % pl]; - Vec2D cin = nextPoint is CubicVertex ? nextPoint.inPoint : null; - Vec2D cout = point is CubicVertex ? point.outPoint : null; - if (cin == null && cout == null) { - _uiPath.lineTo(nextPoint.translation[0], nextPoint.translation[1]); + var firstPoint = vertices.first; + double outX, outY; + bool prevIsCubic; + double startX, startY; + double startInX, startInY; + bool startIsCubic; + if (firstPoint is CubicVertex) { + startIsCubic = prevIsCubic = true; + var inPoint = firstPoint.renderIn; + startInX = inPoint[0]; + startInY = inPoint[1]; + var outPoint = firstPoint.renderOut; + outX = outPoint[0]; + outY = outPoint[1]; + var translation = firstPoint.renderTranslation; + startX = translation[0]; + startY = translation[1]; + _renderPath.moveTo(startX, startY); + } else { + startIsCubic = prevIsCubic = false; + var point = firstPoint as StraightVertex; + var radius = point.radius; + if (radius > 0) { + var prev = vertices[length - 1]; + var pos = point.renderTranslation; + var toPrev = Vec2D.subtract(Vec2D(), + prev is CubicVertex ? prev.renderOut : prev.renderTranslation, pos); + var toPrevLength = Vec2D.length(toPrev); + toPrev[0] /= toPrevLength; + toPrev[1] /= toPrevLength; + var next = vertices[1]; + var toNext = Vec2D.subtract(Vec2D(), + next is CubicVertex ? next.renderIn : next.renderTranslation, pos); + var toNextLength = Vec2D.length(toNext); + toNext[0] /= toNextLength; + toNext[1] /= toNextLength; + var renderRadius = min(toPrevLength, min(toNextLength, radius)); + var translation = Vec2D.scaleAndAdd(Vec2D(), pos, toPrev, renderRadius); + _renderPath.moveTo(startInX = startX = translation[0], + startInY = startY = translation[1]); + var outPoint = Vec2D.scaleAndAdd( + Vec2D(), pos, toPrev, icircleConstant * renderRadius); + var inPoint = Vec2D.scaleAndAdd( + Vec2D(), pos, toNext, icircleConstant * renderRadius); + var posNext = Vec2D.scaleAndAdd(Vec2D(), pos, toNext, renderRadius); + _renderPath.cubicTo(outPoint[0], outPoint[1], inPoint[0], inPoint[1], + outX = posNext[0], outY = posNext[1]); + prevIsCubic = false; } else { - cout ??= point.translation; - cin ??= nextPoint.translation; - _uiPath.cubicTo(cout[0], cout[1], cin[0], cin[1], - nextPoint.translation[0], nextPoint.translation[1]); + var translation = point.renderTranslation; + outX = translation[0]; + outY = translation[1]; + _renderPath.moveTo(startInX = startX = outX, startInY = startY = outY); + } + } + for (int i = 1; i < length; i++) { + var vertex = vertices[i]; + if (vertex is CubicVertex) { + var inPoint = vertex.renderIn; + var translation = vertex.renderTranslation; + _renderPath.cubicTo( + outX, outY, inPoint[0], inPoint[1], translation[0], translation[1]); + prevIsCubic = true; + var outPoint = vertex.renderOut; + outX = outPoint[0]; + outY = outPoint[1]; + } else { + var point = vertex as StraightVertex; + var radius = point.radius; + if (radius > 0) { + var pos = point.renderTranslation; + var toPrev = + Vec2D.subtract(Vec2D(), Vec2D.fromValues(outX, outY), pos); + var toPrevLength = Vec2D.length(toPrev); + toPrev[0] /= toPrevLength; + toPrev[1] /= toPrevLength; + var next = vertices[(i + 1) % length]; + var toNext = Vec2D.subtract( + Vec2D(), + next is CubicVertex ? next.renderIn : next.renderTranslation, + pos); + var toNextLength = Vec2D.length(toNext); + toNext[0] /= toNextLength; + toNext[1] /= toNextLength; + var renderRadius = min(toPrevLength, min(toNextLength, radius)); + var translation = + Vec2D.scaleAndAdd(Vec2D(), pos, toPrev, renderRadius); + if (prevIsCubic) { + _renderPath.cubicTo(outX, outY, translation[0], translation[1], + translation[0], translation[1]); + } else { + _renderPath.lineTo(translation[0], translation[1]); + } + var outPoint = Vec2D.scaleAndAdd( + Vec2D(), pos, toPrev, icircleConstant * renderRadius); + var inPoint = Vec2D.scaleAndAdd( + Vec2D(), pos, toNext, icircleConstant * renderRadius); + var posNext = Vec2D.scaleAndAdd(Vec2D(), pos, toNext, renderRadius); + _renderPath.cubicTo(outPoint[0], outPoint[1], inPoint[0], inPoint[1], + outX = posNext[0], outY = posNext[1]); + prevIsCubic = false; + } else if (prevIsCubic) { + var translation = point.renderTranslation; + var x = translation[0]; + var y = translation[1]; + _renderPath.cubicTo(outX, outY, x, y, x, y); + prevIsCubic = false; + outX = x; + outY = y; + } else { + var translation = point.renderTranslation; + outX = translation[0]; + outY = translation[1]; + _renderPath.lineTo(outX, outY); + } } } if (isClosed) { - _uiPath.close(); + if (prevIsCubic || startIsCubic) { + _renderPath.cubicTo(outX, outY, startInX, startInY, startX, startY); + } + _renderPath.close(); } return true; } - - @override - AABB get localBounds => preciseComputeBounds(renderVertices, Mat2D()); - AABB preciseComputeBounds(List renderPoints, Mat2D transform, - {bool debug = false}) { - if (renderPoints.isEmpty) { - return AABB(); - } - AABB bounds = AABB.empty(); - PathVertex firstPoint = renderPoints[0]; - Vec2D lastPoint = bounds.includePoint(firstPoint.translation, transform); - for (int i = 0, - l = isClosed ? renderPoints.length : renderPoints.length - 1, - pl = renderPoints.length; - i < l; - i++) { - PathVertex point = renderPoints[i]; - PathVertex nextPoint = renderPoints[(i + 1) % pl]; - Vec2D cin = nextPoint is CubicVertex ? nextPoint.inPoint : null; - Vec2D cout = point is CubicVertex ? point.outPoint : null; - if (cin == null && cout == null) { - lastPoint = bounds.includePoint(nextPoint.translation, transform); - } else { - cout ??= point.translation; - cin ??= nextPoint.translation; - var next = bounds.includePoint(nextPoint.translation, transform); - if (transform != null) { - cin = Vec2D.transformMat2D(Vec2D(), cin, transform); - cout = Vec2D.transformMat2D(Vec2D(), cout, transform); - } - final double startX = lastPoint[0]; - final double startY = lastPoint[1]; - final double cpX1 = cout[0]; - final double cpY1 = cout[1]; - final double cpX2 = cin[0]; - final double cpY2 = cin[1]; - final double endX = next[0]; - final double endY = next[1]; - lastPoint = next; - _expandBoundsForAxis(bounds, 0, startX, cpX1, cpX2, endX); - _expandBoundsForAxis(bounds, 1, startY, cpY1, cpY2, endY); - } - } - return bounds; - } } -void _expandBoundsToCubicPoint(AABB bounds, int component, double t, double a, - double b, double c, double d) { - if (t >= 0 && t <= 1) { - var ti = 1 - t; - double extremaY = ((ti * ti * ti) * a) + - ((3 * ti * ti * t) * b) + - ((3 * ti * t * t) * c) + - (t * t * t * d); - if (extremaY < bounds[component]) { - bounds[component] = extremaY; - } - if (extremaY > bounds[component + 2]) { - bounds[component + 2] = extremaY; - } +class RenderPath { + final ui.Path _uiPath = ui.Path(); + ui.Path get uiPath => _uiPath; + void reset() { + _uiPath.reset(); } -} -void _expandBoundsForAxis(AABB bounds, int component, double start, double cp1, - double cp2, double end) { - if (!(((start < cp1) && (cp1 < cp2) && (cp2 < end)) || - ((start > cp1) && (cp1 > cp2) && (cp2 > end)))) { - var a = 3 * (cp1 - start); - var b = 3 * (cp2 - cp1); - var c = 3 * (end - cp2); - var d = a - 2 * b + c; - if (d != 0) { - var m1 = -sqrt(b * b - a * c); - var m2 = -a + b; - _expandBoundsToCubicPoint( - bounds, component, -(m1 + m2) / d, start, cp1, cp2, end); - _expandBoundsToCubicPoint( - bounds, component, -(-m1 + m2) / d, start, cp1, cp2, end); - } else if (b != c && d == 0) { - _expandBoundsToCubicPoint( - bounds, component, (2 * b - c) / (2 * (b - c)), start, cp1, cp2, end); - } - var d2a = 2 * (b - a); - var d2b = 2 * (c - b); - if (d2a != b) { - _expandBoundsToCubicPoint( - bounds, component, d2a / (d2a - d2b), start, cp1, cp2, end); - } + void lineTo(double x, double y) { + _uiPath.lineTo(x, y); + } + + void moveTo(double x, double y) { + _uiPath.moveTo(x, y); + } + + void cubicTo(double ox, double oy, double ix, double iy, double x, double y) { + _uiPath.cubicTo(ox, oy, ix, iy, x, y); + } + + void close() { + _uiPath.close(); } } diff --git a/lib/src/rive_core/shapes/path_composer.dart b/lib/src/rive_core/shapes/path_composer.dart index 568ab7e..5d8a24d 100644 --- a/lib/src/rive_core/shapes/path_composer.dart +++ b/lib/src/rive_core/shapes/path_composer.dart @@ -43,9 +43,6 @@ class PathComposer extends PathComposerBase { localPath.addPath(path.uiPath, ui.Offset.zero, matrix4: localTransform?.mat4); } - if (!buildWorldPath) { - _shape.markBoundsDirty(); - } } if (buildWorldPath) { worldPath.reset(); @@ -53,7 +50,6 @@ class PathComposer extends PathComposerBase { worldPath.addPath(path.uiPath, ui.Offset.zero, matrix4: path.pathTransform?.mat4); } - _shape.markBoundsDirty(); } _fillPath = _shape.fillInWorld ? worldPath : localPath; } diff --git a/lib/src/rive_core/shapes/path_vertex.dart b/lib/src/rive_core/shapes/path_vertex.dart index 7a100dc..ec6b9e1 100644 --- a/lib/src/rive_core/shapes/path_vertex.dart +++ b/lib/src/rive_core/shapes/path_vertex.dart @@ -1,17 +1,21 @@ -import 'package:rive/src/rive_core/component_dirt.dart'; +import 'dart:typed_data'; +import 'package:rive/src/rive_core/bones/weight.dart'; +import 'package:rive/src/rive_core/component.dart'; +import 'package:rive/src/rive_core/math/mat2d.dart'; import 'package:rive/src/rive_core/math/vec2d.dart'; import 'package:rive/src/rive_core/shapes/path.dart'; import 'package:rive/src/generated/shapes/path_vertex_base.dart'; export 'package:rive/src/generated/shapes/path_vertex_base.dart'; -abstract class PathVertex extends PathVertexBase { +abstract class PathVertex extends PathVertexBase { + T _weight; + T get weight => _weight; Path get path => parent as Path; @override void update(int dirt) {} - Vec2D get translation { - return Vec2D.fromValues(x, y); - } - + final Vec2D _renderTranslation = Vec2D(); + Vec2D get translation => Vec2D.fromValues(x, y); + Vec2D get renderTranslation => _renderTranslation; set translation(Vec2D value) { x = value[0]; y = value[1]; @@ -19,13 +23,13 @@ abstract class PathVertex extends PathVertexBase { @override void xChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); + _renderTranslation[0] = to; path?.markPathDirty(); } @override void yChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); + _renderTranslation[1] = to; path?.markPathDirty(); } @@ -33,4 +37,25 @@ abstract class PathVertex extends PathVertexBase { String toString() { return translation.toString(); } + + @override + void childAdded(Component component) { + super.childAdded(component); + if (component is T) { + _weight = component; + } + } + + @override + void childRemoved(Component component) { + super.childRemoved(component); + if (_weight == component) { + _weight = null; + } + } + + void deform(Mat2D world, Float32List boneTransforms) { + Weight.deform(x, y, weight.indices, weight.values, world, boneTransforms, + _weight.translation); + } } diff --git a/lib/src/rive_core/shapes/points_path.dart b/lib/src/rive_core/shapes/points_path.dart index a31746d..8506a66 100644 --- a/lib/src/rive_core/shapes/points_path.dart +++ b/lib/src/rive_core/shapes/points_path.dart @@ -1,3 +1,4 @@ +import 'package:rive/src/rive_core/bones/skinnable.dart'; import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/rive_core/component_dirt.dart'; import 'package:rive/src/rive_core/math/mat2d.dart'; @@ -7,13 +8,13 @@ export 'package:rive/src/generated/shapes/points_path_base.dart'; enum PointsPathEditMode { off, creating, editing } -class PointsPath extends PointsPathBase { +class PointsPath extends PointsPathBase with Skinnable { final List _vertices = []; PointsPath() { isClosed = false; } @override - Mat2D get pathTransform => worldTransform; + Mat2D get pathTransform => skin != null ? Mat2D() : worldTransform; @override Mat2D get inversePathTransform => inverseWorldTransform; @override @@ -40,4 +41,26 @@ class PointsPath extends PointsPathBase { void isClosedChanged(bool from, bool to) { markPathDirty(); } + + @override + void buildDependencies() { + super.buildDependencies(); + skin?.addDependent(this); + } + + @override + void markPathDirty() { + skin?.addDirt(ComponentDirt.path); + super.markPathDirty(); + } + + @override + void markSkinDirty() => super.markPathDirty(); + @override + void update(int dirt) { + if (dirt & ComponentDirt.path != 0) { + skin?.deform(_vertices); + } + super.update(dirt); + } } diff --git a/lib/src/rive_core/shapes/render_cubic_vertex.dart b/lib/src/rive_core/shapes/render_cubic_vertex.dart deleted file mode 100644 index 64451ed..0000000 --- a/lib/src/rive_core/shapes/render_cubic_vertex.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/rive_core/math/vec2d.dart'; -import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; - -class RenderCubicVertex extends CubicVertex { - @override - Vec2D inPoint; - @override - Vec2D outPoint; - @override - void onAddedDirty() {} -} diff --git a/lib/src/rive_core/shapes/shape.dart b/lib/src/rive_core/shapes/shape.dart index 16234fb..bab18d7 100644 --- a/lib/src/rive_core/shapes/shape.dart +++ b/lib/src/rive_core/shapes/shape.dart @@ -1,9 +1,5 @@ import 'dart:ui' as ui; -import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/math/aabb.dart'; -import 'package:rive/src/rive_core/math/mat2d.dart'; -import 'package:rive/src/rive_core/shapes/paint/fill.dart'; import 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart' as core; import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; import 'package:rive/src/rive_core/shapes/paint/stroke.dart'; @@ -32,42 +28,6 @@ class Shape extends ShapeBase with ShapePaintContainer { } ui.Path get fillPath => _pathComposer.fillPath; - AABB _worldBounds; - AABB _localBounds; - @override - AABB get worldBounds => _worldBounds ??= computeWorldBounds(); - @override - AABB get localBounds => _localBounds ??= computeLocalBounds(); - void markBoundsDirty() { - _worldBounds = _localBounds = null; - } - - @override - void childAdded(Component child) { - super.childAdded(child); - switch (child.coreType) { - case FillBase.typeKey: - addFill(child as Fill); - break; - case StrokeBase.typeKey: - addStroke(child as Stroke); - break; - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - switch (child.coreType) { - case FillBase.typeKey: - removeFill(child as Fill); - break; - case StrokeBase.typeKey: - removeStroke(child as Stroke); - break; - } - } - bool addPath(Path path) { paintChanged(); return paths.add(path); @@ -155,51 +115,6 @@ class Shape extends ShapeBase with ShapePaintContainer { return paths.remove(path); } - AABB computeWorldBounds() { - if (paths.isEmpty) { - return AABB.fromMinMax(worldTranslation, worldTranslation); - } - var path = paths.first; - var renderPoints = path.renderVertices; - if (renderPoints.isEmpty) { - return AABB.fromMinMax(worldTranslation, worldTranslation); - } - AABB worldBounds = - path.preciseComputeBounds(renderPoints, path.pathTransform); - for (final path in paths.skip(1)) { - var renderPoints = path.renderVertices; - AABB.combine(worldBounds, worldBounds, - path.preciseComputeBounds(renderPoints, path.pathTransform)); - } - return worldBounds; - } - - AABB computeLocalBounds() { - if (paths.isEmpty) { - return AABB(); - } - var path = paths.first; - var renderPoints = path.renderVertices; - if (renderPoints.isEmpty) { - return AABB(); - } - var toShapeTransform = Mat2D(); - if (!Mat2D.invert(toShapeTransform, worldTransform)) { - Mat2D.identity(toShapeTransform); - } - AABB localBounds = path.preciseComputeBounds(renderPoints, - Mat2D.multiply(Mat2D(), toShapeTransform, path.pathTransform)); - for (final path in paths.skip(1)) { - var renderPoints = path.renderVertices; - AABB.combine( - localBounds, - localBounds, - path.preciseComputeBounds(renderPoints, - Mat2D.multiply(Mat2D(), toShapeTransform, path.pathTransform))); - } - return localBounds; - } - @override void blendModeValueChanged(int from, int to) => _markBlendModeDirty(); @override diff --git a/lib/src/rive_core/shapes/shape_paint_container.dart b/lib/src/rive_core/shapes/shape_paint_container.dart index 868a984..4ab1028 100644 --- a/lib/src/rive_core/shapes/shape_paint_container.dart +++ b/lib/src/rive_core/shapes/shape_paint_container.dart @@ -1,5 +1,4 @@ import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/math/aabb.dart'; import 'package:rive/src/rive_core/math/mat2d.dart'; import 'package:rive/src/rive_core/math/vec2d.dart'; import 'package:rive/src/rive_core/shapes/paint/fill.dart'; @@ -15,7 +14,6 @@ abstract class ShapePaintContainer { void onFillsChanged(); @protected void onStrokesChanged(); - @protected bool addFill(Fill fill) { if (fills.add(fill)) { onFillsChanged(); @@ -24,7 +22,6 @@ abstract class ShapePaintContainer { return false; } - @protected bool removeFill(Fill fill) { if (fills.remove(fill)) { onFillsChanged(); @@ -33,7 +30,6 @@ abstract class ShapePaintContainer { return false; } - @protected bool addStroke(Stroke stroke) { if (strokes.add(stroke)) { onStrokesChanged(); @@ -42,7 +38,6 @@ abstract class ShapePaintContainer { return false; } - @protected bool removeStroke(Stroke stroke) { if (strokes.remove(stroke)) { onStrokesChanged(); @@ -51,8 +46,6 @@ abstract class ShapePaintContainer { return false; } - AABB get worldBounds; - AABB get localBounds; bool addDirt(int value, {bool recurse = false}); bool addDependent(Component dependent); void appendChild(Component child); diff --git a/lib/src/rive_core/shapes/straight_vertex.dart b/lib/src/rive_core/shapes/straight_vertex.dart index c51b97f..0cc1e74 100644 --- a/lib/src/rive_core/shapes/straight_vertex.dart +++ b/lib/src/rive_core/shapes/straight_vertex.dart @@ -1,11 +1,35 @@ +import 'package:rive/src/rive_core/bones/weight.dart'; +import 'package:rive/src/rive_core/component.dart'; +import 'package:rive/src/rive_core/math/vec2d.dart'; import 'package:rive/src/generated/shapes/straight_vertex_base.dart'; export 'package:rive/src/generated/shapes/straight_vertex_base.dart'; class StraightVertex extends StraightVertexBase { + Weight _weight; @override String toString() => 'x[$x], y[$y], r[$radius]'; @override void radiusChanged(double from, double to) { path?.markPathDirty(); } + + @override + void childAdded(Component component) { + super.childAdded(component); + if (component is Weight) { + _weight = component; + } + } + + @override + void childRemoved(Component component) { + super.childRemoved(component); + if (_weight == component) { + _weight = null; + } + } + + @override + Vec2D get renderTranslation => + _weight?.translation ?? super.renderTranslation; } diff --git a/pubspec.yaml b/pubspec.yaml index 9c2ddee..ed4770e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: rive description: Rive 2 Flutter Runtime -version: 0.0.7 +version: 0.5.1 repository: https://github.com/rive-app/rive-flutter homepage: https://rive.app