From c603e2463395f6d0356c0847b0b8279612784cfb Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Sun, 7 Aug 2022 13:54:18 -0700 Subject: [PATCH] Make World own its own memory, along with distant disk lights. --- src/light/distant_disk_light.rs | 35 +++++++++++++-------------------- src/parse/psy.rs | 13 ++++++------ src/parse/psy_light.rs | 7 ++----- src/scene/mod.rs | 5 +++-- src/scene/world.rs | 6 +++--- 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/light/distant_disk_light.rs b/src/light/distant_disk_light.rs index 7553870..75e7d65 100644 --- a/src/light/distant_disk_light.rs +++ b/src/light/distant_disk_light.rs @@ -1,7 +1,5 @@ use std::f64::consts::PI as PI_64; -use kioku::Arena; - use crate::{ color::{Color, SpectralSample}, lerp::lerp_slice, @@ -13,24 +11,19 @@ use super::WorldLightSource; // TODO: handle case where radius = 0.0. -#[derive(Copy, Clone, Debug)] -pub struct DistantDiskLight<'a> { - radii: &'a [f32], - directions: &'a [Vector], - colors: &'a [Color], +#[derive(Debug, Clone)] +pub struct DistantDiskLight { + radii: Vec, + directions: Vec, + colors: Vec, } -impl<'a> DistantDiskLight<'a> { - pub fn new( - arena: &'a Arena, - radii: &[f32], - directions: &[Vector], - colors: &[Color], - ) -> DistantDiskLight<'a> { +impl DistantDiskLight { + pub fn new(radii: &[f32], directions: &[Vector], colors: &[Color]) -> DistantDiskLight { DistantDiskLight { - radii: arena.copy_slice(&radii), - directions: arena.copy_slice(&directions), - colors: arena.copy_slice(&colors), + radii: radii.into(), + directions: directions.into(), + colors: colors.into(), } } @@ -55,7 +48,7 @@ impl<'a> DistantDiskLight<'a> { // } } -impl<'a> WorldLightSource for DistantDiskLight<'a> { +impl WorldLightSource for DistantDiskLight { fn sample_from_point( &self, u: f32, @@ -64,9 +57,9 @@ impl<'a> WorldLightSource for DistantDiskLight<'a> { time: f32, ) -> (SpectralSample, Vector, f32) { // Calculate time interpolated values - let radius: f64 = lerp_slice(self.radii, time) as f64; - let direction = lerp_slice(self.directions, time); - let col = lerp_slice(self.colors, time); + let radius: f64 = lerp_slice(&self.radii, time) as f64; + let direction = lerp_slice(&self.directions, time); + let col = lerp_slice(&self.colors, time); let solid_angle_inv = 1.0 / (2.0 * PI_64 * (1.0 - radius.cos())); // Create a coordinate system from the vector pointing at the center of diff --git a/src/parse/psy.rs b/src/parse/psy.rs index f56c36b..95a202f 100644 --- a/src/parse/psy.rs +++ b/src/parse/psy.rs @@ -9,8 +9,7 @@ use kioku::Arena; use color::rec709_e_to_xyz; use crate::{ - camera::Camera, color::Color, light::WorldLightSource, math::Xform, renderer::Renderer, - scene::Scene, scene::World, + camera::Camera, color::Color, math::Xform, renderer::Renderer, scene::Scene, scene::World, }; use super::{ @@ -153,7 +152,7 @@ pub fn parse_scene<'a>( let camera = parse_camera(tree.iter_children_with_type("Camera").nth(0).unwrap())?; // Parse world - let world = parse_world(arena, tree.iter_children_with_type("World").nth(0).unwrap())?; + let world = parse_world(tree.iter_children_with_type("World").nth(0).unwrap())?; // Parse root scene assembly let assembly = parse_assembly( @@ -440,10 +439,10 @@ fn parse_camera<'a>(tree: &'a DataTree) -> Result { } } -fn parse_world<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result, PsyParseError> { +fn parse_world(tree: &DataTree) -> Result { if tree.is_internal() { let background_color; - let mut lights: Vec<&dyn WorldLightSource> = Vec::new(); + let mut lights: Vec<_> = Vec::new(); // Parse background shader let bgs = { @@ -519,7 +518,7 @@ fn parse_world<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result, Ps for child in tree.iter_children() { match *child { DataTree::Internal { type_name, .. } if type_name == "DistantDiskLight" => { - lights.push(arena.alloc(parse_distant_disk_light(arena, child)?)); + lights.push(parse_distant_disk_light(child)?); } _ => {} @@ -529,7 +528,7 @@ fn parse_world<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result, Ps // Build and return the world return Ok(World { background_color: background_color, - lights: arena.copy_slice(&lights), + lights: lights, }); } else { return Err(PsyParseError::ExpectedInternalNode( diff --git a/src/parse/psy_light.rs b/src/parse/psy_light.rs index 12e7fac..fd799da 100644 --- a/src/parse/psy_light.rs +++ b/src/parse/psy_light.rs @@ -17,10 +17,7 @@ use super::{ DataTree, }; -pub fn parse_distant_disk_light<'a>( - arena: &'a Arena, - tree: &'a DataTree, -) -> Result, PsyParseError> { +pub fn parse_distant_disk_light<'a>(tree: &'a DataTree) -> Result { if let DataTree::Internal { ref children, .. } = *tree { let mut radii = Vec::new(); let mut directions = Vec::new(); @@ -77,7 +74,7 @@ pub fn parse_distant_disk_light<'a>( } } - return Ok(DistantDiskLight::new(arena, &radii, &directions, &colors)); + return Ok(DistantDiskLight::new(&radii, &directions, &colors)); } else { return Err(PsyParseError::UnknownError(tree.byte_offset())); } diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 68064fc..06d9690 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -6,6 +6,7 @@ use crate::{ algorithm::weighted_choice, camera::Camera, color::SpectralSample, + light::WorldLightSource, math::{Normal, Point, Vector, XformFull}, surface::SurfaceIntersection, }; @@ -19,7 +20,7 @@ pub use self::{ pub struct Scene<'a> { pub name: Option, pub camera: Camera, - pub world: World<'a>, + pub world: World, pub root: Assembly<'a>, } @@ -67,7 +68,7 @@ impl<'a> Scene<'a> { if n < wl_prob { // World lights let n = n / wl_prob; - let (i, p) = weighted_choice(self.world.lights, n, |l| l.approximate_energy()); + let (i, p) = weighted_choice(&self.world.lights, n, |l| l.approximate_energy()); let (ss, sv, pdf) = self.world.lights[i].sample_from_point(uvw.0, uvw.1, wavelength, time); return SceneLightSample::Distant { diff --git a/src/scene/world.rs b/src/scene/world.rs index 3ef9331..43bbca5 100644 --- a/src/scene/world.rs +++ b/src/scene/world.rs @@ -1,7 +1,7 @@ -use crate::{color::Color, light::WorldLightSource}; +use crate::{color::Color, light::DistantDiskLight}; #[derive(Debug)] -pub struct World<'a> { +pub struct World { pub background_color: Color, - pub lights: &'a [&'a dyn WorldLightSource], + pub lights: Vec, }