use std; use crate::aabb::surrounding_box; use crate::aabb::AABB; use crate::hitable::Hit; use crate::hitable::HitRecord; use crate::ray::Ray; use crate::vec3::Vec3; #[derive(Default)] pub struct HitableList { list: Vec>, } impl HitableList { pub fn new(list: Vec>) -> HitableList { HitableList { list } } } impl Hit for HitableList { fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option { 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 { // 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, } })) } }