/*
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.render;
import gov.nasa.worldwind.avlist.*;
import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.globes.*;
import gov.nasa.worldwind.pick.*;
import gov.nasa.worldwind.tracks.*;
import gov.nasa.worldwind.util.*;
import javax.media.opengl.*;
import java.util.*;
/**
* @author tag
* @version $Id: TrackRenderer.java 4521 2008-02-20 00:45:39Z tgaskins $
*/
public class TrackRenderer extends LocationRenderer
{
private double markerPixels = 8d; // TODO: these should all be configurable
private double minMarkerSize = 3d;
private Material material = Material.WHITE;
private String iconFilePath;
private LocationRenderer.Shape shape = SPHERE;
public TrackRenderer()
{
}
public double getMarkerPixels()
{
return markerPixels;
}
public void setMarkerPixels(double markerPixels)
{
this.markerPixels = markerPixels;
}
public double getMinMarkerSize()
{
return minMarkerSize;
}
public void setMinMarkerSize(double minMarkerSize)
{
this.minMarkerSize = minMarkerSize;
}
public Material getMaterial()
{
return material;
}
public void setMaterial(Material material)
{
if (material == null)
{
String msg = Logging.getMessage("nullValue.MaterialIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
// don't validate material's colors - material does that.
this.material = material;
}
public String getIconFilePath()
{
return iconFilePath;
}
public void setIconFilePath(String iconFilePath)
{
//don't validate - a null iconFilePath cancels icon drawing
this.iconFilePath = iconFilePath;
}
public void setShapeType(String shapeName)
{
if (shapeName.equalsIgnoreCase("Cone"))
this.shape = CONE;
else if (shapeName.equalsIgnoreCase("Cylinder"))
this.shape = CYLINDER;
else
this.shape = SPHERE;
}
protected Vec4 draw(DrawContext dc, Iterator<TrackPoint> trackPositions)
{
if (dc.getVisibleSector() == null)
return null;
SectorGeometryList geos = dc.getSurfaceGeometry();
if (geos == null)
return null;
if (!this.shape.isInitialized)
this.shape.initialize(dc);
Vec4 lastPointDrawn = null;
this.begin(dc);
{
if (!dc.isPickingMode())
this.material.apply(dc.getGL(), GL.GL_FRONT);
Vec4 previousDrawnPoint = null;
double radius;
for (int index = 0; trackPositions.hasNext(); index++)
{
TrackPoint tp = trackPositions.next();
if (index < this.lowerLimit)
continue;
if (index > this.upperLimit)
break;
Vec4 point = this.computeSurfacePoint(dc, tp);
if (point == null)
continue;
if (dc.isPickingMode())
{
java.awt.Color color = dc.getUniquePickColor();
int colorCode = color.getRGB();
PickedObject po = new PickedObject(colorCode,
this.getClient() != null ? this.getClient() : tp.getPosition(), tp.getPosition(), false);
po.setValue(AVKey.PICKED_OBJECT_ID, index);
this.pickSupport.addPickableObject(po);
dc.getGL().glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue());
}
radius = this.computeMarkerRadius(dc, point);
if (previousDrawnPoint == null)
{
// It's the first point drawn
previousDrawnPoint = point;
this.shape.render(dc, point, radius);
lastPointDrawn = point;
continue;
}
double separation = point.distanceTo3(previousDrawnPoint);
double minSeparation = 4d * radius;
if (separation > minSeparation)
{
previousDrawnPoint = point;
this.shape.render(dc, point, radius);
lastPointDrawn = point;
}
}
}
this.end(dc);
return lastPointDrawn;
}
//
// protected Vec4 doDrawPoints(DrawContext dc, List<Vec4> points)
// {
// Vec4 lastPointDrawn = null;
//
// double radius = this.minMarkerSize;
// for (Vec4 point : points)
// {
// this.shape.render(dc, point, radius);
// lastPointDrawn = point;
// }
//
// return lastPointDrawn;
// }
private double computeMarkerRadius(DrawContext dc, Vec4 point)
{
double d = point.distanceTo3(dc.getView().getEyePoint());
double radius = this.markerPixels * dc.getView().computePixelSizeAtDistance(d);
if (radius < this.minMarkerSize)
radius = this.minMarkerSize;
return radius;
}
}