partialcappedcylinder.java
来自「world wind java sdk 源码」· Java 代码 · 共 724 行 · 第 1/2 页
JAVA
724 行
/*Copyright (C) 2001, 2008 United States Governmentas represented by the Administrator of theNational Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.render.airspaces;import gov.nasa.worldwind.geom.*;import gov.nasa.worldwind.globes.Globe;import gov.nasa.worldwind.render.DrawContext;import gov.nasa.worldwind.util.GeometryBuilder;import gov.nasa.worldwind.util.Logging;import gov.nasa.worldwind.util.RestorableSupport;import javax.media.opengl.GL;import java.util.ArrayList;import java.util.List;/** * A cylinder defined by a geographic position, a radius in meters, and minimum and maximum altitudes. * * @author tag * @version $Id: PartialCappedCylinder.java 9232 2009-03-06 05:52:06Z 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(); } //**************************************************************// //******************** 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 Extent doComputeExtent(DrawContext dc) { double[] angles = this.computeAngles(); // Angles are equal, fall back to building a closed cylinder. if (angles == null) return super.doComputeExtent(dc); double[] radii = this.getRadii(); Matrix transform = this.computeTransform(dc); GeometryBuilder gb = this.getGeometryBuilder(); int count = gb.getPartialCylinderVertexCount(8, 0); int numCoords = 3 * count; float[] verts = new float[numCoords]; gb.makePartialCylinderVertices((float) Math.max(radii[0], radii[1]), 0.0f, 8, 0, (float) angles[0], (float) angles[2], verts); List<LatLon> locations = new ArrayList<LatLon>(); 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(dc.getGlobe().computePositionFromPoint(v)); } return this.computeBoundingCylinder(dc, locations); } 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(); GL gl = dc.getGL(); 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()) { gl.glPushAttrib(GL.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); } } if (this.isEnableCaps()) { gl.glPopAttrib(); } } dc.getView().popReferenceCenter(dc); } //**************************************************************// //******************** 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(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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?