📄 conformingpolygon.java
字号:
float[] colorArray = new float[4]; MemoryCache partitionCache = WorldWind.getMemoryCache(CONFORMINGSHAPE_CACHE_KEY); boolean foundIntersectingPartition = false; if (drawInterior || drawBorder) // make sure cache up to date { for (ConvexPartition partition : this.partitions) { CacheKey key = new CacheKey(this.getClass(),partition.getSector(), partition.serialNumber); CachedShapeDescription csd = (CachedShapeDescription)partitionCache.getObject(key); ArrayList<SectorGeometry.ExtractedShapeDescription> esdL = null; if (csd != null) esdL = csd.esdL; if ((esdL == null) || isExpired(dc)) { if (esdL != null) { partitionCache.remove(key); esdL = null; } Plane[] partitionPlanes = partition.getBoundingPlanes(); Sector[] partitionSector = partition.getSector(); for (SectorGeometry sg : dc.getSurfaceGeometry()) { boolean proceed = false; for (Sector s : partitionSector) if (sg.getSector().intersects(s)) { proceed = true; break; } if (proceed) { SectorGeometry.ExtractedShapeDescription sgPolygons = sg.getIntersectingTessellationPieces(partitionPlanes); if (sgPolygons != null) { if (esdL == null) esdL = new ArrayList<SectorGeometry.ExtractedShapeDescription>(4); esdL.add(sgPolygons); foundIntersectingPartition = true; } } } if (esdL != null) partitionCache.add(key, new CachedShapeDescription(esdL), sizeInBytesOf(esdL)); } if ( (esdL != null) && drawInterior) for (SectorGeometry.ExtractedShapeDescription esd : esdL) for (Vec4[] sgT : esd.interiorPolys) { if (!dc.isPickingMode()) gl.glColor4fv(fillColor.getComponents(colorArray),0); gl.glBegin(GL.GL_POLYGON); for (Vec4 v : sgT) gl.glVertex3d(v.getX(),v.getY(),v.getZ()); gl.glEnd(); } } updateExpiryCriteria(dc); } return foundIntersectingPartition; } protected void renderBoundary(DrawContext dc, GL gl, boolean knownToBeVisible) { if (globe == null) globe = dc.getGlobe(); if (rebuildPartitions) // probably just did a restoreState createPartitions(); if (!knownToBeVisible) { // the shape may or may not be visible; knownToBeVisible could be // false here either because we are not drawing the interiors, or // because we extracted data from the cache. for (ConvexPartition partition : this.partitions) { Sector[] partitionSector = partition.getSector(); for (SectorGeometry sg : dc.getSurfaceGeometry()) { for (Sector s : partitionSector) if (sg.getSector().intersects(s)) { knownToBeVisible = true; break; } if (knownToBeVisible) break; } if (knownToBeVisible) break; } } if (drawBorder && knownToBeVisible) { float[] colorArray = new float[4]; if (!dc.isPickingMode()) gl.glColor4fv(borderColor.getComponents(colorArray),0); MemoryCache partitionCache = WorldWind.getMemoryCache(CONFORMINGSHAPE_CACHE_KEY); for (ConvexPartition partition : this.partitions) { CacheKey key = new CacheKey(this.getClass(),partition.getSector(), partition.serialNumber); CachedShapeDescription csd = (CachedShapeDescription)partitionCache.getObject(key); ArrayList<SectorGeometry.ExtractedShapeDescription> esdL = null; if (csd != null) esdL = csd.esdL; if (esdL != null) for (SectorGeometry.ExtractedShapeDescription esd : esdL) { gl.glBegin(GL.GL_LINES); for (SectorGeometry.BoundaryEdge be : esd.shapeOutline) { Vec4 v1 = be.vertices[be.i1]; Vec4 v2 = be.vertices[be.i2]; if (externalEdge(partition,v1,v2)) { gl.glVertex3d(v1.x,v1.y,v1.z); gl.glVertex3d(v2.x,v2.y,v2.z); } } gl.glEnd(); } } } } protected void setOriginalVertices(Iterable<? extends LatLon> vertices) { // This protected method assumes that the convexity/concavity has not changed. // Note that it uses "this.tessellateContour" as set by the constructor! this.originalVertices.clear(); // the last vertex is a copy of the first, but that confuses the // various pieces of the tessellation logic. We therefore ignore the // first vertex here. boolean first = true; for (LatLon ll : vertices) { if (first) first = false; else this.originalVertices.add(ll); } createPartitions(); } private void createPartitions() { this.partitions.clear(); if (this.tessellateContour && (originalVertices.size() > 3)) // use the glu tessellator to create triangles defining the shape. tessellate(); else partitions.add( new ConvexPartition(globe,originalVertices,null) ); this.rebuildPartitions = false; } protected void doGetRestorableState(RestorableSupport rs, RestorableSupport.StateObject context) { if (this.originalVertices != null) rs.addStateValueAsLatLonList(context, "locations", this.originalVertices); rs.addStateValueAsBoolean(context, "tessellateContour", this.tessellateContour); } protected void doRestoreState(RestorableSupport rs, RestorableSupport.StateObject context) { ArrayList<LatLon> locations = rs.getStateValueAsLatLonList(context, "locations"); if (locations != null) this.originalVertices = locations; Boolean tess = rs.getStateValueAsBoolean(context, "tessellateContour"); if (tess != null) this.tessellateContour = tess.booleanValue(); // force following to be recomputed at the next opportunity this.rebuildPartitions = true; this.globe = null; } public double getLength(Globe globe) { if (areaMeasurer == null) makeAreaMeasurer(); return areaMeasurer.getLength(globe); } public double getArea(Globe globe) { if (areaMeasurer == null) makeAreaMeasurer(); return areaMeasurer.getArea(globe); } public double getPerimeter(Globe globe) { if (areaMeasurer == null) makeAreaMeasurer(); return areaMeasurer.getPerimeter(globe); } public double getWidth(Globe globe) { if (areaMeasurer == null) makeAreaMeasurer(); return areaMeasurer.getWidth(globe); } public double getHeight(Globe globe) { if (areaMeasurer == null) makeAreaMeasurer(); return areaMeasurer.getHeight(globe); } private void makeAreaMeasurer() { ArrayList<Position> positions = new ArrayList<Position>(originalVertices.size() + 1); for (LatLon ll : originalVertices) positions.add(new Position(ll.getLatitude(),ll.getLongitude(),0.0)); positions.add(positions.get(0)); areaMeasurer = new AreaMeasurer(positions); areaMeasurer.setFollowTerrain(true); } private void tessellate() { TessCallback tcb = new TessCallback(partitions,globe); GLUtessellator theTess = glu.gluNewTess(); glu.gluTessCallback(theTess,GLU.GLU_TESS_BEGIN,tcb); glu.gluTessCallback(theTess,GLU.GLU_TESS_VERTEX,tcb); glu.gluTessCallback(theTess,GLU.GLU_TESS_END,tcb); glu.gluTessBeginPolygon(theTess, null); glu.gluTessBeginContour(theTess); int i = 0; for (LatLon ll : this.originalVertices) { double[] xyz = { 0.0, 0.0, 0.0 }; xyz[0] = ll.getLongitude().radians; xyz[1] = ll.getLatitude().radians; TaggedLatLonVertex tLLV = new TaggedLatLonVertex(ll,i); glu.gluTessVertex(theTess,xyz,0,tLLV); i++; } glu.gluTessEndContour(theTess); glu.gluTessEndPolygon(theTess); } private static class TaggedLatLonVertex { public TaggedLatLonVertex(LatLon ll, int i) { this.ll = ll; this.ll_index = i; } public LatLon ll; public int ll_index; } private static class TessCallback implements GLUtessellatorCallback { private int beginType; private ArrayList<ConvexPartition> partitions; private Globe globe; private TaggedLatLonVertex[] workingStore; private int nextWSLoc; public TessCallback(ArrayList<ConvexPartition> partitions, Globe globe) { this.beginType = -1; this.partitions = partitions; this.globe = globe; this.workingStore = new TaggedLatLonVertex[3]; this.nextWSLoc = 0; } public void begin(int type) { beginType = type; nextWSLoc = 0; } public void beginData(int type, Object polygonData) {} public void combine(double[] coords, Object[] data, float[] weight, Object[] outData) {} public void combineData(double[] coords, Object[] data, float[] weight, Object[] outData, Object polygonData) {} public void edgeFlag(boolean boundaryEdge) {} public void edgeFlagData(boolean boundaryEdge, Object polygonData) {} public void end() { beginType = nextWSLoc = -1; } public void endData(Object polygonData) {} public void error(int errnum) {} public void errorData(int errnum, Object polygonData) {} public void vertex(Object vertexData) { TaggedLatLonVertex tLLV = (TaggedLatLonVertex)vertexData; workingStore[nextWSLoc++] = tLLV; if (nextWSLoc == 3) { ArrayList<LatLon> loc = new ArrayList<LatLon>(3); loc.add(workingStore[0].ll); loc.add(workingStore[1].ll); loc.add(workingStore[2].ll); int[] index = { workingStore[0].ll_index, workingStore[1].ll_index, workingStore[2].ll_index }; partitions.add( new ConvexPartition(globe,loc,index) ); switch (beginType) { case GL.GL_TRIANGLE_FAN: workingStore[1] = workingStore[2]; nextWSLoc = 2; break; case GL.GL_TRIANGLE_STRIP: workingStore[0] = workingStore[1]; workingStore[1] = workingStore[2]; nextWSLoc = 2; break; case GL.GL_TRIANGLES: nextWSLoc = 0; break; default: } } } public void vertexData(Object vertexData, Object polygonData) {} }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -