Beispiel #1
0
 private static boolean raysEquivalent(Ray ray1, Ray ray2) {
   Vector3d dir1 = new Vector3d(ray1.direction);
   Vector3d dir2 = new Vector3d(ray2.direction);
   dir1.normalize();
   dir2.normalize();
   dir1.sub(dir2);
   return ray1.origin.dist(ray2.origin) < 1e-6 && dir1.len() < 1e-6;
 }
Beispiel #2
0
  public static void main(String args[]) {
    Vector3d viewPoint = new Vector3d(1, 0.5, 2);
    Vector3d viewDir = new Vector3d(15.23, -1.854, 65.221);
    viewDir.normalize();
    Vector3d viewUp = new Vector3d(1, 0, 0);

    OrthographicCamera orthoCam = new OrthographicCamera();
    orthoCam.setViewPoint(viewPoint);
    orthoCam.setViewDir(viewDir);
    orthoCam.setViewUp(viewUp);

    PerspectiveCamera perspectiveCam = new PerspectiveCamera();
    perspectiveCam.setViewPoint(viewPoint);
    perspectiveCam.setViewDir(viewDir);
    perspectiveCam.setViewUp(viewUp);

    float u = 0.37123f;
    float v = 0.11343f;
    Ray correctRay0 =
        new Ray(
            new Vector3d(0.6235493799051484, 0.36878515466141304, 2.084176425089877),
            new Vector3d(0.22730915261287413, -0.027671120744863338, 0.9734294315537928));
    orthoCam.testGetRay(correctRay0, u, v);

    Ray correctRay1 =
        new Ray(
            new Vector3d(1.0, 0.5, 2.0),
            new Vector3d(-0.13811656557506483, -0.14714072701594028, 0.9794250460177998));
    perspectiveCam.testGetRay(correctRay1, u, v);

    u = 0.00234f;
    v = 0.9832f;
    Ray correctRay2 =
        new Ray(
            new Vector3d(1.4705511166404994, 0.005661926354425948, 1.8760675810709173),
            new Vector3d(0.22730915261287413, -0.027671120744863338, 0.9734294315537928));
    orthoCam.testGetRay(correctRay2, u, v);

    Ray correctRay3 =
        new Ray(
            new Vector3d(1.0, 0.5, 2.0),
            new Vector3d(0.5734153111840217, -0.4289226336993767, 0.698011644029039));
    perspectiveCam.testGetRay(correctRay3, u, v);

    u = 0.2345f;
    v = 0.78201f;
    Ray correctRay4 =
        new Ray(
            new Vector3d(1.2746277432055346, 0.2364287075632546, 1.928378256923414),
            new Vector3d(0.22730915261287413, -0.027671120744863338, 0.9734294315537928));
    orthoCam.testGetRay(correctRay4, u, v);

    Ray correctRay5 =
        new Ray(
            new Vector3d(1.0, 0.5, 2.0),
            new Vector3d(0.46805451959738786, -0.27158260116709737, 0.8409327306198586));
    perspectiveCam.testGetRay(correctRay5, u, v);

    u = 0.55523f;
    v = 0.12555f;
    Ray correctRay6 =
        new Ray(
            new Vector3d(0.635352111386452, 0.552789156075998, 2.0866509013806787),
            new Vector3d(0.22730915261287413, -0.027671120744863338, 0.9734294315537928));
    orthoCam.testGetRay(correctRay6, u, v);

    Ray correctRay7 =
        new Ray(
            new Vector3d(1.0, 0.5, 2.0),
            new Vector3d(-0.12844581009091482, 0.02349159814594461, 0.991438257627089));
    perspectiveCam.testGetRay(correctRay7, u, v);
  }
  @Override
  public void getColor(float u, float v, Color outColor) {
    // TODO A4
    // get our position if sphere is at 0, radius 1 (all that matters is ratios)
    Vector3d pt = getPositionFromUV(u, v);
    // create TBN inverse matrix
    Vector3d normal = (new Vector3d(pt.x, pt.y, pt.z)).normalize();
    Vector3d tangent;
    if (u < .25 || (u > .5 && u < .75)) {
      tangent = (new Vector3d(1 / pt.x, 0, -1 / pt.z)).normalize();
    } else {
      tangent = (new Vector3d(-1 / pt.x, 0, 1 / pt.z)).normalize();
    }
    Vector3d bitangent = (normal.clone().cross(tangent.clone())).normalize();
    Matrix3d invTBN =
        (new Matrix3d(
                tangent.x,
                bitangent.x,
                normal.x,
                tangent.y,
                bitangent.y,
                normal.y,
                tangent.z,
                bitangent.z,
                normal.z))
            .invert();

    // ~-- The rest of this function calculates the new normal --~
    Vector3d newNormal = new Vector3d();
    // first determine distance to closest disk center
    float divSize = (float) (1.0 / resolution);
    //   -calculate column
    float modU = u % divSize;
    float closestColumn = (u - modU) / divSize;
    if (modU > divSize / 2) {
      closestColumn++;
    }
    //   -calculate row
    float modV = v % divSize;
    float closestRow = (v - modV) / divSize;
    if (modV > divSize / 2) {
      closestRow++;
    }
    //   -calculate distance
    float centerX = closestColumn * divSize;
    float centerY = closestRow * divSize;
    double distanceToCenter = Math.sqrt(Math.pow((centerX - u), 2) + Math.pow((centerY - v), 2));
    // If we are on disk, use normal from disk center
    //   (the following formula ensures a bumpRadius of 0.5 is tangent circles, and >=1 is full
    // overlap)
    double diskRadius = (divSize / 2) * (Math.sqrt(2 * bumpRadius));
    if (distanceToCenter <= diskRadius) {
      Vector3d diskNormal = getPositionFromUV(centerX, centerY).normalize();
      newNormal = multByMatrix(diskNormal, invTBN).normalize();
    }
    // if not on disk, use position normalized as normal
    else {
      newNormal = multByMatrix(normal, invTBN).normalize();
    }

    // Convert from [-1,1] to [0,1] to [0, 255]
    Vector3d converted = new Vector3d();
    converted.setMultiple(0.5, newNormal.clone().normalize());
    converted.add(0.5);
    Colord outColorAccurate = new Colord(converted);
    outColor.set(outColorAccurate);
  }
Beispiel #4
0
  /**
   * Tests this surface for intersection with ray. If an intersection is found record is filled out
   * with the information about the intersection and the method returns true. It returns false
   * otherwise and the information in outRecord is not modified.
   *
   * @param outRecord the output IntersectionRecord
   * @param ray the ray to intersect
   * @return true if the surface intersects the ray
   */
  public boolean intersect(IntersectionRecord outRecord, Ray rayIn) {
    // TODO#A2: fill in this function.
    Vector3d p = rayIn.origin.clone().sub(center);
    Vector3d d = rayIn.direction.clone();

    double discr = Math.pow(d.dot(p), 2) - (d.dot(d)) * (p.dot(p) - Math.pow(radius, 2));

    if (discr >= 0) {
      double tPlus = (-d.dot(p) + Math.sqrt(discr)) / d.dot(d);
      double tMinus = (-d.dot(p) - Math.sqrt(discr)) / d.dot(d);
      double t = Math.min(tPlus, tMinus);

      if (t > rayIn.end || t < rayIn.start) return false;

      Vector3d intersect = new Vector3d();
      rayIn.evaluate(intersect, t);
      outRecord.location.set(intersect);

      Vector3d normal = intersect.clone().sub(center).normalize();
      outRecord.normal.set(normal);

      outRecord.t = t;
      outRecord.surface = this;

      return true;
    }
    return false;
  }