55 lines
1.1 KiB
Rust
55 lines
1.1 KiB
Rust
use crate::aabb::AABB;
|
|
use crate::hitable::Hit;
|
|
use crate::hitable::HitRecord;
|
|
use crate::ray::Ray;
|
|
use crate::vec3::Vec3;
|
|
|
|
pub struct Translate<H>
|
|
where
|
|
H: Hit,
|
|
{
|
|
hitable: H,
|
|
offset: Vec3,
|
|
}
|
|
|
|
impl<H> Translate<H>
|
|
where
|
|
H: Hit,
|
|
{
|
|
pub fn new<V>(hitable: H, offset: V) -> Translate<H>
|
|
where
|
|
V: Into<Vec3>,
|
|
{
|
|
Translate {
|
|
hitable,
|
|
offset: offset.into(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<H> Hit for Translate<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.offset, r.direction, r.time);
|
|
if let Some(rec) = self.hitable.hit(moved_r, t_min, t_max) {
|
|
return Some(HitRecord {
|
|
p: rec.p + self.offset,
|
|
..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.offset,
|
|
bbox.max() + self.offset,
|
|
));
|
|
}
|
|
None
|
|
}
|
|
}
|