applyMixingFrom method

double applyMixingFrom(
  1. TrackEntry to,
  2. Skeleton skeleton,
  3. MixPose currentPose
)

Implementation

double applyMixingFrom(
    TrackEntry to, Skeleton skeleton, MixPose currentPose) {
  final TrackEntry from = to.mixingFrom!;
  if (from.mixingFrom != null) applyMixingFrom(from, skeleton, currentPose);

  double mix = 0.0;
  if (to.mixDuration == 0) {
    // Single frame mix to undo mixingFrom changes.
    mix = 1.0;
    currentPose = MixPose.setup;
  } else {
    mix = to.mixTime / to.mixDuration;
    if (mix > 1) mix = 1.0;
  }

  final List<Event?> events =
      mix < from.eventThreshold ? this.events : <Event?>[];
  final bool attachments = mix < from.attachmentThreshold;
  final bool drawOrder = mix < from.drawOrderThreshold;
  final double animationLast = from.animationLast;
  final double animationTime = from.getAnimationTime();
  final List<Timeline> timelines = from.animation!.timelines;
  final Int32List timelineData = Int32List.fromList(from.timelineData);
  final int timelineCount = timelineData.length;
  final List<TrackEntry> timelineDipMix = from.timelineDipMix;

  final bool firstFrame = from.timelinesRotation.isEmpty;
  if (firstFrame) {
    from.timelinesRotation = ArrayUtils.copyWithNewArraySize(
        from.timelinesRotation, timelineCount << 1, double.infinity);
  }
  final Float32List timelinesRotation =
      Float32List.fromList(from.timelinesRotation);

  MixPose pose;
  final double alphaDip = from.alpha * to.interruptAlpha,
      alphaMix = alphaDip * (1 - mix);

  double alpha = 0.0;
  from.totalAlpha = 0.0;
  for (int i = 0; i < timelineCount; i++) {
    final Timeline timeline = timelines[i];
    switch (timelineData[i]) {
      case AnimationState.subsequent:
        if (!attachments && timeline is AttachmentTimeline) continue;
        if (!drawOrder && timeline is DrawOrderTimeline) continue;
        pose = currentPose;
        alpha = alphaMix;
        break;
      case AnimationState.first:
        pose = MixPose.setup;
        alpha = alphaMix;
        break;
      case AnimationState.dip:
        pose = MixPose.setup;
        alpha = alphaDip;
        break;
      default:
        pose = MixPose.setup;
        alpha = alphaDip;
        final TrackEntry dipMix = timelineDipMix[i];
        alpha *= math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
        break;
    }
    from.totalAlpha = from.totalAlpha + alpha;
    if (timeline is RotateTimeline) {
      applyRotateTimeline(timeline, skeleton, animationTime, alpha, pose,
          timelinesRotation, i << 1, firstFrame);
    } else {
      timeline.apply(skeleton, animationLast, animationTime, events, alpha,
          pose, MixDirection.mixOut);
    }
  }

  if (to.mixDuration > 0) queueEvents(from, animationTime);
  this.events.length = 0;
  from
    ..nextAnimationLast = animationTime
    ..nextTrackLast = from.trackTime;

  return mix;
}