raytracers/rtiow/renderer/src/hitable_list.rs
2022-07-28 21:39:00 -07:00

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,
}
}))
}
}