private void makePartialDiskTerrainConformant(
      DrawContext dc,
      int numCoords,
      float[] verts,
      double altitude,
      boolean terrainConformant,
      Vec4 referenceCenter) {
    Globe globe = dc.getGlobe();
    Matrix transform = this.computeTransform(dc.getGlobe(), dc.getVerticalExaggeration());

    for (int i = 0; i < numCoords; i += 3) {
      Vec4 vec = new Vec4(verts[i], verts[i + 1], verts[i + 2]);
      vec = vec.transformBy4(transform);
      Position p = globe.computePositionFromPoint(vec);

      double elevation = altitude;
      if (terrainConformant)
        elevation += this.computeElevationAt(dc, p.getLatitude(), p.getLongitude());

      vec = globe.computePointFromPosition(p.getLatitude(), p.getLongitude(), elevation);
      verts[i] = (float) (vec.x - referenceCenter.x);
      verts[i + 1] = (float) (vec.y - referenceCenter.y);
      verts[i + 2] = (float) (vec.z - referenceCenter.z);
    }
  }
  private void makeRadialWallTerrainConformant(
      DrawContext dc,
      int pillars,
      int stacks,
      float[] verts,
      double[] altitudes,
      boolean[] terrainConformant,
      Vec4 referenceCenter) {
    Globe globe = dc.getGlobe();
    Matrix transform = this.computeTransform(dc.getGlobe(), dc.getVerticalExaggeration());

    for (int p = 0; p <= pillars; p++) {
      int index = p;
      index = 3 * index;
      Vec4 vec = new Vec4(verts[index], verts[index + 1], verts[index + 2]);
      vec = vec.transformBy4(transform);
      Position pos = globe.computePositionFromPoint(vec);

      for (int s = 0; s <= stacks; s++) {
        double elevation = altitudes[s];
        if (terrainConformant[s])
          elevation += this.computeElevationAt(dc, pos.getLatitude(), pos.getLongitude());
        vec = globe.computePointFromPosition(pos.getLatitude(), pos.getLongitude(), elevation);

        index = p + s * (pillars + 1);
        index = 3 * index;
        verts[index] = (float) (vec.x - referenceCenter.x);
        verts[index + 1] = (float) (vec.y - referenceCenter.y);
        verts[index + 2] = (float) (vec.z - referenceCenter.z);
      }
    }
  }
  private void makePartialCylinderTerrainConformant(
      DrawContext dc,
      int slices,
      int stacks,
      float[] verts,
      double[] altitudes,
      boolean[] terrainConformant,
      Vec4 referenceCenter) {
    Globe globe = dc.getGlobe();
    Matrix transform = this.computeTransform(dc.getGlobe(), dc.getVerticalExaggeration());

    for (int i = 0; i <= slices; i++) {
      int index = i * (stacks + 1);
      index = 3 * index;
      Vec4 vec = new Vec4(verts[index], verts[index + 1], verts[index + 2]);
      vec = vec.transformBy4(transform);
      Position p = globe.computePositionFromPoint(vec);

      for (int j = 0; j <= stacks; j++) {
        double elevation = altitudes[j];
        if (terrainConformant[j])
          elevation += this.computeElevationAt(dc, p.getLatitude(), p.getLongitude());
        vec = globe.computePointFromPosition(p.getLatitude(), p.getLongitude(), elevation);

        index = j + i * (stacks + 1);
        index = 3 * index;
        verts[index] = (float) (vec.x - referenceCenter.x);
        verts[index + 1] = (float) (vec.y - referenceCenter.y);
        verts[index + 2] = (float) (vec.z - referenceCenter.z);
      }
    }
  }
    @SuppressWarnings({"RedundantIfStatement"})
    public boolean isInView(DrawContext dc) {
      if (!viewFrustum.intersects(this.getExtent(dc.getGlobe(), dc.getVerticalExaggeration())))
        return false;

      // Check apparent size
      if (getSizeInPixels(dc) <= MIN_CELL_SIZE_PIXELS) return false;

      return true;
    }
예제 #5
0
  @Override
  protected void doRender(DrawContext dc) {
    if (!loaded) {
      loaded = true;
      loadAttempts++;
      downloadData();
    }

    if (lastVerticalExaggeration != dc.getVerticalExaggeration() || lastGlobe != dc.getGlobe()) {
      lastVerticalExaggeration = dc.getVerticalExaggeration();
      lastGlobe = dc.getGlobe();
      recalculateVertices(lastGlobe, lastVerticalExaggeration);
      recalculateColors();
    }

    GL2 gl = dc.getGL().getGL2();

    int push = GL2.GL_CLIENT_VERTEX_ARRAY_BIT;
    if (colors != null) {
      push |= GL2.GL_COLOR_BUFFER_BIT;
    }
    if (getOpacity() < 1.0) {
      push |= GL2.GL_CURRENT_BIT;
    }
    gl.glPushClientAttrib(push);

    if (colors != null) {
      gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
      gl.glColorPointer(4, GL2.GL_DOUBLE, 0, colors.rewind());
    }
    if (getOpacity() < 1.0) {
      setBlendingFunction(dc);
    }

    gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
    gl.glVertexPointer(3, GL2.GL_DOUBLE, 0, vertices.rewind());

    gl.glDrawElements(
        GL2.GL_TRIANGLE_STRIP, indices.limit(), GL2.GL_UNSIGNED_INT, indices.rewind());

    gl.glColor4d(1, 1, 1, 1);
    gl.glPopClientAttrib();
  }
  protected static boolean isNameVisible(
      DrawContext dc, PlaceNameService service, Position namePosition) {
    double elevation = dc.getVerticalExaggeration() * namePosition.getElevation();
    Vec4 namePoint =
        dc.getGlobe()
            .computePointFromPosition(
                namePosition.getLatitude(), namePosition.getLongitude(), elevation);
    Vec4 eyeVec = dc.getView().getEyePoint();

    double dist = eyeVec.distanceTo3(namePoint);
    return dist >= service.getMinDisplayDistance() && dist <= service.getMaxDisplayDistance();
  }
  private boolean needToSplit(DrawContext dc, Sector sector) {
    Vec4[] corners = sector.computeCornerPoints(dc.getGlobe(), dc.getVerticalExaggeration());
    Vec4 centerPoint = sector.computeCenterPoint(dc.getGlobe(), dc.getVerticalExaggeration());

    View view = dc.getView();
    double d1 = view.getEyePoint().distanceTo3(corners[0]);
    double d2 = view.getEyePoint().distanceTo3(corners[1]);
    double d3 = view.getEyePoint().distanceTo3(corners[2]);
    double d4 = view.getEyePoint().distanceTo3(corners[3]);
    double d5 = view.getEyePoint().distanceTo3(centerPoint);

    double minDistance = d1;
    if (d2 < minDistance) minDistance = d2;
    if (d3 < minDistance) minDistance = d3;
    if (d4 < minDistance) minDistance = d4;
    if (d5 < minDistance) minDistance = d5;

    double cellSize =
        (Math.PI * sector.getDeltaLatRadians() * dc.getGlobe().getRadius()) / 20; // TODO

    return !(Math.log10(cellSize) <= (Math.log10(minDistance) - this.splitScale));
  }
