예제 #1
0
  /**
   * Intersect the given Ray with this shape. Tests for every triangle of the shape. Speed depends
   * hence on the complexity of the shape.
   *
   * @param Ray ray The Ray to be intersected
   * @param Matrix4f transformation The transformation of the Shape into its actual position
   * @return a RayShapeIntersection with the coordinates of the HitPoint if any.
   */
  public RayShapeIntersection intersect(Ray ray, Matrix4f transformation) {
    RayShapeIntersection intersection = new RayShapeIntersection();
    List<RayShapeIntersection> hitTriangles = new ArrayList<RayShapeIntersection>();

    // get all triangles
    Iterator<Triangle> it = getTriangles().iterator();
    Triangle triangle;
    // calculate intersection of ray and triangle
    while (it.hasNext()) {
      triangle = it.next();
      triangle.transform(transformation);
      intersection = calculateIntersection(ray, triangle);
      if (intersection.hit) {
        hitTriangles.add(intersection);
      }
    }

    Vector3f distance = new Vector3f();
    float shortestDist = Float.MAX_VALUE;
    for (RayShapeIntersection in : hitTriangles) {
      distance.sub(ray.getOrigin(), in.hitPoint);
      if (distance.length() < shortestDist) {
        intersection = in;
        shortestDist = distance.length();
      }
    }

    // return the intersected point if any
    return intersection;
  }
예제 #2
0
  private RayShapeIntersection calculateIntersection(Ray ray, Triangle triangle) {
    RayShapeIntersection intersection = new RayShapeIntersection();
    Vector3f u = new Vector3f();
    Vector3f v = new Vector3f();
    u.sub(triangle.mY, triangle.mX);
    v.sub(triangle.mZ, triangle.mX);

    Vector3f n = new Vector3f();
    n.cross(u, v);

    if (n.epsilonEquals(mZeroVector, mEpsilon)) {
      // Triangle is either a point or a line (degenerate)
      // Don't deal with this case
      return intersection;
    }

    Vector3f w0 = new Vector3f();
    w0.sub(ray.getOrigin(), triangle.mX);

    float a = -n.dot(w0);
    float b = n.dot(ray.getDirection());
    if (Math.abs(b) < mEpsilon) { // ray is parallel to triangle plane
      if (a == 0) {
        // ray lies in triangle plane
        return intersection;
      } else {
        // ray disjoint from plane
        return intersection;
      }
    }

    float r = a / b;
    if (r < 0.f) {
      // ray goes away from triangle
      return intersection;
    }

    intersection.hit = true;
    intersection.hitPoint = new Vector3f();
    intersection.hitPoint.scaleAdd(r, ray.getDirection(), ray.getOrigin());

    // Is intersection inside the triangle?
    Vector3f w = new Vector3f();
    w.sub(intersection.hitPoint, triangle.mX);
    float uu, uv, vv, wu, wv, D;
    uu = u.dot(u);
    uv = u.dot(v);
    vv = v.dot(v);
    wu = w.dot(u);
    wv = w.dot(v);
    D = uv * uv - uu * vv;

    // get and test parametric coordinates
    float s, t;
    s = (uv * wv - vv * wu) / D;
    if (s < 0.f || s > 1) {
      // I is outside T
      intersection.hit = false;
      intersection.hitPoint = null;
      return intersection;
    }

    t = (uv * wu - uu * wv) / D;
    if (t < 0.0 || (s + t) > 1.0) {
      // I is outside T
      intersection.hit = false;
      intersection.hitPoint = null;
      return intersection;
    }

    return intersection;
  }