From 09047eb7139f80fdadb7367ff91b15301ac478f5 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sun, 18 Jul 2021 12:54:18 -0700 Subject: [PATCH] world: implement World::is_shadowed. --- rtchallenge/src/world.rs | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/rtchallenge/src/world.rs b/rtchallenge/src/world.rs index 121e737..b69e3f4 100644 --- a/rtchallenge/src/world.rs +++ b/rtchallenge/src/world.rs @@ -177,4 +177,48 @@ impl World { None => BLACK, } } + + /// Determine if point in world is in a shadow. + /// + /// # Examples + /// ``` + /// use rtchallenge::{ + /// tuples::{ Tuple}, + /// world::World, + /// }; + /// + /// let w = World::test_world(); + /// + /// // There is no shadow when nothing is collinear with point and light. + /// let p = Tuple::point(0.,10.,0.); + /// assert_eq!(w.is_shadowed(p), false); + /// + /// // There shadow when an object is between the point and the light. + /// let p = Tuple::point(10.,-10.,10.); + /// assert_eq!(w.is_shadowed(p), true); + /// + /// // There is no shadow when an object is behind the light. + /// let p = Tuple::point(-20.,20.,-20.); + /// assert_eq!(w.is_shadowed(p), false); + /// + /// // There is no shadow when an object is behind the point. + /// let p = Tuple::point(-2.,2.,-2.); + /// assert_eq!(w.is_shadowed(p), false); + pub fn is_shadowed(&self, point: Tuple) -> bool { + // TODO(wathiede): how to make this multi light aware? + let light = self + .light + .as_ref() + .expect("cannot compute is_shadowed in world with no light"); + let v = light.position - point; + let distance = v.magnitude(); + let direction = v.normalize(); + + let r = Ray::new(point, direction); + let intersections = self.intersect(&r); + if let Some(h) = intersections.hit() { + return h.t < distance; + } + false + } }