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

View File

@ -39,14 +39,6 @@ where
let v0 = t.verts[0] * scale_factor; let v0 = t.verts[0] * scale_factor;
let v1 = t.verts[1] * scale_factor; let v1 = t.verts[1] * scale_factor;
let v2 = t.verts[2] * 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 { Triangle {
normal: t.normal, normal: t.normal,
verts: [v0, v1, v2], verts: [v0, v1, v2],