gov.nasa.worldwind.view.firstperson.FlyViewInputHandler Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2012 United States Government as represented by the Administrator of the
* National Aeronautics and Space Administration.
* All Rights Reserved.
*/
package gov.nasa.worldwind.view.firstperson;
import gov.nasa.worldwind.*;
import gov.nasa.worldwind.animation.*;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.*;
import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.view.*;
import gov.nasa.worldwind.view.orbit.OrbitViewPropertyAccessor;
import java.awt.event.*;
/**
* @author jym
* @version $Id: FlyViewInputHandler.java 2179 2014-07-25 21:43:39Z dcollins $
*/
public class FlyViewInputHandler extends BasicViewInputHandler
{
public class ResetPitchActionListener extends ViewInputActionHandler
{
public boolean inputActionPerformed(AbstractViewInputHandler inputHandler, java.awt.event.KeyEvent event,
ViewInputAttributes.ActionAttributes viewAction)
{
java.util.List keyList = viewAction.getKeyActions();
for (Object k : keyList)
{
ViewInputAttributes.ActionAttributes.KeyAction keyAction =
(ViewInputAttributes.ActionAttributes.KeyAction) k;
if (event.getKeyCode() == keyAction.keyCode)
{
onResetPitch(viewAction);
return true;
}
}
return false;
}
}
/** Input handler to handle user input that changes Roll. */
public class RollActionListener extends ViewInputActionHandler
{
public boolean inputActionPerformed(AbstractViewInputHandler inputHandler, KeyEventState keys, String target,
ViewInputAttributes.ActionAttributes viewAction)
{
java.util.List keyList = viewAction.getKeyActions();
double rollInput = 0;
for (Object k : keyList)
{
ViewInputAttributes.ActionAttributes.KeyAction keyAction =
(ViewInputAttributes.ActionAttributes.KeyAction) k;
if (keys.isKeyDown(keyAction.keyCode))
{
rollInput += keyAction.sign;
}
}
if (rollInput == 0)
{
return false;
}
//noinspection StringEquality
if (target == GENERATE_EVENTS)
{
ViewInputAttributes.DeviceAttributes deviceAttributes =
inputHandler.getAttributes().getDeviceAttributes(ViewInputAttributes.DEVICE_KEYBOARD);
onRoll(rollInput, deviceAttributes, viewAction);
}
return true;
}
}
AnimationController uiAnimControl = new AnimationController();
AnimationController gotoAnimControl = new AnimationController();
protected static final String VIEW_ANIM_HEADING = "ViewAnimHeading";
protected static final String VIEW_ANIM_PITCH = "ViewAnimPitch";
protected static final String VIEW_ANIM_ROLL = "ViewAnimRoll";
protected static final String VIEW_ANIM_POSITION = "ViewAnimPosition";
protected static final String VIEW_ANIM_PAN = "ViewAnimPan";
protected static final String VIEW_ANIM_APP = "ViewAnimApp";
protected static final String ACTION_RESET_PITCH = "ResetPitch";
protected static final double DEFAULT_MOUSE_ROTATE_MIN_VALUE = 0.014; // Speed in degrees per mouse movement
protected static final double DEFAULT_MOUSE_ROTATE_MAX_VALUE = 0.018; // Speed in degrees per mouse movement
// Keyboard/Action calibration values for extensible view/navigation support
//protected static final double DEFAULT_KEY_HORIZONTAL_TRANSLATE_MIN_VALUE = 10;
protected static final double DEFAULT_KEY_TRANSLATE_SMOOTHING_VALUE = .9;
protected static final double DEFAULT_KEY_HORIZONTAL_TRANSLATE_MAX_VALUE = 1000000.0;
protected static final double DEFAULT_KEY_HORIZONTAL_TRANSLATE_MIN_VALUE = 100;
protected static final double DEFAULT_KEY_HORIZONTAL_TRANSLATE_MIN_VALUE_SLOW = 1;
protected static final double DEFAULT_KEY_HORIZONTAL_TRANSLATE_MAX_VALUE_SLOW = 100000.0;
protected static double DEFAULT_MOUSE_HORIZONTAL_TRANSLATE_MIN_VALUE = 5;
protected static double DEFAULT_MOUSE_HORIZONTAL_TRANSLATE_MAX_VALUE = 50000.0;
protected static final double DEFAULT_MOUSE_VERTICAL_TRANSLATE_MIN_VALUE = 1;
// Speed in log-meters per mouse movement
protected static final double DEFAULT_MOUSE_VERTICAL_TRANSLATE_MAX_VALUE = 30000;
// Speed in log-meters per mouse movement
protected static final double DEFAULT_KEY_VERTICAL_TRANSLATE_MIN_VALUE = 5;
protected static final double DEFAULT_KEY_VERTICAL_TRANSLATE_MAX_VALUE = 5000;
protected static final double DEFAULT_MOUSE_WHEEL_VERTICAL_TRANSLATE_VALUE_MIN_OSX = 10;
// Speed in log-meters per wheel movement
protected static final double DEFAULT_MOUSE_WHEEL_VERTICAL_TRANSLATE_VALUE_MAX_OSX = 900000;
// Speed in log-meters per wheel movement
protected static final double DEFAULT_MOUSE_WHEEL_VERTICAL_TRANSLATE_VALUE_MIN = 100;
// Speed in log-meters per wheel movement
protected static final double DEFAULT_MOUSE_WHEEL_VERTICAL_TRANSLATE_VALUE_MAX = 100000;
// Speed in log-meters per wheel movement
// Reset Heading
protected static final ViewInputAttributes.ActionAttributes.KeyAction
DEFAULT_RESET_PITCH_KEY_ACT =
new ViewInputAttributes.ActionAttributes.KeyAction(
KeyEvent.VK_P, ViewInputAttributes.ActionAttributes.KeyAction.KA_DIR_X, 1);
public static final ViewInputAttributes.ActionAttributes.KeyAction[] resetPitchEvents =
{
DEFAULT_RESET_PITCH_KEY_ACT
};
double speed = 10.0;
public FlyViewInputHandler()
{
// Mouse Button Horizontal Translate Events
// Button 1
this.getAttributes().setValues(ViewInputAttributes.DEVICE_MOUSE,
ViewInputAttributes.VIEW_HORIZONTAL_TRANSLATE,
DEFAULT_MOUSE_HORIZONTAL_TRANSLATE_MIN_VALUE, DEFAULT_MOUSE_HORIZONTAL_TRANSLATE_MAX_VALUE);
this.getAttributes().setActionTrigger(ViewInputAttributes.DEVICE_MOUSE,
ViewInputAttributes.VIEW_HORIZONTAL_TRANSLATE,
ViewInputAttributes.ActionAttributes.ActionTrigger.ON_KEY_DOWN);
// Mouse Button Rotate Events
// Button 1 + SHIFT
this.getAttributes().setValues(ViewInputAttributes.DEVICE_MOUSE, ViewInputAttributes.VIEW_ROTATE_SHIFT,
DEFAULT_MOUSE_ROTATE_MIN_VALUE,
DEFAULT_MOUSE_ROTATE_MAX_VALUE);
this.getAttributes().setActionTrigger(ViewInputAttributes.DEVICE_MOUSE,
ViewInputAttributes.VIEW_ROTATE_SHIFT,
ViewInputAttributes.ActionAttributes.ActionTrigger.ON_KEY_DOWN);
// Button 3
this.getAttributes().setValues(ViewInputAttributes.DEVICE_MOUSE, ViewInputAttributes.VIEW_ROTATE,
DEFAULT_MOUSE_ROTATE_MIN_VALUE,
DEFAULT_MOUSE_ROTATE_MAX_VALUE);
this.getAttributes().setActionTrigger(ViewInputAttributes.DEVICE_MOUSE,
ViewInputAttributes.VIEW_ROTATE,
ViewInputAttributes.ActionAttributes.ActionTrigger.ON_KEY_DOWN);
// Mouse Vertical Translate
// Button 2
this.getAttributes().setValues(ViewInputAttributes.DEVICE_MOUSE,
ViewInputAttributes.VIEW_VERTICAL_TRANSLATE, DEFAULT_MOUSE_VERTICAL_TRANSLATE_MIN_VALUE,
DEFAULT_MOUSE_VERTICAL_TRANSLATE_MAX_VALUE);
this.getAttributes().setActionTrigger(ViewInputAttributes.DEVICE_MOUSE,
ViewInputAttributes.VIEW_VERTICAL_TRANSLATE,
ViewInputAttributes.ActionAttributes.ActionTrigger.ON_KEY_DOWN);
// Button 1 + CTRL
this.getAttributes().setValues(ViewInputAttributes.DEVICE_MOUSE,
ViewInputAttributes.VIEW_VERTICAL_TRANSLATE_CTRL, DEFAULT_MOUSE_VERTICAL_TRANSLATE_MIN_VALUE,
DEFAULT_MOUSE_VERTICAL_TRANSLATE_MAX_VALUE);
this.getAttributes().setActionTrigger(ViewInputAttributes.DEVICE_MOUSE,
ViewInputAttributes.VIEW_VERTICAL_TRANSLATE_CTRL,
ViewInputAttributes.ActionAttributes.ActionTrigger.ON_KEY_DOWN);
// Arrow keys rotate
// ----------------------------------Key Roll --------------------------------------------
RollActionListener rollActionListener = new RollActionListener();
this.getAttributes().setActionListener(
ViewInputAttributes.DEVICE_KEYBOARD, ViewInputAttributes.VIEW_ROLL_KEYS, rollActionListener);
// Arrow Keys horizontal translate
this.getAttributes().setValues(ViewInputAttributes.DEVICE_KEYBOARD,
ViewInputAttributes.VIEW_HORIZONTAL_TRANS_KEYS,
DEFAULT_KEY_HORIZONTAL_TRANSLATE_MIN_VALUE,
DEFAULT_KEY_HORIZONTAL_TRANSLATE_MAX_VALUE);
this.getAttributes().getActionAttributes(ViewInputAttributes.DEVICE_KEYBOARD,
ViewInputAttributes.VIEW_HORIZONTAL_TRANS_KEYS).setSmoothingValue(DEFAULT_KEY_TRANSLATE_SMOOTHING_VALUE);
this.getAttributes().setValues(ViewInputAttributes.DEVICE_KEYBOARD,
ViewInputAttributes.VIEW_HORIZONTAL_TRANSLATE_SLOW,
DEFAULT_KEY_HORIZONTAL_TRANSLATE_MIN_VALUE_SLOW, DEFAULT_KEY_HORIZONTAL_TRANSLATE_MAX_VALUE_SLOW);
/*
this.getAttributes().setActionTrigger(ViewInputAttributes.DEVICE_KEYBOARD,
ViewInputAttributes.VIEW_HORIZONTAL_TRANSLATE_SLOW,
ViewInputAttributes.ActionAttributes.ActionTrigger.ON_KEY_DOWN);
*/
// +- Keys vertical translate
this.getAttributes().setValues(ViewInputAttributes.DEVICE_KEYBOARD,
ViewInputAttributes.VIEW_VERTICAL_TRANS_KEYS,
DEFAULT_KEY_VERTICAL_TRANSLATE_MIN_VALUE, DEFAULT_KEY_VERTICAL_TRANSLATE_MAX_VALUE);
// Arrow keys vertical translate
this.getAttributes().setValues(ViewInputAttributes.DEVICE_KEYBOARD,
ViewInputAttributes.VIEW_VERTICAL_TRANS_KEYS_META,
DEFAULT_KEY_VERTICAL_TRANSLATE_MIN_VALUE, DEFAULT_KEY_VERTICAL_TRANSLATE_MAX_VALUE);
this.getAttributes().setValues(ViewInputAttributes.DEVICE_KEYBOARD,
ViewInputAttributes.VIEW_VERTICAL_TRANS_KEYS_CTRL,
DEFAULT_KEY_VERTICAL_TRANSLATE_MIN_VALUE, DEFAULT_KEY_VERTICAL_TRANSLATE_MAX_VALUE);
// Mouse Wheel vertical translate
if (Configuration.isMacOS())
{
this.getAttributes().setValues(ViewInputAttributes.DEVICE_MOUSE_WHEEL,
ViewInputAttributes.VIEW_VERTICAL_TRANSLATE,
DEFAULT_MOUSE_WHEEL_VERTICAL_TRANSLATE_VALUE_MIN_OSX,
DEFAULT_MOUSE_WHEEL_VERTICAL_TRANSLATE_VALUE_MAX_OSX);
}
else
{
this.getAttributes().setValues(ViewInputAttributes.DEVICE_MOUSE_WHEEL,
ViewInputAttributes.VIEW_VERTICAL_TRANSLATE,
DEFAULT_MOUSE_WHEEL_VERTICAL_TRANSLATE_VALUE_MIN,
DEFAULT_MOUSE_WHEEL_VERTICAL_TRANSLATE_VALUE_MAX);
}
// P Key Reset Pitch
this.getAttributes().addAction(ViewInputAttributes.DEVICE_KEYBOARD,
ViewInputAttributes.ActionAttributes.NO_MODIFIER, ACTION_RESET_PITCH,
new ViewInputAttributes.ActionAttributes(resetPitchEvents,
ViewInputAttributes.ActionAttributes.ActionTrigger.ON_PRESS, 0,
0.1, 0.1, false, 0.1));
// Reset Pitch
ViewInputAttributes.ActionAttributes actionAttrs =
this.getAttributes().getActionMap(ViewInputAttributes.DEVICE_KEYBOARD).getActionAttributes(
ACTION_RESET_PITCH);
actionAttrs.setActionListener(new ResetPitchActionListener());
}
protected void onMoveTo(Position focalPosition,
ViewInputAttributes.DeviceAttributes deviceAttributes,
ViewInputAttributes.ActionAttributes actionAttribs)
{
BasicFlyView view = (BasicFlyView) this.getView();
if (view == null) // include this test to ensure any derived implementation performs it
{
return;
}
// We're treating a speed parameter as smoothing here. A greater speed results in greater smoothing and
// slower response. Therefore the min speed used at lower altitudes ought to be *greater* than the max
// speed used at higher altitudes.
double smoothing = this.getScaleValueElevation(deviceAttributes, actionAttribs);
if (!actionAttribs.isEnableSmoothing())
smoothing = 0.0;
Vec4 currentLookAtPt = view.getCenterPoint();
if (currentLookAtPt == null)
{
currentLookAtPt = view.
getGlobe().computePointFromPosition(focalPosition);
}
Vec4 currentEyePt = view.getEyePoint();
double distanceToSurface = currentEyePt.distanceTo3(currentLookAtPt);
Vec4 lookDirection = currentEyePt.subtract3(currentLookAtPt).normalize3();
Vec4 newLookAtPt = view.getGlobe().computePointFromPosition(focalPosition);
Vec4 flyToPoint = newLookAtPt.add3(lookDirection.multiply3(distanceToSurface));
Position newPosition = view.getGlobe().computePositionFromPoint(flyToPoint);
ViewUtil.ViewState viewCoords = view.getViewState(newPosition, focalPosition);
this.stopAnimators();
this.gotoAnimControl.put(VIEW_ANIM_HEADING,
new RotateToAngleAnimator(
view.getHeading(), viewCoords.getHeading(), smoothing,
ViewPropertyAccessor.createHeadingAccessor(view)));
this.gotoAnimControl.put(VIEW_ANIM_PITCH,
new RotateToAngleAnimator(
view.getPitch(), viewCoords.getPitch(), smoothing,
ViewPropertyAccessor.createPitchAccessor(view)));
double elevation = ((FlyViewLimits)
view.getViewPropertyLimits()).limitEyeElevation(
newPosition, view.getGlobe());
if (elevation != newPosition.getElevation())
{
newPosition = new Position(newPosition, elevation);
}
this.gotoAnimControl.put(VIEW_ANIM_POSITION,
new MoveToPositionAnimator(
view.getEyePosition(), newPosition, smoothing,
ViewPropertyAccessor.createEyePositionAccessor(view)));
view.firePropertyChange(AVKey.VIEW, null, view);
}
protected void onHorizontalTranslateRel(double forwardInput, double sideInput,
double totalForwardInput, double totalSideInput,
ViewInputAttributes.DeviceAttributes deviceAttributes,
ViewInputAttributes.ActionAttributes actionAttributes)
{
Angle forwardChange;
Angle sideChange;
this.stopGoToAnimators();
if (actionAttributes.getMouseActions() != null)
{
forwardChange = Angle.fromDegrees(-totalForwardInput
* getScaleValueElevation(deviceAttributes, actionAttributes));
sideChange = Angle.fromDegrees(totalSideInput
* getScaleValueElevation(deviceAttributes, actionAttributes));
}
else
{
forwardChange = Angle.fromDegrees(
forwardInput * speed * getScaleValueElevation(deviceAttributes, actionAttributes));
sideChange = Angle.fromDegrees(
sideInput * speed * getScaleValueElevation(deviceAttributes, actionAttributes));
}
onHorizontalTranslateRel(forwardChange, sideChange, actionAttributes);
}
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);
}
}
protected void onResetHeading(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_HEADING,
new RotateToAngleAnimator(
view.getHeading(), Angle.ZERO, smoothing,
ViewPropertyAccessor.createHeadingAccessor(view)));
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 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);
}
protected void onRotateView(double headingInput, double pitchInput,
double totalHeadingInput, double totalPitchInput,
ViewInputAttributes.DeviceAttributes deviceAttributes,
ViewInputAttributes.ActionAttributes actionAttributes)
{
Angle headingChange;
Angle pitchChange;
this.stopGoToAnimators();
headingChange = Angle.fromDegrees(
totalHeadingInput * getScaleValueElevation(deviceAttributes, actionAttributes));
pitchChange = Angle.fromDegrees(
totalPitchInput * getScaleValueElevation(deviceAttributes, actionAttributes));
onRotateView(headingChange, pitchChange, actionAttributes);
}
protected void onRotateView(Angle headingChange, Angle pitchChange,
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.setPitch(flyView, this.uiAnimControl, flyView.getPitch().add(pitchChange),
actionAttribs);
this.setHeading(flyView, this.uiAnimControl, flyView.getHeading().add(headingChange),
actionAttribs);
view.firePropertyChange(AVKey.VIEW, null, view);
}
}
/**
* Called when the roll changes due to user input.
*
* @param rollInput Change in roll.
* @param deviceAttributes Attributes of the input device.
* @param actionAttributes Action that caused the change.
*/
protected void onRoll(double rollInput, ViewInputAttributes.DeviceAttributes deviceAttributes,
ViewInputAttributes.ActionAttributes actionAttributes)
{
Angle rollChange;
this.stopGoToAnimators();
rollChange = Angle.fromDegrees(rollInput * getScaleValueElevation(deviceAttributes, actionAttributes));
this.onRoll(rollChange, actionAttributes);
}
/**
* 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);
}
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);
}
}
protected void handleViewStopped()
{
this.stopAnimators();
}
protected void setHeading(View view,
AnimationController animControl,
Angle heading, ViewInputAttributes.ActionAttributes attrib)
{
double smoothing = attrib.getSmoothingValue();
if (!(attrib.isEnableSmoothing() && this.isEnableSmoothing()))
smoothing = 0.0;
AngleAnimator angleAnimator = new RotateToAngleAnimator(
view.getHeading(), heading, smoothing,
ViewPropertyAccessor.createHeadingAccessor(view));
animControl.put(VIEW_ANIM_HEADING, angleAnimator);
}
protected void setPitch(View view,
AnimationController animControl,
Angle pitch, ViewInputAttributes.ActionAttributes attrib)
{
double smoothing = attrib.getSmoothingValue();
if (!(attrib.isEnableSmoothing() && this.isEnableSmoothing()))
smoothing = 0.0;
AngleAnimator angleAnimator = new RotateToAngleAnimator(
view.getPitch(), pitch, smoothing,
ViewPropertyAccessor.createPitchAccessor(view));
animControl.put(VIEW_ANIM_PITCH, angleAnimator);
}
/**
* 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);
}
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);
}
public void goTo(Position lookAtPos, double distance)
{
Globe globe = this.getView().getGlobe();
BasicFlyView view = (BasicFlyView) this.getView();
Position lookFromPos = new Position(lookAtPos,
globe.getElevation(lookAtPos.getLatitude(), lookAtPos.getLongitude()) + distance);
// TODO: scale on mid-altitude?
final long MIN_LENGTH_MILLIS = 4000;
final long MAX_LENGTH_MILLIS = 16000;
long timeToMove = AnimationSupport.getScaledTimeMillisecs(
view.getEyePosition(), lookFromPos,
MIN_LENGTH_MILLIS, MAX_LENGTH_MILLIS);
FlyToFlyViewAnimator panAnimator = FlyToFlyViewAnimator.createFlyToFlyViewAnimator(view,
view.getEyePosition(), lookFromPos,
view.getHeading(), Angle.ZERO,
view.getPitch(), Angle.ZERO,
view.getEyePosition().getElevation(), lookFromPos.getElevation(),
timeToMove, WorldWind.ABSOLUTE);
this.gotoAnimControl.put(VIEW_ANIM_PAN, panAnimator);
this.getView().firePropertyChange(AVKey.VIEW, null, this.getView());
}
public void lookAt(Position lookAtPos, long timeToMove)
{
BasicFlyView view = (BasicFlyView) this.getView();
Vec4 lookDirection;
double distanceToSurface;
Vec4 currentLookAtPt = view.getCenterPoint();
Position newPosition;
if (currentLookAtPt == null)
{
view.getGlobe().computePointFromPosition(lookAtPos);
double elevAtLookAtPos = view.getGlobe().getElevation(
lookAtPos.getLatitude(), lookAtPos.getLongitude());
newPosition = new Position(lookAtPos, elevAtLookAtPos + 10000);
}
else
{
Vec4 currentEyePt = view.getEyePoint();
distanceToSurface = currentEyePt.distanceTo3(currentLookAtPt);
lookDirection = currentLookAtPt.subtract3(currentEyePt).normalize3();
Vec4 newLookAtPt = view.getGlobe().computePointFromPosition(lookAtPos);
Vec4 flyToPoint = newLookAtPt.add3(lookDirection.multiply3(-distanceToSurface));
newPosition = view.getGlobe().computePositionFromPoint(flyToPoint);
}
ViewUtil.ViewState viewCoords = view.getViewState(newPosition, lookAtPos);
FlyToFlyViewAnimator panAnimator = FlyToFlyViewAnimator.createFlyToFlyViewAnimator(view,
view.getEyePosition(), newPosition,
view.getHeading(), viewCoords.getHeading(),
view.getPitch(), viewCoords.getPitch(),
view.getEyePosition().getElevation(), viewCoords.getPosition().getElevation(),
timeToMove, WorldWind.ABSOLUTE);
this.gotoAnimControl.put(VIEW_ANIM_PAN, panAnimator);
this.getView().firePropertyChange(AVKey.VIEW, null, this.getView());
view.firePropertyChange(AVKey.VIEW, null, view);
}
public void stopAnimators()
{
this.stopGoToAnimators();
this.stopUserInputAnimators();
}
public boolean isAnimating()
{
return (this.uiAnimControl.hasActiveAnimation() || this.gotoAnimControl.hasActiveAnimation());
}
public void addAnimator(Animator animator)
{
this.gotoAnimControl.put(VIEW_ANIM_APP, animator);
}
protected void stopGoToAnimators()
{
// Explicitly stop all 'go to' animators, then clear the data structure which holds them. If we remove an
// animator from this data structure without invoking stop(), the animator has no way of knowing it was forcibly
// stopped. An animator's owner - likely an application object other - may need to know if an animator has been
// forcibly stopped in order to react correctly to that event.
this.gotoAnimControl.stopAnimations();
this.gotoAnimControl.clear();
}
protected void stopUserInputAnimators()
{
// Explicitly stop all 'ui' animator, then clear the data structure which holds them. If we remove an animator
// from this data structure without invoking stop(), the animator has no way of knowing it was forcibly stopped.
// Though applications cannot access the 'ui' animator data structure, stopping the animators here is the correct
// action.
this.uiAnimControl.stopAnimations();
this.uiAnimControl.clear();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy