📄 tiledsurfaceobjectrenderer.java
字号:
OGLStateSupport stateSupport = new OGLStateSupport(); stateSupport.setEnableAlphaTest(true); stateSupport.setEnableBlending(!dc.isPickingMode()); stateSupport.setColorMode(OGLStateSupport.COLOR_PREMULTIPLIED_ALPHA); int attribBits = stateSupport.getAttributeBits() | GL.GL_COLOR_BUFFER_BIT | GL.GL_CURRENT_BIT | GL.GL_POLYGON_BIT; stackHandler.pushAttrib(gl, attribBits); stateSupport.apply(gl); gl.glPolygonMode(GL.GL_FRONT, GL.GL_FILL); gl.glEnable(GL.GL_CULL_FACE); gl.glCullFace(GL.GL_BACK); } protected void endRendering(DrawContext dc, OGLStackHandler stackHandler) { stackHandler.pop(dc.getGL()); } protected PickedObject bindPickableObject(DrawContext dc, Object userObject, Object objectId) { java.awt.Color pickColor = dc.getUniquePickColor(); int colorCode = pickColor.getRGB(); dc.getGL().glColor3ub((byte) pickColor.getRed(), (byte) pickColor.getGreen(), (byte) pickColor.getBlue()); PickedObject po = new PickedObject(colorCode, userObject); if (objectId != null) { po.setValue(AVKey.PICKED_OBJECT_ID, objectId); } this.pickSupport.addPickableObject(po); return po; } protected void resolvePick(DrawContext dc, java.awt.Point pickPoint, Layer layer) { if (pickPoint == null) return; PickedObject topObject = this.getTopPickedSurfaceObject(dc, pickPoint); if (topObject == null) return; // Surface objects are by definition on the geometry defined by the terrain. Therefore if no terrain has been // picked, we know that no surface object has been picked. But the converse is not true. Position terrainPosition = this.getPickedTerrainPosition(dc); if (terrainPosition != null) { topObject.setPosition(terrainPosition); } if (layer != null) { topObject.setParentLayer(layer); } dc.addPickedObject(topObject); } protected PickedObject getTopPickedSurfaceObject(DrawContext dc, java.awt.Point pickPoint) { PickedObject topPickedObject = this.pickSupport.getTopObject(dc, pickPoint); if (topPickedObject == null) { return null; } Object topObject = topPickedObject.getObject(); if (topObject == null || !(topObject instanceof SurfaceObject)) { return null; } return topPickedObject; } protected Position getPickedTerrainPosition(DrawContext dc) { PickedObject pickedTerrain = dc.getPickedObjects().getTerrainObject(); if (pickedTerrain != null) { return pickedTerrain.getPosition(); } View view = dc.getView(); Globe globe = dc.getGlobe(); if (view == null || globe == null) { return null; } java.awt.Point pickPoint = dc.getPickPoint(); if (pickPoint == null) { return null; } Line pickRay = view.computeRayFromScreenPoint(pickPoint.getX(), pickPoint.getY()); SectorGeometryList sectorGeometry = dc.getSurfaceGeometry(); if (sectorGeometry != null) { Intersection[] intersection = sectorGeometry.intersect(pickRay); if (intersection != null && intersection.length != 0) { return globe.computePositionFromPoint(intersection[0].getIntersectionPoint()); } } return globe.getIntersectionPosition(pickRay); } //**************************************************************// //******************** Surface Object Assembly ***************// //**************************************************************// protected static class SurfaceObjectInfo { protected SurfaceObject surfaceObject; protected Iterable<? extends Sector> sectors; public SurfaceObjectInfo(SurfaceObject object, Iterable<? extends Sector> sectors) { if (object == null) { String message = Logging.getMessage("nullValue.ObjectIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (sectors == null) { String message = Logging.getMessage("nullValue.IterableIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.surfaceObject = object; this.sectors = sectors; } public SurfaceObject getSurfaceObject() { return this.surfaceObject; } public Iterable<? extends Sector> getSectors() { return this.sectors; } public boolean contains(LatLon latLon) { if (latLon == null) { String message = Logging.getMessage("nullValue.LatLonIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } for (Sector s : this.sectors) { if (s.contains(latLon)) { return true; } } return false; } public boolean contains(Sector sector) { if (sector == null) { String message = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } for (Sector s : this.sectors) { if (s.contains(sector)) { return true; } } return false; } public boolean intersects(Sector sector) { if (sector == null) { String message = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } for (Sector s : this.sectors) { if (s.intersects(sector)) { return true; } } return false; } } protected static class SurfaceObjectState { protected long lastModifiedTime; protected java.util.List<SurfaceObject> surfaceObjectList; public SurfaceObjectState(java.util.List<SurfaceObject> currentSurfaceObjects) { this.surfaceObjectList = currentSurfaceObjects; for (SurfaceObject surfaceObject : currentSurfaceObjects) { if (this.lastModifiedTime < surfaceObject.getLastModifiedTime()) this.lastModifiedTime = surfaceObject.getLastModifiedTime(); } } public long getLastModifiedTime() { return this.lastModifiedTime; } public void setLastModifiedTime(long time) { this.lastModifiedTime = time; } public Iterable<? extends SurfaceObject> getSurfaceObjects() { return this.surfaceObjectList; } public boolean isStateNewerOrModified(SurfaceObjectState that) { //noinspection SimplifiableIfStatement if (that == null) { return false; } return (this.lastModifiedTime < that.lastModifiedTime) || !this.surfaceObjectList.equals(that.surfaceObjectList); } } @SuppressWarnings({"UnusedDeclaration"}) protected void clearSurfaceObjects(DrawContext dc) { this.currentSurfaceObjects.clear(); } protected void assembleSurfaceObjects(DrawContext dc) { for (SurfaceObject surfaceObject : this.surfaceObjectIterable) { this.addSurfaceObject(dc, surfaceObject); } this.currentBoundingSector = this.computeCurrentBoundingSector(); } protected void addSurfaceObject(DrawContext dc, SurfaceObject surfaceObject) { Iterable<? extends Sector> sectors = surfaceObject.getSectors(dc); if (sectors == null) return; SurfaceObjectInfo objectInfo = new SurfaceObjectInfo(surfaceObject, sectors); this.currentSurfaceObjects.add(objectInfo); } protected Sector computeCurrentBoundingSector() { Sector boundingSector = null; for (SurfaceObjectInfo objectInfo : this.currentSurfaceObjects) { for (Sector sector : objectInfo.getSectors()) { boundingSector = (boundingSector != null) ? boundingSector.union(sector) : sector; } } return boundingSector; } protected SurfaceObjectState getCurrentStateFor(Sector sector) { java.util.List<SurfaceObject> intersectingObjects = new java.util.ArrayList<SurfaceObject>(); for (SurfaceObjectInfo objectInfo : this.currentSurfaceObjects) { if (objectInfo.intersects(sector)) { intersectingObjects.add(objectInfo.getSurfaceObject()); } } return new SurfaceObjectState(intersectingObjects); } //**************************************************************// //******************** Tile Assembly *************************// //**************************************************************// @SuppressWarnings({"UnusedDeclaration"}) protected void clearTiles(DrawContext dc) { this.currentTiles.clear(); } protected void assembleTiles(DrawContext dc) { if (this.currentSurfaceObjects.isEmpty()) return; if (this.currentBoundingSector == null || this.currentBoundingSector.equals(Sector.EMPTY_SECTOR)) return; for (TextureTile tile : assembleTopLevelTiles(this.levelSet, this.currentBoundingSector)) { this.addTileOrDescendants(dc, tile); } dc.setPerFrameStatistic(PerformanceStatistic.IMAGE_TILE_COUNT, this.tileCountName, this.currentTiles.size()); this.assemblePickTile(dc); } protected void assemblePickTile(DrawContext dc) { this.havePickTile = false; if (!this.pickEnabled) return; Position pickedTerrainPosition = this.getPickedTerrainPosition(dc); if (pickedTerrainPosition != null) { TextureTile pickedTile = this.getIntersectingTile( pickedTerrainPosition.getLatitude(), pickedTerrainPosition.getLongitude(), this.currentTiles); if (pickedTile != null) { this.pickTile.setSector(pickedTile.getSector()); this.pickTile.setPreferredWidth(pickedTile.getLevel().getTileWidth()); this.pickTile.setPreferredHeight(pickedTile.getLevel().getTileHeight()); this.havePickTile = true; } } } protected void addTileOrDescendants(DrawContext dc, TextureTile tile) { if (!this.isTileVisible(dc, tile)) return; if (!this.isTileNeeded(dc, tile)) return; if (this.isTileMeetsRenderCriteria(dc, tile)) { this.addTile(dc, tile); return; } Level nextLevel = this.levelSet.getLevel(tile.getLevelNumber() + 1); for (TextureTile subTile : tile.createSubTiles(nextLevel)) { this.addTileOrDescendants(dc, subTile); } } @SuppressWarnings({"UnusedDeclaration"}) protected void addTile(DrawContext dc, TextureTile tile) { this.currentTiles.add(tile); } protected boolean isTileVisible(DrawContext dc, SurfaceTile tile) { if (dc.getVisibleSector() != null && !dc.getVisibleSector().intersects(tile.getSector())) { return false; } //noinspection RedundantIfStatement if (!tile.getExtent(dc).intersects(dc.getView().getFrustumInModelCoordinates())) { return false; } return true; } @SuppressWarnings({"UnusedDeclaration"}) protected boolean isTileNeeded(DrawContext dc, Tile tile) { // If tile does not intersect any surface object's bounding sector, the tile is not needed. if (!tile.getSector().intersects(this.currentBoundingSector)) { return false; } // If the tile falls completely outside the bounding sectors of all surface objects, then this tile is not // needed. boolean haveIntersection = false; for (SurfaceObjectInfo objectInfo : this.currentSurfaceObjects) { if (objectInfo.intersects(tile.getSector())) { haveIntersection = true; break; } } return haveIntersection; } protected boolean isTileMeetsRenderCriteria(DrawContext dc, Tile tile) { Level level = tile.getLevel(); if (this.levelSet.isFinalLevel(level.getLevelNumber())) { return true; } // Test the tile against screen metrics. This will attempt to keep the tile texel to screen pixel ratio // close to the user specified value. Substitude the current tile viewport for the level's width and height, // sinde the viewport dimensions are used to define the actual texture dimensions for this tile. return !this.needToSubdivide(dc, tile.getSector(), this.currentTileViewport.width, this.currentTileViewport.height); } protected TextureTile getIntersectingTile(Angle latitude, Angle longitude, Iterable<? extends TextureTile> tiles) { for (TextureTile tile : tiles) { if (tile.getSector().contains(latitude, longitude))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -