summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRosyid Haryadi <rosyid_haryadi@protonmail.com>2025-03-01 19:19:25 +0700
committerRosyid Haryadi <rosyid_haryadi@protonmail.com>2025-03-01 19:19:25 +0700
commit006c0c1f7d622bb2eabbf8b2445cd48d2c493d3b (patch)
treee5bcba34bc50a1f145f3fb2b814e4083748001bd
parent5e61a588a59008705846326956ff0b1f8ee43b16 (diff)
upd interval struct
-rw-r--r--src/interval.rs41
-rw-r--r--src/main.rs1
-rw-r--r--src/object.rs16
-rw-r--r--src/renderer.rs4
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,