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 + -
显示快捷键?