diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/ray.rs | 5 | ||||
-rw-r--r-- | src/core/spectrum.rs | 1 | ||||
-rw-r--r-- | src/world/hittable.rs | 22 | ||||
-rw-r--r-- | src/world/mod.rs | 7 | ||||
-rw-r--r-- | src/world/shapes/sphere.rs | 12 |
5 files changed, 34 insertions, 13 deletions
diff --git a/src/core/ray.rs b/src/core/ray.rs index 0517e50..19d3cf1 100644 --- a/src/core/ray.rs +++ b/src/core/ray.rs @@ -2,8 +2,12 @@ use crate::core::Vector3f; use crate::Float; +/// A ray that is sent into the world. +/// This is the main type used for testing intersections. pub struct Ray { + /// Origin of the ray pub origin: Vector3f, + /// Direction is assumed to be a unit vector. pub direction: Vector3f, } @@ -23,6 +27,7 @@ impl Ray { } } + /// Resolve a point on the ray at time t pub fn at(&self, t: Float) -> Vector3f { self.origin + self.direction * t } diff --git a/src/core/spectrum.rs b/src/core/spectrum.rs index bea056e..ed3505b 100644 --- a/src/core/spectrum.rs +++ b/src/core/spectrum.rs @@ -12,6 +12,7 @@ pub struct Spectrum { impl Spectrum { pub const ZERO: Self = Spectrum { c: [0.0; 3] }; + pub const WHITE: Self = Spectrum { c: [1.0; 3] }; pub fn new_rgb(r: Float, g: Float, b: Float) -> Spectrum { Spectrum { c: [r, g, b] } diff --git a/src/world/hittable.rs b/src/world/hittable.rs index c5a353e..e11a3bc 100644 --- a/src/world/hittable.rs +++ b/src/world/hittable.rs @@ -7,16 +7,26 @@ pub struct Intersection<'a> { /// Normal vector at intersection pub n: Vector3f, pub p: Vector3f, + pub front: bool, pub t: Float, pub m: Option<&'a dyn Material>, } -impl Intersection<'_> { - pub fn norm_against_ray(&self, r: &Ray) -> Vector3f { - if self.n.dot(&r.direction) < 0.0 { - self.n - } else { - -self.n +impl<'a> Intersection<'a> { + pub fn new(out_normal: Vector3f, point: Vector3f, ray: &Ray, t: Float) -> Self { + let front = ray.direction.dot(&out_normal) < 0.0; + Intersection { + n: { if front { out_normal } else { -out_normal } }, + front, + p: point, + m: None, + t, + } + } + + pub fn add_material_if_none(&mut self, mat: &'a dyn Material) { + if let None = self.m { + self.m = Some(mat); } } } diff --git a/src/world/mod.rs b/src/world/mod.rs index 53d8ad3..3a09522 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -27,7 +27,12 @@ impl Object { impl Hittable for Object { fn intersect(&self, ray: &Ray) -> Option<Intersection> { - self.shape.intersect(ray).map(|mut i| {i.m = Some(self.mat.as_ref()); i}) + if let Some(mut inter) = self.shape.intersect(ray) { + inter.add_material_if_none(self.mat.as_ref()); + Some(inter) + } else { + None + } } fn bounding_box(&self) -> Bound3f { diff --git a/src/world/shapes/sphere.rs b/src/world/shapes/sphere.rs index e3348de..9ecedd6 100644 --- a/src/world/shapes/sphere.rs +++ b/src/world/shapes/sphere.rs @@ -42,12 +42,12 @@ impl Hittable for Sphere { return None } let w = ray.at(distance); - Some(Intersection { - n: self.norm_at(&w), - p: w, - t: distance, - m: None, - }) + Some(Intersection::new( + self.norm_at(&w), + w, + ray, + distance, + )) } } |