예제 #8
0
  /**
   * Compute the lat/lon position of the view center
   *
   * @param dc the current DrawContext
   * @param view the current View
   * @return the ground position of the view center or null
   */
  protected Position computeGroundPosition(DrawContext dc, View view) {
    if (view == null) return null;

    Position groundPos =
        view.computePositionFromScreenPoint(
            view.getViewport().getWidth() / 2, view.getViewport().getHeight() / 2);
    if (groundPos == null) return null;

    double elevation =
        dc.getGlobe().getElevation(groundPos.getLatitude(), groundPos.getLongitude());
    return new Position(
        groundPos.getLatitude(),
        groundPos.getLongitude(),
        elevation * dc.getVerticalExaggeration());
  }
  private void drawBoundingVolumes(DrawContext dc, ArrayList<MercatorTextureTile> tiles) {
    float[] previousColor = new float[4];
    dc.getGL().glGetFloatv(GL.GL_CURRENT_COLOR, previousColor, 0);
    dc.getGL().glColor3d(0, 1, 0);

    for (MercatorTextureTile tile : tiles) {
      ((Cylinder) tile.getExtent(dc)).render(dc);
    }

    Cylinder c =
        dc.getGlobe()
            .computeBoundingCylinder(dc.getVerticalExaggeration(), this.levels.getSector());
    dc.getGL().glColor3d(1, 1, 0);
    c.render(dc);

    dc.getGL().glColor4fv(previousColor, 0);
  }
  protected void doRenderGeometry(DrawContext dc, String drawStyle) {
    if (dc == null) {
      String message = Logging.getMessage("nullValue.DrawContextIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (dc.getGL() == null) {
      String message = Logging.getMessage("nullValue.DrawingContextGLIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    double[] angles = this.computeAngles();
    // Angles are equal, fallback to drawing a closed cylinder.
    if (angles == null) {
      super.doRenderGeometry(dc, drawStyle);
      return;
    }

    double[] altitudes = this.getAltitudes(dc.getVerticalExaggeration());
    boolean[] terrainConformant = this.isTerrainConforming();
    double[] radii = this.getRadii();
    int slices = this.getSlices();
    int stacks = this.getStacks();
    int loops = this.getLoops();

    if (this.isEnableLevelOfDetail()) {
      DetailLevel level = this.computeDetailLevel(dc);

      Object o = level.getValue(SLICES);
      if (o != null && o instanceof Integer) slices = (Integer) o;

      o = level.getValue(STACKS);
      if (o != null && o instanceof Integer) stacks = (Integer) o;

      o = level.getValue(LOOPS);
      if (o != null && o instanceof Integer) loops = (Integer) o;

      o = level.getValue(DISABLE_TERRAIN_CONFORMANCE);
      if (o != null && o instanceof Boolean && ((Boolean) o))
        terrainConformant[0] = terrainConformant[1] = false;
    }

    Vec4 referenceCenter = this.computeReferenceCenter(dc);
    this.setExpiryTime(this.nextExpiryTime(dc, terrainConformant));
    this.clearElevationMap();

    GL gl = dc.getGL();
    OGLStackHandler ogsh = new OGLStackHandler();
    try {
      dc.getView().pushReferenceCenter(dc, referenceCenter);

      if (Airspace.DRAW_STYLE_OUTLINE.equals(drawStyle)) {
        this.drawRadialWallOutline(
            dc,
            radii,
            angles[0],
            altitudes,
            terrainConformant,
            loops,
            stacks,
            GeometryBuilder.INSIDE,
            referenceCenter);
        this.drawRadialWallOutline(
            dc,
            radii,
            angles[1],
            altitudes,
            terrainConformant,
            loops,
            stacks,
            GeometryBuilder.OUTSIDE,
            referenceCenter);

        // Outer cylinder isn't rendered if outer radius is zero.
        if (radii[1] != 0.0) {
          this.drawPartialCylinderOutline(
              dc,
              radii[1],
              altitudes,
              terrainConformant,
              slices,
              stacks,
              GeometryBuilder.OUTSIDE,
              angles[0],
              angles[2],
              referenceCenter);
        }
        // Inner cylinder isn't rendered if inner radius is zero.
        if (radii[0] != 0.0) {
          this.drawPartialCylinderOutline(
              dc,
              radii[0],
              altitudes,
              terrainConformant,
              slices,
              stacks,
              GeometryBuilder.INSIDE,
              angles[0],
              angles[2],
              referenceCenter);
        }
      } else if (Airspace.DRAW_STYLE_FILL.equals(drawStyle)) {
        if (this.isEnableCaps()) {
          ogsh.pushAttrib(gl, GL.GL_POLYGON_BIT);
          gl.glEnable(GL.GL_CULL_FACE);
          gl.glFrontFace(GL.GL_CCW);
        }

        if (this.isEnableCaps()) {
          // Caps aren't rendered if radii are equal.
          if (radii[0] != radii[1]) {
            this.drawPartialDisk(
                dc,
                radii,
                altitudes[1],
                terrainConformant[1],
                slices,
                loops,
                GeometryBuilder.OUTSIDE,
                angles[0],
                angles[2],
                referenceCenter);
            // Bottom cap isn't rendered if airspace is collapsed.
            if (!this.isAirspaceCollapsed()) {
              this.drawPartialDisk(
                  dc,
                  radii,
                  altitudes[0],
                  terrainConformant[0],
                  slices,
                  loops,
                  GeometryBuilder.INSIDE,
                  angles[0],
                  angles[2],
                  referenceCenter);
            }
          }
        }

        // Cylinders aren't rendered if airspace is collapsed.
        if (!this.isAirspaceCollapsed()) {
          this.drawRadialWall(
              dc,
              radii,
              angles[0],
              altitudes,
              terrainConformant,
              loops,
              stacks,
              GeometryBuilder.INSIDE,
              referenceCenter);
          this.drawRadialWall(
              dc,
              radii,
              angles[1],
              altitudes,
              terrainConformant,
              loops,
              stacks,
              GeometryBuilder.OUTSIDE,
              referenceCenter);

          // Outer cylinder isn't rendered if outer radius is zero.
          if (radii[1] != 0.0) {
            this.drawPartialCylinder(
                dc,
                radii[1],
                altitudes,
                terrainConformant,
                slices,
                stacks,
                GeometryBuilder.OUTSIDE,
                angles[0],
                angles[2],
                referenceCenter);
          }
          // Inner cylinder isn't rendered if inner radius is zero.
          if (radii[0] != 0.0) {
            this.drawPartialCylinder(
                dc,
                radii[0],
                altitudes,
                terrainConformant,
                slices,
                stacks,
                GeometryBuilder.INSIDE,
                angles[0],
                angles[2],
                referenceCenter);
          }
        }
      }
    } finally {
      dc.getView().popReferenceCenter(dc);
      ogsh.pop(gl);
    }
  }
예제 #11
0
  protected void doRenderGeometry(
      DrawContext dc, String drawStyle, List<LatLon> locations, List<Boolean> edgeFlags) {
    if (dc == null) {
      String message = Logging.getMessage("nullValue.DrawContextIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (dc.getGL() == null) {
      String message = Logging.getMessage("nullValue.DrawingContextGLIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (locations == null) {
      String message = "nullValue.LocationsIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    if (locations.size() == 0) return;

    double[] altitudes = this.getAltitudes(dc.getVerticalExaggeration());
    boolean[] terrainConformant = this.isTerrainConforming();
    boolean enableCaps = this.isEnableCaps();
    int subdivisions = this.subdivisions;

    if (this.getAltitudeDatum()[0].equals(AVKey.ABOVE_GROUND_REFERENCE)
        || this.getAltitudeDatum()[1].equals(AVKey.ABOVE_GROUND_REFERENCE)) {
      this.adjustForGroundReference(dc, terrainConformant, altitudes);
    }

    if (this.isEnableLevelOfDetail()) {
      DetailLevel level = this.computeDetailLevel(dc);

      Object o = level.getValue(SUBDIVISIONS);
      if (o != null && o instanceof Integer) subdivisions = (Integer) o;

      o = level.getValue(DISABLE_TERRAIN_CONFORMANCE);
      if (o != null && o instanceof Boolean && (Boolean) o)
        terrainConformant[0] = terrainConformant[1] = false;
    }

    Vec4 referenceCenter = this.computeReferenceCenter(dc);
    this.setExpiryTime(this.nextExpiryTime(dc, terrainConformant));
    this.clearElevationMap();

    GL gl = dc.getGL();
    OGLStackHandler ogsh = new OGLStackHandler();
    try {
      dc.getView().pushReferenceCenter(dc, referenceCenter);

      if (Airspace.DRAW_STYLE_FILL.equals(drawStyle)) {
        if (enableCaps && !this.isAirspaceCollapsed()) {
          ogsh.pushAttrib(gl, GL.GL_POLYGON_BIT);
          gl.glEnable(GL.GL_CULL_FACE);
          gl.glFrontFace(GL.GL_CCW);
        }

        this.drawPolygonFill(
            dc,
            locations,
            edgeFlags,
            altitudes,
            terrainConformant,
            enableCaps,
            subdivisions,
            referenceCenter);
      } else if (Airspace.DRAW_STYLE_OUTLINE.equals(drawStyle)) {
        this.drawPolygonOutline(
            dc,
            locations,
            edgeFlags,
            altitudes,
            terrainConformant,
            enableCaps,
            subdivisions,
            referenceCenter);
      }
    } finally {
      dc.getView().popReferenceCenter(dc);
      ogsh.pop(gl);
    }
  }