1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use hit::Hit;
use material::Material;
use bvh::*;
use ray::Ray;
use PrimitiveType;
use Traceable;
use bvh::aabb::{Bounded, AABB};
use bvh::bounding_hierarchy::{BHShape, BoundingHierarchy};
use bvh::bvh::BVH;
#[derive(Copy, Clone)]
pub struct Triangle {
pub p0: Vector3,
pub p1: Vector3,
pub p2: Vector3,
pub normal: Vector3,
pub n0: Vector3,
pub n1: Vector3,
pub n2: Vector3,
pub material: Material,
aabb: AABB,
node_index: usize,
}
impl Triangle {
pub fn new(p0: Vector3, p1: Vector3, p2: Vector3, material: Material) -> Triangle {
let temp_p0: Vector3 = Vector3::new(p0.x, p0.y, p0.z);
let temp_p1: Vector3 = Vector3::new(p1.x, p1.y, p1.z);
let temp_p2: Vector3 = Vector3::new(p2.x, p2.y, p2.z);
Triangle {
p0: p0,
p1: p1,
p2: p2,
normal: (p2 - p0).normalize().cross((p1 - p0).normalize()),
n0: (p2 - p0).normalize().cross((p1 - p0).normalize()),
n1: (p2 - p0).normalize().cross((p1 - p0).normalize()),
n2: (p2 - p0).normalize().cross((p1 - p0).normalize()),
material: material,
aabb: AABB::empty().grow(&temp_p0).grow(&temp_p1).grow(&temp_p2),
node_index: 0,
}
}
pub fn new_ext(
p0: Vector3,
p1: Vector3,
p2: Vector3,
n0: Vector3,
n1: Vector3,
n2: Vector3,
material: Material,
) -> Triangle {
let temp_p0: Point3 = Point3::new(p0.x, p0.y, p0.z);
let temp_p1: Point3 = Point3::new(p1.x, p1.y, p1.z);
let temp_p2: Point3 = Point3::new(p2.x, p2.y, p2.z);
Triangle {
p0: p0,
p1: p1,
p2: p2,
n0: n0,
n1: n1,
n2: n2,
normal: (p2 - p0).normalize().cross((p1 - p0).normalize()),
material: material,
aabb: AABB::empty().grow(&temp_p0).grow(&temp_p1).grow(&temp_p2),
node_index: 0,
}
}
}
impl Traceable for Triangle {
fn intersect(&self, r: &Ray, result: &mut Hit) -> bool {
let p0p1 = self.p1 - self.p0;
let p0p2 = self.p2 - self.p0;
let pvec = r.direction.cross(p0p2);
let det = p0p1.dot(pvec).abs();
let tvec = r.origin - self.p0;
let u = tvec.dot(pvec) / det;
if u < 0.0 || u > 1.0 {
return false;
};
let qvec = tvec.cross(p0p1);
let v = r.direction.dot(qvec) / det;
if v < 0.0 || u + v > 1.0 {
return false;
};
result.t = p0p2.dot(qvec) / det;
result.p = r.origin + r.direction * result.t;
result.material = self.material;
result.b = Vector3::new(1.0 - u - v, u, v);
result.n = result.b.x * self.n0 + result.b.y * self.n1 + result.b.z * self.n2;
return true;
}
fn get_primitive_type(&self) -> PrimitiveType {
PrimitiveType::Triangle
}
}
impl Bounded for Triangle {
fn aabb(&self) -> AABB {
self.aabb
}
}
impl BHShape for Triangle {
fn set_bh_node_index(&mut self, index: usize) {
self.node_index = index;
}
fn bh_node_index(&self) -> usize {
self.node_index
}
}