diff --git a/ray-tracing-core/src/light.rs b/ray-tracing-core/src/light.rs index 6f3e2f6..a804669 100644 --- a/ray-tracing-core/src/light.rs +++ b/ray-tracing-core/src/light.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use std::fmt::Debug; -pub trait Light: Sync + Debug { +pub trait Light: Send + Sync + Debug { fn emit(&self, w_in: Dir3, rng: &mut R) -> Color; } diff --git a/ray-tracing-core/src/material.rs b/ray-tracing-core/src/material.rs index c9869af..ae20c8c 100644 --- a/ray-tracing-core/src/material.rs +++ b/ray-tracing-core/src/material.rs @@ -2,7 +2,7 @@ use crate::prelude::*; use std::fmt::Debug; /// All calculations for the material are done a tangent space of the intersection. -pub trait Material: Sync + Debug { +pub trait Material: Send + Sync + Debug { fn eval(&self, w_in: Dir3, w_out: Dir3, rng: &mut R) -> Color; fn sample(&self, w_in: Dir3, rng: &mut R) -> SampleResult { diff --git a/ray-tracing-egui/src/main.rs b/ray-tracing-egui/src/main.rs index af5f5e0..f15175d 100644 --- a/ray-tracing-egui/src/main.rs +++ b/ray-tracing-egui/src/main.rs @@ -91,16 +91,16 @@ fn main() { let scenes = example_scenes::(); let mut settings = { let scene = scenes.iter().next().unwrap(); - let e = (scene.1)(); + let e = scene.1; render::RenderSettings { width: window.inner_size().width, height: window.inner_size().height, scene: scene.0, renderer_id: 0, - camera_pos: e.camera_pos, - camera_look_at: e.camera_look_at, - camera_up: e.camera_up, - camera_horizontal_fov: e.horizontal_fov, + camera_pos: e.get_camera_pos(), + camera_look_at: e.get_camera_look_at(), + camera_up: e.get_camera_up(), + camera_horizontal_fov: e.get_horizontal_fov(), } }; @@ -225,11 +225,12 @@ fn main() { } if scene_changed { settings_changed = true; - let e = scenes[settings.scene](); - settings.camera_pos = e.camera_pos; - settings.camera_look_at = e.camera_look_at; - settings.camera_up = e.camera_up; - settings.camera_horizontal_fov = e.horizontal_fov; + settings.camera_pos = scenes[settings.scene].get_camera_pos(); + settings.camera_look_at = + scenes[settings.scene].get_camera_look_at(); + settings.camera_up = scenes[settings.scene].get_camera_up(); + settings.camera_horizontal_fov = + scenes[settings.scene].get_horizontal_fov(); } }); }); diff --git a/ray-tracing-egui/src/render.rs b/ray-tracing-egui/src/render.rs index 4d01df9..f6a685a 100644 --- a/ray-tracing-egui/src/render.rs +++ b/ray-tracing-egui/src/render.rs @@ -69,8 +69,7 @@ pub fn render_thread( let example_scenes = examples::example_scenes::(); - let e = example_scenes[settings.scene](); - let mut scene = (e.scene)(); + let mut scene = example_scenes[settings.scene].get_scene(); let mut camera = BasicCamera::from_look_at( settings.width, @@ -88,8 +87,7 @@ pub fn render_thread( while let Ok(s) = rx.try_recv() { println!("Settings changed."); settings = s; - let e = example_scenes[settings.scene](); - scene = (e.scene)(); + scene = example_scenes[settings.scene].get_scene(); camera = BasicCamera::from_look_at( settings.width, settings.height, diff --git a/ray-tracing-image/src/main.rs b/ray-tracing-image/src/main.rs index 7990d5f..423eba3 100644 --- a/ray-tracing-image/src/main.rs +++ b/ray-tracing-image/src/main.rs @@ -7,7 +7,7 @@ use ray_tracing_core::{ scene::Scene, }; use ray_tracing_renderer::path_tracer_importance::PathTracerImportance; -use ray_tracing_scene::examples::basic_cornell; +use ray_tracing_scene::examples::{basic_cornell, ExampleScene}; use rayon::prelude::*; use std::path::Path; @@ -45,18 +45,18 @@ fn render_image< fn main() -> ImageResult<()> { // let s = BasicScene::new(); - let s = basic_cornell::scene(); + let s = basic_cornell::BasicCornell::new(); let c = BasicCamera::from_look_at( 400, 400, - s.camera_pos, - s.camera_look_at, - s.camera_up, - s.horizontal_fov, + s.get_camera_pos(), + s.get_camera_look_at(), + s.get_camera_up(), + s.get_horizontal_fov(), ); let r = PathTracerImportance::new(400, 400); - render_image(&r, &(s.scene)(), &c, "test.exr", 1048) + render_image(&r, &s.get_scene(), &c, "test.exr", 1048) } diff --git a/ray-tracing-material/src/microfacet.rs b/ray-tracing-material/src/microfacet.rs index 94e6259..8e2e20f 100644 --- a/ray-tracing-material/src/microfacet.rs +++ b/ray-tracing-material/src/microfacet.rs @@ -28,7 +28,7 @@ pub fn fresnel_real(cos_theta_in: Float, nu1: Float, nu2: Float) -> Float { 0.5 * (rs + rp) } -impl Material for Microfacet { +impl Material for Microfacet { fn eval(&self, w_in: Dir3, w_out: Dir3, _rng: &mut R) -> ray_tracing_core::prelude::Color { if w_out.y() > 0.0 && w_in.y() > 0.0 { let w_h = (w_in + w_out).normalize(); diff --git a/ray-tracing-scene/src/examples/basic_cornell.rs b/ray-tracing-scene/src/examples/basic_cornell.rs index b8f8fe6..0c9dd9d 100644 --- a/ray-tracing-scene/src/examples/basic_cornell.rs +++ b/ray-tracing-scene/src/examples/basic_cornell.rs @@ -1,3 +1,5 @@ +use std::cell::OnceCell; + use crate::triangle_bvh::{BVHMaterial, Triangle, TriangleBVH}; use super::ExampleScene; @@ -5,82 +7,104 @@ use super::ExampleScene; use ray_tracing_core::{light::AreaLight, prelude::*, scene::Scene}; use ray_tracing_material::{diffuse::DiffuseMaterial, mirror::Mirror}; -pub fn scene() -> ExampleScene { - let f = || { - let side_length = 1.5; - let light_size = 0.5; - let light_offset = 0.01; - let box_size = 0.3; - let scene = TriangleBVH::new( - vec![ - Pos3::new(side_length, side_length, side_length), - Pos3::new(side_length, side_length, -side_length), - Pos3::new(side_length, -side_length, side_length), - Pos3::new(side_length, -side_length, -side_length), - Pos3::new(-side_length, side_length, side_length), - Pos3::new(-side_length, side_length, -side_length), - Pos3::new(-side_length, -side_length, side_length), - Pos3::new(-side_length, -side_length, -side_length), - Pos3::new(light_size, side_length - light_offset, light_size), - Pos3::new(light_size, side_length - light_offset, -light_size), - Pos3::new(-light_size, side_length - light_offset, light_size), - Pos3::new(-light_size, side_length - light_offset, -light_size), - Pos3::new(box_size, -side_length, 0.0), - Pos3::new(0.0, -side_length, -box_size), - Pos3::new(-box_size, -side_length, 0.0), - Pos3::new(0.0, -side_length, box_size), - Pos3::new(0.0, box_size - side_length, 0.0), - ], - vec![ - Triangle::new([0, 1, 2], 0), - Triangle::new([1, 3, 2], 0), - Triangle::new([0, 4, 1], 0), - Triangle::new([1, 4, 5], 0), - Triangle::new([2, 3, 6], 0), - Triangle::new([3, 7, 6], 0), - Triangle::new([0, 2, 4], 1), - Triangle::new([6, 4, 2], 1), - Triangle::new([1, 5, 3], 2), - Triangle::new([7, 3, 5], 2), - Triangle::new([8, 10, 9], 3), - Triangle::new([11, 9, 10], 3), - Triangle::new([12, 13, 16], 4), - Triangle::new([13, 14, 16], 4), - Triangle::new([14, 15, 16], 4), - Triangle::new([15, 12, 16], 4), - ], - vec![ - BVHMaterial { - material: Some(Box::new(DiffuseMaterial::new(Color::new(0.8, 0.8, 0.8)))), - light: None, - }, - BVHMaterial { - material: Some(Box::new(DiffuseMaterial::new(Color::new(0.9, 0.0, 0.0)))), - light: None, - }, - BVHMaterial { - material: Some(Box::new(DiffuseMaterial::new(Color::new(0.0, 0.9, 0.0)))), - light: None, - }, - BVHMaterial { - material: None, - light: Some(Box::new(AreaLight::new(Color::white() * 18.0))), - }, - BVHMaterial { - material: Some(Box::new(Mirror::new(Color::new(1.0, 1.0, 1.0)))), - light: None, - }, - ], - ); +pub struct BasicCornell { + scene: OnceCell>, +} - Box::new(scene) as Box + Sync> - }; - - ExampleScene { - scene: f, - camera_pos: Pos3::new(-6.0, 0.0, 0.0), - camera_look_at: Pos3::new(0.0, 0.0, 0.0), - camera_up: Dir3::up(), - horizontal_fov: Float::to_radians(90.0), +impl BasicCornell { + pub fn new() -> Self { + BasicCornell { + scene: OnceCell::new(), + } + } +} + +impl ExampleScene for BasicCornell { + fn get_scene(&self) -> Box + Sync> { + let s = self.scene.get_or_init(|| { + let side_length = 1.5; + let light_size = 0.5; + let light_offset = 0.01; + let box_size = 0.3; + TriangleBVH::new( + vec![ + Pos3::new(side_length, side_length, side_length), + Pos3::new(side_length, side_length, -side_length), + Pos3::new(side_length, -side_length, side_length), + Pos3::new(side_length, -side_length, -side_length), + Pos3::new(-side_length, side_length, side_length), + Pos3::new(-side_length, side_length, -side_length), + Pos3::new(-side_length, -side_length, side_length), + Pos3::new(-side_length, -side_length, -side_length), + Pos3::new(light_size, side_length - light_offset, light_size), + Pos3::new(light_size, side_length - light_offset, -light_size), + Pos3::new(-light_size, side_length - light_offset, light_size), + Pos3::new(-light_size, side_length - light_offset, -light_size), + Pos3::new(box_size, -side_length, 0.0), + Pos3::new(0.0, -side_length, -box_size), + Pos3::new(-box_size, -side_length, 0.0), + Pos3::new(0.0, -side_length, box_size), + Pos3::new(0.0, box_size - side_length, 0.0), + ], + vec![ + Triangle::new([0, 1, 2], 0), + Triangle::new([1, 3, 2], 0), + Triangle::new([0, 4, 1], 0), + Triangle::new([1, 4, 5], 0), + Triangle::new([2, 3, 6], 0), + Triangle::new([3, 7, 6], 0), + Triangle::new([0, 2, 4], 1), + Triangle::new([6, 4, 2], 1), + Triangle::new([1, 5, 3], 2), + Triangle::new([7, 3, 5], 2), + Triangle::new([8, 10, 9], 3), + Triangle::new([11, 9, 10], 3), + Triangle::new([12, 13, 16], 4), + Triangle::new([13, 14, 16], 4), + Triangle::new([14, 15, 16], 4), + Triangle::new([15, 12, 16], 4), + ], + vec![ + BVHMaterial { + material: Some(Box::new(DiffuseMaterial::new(Color::new(0.8, 0.8, 0.8)))), + light: None, + }, + BVHMaterial { + material: Some(Box::new(DiffuseMaterial::new(Color::new(0.9, 0.0, 0.0)))), + light: None, + }, + BVHMaterial { + material: Some(Box::new(DiffuseMaterial::new(Color::new(0.0, 0.9, 0.0)))), + light: None, + }, + BVHMaterial { + material: None, + light: Some(Box::new(AreaLight::new(Color::white() * 18.0))), + }, + BVHMaterial { + material: Some(Box::new(Mirror::new(Color::new(1.0, 1.0, 1.0)))), + light: None, + }, + ], + ) + }); + + Box::new(s.clone()) as Box + Sync> + } + + fn get_camera_pos(&self) -> Pos3 { + Pos3::new(-6.0, 0.0, 0.0) + } + + fn get_camera_look_at(&self) -> Pos3 { + Pos3::new(0.0, 0.0, 0.0) + } + + fn get_camera_up(&self) -> Dir3 { + Dir3::up() + } + + fn get_horizontal_fov(&self) -> Float { + Float::to_radians(90.0) } } diff --git a/ray-tracing-scene/src/examples/cornell2.rs b/ray-tracing-scene/src/examples/cornell2.rs index b953169..98b7a37 100644 --- a/ray-tracing-scene/src/examples/cornell2.rs +++ b/ray-tracing-scene/src/examples/cornell2.rs @@ -1,7 +1,7 @@ use rand::Rng; use ray_tracing_core::{light::AreaLight, prelude::*, scene::Scene}; use ray_tracing_material::{diffuse::DiffuseMaterial, mirror::Mirror}; -use std::fmt::Debug; +use std::{cell::OnceCell, fmt::Debug}; use crate::{ parse_obj::ObjData, @@ -10,42 +10,67 @@ use crate::{ use super::ExampleScene; -pub fn scene() -> ExampleScene { - let f = || { - let obj = ObjData::new("ray-tracing-scene/obj/cornell_box.obj").unwrap(); +pub struct Cornell2 { + scene: OnceCell>, +} - let triangles = obj - .triangle_faces() - .map(|t| Triangle::new(t.v, t.mat.unwrap())) - .collect(); - - let materials = obj - .materials() - .iter() - .map(|m| match m.name.as_str() { - "white" => BVHMaterial::new_material(DiffuseMaterial::new(Color::white())), - "light" => BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)), - "blue" => { - BVHMaterial::new_material(DiffuseMaterial::new(Color::new(0.0, 0.0, 1.0))) - } - "red" => BVHMaterial::new_material(DiffuseMaterial::new(Color::new(1.0, 0.0, 0.0))), - "green" => { - BVHMaterial::new_material(DiffuseMaterial::new(Color::new(0.0, 1.0, 0.0))) - } - "mirror" => BVHMaterial::new_material(Mirror::new(Color::white())), - _ => unreachable!(), - }) - .collect(); - - let scene = TriangleBVH::new(obj.vertices, triangles, materials); - Box::new(scene) as Box + Sync> - }; - - ExampleScene { - scene: f, - camera_pos: Pos3::new(275.0, 275.0, -800.0), - camera_look_at: Pos3::new(275.0, 275.0, 275.0), - camera_up: Dir3::up(), - horizontal_fov: 90.0_f32.to_radians(), +impl Cornell2 { + pub fn new() -> Self { + Self { + scene: OnceCell::new(), + } + } +} + +impl ExampleScene for Cornell2 { + fn get_scene(&self) -> Box + Sync> { + let s = self.scene.get_or_init(|| { + let obj = ObjData::new("ray-tracing-scene/obj/cornell_box.obj").unwrap(); + + let triangles = obj + .triangle_faces() + .map(|t| Triangle::new(t.v, t.mat.unwrap())) + .collect(); + + let materials = obj + .materials() + .iter() + .map(|m| match m.name.as_str() { + "white" => BVHMaterial::new_material(DiffuseMaterial::new(Color::white())), + "light" => BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)), + "blue" => { + BVHMaterial::new_material(DiffuseMaterial::new(Color::new(0.0, 0.0, 1.0))) + } + "red" => { + BVHMaterial::new_material(DiffuseMaterial::new(Color::new(1.0, 0.0, 0.0))) + } + "green" => { + BVHMaterial::new_material(DiffuseMaterial::new(Color::new(0.0, 1.0, 0.0))) + } + "mirror" => BVHMaterial::new_material(Mirror::new(Color::white())), + _ => unreachable!(), + }) + .collect(); + + TriangleBVH::new(obj.vertices, triangles, materials) + }); + + Box::new(s.clone()) + } + + fn get_camera_pos(&self) -> Pos3 { + Pos3::new(275.0, 275.0, -800.0) + } + + fn get_camera_look_at(&self) -> Pos3 { + Pos3::new(275.0, 275.0, 275.0) + } + + fn get_camera_up(&self) -> Dir3 { + Dir3::up() + } + + fn get_horizontal_fov(&self) -> Float { + Float::to_radians(90.0) } } diff --git a/ray-tracing-scene/src/examples/mod.rs b/ray-tracing-scene/src/examples/mod.rs index 68b3cf8..d7eae54 100644 --- a/ray-tracing-scene/src/examples/mod.rs +++ b/ray-tracing-scene/src/examples/mod.rs @@ -2,20 +2,27 @@ use ray_tracing_core::{prelude::*, scene::Scene}; use std::collections::HashMap; use std::fmt::Debug; -pub struct ExampleScene { - pub scene: fn() -> Box + Sync>, - pub camera_pos: Pos3, - pub camera_look_at: Pos3, - pub camera_up: Dir3, - pub horizontal_fov: Float, +pub trait ExampleScene { + fn get_scene(&self) -> Box + Sync>; + + fn get_camera_pos(&self) -> Pos3; + + fn get_camera_look_at(&self) -> Pos3; + + fn get_camera_up(&self) -> Dir3; + + fn get_horizontal_fov(&self) -> Float; } -pub fn example_scenes() -> HashMap<&'static str, fn() -> ExampleScene> +pub fn example_scenes() -> HashMap<&'static str, Box>> { - let mut map: HashMap<&str, fn() -> ExampleScene> = HashMap::new(); - map.insert("basic_cornel", basic_cornell::scene::); - map.insert("cornel2", cornell2::scene::); - map.insert("stanford_dragon", stanford_dragon::scene::); + let mut map: HashMap<&str, Box>> = HashMap::new(); + map.insert("basic_cornel", Box::new(basic_cornell::BasicCornell::new())); + map.insert("cornel2", Box::new(cornell2::Cornell2::new())); + map.insert( + "stanford_dragon", + Box::new(stanford_dragon::StanfordDragon::new()), + ); map } diff --git a/ray-tracing-scene/src/examples/stanford_dragon.rs b/ray-tracing-scene/src/examples/stanford_dragon.rs index f7cee2c..78ba90b 100644 --- a/ray-tracing-scene/src/examples/stanford_dragon.rs +++ b/ray-tracing-scene/src/examples/stanford_dragon.rs @@ -1,11 +1,10 @@ use rand::Rng; use ray_tracing_core::{light::AreaLight, prelude::*, scene::Scene}; use ray_tracing_material::{ - diffuse::DiffuseMaterial, microfacet::{BeckmannDistribution, Microfacet}, oren_nayar::OrenNayar, }; -use std::fmt::Debug; +use std::cell::OnceCell; use crate::{ parse_obj::ObjData, @@ -14,72 +13,95 @@ use crate::{ use super::ExampleScene; -pub fn scene() -> ExampleScene { - let f = || { - let obj = ObjData::new("ray-tracing-scene/obj/stanford_dragon.obj").unwrap(); +pub struct StanfordDragon { + scene: OnceCell>, +} - let mut triangles = obj - .triangle_faces() - .map(|t| Triangle::new(t.v, 0)) - .collect::>(); - - let color = Color::new(0.2, 0.2, 0.9); - let materials = vec![ - BVHMaterial::new_material(Microfacet::new(BeckmannDistribution::new(0.01), color)), - BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.8, 0.8, 0.8))), - BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.9, 0.0, 0.0))), - BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.0, 0.9, 0.0))), - BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)), - ]; - - let mut vertices = obj.vertices; - for v in &mut vertices { - *v = Pos3::new(v.x(), v.z() + 60.0, -v.y()); +impl StanfordDragon { + pub fn new() -> Self { + Self { + scene: OnceCell::new(), } - - let side_length = 400.0; - let light_size = 150.0; - let light_offset = 0.01; - let offset = vertices.len() as u32; - vertices.extend_from_slice(&[ - Pos3::new(side_length, 2.0 * side_length, side_length), - Pos3::new(side_length, 2.0 * side_length, -side_length), - Pos3::new(side_length, 0.0, side_length), - Pos3::new(side_length, 0.0, -side_length), - Pos3::new(-side_length, 2.0 * side_length, side_length), - Pos3::new(-side_length, 2.0 * side_length, -side_length), - Pos3::new(-side_length, 0.0, side_length), - Pos3::new(-side_length, 0.0, -side_length), - Pos3::new(light_size, 2.0 * side_length - light_offset, light_size), - Pos3::new(light_size, 2.0 * side_length - light_offset, -light_size), - Pos3::new(-light_size, 2.0 * side_length - light_offset, light_size), - Pos3::new(-light_size, 2.0 * side_length - light_offset, -light_size), - ]); - - triangles.extend_from_slice(&[ - Triangle::new([offset, 1 + offset, 2 + offset], 1), - Triangle::new([1 + offset, 3 + offset, 2 + offset], 1), - Triangle::new([offset, 4 + offset, 1 + offset], 1), - Triangle::new([1 + offset, 4 + offset, 5 + offset], 1), - Triangle::new([2 + offset, 3 + offset, 6 + offset], 1), - Triangle::new([3 + offset, 7 + offset, 6 + offset], 1), - Triangle::new([offset, 2 + offset, 4 + offset], 2), - Triangle::new([6 + offset, 4 + offset, 2 + offset], 2), - Triangle::new([1 + offset, 5 + offset, 3 + offset], 3), - Triangle::new([7 + offset, 3 + offset, 5 + offset], 3), - Triangle::new([8 + offset, 10 + offset, 9 + offset], 4), - Triangle::new([11 + offset, 9 + offset, 10 + offset], 4), - ]); - - let scene = TriangleBVH::new(vertices, triangles, materials); - Box::new(scene) as Box + Sync> - }; - - ExampleScene { - scene: f, - camera_pos: Pos3::new(-150.0, 160.0, 250.0), - camera_look_at: Pos3::new(0.0, 60.0, 0.0), - camera_up: Dir3::up(), - horizontal_fov: 90.0_f32.to_radians(), + } +} + +impl ExampleScene for StanfordDragon { + fn get_scene(&self) -> Box + Sync> { + let s = self.scene.get_or_init(|| { + let obj = ObjData::new("ray-tracing-scene/obj/stanford_dragon.obj").unwrap(); + + let mut triangles = obj + .triangle_faces() + .map(|t| Triangle::new(t.v, 0)) + .collect::>(); + + let color = Color::new(0.2, 0.2, 0.9); + let materials = vec![ + BVHMaterial::new_material(Microfacet::new(BeckmannDistribution::new(0.01), color)), + BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.8, 0.8, 0.8))), + BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.9, 0.0, 0.0))), + BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.0, 0.9, 0.0))), + BVHMaterial::new_light(AreaLight::new(Color::white() * 30.0)), + ]; + + let mut vertices = obj.vertices; + for v in &mut vertices { + *v = Pos3::new(v.x(), v.z() + 60.0, -v.y()); + } + + let side_length = 400.0; + let light_size = 150.0; + let light_offset = 0.01; + let offset = vertices.len() as u32; + vertices.extend_from_slice(&[ + Pos3::new(side_length, 2.0 * side_length, side_length), + Pos3::new(side_length, 2.0 * side_length, -side_length), + Pos3::new(side_length, 0.0, side_length), + Pos3::new(side_length, 0.0, -side_length), + Pos3::new(-side_length, 2.0 * side_length, side_length), + Pos3::new(-side_length, 2.0 * side_length, -side_length), + Pos3::new(-side_length, 0.0, side_length), + Pos3::new(-side_length, 0.0, -side_length), + Pos3::new(light_size, 2.0 * side_length - light_offset, light_size), + Pos3::new(light_size, 2.0 * side_length - light_offset, -light_size), + Pos3::new(-light_size, 2.0 * side_length - light_offset, light_size), + Pos3::new(-light_size, 2.0 * side_length - light_offset, -light_size), + ]); + + triangles.extend_from_slice(&[ + Triangle::new([offset, 1 + offset, 2 + offset], 1), + Triangle::new([1 + offset, 3 + offset, 2 + offset], 1), + Triangle::new([offset, 4 + offset, 1 + offset], 1), + Triangle::new([1 + offset, 4 + offset, 5 + offset], 1), + Triangle::new([2 + offset, 3 + offset, 6 + offset], 1), + Triangle::new([3 + offset, 7 + offset, 6 + offset], 1), + Triangle::new([offset, 2 + offset, 4 + offset], 2), + Triangle::new([6 + offset, 4 + offset, 2 + offset], 2), + Triangle::new([1 + offset, 5 + offset, 3 + offset], 3), + Triangle::new([7 + offset, 3 + offset, 5 + offset], 3), + Triangle::new([8 + offset, 10 + offset, 9 + offset], 4), + Triangle::new([11 + offset, 9 + offset, 10 + offset], 4), + ]); + + TriangleBVH::new(vertices, triangles, materials) + }); + + Box::new(s.clone()) + } + + fn get_camera_pos(&self) -> Pos3 { + Pos3::new(-150.0, 160.0, 250.0) + } + + fn get_camera_look_at(&self) -> Pos3 { + Pos3::new(0.0, 60.0, 0.0) + } + + fn get_camera_up(&self) -> Dir3 { + Dir3::up() + } + + fn get_horizontal_fov(&self) -> Float { + Float::to_radians(90.0) } } diff --git a/ray-tracing-scene/src/triangle_bvh.rs b/ray-tracing-scene/src/triangle_bvh.rs index 98b6e28..c50700a 100644 --- a/ray-tracing-scene/src/triangle_bvh.rs +++ b/ray-tracing-scene/src/triangle_bvh.rs @@ -4,6 +4,7 @@ use ray_tracing_core::{ scene::{Intersection, LightSample, Scene}, }; use sampling::sample_triangle; +use std::sync::Arc; type Index = u32; @@ -11,11 +12,23 @@ type Index = u32; pub struct TriangleBVH { vertices: Vec, triangles: Vec, - materials: Vec>, + materials: Arc<[BVHMaterial]>, bvh: Vec, lights: Vec, } +impl Clone for TriangleBVH { + fn clone(&self) -> Self { + Self { + vertices: self.vertices.clone(), + triangles: self.triangles.clone(), + materials: Arc::clone(&self.materials), + bvh: self.bvh.clone(), + lights: self.lights.clone(), + } + } +} + #[derive(Debug)] pub struct BVHMaterial { pub material: Option>>, @@ -223,7 +236,7 @@ impl TriangleBVH { vertices, bvh, triangles, - materials, + materials: materials.into(), lights, } } diff --git a/ray-tracing-tev/src/main.rs b/ray-tracing-tev/src/main.rs index 29996b6..7ea3205 100644 --- a/ray-tracing-tev/src/main.rs +++ b/ray-tracing-tev/src/main.rs @@ -97,17 +97,17 @@ fn main() { for scene in scenes { let f = map.get(scene).unwrap(); - let e = f(); + + let s = f.get_scene(); let c = BasicCamera::from_look_at( args.width, args.height, - e.camera_pos, - e.camera_look_at, - e.camera_up, - e.horizontal_fov, + f.get_camera_pos(), + f.get_camera_look_at(), + f.get_camera_up(), + f.get_horizontal_fov(), ); - let s = (e.scene)(); let r = DepthRenderer::new(args.width, args.height); render_image(