/* * CS5600 University of Utah * Charles McGarvey * mcgarvey@eng.utah.edu */ #ifndef _PLANE_HH_ #define _PLANE_HH_ #include "element.hh" namespace rt { /* * A class for a plane object. */ class plane : public element { vec_t norm; scal_t dist; public: plane(vec_t n, scal_t d) : norm(n), dist(d) {} plane(vec_t p, vec_t n) : norm(vec_normalize(n)), dist(-vec_dot(norm, p)) {} plane(vec_t a, vec_t b, vec_t c) : norm(vec_normalize(vec_cross(vec_sub(b, a), vec_sub(c, a)))), dist(-vec_dot(norm, a)) {} virtual ~plane() {} /* * Get the normal vector of the plane. */ vec_t normal() const { return norm; } virtual bool intersect(ray_t ray, contact_t& hit) const { scal_t denom = vec_dot(ray.d, norm); // check for parallel condition if (denom == S(0.0)) { if (scal_isequal(vec_dot(ray.o, norm), -dist)) { hit.p = ray.o; hit.d = S(0.0); hit.n = VEC_ZERO; return true; // the ray lies on the plane } return false; // no solution } scal_t numer = vec_dot(ray.o, norm) + dist; hit.d = -numer / denom; if (hit.d < S(0.0)) { return false; } hit.p = ray_solve(ray, hit.d); if (S(0.0) <= numer) { hit.n = norm; } else { hit.n = vec_neg(norm); } return true; } virtual vec_t txcoord(vec_t point) const { vec_t uv = VEC_ZERO; point.x *= S(0.3); point.y *= S(0.3); uv.x = point.x - scal_floor(point.x); uv.y = point.z - scal_floor(point.z); return uv; } }; /* * Destroy a new'd plane, releasing its memory. */ INLINE_MAYBE void plane_destroy(plane* p) { delete p; } } // namespace rt #endif // _PLANE_HH_