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> {
pub fn new(arena: &'a mut MemArena,
pub fn new(arena: &'a MemArena,
transforms: Vec<Matrix4x4>,
fovs: Vec<f32>,
mut aperture_radii: Vec<f32>,

View File

@ -1,5 +1,7 @@
use std::f64::consts::PI as PI_64;
use mem_arena::MemArena;
use color::{XYZ, SpectralSample, Color};
use lerp::lerp_slice;
use math::{Vector, coordinate_system_from_vector};
@ -9,24 +11,28 @@ use super::WorldLightSource;
// TODO: handle case where radius = 0.0.
#[derive(Debug)]
pub struct DistantDiskLight {
radii: Vec<f32>,
directions: Vec<Vector>,
colors: Vec<XYZ>,
#[derive(Copy, Clone, Debug)]
pub struct DistantDiskLight<'a> {
radii: &'a [f32],
directions: &'a [Vector],
colors: &'a [XYZ],
}
impl DistantDiskLight {
pub fn new(radii: Vec<f32>, directions: Vec<Vector>, colors: Vec<XYZ>) -> DistantDiskLight {
impl<'a> DistantDiskLight<'a> {
pub fn new(arena: &'a MemArena,
radii: Vec<f32>,
directions: Vec<Vector>,
colors: Vec<XYZ>)
-> DistantDiskLight<'a> {
DistantDiskLight {
radii: radii,
directions: directions,
colors: colors,
radii: arena.copy_slice(&radii),
directions: arena.copy_slice(&directions),
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) {
// Calculate time interpolated values
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
pub fn parse_scene<'a>(arena: &'a mut MemArena,
pub fn parse_scene<'a>(arena: &'a MemArena,
tree: &'a DataTree)
-> Result<Renderer<'a>, PsyParseError> {
// 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())?;
// 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
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,
tree: &'a DataTree)
-> Result<Camera<'a>, PsyParseError> {
fn parse_camera<'a>(arena: &'a MemArena, tree: &'a DataTree) -> Result<Camera<'a>, PsyParseError> {
if let &DataTree::Internal { ref children, .. } = tree {
let mut mats = 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() {
let background_color;
let mut lights: Vec<Box<WorldLightSource>> = Vec::new();
let mut lights: Vec<&WorldLightSource> = Vec::new();
// Parse background shader
let bgs = {
@ -326,7 +324,7 @@ fn parse_world(tree: &DataTree) -> Result<World, PsyParseError> {
for child in tree.iter_children() {
match child {
&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
return Ok(World {
background_color: background_color,
lights: lights,
lights: arena.copy_slice(&lights),
});
} else {
return Err(PsyParseError::UnknownError);

View File

@ -4,6 +4,8 @@ use std::result::Result;
use nom::IResult;
use mem_arena::MemArena;
use math::Vector;
use color::{XYZ, rec709e_to_xyz};
use light::{DistantDiskLight, SphereLight, RectangleLight};
@ -13,7 +15,9 @@ use super::DataTree;
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 {
let mut radii = 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 {
return Err(PsyParseError::UnknownError);
}

View File

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

View File

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