// TODO - ED: Test // Source: https://github.com/erich666/GraphicsGems/blob/master/gems/RayBox.c public bool IntersectRay(FixRay ray, out Fix distance) { int whichPlane; bool inside = true; Quadrant[] quadrant = new Quadrant[3]; Fix[] maxT = new Fix[3]; Fix[] candidatePlane = new Fix[3]; Fix[] coord = new Fix[3]; FixVec3 intersection; Fix[] minB = { _min.X, _min.Y, _min.Z }; Fix[] maxB = { _max.X, _max.Y, _max.Z }; Fix[] rayOrigin = { ray.origin.X, ray.origin.Y, ray.origin.Z }; Fix[] rayDirection = { ray.direction.X, ray.direction.Y, ray.direction.Z }; // Find candidate planes; this loop can be avoided if // rays cast all from the eye(assume perpsective view). for (int i = 0; i < 3; i++) { if (rayOrigin[i] < minB[i]) { quadrant[i] = Quadrant.LEFT; candidatePlane[i] = minB[i]; inside = false; } else if (rayOrigin[i] > maxB[i]) { quadrant[i] = Quadrant.RIGHT; candidatePlane[i] = maxB[i]; inside = false; } else { quadrant[i] = Quadrant.MIDDLE; } } // Ray origin inside bounding box. if (inside) { distance = Fix.Zero; return(true); } // Calculate T distances to candidate planes. for (int i = 0; i < 3; i++) { if (quadrant[i] != Quadrant.MIDDLE && rayDirection[i] != Fix.Zero) { maxT[i] = (candidatePlane[i] - rayOrigin[i]) / rayDirection[i]; } else { maxT[i] = -Fix.One; } } // Get largest of the maxT's for final choice of intersection. whichPlane = 0; for (int i = 1; i < 3; i++) { if (maxT[whichPlane] < maxT[i]) { whichPlane = i; } } // Check final candidate actually inside box. if (maxT[whichPlane] < Fix.Zero) { distance = Fix.Zero; return(false); } for (int i = 0; i < 3; i++) { if (whichPlane != i) { coord[i] = rayOrigin[i] + maxT[whichPlane] * rayDirection[i]; if (coord[i] < minB[i] || coord[i] > maxB[i]) { distance = Fix.Zero; return(false); } } else { coord[i] = candidatePlane[i]; } } intersection = new FixVec3(coord[0], coord[1], coord[2]); distance = (intersection - ray.origin).GetMagnitude(); return(true); }
// TODO - ED: Test public bool IntersectRay(FixRay ray) { Fix dummy; return(IntersectRay(ray, out dummy)); }