refactor: use Option to bypass bounding sphere system

This commit is contained in:
Kiana Sheibani 2024-10-16 15:48:42 -04:00
parent 878f7c9ebb
commit f0c8dae74c
Signed by: toki
GPG key ID: 6CB106C25E86A9F7
5 changed files with 13 additions and 31 deletions

View file

@ -27,12 +27,12 @@ pub trait Surface {
fn get_texture(&self, point: Point3f) -> Texture; fn get_texture(&self, point: Point3f) -> Texture;
// Creates a bounding sphere around the object. // Creates a bounding sphere around the object.
fn bound(&self) -> Bound; fn bound(&self) -> Option<Bound>;
} }
pub struct Object { pub struct Object {
pub surface: Box<dyn Surface>, pub surface: Box<dyn Surface>,
bound: Bound, bound: Option<Bound>,
} }
impl Object { impl Object {
@ -46,7 +46,7 @@ impl Object {
} }
pub fn intersect(&self, ray: Ray) -> Option<f64> { pub fn intersect(&self, ray: Ray) -> Option<f64> {
if self.bound.is_intersected(ray) { if !self.bound.as_ref().is_some_and(|b| !b.is_intersected(ray)) {
self.surface.intersect(ray) self.surface.intersect(ray)
} else { } else {
None None

View file

@ -9,28 +9,13 @@ use crate::util::*;
pub struct Bound { pub struct Bound {
pub center: Point3f, pub center: Point3f,
pub radius: f64, pub radius: f64,
// If true, then the bounding sphere is disabled.
pub bypass: bool,
} }
impl Bound { impl Bound {
pub fn is_intersected(&self, ray: Ray) -> bool { pub fn is_intersected(&self, ray: Ray) -> bool {
if self.bypass {
return true;
}
let l = ray.origin - self.center; let l = ray.origin - self.center;
l.norm_squared() >= self.radius * self.radius l.norm_squared() >= self.radius * self.radius
} }
// pub fn contains(&self, point: &Point3f) -> bool { distance(&self.center, point) < self.radius } // pub fn contains(&self, point: &Point3f) -> bool { distance(&self.center, point) < self.radius }
pub fn bypass() -> Self {
Bound {
center: Point3::origin(),
radius: 0.0,
bypass: true,
}
}
} }

View file

@ -111,9 +111,8 @@ impl Surface for Plane {
(*self.texture)(x, y) (*self.texture)(x, y)
} }
// Planes are infinite, so no finite // Planes are infinite, so no finite bounding sphere could possibly contain one
// bounding sphere could possibly contain one. fn bound(&self) -> Option<Bound> {
fn bound(&self) -> Bound { None
Bound::bypass()
} }
} }

View file

@ -89,11 +89,10 @@ impl Surface for Sphere {
(*self.texture)(x, y) (*self.texture)(x, y)
} }
fn bound(&self) -> Bound { fn bound(&self) -> Option<Bound> {
Bound { Some(Bound {
center: self.center, center: self.center,
radius: self.radius, radius: self.radius,
bypass: false, })
}
} }
} }

View file

@ -212,7 +212,7 @@ impl Surface for TriangleMesh {
} }
// Uses Welzl's algorithm to solve the bounding sphere problem // Uses Welzl's algorithm to solve the bounding sphere problem
fn bound(&self) -> Bound { fn bound(&self) -> Option<Bound> {
fn smallest_sphere_plane(points: Vec<&Point3f>, boundary: Vec<&Point3f>) -> (Point3f, f64) { fn smallest_sphere_plane(points: Vec<&Point3f>, boundary: Vec<&Point3f>) -> (Point3f, f64) {
if points.len() == 0 || boundary.len() == 3 { if points.len() == 0 || boundary.len() == 3 {
match boundary.len() { match boundary.len() {
@ -270,7 +270,7 @@ impl Surface for TriangleMesh {
let a = matrix.determinant() * 2.0; let a = matrix.determinant() * 2.0;
if (a != 0.0) { if a != 0.0 {
let mut matrix_mut = matrix.clone(); let mut matrix_mut = matrix.clone();
let squares = Vector4::new( let squares = Vector4::new(
@ -338,10 +338,9 @@ impl Surface for TriangleMesh {
let (center, radius) = smallest_sphere(points, Vec::new()); let (center, radius) = smallest_sphere(points, Vec::new());
Bound { Some(Bound {
center, center,
radius: radius + 1e-3, radius: radius + 1e-3,
bypass: false, })
}
} }
} }