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