/* Copyright (C) 2001, 2006 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. */ package gov.nasa.worldwind.globes; import gov.nasa.worldwind.geom.*; import gov.nasa.worldwind.pick.*; import gov.nasa.worldwind.render.DrawContext; import gov.nasa.worldwind.util.Logging; import javax.media.opengl.GL; import java.awt.*; import java.util.*; import java.util.List; /** * @author tag * @version $Id: SectorGeometryList.java 3632 2007-11-28 03:28:17Z tgaskins $ */ public class SectorGeometryList extends ArrayList<SectorGeometry> { private Sector sector; private PickSupport pickSupport = new PickSupport(); public SectorGeometryList() { } public SectorGeometryList(SectorGeometryList list) { super(list); } public Sector getSector() { return sector; } public void setSector(Sector sector) { this.sector = sector; } public void pick(DrawContext dc, java.awt.Point pickPoint) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (pickPoint == null) return; this.pickSupport.clearPickList(); this.pickSupport.beginPicking(dc); GL gl = dc.getGL(); gl.glPushAttrib(GL.GL_LIGHTING_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_ENABLE_BIT | GL.GL_CURRENT_BIT); gl.glEnable(GL.GL_DEPTH_TEST); gl.glShadeModel(GL.GL_FLAT); gl.glDisable(GL.GL_CULL_FACE); try { // render each sector in unique color for (SectorGeometry sector : this) { Color color = dc.getUniquePickColor(); dc.getGL().glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()); sector.render(dc); // lat/lon/elevation not used in this case this.pickSupport.addPickableObject(color.getRGB(), sector, Position.ZERO, true); } PickedObject pickedSector = this.pickSupport.getTopObject(dc, pickPoint, null); if (pickedSector == null || pickedSector.getObject() == null) return; // no sector picked SectorGeometry sector = (SectorGeometry) pickedSector.getObject(); gl.glDepthFunc(GL.GL_LEQUAL); sector.pick(dc, pickPoint); } finally { gl.glPopAttrib(); this.pickSupport.endPicking(dc); this.pickSupport.clearPickList(); } } private HashMap<SectorGeometry, ArrayList<Point>> pickSectors = new HashMap<SectorGeometry, ArrayList<Point>>(); public ArrayList<PickedObject> pick(DrawContext dc, List<Point> pickPoints) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (pickPoints == null || pickPoints.size() < 1) return null; this.pickSupport.clearPickList(); this.pickSupport.beginPicking(dc); GL gl = dc.getGL(); gl.glPushAttrib(GL.GL_LIGHTING_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_ENABLE_BIT | GL.GL_CURRENT_BIT); gl.glEnable(GL.GL_DEPTH_TEST); gl.glShadeModel(GL.GL_FLAT); gl.glDisable(GL.GL_CULL_FACE); try { // render each sector in a unique color for (SectorGeometry sector : this) { Color color = dc.getUniquePickColor(); dc.getGL().glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()); sector.render(dc); // lat/lon/elevation not used in this case this.pickSupport.addPickableObject(color.getRGB(), sector, Position.ZERO, true); } // Determine the sectors underneath the pick points. Assemble a pick-points per sector map. // Several pick points might intersect the same sector. this.pickSectors.clear(); for (Point pickPoint : pickPoints) { PickedObject pickedSector = this.pickSupport.getTopObject(dc, pickPoint, null); if (pickedSector == null || pickedSector.getObject() == null) continue; SectorGeometry sector = (SectorGeometry) pickedSector.getObject(); ArrayList<Point> sectorPickPoints; if (!this.pickSectors.containsKey(sector)) { sectorPickPoints = new ArrayList<Point>(); this.pickSectors.put(sector, sectorPickPoints); } else { sectorPickPoints = this.pickSectors.get(sector); } sectorPickPoints.add(pickPoint); } if (this.pickSectors.size() < 1) return null; // Now have each sector determine the pick position for each intersecting pick point. gl.glDepthFunc(GL.GL_LEQUAL); ArrayList<PickedObject> pickedObjects = new ArrayList<PickedObject>(); for (Map.Entry<SectorGeometry, ArrayList<Point>> sector : this.pickSectors.entrySet()) { ArrayList<Point> sectorPickPoints = sector.getValue(); PickedObject[] pos = sector.getKey().pick(dc, sectorPickPoints); if (pos == null) continue; for (PickedObject po : pos) { if (po != null) pickedObjects.add(po); } } return pickedObjects; } finally { gl.glPopAttrib(); this.pickSupport.endPicking(dc); this.pickSupport.clearPickList(); } } public Vec4 getSurfacePoint(Position position) { return this.getSurfacePoint(position.getLatitude(), position.getLongitude(), position.getElevation()); } public Vec4 getSurfacePoint(Angle latitude, Angle longitude) { return this.getSurfacePoint(latitude, longitude, 0d); } public Vec4 getSurfacePoint(Angle latitude, Angle longitude, double metersOffset) { if (latitude == null || longitude == null) { String msg = Logging.getMessage("nullValue.LatLonIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } for (SectorGeometry sg : this) { if (sg.getSector().contains(latitude, longitude)) { Vec4 point = sg.getSurfacePoint(latitude, longitude, metersOffset); if (point != null) return point; } } return null; } }