/** * Setup the view to a first person mode (zoom = 0) * * @param view the orbit view to set into a first person view. */ protected void setupFirstPersonView(OrbitView view) { if (view.getZoom() == 0) // already in first person mode return; Vec4 eyePoint = view.getEyePoint(); // Center pos at eye pos Position centerPosition = wwd.getModel().getGlobe().computePositionFromPoint(eyePoint); // Compute pitch and heading relative to center position Vec4 normal = wwd.getModel() .getGlobe() .computeSurfaceNormalAtLocation( centerPosition.getLatitude(), centerPosition.getLongitude()); Vec4 north = wwd.getModel() .getGlobe() .computeNorthPointingTangentAtLocation( centerPosition.getLatitude(), centerPosition.getLongitude()); // Pitch view.setPitch(Angle.POS180.subtract(view.getForwardVector().angleBetween3(normal))); // Heading Vec4 perpendicular = view.getForwardVector().perpendicularTo3(normal); Angle heading = perpendicular.angleBetween3(north); double direction = Math.signum(-normal.cross3(north).dot3(perpendicular)); view.setHeading(heading.multiply(direction)); // Zoom view.setZoom(0); // Center pos view.setCenterPosition(centerPosition); }
/** * Reset the view to an orbit view state if in first person mode (zoom = 0) * * @param view the orbit view to reset */ protected void resetOrbitView(OrbitView view) { if (view.getZoom() > 0) // already in orbit view mode return; // Find out where on the terrain the eye is looking at in the viewport center // TODO: if no terrain is found in the viewport center, iterate toward viewport bottom until it // is found Vec4 centerPoint = computeSurfacePoint(view, view.getHeading(), view.getPitch()); // Reset the orbit view center point heading, pitch and zoom if (centerPoint != null) { Vec4 eyePoint = view.getEyePoint(); // Center pos on terrain surface Position centerPosition = wwd.getModel().getGlobe().computePositionFromPoint(centerPoint); // Compute pitch and heading relative to center position Vec4 normal = wwd.getModel() .getGlobe() .computeSurfaceNormalAtLocation( centerPosition.getLatitude(), centerPosition.getLongitude()); Vec4 north = wwd.getModel() .getGlobe() .computeNorthPointingTangentAtLocation( centerPosition.getLatitude(), centerPosition.getLongitude()); // Pitch view.setPitch(Angle.POS180.subtract(view.getForwardVector().angleBetween3(normal))); // Heading Vec4 perpendicular = view.getForwardVector().perpendicularTo3(normal); Angle heading = perpendicular.angleBetween3(north); double direction = Math.signum(-normal.cross3(north).dot3(perpendicular)); view.setHeading(heading.multiply(direction)); // Zoom view.setZoom(eyePoint.distanceTo3(centerPoint)); // Center pos view.setCenterPosition(centerPosition); } }
protected void updateView(ScreenAnnotation control, String controlType) { if (this.wwd == null) return; if (!(this.wwd.getView() instanceof OrbitView)) return; OrbitView view = (OrbitView) this.wwd.getView(); view.stopAnimations(); view.stopMovement(); if (controlType.equals(AVKey.VIEW_PAN)) { resetOrbitView(view); // Go some distance in the control mouse direction Angle heading = computePanHeading(view, control); Angle distance = computePanAmount(this.wwd.getModel().getGlobe(), view, control, panStep); LatLon newViewCenter = LatLon.greatCircleEndPosition(view.getCenterPosition(), heading, distance); // Turn around if passing by a pole - TODO: better handling of the pole crossing situation if (this.isPathCrossingAPole(newViewCenter, view.getCenterPosition())) view.setHeading(Angle.POS180.subtract(view.getHeading())); // Set new center pos view.setCenterPosition(new Position(newViewCenter, view.getCenterPosition().getElevation())); } else if (controlType.equals(AVKey.VIEW_LOOK)) { setupFirstPersonView(view); Angle heading = computeLookHeading(view, control, headingStep); Angle pitch = computeLookPitch(view, control, pitchStep); // Check whether the view will still point at terrain Vec4 surfacePoint = computeSurfacePoint(view, heading, pitch); if (surfacePoint != null) { // Change view state final Position eyePos = view.getEyePosition(); // Save current eye position view.setHeading(heading); view.setPitch(pitch); view.setZoom(0); view.setCenterPosition(eyePos); // Set center at the eye position } } else if (controlType.equals(AVKey.VIEW_ZOOM_IN)) { resetOrbitView(view); view.setZoom(computeNewZoom(view, -zoomStep)); } else if (controlType.equals(AVKey.VIEW_ZOOM_OUT)) { resetOrbitView(view); view.setZoom(computeNewZoom(view, zoomStep)); } else if (controlType.equals(AVKey.VIEW_HEADING_LEFT)) { resetOrbitView(view); view.setHeading(view.getHeading().addDegrees(headingStep)); } else if (controlType.equals(AVKey.VIEW_HEADING_RIGHT)) { resetOrbitView(view); view.setHeading(view.getHeading().addDegrees(-headingStep)); } else if (controlType.equals(AVKey.VIEW_PITCH_UP)) { resetOrbitView(view); if (view.getPitch().degrees >= pitchStep) view.setPitch(view.getPitch().addDegrees(-pitchStep)); } else if (controlType.equals(AVKey.VIEW_PITCH_DOWN)) { resetOrbitView(view); if (view.getPitch().degrees <= 90 - pitchStep) view.setPitch(view.getPitch().addDegrees(pitchStep)); } else if (controlType.equals(AVKey.VIEW_FOV_NARROW)) { if (view.getFieldOfView().degrees / fovStep >= 4) view.setFieldOfView(view.getFieldOfView().divide(fovStep)); } else if (controlType.equals(AVKey.VIEW_FOV_WIDE)) { if (view.getFieldOfView().degrees * fovStep < 120) view.setFieldOfView(view.getFieldOfView().multiply(fovStep)); } else if (controlType.equals(AVKey.VERTICAL_EXAGGERATION_UP)) { SceneController sc = this.wwd.getSceneController(); sc.setVerticalExaggeration(sc.getVerticalExaggeration() + this.veStep); } else if (controlType.equals(AVKey.VERTICAL_EXAGGERATION_DOWN)) { SceneController sc = this.wwd.getSceneController(); sc.setVerticalExaggeration(Math.max(1d, sc.getVerticalExaggeration() - this.veStep)); } view.firePropertyChange(AVKey.VIEW, null, view); }