/** * 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(B): fill in this function. // Hint: This object can be transformed by a transformation matrix. // So the rayIn needs to be processed so that it is in the same // coordinate as the object. Ray ray = untransformRay(rayIn); double ax = owner.getVertex(index[0]).x; double ay = owner.getVertex(index[0]).y; double az = owner.getVertex(index[0]).z; double px = ray.origin.x; double py = ray.origin.y; double pz = ray.origin.z; double dx = ray.direction.x; double dy = ray.direction.y; double dz = ray.direction.z; // calculating t, gamma, and beta based on linear system presented in // Shirley and Marschner double ei_hf = e * dz - dy * f; double gf_di = dx * f - d * dz; double dh_eg = d * dy - e * dx; double ak_jb = a * (ay - py) - (ax - px) * b; double jc_al = (ax - px) * c - a * (az - pz); double bl_kc = b * (az - pz) - (ay - py) * c; double m = a * ei_hf + b * gf_di + c * dh_eg; double t = -(f * ak_jb + e * jc_al + d * bl_kc) / m; if (t < ray.start || t > ray.end) { return false; } double gamma = (dz * ak_jb + dy * jc_al + dx * bl_kc) / m; if (gamma < 0 || gamma > 1) { return false; } double beta = ((ax - px) * ei_hf + (ay - py) * gf_di + (az - pz) * dh_eg) / m; if (beta < 0 || beta > 1 - gamma) { return false; } if (outRecord != null) { outRecord.t = t; ray.evaluate(outRecord.location, t); outRecord.surface = this; if (norm == null) { // interpolate normal based on barycentric coords double alpha = 1.0 - gamma - beta; Vector3 an = owner.getNormal(index[0]); an.scale(alpha); Vector3 bn = owner.getNormal(index[1]); bn.scale(beta); Vector3 cn = owner.getNormal(index[2]); cn.scale(gamma); Vector3 n = new Vector3(an.x + bn.x + cn.x, an.y + bn.y + cn.y, an.z + bn.z + cn.z); outRecord.normal.set(n); } else { outRecord.normal.set(norm); } tMat.rightMultiply(outRecord.location); tMatTInv.rightMultiply(outRecord.normal); outRecord.normal.normalize(); } return true; }