?? rectangularnormaltessellator.java
字號(hào):
/*
Copyright (C) 2001, 2009 United States Government
as represented by the Administrator of the
National Aeronautics and Space Administration.
All Rights Reserved.
*/
package gov.nasa.worldwind.examples.sunlight;
import com.sun.opengl.util.BufferUtil;
import gov.nasa.worldwind.*;
import gov.nasa.worldwind.terrain.*;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.cache.*;
import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.pick.*;
import gov.nasa.worldwind.render.*;
import gov.nasa.worldwind.util.Logging;
import javax.media.opengl.GL;
import java.awt.*;
import java.nio.*;
import java.util.*;
import java.util.List;
/**
* @author tag
* @version $Id: RectangularNormalTessellator.java 10406 2009-04-22 18:28:45Z patrickmurris $
*
* Modified by Michael de Hoog to add simple normals based on globe
* ellipse, (globe.computeSurfaceNormalAtPoint()), also added more
* exact normal calculator for terrain tiles, see getNormals()
*/
public class RectangularNormalTessellator extends WWObjectImpl implements Tessellator
{
protected static class RenderInfo
{
private final int density;
private final Vec4 referenceCenter;
private final DoubleBuffer vertices;
private final DoubleBuffer normals;
private final DoubleBuffer texCoords;
private final IntBuffer indices;
private final long time;
private RenderInfo(int density, DoubleBuffer vertices, DoubleBuffer texCoords, DoubleBuffer normals, Vec4 refCenter)
{
this.density = density;
this.vertices = vertices;
this.texCoords = texCoords;
this.referenceCenter = refCenter;
this.indices = getIndices(this.density);
this.normals = normals;
this.time = System.currentTimeMillis();
}
private long getSizeInBytes()
{
// Texture coordinates are shared among all tiles of the same density, so do not count towards size.
// 8 references, doubles in buffer.
return 8 * 4 + (this.vertices.limit()) * Double.SIZE;
}
}
public static class RectTile implements SectorGeometry
{
private final RectangularNormalTessellator tessellator;
private final int level;
private final Sector sector;
private final int density;
private final double log10CellSize;
private Extent extent; // extent of sector in object coordinates
private RenderInfo ri;
private int minColorCode = 0;
private int maxColorCode = 0;
public RectTile(RectangularNormalTessellator tessellator, Extent extent,
int level, int density, Sector sector, double cellSize)
{
this.tessellator = tessellator;
this.level = level;
this.density = density;
this.sector = sector;
this.extent = extent;
this.log10CellSize = Math.log10(cellSize);
}
public Sector getSector()
{
return this.sector;
}
public Extent getExtent()
{
return this.extent;
}
public void renderMultiTexture(DrawContext dc, int numTextureUnits)
{
this.tessellator.renderMultiTexture(dc, this, numTextureUnits);
}
public void render(DrawContext dc)
{
this.tessellator.render(dc, this);
}
public void renderWireframe(DrawContext dc, boolean showTriangles,
boolean showTileBoundary)
{
this.tessellator.renderWireframe(dc, this, showTriangles,
showTileBoundary);
}
public void renderBoundingVolume(DrawContext dc)
{
this.tessellator.renderBoundingVolume(dc, this);
}
public PickedObject[] pick(DrawContext dc, List<? extends Point> pickPoints)
{
return this.tessellator.pick(dc, this, pickPoints);
}
public void pick(DrawContext dc, Point pickPoint)
{
this.tessellator.pick(dc, this, pickPoint);
}
public Vec4 getSurfacePoint(Angle latitude, Angle longitude,
double metersOffset)
{
return this.tessellator.getSurfacePoint(this, latitude, longitude,
metersOffset);
}
public double getResolution()
{
return this.sector.getDeltaLatRadians() / this.density;
}
public Intersection[] intersect(Line line)
{
return this.tessellator.intersect(this, line);
}
public Intersection[] intersect(double elevation)
{
return this.tessellator.intersect(this,elevation);
}
public DoubleBuffer makeTextureCoordinates(GeographicTextureCoordinateComputer computer)
{
return this.tessellator.makeGeographicTexCoords(this, computer);
}
public ExtractedShapeDescription getIntersectingTessellationPieces(Plane[] p)
{
return this.tessellator.getIntersectingTessellationPieces(this,p);
}
public ExtractedShapeDescription getIntersectingTessellationPieces(Vec4 Cxyz,
Vec4 uHat, Vec4 vHat, double uRadius, double vRadius)
{
return this.tessellator.getIntersectingTessellationPieces(this,Cxyz,
uHat,vHat,uRadius,vRadius);
}
}
private static class CacheKey
{
private final Sector sector;
private final int density;
private final Object globeStateKey;
public CacheKey(DrawContext dc, Sector sector, int density)
{
this.sector = sector;
this.density = density;
this.globeStateKey = dc.getGlobe().getStateKey(dc);
}
@SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"})
public boolean equals(Object o)
{
if (this == o) return true;
CacheKey cacheKey = (CacheKey) o; // Note: no check of class type equivalence, for performance
if (density != cacheKey.density) return false;
if (globeStateKey != null ? !globeStateKey.equals(cacheKey.globeStateKey) : cacheKey.globeStateKey != null)
return false;
//noinspection RedundantIfStatement
if (sector != null ? !sector.equals(cacheKey.sector) : cacheKey.sector != null) return false;
return true;
}
public int hashCode()
{
int result;
result = (sector != null ? sector.hashCode() : 0);
result = 31 * result + density;
result = 31 * result + (globeStateKey != null ? globeStateKey.hashCode() : 0);
return result;
}
}
// TODO: Make all this configurable
private static final double DEFAULT_LOG10_RESOLUTION_TARGET = 1.3;
private static final int DEFAULT_MAX_LEVEL = 12;
private static final int DEFAULT_NUM_LAT_SUBDIVISIONS = 5;
private static final int DEFAULT_NUM_LON_SUBDIVISIONS = 10;
private static final int DEFAULT_DENSITY = 20;
private static final String CACHE_NAME = "Terrain";
private static final String CACHE_ID = RectangularNormalTessellator.class.getName();
// Tri-strip indices and texture coordinates. These depend only on density and can therefore be statically cached.
private static final HashMap<Integer, DoubleBuffer> parameterizations = new HashMap<Integer, DoubleBuffer>();
private static final HashMap<Integer, IntBuffer> indexLists = new HashMap<Integer, IntBuffer>();
private ArrayList<RectTile> topLevels;
private PickSupport pickSupport = new PickSupport();
private SectorGeometryList currentTiles = new SectorGeometryList();
private Frustum currentFrustum;
private Sector currentCoverage; // union of all tiles selected during call to render()
private boolean makeTileSkirts = true;
private int currentLevel;
private int maxLevel = DEFAULT_MAX_LEVEL;
private Globe globe;
private int density = DEFAULT_DENSITY;
// Lighting
private Vec4 lightDirection;
private Material material = new Material(Color.WHITE);
private Color lightColor = Color.WHITE;
private Color ambientColor = new Color(.1f, .1f, .1f);
public SectorGeometryList tessellate(DrawContext dc)
{
if (dc == null)
{
String msg = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (dc.getView() == null)
{
String msg = Logging.getMessage("nullValue.ViewIsNull");
Logging.logger().severe(msg);
throw new IllegalStateException(msg);
}
if (!WorldWind.getMemoryCacheSet().containsCache(CACHE_ID))
{
long size = Configuration.getLongValue(
AVKey.SECTOR_GEOMETRY_CACHE_SIZE, 20000000L);
MemoryCache cache = new BasicMemoryCache((long) (0.85 * size), size);
cache.setName(CACHE_NAME);
WorldWind.getMemoryCacheSet().addCache(CACHE_ID, cache);
}
if (this.topLevels == null)
this.topLevels = this.createTopLevelTiles(dc);
this.currentTiles.clear();
this.currentLevel = 0;
this.currentCoverage = null;
this.currentFrustum = dc.getView().getFrustumInModelCoordinates();
for (RectTile tile : this.topLevels)
{
this.selectVisibleTiles(dc, tile);
}
this.currentTiles.setSector(this.currentCoverage);
for (SectorGeometry tile : this.currentTiles)
{
this.makeVerts(dc, (RectTile) tile);
}
return this.currentTiles;
}
private ArrayList<RectTile> createTopLevelTiles(DrawContext dc)
{
ArrayList<RectTile> tops = new ArrayList<RectTile>(
DEFAULT_NUM_LAT_SUBDIVISIONS * DEFAULT_NUM_LON_SUBDIVISIONS);
this.globe = dc.getGlobe();
double deltaLat = 180d / DEFAULT_NUM_LAT_SUBDIVISIONS;
double deltaLon = 360d / DEFAULT_NUM_LON_SUBDIVISIONS;
Angle lastLat = Angle.NEG90;
for (int row = 0; row < DEFAULT_NUM_LAT_SUBDIVISIONS; row++)
{
Angle lat = lastLat.addDegrees(deltaLat);
if (lat.getDegrees() + 1d > 90d)
lat = Angle.POS90;
Angle lastLon = Angle.NEG180;
for (int col = 0; col < DEFAULT_NUM_LON_SUBDIVISIONS; col++)
{
Angle lon = lastLon.addDegrees(deltaLon);
if (lon.getDegrees() + 1d > 180d)
lon = Angle.POS180;
Sector tileSector = new Sector(lastLat, lat, lastLon, lon);
tops.add(this.createTile(dc, tileSector, 0));
lastLon = lon;
}
lastLat = lat;
}
return tops;
}
private RectTile createTile(DrawContext dc, Sector tileSector, int level)
{
Cylinder cylinder = dc.getGlobe().computeBoundingCylinder(
dc.getVerticalExaggeration(), tileSector);
double cellSize = tileSector.getDeltaLatRadians()
* dc.getGlobe().getRadius() / this.density;
return new RectTile(this, cylinder, level, this.density, tileSector,
cellSize);
}
public boolean isMakeTileSkirts()
{
return makeTileSkirts;
}
public void setMakeTileSkirts(boolean makeTileSkirts)
{
this.makeTileSkirts = makeTileSkirts;
}
public Vec4 getLightDirection()
{
return this.lightDirection;
}
public void setLightDirection(Vec4 direction)
{
this.lightDirection = direction;
}
public Color getLightColor()
{
return this.lightColor;
}
public void setLightColor(Color color)
{
if (color == null)
{
String msg = Logging.getMessage("nullValue.ColorIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
this.lightColor = color;
}
public Color getAmbientColor()
{
return this.ambientColor;
}
public void setAmbientColor(Color color)
{
if (color == null)
{
String msg = Logging.getMessage("nullValue.ColorIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
this.ambientColor = color;
}
// public int getTargetResolution(DrawContext dc, RectTile tile)
// {
// return dc.getGlobe().getElevationModel().getTargetResolution(dc, tile.sector, tile.density);
// }
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -