diff --git a/rtchallenge/src/intersections.rs b/rtchallenge/src/intersections.rs index 19dba3c..71ff327 100644 --- a/rtchallenge/src/intersections.rs +++ b/rtchallenge/src/intersections.rs @@ -1,6 +1,6 @@ use std::ops::Index; -use crate::spheres::Sphere; +use crate::{rays::Ray, spheres::Sphere, tuples::Tuple}; #[derive(Debug, Clone, PartialEq)] pub struct Intersection<'i> { @@ -129,3 +129,43 @@ impl<'i> Index for Intersections<'i> { &self.0[idx] } } + +pub struct PrecomputedData<'i> { + pub t: f32, + pub object: &'i Sphere, + pub point: Tuple, + pub eyev: Tuple, + pub normalv: Tuple, +} + +/// Precomputes data common to all intersections. +/// +/// # Examples +/// ``` +/// use rtchallenge::{ +/// intersections::{prepare_computations, Intersection, Intersections}, +/// rays::Ray, +/// spheres::{intersect, Sphere}, +/// tuples::Tuple, +/// }; +/// +/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.)); +/// let shape = Sphere::default(); +/// let i = Intersection::new(4., &shape); +/// let comps = prepare_computations(&i, &r); +/// assert_eq!(comps.t, i.t); +/// assert_eq!(comps.object, i.object); +/// assert_eq!(comps.point, Tuple::point(0., 0., -1.)); +/// assert_eq!(comps.eyev, Tuple::vector(0., 0., -1.)); +/// assert_eq!(comps.normalv, Tuple::vector(0., 0., -1.)); +/// ``` +pub fn prepare_computations<'i>(i: &'i Intersection, r: &Ray) -> PrecomputedData<'i> { + let point = r.position(i.t); + PrecomputedData { + t: i.t, + object: i.object, + point, + eyev: -r.direction, + normalv: i.object.normal_at(point), + } +}