diff options
Diffstat (limited to 'src/world')
-rw-r--r-- | src/world/container/list.rs | 56 | ||||
-rw-r--r-- | src/world/container/mod.rs | 3 | ||||
-rw-r--r-- | src/world/hittable.rs | 41 | ||||
-rw-r--r-- | src/world/mod.rs | 42 | ||||
-rw-r--r-- | src/world/scene.rs | 43 | ||||
-rw-r--r-- | src/world/shapes/mod.rs | 30 | ||||
-rw-r--r-- | src/world/shapes/sphere.rs | 98 |
7 files changed, 0 insertions, 313 deletions
diff --git a/src/world/container/list.rs b/src/world/container/list.rs deleted file mode 100644 index 22b6d88..0000000 --- a/src/world/container/list.rs +++ /dev/null @@ -1,56 +0,0 @@ -use crate::world::{Object, Hittable, Intersection}; -use crate::core::{Bound3f, Ray}; - - -pub struct HittableList { - elems: Vec<Object>, -} - -impl HittableList { - pub fn new() -> Self { - Self::default() - } - - pub fn add(&mut self, h: Object) { - self.elems.push(h); - } -} - -impl Hittable for HittableList { - fn intersect(&self, ray: &Ray) -> Option<Intersection> { - let mut min: Option<Intersection> = 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 deleted file mode 100644 index 35d4693..0000000 --- a/src/world/container/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod list; - -pub use list::HittableList; diff --git a/src/world/hittable.rs b/src/world/hittable.rs deleted file mode 100644 index e11a3bc..0000000 --- a/src/world/hittable.rs +++ /dev/null @@ -1,41 +0,0 @@ -use crate::core::{Vector3f, Bound3f, Ray}; -use crate::Float; -use crate::material::Material; - -/// Returns the context of a intersection -pub struct Intersection<'a> { - /// Normal vector at intersection - pub n: Vector3f, - pub p: Vector3f, - pub front: bool, - pub t: Float, - pub m: Option<&'a dyn Material>, -} - -impl<'a> Intersection<'a> { - pub fn new(out_normal: Vector3f, point: Vector3f, ray: &Ray, t: Float) -> Self { - let front = ray.direction.dot(&out_normal) < 0.0; - Intersection { - n: { if front { out_normal } else { -out_normal } }, - front, - p: point, - m: None, - t, - } - } - - pub fn add_material_if_none(&mut self, mat: &'a dyn Material) { - if let None = self.m { - self.m = Some(mat); - } - } -} - -/// Defines a common trait for objects in the scene -pub trait Hittable: Sync + Send { - /// Returns the intersection with ray - fn intersect(&self, ray: &Ray) -> Option<Intersection>; - - /// Returns the axis alligned bounding box containing self - fn bounding_box(&self) -> Bound3f; -} diff --git a/src/world/mod.rs b/src/world/mod.rs deleted file mode 100644 index cba6ddc..0000000 --- a/src/world/mod.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! Manages world objects, and implements intersection -pub mod shapes; - -mod scene; -pub mod container; -mod hittable; -pub use scene::*; -pub use hittable::{Intersection, Hittable}; -pub use shapes::Shape; - -use std::sync::Arc; -use crate::material::Material; -use crate::core::{Bound3f, Ray}; - -pub struct Object { - pub shape: Shape, - pub mat: Arc<dyn Material>, -} - -impl Object { - pub fn new<T: Into<Shape>>(mat: Arc<dyn Material>, shape: T) -> Self { - Object { - mat, - shape: shape.into(), - } - } -} - -impl Hittable for Object { - fn intersect(&self, ray: &Ray) -> Option<Intersection> { - if let Some(mut inter) = self.shape.intersect(ray) { - inter.add_material_if_none(self.mat.as_ref()); - Some(inter) - } else { - None - } - } - - fn bounding_box(&self) -> Bound3f { - self.shape.bounding_box() - } -} diff --git a/src/world/scene.rs b/src/world/scene.rs deleted file mode 100644 index 87bec1f..0000000 --- a/src/world/scene.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::core::{Bound3f, Ray}; - -use super::{Object, container, Hittable, Intersection}; - -type Container = container::HittableList; - -pub struct Scene { - content: Container, -} - -impl Scene { - pub fn new() -> Self { - Self::default() - } - - pub fn add_object(&mut self, obj: Object) { - self.content.add(obj); - } - - pub fn add_objects(&mut self, objs: Vec<Object>) { - for obj in objs { - self.add_object(obj); - } - } -} - -impl Hittable for Scene { - fn intersect(&self, ray: &Ray) -> Option<Intersection> { - self.content.intersect(ray) - } - - fn bounding_box(&self) -> Bound3f { - self.content.bounding_box() - } -} - -impl Default for Scene { - fn default() -> Self { - Self { - content: Container::new(), - } - } -} diff --git a/src/world/shapes/mod.rs b/src/world/shapes/mod.rs deleted file mode 100644 index a11df5d..0000000 --- a/src/world/shapes/mod.rs +++ /dev/null @@ -1,30 +0,0 @@ -mod sphere; - -pub use sphere::Sphere; - -use crate::world::{Hittable, Intersection}; -use crate::core::{Bound3f, Ray}; - -pub enum Shape { - Sphere(Sphere), -} - -impl Hittable for Shape { - fn intersect(&self, ray: &Ray) -> Option<Intersection> { - match self { - Self::Sphere(sph) => sph.intersect(ray) - } - } - - fn bounding_box(&self) -> Bound3f { - match self { - Self::Sphere(sph) => sph.bounding_box() - } - } -} - -impl From<Sphere> for Shape { - fn from(s: Sphere) -> Self { - Self::Sphere(s) - } -} diff --git a/src/world/shapes/sphere.rs b/src/world/shapes/sphere.rs deleted file mode 100644 index 1df9c35..0000000 --- a/src/world/shapes/sphere.rs +++ /dev/null @@ -1,98 +0,0 @@ -//! Implements sphere -//! -//! Spheres are relatively easy to calculate intersections between -use crate::{Float, NEAR_ZERO}; -use crate::core::{Ray, Vector3f, Bound3f}; -use crate::world::{Hittable, Intersection}; - -pub struct Sphere { - radius: Float, - center: Vector3f, -} - -impl Sphere { - pub fn new(radius: Float, center: Vector3f) -> Sphere { - Sphere { - radius, - center, - } - } - - fn norm_at(&self, point: &Vector3f) -> Vector3f { - let mut v = *point - self.center; - v /= self.radius; - v - } -} - -impl Hittable for Sphere { - // Implementation from ray tracing in a weekend - fn intersect(&self, ray: &Ray) -> Option<Intersection> { - let oc = ray.origin - self.center; - let a = ray.direction.len_squared(); - let half_b = oc.dot(&ray.direction); - let c = oc.len_squared() - self.radius * self.radius; - let disc = half_b*half_b - a*c; - - if disc < 0.0 { - None - } else { - let disc_sqrt = disc.sqrt(); - - let mut distance = -half_b - disc_sqrt; - if distance <= NEAR_ZERO { - distance = -half_b + disc_sqrt; - } - if distance <= NEAR_ZERO { - return None; - } - - distance /= a; - let w = ray.at(distance); - Some(Intersection::new( - self.norm_at(&w), - w, - ray, - distance, - )) - } - - } - - /// Box containing the circle - /// - /// # Examples - /// - /// ``` - /// 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(); - /// - /// 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) -> Bound3f { - let offset = Vector3f::new(self.radius); - - Bound3f::new(self.center - offset, self.center + offset) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn sphere_intersect() { - let sph = Sphere::new(2.0, Vector3f::new_xyz(2.0, 3.0, 4.0)); - - let ray = Ray { - origin: Vector3f::new_xyz(1.0, 0.0, 0.0), - direction: Vector3f::new_xyz(0.0, 1.0, 1.5).norm(), - }; - - let dist = sph.intersect(&ray).unwrap(); - assert!((dist.t - 3.28).abs() < 0.01); - } -} |