diff --git a/rtiow/src/bvh.rs b/rtiow/src/bvh.rs index fcf8898..12d4a6e 100644 --- a/rtiow/src/bvh.rs +++ b/rtiow/src/bvh.rs @@ -12,7 +12,7 @@ use crate::hitable::HitRecord; use crate::ray::Ray; enum BVHNode { - Leaf(Box), + Leaf(Box), Branch { left: Box, right: Box, @@ -43,7 +43,7 @@ impl fmt::Display for BVHNode { // Lint is wrong when dealing with Box #[allow(clippy::borrowed_box)] -fn box_x_compare(ah: &Box, bh: &Box) -> std::cmp::Ordering { +fn box_x_compare(ah: &Box, bh: &Box) -> std::cmp::Ordering { match (ah.bounding_box(0., 0.), bh.bounding_box(0., 0.)) { (Some(box_left), Some(box_right)) => { box_left.min().x.partial_cmp(&box_right.min().x).unwrap() @@ -53,7 +53,7 @@ fn box_x_compare(ah: &Box, bh: &Box) -> std::cmp::Ordering { } #[allow(clippy::borrowed_box)] -fn box_y_compare(ah: &Box, bh: &Box) -> std::cmp::Ordering { +fn box_y_compare(ah: &Box, bh: &Box) -> std::cmp::Ordering { match (ah.bounding_box(0., 0.), bh.bounding_box(0., 0.)) { (Some(box_left), Some(box_right)) => { box_left.min().y.partial_cmp(&box_right.min().y).unwrap() @@ -63,7 +63,7 @@ fn box_y_compare(ah: &Box, bh: &Box) -> std::cmp::Ordering { } #[allow(clippy::borrowed_box)] -fn box_z_compare(ah: &Box, bh: &Box) -> std::cmp::Ordering { +fn box_z_compare(ah: &Box, bh: &Box) -> std::cmp::Ordering { match (ah.bounding_box(0., 0.), bh.bounding_box(0., 0.)) { (Some(box_left), Some(box_right)) => { box_left.min().z.partial_cmp(&box_right.min().z).unwrap() @@ -99,11 +99,11 @@ fn vec_split_into(v: Vec, offset: usize) -> (Vec, Vec) { } impl BVHNode { - fn new(l: Vec>, t_min: f32, t_max: f32) -> BVHNode { + fn new(l: Vec>, t_min: f32, t_max: f32) -> BVHNode { if l.len() == 1 { BVHNode::Leaf(vec_first_into(l)) } else { - let mut l: Vec> = l.into_iter().collect(); + let mut l: Vec> = l.into_iter().collect(); let mut rng = rand::thread_rng(); match rng.gen_range::(0, 3) { 0 => l.sort_by(box_x_compare), @@ -121,7 +121,7 @@ impl BVHNode { } } - fn surrounding_box(left: &Hit, right: &Hit, t_min: f32, t_max: f32) -> Option { + fn surrounding_box(left: &dyn Hit, right: &dyn Hit, t_min: f32, t_max: f32) -> Option { match ( left.bounding_box(t_min, t_max), right.bounding_box(t_min, t_max), @@ -185,7 +185,7 @@ pub struct BVH { } impl BVH { - pub fn new(l: Vec>, t_min: f32, t_max: f32) -> BVH { + pub fn new(l: Vec>, t_min: f32, t_max: f32) -> BVH { let count = l.len(); let start = Instant::now(); let bvh = BVH { diff --git a/rtiow/src/cuboid.rs b/rtiow/src/cuboid.rs index ee66100..5639f5b 100644 --- a/rtiow/src/cuboid.rs +++ b/rtiow/src/cuboid.rs @@ -21,7 +21,7 @@ pub struct Cuboid { impl Cuboid { // This clippy doesn't work right with Arc. #[allow(clippy::needless_pass_by_value)] - pub fn new(p_min: Vec3, p_max: Vec3, material: Arc) -> Cuboid { + pub fn new(p_min: Vec3, p_max: Vec3, material: Arc) -> Cuboid { Cuboid { p_min, p_max, diff --git a/rtiow/src/hitable.rs b/rtiow/src/hitable.rs index 512baa9..6660da9 100644 --- a/rtiow/src/hitable.rs +++ b/rtiow/src/hitable.rs @@ -10,7 +10,7 @@ pub struct HitRecord<'m> { pub uv: (f32, f32), pub p: Vec3, pub normal: Vec3, - pub material: &'m Material, + pub material: &'m dyn Material, } pub trait Hit: Send + Sync { @@ -18,7 +18,7 @@ pub trait Hit: Send + Sync { fn bounding_box(&self, t_min: f32, t_max: f32) -> Option; } -impl Hit for Arc { +impl Hit for Arc { fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option { (**self).hit(r, t_min, t_max) } diff --git a/rtiow/src/hitable_list.rs b/rtiow/src/hitable_list.rs index a0b37d8..f26cb20 100644 --- a/rtiow/src/hitable_list.rs +++ b/rtiow/src/hitable_list.rs @@ -9,11 +9,11 @@ use crate::vec3::Vec3; #[derive(Default)] pub struct HitableList { - list: Vec>, + list: Vec>, } impl HitableList { - pub fn new(list: Vec>) -> HitableList { + pub fn new(list: Vec>) -> HitableList { HitableList { list } } } diff --git a/rtiow/src/kdtree.rs b/rtiow/src/kdtree.rs index a0e4f2e..034504b 100644 --- a/rtiow/src/kdtree.rs +++ b/rtiow/src/kdtree.rs @@ -7,7 +7,7 @@ use crate::hitable::HitRecord; use crate::ray::Ray; pub enum KDTree { - Leaf(Box), + Leaf(Box), Branch { left: Box, right: Box, @@ -42,7 +42,7 @@ fn vec_split_into(v: Vec, offset: usize) -> (Vec, Vec) { } impl KDTree { - pub fn new(l: Vec>, t_min: f32, t_max: f32) -> KDTree { + pub fn new(l: Vec>, t_min: f32, t_max: f32) -> KDTree { if l.is_empty() { panic!("Attempt to build k-d tree with no Hit objects"); } @@ -150,9 +150,11 @@ impl fmt::Display for KDTree { impl Hit for KDTree { fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option { match self.bounding_box(t_min, t_max) { - Some(bbox) => if !bbox.hit(r, t_min, t_max) { - return None; - }, + Some(bbox) => { + if !bbox.hit(r, t_min, t_max) { + return None; + } + } None => { info!("KDTree::hit no bbox: {:?}", r); return None; @@ -163,11 +165,13 @@ impl Hit for KDTree { KDTree::Branch { left, right, bbox } => match bbox { None => None, Some(_bbox) => match (left.hit(r, t_min, t_max), right.hit(r, t_min, t_max)) { - (Some(hit_left), Some(hit_right)) => if hit_left.t < hit_right.t { - Some(hit_left) - } else { - Some(hit_right) - }, + (Some(hit_left), Some(hit_right)) => { + if hit_left.t < hit_right.t { + Some(hit_left) + } else { + Some(hit_right) + } + } (Some(hit_left), None) => Some(hit_left), (None, Some(hit_right)) => Some(hit_right), (None, None) => None, diff --git a/rtiow/src/material.rs b/rtiow/src/material.rs index 1b45be5..6ef0664 100644 --- a/rtiow/src/material.rs +++ b/rtiow/src/material.rs @@ -13,11 +13,12 @@ fn random_in_unit_sphere() -> Vec3 { let mut rng = rand::thread_rng(); let v = Vec3::new(1., 1., 1.); loop { - let p = 2. * Vec3::new( - rng.gen_range::(0., 1.), - rng.gen_range::(0., 1.), - rng.gen_range::(0., 1.), - ) - v; + let p = + 2. * Vec3::new( + rng.gen_range::(0., 1.), + rng.gen_range::(0., 1.), + rng.gen_range::(0., 1.), + ) - v; if p.squared_length() < 1. { return p; } @@ -38,7 +39,7 @@ pub trait Material: Send + Sync { } } -impl Material for Arc { +impl Material for Arc { fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse { (**self).scatter(r_in, rec) } @@ -47,7 +48,7 @@ impl Material for Arc { } } -impl Material for Box { +impl Material for Box { fn scatter(&self, r_in: &Ray, rec: &HitRecord) -> ScatterResponse { (**self).scatter(r_in, rec) } @@ -257,7 +258,7 @@ mod tests { #[test] fn arc_material() { - let white: Arc = + let white: Arc = Arc::new(Lambertian::new(ConstantTexture::new([0.73, 0.73, 0.73]))); fn material_fn(m: M) diff --git a/rtiow/src/noise/mod.rs b/rtiow/src/noise/mod.rs index 6b73549..4440461 100644 --- a/rtiow/src/noise/mod.rs +++ b/rtiow/src/noise/mod.rs @@ -38,7 +38,7 @@ pub trait NoiseSource: Send + Sync { } } -impl NoiseSource for Box { +impl NoiseSource for Box { fn value(&self, p: Vec3) -> f32 { (**self).value(p) } diff --git a/rtiow/src/scenes/bench.rs b/rtiow/src/scenes/bench.rs index 50475f2..79de3fa 100644 --- a/rtiow/src/scenes/bench.rs +++ b/rtiow/src/scenes/bench.rs @@ -32,7 +32,7 @@ pub fn new(opt: &Opt) -> Scene { time_max, ); let mut rng = rand::thread_rng(); - let mut grid: Vec> = Vec::new(); + let mut grid: Vec> = Vec::new(); let len = 1000; for x in 0..len { for z in 0..len { @@ -50,7 +50,7 @@ pub fn new(opt: &Opt) -> Scene { ))); } } - let world: Box; + let world: Box; if opt.use_accel { let use_kd = true; if use_kd { diff --git a/rtiow/src/scenes/book.rs b/rtiow/src/scenes/book.rs index 6c5f912..0117d45 100644 --- a/rtiow/src/scenes/book.rs +++ b/rtiow/src/scenes/book.rs @@ -40,7 +40,7 @@ pub fn new(opt: &Opt) -> Scene { } else { [0.4, 1.0, 0.4] }; - let world: Box = if opt.use_accel { + let world: Box = if opt.use_accel { Box::new(KDTree::new(random_scene(ground_color), time_min, time_max)) } else { Box::new(HitableList::new(random_scene(ground_color))) @@ -58,13 +58,13 @@ pub fn new(opt: &Opt) -> Scene { } } -fn random_scene(ground_color: V) -> Vec> +fn random_scene(ground_color: V) -> Vec> where V: Into, { let mut rng = rand::thread_rng(); let checker = true; - let ground_material: Box = if checker { + let ground_material: Box = if checker { Box::new(Lambertian::new(CheckerTexture::new( ConstantTexture::new([0., 0., 0.]), ConstantTexture::new(ground_color), @@ -73,7 +73,7 @@ where Box::new(Lambertian::new(ConstantTexture::new(ground_color))) }; - let mut objects: Vec> = vec![Box::new(Sphere::new( + let mut objects: Vec> = vec![Box::new(Sphere::new( [0., -1000., 0.], 1000., ground_material, @@ -85,7 +85,7 @@ where let choose_mat = random(); let center = Vec3::new(a as f32 + 0.9 * random(), 0.2, b as f32 + 0.9 * random()); if (center - Vec3::new(4., 0.2, 0.)).length() > 0.9 { - let sphere: Box = if choose_mat < 0.8 { + let sphere: Box = if choose_mat < 0.8 { // diffuse Box::new(Sphere::new( center, @@ -119,7 +119,7 @@ where } } - let more: Vec> = vec![ + let more: Vec> = vec![ Box::new(Sphere::new( Vec3::new(0., 1., 0.), 1.0, diff --git a/rtiow/src/scenes/bvh.rs b/rtiow/src/scenes/bvh.rs index 8ffc228..53f5c98 100644 --- a/rtiow/src/scenes/bvh.rs +++ b/rtiow/src/scenes/bvh.rs @@ -58,7 +58,7 @@ pub fn new(opt: &Opt) -> Scene { time_max, ); trace!(target: "bvh", "World {}", b); - let world: Box = Box::new(b); + let world: Box = Box::new(b); Scene { camera, world, diff --git a/rtiow/src/scenes/cornell_box.rs b/rtiow/src/scenes/cornell_box.rs index 2b574ac..2ef80dc 100644 --- a/rtiow/src/scenes/cornell_box.rs +++ b/rtiow/src/scenes/cornell_box.rs @@ -37,7 +37,7 @@ pub fn new(opt: &Opt) -> Scene { time_max, ); - let objects: Vec> = vec![ + let objects: Vec> = vec![ // Box1 Box::new(Translate::new( RotateY::new( @@ -121,7 +121,7 @@ pub fn new(opt: &Opt) -> Scene { Lambertian::new(ConstantTexture::new(Vec3::new(0.73, 0.73, 0.73))), ))), ]; - let world: Box = if opt.use_accel { + let world: Box = if opt.use_accel { Box::new(KDTree::new(objects, time_min, time_max)) } else { Box::new(HitableList::new(objects)) diff --git a/rtiow/src/scenes/cornell_smoke.rs b/rtiow/src/scenes/cornell_smoke.rs index a54e9f2..df02b71 100644 --- a/rtiow/src/scenes/cornell_smoke.rs +++ b/rtiow/src/scenes/cornell_smoke.rs @@ -40,11 +40,12 @@ pub fn new(opt: &Opt) -> Scene { ); let red = Lambertian::new(ConstantTexture::new([0.65, 0.05, 0.05])); - let white: Arc = Arc::new(Lambertian::new(ConstantTexture::new([0.73, 0.73, 0.73]))); + let white: Arc = + Arc::new(Lambertian::new(ConstantTexture::new([0.73, 0.73, 0.73]))); let green = Lambertian::new(ConstantTexture::new([0.12, 0.45, 0.15])); let light = DiffuseLight::new(ConstantTexture::new([7., 7., 7.])); - let objects: Vec> = vec![ + let objects: Vec> = vec![ // White smoke box on the right Box::new(ConstantMedium::new( Translate::new( @@ -106,7 +107,7 @@ pub fn new(opt: &Opt) -> Scene { Arc::clone(&white), ))), ]; - let world: Box = if opt.use_accel { + let world: Box = if opt.use_accel { Box::new(KDTree::new(objects, time_min, time_max)) } else { Box::new(HitableList::new(objects)) diff --git a/rtiow/src/scenes/final_scene.rs b/rtiow/src/scenes/final_scene.rs index e7d8c02..e2507f0 100644 --- a/rtiow/src/scenes/final_scene.rs +++ b/rtiow/src/scenes/final_scene.rs @@ -51,10 +51,12 @@ pub fn new(opt: &Opt) -> Scene { let nb = 20; let rng = &mut rand::thread_rng(); - let mut boxlist: Vec> = Vec::with_capacity(10000); - let mut list: Vec> = Vec::new(); - let white: Arc = Arc::new(Lambertian::new(ConstantTexture::new([0.73, 0.73, 0.73]))); - let ground: Arc = Arc::new(Lambertian::new(ConstantTexture::new([0.48, 0.83, 0.53]))); + let mut boxlist: Vec> = Vec::with_capacity(10000); + let mut list: Vec> = Vec::new(); + let white: Arc = + Arc::new(Lambertian::new(ConstantTexture::new([0.73, 0.73, 0.73]))); + let ground: Arc = + Arc::new(Lambertian::new(ConstantTexture::new([0.48, 0.83, 0.53]))); for i in 0..nb { for j in 0..nb { let w = 100.; @@ -102,7 +104,8 @@ pub fn new(opt: &Opt) -> Scene { ))); // Blue smokey glass ball lower-left - let boundary: Arc = Arc::new(Sphere::new([360., 150., 145.], 70., Dielectric::new(1.5))); + let boundary: Arc = + Arc::new(Sphere::new([360., 150., 145.], 70., Dielectric::new(1.5))); list.push(Box::new(Arc::clone(&boundary))); list.push(Box::new(ConstantMedium::new( Arc::clone(&boundary), @@ -111,7 +114,7 @@ pub fn new(opt: &Opt) -> Scene { ))); // General white mist over whole scene - let boundary: Arc = Arc::new(Sphere::new([0., 0., 0.], 5000., Dielectric::new(1.5))); + let boundary: Arc = Arc::new(Sphere::new([0., 0., 0.], 5000., Dielectric::new(1.5))); list.push(Box::new(Arc::clone(&boundary))); list.push(Box::new(ConstantMedium::new( Arc::clone(&boundary), @@ -145,7 +148,7 @@ pub fn new(opt: &Opt) -> Scene { // White 'cube' made of 1000 spheres let ns = 1000; - let mut boxlist: Vec> = Vec::with_capacity(1000); + let mut boxlist: Vec> = Vec::with_capacity(1000); for _ in 0..ns { boxlist.push(Box::new(Sphere::new( [ diff --git a/rtiow/src/scenes/mandelbrot.rs b/rtiow/src/scenes/mandelbrot.rs index 7237222..7574f49 100644 --- a/rtiow/src/scenes/mandelbrot.rs +++ b/rtiow/src/scenes/mandelbrot.rs @@ -15,6 +15,7 @@ use crate::renderer::Opt; use crate::renderer::Scene; use crate::sphere::Sphere; use crate::texture::ConstantTexture; +use crate::texture::ImageTexture; use crate::texture::Mandelbrot; use crate::texture::NoiseTexture; use crate::vec3::Vec3; @@ -44,28 +45,32 @@ pub fn new(opt: &Opt) -> Scene { Box::new(ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4))) }; + let world_image_bytes = include_bytes!("../../images/world.jpg"); + let it = ImageTexture::new(image::load_from_memory(world_image_bytes).unwrap().to_rgb()); let noise_source = Perlin::new(rng); let noise_type = NoiseType::Scale(10.); - let objects: Vec> = vec![ + let objects: Vec> = vec![ // Textured globe // Box::new(Sphere::new(Vec3::new(0., 2., 0.), 2.0, Lambertian::new(it))), Box::new(Sphere::new( Vec3::new(0., 2., 0.), 2.0, - DiffuseLight::new(Mandelbrot::default()), - )), - // Earth sized sphere - Box::new(Sphere::new( - Vec3::new(0., -1000., 0.), - 1000., - // Box::new(Lambertian::new(ground_color)), - Lambertian::new(NoiseTexture::new(noise_source, noise_type)), + DiffuseLight::new(it), )), + // Ground Box::new(XZRect::new( -100., 100., -100., 1000., + -60., + DiffuseLight::new(Mandelbrot::default()), + )), + Box::new(XZRect::new( + -100., + 100., + -100., + 200., 60., DiffuseLight::new(ConstantTexture::new(Vec3::new(1., 1., 1.))), )), @@ -107,7 +112,7 @@ pub fn new(opt: &Opt) -> Scene { 1., 3., 4., - DiffuseLight::new(Mandelbrot::default()), + Lambertian::new(NoiseTexture::new(noise_source, noise_type)), )), /* Box::new(Sphere::new( @@ -135,7 +140,7 @@ pub fn new(opt: &Opt) -> Scene { )), */ ]; - let world: Box = if opt.use_accel { + let world: Box = if opt.use_accel { Box::new(KDTree::new(objects, time_min, time_max)) } else { Box::new(HitableList::new(objects)) diff --git a/rtiow/src/scenes/perlin_debug.rs b/rtiow/src/scenes/perlin_debug.rs index 32091e7..a9d26e0 100644 --- a/rtiow/src/scenes/perlin_debug.rs +++ b/rtiow/src/scenes/perlin_debug.rs @@ -42,9 +42,9 @@ pub fn new(opt: &Opt) -> Scene { size: 32, scale: 0.05, }; - let pertext: Arc = Arc::new(NoiseTexture::new(noise_source, noise_type)); + let pertext: Arc = Arc::new(NoiseTexture::new(noise_source, noise_type)); - let objects: Vec> = vec![ + let objects: Vec> = vec![ Box::new(Sphere::new( Vec3::new(0., -1000., 0.), 1000., @@ -56,7 +56,7 @@ pub fn new(opt: &Opt) -> Scene { Lambertian::new(Arc::clone(&pertext)), )), ]; - let world: Box = if opt.use_accel { + let world: Box = if opt.use_accel { Box::new(KDTree::new(objects, time_min, time_max)) } else { Box::new(HitableList::new(objects)) diff --git a/rtiow/src/scenes/test.rs b/rtiow/src/scenes/test.rs index 143dcd6..77ee2fa 100644 --- a/rtiow/src/scenes/test.rs +++ b/rtiow/src/scenes/test.rs @@ -49,7 +49,7 @@ pub fn new(opt: &Opt) -> Scene { let it = ImageTexture::new(image::load_from_memory(world_image_bytes).unwrap().to_rgb()); let noise_source = Perlin::new(rng); let noise_type = NoiseType::Scale(10.); - let objects: Vec> = vec![ + let objects: Vec> = vec![ // Big sphere Box::new(Sphere::new(Vec3::new(0., 2., 0.), 2.0, Lambertian::new(it))), // Earth sized sphere @@ -133,7 +133,7 @@ pub fn new(opt: &Opt) -> Scene { )), */ ]; - let world: Box = if opt.use_accel { + let world: Box = if opt.use_accel { Box::new(KDTree::new(objects, time_min, time_max)) } else { Box::new(HitableList::new(objects)) diff --git a/rtiow/src/scenes/tutorial.rs b/rtiow/src/scenes/tutorial.rs index caefd56..0182db6 100644 --- a/rtiow/src/scenes/tutorial.rs +++ b/rtiow/src/scenes/tutorial.rs @@ -35,7 +35,7 @@ pub fn new(opt: &Opt) -> Scene { ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4)) }; - let objects: Vec> = vec![ + let objects: Vec> = vec![ //let world: Box = Box::new(HitableList::new(vec![ Box::new(Sphere::new( Vec3::new(0., 0., -1.), @@ -61,7 +61,7 @@ pub fn new(opt: &Opt) -> Scene { Lambertian::new(ConstantTexture::new(Vec3::new(0.2, 0.8, 0.2))), )), ]; - let world: Box = if opt.use_accel { + let world: Box = if opt.use_accel { Box::new(KDTree::new(objects, time_min, time_max)) } else { Box::new(HitableList::new(objects)) diff --git a/rtiow/src/texture/mod.rs b/rtiow/src/texture/mod.rs index baf9c88..f732300 100644 --- a/rtiow/src/texture/mod.rs +++ b/rtiow/src/texture/mod.rs @@ -19,7 +19,7 @@ pub trait Texture: Send + Sync { fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3; } -impl Texture for Arc { +impl Texture for Arc { fn value(&self, u: f32, v: f32, p: Vec3) -> Vec3 { (**self).value(u, v, p) }