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/core/bound3.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) (limited to 'src/core') diff --git a/src/core/bound3.rs b/src/core/bound3.rs index 7f54e03..ce6bb09 100644 --- a/src/core/bound3.rs +++ b/src/core/bound3.rs @@ -1,6 +1,6 @@ //! Implements 3d axis aligned bounding box use crate::{Number, Float}; -use super::vector3::Vector3; +use super::vector3::{Vector3, Vector3f}; use crate::core::{min, max}; use crate::core::Ray; @@ -29,23 +29,64 @@ impl Bound3 { Self {min, max} } + + pub fn combine(&self, op: &Self) -> Self { + let min = Vector3::new_xyz( + min(self.min.x, op.min.x), + min(self.min.y, op.min.y), + min(self.min.z, op.min.z) + ); + let max = Vector3::new_xyz( + max(self.max.x, op.max.x), + max(self.max.y, op.max.y), + max(self.max.z, op.max.z) + ); + + Self {min, max} + } + + pub fn and(&self, op: &Self) -> Self { + let min_b = Vector3::new_xyz( + max(self.min.x, op.min.x), + max(self.min.y, op.min.y), + max(self.min.z, op.min.z) + ); + let max_b = Vector3::new_xyz( + min(self.max.x, op.max.x), + min(self.max.y, op.max.y), + min(self.max.z, op.max.z) + ); + + Self {min: min_b, max: max_b} + } + + pub fn area(&self) -> T { + let diag = self.max - self.min; + diag.x * diag.y * diag.z + } } impl Bound3f { + pub const EMPTY: Bound3f = Bound3f{min: Vector3f::ZERO, max: Vector3f::ZERO}; + /// Calculate whether there is a intersect between a bounding box and a ray /// /// # Examples: /// /// ``` /// use rendering::core::{Bound3f, Vector3f, Ray}; + /// use rendering::INFTY; /// 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 r2 = 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)); + /// assert!(b.intersect(&r1, 0.0, INFTY)); + /// assert!(!b.intersect(&r2, 0.0, INFTY)); + /// assert!(!b.intersect(&r3, 0.0, INFTY)); /// ``` - pub fn intersect(&self, ray: &Ray) -> bool { + pub fn intersect(&self, ray: &Ray, t_min: Float, t_max: Float) -> bool { + println!("BIN: {} -> {}", self.min, self.max); // Method stolen from Ray tracing the next week. // They mention its from pixar for i in 0..3 { @@ -59,7 +100,10 @@ impl Bound3f { t1 = tmp; } - if t1 <= t0 { + let t_min = max(t0, t_min); + let t_max = min(t1, t_max); + + if t_max <= t_min { return false; } } -- cgit v1.2.3