49 lines
1.3 KiB
Rust
49 lines
1.3 KiB
Rust
use std;
|
|
|
|
use crate::{
|
|
aabb::{surrounding_box, AABB},
|
|
hitable::{Hit, HitRecord},
|
|
ray::Ray,
|
|
vec3::Vec3,
|
|
};
|
|
|
|
#[derive(Default)]
|
|
pub struct HitableList {
|
|
list: Vec<Box<dyn Hit>>,
|
|
}
|
|
|
|
impl HitableList {
|
|
pub fn new(list: Vec<Box<dyn Hit>>) -> HitableList {
|
|
HitableList { list }
|
|
}
|
|
}
|
|
|
|
impl Hit for HitableList {
|
|
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
|
let mut min_hit = None;
|
|
let mut closest_so_far = t_max;
|
|
for hitable in &self.list {
|
|
if let Some(h) = hitable.hit(r, t_min, closest_so_far) {
|
|
closest_so_far = h.t;
|
|
min_hit = Some(h);
|
|
}
|
|
}
|
|
min_hit
|
|
}
|
|
|
|
fn bounding_box(&self, t_min: f32, t_max: f32) -> Option<AABB> {
|
|
// TODO(wathiede): I don't understand the version from the book, this implementation
|
|
// returns a superset of all bounding boxes.
|
|
let super_box = AABB::new(
|
|
Vec3::new(std::f32::MAX, std::f32::MAX, std::f32::MAX),
|
|
Vec3::new(std::f32::MIN, std::f32::MIN, std::f32::MIN),
|
|
);
|
|
Some(self.list.iter().fold(super_box, |acc, hitable| {
|
|
match hitable.bounding_box(t_min, t_max) {
|
|
Some(bbox) => surrounding_box(&acc, &bbox),
|
|
None => acc,
|
|
}
|
|
}))
|
|
}
|
|
}
|