1 #ifndef TRIANGLE_HXX
2 #define TRIANGLE_HXX
3
4 #include "Primitive.hxx"
5 #include "Shader.hxx"
6 #include "Box.hxx"
7
8 using namespace std;
9
10 class Triangle : public Primitive
11 {
12 Vec3f a, b, c, edge1, edge2, normal, min, max;
13 Box box;
14 public:
15 Triangle(Vec3f a, Vec3f b, Vec3f c, Shader *shader, PhotonDistributor *photon_distributor)
16 : Primitive(shader, photon_distributor),a(a),b(b),c(c)
17 {
18 // Precomputation general
19 edge1 = b - a;
20 edge2 = c - a;
21
22 // Precomputation normal
23 normal = Cross(edge1, edge2);
24 Normalize(normal);
25
26 // Precomputation bounds
27 box.Extend(a);
28 box.Extend(b);
29 box.Extend(c);
30
31 box.Extend(box.min - Vec3f(Epsilon));
32 box.Extend(box.max + Vec3f(Epsilon));
33 };
34
35 virtual ~Triangle(){};
36
37 virtual bool Intersect(Ray &ray)
38 {
39 const Vec3f pvec = ray.dir ^ edge2;
40
41 const float det = Dot(edge1, pvec);
42 if (fabs(det) < 1E-5)
43 return false;
44
45 const float inv_det = 1.0f / det;
46
47 const Vec3f tvec = ray.org - a;
48 float lambda = Dot(tvec, pvec);
49 lambda *= inv_det;
50
51 if (lambda < 0.0f || lambda > 1.0f)
52 return false;
53
54 const Vec3f qvec = tvec^edge1;
55 float mue = Dot(ray.dir, qvec);
56 mue *= inv_det;
57
58 if (mue < 0.0f || mue + lambda > 1.0f)
59 return false;
60
61 float f = Dot(edge2, qvec);
62 f *= inv_det;
63 if (ray.t <= f || f < 1E-5)
64 return false;
65
66 ray.u = lambda;
67 ray.v = mue;
68
69 ray.t = f;
70 ray.hit = this;
71
72 return true;
73 };
74
75 virtual Vec3f GetNormal(Ray &ray)
76 {
77 return normal;
78 };
79
80 virtual Box CalcBounds()
81 {
82 return box;
83 }
84 };
85
86 #endif
syntax highlighted by Code2HTML, v. 0.9.1