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
use bsdf::BSDF;
use bvh::aabb::{Bounded, AABB};
use bvh::bounding_hierarchy::BoundingHierarchy;
use bvh::bvh::BVH;
use bvh::{Point3,};
use bvh::ray::Ray as NewRay;
use hit::Hit;
use ray::Ray;
use std::f32::*;
use triangle::Triangle;
use Traceable;
pub struct Scene {
pub objects: Vec<Box<dyn Traceable>>,
pub triangles: Vec<Triangle>,
bvh: BVH,
bvh_built: bool,
}
impl Scene {
pub fn add(&mut self, obj: Box<dyn Traceable>) {
self.objects.push(obj);
}
pub fn add_triangle(&mut self, triangle: Triangle) {
self.triangles.push(triangle);
}
pub fn init() -> Scene {
Scene {
objects: vec![],
triangles: vec![],
bvh: BVH { nodes: vec![] },
bvh_built: false,
}
}
pub fn intersect(&self, ray: Ray) -> Option<Hit> {
let mut final_hit = Hit::init();
for s in 0..self.objects.len() {
let mut current_hit = Hit::init();
let hit = self.objects[s].intersect(&ray, &mut current_hit);
if hit == true && current_hit.t < final_hit.t && current_hit.t > 1e-6 {
final_hit = current_hit;
}
}
if self.bvh_built {
let bvh_ray = NewRay::new(
Point3::new(ray.origin.x, ray.origin.y, ray.origin.z),
Point3::new(ray.direction.x, ray.direction.y, ray.direction.z),
);
let hits = self.bvh.traverse(&bvh_ray, &self.triangles);
if hits.len() > 0 {
let mut current_hit = Hit::init();
for hit in 0..hits.len() {
let hit = hits[hit].intersect(&ray, &mut current_hit);
if hit == true && current_hit.t < final_hit.t && current_hit.t > 1e-6 {
final_hit = current_hit;
}
}
}
}
if final_hit.t != INFINITY {
Some(final_hit)
} else {
None
}
}
pub fn build_bvh(&mut self) {
self.bvh = BVH::build(&mut self.triangles);
self.bvh_built = true;
}
}