From 3f78cacdd93036dbd51bae77d5d8e5430a0bc75f Mon Sep 17 00:00:00 2001 From: Julian T Date: Sat, 6 Mar 2021 16:15:26 +0100 Subject: Several changes to bounding boxes For instance removed support for shapes without a bounding box, such as planes --- src/world/container.rs | 43 ---------------------------------- src/world/container/list.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++ src/world/container/mod.rs | 3 +++ src/world/hittable.rs | 4 +--- src/world/mod.rs | 5 ++-- src/world/scene.rs | 14 ++++++++---- src/world/shapes/sphere.rs | 13 +++++------ 7 files changed, 78 insertions(+), 60 deletions(-) delete mode 100644 src/world/container.rs create mode 100644 src/world/container/list.rs create mode 100644 src/world/container/mod.rs (limited to 'src/world') diff --git a/src/world/container.rs b/src/world/container.rs deleted file mode 100644 index 6f8c182..0000000 --- a/src/world/container.rs +++ /dev/null @@ -1,43 +0,0 @@ -use super::{Hittable, Intersection}; -use crate::core::Ray; - -pub struct HittableList { - elems: Vec>, -} - -impl HittableList { - pub fn new() -> Self { - Self::default() - } - - pub fn add(&mut self, h: Box) { - self.elems.push(h); - } -} - -impl Hittable for HittableList { - fn intersect(&self, ray: &Ray) -> Option { - let mut min: Option = None; - - for e in self.elems.iter() { - if let Some(i) = e.intersect(&ray) { - match min { - // Do nothing if distance is bigger than min - Some(ref min_i) if min_i.t < i.t => {}, - // If no existing min or closer than - _ => min = Some(i), - } - } - } - - min - } -} - -impl Default for HittableList { - fn default() -> Self { - Self { - elems: Vec::new(), - } - } -} diff --git a/src/world/container/list.rs b/src/world/container/list.rs new file mode 100644 index 0000000..c8e3fdd --- /dev/null +++ b/src/world/container/list.rs @@ -0,0 +1,56 @@ +use crate::world::{Hittable, Intersection}; +use crate::core::{Bound3f, Ray}; + + +pub struct HittableList { + elems: Vec>, +} + +impl HittableList { + pub fn new() -> Self { + Self::default() + } + + pub fn add(&mut self, h: Box) { + self.elems.push(h); + } +} + +impl Hittable for HittableList { + fn intersect(&self, ray: &Ray) -> Option { + let mut min: Option = None; + + for e in self.elems.iter() { + if let Some(i) = e.intersect(&ray) { + match min { + // Do nothing if distance is bigger than min + Some(ref min_i) if min_i.t < i.t => {}, + // If no existing min or closer than + _ => min = Some(i), + } + } + } + + min + } + + fn bounding_box(&self) -> Bound3f { + let mut bound: Bound3f = Bound3f::EMPTY; + + for e in self.elems.iter() { + let eb = e.bounding_box(); + bound = bound.combine(&eb); + } + + bound + } +} + +impl Default for HittableList { + fn default() -> Self { + Self { + elems: Vec::new(), + } + } +} + diff --git a/src/world/container/mod.rs b/src/world/container/mod.rs new file mode 100644 index 0000000..35d4693 --- /dev/null +++ b/src/world/container/mod.rs @@ -0,0 +1,3 @@ +mod list; + +pub use list::HittableList; diff --git a/src/world/hittable.rs b/src/world/hittable.rs index 720a019..c5a353e 100644 --- a/src/world/hittable.rs +++ b/src/world/hittable.rs @@ -27,7 +27,5 @@ pub trait Hittable: Sync + Send { fn intersect(&self, ray: &Ray) -> Option; /// Returns the axis alligned bounding box containing self - fn bounding_box(&self) -> Option { - None - } + fn bounding_box(&self) -> Bound3f; } diff --git a/src/world/mod.rs b/src/world/mod.rs index 43f7530..53d8ad3 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -2,11 +2,10 @@ pub mod shapes; mod scene; -mod container; +pub mod container; mod hittable; pub use scene::*; pub use hittable::{Intersection, Hittable}; -pub use container::HittableList; use std::sync::Arc; use crate::material::Material; @@ -31,7 +30,7 @@ impl Hittable for Object { self.shape.intersect(ray).map(|mut i| {i.m = Some(self.mat.as_ref()); i}) } - fn bounding_box(&self) -> Option { + fn bounding_box(&self) -> Bound3f { self.shape.bounding_box() } } diff --git a/src/world/scene.rs b/src/world/scene.rs index 03578be..6d15fc1 100644 --- a/src/world/scene.rs +++ b/src/world/scene.rs @@ -1,9 +1,11 @@ -use crate::core::Ray; +use crate::core::{Bound3f, Ray}; -use super::{Object, HittableList, Hittable, Intersection}; +use super::{Object, container, Hittable, Intersection}; + +type Container = container::HittableList; pub struct Scene { - content: HittableList, + content: Container, } impl Scene { @@ -26,12 +28,16 @@ impl Hittable for Scene { fn intersect(&self, ray: &Ray) -> Option { self.content.intersect(ray) } + + fn bounding_box(&self) -> Bound3f { + self.content.bounding_box() + } } impl Default for Scene { fn default() -> Self { Self { - content: HittableList::new(), + content: Container::new(), } } } diff --git a/src/world/shapes/sphere.rs b/src/world/shapes/sphere.rs index 55fc8b4..e3348de 100644 --- a/src/world/shapes/sphere.rs +++ b/src/world/shapes/sphere.rs @@ -57,19 +57,18 @@ impl Hittable for Sphere { /// # Examples /// /// ``` - /// use rendering::core::{Vector3f, Hittable}; - /// use rendering::world::shapes::Sphere; + /// use rendering::core::Vector3f; + /// use rendering::world::{Hittable, shapes::Sphere}; /// /// let sph = Sphere::new(1.0, Vector3f::new(0.0)); - /// let b = sph.bounding_box().unwrap(); + /// let b = sph.bounding_box(); /// /// assert!(b.min.x == -1.0 && b.min.y == -1.0 && b.min.z == -1.0); /// assert!(b.max.x == 1.0 && b.max.y == 1.0 && b.max.z == 1.0); - fn bounding_box(&self) -> Option { + fn bounding_box(&self) -> Bound3f { let offset = Vector3f::new(self.radius); - Some( - Bound3f::new(self.center - offset, self.center + offset) - ) + + Bound3f::new(self.center - offset, self.center + offset) } } -- cgit v1.2.3