Applying latest fix from editor for ik constraints with skinned bones.

This commit is contained in:
Luigi Rosso
2021-07-27 15:38:05 -07:00
committed by Luigi Rosso
parent c3f045915c
commit 72d2238d1d
3 changed files with 60 additions and 6 deletions

View File

@ -1,3 +1,4 @@
import 'package:rive/src/rive_core/constraints/constraint.dart';
import 'package:rive/src/rive_core/math/mat2d.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/math/vec2d.dart';
import 'package:rive/src/generated/bones/bone_base.dart'; import 'package:rive/src/generated/bones/bone_base.dart';
@ -6,6 +7,14 @@ export 'package:rive/src/generated/bones/bone_base.dart';
typedef bool BoneCallback(Bone bone); typedef bool BoneCallback(Bone bone);
class Bone extends BoneBase { class Bone extends BoneBase {
/// Child constraints applied to some child of this bone which also affect
/// this bone.
final Set<Constraint> _peerConstraints = {};
Iterable<Constraint> get peerConstraints => _peerConstraints;
bool addPeerConstraint(Constraint child) => _peerConstraints.add(child);
bool removePeerConstraint(Constraint child) => _peerConstraints.remove(child);
@override @override
void lengthChanged(double from, double to) { void lengthChanged(double from, double to) {
for (final child in children) { for (final child in children) {

View File

@ -1,5 +1,6 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:rive/src/rive_core/bones/bone.dart';
import 'package:rive/src/rive_core/bones/skinnable.dart'; import 'package:rive/src/rive_core/bones/skinnable.dart';
import 'package:rive/src/rive_core/bones/tendon.dart'; import 'package:rive/src/rive_core/bones/tendon.dart';
import 'package:rive/src/rive_core/component.dart'; import 'package:rive/src/rive_core/component.dart';
@ -96,7 +97,16 @@ class Skin extends SkinBase {
// A skin depends on all its bones. N.B. that we don't depend on the parent // A skin depends on all its bones. N.B. that we don't depend on the parent
// skinnable. The skinnable depends on us. // skinnable. The skinnable depends on us.
for (final tendon in _tendons) { for (final tendon in _tendons) {
tendon.bone?.addDependent(this); var bone = tendon.bone;
if (bone == null) {
continue;
}
bone.addDependent(this);
if (bone is Bone) {
for (final childConstraint in bone.peerConstraints) {
childConstraint.constrainedComponent?.addDependent(this);
}
}
} }
} }

View File

@ -35,11 +35,28 @@ class IKConstraint extends IKConstraintBase {
Iterable<_BoneChainLink> get fkChain => _fkChain; Iterable<_BoneChainLink> get fkChain => _fkChain;
@override @override
void buildDependencies() { void onAdded() {
super.buildDependencies(); super.onAdded();
_buildFKChain();
}
// Rebuild the FK chain when we update dependencies. @override
void onRemoved() {
_clearFKChain();
super.onRemoved();
}
void _clearFKChain() {
for (final link in _fkChain) {
link.bone.markRebuildDependencies();
link.bone.removePeerConstraint(this);
}
_fkChain.clear(); _fkChain.clear();
}
bool _buildFKChain() {
var nextFKChain = <_BoneChainLink>[];
var boneCount = parentBoneCount; var boneCount = parentBoneCount;
var bone = parent as Bone; var bone = parent as Bone;
var bones = <Bone>[bone]; var bones = <Bone>[bone];
@ -51,15 +68,33 @@ class IKConstraint extends IKConstraintBase {
} }
// Now put them in FK order (top to bottom). // Now put them in FK order (top to bottom).
for (final bone in bones.reversed) { for (final bone in bones.reversed) {
_fkChain.add(_BoneChainLink( bone.addPeerConstraint(this);
index: _fkChain.length, nextFKChain.add(_BoneChainLink(
index: nextFKChain.length,
bone: bone, bone: bone,
)); ));
} }
_clearFKChain();
_fkChain.addAll(nextFKChain);
for (final link in _fkChain) {
link.bone.markRebuildDependencies();
link.bone.addPeerConstraint(this);
}
markRebuildDependencies();
return true;
}
@override
void buildDependencies() {
super.buildDependencies();
// Make sure all of the first level children of each bone depend on the // Make sure all of the first level children of each bone depend on the
// tip (constrainedComponent). // tip (constrainedComponent).
var tip = parent as Bone; var tip = parent as Bone;
var bones = _fkChain.reversed.map((link) => link.bone).toSet();
for (final bone in bones.skip(1)) { for (final bone in bones.skip(1)) {
for (final child in bone.children) { for (final child in bone.children) {
if (child is TransformComponent && !bones.contains(child)) { if (child is TransformComponent && !bones.contains(child)) {