⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 surfaceshapegeometry.java

📁 world wind java sdk 源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*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;import com.sun.opengl.util.*;import gov.nasa.worldwind.*;import gov.nasa.worldwind.geom.*;import gov.nasa.worldwind.globes.*;import gov.nasa.worldwind.terrain.*;import gov.nasa.worldwind.util.*;import javax.media.opengl.*;import javax.media.opengl.glu.*;import java.awt.*;import java.nio.*;import java.util.*;/** * @author $Author$ * @version $Id: SurfaceShapeGeometry.java 8280 2008-12-24 23:08:45Z tgaskins $ */public abstract class SurfaceShapeGeometry implements Renderable, Disposable, Movable {    protected Globe globe;    protected ArrayList<LatLon> positions = new ArrayList<LatLon>();    private Sector sector;    private Vector<Triangle> triangles;    private Vector<Polygon> polygons = new Vector<Polygon>();    private Polyline polyline;    private Extent extent;    private long lastFrameTime = 0;    private boolean forceSurfaceIntersect = true;    private Color interiorColor;    private float[] interiorColorGL = new float[4];    private boolean drawBorder = true;    private boolean drawInterior = true;    private boolean antiAlias = true;    private DoubleBuffer buff;    private int[] firsts;    private int[] counts;    private static long THROTTLE_RATE = 1000L;    private static final double EPSILON = 1.e-10;    private static final Color DEFAULT_COLOR = new Color(1f, 1f, 0f, 0.4f);    private static final Color DEFAULT_BORDER_COLOR = new Color(1f, 1f, 0f, 0.7f);    // symbolic indices into double[] arrays holding coordinates...    private static final int X = 0;    private static final int Y = 1;    private static final int Z = 2;    public SurfaceShapeGeometry(Iterable<? extends LatLon> positions, Color color, Color borderColor) {        if (positions == null) {            String message = Logging.getMessage("nullValue.PositionsListIsNull");            Logging.logger().severe(message);            throw new IllegalArgumentException(message);        }        setInteriorColor((color != null) ? color : DEFAULT_COLOR);        this.polyline = new Polyline();        this.polyline.setColor(borderColor != null ? borderColor : DEFAULT_BORDER_COLOR);        this.polyline.setFollowTerrain(true);        this.polyline.setPathType(Polyline.LINEAR);        // Copy positions list.        this.replacePositions(positions);    }    private void replacePositions(Iterable<? extends LatLon> newPositions) {        this.positions.clear();        for (LatLon position : newPositions) {            this.positions.add(position);        }        this.polyline.setPositions(this.positions, 0.);        resetBounds();    }    public void dispose() {    }    public ArrayList<Sector> getSectors() {        ArrayList<Sector> sectors = new ArrayList<Sector>();        sectors.add(this.sector);        return sectors;    }    public Iterable<LatLon> getPositions() {        return this.positions;    }    public void setPositions(Iterable<? extends LatLon> positions) {        this.replacePositions(positions);    }    public Paint getInteriorColor() {        return interiorColor;    }    public void setInteriorColor(Color color) {        this.interiorColor = color;        this.interiorColorGL[0] = this.interiorColor.getRed() / 255f;        this.interiorColorGL[1] = this.interiorColor.getGreen() / 255f;        this.interiorColorGL[2] = this.interiorColor.getBlue() / 255f;        this.interiorColorGL[3] = this.interiorColor.getAlpha() / 255f;    }    public Color getBorderColor() {        return this.polyline.getColor();    }    public void setBorderColor(Color borderColor) {        this.polyline.setColor(borderColor);    }    public void setBorderWidth(double width) {        this.polyline.setLineWidth(width);    }    public double getBorderWidth() {        return this.polyline.getLineWidth();    }    public boolean isDrawBorder() {        return drawBorder;    }    public void setDrawBorder(boolean drawBorder) {        this.drawBorder = drawBorder;    }    public boolean isDrawInterior() {        return drawInterior;    }    public void setDrawInterior(boolean drawInterior) {        this.drawInterior = drawInterior;    }    public boolean isAntiAlias() {        return antiAlias;    }    public void setAntiAlias(boolean antiAlias) {        this.antiAlias = antiAlias;    }    /*     * ***********************     * public double getNumEdgeIntervalsPerDegree() {     * return numEdgeIntervalsPerDegree;     * }     * <p/>     * public void setNumEdgeIntervalsPerDegree(double numEdgeIntervals) {     * this.numEdgeIntervalsPerDegree = numEdgeIntervals;     * this.clearTextureData();     * }     * *********************     */    public double getPerimeter()    {        return this.polyline.getLength();    }    public double getArea() throws IllegalStateException {        if (this.polygons == null || this.polygons.size() == 0 || this.globe == null) {            // TODO:  I8N this...            throw new IllegalStateException("NPE in getArea");        }        double area = 0.;        double[] PQ = new double[3];        double[] PR = new double[3];        for (Polygon p : this.polygons) {            // We have 3,4,5,6 sided, convex polygons. Treat them like a triangle-fan, and compute the area            // of the individual triangles using the cross-product method.            for (int i = 2; i < p.numVerts; i++) {                // The convention here is that we have a triangle with vertices P, Q, and R.                // Compute the cross-product of the vectors PQ and PR...                // NOTE: we are purposefully avoiding the use of Vec4 here to avoid having to allocate                // so many instances.                // Also note that we've previously stored the polygon coordinates with the ReferencePoint subtracted,                // so we are not dealing with as huge of numbers in these calculations.                PQ[0] = (p.xy[i - 1][X]) - (p.xy[0][X]);                PQ[1] = (p.xy[i - 1][Y]) - (p.xy[0][Y]);                PQ[2] = (p.xy[i - 1][Z]) - (p.xy[0][Z]);                PR[0] = (p.xy[i][X]) - (p.xy[0][X]);                PR[1] = (p.xy[i][Y]) - (p.xy[0][Y]);                PR[2] = (p.xy[i][Z]) - (p.xy[0][Z]);                // Compute cross product: PQ X PR.  Note that the crossY component should be negated for the actual                // cross product. But we're just after the magnitude of the vector, and are going to "square-away"                // the sign, so it doesn't matter.                double crossX = PQ[Y] * PR[Z] - PR[Y] * PQ[Z];                double crossY = PQ[X] * PR[Z] - PR[X] * PQ[Z];                double crossZ = PQ[X] * PR[Y] - PR[X] * PQ[Y];                area += 0.5 * Math.sqrt(crossX * crossX + crossY * crossY + crossZ * crossZ);            }        }        return area;    }    public void render(DrawContext dc) {        // Capture this right away, as several subsequent computations require it....        this.globe = dc.getGlobe();        Frustum f = dc.getView().getFrustumInModelCoordinates();        if (!getExtent(dc).intersects(f))            return;        // Do we need to perform top-level tessellation?  THis is generally performed once, the first time around...        if (this.triangles == null) {            this.tessellate();        }        if ((System.currentTimeMillis() - this.lastFrameTime) > THROTTLE_RATE || this.forceSurfaceIntersect) {            Iterable<SectorGeometry> geom = getIntersectingGeometryTiles(dc.getSurfaceGeometry());            intersectSurfaceGeometry(geom);            packagePolygonsForDrawing();            this.lastFrameTime = System.currentTimeMillis();            this.forceSurfaceIntersect = false;        }        renderPolygons(dc);    }    //    // Package up the polygon data into a vertex array.    //    private void packagePolygonsForDrawing() {        if (polygons.size() == 0)            return;                int buffSize = 0;        for (Polygon p : this.polygons) {            buffSize += p.numVerts;        }        this.buff = BufferUtil.newDoubleBuffer(buffSize*3);        this.firsts = new int[polygons.size()];        this.counts = new int[polygons.size()];        buffSize = 0;        int i = 0;        for (Polygon p : this.polygons) {            this.firsts[i] = buffSize;            this.counts[i] = p.numVerts;            for (int j=0; j<p.numVerts; j++) {                this.buff.put(p.xy[j]);            }            buffSize += p.numVerts;            i++;        }    }    private void renderPolygons(DrawContext dc) {        Vec4 refPoint = getReferencePoint();        GL gl = dc.getGL();        gl.glPushAttrib(GL.GL_COLOR_BUFFER_BIT | GL.GL_POLYGON_BIT | GL.GL_CURRENT_BIT);        dc.getView().pushReferenceCenter(dc, refPoint);        this.pushOffset(dc);        try {            if (!dc.isPickingMode()) {                gl.glEnable(GL.GL_BLEND);                gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);                gl.glColor4fv(this.interiorColorGL, 0);            }            if (this.drawInterior || dc.isPickingMode()) {                gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);                gl.glEnableClientState(GL.GL_VERTEX_ARRAY);                buff.rewind();                gl.glVertexPointer(3, GL.GL_DOUBLE, 0, buff);                gl.glMultiDrawArrays(GL.GL_TRIANGLE_FAN, this.firsts, 0, this.counts, 0, this.firsts.length);                gl.glDisableClientState(GL.GL_VERTEX_ARRAY);            }            /** pre vertex-array style drawing.  Leave for now; not convinced VA's have helped enough here             *  to warrant their memory overhead.            if (this.drawInterior) {                gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);                for (Polygon p : polygons) {                    gl.glBegin(GL.GL_TRIANGLE_FAN);                    for (int i = 0; i < p.numVerts; i++) {                        gl.glVertex3d(p.xy[i][X]-refPoint.x, p.xy[i][Y]-refPoint.y, p.xy[i][Z]-refPoint.z);                    }                    gl.glEnd();                }            }             ***********/            /******************             // Draw the border...             if (!dc.isPickingMode()) {             gl.glColor4fv(this.borderColorGL, 0);             }             gl.glBegin(GL.GL_LINE_LOOP);             for (LatLon p : positions) {             elev = dc.getGlobe().getElevation(p.getLatitude(), p.getLongitude());             Position pos = new Position(p, elev);             Vec4 pnt = this.globe.computePointFromPosition(pos);             pnt = pnt.subtract3(refCenterPoint);             gl.glVertex3d(pnt.x, pnt.y, pnt.z);             }             gl.glEnd();             ********************/            // delegate to render the border...            if (!dc.isPickingMode() && this.drawBorder)                this.polyline.render(dc);        }        finally {            this.popOffset(dc);            dc.getView().popReferenceCenter(dc);            gl.glPopAttrib();        }    }    private void pushOffset(DrawContext dc) {        // Modify the projection transform to shift the depth values slightly toward the camera in order to        // ensure the lines are selected during depth buffering.        GL gl = dc.getGL();        float[] pm = new float[16];        gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, pm, 0);        pm[10] *= 0.99; // TODO: See Lengyel 2 ed. Section 9.1.2 to compute optimal/minimal offset        gl.glPushAttrib(GL.GL_TRANSFORM_BIT);        gl.glMatrixMode(GL.GL_PROJECTION);        gl.glPushMatrix();        gl.glLoadMatrixf(pm, 0);    }    private void popOffset(DrawContext dc) {        GL gl = dc.getGL();        gl.glMatrixMode(GL.GL_PROJECTION);        gl.glPopMatrix();        gl.glPopAttrib();    }    //    // Intersects the collection of triangles that make up this object with a set of  SectorGeometry    // objects.    //    private void intersectSurfaceGeometry(Iterable<SectorGeometry> geom) {        // clear existing polygon list...        this.polygons.clear();        if (geom == null)            return;        for (SectorGeometry g : geom) {            RectangularTessellator.RectGeometry terrain = RectangularTessellator.getTerrainGeometry(g);            for (Triangle t : this.triangles) {                if (t.spansDateline)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -