protected void onHorizontalTranslateRel(
      Angle forwardChange, Angle sideChange, ViewInputAttributes.ActionAttributes actionAttribs) {
    View view = this.getView();
    if (view == null) // include this test to ensure any derived implementation performs it
    {
      return;
    }

    if (forwardChange.equals(Angle.ZERO) && sideChange.equals(Angle.ZERO)) {
      return;
    }

    if (view instanceof BasicFlyView) {

      Vec4 forward = view.getForwardVector();
      Vec4 up = view.getUpVector();
      Vec4 side = forward.transformBy3(Matrix.fromAxisAngle(Angle.fromDegrees(90), up));

      forward = forward.multiply3(forwardChange.getDegrees());
      side = side.multiply3(sideChange.getDegrees());
      Vec4 eyePoint = view.getEyePoint();
      eyePoint = eyePoint.add3(forward.add3(side));
      Position newPosition = view.getGlobe().computePositionFromPoint(eyePoint);

      this.setEyePosition(this.uiAnimControl, view, newPosition, actionAttribs);
      view.firePropertyChange(AVKey.VIEW, null, view);
    }
  }
Пример #2
0
  /**
   * Compute the positions of the arrow head of the graphic's legs.
   *
   * @param dc Current draw context
   * @param base Position of the arrow's starting point.
   * @param tip Position of the arrow head tip.
   * @param arrowLength Length of the arrowhead as a fraction of the total line length.
   * @param arrowAngle Angle of the arrow head.
   * @return Positions required to draw the arrow head.
   */
  protected List<Position> computeArrowheadPositions(
      DrawContext dc, Position base, Position tip, double arrowLength, Angle arrowAngle) {
    // Build a triangle to represent the arrowhead. The triangle is built from two vectors, one
    // parallel to the
    // segment, and one perpendicular to it.

    Globe globe = dc.getGlobe();

    Vec4 ptA = globe.computePointFromPosition(base);
    Vec4 ptB = globe.computePointFromPosition(tip);

    // Compute parallel component
    Vec4 parallel = ptA.subtract3(ptB);

    Vec4 surfaceNormal = globe.computeSurfaceNormalAtPoint(ptB);

    // Compute perpendicular component
    Vec4 perpendicular = surfaceNormal.cross3(parallel);

    double finalArrowLength = arrowLength * parallel.getLength3();
    double arrowHalfWidth = finalArrowLength * arrowAngle.tanHalfAngle();

    perpendicular = perpendicular.normalize3().multiply3(arrowHalfWidth);
    parallel = parallel.normalize3().multiply3(finalArrowLength);

    // Compute geometry of direction arrow
    Vec4 vertex1 = ptB.add3(parallel).add3(perpendicular);
    Vec4 vertex2 = ptB.add3(parallel).subtract3(perpendicular);

    return TacticalGraphicUtil.asPositionList(globe, vertex1, vertex2, ptB);
  }
Пример #3
0
  protected void assembleHeightControlPoints() {
    if (this.controlPoints.size() < 2) return;

    // Add one control point for the height between the first and second vertices.
    // TODO: ensure that this control point is visible
    Position firstVertex = this.controlPoints.get(0).getPosition();
    Position secondVertex = this.controlPoints.get(1).getPosition();

    Globe globe = this.wwd.getModel().getGlobe();

    // Get cartesian points for the vertices
    Vec4 firstPoint = globe.computePointFromPosition(firstVertex);
    Vec4 secondPoint = globe.computePointFromPosition(secondVertex);

    // Find the midpoint of the line segment that connects the vertices
    Vec4 halfwayPoint = firstPoint.add3(secondPoint).divide3(2.0);

    Position halfwayPosition = globe.computePositionFromPoint(halfwayPoint);

    this.controlPoints.add(
        new ControlPointMarker(
            CHANGE_HEIGHT_ACTION,
            halfwayPosition,
            halfwayPoint,
            this.heightControlAttributes,
            this.controlPoints.size()));
  }
Пример #4
0
  /**
   * Construct a unit-length cube centered at a specified point.
   *
   * @param point the center of the cube.
   * @throws IllegalArgumentException if the point is null.
   */
  public Box(Vec4 point) {
    if (point == null) {
      String msg = Logging.getMessage("nullValue.PointIsNull");
      Logging.error(msg);
      throw new IllegalArgumentException(msg);
    }

    this.ru = new Vec4(1, 0, 0, 1);
    this.su = new Vec4(0, 1, 0, 1);
    this.tu = new Vec4(0, 0, 1, 1);

    this.r = this.ru;
    this.s = this.su;
    this.t = this.tu;

    this.rLength = 1;
    this.sLength = 1;
    this.tLength = 1;

    // Plane normals point outwards from the box.
    this.planes = new Plane[6];
    double d = 0.5 * point.getLength3();
    this.planes[0] = new Plane(-this.ru.x, -this.ru.y, -this.ru.z, -(d + 0.5));
    this.planes[1] = new Plane(+this.ru.x, +this.ru.y, +this.ru.z, -(d + 0.5));
    this.planes[2] = new Plane(-this.su.x, -this.su.y, -this.su.z, -(d + 0.5));
    this.planes[3] = new Plane(+this.su.x, +this.su.y, +this.su.z, -(d + 0.5));
    this.planes[4] = new Plane(-this.tu.x, -this.tu.y, -this.tu.z, -(d + 0.5));
    this.planes[5] = new Plane(+this.tu.x, +this.tu.y, +this.tu.z, -(d + 0.5));

    this.center = ru.add3(su).add3(tu).multiply3(0.5);

    Vec4 rHalf = r.multiply3(0.5);
    this.topCenter = this.center.add3(rHalf);
    this.bottomCenter = this.center.subtract3(rHalf);
  }
Пример #5
0
  protected void assembleVertexControlPoints(DrawContext dc) {
    Terrain terrain = dc.getTerrain();
    ExtrudedPolygon polygon = this.getPolygon();

    Position refPos = polygon.getReferencePosition();
    Vec4 refPoint = terrain.getSurfacePoint(refPos.getLatitude(), refPos.getLongitude(), 0);

    int altitudeMode = polygon.getAltitudeMode();
    double height = polygon.getHeight();

    Vec4 vaa = null;
    double vaaLength = 0; // used to compute independent length of each cap vertex
    double vaLength = 0;

    int i = 0;
    for (LatLon location : polygon.getOuterBoundary()) {
      Vec4 vert;

      // Compute the top/cap point.
      if (altitudeMode == WorldWind.CONSTANT || !(location instanceof Position)) {
        if (vaa == null) {
          // Compute the vector lengths of the top and bottom points at the reference position.
          vaa = refPoint.multiply3(height / refPoint.getLength3());
          vaaLength = vaa.getLength3();
          vaLength = refPoint.getLength3();
        }

        // Compute the bottom point, which is on the terrain.
        vert = terrain.getSurfacePoint(location.getLatitude(), location.getLongitude(), 0);

        double delta = vaLength - vert.dot3(refPoint) / vaLength;
        vert = vert.add3(vaa.multiply3(1d + delta / vaaLength));
      } else if (altitudeMode == WorldWind.RELATIVE_TO_GROUND) {
        vert =
            terrain.getSurfacePoint(
                location.getLatitude(),
                location.getLongitude(),
                ((Position) location).getAltitude());
      } else // WorldWind.ABSOLUTE
      {
        vert =
            terrain
                .getGlobe()
                .computePointFromPosition(
                    location.getLatitude(),
                    location.getLongitude(),
                    ((Position) location).getAltitude() * terrain.getVerticalExaggeration());
      }

      Position vertexPosition = this.wwd.getModel().getGlobe().computePositionFromPoint(vert);

      this.controlPoints.add(
          new ControlPointMarker(
              MOVE_VERTEX_ACTION, vertexPosition, vert, this.vertexControlAttributes, i));
      i++;
    }
  }
Пример #6
0
  /**
   * Determine the positions that make up the arrowhead.
   *
   * @param dc Current draw context.
   * @param startPosition Position of the arrow's base.
   * @param endPosition Position of the arrow head tip.
   * @return Positions that define the arrowhead.
   */
  protected List<Position> computeArrowheadPositions(
      DrawContext dc, Position startPosition, Position endPosition) {
    Globe globe = dc.getGlobe();

    // Arrowhead looks like this:
    //                  _
    //        A\         | 1/2 width
    // ________B\       _|
    // Pt. 1    /
    //        C/
    //         | |
    //      Length

    Vec4 p1 = globe.computePointFromPosition(startPosition);
    Vec4 pB = globe.computePointFromPosition(endPosition);

    // Find vector in the direction of the arrow
    Vec4 vB1 = p1.subtract3(pB);

    double arrowLengthFraction = this.getArrowLength();

    // Find the point at the base of the arrowhead
    Vec4 arrowBase = pB.add3(vB1.multiply3(arrowLengthFraction));

    Vec4 normal = globe.computeSurfaceNormalAtPoint(arrowBase);

    // Compute the length of the arrowhead
    double arrowLength = vB1.getLength3() * arrowLengthFraction;
    double arrowHalfWidth = arrowLength * this.getArrowAngle().tanHalfAngle();

    // Compute a vector perpendicular to the segment and the normal vector
    Vec4 perpendicular = vB1.cross3(normal);
    perpendicular = perpendicular.normalize3().multiply3(arrowHalfWidth);

    // Find points A and C
    Vec4 pA = arrowBase.add3(perpendicular);
    Vec4 pC = arrowBase.subtract3(perpendicular);

    return TacticalGraphicUtil.asPositionList(globe, pA, pB, pC);
  }
Пример #7
0
  protected void addToolTip(DrawContext dc, WWIcon icon, Vec4 iconPoint) {
    if (icon.getToolTipFont() == null && icon.getToolTipText() == null) return;

    Vec4 screenPoint = dc.getView().project(iconPoint);
    if (screenPoint == null) return;

    if (icon.getToolTipOffset() != null) screenPoint = screenPoint.add3(icon.getToolTipOffset());

    OrderedText tip =
        new OrderedText(
            icon.getToolTipText(),
            icon.getToolTipFont(),
            screenPoint,
            icon.getToolTipTextColor(),
            0d);
    dc.addOrderedRenderable(tip);
  }
  public void lookAt(Position lookAtPos, long timeToMove) {
    BasicFlyView view = (BasicFlyView) this.getView();
    Vec4 lookDirection;
    double distanceToSurface;
    Vec4 currentLookAtPt = view.getCenterPoint();
    Position newPosition;
    if (currentLookAtPt == null) {
      view.getGlobe().computePointFromPosition(lookAtPos);
      double elevAtLookAtPos =
          view.getGlobe().getElevation(lookAtPos.getLatitude(), lookAtPos.getLongitude());
      newPosition = new Position(lookAtPos, elevAtLookAtPos + 10000);
    } else {
      Vec4 currentEyePt = view.getEyePoint();
      distanceToSurface = currentEyePt.distanceTo3(currentLookAtPt);
      lookDirection = currentLookAtPt.subtract3(currentEyePt).normalize3();
      Vec4 newLookAtPt = view.getGlobe().computePointFromPosition(lookAtPos);
      Vec4 flyToPoint = newLookAtPt.add3(lookDirection.multiply3(-distanceToSurface));
      newPosition = view.getGlobe().computePositionFromPoint(flyToPoint);
    }

    ViewUtil.ViewState viewCoords = view.getViewState(newPosition, lookAtPos);

    FlyToFlyViewAnimator panAnimator =
        FlyToFlyViewAnimator.createFlyToFlyViewAnimator(
            view,
            view.getEyePosition(),
            newPosition,
            view.getHeading(),
            viewCoords.getHeading(),
            view.getPitch(),
            viewCoords.getPitch(),
            view.getEyePosition().getElevation(),
            viewCoords.getPosition().getElevation(),
            timeToMove,
            WorldWind.ABSOLUTE);

    this.gotoAnimControl.put(VIEW_ANIM_PAN, panAnimator);
    this.getView().firePropertyChange(AVKey.VIEW, null, this.getView());

    view.firePropertyChange(AVKey.VIEW, null, view);
  }
  /**
   * Determines whether this sector intersects the specified geographic line segment. The line
   * segment is specified by a begin location and an end location. The locations are are assumed to
   * be connected by a linear path in geographic space. This returns true if any location along that
   * linear path intersects this sector, including the begin and end locations.
   *
   * @param begin the line segment begin location.
   * @param end the line segment end location.
   * @return true <code>true</code> if this sector intersects the line segment, otherwise <code>
   *     false</code>.
   * @throws IllegalArgumentException if either the begin location or the end location is null.
   */
  public boolean intersectsSegment(LatLon begin, LatLon end) {
    if (begin == null) {
      throw new IllegalArgumentException("Begin Is Null");
    }

    if (end == null) {
      throw new IllegalArgumentException("End Is Null");
    }

    Vec4 segmentBegin = new Vec4(begin.getLongitude().degrees, begin.getLatitude().degrees, 0);
    Vec4 segmentEnd = new Vec4(end.getLongitude().degrees, end.getLatitude().degrees, 0);
    Vec4 tmp = segmentEnd.subtract3(segmentBegin);
    Vec4 segmentCenter = segmentBegin.add3(segmentEnd).divide3(2);
    Vec4 segmentDirection = tmp.normalize3();
    double segmentExtent = tmp.getLength3() / 2.0;

    LatLon centroid = this.getCentroid();
    Vec4 boxCenter = new Vec4(centroid.getLongitude().degrees, centroid.getLatitude().degrees, 0);
    double boxExtentX = this.getDeltaLonDegrees() / 2.0;
    double boxExtentY = this.getDeltaLatDegrees() / 2.0;

    Vec4 diff = segmentCenter.subtract3(boxCenter);

    if (Math.abs(diff.x) > (boxExtentX + segmentExtent * Math.abs(segmentDirection.x))) {
      return false;
    }

    if (Math.abs(diff.y) > (boxExtentY + segmentExtent * Math.abs(segmentDirection.y))) {
      return false;
    }

    //noinspection SuspiciousNameCombination
    Vec4 segmentPerp = new Vec4(segmentDirection.y, -segmentDirection.x, 0);

    return Math.abs(segmentPerp.dot3(diff))
        <= (boxExtentX * Math.abs(segmentPerp.x) + boxExtentY * Math.abs(segmentPerp.y));
  }
Пример #10
0
  /**
   * Compute points on either side of a line segment. This method requires a point on the line, and
   * either a next point, previous point, or both.
   *
   * @param point Center point about which to compute side points.
   * @param prev Previous point on the line. May be null if {@code next} is non-null.
   * @param next Next point on the line. May be null if {@code prev} is non-null.
   * @param leftPositions Left position will be added to this list.
   * @param rightPositions Right position will be added to this list.
   * @param halfWidth Distance from the center line to the left or right lines.
   * @param globe Current globe.
   */
  protected void generateParallelPoints(
      Vec4 point,
      Vec4 prev,
      Vec4 next,
      List<Position> leftPositions,
      List<Position> rightPositions,
      double halfWidth,
      Globe globe) {
    if ((point == null) || (prev == null && next == null)) {
      String message = Logging.getMessage("nullValue.PointIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (leftPositions == null || rightPositions == null) {
      String message = Logging.getMessage("nullValue.PositionListIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (globe == null) {
      String message = Logging.getMessage("nullValue.GlobeIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    Vec4 offset;
    Vec4 normal = globe.computeSurfaceNormalAtPoint(point);

    // Compute vector in the direction backward along the line.
    Vec4 backward = (prev != null) ? prev.subtract3(point) : point.subtract3(next);

    // Compute a vector perpendicular to segment BC, and the globe normal vector.
    Vec4 perpendicular = backward.cross3(normal);

    double length;
    // If both next and previous points are supplied then calculate the angle that bisects the angle
    // current, next, prev.
    if (next != null && prev != null && !Vec4.areColinear(prev, point, next)) {
      // Compute vector in the forward direction.
      Vec4 forward = next.subtract3(point);

      // Calculate the vector that bisects angle ABC.
      offset = forward.normalize3().add3(backward.normalize3());
      offset = offset.normalize3();

      // Compute the scalar triple product of the vector BC, the normal vector, and the offset
      // vector to
      // determine if the offset points to the left or the right of the control line.
      double tripleProduct = perpendicular.dot3(offset);
      if (tripleProduct < 0) {
        offset = offset.multiply3(-1);
      }

      // Determine the length of the offset vector that will keep the left and right lines parallel
      // to the control
      // line.
      Angle theta = backward.angleBetween3(offset);
      if (!Angle.ZERO.equals(theta)) length = halfWidth / theta.sin();
      else length = halfWidth;
    } else {
      offset = perpendicular.normalize3();
      length = halfWidth;
    }
    offset = offset.multiply3(length);

    // Determine the left and right points by applying the offset.
    Vec4 ptRight = point.add3(offset);
    Vec4 ptLeft = point.subtract3(offset);

    // Convert cartesian points to geographic.
    Position posLeft = globe.computePositionFromPoint(ptLeft);
    Position posRight = globe.computePositionFromPoint(ptRight);

    leftPositions.add(posLeft);
    rightPositions.add(posRight);
  }
  protected void onMoveTo(
      Position focalPosition,
      ViewInputAttributes.DeviceAttributes deviceAttributes,
      ViewInputAttributes.ActionAttributes actionAttribs) {
    BasicFlyView view = (BasicFlyView) this.getView();
    if (view == null) // include this test to ensure any derived implementation performs it
    {
      return;
    }

    // We're treating a speed parameter as smoothing here. A greater speed results in greater
    // smoothing and
    // slower response. Therefore the min speed used at lower altitudes ought to be *greater* than
    // the max
    // speed used at higher altitudes.
    double smoothing = this.getScaleValueElevation(deviceAttributes, actionAttribs);
    if (!actionAttribs.isEnableSmoothing()) smoothing = 0.0;

    Vec4 currentLookAtPt = view.getCenterPoint();
    if (currentLookAtPt == null) {
      currentLookAtPt = view.getGlobe().computePointFromPosition(focalPosition);
    }

    Vec4 currentEyePt = view.getEyePoint();
    double distanceToSurface = currentEyePt.distanceTo3(currentLookAtPt);
    Vec4 lookDirection = currentEyePt.subtract3(currentLookAtPt).normalize3();
    Vec4 newLookAtPt = view.getGlobe().computePointFromPosition(focalPosition);
    Vec4 flyToPoint = newLookAtPt.add3(lookDirection.multiply3(distanceToSurface));

    Position newPosition = view.getGlobe().computePositionFromPoint(flyToPoint);

    ViewUtil.ViewState viewCoords = view.getViewState(newPosition, focalPosition);

    this.stopAnimators();
    this.gotoAnimControl.put(
        VIEW_ANIM_HEADING,
        new RotateToAngleAnimator(
            view.getHeading(),
            viewCoords.getHeading(),
            smoothing,
            ViewPropertyAccessor.createHeadingAccessor(view)));
    this.gotoAnimControl.put(
        VIEW_ANIM_PITCH,
        new RotateToAngleAnimator(
            view.getPitch(),
            viewCoords.getPitch(),
            smoothing,
            ViewPropertyAccessor.createPitchAccessor(view)));

    double elevation =
        ((FlyViewLimits) view.getViewPropertyLimits())
            .limitEyeElevation(newPosition, view.getGlobe());
    if (elevation != newPosition.getElevation()) {
      newPosition = new Position(newPosition, elevation);
    }
    this.gotoAnimControl.put(
        VIEW_ANIM_POSITION,
        new MoveToPositionAnimator(
            view.getEyePosition(),
            newPosition,
            smoothing,
            ViewPropertyAccessor.createEyePositionAccessor(view)));

    view.firePropertyChange(AVKey.VIEW, null, view);
  }
Пример #12
0
  // Rendering
  public void draw(DrawContext dc) {
    GL gl = dc.getGL();

    boolean attribsPushed = false;
    boolean modelviewPushed = false;
    boolean projectionPushed = false;

    try {
      gl.glPushAttrib(
          GL.GL_DEPTH_BUFFER_BIT
              | GL.GL_COLOR_BUFFER_BIT
              | GL.GL_ENABLE_BIT
              | GL.GL_TEXTURE_BIT
              | GL.GL_TRANSFORM_BIT
              | GL.GL_VIEWPORT_BIT
              | GL.GL_CURRENT_BIT);
      attribsPushed = true;

      gl.glDisable(GL.GL_TEXTURE_2D); // no textures

      gl.glEnable(GL.GL_BLEND);
      gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
      gl.glDisable(GL.GL_DEPTH_TEST);

      double width = this.size.width;
      double height = this.size.height;

      // Load a parallel projection with xy dimensions (viewportWidth, viewportHeight)
      // into the GL projection matrix.
      java.awt.Rectangle viewport = dc.getView().getViewport();
      gl.glMatrixMode(javax.media.opengl.GL.GL_PROJECTION);
      gl.glPushMatrix();
      projectionPushed = true;
      gl.glLoadIdentity();
      double maxwh = width > height ? width : height;
      gl.glOrtho(0d, viewport.width, 0d, viewport.height, -0.6 * maxwh, 0.6 * maxwh);

      gl.glMatrixMode(GL.GL_MODELVIEW);
      gl.glPushMatrix();
      modelviewPushed = true;
      gl.glLoadIdentity();

      // Scale to a width x height space
      // located at the proper position on screen
      double scale = this.computeScale(viewport);
      Vec4 locationSW = this.computeLocation(viewport, scale);
      gl.glTranslated(locationSW.x(), locationSW.y(), locationSW.z());
      gl.glScaled(scale, scale, 1);

      // Compute scale size in real world
      Position referencePosition = dc.getViewportCenterPosition();
      if (referencePosition != null) {
        Vec4 groundTarget = dc.getGlobe().computePointFromPosition(referencePosition);
        Double distance = dc.getView().getEyePoint().distanceTo3(groundTarget);
        this.pixelSize = dc.getView().computePixelSizeAtDistance(distance);
        Double scaleSize = this.pixelSize * width * scale; // meter
        String unitLabel = "m";
        if (this.unit.equals(UNIT_METRIC)) {
          if (scaleSize > 10000) {
            scaleSize /= 1000;
            unitLabel = "Km";
          }
        } else if (this.unit.equals(UNIT_IMPERIAL)) {
          scaleSize *= 3.280839895; // feet
          unitLabel = "ft";
          if (scaleSize > 5280) {
            scaleSize /= 5280;
            unitLabel = "mile(s)";
          }
        }

        // Rounded division size
        int pot = (int) Math.floor(Math.log10(scaleSize));
        if (!Double.isNaN(pot)) {
          int digit = Integer.parseInt(String.format("%.0f", scaleSize).substring(0, 1));
          double divSize = digit * Math.pow(10, pot);
          if (digit >= 5) divSize = 5 * Math.pow(10, pot);
          else if (digit >= 2) divSize = 2 * Math.pow(10, pot);
          double divWidth = width * divSize / scaleSize;

          // Draw scale
          if (!dc.isPickingMode()) {
            // Set color using current layer opacity
            Color backColor = this.getBackgroundColor(this.color);
            float[] colorRGB = backColor.getRGBColorComponents(null);
            gl.glColor4d(
                colorRGB[0],
                colorRGB[1],
                colorRGB[2],
                (double) backColor.getAlpha() / 255d * this.getOpacity());
            gl.glTranslated((width - divWidth) / 2, 0d, 0d);
            this.drawScale(dc, divWidth, height);

            colorRGB = this.color.getRGBColorComponents(null);
            gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity());
            gl.glTranslated(-1d / scale, 1d / scale, 0d);
            this.drawScale(dc, divWidth, height);

            // Draw label
            String label = String.format("%.0f ", divSize) + unitLabel;
            gl.glLoadIdentity();
            gl.glDisable(GL.GL_CULL_FACE);
            drawLabel(
                dc,
                label,
                locationSW.add3(
                    new Vec4(divWidth * scale / 2 + (width - divWidth) / 2, height * scale, 0)));
          } else {
            // Picking
            this.pickSupport.clearPickList();
            this.pickSupport.beginPicking(dc);
            // Draw unique color across the map
            Color color = dc.getUniquePickColor();
            int colorCode = color.getRGB();
            // Add our object(s) to the pickable list
            this.pickSupport.addPickableObject(colorCode, this, referencePosition, false);
            gl.glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue());
            gl.glTranslated((width - divWidth) / 2, 0d, 0d);
            this.drawRectangle(dc, divWidth, height);
            // Done picking
            this.pickSupport.endPicking(dc);
            this.pickSupport.resolvePick(dc, dc.getPickPoint(), this);
          }
        }
      }
    } finally {
      if (projectionPushed) {
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPopMatrix();
      }
      if (modelviewPushed) {
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPopMatrix();
      }
      if (attribsPushed) gl.glPopAttrib();
    }
  }