protected void setEyePosition(
      AnimationController animControl,
      View view,
      Position position,
      ViewInputAttributes.ActionAttributes attrib) {

    MoveToPositionAnimator posAnimator =
        (MoveToPositionAnimator) animControl.get(VIEW_ANIM_POSITION);

    double smoothing = attrib.getSmoothingValue();
    if (!(attrib.isEnableSmoothing() && this.isEnableSmoothing())) smoothing = 0.0;

    if (smoothing != 0.0) {

      double elevation =
          ((FlyViewLimits) view.getViewPropertyLimits())
              .limitEyeElevation(position, view.getGlobe());
      if (elevation != position.getElevation()) {
        position = new Position(position, elevation);
      }
      if (posAnimator == null) {
        posAnimator =
            new MoveToPositionAnimator(
                view.getEyePosition(),
                position,
                smoothing,
                OrbitViewPropertyAccessor.createEyePositionAccessor(view));
        animControl.put(VIEW_ANIM_POSITION, posAnimator);
      } else {
        posAnimator.setEnd(position);
        posAnimator.start();
      }
    }
    view.firePropertyChange(AVKey.VIEW, null, view);
  }
 protected void onResetHeadingPitchRoll(ViewInputAttributes.ActionAttributes actionAttribs) {
   View view = this.getView();
   if (view == null) // include this test to ensure any derived implementation performs it
   {
     return;
   }
   double smoothing = 0.95;
   this.gotoAnimControl.put(
       VIEW_ANIM_HEADING,
       new RotateToAngleAnimator(
           view.getHeading(),
           Angle.ZERO,
           smoothing,
           ViewPropertyAccessor.createHeadingAccessor(view)));
   this.gotoAnimControl.put(
       VIEW_ANIM_PITCH,
       new RotateToAngleAnimator(
           view.getPitch(),
           Angle.POS90,
           smoothing,
           ViewPropertyAccessor.createPitchAccessor(view)));
   this.gotoAnimControl.put(
       VIEW_ANIM_ROLL,
       new RotateToAngleAnimator(
           view.getPitch(), Angle.ZERO, smoothing, ViewPropertyAccessor.createRollAccessor(view)));
   view.firePropertyChange(AVKey.VIEW, null, view);
 }
  public void apply() {
    super.apply();

    View view = this.getView();
    if (view == null) {
      return;
    }
    if (this.gotoAnimControl.stepAnimators()) {
      view.firePropertyChange(AVKey.VIEW, null, view);
    }
    if (this.uiAnimControl.stepAnimators()) {
      view.firePropertyChange(AVKey.VIEW, null, view);
    }
  }
  /**
   * Called when the roll changes due to user input.
   *
   * @param rollChange Change in roll.
   * @param actionAttribs Action that caused the change.
   */
  protected void onRoll(Angle rollChange, ViewInputAttributes.ActionAttributes actionAttribs) {
    View view = this.getView();
    if (view == null) // include this test to ensure any derived implementation performs it
    {
      return;
    }

    if (view instanceof BasicFlyView) {
      BasicFlyView flyView = (BasicFlyView) view;
      this.setRoll(flyView, this.uiAnimControl, flyView.getRoll().add(rollChange), actionAttribs);

      view.firePropertyChange(AVKey.VIEW, null, view);
    }
  }
  protected void onVerticalTranslate(
      double translateChange,
      double totalTranslateChange,
      ViewInputAttributes.DeviceAttributes deviceAttributes,
      ViewInputAttributes.ActionAttributes actionAttribs) {
    this.stopGoToAnimators();
    double elevChange =
        -(totalTranslateChange * getScaleValueElevation(deviceAttributes, actionAttribs));
    View view = this.getView();
    Position position = view.getEyePosition();
    Position newPos = new Position(position, position.getElevation() + (elevChange));
    this.setEyePosition(uiAnimControl, view, newPos, actionAttribs);

    view.firePropertyChange(AVKey.VIEW, null, view);
  }
  protected void onResetPitch(ViewInputAttributes.ActionAttributes actionAttribs) {

    View view = this.getView();
    if (view == null) // include this test to ensure any derived implementation performs it
    {
      return;
    }
    double smoothing = actionAttribs.getSmoothingValue();
    if (!(actionAttribs.isEnableSmoothing() && this.isEnableSmoothing())) smoothing = 0.0;
    this.gotoAnimControl.put(
        VIEW_ANIM_PITCH,
        new RotateToAngleAnimator(
            view.getPitch(),
            Angle.POS90,
            smoothing,
            ViewPropertyAccessor.createPitchAccessor(view)));
    view.firePropertyChange(AVKey.VIEW, null, view);
  }
  protected void onHorizontalTranslateRel(
      Angle forwardChange, Angle sideChange, ViewInputAttributes.ActionAttributes actionAttribs) {
    View view = this.getView();
    if (view == null) // include this test to ensure any derived implementation performs it
    {
      return;
    }

    if (forwardChange.equals(Angle.ZERO) && sideChange.equals(Angle.ZERO)) {
      return;
    }

    if (view instanceof BasicFlyView) {

      Vec4 forward = view.getForwardVector();
      Vec4 up = view.getUpVector();
      Vec4 side = forward.transformBy3(Matrix.fromAxisAngle(Angle.fromDegrees(90), up));

      forward = forward.multiply3(forwardChange.getDegrees());
      side = side.multiply3(sideChange.getDegrees());
      Vec4 eyePoint = view.getEyePoint();
      eyePoint = eyePoint.add3(forward.add3(side));
      Position newPosition = view.getGlobe().computePositionFromPoint(eyePoint);

      this.setEyePosition(this.uiAnimControl, view, newPosition, actionAttribs);
      view.firePropertyChange(AVKey.VIEW, null, view);
    }
  }
  /**
   * Set the roll in a view.
   *
   * @param view View to modify.
   * @param animControl Animator controller for the view.
   * @param roll new roll value.
   * @param attrib action that caused the roll to change.
   */
  protected void setRoll(
      View view,
      AnimationController animControl,
      Angle roll,
      ViewInputAttributes.ActionAttributes attrib) {
    double smoothing = attrib.getSmoothingValue();
    if (!(attrib.isEnableSmoothing() && this.isEnableSmoothing())) smoothing = 0.0;

    AngleAnimator angleAnimator =
        new RotateToAngleAnimator(
            view.getRoll(), roll, smoothing, ViewPropertyAccessor.createRollAccessor(view));
    animControl.put(VIEW_ANIM_ROLL, angleAnimator);
  }