src.gov.nasa.worldwind.render.airspaces.PartialCappedCylinder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of worldwindx Show documentation
Show all versions of worldwindx Show documentation
World Wind is a collection of components that interactively display 3D geographic information within Java applications or applets.
/*
* 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.render.airspaces;
import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.geom.Box;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.render.DrawContext;
import gov.nasa.worldwind.util.*;
import javax.media.opengl.*;
import java.util.*;
/**
* A cylinder defined by a geographic position, a radius in meters, and minimum and maximum altitudes.
*
* @author tag
* @version $Id: PartialCappedCylinder.java 1171 2013-02-11 21:45:02Z dcollins $
*/
public class PartialCappedCylinder extends CappedCylinder
{
private Angle leftAzimuth = Angle.ZERO;
private Angle rightAzimuth = Angle.POS360;
public PartialCappedCylinder(LatLon location, double radius, Angle leftAzimuth, Angle rightAzimuth)
{
super(location, radius);
if (leftAzimuth == null)
{
String message = "nullValue.LeftAzimuthIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (rightAzimuth == null)
{
String message = "nullValue.RightAzimuthIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.leftAzimuth = leftAzimuth;
this.rightAzimuth = rightAzimuth;
}
public PartialCappedCylinder(LatLon location, double radius)
{
super(location, radius);
}
public PartialCappedCylinder(AirspaceAttributes attributes)
{
super(attributes);
}
public PartialCappedCylinder()
{
}
public Angle[] getAzimuths()
{
Angle[] array = new Angle[2];
array[0] = this.leftAzimuth;
array[1] = this.rightAzimuth;
return array;
}
public void setAzimuths(Angle leftAzimuth, Angle rightAzimuth)
{
if (leftAzimuth == null)
{
String message = "nullValue.LeftAzimuthIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (rightAzimuth == null)
{
String message = "nullValue.RightAzimuthIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.leftAzimuth = leftAzimuth;
this.rightAzimuth = rightAzimuth;
this.setExtentOutOfDate();
}
protected Box computeExtent(Globe globe, double verticalExaggeration)
{
List points = this.computeMinimalGeometry(globe, verticalExaggeration);
if (points == null || points.isEmpty())
return null;
// A bounding box typically provides a better fit for a partial capped cylinder than a bounding cylinder.
return Box.computeBoundingBox(points);
}
@Override
protected List computeMinimalGeometry(Globe globe, double verticalExaggeration)
{
double[] angles = this.computeAngles();
// Angles are equal, fall back to building a closed cylinder.
if (angles == null)
return super.computeMinimalGeometry(globe, verticalExaggeration);
double[] radii = this.getRadii();
Matrix transform = this.computeTransform(globe, verticalExaggeration);
GeometryBuilder gb = this.getGeometryBuilder();
int count = gb.getPartialDiskVertexCount(MINIMAL_GEOMETRY_SLICES, MINIMAL_GEOMETRY_LOOPS);
int numCoords = 3 * count;
float[] verts = new float[numCoords];
gb.makePartialDiskVertices(
(float) radii[0], (float) radii[1], // Inner radius, outer radius.
MINIMAL_GEOMETRY_SLICES, MINIMAL_GEOMETRY_LOOPS, // Slices, loops,
(float) angles[0], (float) angles[2], // Start angle, sweep angle.
verts);
List locations = new ArrayList();
for (int i = 0; i < numCoords; i += 3)
{
Vec4 v = new Vec4(verts[i], verts[i + 1], verts[i + 2]);
v = v.transformBy4(transform);
locations.add(globe.computePositionFromPoint(v));
}
ArrayList points = new ArrayList();
this.makeExtremePoints(globe, verticalExaggeration, locations, points);
return points;
}
//**************************************************************//
//******************** Geometry Rendering ********************//
//**************************************************************//
protected double[] computeAngles()
{
// Compute the start and sweep angles such that the partial cylinder shape tranverses a clockwise path from
// the start angle to the stop angle.
Angle startAngle, stopAngle, sweepAngle;
startAngle = normalizedAzimuth(this.leftAzimuth);
stopAngle = normalizedAzimuth(this.rightAzimuth);
int i = startAngle.compareTo(stopAngle);
// Angles are equal, fallback to building a closed cylinder.
if (i == 0)
return null;
if (i < 0)
sweepAngle = stopAngle.subtract(startAngle);
else // (i > 0)
sweepAngle = Angle.POS360.subtract(startAngle).add(stopAngle);
double[] array = new double[3];
array[0] = startAngle.radians;
array[1] = stopAngle.radians;
array[2] = sweepAngle.radians;
return array;
}
protected Angle normalizedAzimuth(Angle azimuth)
{
if (azimuth == null)
{
String message = "nullValue.AzimuthIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
double degrees = azimuth.degrees;
double normalizedDegrees = degrees < 0.0 ? degrees + 360.0 : (degrees >= 360.0 ? degrees - 360.0 : degrees);
return Angle.fromDegrees(normalizedDegrees);
}
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);
}
double[] angles = this.computeAngles();
// Angles are equal, fallback to drawing a closed cylinder.
if (angles == null)
{
super.doRenderGeometry(dc, drawStyle);
return;
}
double[] altitudes = this.getAltitudes(dc.getVerticalExaggeration());
boolean[] terrainConformant = this.isTerrainConforming();
double[] radii = this.getRadii();
int slices = this.getSlices();
int stacks = this.getStacks();
int loops = this.getLoops();
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 referenceCenter = 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, referenceCenter);
if (Airspace.DRAW_STYLE_OUTLINE.equals(drawStyle))
{
this.drawRadialWallOutline(dc, radii, angles[0], altitudes, terrainConformant,
loops, stacks, GeometryBuilder.INSIDE, referenceCenter);
this.drawRadialWallOutline(dc, radii, angles[1], altitudes, terrainConformant,
loops, stacks, GeometryBuilder.OUTSIDE, referenceCenter);
// Outer cylinder isn't rendered if outer radius is zero.
if (radii[1] != 0.0)
{
this.drawPartialCylinderOutline(dc, radii[1], altitudes, terrainConformant,
slices, stacks, GeometryBuilder.OUTSIDE, angles[0], angles[2], referenceCenter);
}
// Inner cylinder isn't rendered if inner radius is zero.
if (radii[0] != 0.0)
{
this.drawPartialCylinderOutline(dc, radii[0], altitudes, terrainConformant,
slices, stacks, GeometryBuilder.INSIDE, angles[0], angles[2], referenceCenter);
}
}
else if (Airspace.DRAW_STYLE_FILL.equals(drawStyle))
{
if (this.isEnableCaps())
{
ogsh.pushAttrib(gl, GL2.GL_POLYGON_BIT);
gl.glEnable(GL.GL_CULL_FACE);
gl.glFrontFace(GL.GL_CCW);
}
if (this.isEnableCaps())
{
// Caps aren't rendered if radii are equal.
if (radii[0] != radii[1])
{
this.drawPartialDisk(dc, radii, altitudes[1], terrainConformant[1],
slices, loops, GeometryBuilder.OUTSIDE, angles[0], angles[2], referenceCenter);
// Bottom cap isn't rendered if airspace is collapsed.
if (!this.isAirspaceCollapsed())
{
this.drawPartialDisk(dc, radii, altitudes[0], terrainConformant[0],
slices, loops, GeometryBuilder.INSIDE, angles[0], angles[2], referenceCenter);
}
}
}
// Cylinders aren't rendered if airspace is collapsed.
if (!this.isAirspaceCollapsed())
{
this.drawRadialWall(dc, radii, angles[0], altitudes, terrainConformant,
loops, stacks, GeometryBuilder.INSIDE, referenceCenter);
this.drawRadialWall(dc, radii, angles[1], altitudes, terrainConformant,
loops, stacks, GeometryBuilder.OUTSIDE, referenceCenter);
// Outer cylinder isn't rendered if outer radius is zero.
if (radii[1] != 0.0)
{
this.drawPartialCylinder(dc, radii[1], altitudes, terrainConformant,
slices, stacks, GeometryBuilder.OUTSIDE, angles[0], angles[2], referenceCenter);
}
// Inner cylinder isn't rendered if inner radius is zero.
if (radii[0] != 0.0)
{
this.drawPartialCylinder(dc, radii[0], altitudes, terrainConformant,
slices, stacks, GeometryBuilder.INSIDE, angles[0], angles[2], referenceCenter);
}
}
}
}
finally
{
dc.getView().popReferenceCenter(dc);
ogsh.pop(gl);
}
}
//**************************************************************//
//******************** Partial Cylinder ********************//
//**************************************************************//
private void drawPartialCylinder(DrawContext dc, double radius, double[] altitudes, boolean[] terrainConformant,
int slices, int stacks, int orientation,
double start, double sweep,
Vec4 referenceCenter)
{
Geometry vertexGeom = createPartialCylinderVertexGeometry(dc, radius, altitudes, terrainConformant,
slices, stacks, orientation, start, sweep, referenceCenter);
Object cacheKey = new Geometry.CacheKey(this.getClass(), "PartialCylinder.Indices",
slices, stacks, orientation);
Geometry indexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (indexGeom == null)
{
indexGeom = new Geometry();
this.makePartialCylinderIndices(slices, stacks, orientation, indexGeom);
this.getGeometryCache().add(cacheKey, indexGeom);
}
this.getRenderer().drawGeometry(dc, indexGeom, vertexGeom);
}
private void drawPartialCylinderOutline(DrawContext dc, double radius, double[] altitudes,
boolean[] terrainConformant,
int slices, int stacks, int orientation,
double start, double sweep,
Vec4 referenceCenter)
{
Geometry vertexGeom = createPartialCylinderVertexGeometry(dc, radius, altitudes, terrainConformant,
slices, stacks, orientation, start, sweep, referenceCenter);
Object cacheKey = new Geometry.CacheKey(this.getClass(), "PartialCylinder.OutlineIndices",
slices, stacks, orientation);
Geometry outlineIndexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (outlineIndexGeom == null)
{
outlineIndexGeom = new Geometry();
this.makePartialCylinderOutlineIndices(slices, stacks, orientation, outlineIndexGeom);
this.getGeometryCache().add(cacheKey, outlineIndexGeom);
}
this.getRenderer().drawGeometry(dc, outlineIndexGeom, vertexGeom);
}
private Geometry createPartialCylinderVertexGeometry(DrawContext dc, double radius, double[] altitudes,
boolean[] terrainConformant, int slices, int stacks, int orientation,
double start, double sweep,
Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "PartialCylinder.Vertices",
radius, altitudes[0], altitudes[1], terrainConformant[0], terrainConformant[1],
slices, stacks, orientation, start, sweep, referenceCenter);
Geometry vertexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (vertexGeom == null || this.isExpired(dc, vertexGeom))
{
if (vertexGeom == null)
vertexGeom = new Geometry();
this.makePartialCylinder(dc, radius, altitudes, terrainConformant,
slices, stacks, orientation, start, sweep, referenceCenter, vertexGeom);
this.updateExpiryCriteria(dc, vertexGeom);
this.getGeometryCache().add(cacheKey, vertexGeom);
}
return vertexGeom;
}
private void makePartialCylinder(DrawContext dc, double radius, double[] altitudes, boolean[] terrainConformant,
int slices, int stacks, int orientation,
double start, double sweep,
Vec4 referenceCenter,
Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
float height = (float) (altitudes[1] - altitudes[0]);
int count = gb.getPartialCylinderVertexCount(slices, stacks);
int numCoords = 3 * count;
float[] verts = new float[numCoords];
float[] norms = new float[numCoords];
gb.makePartialCylinderVertices((float) radius, height, slices, stacks, (float) start, (float) sweep,
verts);
gb.makePartialCylinderNormals((float) radius, height, slices, stacks, (float) start, (float) sweep,
norms);
this.makePartialCylinderTerrainConformant(dc, slices, stacks, verts,
altitudes, terrainConformant, referenceCenter);
dest.setVertexData(count, verts);
dest.setNormalData(count, norms);
}
private void makePartialCylinderTerrainConformant(DrawContext dc, int slices, int stacks, float[] verts,
double[] altitudes, boolean[] terrainConformant,
Vec4 referenceCenter)
{
Globe globe = dc.getGlobe();
Matrix transform = this.computeTransform(dc.getGlobe(), dc.getVerticalExaggeration());
for (int i = 0; i <= slices; i++)
{
int index = i * (stacks + 1);
index = 3 * index;
Vec4 vec = new Vec4(verts[index], verts[index + 1], verts[index + 2]);
vec = vec.transformBy4(transform);
Position p = globe.computePositionFromPoint(vec);
for (int j = 0; j <= stacks; j++)
{
double elevation = altitudes[j];
if (terrainConformant[j])
elevation += this.computeElevationAt(dc, p.getLatitude(), p.getLongitude());
vec = globe.computePointFromPosition(p.getLatitude(), p.getLongitude(), elevation);
index = j + i * (stacks + 1);
index = 3 * index;
verts[index] = (float) (vec.x - referenceCenter.x);
verts[index + 1] = (float) (vec.y - referenceCenter.y);
verts[index + 2] = (float) (vec.z - referenceCenter.z);
}
}
}
private void makePartialCylinderIndices(int slices, int stacks, int orientation, Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int mode = gb.getPartialCylinderDrawMode();
int count = gb.getPartialCylinderIndexCount(slices, stacks);
int[] indices = new int[count];
gb.makePartialCylinderIndices(slices, stacks, indices);
dest.setElementData(mode, count, indices);
}
private void makePartialCylinderOutlineIndices(int slices, int stacks, int orientation, Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int mode = gb.getPartialCylinderOutlineDrawMode();
int count = gb.getPartialCylinderOutlineIndexCount(slices, stacks);
int[] indices = new int[count];
gb.makePartialCylinderOutlineIndices(slices, stacks, indices);
dest.setElementData(mode, count, indices);
}
//**************************************************************//
//******************** Partial Disk ********************//
//**************************************************************//
private void drawPartialDisk(DrawContext dc, double[] radii, double altitude, boolean terrainConformant,
int slices, int loops, int orientation,
double start, double sweep,
Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "PartialDisk.Vertices",
radii[0], radii[1], altitude, terrainConformant,
slices, loops, orientation, start, sweep, referenceCenter);
Geometry vertexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (vertexGeom == null || this.isExpired(dc, vertexGeom))
{
if (vertexGeom == null)
vertexGeom = new Geometry();
this.makePartialDisk(dc, radii, altitude, terrainConformant,
slices, loops, orientation, start, sweep, referenceCenter, vertexGeom);
this.updateExpiryCriteria(dc, vertexGeom);
this.getGeometryCache().add(cacheKey, vertexGeom);
}
cacheKey = new Geometry.CacheKey(this.getClass(), "PartialDisk.Indices",
slices, loops, orientation);
Geometry indexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (indexGeom == null)
{
indexGeom = new Geometry();
this.makePartialDiskIndices(slices, loops, orientation, indexGeom);
this.getGeometryCache().add(cacheKey, indexGeom);
}
this.getRenderer().drawGeometry(dc, indexGeom, vertexGeom);
}
private void makePartialDisk(DrawContext dc, double[] radii, double altitude, boolean terrainConformant,
int slices, int loops, int orientation,
double start, double sweep,
Vec4 referenceCenter,
Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int count = gb.getPartialDiskIndexCount(slices, loops);
int numCoords = 3 * count;
float[] verts = new float[numCoords];
float[] norms = new float[numCoords];
gb.makePartialDiskVertices((float) radii[0], (float) radii[1], slices, loops,
(float) start, (float) sweep, verts);
this.makePartialDiskTerrainConformant(dc, numCoords, verts, altitude, terrainConformant, referenceCenter);
gb.makePartialDiskVertexNormals((float) radii[0], (float) radii[1], slices, loops,
(float) start, (float) sweep, verts, norms);
dest.setVertexData(count, verts);
dest.setNormalData(count, norms);
}
private void makePartialDiskTerrainConformant(DrawContext dc, int numCoords, float[] verts,
double altitude, boolean terrainConformant,
Vec4 referenceCenter)
{
Globe globe = dc.getGlobe();
Matrix transform = this.computeTransform(dc.getGlobe(), dc.getVerticalExaggeration());
for (int i = 0; i < numCoords; i += 3)
{
Vec4 vec = new Vec4(verts[i], verts[i + 1], verts[i + 2]);
vec = vec.transformBy4(transform);
Position p = globe.computePositionFromPoint(vec);
double elevation = altitude;
if (terrainConformant)
elevation += this.computeElevationAt(dc, p.getLatitude(), p.getLongitude());
vec = globe.computePointFromPosition(p.getLatitude(), p.getLongitude(), elevation);
verts[i] = (float) (vec.x - referenceCenter.x);
verts[i + 1] = (float) (vec.y - referenceCenter.y);
verts[i + 2] = (float) (vec.z - referenceCenter.z);
}
}
private void makePartialDiskIndices(int slices, int loops, int orientation, Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int mode = gb.getPartialDiskDrawMode();
int count = gb.getPartialDiskIndexCount(slices, loops);
int[] indices = new int[count];
gb.makePartialDiskIndices(slices, loops, indices);
dest.setElementData(mode, count, indices);
}
//**************************************************************//
//******************** Radial Wall ********************//
//**************************************************************//
private void drawRadialWall(DrawContext dc, double[] radii, double angle,
double[] altitudes, boolean[] terrainConformant,
int pillars, int stacks, int orientation,
Vec4 referenceCenter)
{
Geometry vertexGeom = createRadialWallVertexGeometry(dc, radii, angle, altitudes, terrainConformant,
pillars, stacks, orientation, referenceCenter);
Object cacheKey = new Geometry.CacheKey(this.getClass(), "RadialWall.Indices",
pillars, stacks, orientation);
Geometry indexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (indexGeom == null)
{
indexGeom = new Geometry();
this.makeRadialWallIndices(pillars, stacks, orientation, indexGeom);
this.getGeometryCache().add(cacheKey, indexGeom);
}
this.getRenderer().drawGeometry(dc, indexGeom, vertexGeom);
}
private void drawRadialWallOutline(DrawContext dc, double[] radii, double angle,
double[] altitudes, boolean[] terrainConformant,
int pillars, int stacks, int orientation,
Vec4 referenceCenter)
{
Geometry vertexGeom = createRadialWallVertexGeometry(dc, radii, angle, altitudes, terrainConformant,
pillars, stacks, orientation, referenceCenter);
Object cacheKey = new Geometry.CacheKey(this.getClass(), "RadialWall.OutlineIndices",
pillars, stacks, orientation);
Geometry outlineIndexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (outlineIndexGeom == null)
{
outlineIndexGeom = new Geometry();
this.makeRadialWallOutlineIndices(pillars, stacks, orientation, outlineIndexGeom);
this.getGeometryCache().add(cacheKey, outlineIndexGeom);
}
this.getRenderer().drawGeometry(dc, outlineIndexGeom, vertexGeom);
}
private Geometry createRadialWallVertexGeometry(DrawContext dc, double[] radii, double angle,
double[] altitudes, boolean[] terrainConformant,
int pillars, int stacks, int orientation,
Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "RadialWall.Vertices",
radii[0], radii[1], angle, altitudes[0], altitudes[1], terrainConformant[0], terrainConformant[1],
pillars, stacks, orientation, referenceCenter);
Geometry vertexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
if (vertexGeom == null || this.isExpired(dc, vertexGeom))
{
if (vertexGeom == null)
vertexGeom = new Geometry();
this.makeRadialWall(dc, radii, angle, altitudes, terrainConformant,
pillars, stacks, orientation, referenceCenter, vertexGeom);
this.updateExpiryCriteria(dc, vertexGeom);
this.getGeometryCache().add(cacheKey, vertexGeom);
}
return vertexGeom;
}
private void makeRadialWall(DrawContext dc, double[] radii, double angle,
double[] altitudes, boolean[] terrainConformant,
int pillars, int stacks, int orientation,
Vec4 referenceCenter,
Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
float height = (float) (altitudes[1] - altitudes[0]);
int count = gb.getRadialWallVertexCount(pillars, stacks);
int numCoords = 3 * count;
float[] verts = new float[numCoords];
float[] norms = new float[numCoords];
gb.makeRadialWallVertices((float) radii[0], (float) radii[1], height, (float) angle,
pillars, stacks, verts);
this.makeRadialWallTerrainConformant(dc, pillars, stacks, verts, altitudes, terrainConformant, referenceCenter);
gb.makeRadialWallNormals((float) radii[0], (float) radii[1], height, (float) angle,
pillars, stacks, norms);
dest.setVertexData(count, verts);
dest.setNormalData(count, norms);
}
private void makeRadialWallTerrainConformant(DrawContext dc, int pillars, int stacks, float[] verts,
double[] altitudes, boolean[] terrainConformant,
Vec4 referenceCenter)
{
Globe globe = dc.getGlobe();
Matrix transform = this.computeTransform(dc.getGlobe(), dc.getVerticalExaggeration());
for (int p = 0; p <= pillars; p++)
{
int index = p;
index = 3 * index;
Vec4 vec = new Vec4(verts[index], verts[index + 1], verts[index + 2]);
vec = vec.transformBy4(transform);
Position pos = globe.computePositionFromPoint(vec);
for (int s = 0; s <= stacks; s++)
{
double elevation = altitudes[s];
if (terrainConformant[s])
elevation += this.computeElevationAt(dc, pos.getLatitude(), pos.getLongitude());
vec = globe.computePointFromPosition(pos.getLatitude(), pos.getLongitude(), elevation);
index = p + s * (pillars + 1);
index = 3 * index;
verts[index] = (float) (vec.x - referenceCenter.x);
verts[index + 1] = (float) (vec.y - referenceCenter.y);
verts[index + 2] = (float) (vec.z - referenceCenter.z);
}
}
}
private void makeRadialWallIndices(int pillars, int stacks, int orientation, Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int mode = gb.getRadialWallDrawMode();
int count = gb.getRadialWallIndexCount(pillars, stacks);
int[] indices = new int[count];
gb.makeRadialWallIndices(pillars, stacks, indices);
dest.setElementData(mode, count, indices);
}
private void makeRadialWallOutlineIndices(int pillars, int stacks, int orientation, Geometry dest)
{
GeometryBuilder gb = this.getGeometryBuilder();
gb.setOrientation(orientation);
int mode = gb.getRadialWallOutlineDrawMode();
int count = gb.getRadialWallOutlineIndexCount(pillars, stacks);
int[] indices = new int[count];
gb.makeRadialWallOutlineIndices(pillars, stacks, indices);
dest.setElementData(mode, count, indices);
}
//**************************************************************//
//******************** END Geometry Rendering ****************//
//**************************************************************//
@Override
protected void doGetRestorableState(RestorableSupport rs, RestorableSupport.StateObject context)
{
super.doGetRestorableState(rs, context);
rs.addStateValueAsDouble(context, "leftAzimuthDegrees", this.leftAzimuth.degrees);
rs.addStateValueAsDouble(context, "rightAzimuthDegrees", this.rightAzimuth.degrees);
}
@Override
protected void doRestoreState(RestorableSupport rs, RestorableSupport.StateObject context)
{
super.doRestoreState(rs, context);
Double la = rs.getStateValueAsDouble(context, "leftAzimuthDegrees");
if (la == null)
la = this.leftAzimuth.degrees;
Double ra = rs.getStateValueAsDouble(context, "rightAzimuthDegrees");
if (ra == null)
ra = this.rightAzimuth.degrees;
this.setAzimuths(Angle.fromDegrees(la), Angle.fromDegrees(ra));
}
}