Skip to content

Commit

Permalink
Added multi-window support to all airspace shapes. See http://issues.…
Browse files Browse the repository at this point in the history
  • Loading branch information
dcollins committed Dec 16, 2011
1 parent f6757d9 commit 981ed1f
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 58 deletions.
Expand Up @@ -19,7 +19,6 @@
* @author dcollins
* @version $Id$
*/
@SuppressWarnings({"deprecation"})
public abstract class AbstractAirspace extends AVListImpl implements Airspace, Movable
{
protected static final String ARC_SLICES = "ArcSlices";
Expand Down Expand Up @@ -668,12 +667,14 @@ protected boolean isExpired(DrawContext dc, Geometry geom)
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);
}

if (geom == null)
{
String message = "nullValue.AirspaceGeometryIsNull";
Expand All @@ -682,14 +683,13 @@ protected boolean isExpired(DrawContext dc, Geometry geom)
}

Object o = geom.getValue(EXPIRY_TIME);
if (o != null && o instanceof Long)
if (dc.getFrameTimeStamp() > (Long) o)
return true;
if (o != null && o instanceof Long && dc.getFrameTimeStamp() > (Long) o)
return true;

o = geom.getValue(GLOBE_KEY);
if (o != null)
if (!dc.getGlobe().getStateKey(dc).equals(o))
return true;
//noinspection RedundantIfStatement
if (o != null && !dc.getGlobe().getStateKey(dc).equals(o))
return true;

return false;
}
Expand All @@ -702,6 +702,7 @@ protected void updateExpiryCriteria(DrawContext dc, Geometry geom)
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}

