gov.nasa.worldwind.render.airspaces.CappedEllipticalCylinder Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2015 United States Government as represented by the Administrator of the
* National Aeronautics and Space Administration.
* All Rights Reserved.
*/
package gov.nasa.worldwind.render.airspaces;
import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.geom.Box;
import gov.nasa.worldwind.geom.Cylinder;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.render.*;
import gov.nasa.worldwind.util.*;
import com.jogamp.opengl.*;
import java.util.*;
/**
* An elliptical cylinder defined by a geographic position, major and minor radii in meters, and minimum and maximum
* altitudes.
*
* @author tag
* @version $Id: CappedEllipticalCylinder.java 3424 2015-09-29 19:34:00Z tgaskins $
*/
public class CappedEllipticalCylinder extends AbstractAirspace
{
protected static final int DEFAULT_SLICES = 32;
protected static final int DEFAULT_STACKS = 1;
protected static final int DEFAULT_LOOPS = 8;
protected static final int MINIMAL_GEOMETRY_SLICES = 8;
protected static final int MINIMAL_GEOMETRY_LOOPS = 4;
protected LatLon center = LatLon.ZERO;
protected double innerMinorRadius = 0.0;
protected double outerMinorRadius = 1.0;
protected double innerMajorRadius = 0.0;
protected double outerMajorRadius = 1.0;
protected Angle heading = Angle.ZERO;
protected boolean enableCaps = true;
protected int slices = DEFAULT_SLICES;
protected final int stacks = DEFAULT_STACKS;
protected int loops = DEFAULT_LOOPS;
public CappedEllipticalCylinder(LatLon location, double minorRadius, double majorRadius, Angle heading)
{
if (location == null)
{
String message = Logging.getMessage("nullValue.LatLonIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (minorRadius < 0 | majorRadius < 0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", "minor radius=" + minorRadius);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (majorRadius < 0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", "major radius=" + majorRadius);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.center = location;
this.outerMinorRadius = minorRadius;
this.outerMajorRadius = majorRadius;
this.heading = heading;
this.makeDefaultDetailLevels();
}
public CappedEllipticalCylinder(CappedEllipticalCylinder source)
{
super(source);
this.center = source.center;
this.innerMinorRadius = source.innerMinorRadius;
this.outerMinorRadius = source.outerMinorRadius;
this.innerMajorRadius = source.innerMajorRadius;
this.outerMajorRadius = source.outerMajorRadius;
this.heading = source.heading;
this.enableCaps = source.enableCaps;
this.slices = source.slices;
this.loops = source.loops;
this.makeDefaultDetailLevels();
}
public CappedEllipticalCylinder(AirspaceAttributes attributes)
{
super(attributes);
this.makeDefaultDetailLevels();
}
public CappedEllipticalCylinder()
{
this.makeDefaultDetailLevels();
}
private void makeDefaultDetailLevels()
{
List levels = new ArrayList();
double[] ramp = ScreenSizeDetailLevel.computeDefaultScreenSizeRamp(5);
DetailLevel level;
level = new ScreenSizeDetailLevel(ramp[0], "Detail-Level-0");
level.setValue(SLICES, 32);
level.setValue(STACKS, 1);
level.setValue(LOOPS, 8);
level.setValue(DISABLE_TERRAIN_CONFORMANCE, false);
levels.add(level);
level = new ScreenSizeDetailLevel(ramp[1], "Detail-Level-1");
level.setValue(SLICES, 26);
level.setValue(STACKS, 1);
level.setValue(LOOPS, 6);
level.setValue(DISABLE_TERRAIN_CONFORMANCE, false);
levels.add(level);
level = new ScreenSizeDetailLevel(ramp[2], "Detail-Level-2");
level.setValue(SLICES, 20);
level.setValue(STACKS, 1);
level.setValue(LOOPS, 4);
level.setValue(DISABLE_TERRAIN_CONFORMANCE, false);
levels.add(level);
level = new ScreenSizeDetailLevel(ramp[3], "Detail-Level-3");
level.setValue(SLICES, 14);
level.setValue(STACKS, 1);
level.setValue(LOOPS, 2);
level.setValue(DISABLE_TERRAIN_CONFORMANCE, false);
levels.add(level);
level = new ScreenSizeDetailLevel(ramp[4], "Detail-Level-4");
level.setValue(SLICES, 14);
level.setValue(STACKS, 1);
level.setValue(LOOPS, 1);
level.setValue(DISABLE_TERRAIN_CONFORMANCE, true);
levels.add(level);
this.setDetailLevels(levels);
}
/**
* Returns the geographic location of the cylinder's center.
*
* @return the cylinder's center
*/
public LatLon getCenter()
{
return this.center;
}
/**
* Sets the cylinder's center.
*
* @param location the geographic position (latitude and longitude) of the cylinder's center.
*
* @throws IllegalArgumentException if the location is null.
*/
public void setCenter(LatLon location)
{
if (location == null)
{
String message = Logging.getMessage("nullValue.LatLonIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.center = location;
this.invalidateAirspaceData();
}
/**
* Returns the cylinder's radii, in meters.
*
* @return the cylinder's radii, in meters. The returned array contains the inner minor radius, inner major radius,
* outer minor radius and outer major radius, in that order.
*/
public double[] getRadii()
{
double[] array = new double[4];
array[0] = this.innerMinorRadius;
array[1] = this.innerMajorRadius;
array[2] = this.outerMinorRadius;
array[3] = this.outerMajorRadius;
return array;
}
/**
* Sets the cylinder's radii.
*
* @param innerMinorRadius the cylinder's inner minor radius, in meters.
* @param innerMajorRadius The cylinder's inner major radius, in meters.
* @param outerMinorRadius the cylinder's outer minor radius, in meters.
* @param outerMajorRadius The cylinder's outer major radius, in meters.
*
* @throws IllegalArgumentException if either radius is less than zero.
*/
public void setRadii(double innerMinorRadius, double innerMajorRadius, double outerMinorRadius,
double outerMajorRadius)
{
if (innerMinorRadius < 0.0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", "innerMinorRadius=" + innerMinorRadius);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (outerMinorRadius < 0.0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", "outerMinorRadius=" + outerMinorRadius);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (innerMajorRadius < 0.0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", "innerMajorRadius=" + innerMajorRadius);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (outerMajorRadius < 0.0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", "outerMajorRadius=" + outerMajorRadius);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.innerMinorRadius = innerMinorRadius;
this.outerMinorRadius = outerMinorRadius;
this.innerMajorRadius = innerMajorRadius;
this.outerMajorRadius = outerMajorRadius;
this.invalidateAirspaceData();
}
/**
* Sets the cylinder's outer radii.
*
* @param outerMinorRadius the cylinder's outer minor radius, in meters.
* @param outerMajorRadius the cylinder's outer major radius, in meters.
*
* @throws IllegalArgumentException if either radius is less than zero.
*/
public void setRadii(double outerMinorRadius, double outerMajorRadius)
{
if (outerMinorRadius < 0.0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", "outerMinorRadius=" + outerMinorRadius);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (outerMajorRadius < 0.0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", "outerMajorRadius=" + outerMajorRadius);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.setRadii(0, 0, outerMinorRadius, outerMajorRadius);
}
/**
* Returns this cylinder's heading, in degrees.
*
* @return This cylinder's heading, in degrees.
*/
public Angle getHeading()
{
return heading;
}
/**
* Sets this cylinder's heading, in degrees.
*
* @param heading This cylinder's heading, in degrees.
*/
public void setHeading(Angle heading)
{
this.heading = heading;
this.invalidateAirspaceData();
}
public boolean isEnableCaps()
{
return this.enableCaps;
}
public void setEnableCaps(boolean enable)
{
this.enableCaps = enable;
}
public Position getReferencePosition()
{
double[] altitudes = this.getAltitudes();
return new Position(this.center, altitudes[0]);
}
protected Extent computeExtent(Globe globe, double verticalExaggeration)
{
List points = this.computeMinimalGeometry(globe, verticalExaggeration);
if (points == null || points.isEmpty())
return null;
Vec4 centerPoint = globe.computePointFromLocation(this.getCenter());
Vec4 cylinderAxis = globe.computeSurfaceNormalAtPoint(centerPoint);
double minProj = Double.MAX_VALUE;
double maxProj = -Double.MAX_VALUE;
double maxPerp = -Double.MAX_VALUE;
for (Vec4 vec : points)
{
Vec4 v = vec.subtract3(centerPoint);
double proj = v.dot3(cylinderAxis);
double perp = v.perpendicularTo3(cylinderAxis).getLengthSquared3();
if (minProj > proj)
minProj = proj;
if (maxProj < proj)
maxProj = proj;
if (maxPerp < perp)
maxPerp = perp;
}
if (minProj != maxProj && maxPerp > 0.0)
{
Vec4 bottomCenter = centerPoint.add3(cylinderAxis.multiply3(minProj));
Vec4 topCenter = centerPoint.add3(cylinderAxis.multiply3(maxProj));
double radius = Math.sqrt(maxPerp);
return new Cylinder(bottomCenter, topCenter, radius);
}
else
{
return Box.computeBoundingBox(points);
}
}
@Override
protected List computeMinimalGeometry(Globe globe, double verticalExaggeration)
{
GeometryBuilder gb = new GeometryBuilder();
LatLon[] locations = gb.makeDiskLocations(globe, this.center, this.getRadii(),
this.heading, MINIMAL_GEOMETRY_SLICES, MINIMAL_GEOMETRY_LOOPS);
ArrayList points = new ArrayList();
this.makeExtremePoints(globe, verticalExaggeration, Arrays.asList(locations), points);
return points;
}
protected void doMoveTo(Globe globe, Position oldRef, Position newRef)
{
if (oldRef == null)
{
String message = "nullValue.OldRefIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (newRef == null)
{
String message = "nullValue.NewRefIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
List oldLocations = new ArrayList(1);
oldLocations.add(this.getCenter());
List newLocations = LatLon.computeShiftedLocations(globe, oldRef, newRef, oldLocations);
this.setCenter(newLocations.get(0));
super.doMoveTo(oldRef, newRef);
}
protected void doMoveTo(Position oldRef, Position newRef)
{
if (oldRef == null)
{
String message = "nullValue.OldRefIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (newRef == null)
{
String message = "nullValue.NewRefIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
super.doMoveTo(oldRef, newRef);
LatLon center = this.getCenter();
double distance = LatLon.greatCircleDistance(oldRef, center).radians;
double azimuth = LatLon.greatCircleAzimuth(oldRef, center).radians;
this.setCenter(LatLon.greatCircleEndPosition(newRef, azimuth, distance));
}
@Override
protected SurfaceShape createSurfaceShape()
{
return new SurfacePolygon();
}
@Override
protected void updateSurfaceShape(DrawContext dc, SurfaceShape shape)
{
super.updateSurfaceShape(dc, shape);
boolean mustDrawInterior = this.getActiveAttributes().isDrawInterior() && this.isEnableCaps();
shape.getAttributes().setDrawInterior(mustDrawInterior); // suppress the shape interior when caps are disabled
}
@Override
protected void regenerateSurfaceShape(DrawContext dc, SurfaceShape shape)
{
GeometryBuilder gb = new GeometryBuilder();
LatLon[] locations = gb.makeCylinderLocations(dc.getGlobe(), this.center,
this.outerMinorRadius, this.outerMajorRadius, this.heading, this.slices);
((SurfacePolygon) shape).getBoundaries().clear();
((SurfacePolygon) shape).setOuterBoundary(Arrays.asList(locations));
if (this.innerMinorRadius > 0 && this.innerMajorRadius > 0)
{
locations = gb.makeCylinderLocations(dc.getGlobe(), this.center,
this.innerMinorRadius, this.innerMajorRadius, this.heading, this.slices);
((SurfacePolygon) shape).addInnerBoundary(Arrays.asList(locations));
}
}
public int getSlices()
{
return this.slices;
}
public void setSlices(int slices)
{
if (slices < 0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", "slices=" + slices);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.slices = slices;
}
public int getStacks()
{
return this.stacks;
}
public int getLoops()
{
return this.loops;
}
public void setLoops(int loops)
{
if (loops < 0)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", "loops=" + loops);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.loops = loops;
}
//**************************************************************//
//******************** Geometry Rendering ********************//
//**************************************************************//
protected Vec4 computeReferenceCenter(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (dc.getGlobe() == null)
{
String message = Logging.getMessage("nullValue.DrawingContextGlobeIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
double[] altitudes = this.getAltitudes(dc.getVerticalExaggeration());
return dc.getGlobe().computePointFromPosition(this.center.getLatitude(), this.center.getLongitude(),
altitudes[0]); // model-coordinate reference center
}
protected void doRenderGeometry(DrawContext dc, String drawStyle)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (dc.getGL() == null)
{
String message = Logging.getMessage("nullValue.DrawingContextGLIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
LatLon center = this.getCenter();
double[] altitudes = this.getAltitudes(dc.getVerticalExaggeration());
boolean[] terrainConformant = this.isTerrainConforming();
double[] radii = this.getRadii();
int slices = this.slices;
int stacks = this.stacks;
int loops = this.loops;
if (this.isEnableLevelOfDetail())
{
DetailLevel level = this.computeDetailLevel(dc);
Object o = level.getValue(SLICES);
if (o != null && o instanceof Integer)
slices = (Integer) o;
o = level.getValue(STACKS);
if (o != null && o instanceof Integer)
stacks = (Integer) o;
o = level.getValue(LOOPS);
if (o != null && o instanceof Integer)
loops = (Integer) o;
o = level.getValue(DISABLE_TERRAIN_CONFORMANCE);
if (o != null && o instanceof Boolean && ((Boolean) o))
terrainConformant[0] = terrainConformant[1] = false;
}
Vec4 refCenter = this.computeReferenceCenter(dc);
this.setExpiryTime(this.nextExpiryTime(dc, terrainConformant));
this.clearElevationMap();
GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.
OGLStackHandler ogsh = new OGLStackHandler();
try
{
dc.getView().pushReferenceCenter(dc, refCenter);
if (Airspace.DRAW_STYLE_OUTLINE.equals(drawStyle))
{
// Outer cylinder isn't rendered if outer radius is zero.
if (radii[2] != 0.0 && radii[3] != 0)
{
this.drawCylinderOutline(dc, center, radii[2], radii[3], this.heading, altitudes,
terrainConformant, slices, stacks, GeometryBuilder.OUTSIDE, refCenter);
}
// Inner cylinder isn't rendered if inner radius is zero.
if (radii[0] != 0.0 && radii[1] != 0)
{
this.drawCylinderOutline(dc, center, radii[0], radii[1], this.heading, altitudes,
terrainConformant, slices, stacks, GeometryBuilder.INSIDE, refCenter);
}
}
else if (Airspace.DRAW_STYLE_FILL.equals(drawStyle))
{
if (this.enableCaps)
{
ogsh.pushAttrib(gl, GL2.GL_POLYGON_BIT);
gl.glEnable(GL.GL_CULL_FACE);
gl.glFrontFace(GL.GL_CCW);
}
if (this.enableCaps)
{
// Caps aren't rendered if radii are equal.
if ((radii[0] != radii[2]) && (radii[1] != radii[3]))
{
this.drawDisk(dc, center, radii, this.heading, altitudes[1], terrainConformant[1], slices, loops,
GeometryBuilder.OUTSIDE, refCenter);
// Bottom cap isn't rendered if airspace is collapsed
if (!this.isAirspaceCollapsed())
{
this.drawDisk(dc, center, radii, this.heading, altitudes[0], terrainConformant[0], slices, loops,
GeometryBuilder.INSIDE, refCenter);
}
}
}
// Cylinders aren't rendered if airspace is collapsed
if (!this.isAirspaceCollapsed())
{
// Outer cylinder isn't rendered if outer radius is zero.
if (radii[2] != 0.0 && radii[3] != 0)
{
this.drawCylinder(dc, center, radii[2], radii[3], this.heading, altitudes, terrainConformant,
slices, stacks, GeometryBuilder.OUTSIDE, refCenter);
}
// Inner cylinder isn't rendered if inner radius is zero.
if (radii[0] != 0.0)
{
this.drawCylinder(dc, center, radii[0], radii[1], this.heading, altitudes, terrainConformant,
slices, stacks, GeometryBuilder.INSIDE, refCenter);
}
}
}
}
finally
{
dc.getView().popReferenceCenter(dc);
ogsh.pop(gl);
}
}
//**************************************************************//
//******************** Cylinder ********************//
//**************************************************************//
private void drawCylinder(DrawContext dc, LatLon center, double minorRadius, double majorRadius, Angle heading,
double[] altitudes, boolean[] terrainConformant, int slices, int stacks, int orientation, Vec4 referenceCenter)
{
Geometry vertexGeom = this.createCylinderVertexGeometry(dc, center, minorRadius, majorRadius, heading,
altitudes, terrainConformant, slices, stacks, orientation, referenceCenter);
Object cacheKey = new Geometry.CacheKey(this.getClass(), "EllipticalCylinder.Indices", slices, stacks, orientation);
Geometry indexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (indexGeom == null)
{
indexGeom = new Geometry();
this.makeCylinderIndices(slices, stacks, orientation, indexGeom);
this.getGeometryCache().add(cacheKey, indexGeom);
}
this.drawGeometry(dc, indexGeom, vertexGeom);
}
private void drawCylinderOutline(DrawContext dc, LatLon center, double minorRadius, double majorRadius,
Angle heading, double[] altitudes, boolean[] terrainConformant, int slices, int stacks, int orientation,
Vec4 referenceCenter)
{
Geometry vertexGeom = this.createCylinderVertexGeometry(dc, center, minorRadius, majorRadius, heading, altitudes,
terrainConformant, slices, stacks, orientation, referenceCenter);
Object cacheKey = new Geometry.CacheKey(this.getClass(), "EllipticalCylinder.OutlineIndices", slices, stacks,
orientation);
Geometry outlineIndexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (outlineIndexGeom == null)
{
outlineIndexGeom = new Geometry();
this.makeCylinderOutlineIndices(slices, stacks, orientation, outlineIndexGeom);
this.getGeometryCache().add(cacheKey, outlineIndexGeom);
}
this.drawGeometry(dc, outlineIndexGeom, vertexGeom);
}
private Geometry createCylinderVertexGeometry(DrawContext dc, LatLon center, double minorRadius, double majorRadius,
Angle heading, double[] altitudes, boolean[] terrainConformant, int slices, int stacks, int orientation,
Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "EllipticalCylinder.Vertices", center,
minorRadius, majorRadius, heading,
altitudes[0], altitudes[1], terrainConformant[0], terrainConformant[1], slices, stacks, orientation,
referenceCenter);
Geometry vertexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (vertexGeom == null || this.isExpired(dc, vertexGeom))
{
if (vertexGeom == null)
vertexGeom = new Geometry();
this.makeCylinder(dc, center, minorRadius, majorRadius, heading, altitudes, terrainConformant, slices,
stacks, orientation, referenceCenter, vertexGeom);
this.updateExpiryCriteria(dc, vertexGeom);
this.getGeometryCache().add(cacheKey, vertexGeom);
}
return vertexGeom;
}
private void makeCylinder(DrawContext dc, LatLon center, double minorRadius, double majorRadius, Angle heading,
double[] altitudes,
boolean[] terrainConformant, int slices, int stacks, int orientation, Vec4 referenceCenter, Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int count = gb.getCylinderVertexCount(slices, stacks);
float[] verts = new float[3 * count];
float[] norms = new float[3 * count];
gb.makeCylinderVertices(dc.getTerrain(), center, minorRadius, majorRadius, heading, altitudes,
terrainConformant, slices, stacks, referenceCenter, verts);
gb.makeEllipticalCylinderNormals(slices, stacks, minorRadius, majorRadius, heading, norms);
dest.setVertexData(count, verts);
dest.setNormalData(count, norms);
}
private void makeCylinderIndices(int slices, int stacks, int orientation, Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int mode = gb.getCylinderDrawMode();
int count = gb.getCylinderIndexCount(slices, stacks);
int[] indices = new int[count];
gb.makeCylinderIndices(slices, stacks, indices);
dest.setElementData(mode, count, indices);
}
private void makeCylinderOutlineIndices(int slices, int stacks, int orientation, Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int mode = gb.getCylinderOutlineDrawMode();
int count = gb.getCylinderOutlineIndexCount(slices, stacks);
int[] indices = new int[count];
gb.makeCylinderOutlineIndices(slices, stacks, indices);
dest.setElementData(mode, count, indices);
}
//**************************************************************//
//******************** Disk ********************//
//**************************************************************//
private void drawDisk(DrawContext dc, LatLon center, double[] radii, Angle heading, double altitude,
boolean terrainConformant, int slices, int loops, int orientation, Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "EllipticalDisk.Vertices",
center, radii[0], radii[1], radii[2], radii[3], heading, altitude, terrainConformant,
slices, loops, orientation, referenceCenter);
Geometry vertexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (vertexGeom == null || this.isExpired(dc, vertexGeom))
{
if (vertexGeom == null)
vertexGeom = new Geometry();
this.makeDisk(dc, center, radii, heading, altitude, terrainConformant,
slices, loops, orientation, referenceCenter, vertexGeom);
this.updateExpiryCriteria(dc, vertexGeom);
this.getGeometryCache().add(cacheKey, vertexGeom);
}
cacheKey = new Geometry.CacheKey(this.getClass(), "EllipticalDisk.Indices", slices, loops, orientation);
Geometry indexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (indexGeom == null)
{
indexGeom = new Geometry();
this.makeDiskIndices(slices, loops, orientation, indexGeom);
this.getGeometryCache().add(cacheKey, indexGeom);
}
this.drawGeometry(dc, indexGeom, vertexGeom);
}
private void makeDisk(DrawContext dc, LatLon center, double[] radii, Angle heading, double altitude,
boolean terrainConformant, int slices, int loops, int orientation, Vec4 referenceCenter, Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int count = gb.getDiskVertexCount(slices, loops);
float[] verts = new float[3 * count];
float[] norms = new float[3 * count];
gb.makeDiskVertices(dc.getTerrain(), center, radii, heading, altitude, terrainConformant, slices, loops,
referenceCenter, verts);
gb.makeDiskVertexNormals(radii[0], radii[2], slices, loops, verts, norms);
dest.setVertexData(count, verts);
dest.setNormalData(count, norms);
}
private void makeDiskIndices(int slices, int loops, int orientation, Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int mode = gb.getCylinderDrawMode();
int count = gb.getDiskIndexCount(slices, loops);
int[] indices = new int[count];
gb.makeDiskIndices(slices, loops, indices);
dest.setElementData(mode, count, indices);
}
//**************************************************************//
//******************** END Geometry Rendering ****************//
//**************************************************************//
@Override
protected void doGetRestorableState(RestorableSupport rs, RestorableSupport.StateObject context)
{
super.doGetRestorableState(rs, context);
rs.addStateValueAsBoolean(context, "capsVisible", this.isEnableCaps());
rs.addStateValueAsLatLon(context, "center", this.getCenter());
rs.addStateValueAsDouble(context, "innerMinorRadius", this.getRadii()[0]);
rs.addStateValueAsDouble(context, "innerMajorRadius", this.getRadii()[1]);
rs.addStateValueAsDouble(context, "outerMinorRadius", this.getRadii()[2]);
rs.addStateValueAsDouble(context, "outerMajorRadius", this.getRadii()[3]);
rs.addStateValueAsDouble(context, "heading", this.getHeading().degrees);
}
@Override
protected void doRestoreState(RestorableSupport rs, RestorableSupport.StateObject context)
{
super.doRestoreState(rs, context);
Boolean booleanState = rs.getStateValueAsBoolean(context, "capsVisible");
if (booleanState != null)
this.setEnableCaps(booleanState);
LatLon ll = rs.getStateValueAsLatLon(context, "center");
if (ll != null)
this.setCenter(ll);
Double innerMinorRadius = rs.getStateValueAsDouble(context, "innerMinorRadius");
if (innerMinorRadius == null)
innerMinorRadius = this.getRadii()[0];
Double innerMajorRadius = rs.getStateValueAsDouble(context, "innerMajorRadius");
if (innerMajorRadius == null)
innerMajorRadius = this.getRadii()[1];
Double outerMinorRadius = rs.getStateValueAsDouble(context, "outerMinorRadius");
if (outerMinorRadius == null)
outerMinorRadius = this.getRadii()[0];
Double outerMajorRadius = rs.getStateValueAsDouble(context, "outerMajorRadius");
if (outerMajorRadius == null)
outerMajorRadius = this.getRadii()[1];
this.setRadii(innerMinorRadius, innerMajorRadius, outerMinorRadius, outerMajorRadius);
Double heading = rs.getStateValueAsDouble(context, "heading");
if (heading == null)
heading = this.getHeading().degrees;
this.setHeading(Angle.fromDegrees(heading));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy