rtiow: add new Scale tranformer.

This commit is contained in:
Bill Thiede 2023-01-18 20:15:06 -08:00
parent 3e9d900f1e
commit b9ebc186fa
4 changed files with 69 additions and 16 deletions

View File

@ -17,6 +17,7 @@ pub mod ray;
pub mod rect;
pub mod renderer;
pub mod rotate;
pub mod scale;
pub mod scenes;
pub mod sphere;
pub mod texture;

View File

@ -0,0 +1,53 @@
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
}
}

View File

@ -9,9 +9,9 @@ use crate::{
material::{DiffuseLight, Lambertian, Metal},
rect::{XYRect, XZRect},
renderer::{Opt, Scene},
scale::Scale,
sphere::Sphere,
texture::ConstantTexture,
translate::Translate,
triangles::Triangles,
vec3::Vec3,
};
@ -48,7 +48,7 @@ pub fn new(opt: &Opt) -> Scene {
let light_size = 50.;
let light_height = 200.;
let objects: Vec<Box<dyn Hit>> = vec![
// Light from above
// Light from above - white
Box::new(XZRect::new(
-light_size,
light_size,
@ -57,7 +57,7 @@ pub fn new(opt: &Opt) -> Scene {
light_height,
DiffuseLight::new(ConstantTexture::new(Vec3::new(15., 15., 15.))),
)),
// Light from back
// Light from back - green
Box::new(XYRect::new(
-light_size,
light_size,
@ -66,7 +66,7 @@ pub fn new(opt: &Opt) -> Scene {
-light_height,
DiffuseLight::new(ConstantTexture::new(Vec3::new(1., 15., 1.))),
)),
// Light from front
// Light from front - blue
Box::new(XYRect::new(
-light_size,
light_size,
@ -81,26 +81,33 @@ pub fn new(opt: &Opt) -> Scene {
1000.,
Lambertian::new(ground_color),
)),
/*
// Blue sphere
Box::new(Sphere::new(
Vec3::new(-40., 20., 0.),
20.,
Lambertian::new(ConstantTexture::new(Vec3::new(0.1, 0.2, 0.5))),
)),
*/
// Shiny sphere
Box::new(Sphere::new(
Vec3::new(40., 20., 0.),
Vec3::new(40., 20., -40.),
20.,
Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
)),
Box::new(Sphere::new(
Vec3::new(-40., 20., 40.),
20.,
Metal::new(Vec3::new(0.8, 0.8, 0.8), 0.2),
)),
// STL Mesh
Box::new(Translate::new(
Box::new(Scale::new(
Triangles::new(
&stl_cube,
Lambertian::new(ConstantTexture::new(Vec3::new(1., 1.0, 1.0))),
Lambertian::new(ConstantTexture::new(Vec3::new(0.6, 0.6, 0.6))),
1.,
),
[-10., 0., 0.],
0.5,
)),
];
let world: Box<dyn Hit> = if opt.use_accel {

View File

@ -39,14 +39,6 @@ where
let v0 = t.verts[0] * scale_factor;
let v1 = t.verts[1] * scale_factor;
let v2 = t.verts[2] * scale_factor;
assert_eq!(
t.normal,
cross(v1 - v0, v2 - v0).unit_vector(),
"v1 {} v2 {} v3 {}",
v0,
v1,
v2
);
Triangle {
normal: t.normal,
verts: [v0, v1, v2],