diff options
Diffstat (limited to 'src/scene/shapes/sphere.rs')
-rw-r--r-- | src/scene/shapes/sphere.rs | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/src/scene/shapes/sphere.rs b/src/scene/shapes/sphere.rs index da7f321..acca2b7 100644 --- a/src/scene/shapes/sphere.rs +++ b/src/scene/shapes/sphere.rs @@ -3,7 +3,7 @@ //! Spheres are relatively easy to calculate intersections between use crate::Float; use crate::core::{Ray, Vector3f}; -use super::Shape; +use crate::scene::{Hittable, Intersection}; pub struct Sphere { radius: Float, @@ -17,11 +17,17 @@ impl Sphere { center, } } + + fn norm_at(&self, point: &Vector3f) -> Vector3f { + let mut v = *point - self.center; + v /= self.radius; + v + } } -impl Shape for Sphere { +impl Hittable for Sphere { // Implementation from ray tracing in a weekend - fn intersect(&self, ray: &Ray) -> Option<Float> { + 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); @@ -29,18 +35,20 @@ impl Shape for Sphere { let disc = half_b*half_b - a*c; if disc < 0.0 { - None + return None } else { - Some( (-half_b - disc.sqrt()) / a) + let distance = (-half_b - disc.sqrt()) / a; + if distance < 0.0 { + return None + } + let w = ray.at(distance); + Some(Intersection { + n: self.norm_at(&w), + p: w, + }) } } - - fn norm_at(&self, point: &Vector3f) -> Vector3f { - let mut v = *point - self.center; - v /= self.radius; - v - } } #[cfg(test)] |