diff --git a/output.png b/output.png index 8cca54b..67486f6 100644 Binary files a/output.png and b/output.png differ diff --git a/src/main.rs b/src/main.rs index 713cd85..fd03b8c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,26 +9,14 @@ use std::cmp::max; use crate::objects::hit::Hit; use crate::objects::sphere::Sphere; -use crate::objects::traits::{Hittable, Normal}; +use crate::objects::traits::Hittable; use crate::ray::Ray; use crate::vec3::{Colour, Vec3}; use log::info; use pretty_env_logger; -fn ray_colour(hittables: &Vec, r: &Ray) -> Colour -where - T: Hittable + Normal, -{ - let mut closest: Option = None; - for hittable in hittables { - if let Some(hit) = hittable.hit(r) { - // hit happens in front of camera and is closer than closest - if *hit.t() > 0. && (closest.is_none() || closest.as_ref().unwrap().t() > hit.t()) { - closest = Some(hit); - } - } - } - +fn ray_colour(hittables: &Vec, r: &Ray) -> Colour { + let closest = Hit::hit_list(hittables, r); if let Some(hit) = closest { let n = hit.n(); return 0.5 * Colour::new(n.x() + 1., n.y() + 1., n.z() + 1.); @@ -42,12 +30,13 @@ where } fn main() { - // use structs so rust-analyzer can provide lsp - let s = Sphere::new(Vec3::new(0., 0., -1.), 0.5); - let objects = vec![s]; - pretty_env_logger::init(); + // setup objects + let mut objects = vec![Sphere::new(Vec3::new(0., 0., -1.), 0.5)]; + objects.push(Sphere::new(Vec3::new(0., 0., -0.1), 0.01)); + objects.push(Sphere::new(Vec3::new(0., -100.5, -1.), 100.)); + let aspect_ratio = 16. / 9.; let image_width = 400; let image_height = max(1, (image_width as f32 / aspect_ratio) as u32); diff --git a/src/objects/hit.rs b/src/objects/hit.rs index e801ec7..e1514d2 100644 --- a/src/objects/hit.rs +++ b/src/objects/hit.rs @@ -1,4 +1,4 @@ -use crate::vec3::Vec3; +use crate::{objects::traits::Hittable, ray::Ray, vec3::Vec3}; pub struct Hit { t: f32, @@ -22,4 +22,17 @@ impl Hit { pub fn n(&self) -> &Vec3 { &self.n } + + pub fn hit_list(hittables: &Vec, r: &Ray) -> Option { + let mut closest: Option = None; + for hittable in hittables { + if let Some(hit) = hittable.hit(r) { + // hit happens in front of camera and is closer than closest + if *hit.t() > 0. && (closest.is_none() || closest.as_ref().unwrap().t() > hit.t()) { + closest = Some(hit); + } + } + } + return closest; + } } diff --git a/src/objects/sphere.rs b/src/objects/sphere.rs index 4f36ee1..ab52fb9 100644 --- a/src/objects/sphere.rs +++ b/src/objects/sphere.rs @@ -1,7 +1,7 @@ use core::f32::math::sqrt; use crate::objects::hit::Hit; -use crate::objects::traits::{Hittable, Normal}; +use crate::objects::traits::Hittable; use crate::Vec3; pub struct Sphere { @@ -34,9 +34,7 @@ impl Hittable for Sphere { Some(Hit::new(t, p, self.normal_at(&p))) } } -} -impl Normal for Sphere { fn normal_at(&self, p: &Vec3) -> Vec3 { (*p - self.center).get_unit() } diff --git a/src/objects/traits.rs b/src/objects/traits.rs index 48d571e..8e82d6a 100644 --- a/src/objects/traits.rs +++ b/src/objects/traits.rs @@ -4,8 +4,5 @@ use crate::Vec3; pub trait Hittable { fn hit(&self, r: &Ray) -> Option; -} - -pub trait Normal { fn normal_at(&self, p: &Vec3) -> Vec3; }