Ejemplo n.º 1
0
  public void drawSphere(
      Coords center,
      double radius,
      int longitude,
      double longitudeStart,
      int longitudeLength,
      double frustumRadius) {

    manager.startGeometry(Manager.Type.TRIANGLES);

    // set texture to (0,0)
    manager.setDummyTexture();

    int latitude = longitude / 4;

    // check which parts are visible (latitudes)
    Coords o = manager.getView3D().getCenter();

    double z = center.getZ();
    double zMin = o.getZ() - frustumRadius;
    double zMax = o.getZ() + frustumRadius;

    int latitudeMaxTop = 0;
    latitudeMaxTop = latitude;
    if (Kernel.isGreater(z + radius, zMax)) {
      double angle = Math.asin((zMax - z) / radius);
      latitudeMaxTop = (int) (latitude * 2 * angle / Math.PI) + 2;
    }

    int latitudeMaxBottom = 0;
    latitudeMaxBottom = latitude;
    if (Kernel.isGreater(zMin, z - radius)) {
      double angle = Math.asin((z - zMin) / radius);
      latitudeMaxBottom = (int) (latitude * 2 * angle / Math.PI) + 2;
    }

    // Log.debug(latitudeMaxBottom+","+latitudeMaxTop);

    int latitudeMax = Math.max(latitudeMaxTop, latitudeMaxBottom);

    int latitudeMin = 0; // start on equator
    if (latitudeMaxTop < 0) { // start below equator
      latitudeMin = -latitudeMaxTop;
    } else if (latitudeMaxBottom < 0) { // start above equator
      latitudeMin = -latitudeMaxBottom;
    }

    // check which parts are visible (longitudes)

    // start drawing
    if (coordsArray.length <= longitudeLength) {
      coordsArray = new Coords[longitudeLength + 1];
      for (int ui = 0; ui <= longitudeLength; ui++) {
        coordsArray[ui] = new Coords(4);
      }
    }

    Coords norm1 = new Coords(4), norm2 = new Coords(4), n1b = new Coords(4), n2b = new Coords(4);

    double[] cosSinV = new double[2];

    // equator
    // cosSinV[0] = 1; // cos(0)
    // cosSinV[1] = 0; // sin(0)
    cosSin(latitudeMin, latitude, cosSinV);
    double lastCos = 1;
    for (int ui = 0; ui <= longitudeLength; ui++) {
      sphericalCoords(ui, longitude, longitudeStart, cosSinV, coordsArray[ui]);
    }

    // shift for longitude
    int shift = 1;

    boolean jumpNeeded = false;

    for (int vi = latitudeMin + 1; vi < latitudeMax; vi++) {

      cosSin(vi, latitude, cosSinV);

      // check if parallel is small enough to make jumps
      if (2 * cosSinV[0] < lastCos) {
        lastCos = lastCos / 2;
        jumpNeeded = true;
      } else {
        jumpNeeded = false;
      }

      // first values
      norm2.set(coordsArray[0]);
      sphericalCoords(0, longitude, longitudeStart, cosSinV, n2b);

      // first : no jump
      boolean jump = jumpNeeded;

      for (int ui = shift; ui <= longitudeLength; ui += shift) {

        // last latitude values
        norm1.set(norm2);
        norm2.set(coordsArray[ui]);

        // new latitude values and draw triangles
        n1b.set(n2b);
        if (jumpNeeded) {
          if (jump) { // draw edge triangle and center triangle

            sphericalCoords(ui + shift, longitude, longitudeStart, cosSinV, n2b);

            if (vi < latitudeMaxTop) { // top triangles
              drawNCr(norm1, center, radius);
              drawNCr(norm2, center, radius);
              drawNCr(n1b, center, radius);

              drawNCr(n1b, center, radius);
              drawNCr(norm2, center, radius);
              drawNCr(n2b, center, radius);
            }

            if (vi < latitudeMaxBottom) { // bottom triangles
              drawNCrm(norm1, center, radius);
              drawNCrm(n1b, center, radius);
              drawNCrm(norm2, center, radius);

              drawNCrm(n1b, center, radius);
              drawNCrm(n2b, center, radius);
              drawNCrm(norm2, center, radius);
            }

          } else { // draw edge triangle

            sphericalCoords(ui, longitude, longitudeStart, cosSinV, n2b);

            if (vi < latitudeMaxTop) { // top triangles
              drawNCr(norm1, center, radius);
              drawNCr(norm2, center, radius);
              drawNCr(n1b, center, radius);
            }

            if (vi < latitudeMaxBottom) { // bottom triangles
              drawNCrm(norm1, center, radius);
              drawNCrm(n1b, center, radius);
              drawNCrm(norm2, center, radius);
            }
          }
        } else { // no jump : draw two triangles

          sphericalCoords(ui, longitude, longitudeStart, cosSinV, n2b);

          if (vi < latitudeMaxTop) { // top triangles
            drawNCr(norm1, center, radius);
            drawNCr(norm2, center, radius);
            drawNCr(n1b, center, radius);

            drawNCr(norm2, center, radius);
            drawNCr(n2b, center, radius);
            drawNCr(n1b, center, radius);
          }

          if (vi < latitudeMaxBottom) { // bottom triangles
            drawNCrm(norm1, center, radius);
            drawNCrm(n1b, center, radius);
            drawNCrm(norm2, center, radius);

            drawNCrm(norm2, center, radius);
            drawNCrm(n1b, center, radius);
            drawNCrm(n2b, center, radius);
          }
        }

        coordsArray[ui].set(n2b);

        if (jumpNeeded) {
          jump = !jump;
        }
      }

      // if just jumps done, next shift is twice
      if (jumpNeeded) {
        shift = shift * 2;
      }

      sphericalCoords(0, longitude, longitudeStart, cosSinV, coordsArray[0]);
    }

    if (latitudeMax == latitude) {
      // pole
      norm2.set(coordsArray[0]);
      for (int ui = shift; ui <= longitudeLength; ui += shift) {
        norm1.set(norm2);
        norm2.set(coordsArray[ui]);

        if (latitudeMaxTop == latitude) { // top triangles
          drawNCr(norm1, center, radius);
          drawNCr(norm2, center, radius);
          drawNCr(Coords.VZ, center, radius);
        }

        if (latitudeMaxBottom == latitude) { // bottom triangles
          drawNCrm(norm1, center, radius);
          drawNCrm(Coords.VZ, center, radius);
          drawNCrm(norm2, center, radius);
        }
      }
    }

    manager.endGeometry();
  }