From a9badcdeddc52a4bff5346ad206ab1badcc3b55d Mon Sep 17 00:00:00 2001 From: plexx Date: Sun, 29 Jan 2023 15:02:32 +0100 Subject: [PATCH] latest changes --- src/hittable.rs | 29 +++++++++++++++++++++++++++++ src/hittable_list.rs | 29 +++++++++++++++++++++++++++++ src/main.rs | 5 ++++- src/sphere.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 src/hittable.rs create mode 100644 src/hittable_list.rs create mode 100644 src/sphere.rs diff --git a/src/hittable.rs b/src/hittable.rs new file mode 100644 index 0000000..3d5e3bf --- /dev/null +++ b/src/hittable.rs @@ -0,0 +1,29 @@ +use crate::ray::*; +use crate::vec3::*; + +#[derive(Clone)] +pub struct HitRecord { + pub p: Point3, + pub normal: Vec3, + pub t: f64, + pub front_face: bool, +} + +impl HitRecord { + pub fn new_empty() -> Self { + HitRecord { p: Point3::new(0.0, 0.0, 0.0), normal: Vec3::new(0.0, 0.0, 0.0), t: 0.0, front_face: false } + } + + pub fn set_face_normal(&mut self, r: &Ray, outward_normal: &Vec3) { + self.front_face = r.direction().dot(outward_normal) < 0.0; + self.normal = if self.front_face { + *outward_normal + } else { + *outward_normal * -1.0 + } + } +} + +pub trait Hittable { + fn hit(&self, r: &Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool; +} \ No newline at end of file diff --git a/src/hittable_list.rs b/src/hittable_list.rs new file mode 100644 index 0000000..4cf585e --- /dev/null +++ b/src/hittable_list.rs @@ -0,0 +1,29 @@ +use crate::hittable::*; + +struct HittableList { + pub objects: Vec> +} + +impl HittableList { + pub fn add(&mut self, object: Box) { + self.objects.push(object); + } + + pub fn clear(&mut self) { + self.objects.clear(); + } +} + +impl Hittable for HittableList { + fn hit(&self, r: &crate::ray::Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool { + let mut temp_rec = HitRecord::new_empty(); + let mut hit_anything = false; + let mut closest_so_far = t_max; + + for object in &self.objects { + + } + + hit_anything + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d605127..ed565c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,15 @@ pub mod vec3; pub mod color; pub mod ray; +pub mod sphere; +pub mod hittable; +pub mod hittable_list; use std::{io::{BufWriter, Write}, fs::File}; use crate::{ vec3::*, color::*, - ray::* + ray::*, }; fn hit_sphere(center: &Point3, radius: f64, r: &Ray) -> f64 { diff --git a/src/sphere.rs b/src/sphere.rs new file mode 100644 index 0000000..0ffb2be --- /dev/null +++ b/src/sphere.rs @@ -0,0 +1,42 @@ +use crate::hittable::*; +use crate::vec3::*; + +struct Sphere { + center: Point3, + radius: f64 +} + +impl Sphere { + pub fn new(center: Point3, radius: f64) -> Self { + Sphere {center, radius} + } +} + +impl Hittable for Sphere { + fn hit(&self, r: &crate::ray::Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool { + let oc = r.origin() - self.center; + let a = r.direction().length_squared(); + let half_b = oc.dot(&r.direction()); + let c = oc.length_squared() - self.radius*self.radius; + + let discriminant = half_b*half_b - a*c; + if discriminant < 0.0 { return false; } + let sqrtd = discriminant.sqrt(); + + // Find the nearest root that lies in the acceptable range + let mut root = (-half_b - sqrtd) / a; + if root < t_min || t_max < root { + root = (-half_b + sqrtd) / a; + if root < t_min || t_max < root { + return false; + } + } + + rec.t = root; + rec.p = r.at(rec.t); + let outward_normal = (rec.p - self.center) / self.radius; + rec.set_face_normal(r, &outward_normal); + + return true; + } +} \ No newline at end of file