if (dc.getGlobe() == null)
{
String message = Logging.getMessage("nullValue.DrawingContextGlobeIsNull");
Expand Down
119 changes: 108 additions & 11 deletions WorldWind/src/gov/nasa/worldwind/render/airspaces/Box.java
Expand Up @@ -6,7 +6,7 @@
package gov.nasa.worldwind.render.airspaces;

import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.globes.*;
import gov.nasa.worldwind.render.DrawContext;
import gov.nasa.worldwind.util.*;

Expand All @@ -19,6 +19,26 @@
*/
public class Box extends AbstractAirspace
{
/**
* Holds a box's vertex data that's associated with a particular globe. The globeStateKey property indicates the
* globe state used to generate the vertex data.
*/
protected static class BoxData
{
/** Indicates the globe state used to generate the vertex data. Initially <code>null</code>. */
public GlobeStateKey globeStateKey;
/** Indicates the Box's vertex data. Initially an array with length eight containing <code>null</code> entries. */
public Vec4[] vertices = new Vec4[8];

/**
* Constructs a new BoxData with its globeStateKey initialized to <code>null</code> and its vertices initialized
* to a new array with length eight.
*/
public BoxData()
{
}
}

public static final int FACE_TOP = 0;
public static final int FACE_BOTTOM = 1;
public static final int FACE_LEFT = 2;
Expand Down Expand Up @@ -51,8 +71,14 @@ public class Box extends AbstractAirspace
private double rightWidth = 1.0;
private boolean enableStartCap = true;
private boolean enableEndCap = true;
// Geometry.
private Vec4[] vertices;

/**
* Map indicating the box's vertices associated with a particular globe. This enables a box to be used
* simultaneously in multiple models with different globes. This is initialized to a HashMap in order to support
* <code>null</code> keys. Null keys are used for backward compatibility with the Box accessor methods that do not
* specify a globe.
*/
protected Map<Globe, BoxData> boxData = new HashMap<Globe, BoxData>(2); // Usually holds either one or two entries.
private boolean forceCullFace = false;
private int pillars = DEFAULT_PILLARS;
private int stacks = DEFAULT_STACKS;
Expand Down Expand Up @@ -237,14 +263,68 @@ public void setEnableEndCap(boolean enable)

public Vec4[] getVertices()
{
return this.vertices;
return this.getVertices(null);
}

public void setVertices(Vec4[] vertices)
{
this.setVertices(null, vertices);
}

/**
* Indicates whether the box's vertices associated with the specific globe are valid for the globe's current state.
* This returns <code>true</code> if this box has any vertex data associated with the globe and the globe state used
* to generate the data is equivalent to the globe's current state. This returns <code>false</code> if this box does
* not have any vertex data associated with the globe, or if the vertex data is out of date.
*
* @param globe the globe the vertices are associated with, or <code>null</code> to get the valid state of the
* vertices that are not associated with any globe.
*
* @return <code>true</code> if this box has vertices associated with the globe which are valid for the globe's
* current state, and <code>false</code> otherwise.
*/
public boolean isVerticesValid(Globe globe)
{
BoxData data = this.boxData.get(globe);
return data != null && data.globeStateKey != null && data.globeStateKey.equals(globe.getGlobeStateKey());
}

/**
* Indicates this box's vertices that associated with the specified globe. This returns <code>null</code> if no
* vertices are currently associated with the specified globe. Specify <code>null</code> to get the vertices that
* are not associated with any globe.
*
* @param globe the globe the vertices are associated with, or <code>null</code> to get the vertices that are not
* associated with any globe.
*
* @return an array of length 8 indicating this box's vertices in model coordinates, or <code>null</code> to
* indicate that no vertices are associated with the globe.
*/
public Vec4[] getVertices(Globe globe)
{
BoxData data = this.boxData.get(globe);
return data != null ? data.vertices : null;
}

/**
* Specifies this box's vertices that are associated with the specified globe. Specify a <code>null</code> globe to
* indicate that the vertices are not associated with any globe. Specify <code>null</code> vertices to remove
* vertices associated with the specified globe. This copies the elements of the specified vertices array; changes
* to the array after this method do not affect the data held by this box.
*
* @param globe the globe the vertices are associated with, or <code>null</code> to indicate that the vertices
* are not associated with any globe.
* @param vertices an array of length 8 indicating this box's vertices in model coordinates, or <code>null</code> to
* remove vertices associated with the specified globe.
*
* @throws IllegalArgumentException if the vertices array is not <code>null</code> and has fewer than eight
* elements.
*/
public void setVertices(Globe globe, Vec4[] vertices)
{
if (vertices == null)
{
this.vertices = null;
this.boxData.remove(globe);
}
else
{
Expand All @@ -255,13 +335,30 @@ public void setVertices(Vec4[] vertices)
throw new IllegalArgumentException(message);
}

if (this.vertices == null)
this.vertices = new Vec4[8];
System.arraycopy(vertices, 0, this.vertices, 0, 8);
BoxData data = this.boxData.get(globe);

// Create a box data if one doesn't already exist and put it in the map.
if (data == null)
{
data = new BoxData();
this.boxData.put(globe, data);
}

// Copy the specified vertices into the data held by this box's map.
System.arraycopy(vertices, 0, data.vertices, 0, 8);
// Update the box data's globe state key.
data.globeStateKey = globe.getGlobeStateKey();
}

this.setExtentOutOfDate();
}

/** Removes all of this box's globe-associated vertex data. */
public void clearVertices()
{
this.boxData.clear();
}

public static Vec4[] computeStandardVertices(Globe globe, double verticalExaggeration, Box box)
{
if (globe == null)
Expand Down Expand Up @@ -368,7 +465,7 @@ protected gov.nasa.worldwind.geom.Box computeExtent(Globe globe, double vertical
@Override
protected List<Vec4> computeMinimalGeometry(Globe globe, double verticalExaggeration)
{
Vec4[] verts = this.getVertices();
Vec4[] verts = this.getVertices(globe);
if (verts == null)
verts = computeStandardVertices(globe, verticalExaggeration, this);

Expand Down Expand Up @@ -499,7 +596,7 @@ protected void doRenderGeometry(DrawContext dc, String drawStyle)
throw new IllegalArgumentException(message);
}

Vec4[] verts = this.getVertices();
Vec4[] verts = this.getVertices(dc.getGlobe());
if (verts == null)
verts = computeStandardVertices(dc.getGlobe(), dc.getVerticalExaggeration(), this);

Expand Down Expand Up @@ -630,7 +727,7 @@ private Geometry getBoxVertexGeometry(DrawContext dc, Vec4[] verts,
int pillars, int stacks, int heightStacks,
Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(this.getClass(), "Box.Vertices",
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "Box.Vertices",
verts, altitudes[0], altitudes[1], terrainConformant[0], terrainConformant[1],
enableCaps[0], enableCaps[1], pillars, stacks, heightStacks, referenceCenter);

Expand Down
Expand Up @@ -556,7 +556,7 @@ private Geometry createCylinderVertexGeometry(DrawContext dc, double radius, dou
boolean[] terrainConformant, int slices, int stacks, int orientation,
Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(this.getClass(), "Cylinder.Vertices",
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "Cylinder.Vertices",
radius, altitudes[0], altitudes[1], terrainConformant[0], terrainConformant[1],
slices, stacks, orientation, referenceCenter);
Geometry vertexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
Expand Down Expand Up @@ -661,7 +661,7 @@ private void drawDisk(DrawContext dc, double[] radii, double altitude, boolean t
int slices, int loops, int orientation,
Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(this.getClass(), "Disk.Vertices",
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "Disk.Vertices",
radii[0], radii[1], altitude, terrainConformant,
slices, loops, orientation, referenceCenter);
Geometry vertexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
Expand Down
Expand Up @@ -347,7 +347,7 @@ protected CurtainGeometry getCurtainGeometry(DrawContext dc, int count, LatLon[]
double[] altitudes, boolean[] terrainConformant,
Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(this.getClass(), "Curtain",
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "Curtain",
locations, pathType, altitudes[0], altitudes[1], terrainConformant[0], terrainConformant[1],
splitThreshold, referenceCenter);

Expand Down
33 changes: 20 additions & 13 deletions WorldWind/src/gov/nasa/worldwind/render/airspaces/Geometry.java
Expand Up @@ -8,11 +8,10 @@
import com.sun.opengl.util.BufferUtil;
import gov.nasa.worldwind.avlist.AVListImpl;
import gov.nasa.worldwind.cache.Cacheable;
import gov.nasa.worldwind.globes.Globe;

import javax.media.opengl.GL;
import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.*;
import java.util.Arrays;

/**
Expand All @@ -23,21 +22,28 @@ public class Geometry extends AVListImpl implements Cacheable
{
public static class CacheKey
{
private final Globe globe;
private final Class cls;
private final String key;
private final Object[] params;
private int hash = 0;

public CacheKey(Class cls, String key, Object... params)
public CacheKey(Globe globe, Class cls, String key, Object... params)
{
this.globe = globe;
this.cls = cls;
this.key = key;
this.params = params;
}

public CacheKey(Class cls, String key, Object... params)
{
this(null, cls, key, params);
}

public CacheKey(String key, Object... params)
{
this(null, key, params);
this(null, null, key, params);
}

public boolean equals(Object o)
Expand All @@ -47,14 +53,16 @@ public boolean equals(Object o)
if (o == null || this.getClass() != o.getClass())
return false;

CacheKey cacheKey = (CacheKey) o;
CacheKey that = (CacheKey) o;

if (this.cls != null ? !this.cls.equals(cacheKey.cls) : cacheKey.cls != null)
if (this.globe != null ? !this.globe.equals(that.globe) : that.globe != null)
return false;
if (this.key != null ? !this.key.equals(cacheKey.key) : cacheKey.key != null)
if (this.cls != null ? !this.cls.equals(that.cls) : that.cls != null)
return false;
if (this.key != null ? !this.key.equals(that.key) : that.key != null)
return false;
//noinspection RedundantIfStatement
if (!Arrays.deepEquals(this.params, cacheKey.params))
if (!Arrays.deepEquals(this.params, that.params))
return false;

return true;
Expand All @@ -65,11 +73,13 @@ public int hashCode()
if (this.hash == 0)
{
int result;
result = (this.cls != null ? cls.hashCode() : 0);
result = (this.globe != null ? this.globe.hashCode() : 0);
result = 31 * result + (this.cls != null ? this.cls.hashCode() : 0);
result = 31 * result + (this.key != null ? this.key.hashCode() : 0);
result = 31 * result + (this.params != null ? Arrays.deepHashCode(this.params) : 0);
this.hash = result;
}

return this.hash;
}
}
Expand Down Expand Up @@ -246,7 +256,6 @@ public void setTextureCoordData(int count, FloatBuffer src)
this.count[NORMAL] = count;
}


public void clear(int type)
{
this.mode[type] = 0;
Expand All @@ -257,8 +266,6 @@ public void clear(int type)
this.buffer[type] = null;
}



public long getSizeInBytes()
{
return this.bufferSize(ELEMENT) + this.bufferSize(VERTEX) + this.bufferSize(NORMAL);
Expand Down
4 changes: 2 additions & 2 deletions WorldWind/src/gov/nasa/worldwind/render/airspaces/Orbit.java
Expand Up @@ -579,7 +579,7 @@ private Geometry createLongCylinderVertexGeometry(DrawContext dc, double radius,
int arcSlices, int lengthSlices, int stacks, int orientation,
Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(this.getClass(), "LongCylinder.Vertices",
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "LongCylinder.Vertices",
radius, length, altitudes[0], altitudes[1], terrainConformant[0], terrainConformant[1], type,
arcSlices, lengthSlices, stacks, orientation, referenceCenter);
Geometry vertexGeom = (Geometry) this.getGeometryCache().getObject(cacheKey);
Expand Down Expand Up @@ -689,7 +689,7 @@ private void drawLongDisk(DrawContext dc,
int arcSlices, int lengthSlices, int loops, int orientation,
Vec4 referenceCenter)
{
Object cacheKey = new Geometry.CacheKey(this.getClass(), "LongDisk.Vertices",
Object cacheKey = new Geometry.CacheKey(dc.getGlobe(), this.getClass(), "LongDisk.Vertices",
radii[0], radii[1], length, altitudes, terrainConformant, type,
arcSlices, lengthSlices, loops, orientation,
referenceCenter);
Expand Down

0 comments on commit 981ed1f

Please sign in to comment.