completeResolve method

  1. @override
void completeResolve()
override

Implementation

@override
void completeResolve() {
  if (_influencedBones == null || _influencedBones!.isEmpty) {
    return;
  }

  // Initialize solver.
  ActorBone start = _influencedBones![0].bone;
  ActorNode? end = _influencedBones![_influencedBones!.length - 1].bone;
  _fkChain = <BoneChain>[];
  while (end != null && end != start.parent) {
    BoneChain bc = BoneChain(
      idx,
      end as ActorBone,
      0.0,
      false, // initialize to false and correct to true later if length < 3.
      TransformComponents(),
      Mat2D(),
    );
    _fkChain.add(bc);
    end = end.parent;
  }
  bool allIn = _fkChain.length < 3;
  if (allIn) {
    for (final bc in _fkChain) {
      bc.included = true;
    }
  }
  _fkChain = _fkChain.reversed.toList();

  // Make sure bones are good.
  _boneData = <BoneChain>[];
  for (final InfluencedBone bone in _influencedBones!) {
    BoneChain? item =
        _fkChain.firstWhereOrNull((chainItem) => chainItem.bone == bone.bone);
    if (item == null) {
      print('Bone not in chain: ' + bone.bone.name);
      continue;
    }
    _boneData.add(item);
  }
  if (!allIn) {
    // Influenced bones are in the IK chain.
    for (int i = 0; i < _boneData.length - 1; i++) {
      BoneChain item = _boneData[i];
      item.included = true;
      _fkChain[item.index + 1].included = true;
    }
  }

  // Finally mark dependencies.
  for (final InfluencedBone bone in _influencedBones!) {
    // Don't mark dependency on parent as ActorComponent already does this.
    if (bone.bone == parent) {
      continue;
    }

    artboard.addDependency(this, bone.bone);
  }

  if (target != null) {
    artboard.addDependency(this, target!);
  }

  // All the first level children of the influenced bones should
  // depend on the final bone.
  BoneChain tip = _fkChain[_fkChain.length - 1];
  for (final BoneChain fk in _fkChain) {
    if (fk == tip) {
      continue;
    }

    ActorBone bone = fk.bone;
    for (final node in bone.children!) {
      BoneChain? item =
          _fkChain.firstWhereOrNull((chainItem) => chainItem.bone == node);
      if (item != null) {
        // node is in the FK chain.
        continue;
      }
      artboard.addDependency(node, tip.bone);
    }
  }
}