protected void makeTessellatedLocations( Globe globe, int subdivisions, List<LatLon> locations, List<LatLon> tessellatedLocations) { ArrayList<Vec4> points = new ArrayList<Vec4>(); for (LatLon ll : locations) { points.add(globe.computePointFromLocation(ll)); } //noinspection StringEquality if (WWMath.computeWindingOrderOfLocations(locations) != AVKey.COUNTER_CLOCKWISE) Collections.reverse(locations); Vec4 centerPoint = Vec4.computeAveragePoint(points); Vec4 surfaceNormal = globe.computeSurfaceNormalAtPoint(centerPoint); int numPoints = points.size(); float[] coords = new float[3 * numPoints]; for (int i = 0; i < numPoints; i++) { points.get(i).toFloatArray(coords, 3 * i, 3); } GeometryBuilder gb = new GeometryBuilder(); GeometryBuilder.IndexedTriangleArray tessellatedPoints = gb.tessellatePolygon(0, numPoints, coords, surfaceNormal); for (int i = 0; i < subdivisions; i++) { gb.subdivideIndexedTriangleArray(tessellatedPoints); } for (int i = 0; i < tessellatedPoints.getVertexCount(); i++) { Vec4 v = Vec4.fromFloatArray(tessellatedPoints.getVertices(), 3 * i, 3); tessellatedLocations.add(globe.computePositionFromPoint(v)); } }
private void makePolygon( DrawContext dc, List<LatLon> locations, List<Boolean> edgeFlags, double[] altitudes, boolean[] terrainConformant, boolean enableCaps, int subdivisions, Vec4 referenceCenter, PolygonGeometry dest) { if (locations.size() == 0) return; GeometryBuilder gb = this.getGeometryBuilder(); Vec4[] polyPoints = new Vec4[locations.size() + 1]; Boolean[] polyEdgeFlags = new Boolean[locations.size() + 1]; Matrix[] polyTransform = new Matrix[1]; int polyCount = this.computeCartesianPolygon( dc.getGlobe(), locations, edgeFlags, polyPoints, polyEdgeFlags, polyTransform); // Compute the winding order of the planar cartesian points. If the order is not // counter-clockwise, then // reverse the locations and points ordering. int winding = gb.computePolygonWindingOrder2(0, polyCount, polyPoints); if (winding != GeometryBuilder.COUNTER_CLOCKWISE) { gb.reversePoints(0, polyCount, polyPoints); gb.reversePoints(0, polyCount, polyEdgeFlags); } float[] polyVertices = new float[3 * polyCount]; this.makePolygonVertices(polyCount, polyPoints, polyVertices); int fillDrawMode = GL.GL_TRIANGLES; int outlineDrawMode = GL.GL_LINES; int fillIndexCount = 0; int outlineIndexCount = 0; int vertexCount = 0; GeometryBuilder.IndexedTriangleArray ita = null; fillIndexCount += this.getEdgeFillIndexCount(polyCount, subdivisions); outlineIndexCount += this.getEdgeOutlineIndexCount(polyCount, subdivisions, polyEdgeFlags); vertexCount += this.getEdgeVertexCount(polyCount, subdivisions); if (enableCaps) { ita = gb.tessellatePolygon2(0, polyCount, polyVertices); for (int i = 0; i < subdivisions; i++) { gb.subdivideIndexedTriangleArray(ita); } fillIndexCount += ita.getIndexCount(); vertexCount += ita.getVertexCount(); // Bottom cap isn't drawn if airspace is collapsed. if (!this.isAirspaceCollapsed()) { fillIndexCount += ita.getIndexCount(); vertexCount += ita.getVertexCount(); } } int[] fillIndices = new int[fillIndexCount]; int[] outlineIndices = new int[outlineIndexCount]; float[] vertices = new float[3 * vertexCount]; float[] normals = new float[3 * vertexCount]; int fillIndexPos = 0; int outlineIndexPos = 0; int vertexPos = 0; this.makeEdge( dc, polyCount, polyVertices, polyEdgeFlags, altitudes, terrainConformant, subdivisions, GeometryBuilder.OUTSIDE, polyTransform[0], referenceCenter, fillIndexPos, fillIndices, outlineIndexPos, outlineIndices, vertexPos, vertices, normals); fillIndexPos += this.getEdgeFillIndexCount(polyCount, subdivisions); outlineIndexPos += this.getEdgeOutlineIndexCount(polyCount, subdivisions, polyEdgeFlags); vertexPos += this.getEdgeVertexCount(polyCount, subdivisions); if (enableCaps) { this.makeCap( dc, ita, altitudes[1], terrainConformant[1], GeometryBuilder.OUTSIDE, polyTransform[0], referenceCenter, fillIndexPos, fillIndices, vertexPos, vertices, normals); fillIndexPos += ita.getIndexCount(); vertexPos += ita.getVertexCount(); // Bottom cap isn't drawn if airspace is collapsed. if (!this.isAirspaceCollapsed()) { this.makeCap( dc, ita, altitudes[0], terrainConformant[0], GeometryBuilder.INSIDE, polyTransform[0], referenceCenter, fillIndexPos, fillIndices, vertexPos, vertices, normals); fillIndexPos += ita.getIndexCount(); vertexPos += ita.getVertexCount(); } } dest.getFillIndexGeometry().setElementData(fillDrawMode, fillIndexCount, fillIndices); dest.getOutlineIndexGeometry() .setElementData(outlineDrawMode, outlineIndexCount, outlineIndices); dest.getVertexGeometry().setVertexData(vertexCount, vertices); dest.getVertexGeometry().setNormalData(vertexCount, normals); }