/* * CS5600 University of Utah * Charles McGarvey * mcgarvey@eng.utah.edu */ #ifndef _TRIANGLE_HH_ #define _TRIANGLE_HH_ #include "color.hh" #include "element.hh" namespace rt { /* * A class for a triangle object. */ class triangle : public element { public: color_t material; vec_t a; vec_t b; vec_t c; triangle(vec_t a, vec_t b, vec_t c, color_t color = COLOR_WHITE) : a(a), b(b), c(c), material(color) {} virtual ~triangle() {} virtual bool intersect(ray_t ray, contact_t& hit) const { plane p = plane(a, b, c); if (!p.intersect(ray, hit)) { return false; } scal_t bc[3]; if (barycentric(bc, hit.p)) { return true; } return false; } virtual color_t color(vec_t point) const { return material; } /* * Calculate barycentric coordinates for the triangle. */ bool barycentric(scal_t* bc, vec_t v) const { scal_t denom = (b.y - c.y) * (a.x - c.x) + (c.x - b.x) * (a.y - c.y); bc[0] = ((b.y - c.y) * (v.x - c.x) + (c.x - b.x) * (v.y - c.y)) / denom; bc[1] = ((c.y - a.y) * (v.x - c.x) + (a.x - c.x) * (v.y - c.y)) / denom; bc[2] = S(1.0) - bc[0] - bc[1]; if (S(0.0) <= bc[0] && bc[0] <= S(1.0) && S(0.0) <= bc[1] && bc[1] <= S(1.0) && S(0.0) <= bc[2] && bc[2] <= S(1.0)) { return true; } return false; } }; /* * Destroy a new'd triangle, releasing its memory. */ INLINE_MAYBE void triangle_destroy(plane* t) { delete t; } } // namespace rt #endif // _PLANE_HH_