refactor: use Option to bypass bounding sphere system
This commit is contained in:
parent
878f7c9ebb
commit
f0c8dae74c
5 changed files with 13 additions and 31 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue