diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/bound2.rs (renamed from src/core/bound.rs) | 17 | ||||
-rw-r--r-- | src/core/bound3.rs | 69 | ||||
-rw-r--r-- | src/core/hittable.rs | 25 | ||||
-rw-r--r-- | src/core/mod.rs | 31 | ||||
-rw-r--r-- | src/core/vector3.rs | 16 |
5 files changed, 110 insertions, 48 deletions
diff --git a/src/core/bound.rs b/src/core/bound2.rs index 37918d4..bc0e7cd 100644 --- a/src/core/bound.rs +++ b/src/core/bound2.rs @@ -1,7 +1,8 @@ -//! Implements a 2d region +//! Implements a 2d axis aligned bounding box use crate::{Number, Float}; use super::vector2::Vector2; use crate::core; +use crate::core::{min, max}; /// Implements a region between min and max #[derive(Clone)] @@ -13,20 +14,6 @@ pub struct Bound2<T: Number> { pub type Bound2i = Bound2<i32>; pub type Bound2f = Bound2<Float>; -fn min<T: Number> (a: T, b: T) -> T { - if b < a { - return b; - } - a -} - -fn max<T: Number> (a: T, b: T) -> T { - if b > a { - return b; - } - a -} - impl<T: Number> Bound2<T> { /// Creates a new bound from two points /// diff --git a/src/core/bound3.rs b/src/core/bound3.rs new file mode 100644 index 0000000..7f54e03 --- /dev/null +++ b/src/core/bound3.rs @@ -0,0 +1,69 @@ +//! Implements 3d axis aligned bounding box +use crate::{Number, Float}; +use super::vector3::Vector3; +use crate::core::{min, max}; +use crate::core::Ray; + +#[derive(Clone)] +pub struct Bound3<T: Number> { + pub min: Vector3<T>, + pub max: Vector3<T> +} + +pub type Bound3f = Bound3<Float>; + +impl<T: Number> Bound3<T> { + /// Creates a bound from two points + pub fn new(p0: Vector3<T>, p1: Vector3<T>) -> Self { + // Elliminate some code duplication here + let min = Vector3::new_xyz( + min(p0.x, p1.x), + min(p0.y, p1.y), + min(p0.z, p1.z) + ); + let max = Vector3::new_xyz( + max(p0.x, p1.x), + max(p0.y, p1.y), + max(p0.z, p1.z) + ); + + Self {min, max} + } +} + +impl Bound3f { + /// Calculate whether there is a intersect between a bounding box and a ray + /// + /// # Examples: + /// + /// ``` + /// use rendering::core::{Bound3f, Vector3f, Ray}; + /// let b = Bound3f::new(Vector3f::new(7.0), Vector3f::new(10.0)); + /// let r1 = Ray::new_to(Vector3f::new(0.0), Vector3f::new(5.0)); + /// let r3 = Ray::new(Vector3f::new_xyz(-1.0, 0.0, 0.0), Vector3f::new_xyz(1.0, 0.0, 0.0)); + /// + /// assert!(b.intersect(&r1)); + /// assert!(!b.intersect(&r3)); + /// ``` + pub fn intersect(&self, ray: &Ray) -> bool { + // Method stolen from Ray tracing the next week. + // They mention its from pixar + for i in 0..3 { + let inv = 1.0 / ray.direction[i]; + let mut t0 = (self.min[i] - ray.origin[i]) * inv; + let mut t1 = (self.max[i] - ray.origin[i]) * inv; + + if inv < 0.0 { + let tmp = t0; + t0 = t1; + t1 = tmp; + } + + if t1 <= t0 { + return false; + } + } + + return true; + } +} diff --git a/src/core/hittable.rs b/src/core/hittable.rs deleted file mode 100644 index e495d5b..0000000 --- a/src/core/hittable.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::core::{Vector3f, Ray}; -use crate::Float; - -/// Returns the context of a intersection -pub struct Intersection { - /// Normal vector at intersection - pub n: Vector3f, - pub p: Vector3f, - pub t: Float, -} - -impl Intersection { - pub fn norm_against_ray(&self, r: &Ray) -> Vector3f { - if self.n.dot(&r.direction) < 0.0 { - self.n - } else { - -self.n - } - } -} - -/// Defines a common trait for objects in the scene -pub trait Hittable { - fn intersect(&self, ray: &Ray) -> Option<Intersection>; -} diff --git a/src/core/mod.rs b/src/core/mod.rs index c2b3771..07793ec 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -2,16 +2,33 @@ //! //! Also creates a shortcut for some common types -pub mod vector2; -pub mod vector3; -pub mod bound; -pub mod spectrum; -pub mod hittable; +mod vector2; +mod vector3; +mod bound2; +mod bound3; +mod spectrum; mod ray; pub use vector2::{Vector2i, Vector2f}; pub use vector3::Vector3f; -pub use bound::{Bound2i, Bound2f}; +pub use bound2::{Bound2i, Bound2f}; +pub use bound3::Bound3f; pub use spectrum::Spectrum; pub use ray::Ray; -pub use hittable::{Hittable, Intersection}; + +use crate::Number; + +fn min<T: Number> (a: T, b: T) -> T { + if b < a { + return b; + } + a +} + +fn max<T: Number> (a: T, b: T) -> T { + if b > a { + return b; + } + a +} + diff --git a/src/core/vector3.rs b/src/core/vector3.rs index e26c07c..1cc6f60 100644 --- a/src/core/vector3.rs +++ b/src/core/vector3.rs @@ -2,7 +2,7 @@ //! //! Also add more 3d math things needed for shading and 3d calculations. use crate::{Float, Number, NEAR_ZERO}; -use std::ops::{Mul, Sub, Add, DivAssign, Neg, AddAssign}; +use std::ops::{Mul, Sub, Add, DivAssign, Neg, AddAssign, Index}; use std::fmt; #[derive(Clone, Copy)] @@ -107,6 +107,20 @@ impl<T: Number> fmt::Display for Vector3<T> { } } +// Ohh god +impl<T: Number> Index<u32> for Vector3<T> { + type Output = T; + + fn index(&self, i: u32) -> &Self::Output { + match i { + 0 => &self.x, + 1 => &self.y, + 2 => &self.z, + _ => panic!("index out of bounds: index {} is not possible with 3d vector", i) + } + } +} + impl Vector3f { pub const ZERO: Self = Vector3f {x: 0.0, y: 0.0, z: 0.0}; |