/** * 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; }
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; }