示例#1
1
  /** Query the texture for the colour at the given intersection (in 3D space). */
  private Colour queryTexture(Vector3 intersection) {
    Vector3 Vn = mNorth;
    Vector3 Ve = Vector3.pool.borrow().reset(Vn.y, -Vn.x, 0.0); // (AKA Vn.cross(0, 0, 1))
    Vector3 Vp = Vector3.pool.borrow().reset(intersection);
    Vp.subtract(mPlanetOrigin);

    Ve.normalize();
    Vp.normalize();

    double phi = Math.acos(-1.0 * Vector3.dot(Vn, Vp));
    double v = phi / Math.PI;

    double theta = (Math.acos(Vector3.dot(Vp, Ve) / Math.sin(phi))) / (Math.PI * 2.0);
    double u;

    Vector3 c = Vector3.cross(Vn, Ve);
    if (Vector3.dot(c, Vp) > 0) {
      u = theta;
    } else {
      u = 1.0 - theta;
    }

    Vector3.pool.release(c);
    Vector3.pool.release(Ve);
    Vector3.pool.release(Vp);

    return mTexture.getTexel(u, v);
  }
示例#2
0
  /**
   * Calculates diffuse lighting at the given point with the given normal.
   *
   * @param normal Normal at the point we're calculating diffuse lighting for.
   * @param point The point at which we're calculating diffuse lighting.
   * @return The diffuse factor of lighting.
   */
  private double diffuse(Vector3 normal, Vector3 point) {
    Vector3 directionToLight = Vector3.pool.borrow().reset(mSunOrigin);
    directionToLight.subtract(point);
    directionToLight.normalize();

    double factor = Vector3.dot(normal, directionToLight);
    Vector3.pool.release(directionToLight);
    return factor;
  }
示例#3
0
  /**
   * Calculates light intensity from the sun.
   *
   * @param intersection Point where the ray we're currently tracing intersects with the planet.
   */
  private double lightSphere(Vector3 intersection) {
    Vector3 surfaceNormal = Vector3.pool.borrow().reset(intersection);
    surfaceNormal.subtract(mPlanetOrigin);
    surfaceNormal.normalize();

    double intensity = diffuse(surfaceNormal, intersection);
    intensity = Math.max(mAmbient, Math.min(1.0, intensity));

    Vector3.pool.release(surfaceNormal);
    return intensity;
  }
示例#4
0
  public PlanetRenderer(Template.PlanetTemplate tmpl, Random rand) {
    mPlanetOrigin = Vector3.pool.borrow().reset(0.0, 0.0, 30.0);
    mTexture = new TextureGenerator(tmpl.getParameter(Template.TextureTemplate.class), rand);
    mSunOrigin = tmpl.getSunLocation();
    mAmbient = tmpl.getAmbient();
    mPlanetRadius = tmpl.getPlanetSize();

    List<Template.AtmosphereTemplate> atmosphereTemplates =
        tmpl.getParameters(Template.AtmosphereTemplate.class);
    if (atmosphereTemplates != null && atmosphereTemplates.size() > 0) {
      mAtmospheres = new ArrayList<Atmosphere>();
      for (Template.AtmosphereTemplate atmosphereTemplate : atmosphereTemplates) {
        mAtmospheres.add(new Atmosphere(atmosphereTemplate, rand));
      }
    }

    mNorth = Vector3.pool.borrow().reset(tmpl.getNorthFrom());
    Vector3.interpolate(mNorth, tmpl.getNorthTo(), rand.nextDouble());
    mNorth.normalize();
  }
示例#5
0
  /**
   * Definiert die Plane über drei Punkte.
   *
   * @param a Erster Punkt
   * @param b Zweiter Punkt
   * @param c Dritter Punkt
   * @return Diese Instanz für method chaining
   */
  @NotNull
  public Plane3 set(@NotNull final Vector3 a, @NotNull final Vector3 b, @NotNull final Vector3 c) {
    assert !a.equals(b) && !b.equals(c); // TODO: Dürfen nicht auf einer Geraden liegen!

    // Normale berechnen: _normal = a.sub(b).cross(a.sub(c));
    final Vector3 aSubB = a.sub(b);
    Vector3 aSubC = a.sub(c);

    _normal.set(aSubB.cross(aSubC));
    _normal.normalize();

    // aSubB freigeben.
    // aSubC wird noch nicht freigegeben, da wir den Wert in Kürze weiterverwenden werden
    aSubB.recycle();

    // Entfernung berechnen
    final Vector3 invNormal = aSubC;
    invNormal.set(_normal).invert();
    _distanceToOrigin = invNormal.dot(a);
    invNormal.recycle();
    return this;
  }
示例#6
0
  /**
   * Computes the colour of the pixel at (x,y) where each coordinate is defined to be in the range
   * (-0.5, +0.5).
   *
   * @param x The x-coordinate, between -0.5 and +0.5.
   * @param y The y-coordinate, between -0.5 and +0.5.
   * @return The colour at the given pixel.
   */
  private Colour getPixelColour(double x, double y) {
    Colour c = Colour.pool.borrow().reset(Colour.TRANSPARENT);

    Vector3 ray = Vector3.pool.borrow().reset(x, -y, 1.0);
    ray.normalize();

    Vector3 intersection = raytrace(ray);
    if (intersection != null) {
      // we intersected with the planet. Now we need to work out the colour at this point
      // on the planet.
      Colour t = queryTexture(intersection);
      double intensity = lightSphere(intersection);
      c.reset(1.0, t.r * intensity, t.g * intensity, t.b * intensity);
      Colour.pool.release(t);

      if (mAtmospheres != null) {
        Vector3 surfaceNormal = Vector3.pool.borrow().reset(intersection);
        surfaceNormal.subtract(mPlanetOrigin);
        surfaceNormal.normalize();

        Vector3 sunDirection = Vector3.pool.borrow().reset(mSunOrigin);
        sunDirection.subtract(intersection);
        sunDirection.normalize();

        final int numAtmospheres = mAtmospheres.size();
        for (int i = 0; i < numAtmospheres; i++) {
          final Atmosphere atmosphere = mAtmospheres.get(i);
          Colour atmosphereColour =
              atmosphere.getInnerPixelColour(
                  x + 0.5, y + 0.5, intersection, surfaceNormal, sunDirection);
          Colour.blend(c, atmosphereColour);
          Colour.pool.release(atmosphereColour);
        }

        Vector3.pool.release(surfaceNormal);
        Vector3.pool.release(sunDirection);
      }
    } else if (mAtmospheres != null) {
      // if we're rendering an atmosphere, we need to work out the distance of this ray
      // to the planet's surface
      double u = Vector3.dot(mPlanetOrigin, ray);
      Vector3 closest = Vector3.pool.borrow().reset(ray);
      closest.scale(u);

      double distance = (Vector3.distanceBetween(closest, mPlanetOrigin) - mPlanetRadius);

      Vector3 surfaceNormal = Vector3.pool.borrow().reset(closest);
      surfaceNormal.subtract(mPlanetOrigin);
      surfaceNormal.normalize();

      Vector3 sunDirection = Vector3.pool.borrow().reset(mSunOrigin);
      sunDirection.subtract(closest);
      sunDirection.normalize();

      final int numAtmospheres = mAtmospheres.size();
      for (int i = 0; i < numAtmospheres; i++) {
        final Atmosphere atmosphere = mAtmospheres.get(i);
        Colour atmosphereColour =
            atmosphere.getOuterPixelColour(x + 0.5, y + 0.5, surfaceNormal, distance, sunDirection);
        Colour.blend(c, atmosphereColour);
        Colour.pool.release(atmosphereColour);
      }

      Vector3.pool.release(closest);
      Vector3.pool.release(surfaceNormal);
      Vector3.pool.release(sunDirection);
    }

    Vector3.pool.release(ray);
    Vector3.pool.release(intersection);
    return c;
  }
示例#7
0
 public Ray(Coordinate3 coordinate, Vector3 v) {
   this.coordinate = coordinate;
   v.normalize();
   this.v = v;
 }
示例#8
0
 public Ray(Coordinate3 coordinate, Vector3 v, boolean insideSomething) {
   this.coordinate = coordinate;
   v.normalize();
   this.v = v;
   this.insideSomething = insideSomething;
 }