diff options
Diffstat (limited to 'src/world')
-rw-r--r-- | src/world/hittable.rs | 18 | ||||
-rw-r--r-- | src/world/mod.rs | 12 | ||||
-rw-r--r-- | src/world/scene.rs | 9 | ||||
-rw-r--r-- | src/world/shapes/sphere.rs | 8 |
4 files changed, 38 insertions, 9 deletions
diff --git a/src/world/hittable.rs b/src/world/hittable.rs index e11a3bc..4fbd3d0 100644 --- a/src/world/hittable.rs +++ b/src/world/hittable.rs @@ -2,6 +2,8 @@ use crate::core::{Vector3f, Bound3f, Ray}; use crate::Float; use crate::material::Material; +use std::ops::Deref; + /// Returns the context of a intersection pub struct Intersection<'a> { /// Normal vector at intersection @@ -39,3 +41,19 @@ pub trait Hittable: Sync + Send { /// Returns the axis alligned bounding box containing self fn bounding_box(&self) -> Bound3f; } + +pub struct DynHittable(Box<dyn Hittable>); + +impl DynHittable { + pub fn new(hit: Box<dyn Hittable>) -> Self { + Self (hit) + } +} + +impl Deref for DynHittable { + type Target = dyn Hittable; + + fn deref(&self) -> &Self::Target { + self.0.as_ref() + } +} diff --git a/src/world/mod.rs b/src/world/mod.rs index cba6ddc..0779551 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -5,7 +5,7 @@ mod scene; pub mod container; mod hittable; pub use scene::*; -pub use hittable::{Intersection, Hittable}; +pub use hittable::{Intersection, Hittable, DynHittable}; pub use shapes::Shape; use std::sync::Arc; @@ -13,22 +13,22 @@ use crate::material::Material; use crate::core::{Bound3f, Ray}; pub struct Object { - pub shape: Shape, + pub inner: DynHittable, pub mat: Arc<dyn Material>, } impl Object { - pub fn new<T: Into<Shape>>(mat: Arc<dyn Material>, shape: T) -> Self { + pub fn new<T: Into<DynHittable>>(mat: Arc<dyn Material>, inner: T) -> Self { Object { mat, - shape: shape.into(), + inner: inner.into(), } } } impl Hittable for Object { fn intersect(&self, ray: &Ray) -> Option<Intersection> { - if let Some(mut inter) = self.shape.intersect(ray) { + if let Some(mut inter) = self.inner.intersect(ray) { inter.add_material_if_none(self.mat.as_ref()); Some(inter) } else { @@ -37,6 +37,6 @@ impl Hittable for Object { } fn bounding_box(&self) -> Bound3f { - self.shape.bounding_box() + self.inner.bounding_box() } } diff --git a/src/world/scene.rs b/src/world/scene.rs index 87bec1f..8954050 100644 --- a/src/world/scene.rs +++ b/src/world/scene.rs @@ -1,5 +1,7 @@ use crate::core::{Bound3f, Ray}; +use std::iter::IntoIterator; + use super::{Object, container, Hittable, Intersection}; type Container = container::HittableList; @@ -17,8 +19,11 @@ impl Scene { self.content.add(obj); } - pub fn add_objects(&mut self, objs: Vec<Object>) { - for obj in objs { + pub fn add_objects<T>(&mut self, objs: T) + where + T: IntoIterator<Item = Object>, + { + for obj in objs.into_iter() { self.add_object(obj); } } diff --git a/src/world/shapes/sphere.rs b/src/world/shapes/sphere.rs index 1df9c35..fc2cfe2 100644 --- a/src/world/shapes/sphere.rs +++ b/src/world/shapes/sphere.rs @@ -3,7 +3,7 @@ //! Spheres are relatively easy to calculate intersections between use crate::{Float, NEAR_ZERO}; use crate::core::{Ray, Vector3f, Bound3f}; -use crate::world::{Hittable, Intersection}; +use crate::world::{Hittable, DynHittable, Intersection}; pub struct Sphere { radius: Float, @@ -79,6 +79,12 @@ impl Hittable for Sphere { } } +impl Into<DynHittable> for Sphere { + fn into(self) -> DynHittable { + DynHittable::new(Box::new(self)) + } +} + #[cfg(test)] mod tests { use super::*; |