/** @param last May be null. */
  private TrackEntry trackEntry(
      int trackIndex, Animation animation, boolean loop, TrackEntry last) {
    TrackEntry entry = trackEntryPool.obtain();
    entry.trackIndex = trackIndex;
    entry.animation = animation;
    entry.loop = loop;

    entry.eventThreshold = 0;
    entry.attachmentThreshold = 0;
    entry.drawOrderThreshold = 0;

    entry.animationStart = 0;
    entry.animationEnd = animation.getDuration();
    entry.animationLast = -1;
    entry.nextAnimationLast = -1;

    entry.delay = 0;
    entry.trackTime = 0;
    entry.trackLast = -1;
    entry.nextTrackLast = -1;
    entry.trackEnd = Float.MAX_VALUE;
    entry.timeScale = 1;

    entry.alpha = 1;
    entry.mixAlpha = 1;
    entry.mixTime = 0;
    entry.mixDuration = last == null ? 0 : data.getMix(last.animation, animation);
    return entry;
  }
  private void setCurrent(int index, TrackEntry current, boolean interrupt) {
    TrackEntry from = expandToIndex(index);
    tracks.set(index, current);

    if (from != null) {
      if (interrupt) queue.interrupt(from);
      current.mixingFrom = from;
      current.mixTime = 0;

      from.timelinesRotation.clear(); // Reset rotation for mixing out, in case entry was mixed in.

      // If not completely mixed in, set mixAlpha so mixing out happens from current mix to zero.
      if (from.mixingFrom != null && from.mixDuration > 0)
        current.mixAlpha *= Math.min(from.mixTime / from.mixDuration, 1);
    }

    queue.start(current);
  }