54 lines
1.0 KiB
Rust

use crate::{
aabb::AABB,
hitable::{Hit, HitRecord},
ray::Ray,
vec3::Vec3,
};
#[derive(Debug)]
pub struct Scale<H>
where
H: Hit,
{
hitable: H,
scale: Vec3,
}
impl<H> Scale<H>
where
H: Hit,
{
pub fn new<V>(hitable: H, scale: V) -> Scale<H>
where
V: Into<Vec3>,
{
Scale {
hitable,
scale: scale.into(),
}
}
}
impl<H> Hit for Scale<H>
where
H: Hit,
{
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
let moved_r = Ray::new(r.origin / self.scale, r.direction, r.time);
if let Some(rec) = self.hitable.hit(moved_r, t_min, t_max) {
return Some(HitRecord {
p: rec.p * self.scale,
..rec
});
}
None
}
fn bounding_box(&self, t_min: f32, t_max: f32) -> Option<AABB> {
if let Some(bbox) = self.hitable.bounding_box(t_min, t_max) {
return Some(AABB::new(bbox.min() * self.scale, bbox.max() * self.scale));
}
None
}
}