/*
Copyright (C) 2001, 2006 United States Government
as represented by the Administrator of the
National Aeronautics and Space Administration.
All Rights Reserved.
*/
package gov.nasa.worldwind.applications.sar;
import gov.nasa.worldwind.Movable;
import gov.nasa.worldwind.View;
import gov.nasa.worldwind.WorldWindow;
import gov.nasa.worldwind.event.DragSelectEvent;
import gov.nasa.worldwind.event.SelectEvent;
import gov.nasa.worldwind.event.SelectListener;
import gov.nasa.worldwind.geom.Intersection;
import gov.nasa.worldwind.geom.Line;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.geom.Vec4;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.util.Logging;
import java.awt.*;
/**
* @author tag
* @version $Id: BasicDragger2.java 4909 2008-04-03 22:40:05Z patrickmurris $
*/
public class BasicDragger2 implements SelectListener
{
private final WorldWindow wwd;
private boolean dragging = false;
private Point dragRefCursorPoint;
private Vec4 dragRefObjectPoint;
private double dragRefAltitude;
public BasicDragger2(WorldWindow wwd)
{
if (wwd == null)
{
String msg = Logging.getMessage("nullValue.WorldWindow");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
this.wwd = wwd;
}
public boolean isDragging()
{
return this.dragging;
}
public void selected(SelectEvent event)
{
if (event == null)
{
String msg = Logging.getMessage("nullValue.EventIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (event.getEventAction().equals(SelectEvent.DRAG_END))
{
this.dragging = false;
}
else if (event.getEventAction().equals(SelectEvent.DRAG))
{
DragSelectEvent dragEvent = (DragSelectEvent) event;
Object topObject = dragEvent.getTopObject();
if (topObject == null)
return;
if (!(topObject instanceof Movable))
return;
Movable dragObject = (Movable) topObject;
View view = wwd.getView();
Globe globe = wwd.getModel().getGlobe();
// Compute dragged object ref-point in model coordinates.
// Use the Icon and Annotation logic of elevation as offset above ground when below max elevation.
Position refPos = dragObject.getReferencePosition();
Vec4 refPoint = null;
if (refPos.getElevation() < globe.getMaxElevation())
refPoint = wwd.getSceneController().getTerrain().getSurfacePoint(refPos);
if (refPoint == null)
refPoint = globe.computePointFromPosition(refPos);
if (!this.isDragging()) // Dragging started
{
// Save initial reference points for object and cursor in screen coordinates
// Note: y is inverted for the object point.
this.dragRefObjectPoint = view.project(refPoint);
// Save cursor position
this.dragRefCursorPoint = dragEvent.getPreviousPickPoint();
// Save start altitude
this.dragRefAltitude = globe.computePositionFromPoint(refPoint).getElevation();
}
// Compute screen-coord delta since drag started.
int dx = dragEvent.getPickPoint().x - this.dragRefCursorPoint.x;
int dy = dragEvent.getPickPoint().y - this.dragRefCursorPoint.y;
// Find intersection of screen coord (refObjectPoint + delta) with globe.
double x = this.dragRefObjectPoint.x + dx;
double y = event.getMouseEvent().getComponent().getSize().height - this.dragRefObjectPoint.y + dy - 1;
Line ray = view.computeRayFromScreenPoint(x, y);
Position pickPos = null;
if (view.getEyePosition().getElevation() < globe.getMaxElevation() * 10)
{
// Use ray casting below some altitude
pickPos = RayCastingSupport.intersectRayWithTerrain(globe,
ray.getOrigin(), ray.getDirection(), 200, 20);
}
else
{
// Use intersection with sphere at reference altitude.
Intersection inters[] = globe.intersect(ray, this.dragRefAltitude);
if (inters != null)
pickPos = globe.computePositionFromPoint(inters[0].getIntersectionPoint());
}
if (pickPos != null)
{
// Intersection with globe. Move reference point to the intersection point,
// but maintain current altitude.
Position p = new Position( pickPos.getLatLon(), dragObject.getReferencePosition().getElevation());
dragObject.moveTo(p);
}
this.dragging = true;
}
}
}