1use bsdf::BSDF;
2use bvh::aabb::{Bounded, AABB};
3use bvh::bounding_hierarchy::BoundingHierarchy;
4use bvh::bvh::BVH;
5use bvh::ray::Ray as NewRay;
6use bvh::Point3;
7use hit::Hit;
8use ray::Ray;
9use std::f32::INFINITY;
10use triangle::Triangle;
11use Traceable;
12
13pub struct Scene {
15 pub objects: Vec<Box<dyn Traceable>>,
16 pub triangles: Vec<Triangle>,
17 bvh: BVH,
19 bvh_built: bool,
20}
21
22impl Scene {
23 pub fn add(&mut self, obj: Box<dyn Traceable>) {
24 self.objects.push(obj);
25 }
26
27 pub fn add_triangle(&mut self, triangle: Triangle) {
28 self.triangles.push(triangle);
29 }
30
31 pub fn init() -> Scene {
32 Scene {
33 objects: vec![],
34 triangles: vec![],
35 bvh: BVH { nodes: vec![] },
36 bvh_built: false,
37 }
38 }
39
40 pub fn intersect(&self, ray: Ray) -> Option<Hit> {
41 let mut final_hit = Hit::init();
42
43 for s in 0..self.objects.len() {
45 let mut current_hit = Hit::init();
46 let hit = self.objects[s].intersect(&ray, &mut current_hit);
47
48 if hit && current_hit.t < final_hit.t && current_hit.t > 1e-6 {
50 final_hit = current_hit;
51 }
52 }
53
54 if self.bvh_built {
55 let bvh_ray = NewRay::new(
56 Point3::new(ray.origin.x, ray.origin.y, ray.origin.z),
57 Point3::new(ray.direction.x, ray.direction.y, ray.direction.z),
58 );
59 let hits = self.bvh.traverse(&bvh_ray, &self.triangles);
60
61 if !hits.is_empty() {
63 let mut current_hit = Hit::init();
64
65 for hit in hits {
67 let is_hit = hit.intersect(&ray, &mut current_hit);
68
69 if is_hit && current_hit.t < final_hit.t && current_hit.t > 1e-6 {
70 final_hit = current_hit;
71 }
72 }
73 }
74 }
75
76 if final_hit.t != INFINITY {
77 Some(final_hit)
78 } else {
79 None
80 }
81 }
82
83 pub fn build_bvh(&mut self) {
84 self.bvh = BVH::build(&mut self.triangles);
85 self.bvh_built = true; }
87}