First steps towards using the memory arena allocator.

Changed Camera to us the memory arena allocator, and worked out a
bunch of stuff through doing that.
This commit is contained in:
Nathan Vegdahl 2017-04-09 17:31:17 -07:00
parent a8bea5c09d
commit 57aa9be496
6 changed files with 46 additions and 28 deletions

View File

@ -1,26 +1,29 @@
#![allow(dead_code)]
use mem_arena::MemArena;
use lerp::lerp_slice;
use math::{Vector, Point, Matrix4x4};
use ray::Ray;
use sampling::square_to_circle;
#[derive(Debug)]
pub struct Camera {
transforms: Vec<Matrix4x4>,
fovs: Vec<f32>,
tfovs: Vec<f32>,
aperture_radii: Vec<f32>,
focus_distances: Vec<f32>,
#[derive(Copy, Clone, Debug)]
pub struct Camera<'a> {
transforms: &'a [Matrix4x4],
fovs: &'a [f32],
tfovs: &'a [f32],
aperture_radii: &'a [f32],
focus_distances: &'a [f32],
}
impl Camera {
pub fn new(transforms: Vec<Matrix4x4>,
impl<'a> Camera<'a> {
pub fn new(arena: &'a mut MemArena,
transforms: Vec<Matrix4x4>,
fovs: Vec<f32>,
mut aperture_radii: Vec<f32>,
mut focus_distances: Vec<f32>)
-> Camera {
-> Camera<'a> {
assert!(transforms.len() != 0, "Camera has no transform(s)!");
assert!(fovs.len() != 0, "Camera has no fov(s)!");
@ -48,14 +51,14 @@ impl Camera {
}
// Convert angle fov into linear fov.
let tfovs = fovs.iter().map(|n| (n / 2.0).sin() / (n / 2.0).cos()).collect();
let tfovs: Vec<f32> = fovs.iter().map(|n| (n / 2.0).sin() / (n / 2.0).cos()).collect();
Camera {
transforms: transforms,
fovs: fovs,
tfovs: tfovs,
aperture_radii: aperture_radii,
focus_distances: focus_distances,
transforms: arena.copy_slice(&transforms),
fovs: arena.copy_slice(&fovs),
tfovs: arena.copy_slice(&tfovs),
aperture_radii: arena.copy_slice(&aperture_radii),
focus_distances: arena.copy_slice(&focus_distances),
}
}

View File

@ -1,3 +1,5 @@
extern crate mem_arena;
extern crate crossbeam;
extern crate docopt;
extern crate lodepng;
@ -45,6 +47,8 @@ use std::path::Path;
use docopt::Docopt;
use mem_arena::MemArena;
use parse::{parse_scene, DataTree};
use ray::{Ray, AccelRay};
use renderer::LightPath;
@ -131,7 +135,9 @@ fn main() {
t.tick();
if child.type_name() == "Scene" {
println!("Building scene...");
let mut r = parse_scene(child).unwrap();
let mut arena = MemArena::new();
let mut r = parse_scene(&mut arena, child).unwrap();
if let Some(spp) = args.flag_spp {
println!("\tOverriding scene spp: {}", spp);

View File

@ -5,6 +5,8 @@ use std::result::Result;
use nom;
use nom::IResult;
use mem_arena::MemArena;
use camera::Camera;
use color::{XYZ, rec709e_to_xyz};
use light::WorldLightSource;
@ -27,7 +29,9 @@ pub enum PsyParseError {
/// Takes in a DataTree representing a Scene node and returns
pub fn parse_scene(tree: &DataTree) -> Result<Renderer, PsyParseError> {
pub fn parse_scene<'a>(arena: &'a mut MemArena,
tree: &'a DataTree)
-> Result<Renderer<'a>, PsyParseError> {
// Verify we have the right number of each section
if tree.iter_children_with_type("Output").count() != 1 {
let count = tree.iter_children_with_type("Output").count();
@ -61,7 +65,8 @@ pub fn parse_scene(tree: &DataTree) -> Result<Renderer, PsyParseError> {
.unwrap())?;
// Parse camera
let camera = parse_camera(tree.iter_children_with_type("Camera").nth(0).unwrap())?;
let camera = parse_camera(arena,
tree.iter_children_with_type("Camera").nth(0).unwrap())?;
// Parse world
let world = parse_world(tree.iter_children_with_type("World").nth(0).unwrap())?;
@ -205,7 +210,9 @@ fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyP
fn parse_camera(tree: &DataTree) -> Result<Camera, PsyParseError> {
fn parse_camera<'a>(arena: &'a mut 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();
@ -259,7 +266,7 @@ fn parse_camera(tree: &DataTree) -> Result<Camera, PsyParseError> {
}
}
return Ok(Camera::new(mats, fovs, aperture_radii, focus_distances));
return Ok(Camera::new(arena, mats, fovs, aperture_radii, focus_distances));
} else {
return Err(PsyParseError::UnknownError);
}

View File

@ -96,7 +96,7 @@ pub fn parse_assembly(tree: &DataTree) -> Result<Assembly, PsyParseError> {
"SurfaceShader" => {
if let &DataTree::Internal { ident: Some(ident), .. } = child {
// TODO
unimplemented!()
//unimplemented!()
} else {
// TODO: error condition of some kind, because no ident
panic!();

View File

@ -23,15 +23,15 @@ use transform_stack::TransformStack;
#[derive(Debug)]
pub struct Renderer {
pub struct Renderer<'a> {
pub output_file: String,
pub resolution: (usize, usize),
pub spp: usize,
pub seed: u32,
pub scene: Scene,
pub scene: Scene<'a>,
}
impl Renderer {
impl<'a> Renderer<'a> {
pub fn render(&self, max_samples_per_bucket: u32, thread_count: u32) -> Image {
let mut tpool = Pool::new(thread_count);

View File

@ -1,3 +1,5 @@
use mem_arena::MemArena;
use accel::LightAccel;
use algorithm::weighted_choice;
use camera::Camera;
@ -11,14 +13,14 @@ use super::World;
#[derive(Debug)]
pub struct Scene {
pub struct Scene<'a> {
pub name: Option<String>,
pub camera: Camera,
pub camera: Camera<'a>,
pub world: World,
pub root: Assembly,
}
impl Scene {
impl<'a> Scene<'a> {
pub fn sample_lights(&self,
xform_stack: &mut TransformStack,
n: f32,