Assembly type now partially uses MemArena.
This commit is contained in:
parent
fc15fa9192
commit
e9e202933f
|
@ -71,6 +71,8 @@ impl MemArena {
|
||||||
///
|
///
|
||||||
/// CAUTION: the memory returned is uninitialized. Make sure to initalize before using!
|
/// CAUTION: the memory returned is uninitialized. Make sure to initalize before using!
|
||||||
pub unsafe fn alloc_uninitialized<'a, T: Copy>(&'a self) -> &'a mut T {
|
pub unsafe fn alloc_uninitialized<'a, T: Copy>(&'a self) -> &'a mut T {
|
||||||
|
assert!(size_of::<T>() > 0);
|
||||||
|
|
||||||
let memory = self.alloc_raw(size_of::<T>(), align_of::<T>()) as *mut T;
|
let memory = self.alloc_raw(size_of::<T>(), align_of::<T>()) as *mut T;
|
||||||
|
|
||||||
memory.as_mut().unwrap()
|
memory.as_mut().unwrap()
|
||||||
|
@ -103,6 +105,8 @@ impl MemArena {
|
||||||
/// Allocates memory for `len` values of type `T`, returning a mutable slice to it.
|
/// Allocates memory for `len` values of type `T`, returning a mutable slice to it.
|
||||||
/// All elements are initialized to the given `value`.
|
/// All elements are initialized to the given `value`.
|
||||||
pub unsafe fn alloc_array_uninitialized<'a, T: Copy>(&'a self, len: usize) -> &'a mut [T] {
|
pub unsafe fn alloc_array_uninitialized<'a, T: Copy>(&'a self, len: usize) -> &'a mut [T] {
|
||||||
|
assert!(size_of::<T>() > 0);
|
||||||
|
|
||||||
let array_mem_size = {
|
let array_mem_size = {
|
||||||
let alignment_padding = alignment_offset(size_of::<T>(), align_of::<T>());
|
let alignment_padding = alignment_offset(size_of::<T>(), align_of::<T>());
|
||||||
let aligned_type_size = size_of::<T>() + alignment_padding;
|
let aligned_type_size = size_of::<T>() + alignment_padding;
|
||||||
|
@ -119,13 +123,17 @@ impl MemArena {
|
||||||
/// CAUTION: this returns uninitialized memory. Make sure to initialize the
|
/// CAUTION: this returns uninitialized memory. Make sure to initialize the
|
||||||
/// memory after calling.
|
/// memory after calling.
|
||||||
unsafe fn alloc_raw(&self, size: usize, alignment: usize) -> *mut u8 {
|
unsafe fn alloc_raw(&self, size: usize, alignment: usize) -> *mut u8 {
|
||||||
assert!(size > 0);
|
|
||||||
assert!(alignment > 0);
|
assert!(alignment > 0);
|
||||||
|
|
||||||
let mut blocks = self.blocks.borrow_mut();
|
let mut blocks = self.blocks.borrow_mut();
|
||||||
|
|
||||||
|
|
||||||
|
// If it's a zero-size allocation, just point to the beginning of the curent block.
|
||||||
|
if size == 0 {
|
||||||
|
return blocks.first_mut().unwrap().as_mut_ptr();
|
||||||
|
}
|
||||||
// If the desired size is considered a "large allocation", give it its own memory block.
|
// If the desired size is considered a "large allocation", give it its own memory block.
|
||||||
if size > self.large_alloc_threshold {
|
else if size > self.large_alloc_threshold {
|
||||||
blocks.push(Vec::with_capacity(size + alignment - 1));
|
blocks.push(Vec::with_capacity(size + alignment - 1));
|
||||||
blocks.last_mut().unwrap().set_len(size + alignment - 1);
|
blocks.last_mut().unwrap().set_len(size + alignment - 1);
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,8 @@ pub fn parse_scene<'a>(arena: &'a MemArena,
|
||||||
let world = parse_world(arena, 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(arena,
|
||||||
|
tree.iter_children_with_type("Assembly").nth(0).unwrap())?;
|
||||||
|
|
||||||
// Put scene together
|
// Put scene together
|
||||||
let scene_name = if let &DataTree::Internal { ident, .. } = tree {
|
let scene_name = if let &DataTree::Internal { ident, .. } = tree {
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
|
|
||||||
|
use mem_arena::MemArena;
|
||||||
|
|
||||||
use scene::{Assembly, AssemblyBuilder, Object};
|
use scene::{Assembly, AssemblyBuilder, Object};
|
||||||
|
|
||||||
use super::DataTree;
|
use super::DataTree;
|
||||||
|
@ -10,8 +12,10 @@ use super::psy_mesh_surface::parse_mesh_surface;
|
||||||
use super::psy::{parse_matrix, PsyParseError};
|
use super::psy::{parse_matrix, PsyParseError};
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_assembly(tree: &DataTree) -> Result<Assembly, PsyParseError> {
|
pub fn parse_assembly<'a>(arena: &'a MemArena,
|
||||||
let mut builder = AssemblyBuilder::new();
|
tree: &'a DataTree)
|
||||||
|
-> Result<Assembly<'a>, PsyParseError> {
|
||||||
|
let mut builder = AssemblyBuilder::new(arena);
|
||||||
|
|
||||||
if tree.is_internal() {
|
if tree.is_internal() {
|
||||||
for child in tree.iter_children() {
|
for child in tree.iter_children() {
|
||||||
|
@ -19,7 +23,7 @@ pub fn parse_assembly(tree: &DataTree) -> Result<Assembly, PsyParseError> {
|
||||||
// Sub-Assembly
|
// Sub-Assembly
|
||||||
"Assembly" => {
|
"Assembly" => {
|
||||||
if let &DataTree::Internal { ident: Some(ident), .. } = child {
|
if let &DataTree::Internal { ident: Some(ident), .. } = child {
|
||||||
builder.add_assembly(ident, parse_assembly(&child)?);
|
builder.add_assembly(ident, parse_assembly(arena, &child)?);
|
||||||
} else {
|
} else {
|
||||||
// TODO: error condition of some kind, because no ident
|
// TODO: error condition of some kind, because no ident
|
||||||
panic!();
|
panic!();
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use mem_arena::MemArena;
|
||||||
|
|
||||||
use accel::{LightAccel, LightTree};
|
use accel::{LightAccel, LightTree};
|
||||||
use accel::BVH;
|
use accel::BVH;
|
||||||
use bbox::{BBox, transform_bbox_slice_from};
|
use bbox::{BBox, transform_bbox_slice_from};
|
||||||
|
@ -13,17 +15,17 @@ use transform_stack::TransformStack;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Assembly {
|
pub struct Assembly<'a> {
|
||||||
// Instance list
|
// Instance list
|
||||||
pub instances: Vec<Instance>,
|
pub instances: &'a [Instance],
|
||||||
pub light_instances: Vec<Instance>,
|
pub light_instances: &'a [Instance],
|
||||||
pub xforms: Vec<Matrix4x4>,
|
pub xforms: &'a [Matrix4x4],
|
||||||
|
|
||||||
// Object list
|
// Object list
|
||||||
pub objects: Vec<Object>,
|
pub objects: Vec<Object>,
|
||||||
|
|
||||||
// Assembly list
|
// Assembly list
|
||||||
pub assemblies: Vec<Assembly>,
|
pub assemblies: Vec<Assembly<'a>>,
|
||||||
|
|
||||||
// Object accel
|
// Object accel
|
||||||
pub object_accel: BVH,
|
pub object_accel: BVH,
|
||||||
|
@ -32,7 +34,7 @@ pub struct Assembly {
|
||||||
pub light_accel: LightTree,
|
pub light_accel: LightTree,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Assembly {
|
impl<'a> Assembly<'a> {
|
||||||
// Returns (light_color, shadow_vector, pdf, selection_pdf)
|
// Returns (light_color, shadow_vector, pdf, selection_pdf)
|
||||||
pub fn sample_lights(&self,
|
pub fn sample_lights(&self,
|
||||||
xform_stack: &mut TransformStack,
|
xform_stack: &mut TransformStack,
|
||||||
|
@ -119,15 +121,17 @@ impl Assembly {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Boundable for Assembly {
|
impl<'a> Boundable for Assembly<'a> {
|
||||||
fn bounds<'a>(&'a self) -> &'a [BBox] {
|
fn bounds<'b>(&'b self) -> &'b [BBox] {
|
||||||
self.object_accel.bounds()
|
self.object_accel.bounds()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AssemblyBuilder {
|
pub struct AssemblyBuilder<'a> {
|
||||||
|
arena: &'a MemArena,
|
||||||
|
|
||||||
// Instance list
|
// Instance list
|
||||||
instances: Vec<Instance>,
|
instances: Vec<Instance>,
|
||||||
xforms: Vec<Matrix4x4>,
|
xforms: Vec<Matrix4x4>,
|
||||||
|
@ -137,14 +141,15 @@ pub struct AssemblyBuilder {
|
||||||
object_map: HashMap<String, usize>, // map Name -> Index
|
object_map: HashMap<String, usize>, // map Name -> Index
|
||||||
|
|
||||||
// Assembly list
|
// Assembly list
|
||||||
assemblies: Vec<Assembly>,
|
assemblies: Vec<Assembly<'a>>,
|
||||||
assembly_map: HashMap<String, usize>, // map Name -> Index
|
assembly_map: HashMap<String, usize>, // map Name -> Index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl AssemblyBuilder {
|
impl<'a> AssemblyBuilder<'a> {
|
||||||
pub fn new() -> AssemblyBuilder {
|
pub fn new(arena: &'a MemArena) -> AssemblyBuilder<'a> {
|
||||||
AssemblyBuilder {
|
AssemblyBuilder {
|
||||||
|
arena: arena,
|
||||||
instances: Vec::new(),
|
instances: Vec::new(),
|
||||||
xforms: Vec::new(),
|
xforms: Vec::new(),
|
||||||
objects: Vec::new(),
|
objects: Vec::new(),
|
||||||
|
@ -165,7 +170,7 @@ impl AssemblyBuilder {
|
||||||
self.objects.push(obj);
|
self.objects.push(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_assembly(&mut self, name: &str, asmb: Assembly) {
|
pub fn add_assembly(&mut self, name: &str, asmb: Assembly<'a>) {
|
||||||
// Make sure the name hasn't already been used.
|
// Make sure the name hasn't already been used.
|
||||||
if self.name_exists(name) {
|
if self.name_exists(name) {
|
||||||
panic!("Attempted to add assembly to another assembly with a name that already \
|
panic!("Attempted to add assembly to another assembly with a name that already \
|
||||||
|
@ -221,13 +226,7 @@ impl AssemblyBuilder {
|
||||||
self.object_map.contains_key(name) || self.assembly_map.contains_key(name)
|
self.object_map.contains_key(name) || self.assembly_map.contains_key(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(mut self) -> Assembly {
|
pub fn build(mut self) -> Assembly<'a> {
|
||||||
// Shrink storage to minimum.
|
|
||||||
self.instances.shrink_to_fit();
|
|
||||||
self.xforms.shrink_to_fit();
|
|
||||||
self.objects.shrink_to_fit();
|
|
||||||
self.assemblies.shrink_to_fit();
|
|
||||||
|
|
||||||
// Calculate instance bounds, used for building object accel and light accel.
|
// Calculate instance bounds, used for building object accel and light accel.
|
||||||
let (bis, bbs) = self.instance_bounds();
|
let (bis, bbs) = self.instance_bounds();
|
||||||
|
|
||||||
|
@ -276,9 +275,9 @@ impl AssemblyBuilder {
|
||||||
});
|
});
|
||||||
|
|
||||||
Assembly {
|
Assembly {
|
||||||
instances: self.instances,
|
instances: self.arena.copy_slice(&self.instances),
|
||||||
light_instances: light_instances,
|
light_instances: self.arena.copy_slice(&light_instances),
|
||||||
xforms: self.xforms,
|
xforms: self.arena.copy_slice(&self.xforms),
|
||||||
objects: self.objects,
|
objects: self.objects,
|
||||||
assemblies: self.assemblies,
|
assemblies: self.assemblies,
|
||||||
object_accel: object_accel,
|
object_accel: object_accel,
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub struct Scene<'a> {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub camera: Camera<'a>,
|
pub camera: Camera<'a>,
|
||||||
pub world: World<'a>,
|
pub world: World<'a>,
|
||||||
pub root: Assembly,
|
pub root: Assembly<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Scene<'a> {
|
impl<'a> Scene<'a> {
|
||||||
|
|
|
@ -36,7 +36,7 @@ impl<'a> Tracer<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TracerInner<'a> {
|
struct TracerInner<'a> {
|
||||||
root: &'a Assembly,
|
root: &'a Assembly<'a>,
|
||||||
xform_stack: TransformStack,
|
xform_stack: TransformStack,
|
||||||
isects: Vec<SurfaceIntersection>,
|
isects: Vec<SurfaceIntersection>,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user