1 #include "triangle.h"
2 #include <iostream.h>
3 #include <assert.h>
4 #include <algorithm>
5
6 Triangle::Triangle() { }
7
8 Triangle::Triangle(const Vector& v0,const Vector& v1, const Vector& v2) {
9 v_[0] = v0;
10 v_[1] = v1;
11 v_[2] = v2;
12 triNrm_ = makeCWTriangleNormal(v_[0],v_[1],v_[2]);
13 n_[0] = n_[1] = n_[2] = triNrm_;
14 }
15
16
17 void Triangle::normalizeNormals() {
18 n_[0].normalize();
19 n_[1].normalize();
20 n_[2].normalize();
21 }
22
23 static inline int MeshMaxIndex(double a, double b, double c) {
24 return((a > b) ? ((a > c) ? 0 : 2) : ((b > c) ? 1 : 2));
25 }
26
27 bool Triangle::intersect(const Ray& ray,Vector& point,Vector& normal, double& distance) const {
28 // edges of the triangle
29 const Vector edge1 = v_[1] - v_[0];
30 const Vector edge2 = v_[2] - v_[0];
31
32 const Vector p = ray.getDirection() * edge2;
33 const double detA = dotProduct(p, edge1);
34
35 // det(A) != 0
36 if (detA == 0)
37 return false;
38
39 const double f = 1/detA;
40 const Vector s = ray.getOrigin() - v_[0];
41 const double u = f * dotProduct(p, s);
42
43 // first barycentric value must be in [0,1]
44 if (u<0 || u>1)
45 return false;
46
47 const Vector q = s*edge1;
48 const double v = f * dotProduct(q, ray.getDirection());
49
50 // second barycentric value must be in [0,1]
51 if (v<0 || v>1 || u+v>1)
52 return false;
53
54 const double t = f * dotProduct(q, edge2);
55
56 // object on the wrong side of the ray ?
57 if (t <= 0)
58 return false;
59
60
61 // intersection found, barycentric coordinates are (u,v,t)
62 point = ray.getOrigin() + t*ray.getDirection();
63
64 normal = triNrm_;
65 // invert normal to allow the triangle being viewed from its back side
66 if (dotProduct(normal, ray.getDirection()) > 0)
67 normal = -normal;
68
69 distance = t;//abs(point-ray.getOrigin());
70
71 return true;
72 }
73
74 //
75 // IO
76 //
77
78 istream& operator>>(istream& s, Triangle& u) {
79 Vector t;
80 for (int i = 0; i < 3; i++) {
81 if (!(s >> t[0] >> t[1] >> t[2])) {
82 assert(0);
83 }
84 u.v_[i] = t;
85 }
86 u.triNrm_ = makeCWTriangleNormal(u.v_[0],u.v_[1],u.v_[2]);
87 u.n_[0] = u.n_[1] = u.n_[2] = u.triNrm_;
88 return s;
89 }
90