smallpt/
scene.rs

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
13// #[derive(Default)]
14pub struct Scene {
15	pub objects: Vec<Box<dyn Traceable>>,
16	pub triangles: Vec<Triangle>,
17	//
18	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		// Intersect parametric scene objects
44		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			// todo: hit min&max
49			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			// Triangles vs BVH
62			if !hits.is_empty() {
63				let mut current_hit = Hit::init();
64
65				// Of all the hits, return the closest hit
66				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; //boo
86	}
87}