diff options
author | Rosyid Haryadi <rosyid_haryadi@protonmail.com> | 2025-03-01 19:19:25 +0700 |
---|---|---|
committer | Rosyid Haryadi <rosyid_haryadi@protonmail.com> | 2025-03-01 19:19:25 +0700 |
commit | 006c0c1f7d622bb2eabbf8b2445cd48d2c493d3b (patch) | |
tree | e5bcba34bc50a1f145f3fb2b814e4083748001bd | |
parent | 5e61a588a59008705846326956ff0b1f8ee43b16 (diff) |
upd interval struct
-rw-r--r-- | src/interval.rs | 41 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/object.rs | 16 | ||||
-rw-r--r-- | src/renderer.rs | 4 |
4 files changed, 54 insertions, 8 deletions
diff --git a/src/interval.rs b/src/interval.rs new file mode 100644 index 0000000..24b1841 --- /dev/null +++ b/src/interval.rs @@ -0,0 +1,41 @@ +pub struct Interval { + pub min: f32, + pub max: f32, +} + +impl Interval { + pub fn new(min: f32, max: f32) -> Self { + Self { min, max } + } + + pub fn size(&self) -> f32 { + self.max - self.min + } + + pub fn contains(&self, x: f32) -> bool { + self.min <= x && x <= self.max + } + + pub fn surrounds(&self, x: f32) -> bool { + self.min < x && x < self.max + } +} + +impl Default for Interval { + fn default() -> Self { + Self { + min: f32::NEG_INFINITY, + max: f32::INFINITY + } + } +} + +pub const INTERVAL_EMPTY: Interval = Interval { + min: f32::INFINITY, + max: f32::NEG_INFINITY +}; + +pub const INTERVAL_UNIVERSE: Interval = Interval { + min: f32::NEG_INFINITY, + max: f32::INFINITY +}; diff --git a/src/main.rs b/src/main.rs index db7d2ee..3f3b866 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ mod global; mod calculus; mod renderer; mod object; +mod interval; use crate::global::*; use crate::renderer::render; diff --git a/src/object.rs b/src/object.rs index 0da9148..c1bce61 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,4 +1,5 @@ use crate::calculus::calculus::{Point3, Ray, Vec3}; +use crate::interval::Interval; #[derive(Clone)] pub struct HitRecord { @@ -27,7 +28,7 @@ impl HitRecord { } pub trait Hittable { - fn hit(&self, r: &Ray, ray_tmin: f32, ray_tmax: f32, rec: &mut HitRecord) -> bool; + fn hit(&self, r: &Ray, ray_t: Interval, rec: &mut HitRecord) -> bool; } pub struct Sphere { @@ -43,7 +44,7 @@ impl Sphere { } impl Hittable for Sphere { - fn hit(&self, r: &Ray, ray_tmin: f32, ray_tmax: f32, rec: &mut HitRecord) -> bool { + fn hit(&self, r: &Ray, ray_t: Interval, rec: &mut HitRecord) -> bool { let oc = self.center.sub(&r.origin); let a = r.direction.mag_sqr(); let h = r.direction.dot_prod(&oc); @@ -56,9 +57,9 @@ impl Hittable for Sphere { let sqrtd = discriminant.sqrt(); let mut root = (h - sqrtd) / a; - if root <= ray_tmin || ray_tmax <= root { + if root <= ray_t.min || ray_t.max <= root { root = (h + sqrtd) / a; - if root <= ray_tmin || ray_tmax <= root { + if root <= ray_t.min || ray_t.max <= root { return false; } } @@ -89,14 +90,15 @@ impl HittableList { } impl Hittable for HittableList { - fn hit(&self, r: &Ray, ray_tmin: f32, ray_tmax: f32, rec: &mut HitRecord) -> bool { + fn hit(&self, r: &Ray, ray_t: Interval, rec: &mut HitRecord) -> bool { let mut temp_rec = HitRecord::default(); let mut hit_anything = false; - let mut closest_so_far = ray_tmax; + let mut closest_so_far = ray_t.max; self.objects.iter().for_each( |object| { - if object.hit(r, ray_tmin, closest_so_far, &mut temp_rec) { + let interval = Interval::new(ray_t.min, closest_so_far); + if object.hit(r, interval, &mut temp_rec) { hit_anything = true; closest_so_far = temp_rec.t; *rec = temp_rec.clone(); diff --git a/src/renderer.rs b/src/renderer.rs index 4936d9e..72ecf4e 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -1,10 +1,12 @@ use crate::calculus::calculus::{Point3, Ray, Vec3}; use crate::global::{Color, DisplayBuffer, Pixel, CAMERA_CENTER, FOCAL_LENGTH, IMG_HEIGHT, IMG_WIDTH, VIEWPORT_HEIGHT, VIEWPORT_WIDTH}; +use crate::interval::Interval; use crate::object::{HitRecord, Hittable, HittableList, Sphere}; fn ray_color(ray: &Ray, world: &HittableList) -> Color { let mut rec = HitRecord::default(); - if world.hit(ray, 0.0, f32::INFINITY, &mut rec) { + let ray_t = Interval::new(0.0, f32::INFINITY); + if world.hit(ray, ray_t, &mut rec) { let color = Color::new(1.0, 1.0, 1.0) .add(&Color::new( rec.normal.x, |