예제 #1
0
  protected KeyFrameInterpolator(KeyFrameInterpolator otherKFI) {
    this.gScene = otherKFI.gScene;
    this.path = new ArrayList<Frame>();
    ListIterator<Frame> frameIt = otherKFI.path.listIterator();
    while (frameIt.hasNext()) {
      this.path.add(frameIt.next().get());
    }

    this.setFrame(otherKFI.frame());

    this.period = otherKFI.period;
    this.interpolationTm = otherKFI.interpolationTm;
    this.interpolationSpd = otherKFI.interpolationSpd;
    this.interpolationStrt = otherKFI.interpolationStrt;
    this.lpInterpolation = otherKFI.lpInterpolation;
    this.pathIsValid = otherKFI.pathIsValid;
    this.valuesAreValid = otherKFI.valuesAreValid;
    this.currentFrmValid = otherKFI.currentFrmValid;

    this.keyFrameList = new ArrayList<KeyFrame>();

    for (KeyFrame element : otherKFI.keyFrameList) {
      KeyFrame kf = (KeyFrame) element.get();
      this.keyFrameList.add(kf);
    }

    this.currentFrame0 = keyFrameList.listIterator(otherKFI.currentFrame0.nextIndex());
    this.currentFrame1 = keyFrameList.listIterator(otherKFI.currentFrame1.nextIndex());
    this.currentFrame2 = keyFrameList.listIterator(otherKFI.currentFrame2.nextIndex());
    this.currentFrame3 = keyFrameList.listIterator(otherKFI.currentFrame3.nextIndex());

    this.interpolationTimerTask =
        new TimingTask() {
          public void execute() {
            update();
          }
        };
    gScene.registerTimingTask(interpolationTimerTask);

    this.invalidateValues();
  }
예제 #2
0
 protected void updateSplineCache() {
   Vec deltaP =
       Vec.subtract(
           keyFrameList.get(currentFrame2.nextIndex()).position(),
           keyFrameList.get(currentFrame1.nextIndex()).position());
   pv1 =
       Vec.add(
           Vec.multiply(deltaP, 3.0f),
           Vec.multiply(keyFrameList.get(currentFrame1.nextIndex()).tgP(), (-2.0f)));
   pv1 = Vec.subtract(pv1, keyFrameList.get(currentFrame2.nextIndex()).tgP());
   pv2 = Vec.add(Vec.multiply(deltaP, (-2.0f)), keyFrameList.get(currentFrame1.nextIndex()).tgP());
   pv2 = Vec.add(pv2, keyFrameList.get(currentFrame2.nextIndex()).tgP());
   splineCacheIsValid = true;
 }
예제 #3
0
  /**
   * Interpolate {@link #frame()} at time {@code time} (expressed in seconds). {@link
   * #interpolationTime()} is set to {@code time} and {@link #frame()} is set accordingly.
   *
   * <p>If you simply want to change {@link #interpolationTime()} but not the {@link #frame()}
   * state, use {@link #setInterpolationTime(float)} instead.
   */
  public void interpolateAtTime(float time) {
    this.checkValidity();
    setInterpolationTime(time);

    if ((keyFrameList.isEmpty()) || (frame() == null)) return;

    if (!valuesAreValid) updateModifiedFrameValues();

    updateCurrentKeyFrameForTime(time);

    if (!splineCacheIsValid) updateSplineCache();

    float alpha;
    float dt =
        keyFrameList.get(currentFrame2.nextIndex()).time()
            - keyFrameList.get(currentFrame1.nextIndex()).time();
    if (Util.zero(dt)) alpha = 0.0f;
    else alpha = (time - keyFrameList.get(currentFrame1.nextIndex()).time()) / dt;

    Vec pos =
        Vec.add(
            keyFrameList.get(currentFrame1.nextIndex()).position(),
            Vec.multiply(
                Vec.add(
                    keyFrameList.get(currentFrame1.nextIndex()).tgP(),
                    Vec.multiply(Vec.add(pv1, Vec.multiply(pv2, alpha)), alpha)),
                alpha));

    float mag =
        Util.lerp(
            keyFrameList.get(currentFrame1.nextIndex()).magnitude(),
            keyFrameList.get(currentFrame2.nextIndex()).magnitude(),
            alpha);

    Rotation q;
    if (gScene.is3D()) {
      q =
          Quat.squad(
              (Quat) keyFrameList.get(currentFrame1.nextIndex()).orientation(),
              ((KeyFrame3D) keyFrameList.get(currentFrame1.nextIndex())).tgQ(),
              ((KeyFrame3D) keyFrameList.get(currentFrame2.nextIndex())).tgQ(),
              (Quat) keyFrameList.get(currentFrame2.nextIndex()).orientation(),
              alpha);
    } else {
      q =
          new Rot(
              Util.lerp(
                  keyFrameList.get(currentFrame1.nextIndex()).orientation().angle(),
                  keyFrameList.get(currentFrame2.nextIndex()).orientation().angle(),
                  (alpha)));
    }

    frame().setPositionWithConstraint(pos);
    frame().setRotationWithConstraint(q);
    frame().setMagnitude(mag);
  }
예제 #4
0
  protected void updateCurrentKeyFrameForTime(float time) {
    // Assertion: times are sorted in monotone order.
    // Assertion: keyFrame_ is not empty

    // TODO: Special case for loops when closed path is implemented !!
    if (!currentFrmValid)
      // Recompute everything from scratch
      currentFrame1 = keyFrameList.listIterator();

    // currentFrame_[1]->peekNext() <---> keyFr.get(currentFrame1.nextIndex());
    while (keyFrameList.get(currentFrame1.nextIndex()).time() > time) {
      currentFrmValid = false;
      if (!currentFrame1.hasPrevious()) break;
      currentFrame1.previous();
    }

    if (!currentFrmValid) currentFrame2 = keyFrameList.listIterator(currentFrame1.nextIndex());

    while (keyFrameList.get(currentFrame2.nextIndex()).time() < time) {
      currentFrmValid = false;

      if (!currentFrame2.hasNext()) break;

      currentFrame2.next();
    }

    if (!currentFrmValid) {
      currentFrame1 = keyFrameList.listIterator(currentFrame2.nextIndex());

      if ((currentFrame1.hasPrevious())
          && (time < keyFrameList.get(currentFrame2.nextIndex()).time())) currentFrame1.previous();

      currentFrame0 = keyFrameList.listIterator(currentFrame1.nextIndex());

      if (currentFrame0.hasPrevious()) currentFrame0.previous();

      currentFrame3 = keyFrameList.listIterator(currentFrame2.nextIndex());

      if (currentFrame3.hasNext()) currentFrame3.next();

      currentFrmValid = true;
      splineCacheIsValid = false;
    }
  }