📄 ebsrectangulartessellator.java
字号:
/*Copyright (C) 2001, 2006 United States Governmentas represented by the Administrator of theNational Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.terrain.ebs;import com.sun.opengl.util.BufferUtil;import gov.nasa.worldwind.*;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.DrawContext;import gov.nasa.worldwind.terrain.*;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 Jim Miller * @version $Id: EBSRectangularTessellator.java 8723 2009-02-03 03:57:57Z jmiller $ */public class EBSRectangularTessellator extends WWObjectImpl implements Tessellator{ // FOR RAIL EDGE TEXTURE COORDINATE LOGGING: <--- search for this string //public static java.io.PrintWriter[] sectorPW; //public static java.io.PrintWriter curSectorPW = null; //static //{ //String base = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + "EBS_"; //sectorPW=new java.io.PrintWriter[9]; //try //{ //sectorPW[0] = new java.io.PrintWriter(base + "0_LatLonLatLon.txt"); //sectorPW[1] = new java.io.PrintWriter(base + "1_LatLatLonLon.txt"); //sectorPW[2] = new java.io.PrintWriter(base + "2_LatGEGELon.txt"); //sectorPW[3] = new java.io.PrintWriter(base + "3_LatLonGEGE.txt"); //sectorPW[4] = new java.io.PrintWriter(base + "4_LatLatGEGE.txt"); //sectorPW[5] = new java.io.PrintWriter(base + "5_LonLonGEGE.txt"); //sectorPW[6] = new java.io.PrintWriter(base + "6_LatGEGEGE.txt"); //sectorPW[7] = new java.io.PrintWriter(base + "7_LonGEGEGE.txt"); //sectorPW[8] = new java.io.PrintWriter(base + "8_GEGEGEGE.txt"); //} //catch (Exception e) {} //} // protected static class RenderInfo { private final int density; private final int numVerticesDroppedPerRow; private final Vec4 referenceCenter; private final DoubleBuffer vertices; private final DoubleBuffer texCoords; private final IntBuffer indices; private final long time; private RenderInfo(int density, int numVerticesDroppedPerRow, DoubleBuffer vertices, DoubleBuffer texCoords, Vec4 refCenter) { this.density = density; this.numVerticesDroppedPerRow = numVerticesDroppedPerRow; this.vertices = vertices; this.texCoords = texCoords; this.referenceCenter = refCenter; this.indices = getIndices(this.density,this.numVerticesDroppedPerRow); 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; } } private static class RectTile implements SectorGeometry { private final EBSRectangularTessellator tessellator; private final int level; private final EdgeBoundedSector 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(EBSRectangularTessellator tessellator, Extent extent, int level, int density, EdgeBoundedSector sector, double cellSize) { this.tessellator = tessellator; this.level = level; this.density = density; this.sector = sector; this.extent = extent; this.log10CellSize = Math.log10(cellSize); } public DoubleBuffer makeTextureCoordinates(GeographicTextureCoordinateComputer computer) { return null; // TODO: implement this method } public EdgeBoundedSector 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 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 EdgeBoundedSector sector; private final int density; private final Object globeStateKey; public CacheKey(DrawContext dc, EdgeBoundedSector 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; long temp; 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 = 17; private static final int DEFAULT_DENSITY = 20; private static final String CACHE_NAME = "Terrain"; private static final String CACHE_ID = EBSRectangularTessellator.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; // cube-based tessellation parameters private static double latitudeCutoffInDegrees = 40.0; 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); } this.maxLevel = Configuration.getIntegerValue(AVKey.RECTANGULAR_TESSELLATOR_MAX_LEVEL, DEFAULT_MAX_LEVEL); EdgeBoundedSector.recordGlobe(dc.getGlobe()); 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) { this.globe = dc.getGlobe(); boolean forceExtraInitialSubdivisionInPolarRegion = true; // the 4 lateral cube faces are divided into 4 sectors each ( 16) // the top and bottom faces are divided into 16 each // (when forceExtraInitialSubdivisionInPolarRegion==true) (+32) ArrayList<RectTile> tops = new ArrayList<RectTile>(48); EdgeBoundedSector[] s = EdgeBoundedSector.initialCubeMapping(Angle.fromDegrees(latitudeCutoffInDegrees)); for (int i = 0; i < 6; i++) { // Subdivide all the original ones once (partly to avoid having tiles in the polar // regions with deltaLatitude = 0). This first subdivision will produce tiles // subtending 45 degree angles. (Two subdivisions would produce ones subtending 22.5 // degrees.) By comparison, the original RectangularTessellator started with 36 degree // top level tiles. EdgeBoundedSector[] si = (EdgeBoundedSector[])s[i].subdivide();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -