44 lines
990 B
Rust
44 lines
990 B
Rust
use crate::{
|
|
ray::Ray,
|
|
vec::{Point3, Vec3},
|
|
};
|
|
|
|
pub struct HitRecord {
|
|
pub p: Point3,
|
|
pub normal: Vec3,
|
|
pub t: f64,
|
|
pub front_face: bool,
|
|
}
|
|
impl HitRecord {
|
|
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 {
|
|
(-1.0) * outward_normal
|
|
};
|
|
}
|
|
}
|
|
|
|
pub trait Hit {
|
|
fn hit(&self, r: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord>;
|
|
}
|
|
|
|
pub type World = Vec<Box<dyn Hit>>;
|
|
|
|
impl Hit for World {
|
|
fn hit(&self, r: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
|
|
let mut tmp_rec = None;
|
|
let mut closest_so_far = t_max;
|
|
|
|
for object in self {
|
|
if let Some(rec) = object.hit(r, t_min, closest_so_far) {
|
|
closest_so_far = rec.t;
|
|
tmp_rec = Some(rec);
|
|
}
|
|
}
|
|
|
|
tmp_rec
|
|
}
|
|
}
|