#ifndef TRIANGLE_H #define TRIANGLE_H #include "entity.h" #include "lin_alg.h" class Triangle : public Entity { public: Triangle(const vector3d& x, const vector3d& y, const vector3d& z) { a = x; b = y; c = z; UpdateNorm(); } virtual ~Triangle() {} virtual RayIntersect CalcRayIntersect(Ray ray, int special=-1); virtual vector3d CalcNormal(Ray ray, RayIntersect&ri); virtual void PathCompress(const Transform&T, queue >&, vector&); virtual int IntersectionTest(Ray ray, int special=-1); virtual void GridCollect(vector& vec) { EntityWrapBound ewb; ewb.E = this; ewb.lo = a; ewb.hi = a; update_min_max(ewb.lo, ewb.hi, b); update_min_max(ewb.lo, ewb.hi, c); vec.push_back(ewb); } const vector3d& GetA() {return a;} const vector3d& GetB() {return b;} const vector3d& GetC() {return c;} private: void UpdateNorm() { norm = (b-a).cross(c-a); norm.make_unit(); } vector3d a, b, c, norm; }; double intersect_triangle_ray(Ray & ray, vector3d&a, vector3d&b, vector3d&c, double&aa, double&bb); inline void Triangle::PathCompress(const Transform&T, queue >&Q, vector&V) { Triangle * tr = new Triangle(*this); tr->a = T*a; tr->b = T*b; tr->c = T*c; tr->UpdateNorm(); V.push_back(tr); } inline RayIntersect Triangle::CalcRayIntersect(Ray ray, int special) { RayIntersect ri; double aa, bb; ri.param_t = intersect_triangle_ray(ray, a, b, c, aa, bb); ri.E = ri.param_t < 1 ? 0 : this; return ri; } inline int Triangle::IntersectionTest(Ray ray, int special) { double aa, bb; return intersect_triangle_ray(ray, a, b, c, aa, bb) > 0; } inline vector3d Triangle::CalcNormal(Ray ray, RayIntersect&ri) { return norm; } #endif