World type uses memory arena now.

This commit is contained in:
Nathan Vegdahl 2017-04-09 17:56:06 -07:00
parent 57aa9be496
commit fc15fa9192
6 changed files with 34 additions and 28 deletions

View File

@ -18,7 +18,7 @@ pub struct Camera<'a> {
} }
impl<'a> Camera<'a> { impl<'a> Camera<'a> {
pub fn new(arena: &'a mut MemArena, pub fn new(arena: &'a MemArena,
transforms: Vec<Matrix4x4>, transforms: Vec<Matrix4x4>,
fovs: Vec<f32>, fovs: Vec<f32>,
mut aperture_radii: Vec<f32>, mut aperture_radii: Vec<f32>,

View File

@ -1,5 +1,7 @@
use std::f64::consts::PI as PI_64; use std::f64::consts::PI as PI_64;
use mem_arena::MemArena;
use color::{XYZ, SpectralSample, Color}; use color::{XYZ, SpectralSample, Color};
use lerp::lerp_slice; use lerp::lerp_slice;
use math::{Vector, coordinate_system_from_vector}; use math::{Vector, coordinate_system_from_vector};
@ -9,24 +11,28 @@ use super::WorldLightSource;
// TODO: handle case where radius = 0.0. // TODO: handle case where radius = 0.0.
#[derive(Debug)] #[derive(Copy, Clone, Debug)]
pub struct DistantDiskLight { pub struct DistantDiskLight<'a> {
radii: Vec<f32>, radii: &'a [f32],
directions: Vec<Vector>, directions: &'a [Vector],
colors: Vec<XYZ>, colors: &'a [XYZ],
} }
impl DistantDiskLight { impl<'a> DistantDiskLight<'a> {
pub fn new(radii: Vec<f32>, directions: Vec<Vector>, colors: Vec<XYZ>) -> DistantDiskLight { pub fn new(arena: &'a MemArena,
radii: Vec<f32>,
directions: Vec<Vector>,
colors: Vec<XYZ>)
-> DistantDiskLight<'a> {
DistantDiskLight { DistantDiskLight {
radii: radii, radii: arena.copy_slice(&radii),
directions: directions, directions: arena.copy_slice(&directions),
colors: colors, colors: arena.copy_slice(&colors),
} }
} }
} }
impl WorldLightSource for DistantDiskLight { impl<'a> WorldLightSource for DistantDiskLight<'a> {
fn sample(&self, u: f32, v: f32, wavelength: f32, time: f32) -> (SpectralSample, Vector, f32) { fn sample(&self, u: f32, v: f32, wavelength: f32, time: f32) -> (SpectralSample, Vector, f32) {
// Calculate time interpolated values // Calculate time interpolated values
let radius: f64 = lerp_slice(&self.radii, time) as f64; let radius: f64 = lerp_slice(&self.radii, time) as f64;

View File

@ -29,7 +29,7 @@ pub enum PsyParseError {
/// Takes in a DataTree representing a Scene node and returns /// Takes in a DataTree representing a Scene node and returns
pub fn parse_scene<'a>(arena: &'a mut MemArena, pub fn parse_scene<'a>(arena: &'a MemArena,
tree: &'a DataTree) tree: &'a DataTree)
-> Result<Renderer<'a>, PsyParseError> { -> Result<Renderer<'a>, PsyParseError> {
// Verify we have the right number of each section // Verify we have the right number of each section
@ -69,7 +69,7 @@ pub fn parse_scene<'a>(arena: &'a mut MemArena,
tree.iter_children_with_type("Camera").nth(0).unwrap())?; tree.iter_children_with_type("Camera").nth(0).unwrap())?;
// Parse world // Parse world
let world = parse_world(tree.iter_children_with_type("World").nth(0).unwrap())?; let world = parse_world(arena, tree.iter_children_with_type("World").nth(0).unwrap())?;
// Parse root scene assembly // Parse root scene assembly
let assembly = parse_assembly(tree.iter_children_with_type("Assembly").nth(0).unwrap())?; let assembly = parse_assembly(tree.iter_children_with_type("Assembly").nth(0).unwrap())?;
@ -210,9 +210,7 @@ fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyP
fn parse_camera<'a>(arena: &'a mut MemArena, fn parse_camera<'a>(arena: &'a MemArena, tree: &'a DataTree) -> Result<Camera<'a>, PsyParseError> {
tree: &'a DataTree)
-> Result<Camera<'a>, PsyParseError> {
if let &DataTree::Internal { ref children, .. } = tree { if let &DataTree::Internal { ref children, .. } = tree {
let mut mats = Vec::new(); let mut mats = Vec::new();
let mut fovs = Vec::new(); let mut fovs = Vec::new();
@ -275,10 +273,10 @@ fn parse_camera<'a>(arena: &'a mut MemArena,
fn parse_world(tree: &DataTree) -> Result<World, PsyParseError> { fn parse_world<'a>(arena: &'a MemArena, tree: &'a DataTree) -> Result<World<'a>, PsyParseError> {
if tree.is_internal() { if tree.is_internal() {
let background_color; let background_color;
let mut lights: Vec<Box<WorldLightSource>> = Vec::new(); let mut lights: Vec<&WorldLightSource> = Vec::new();
// Parse background shader // Parse background shader
let bgs = { let bgs = {
@ -326,7 +324,7 @@ fn parse_world(tree: &DataTree) -> Result<World, PsyParseError> {
for child in tree.iter_children() { for child in tree.iter_children() {
match child { match child {
&DataTree::Internal { type_name, .. } if type_name == "DistantDiskLight" => { &DataTree::Internal { type_name, .. } if type_name == "DistantDiskLight" => {
lights.push(Box::new(parse_distant_disk_light(&child)?)); lights.push(arena.alloc(parse_distant_disk_light(arena, &child)?));
} }
_ => {} _ => {}
@ -336,7 +334,7 @@ fn parse_world(tree: &DataTree) -> Result<World, PsyParseError> {
// Build and return the world // Build and return the world
return Ok(World { return Ok(World {
background_color: background_color, background_color: background_color,
lights: lights, lights: arena.copy_slice(&lights),
}); });
} else { } else {
return Err(PsyParseError::UnknownError); return Err(PsyParseError::UnknownError);

View File

@ -4,6 +4,8 @@ use std::result::Result;
use nom::IResult; use nom::IResult;
use mem_arena::MemArena;
use math::Vector; use math::Vector;
use color::{XYZ, rec709e_to_xyz}; use color::{XYZ, rec709e_to_xyz};
use light::{DistantDiskLight, SphereLight, RectangleLight}; use light::{DistantDiskLight, SphereLight, RectangleLight};
@ -13,7 +15,9 @@ use super::DataTree;
use super::psy::PsyParseError; use super::psy::PsyParseError;
pub fn parse_distant_disk_light(tree: &DataTree) -> Result<DistantDiskLight, PsyParseError> { pub fn parse_distant_disk_light<'a>(arena: &'a MemArena,
tree: &'a DataTree)
-> Result<DistantDiskLight<'a>, PsyParseError> {
if let &DataTree::Internal { ref children, .. } = tree { if let &DataTree::Internal { ref children, .. } = tree {
let mut radii = Vec::new(); let mut radii = Vec::new();
let mut directions = Vec::new(); let mut directions = Vec::new();
@ -61,7 +65,7 @@ pub fn parse_distant_disk_light(tree: &DataTree) -> Result<DistantDiskLight, Psy
} }
} }
return Ok(DistantDiskLight::new(radii, directions, colors)); return Ok(DistantDiskLight::new(arena, radii, directions, colors));
} else { } else {
return Err(PsyParseError::UnknownError); return Err(PsyParseError::UnknownError);
} }

View File

@ -1,5 +1,3 @@
use mem_arena::MemArena;
use accel::LightAccel; use accel::LightAccel;
use algorithm::weighted_choice; use algorithm::weighted_choice;
use camera::Camera; use camera::Camera;
@ -16,7 +14,7 @@ use super::World;
pub struct Scene<'a> { pub struct Scene<'a> {
pub name: Option<String>, pub name: Option<String>,
pub camera: Camera<'a>, pub camera: Camera<'a>,
pub world: World, pub world: World<'a>,
pub root: Assembly, pub root: Assembly,
} }

View File

@ -2,7 +2,7 @@ use color::XYZ;
use light::WorldLightSource; use light::WorldLightSource;
#[derive(Debug)] #[derive(Debug)]
pub struct World { pub struct World<'a> {
pub background_color: XYZ, pub background_color: XYZ,
pub lights: Vec<Box<WorldLightSource>>, pub lights: &'a [&'a WorldLightSource],
} }