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!
|
||||
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;
|
||||
|
||||
memory.as_mut().unwrap()
|
||||
|
@ -103,6 +105,8 @@ impl MemArena {
|
|||
/// Allocates memory for `len` values of type `T`, returning a mutable slice to it.
|
||||
/// All elements are initialized to the given `value`.
|
||||
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 alignment_padding = alignment_offset(size_of::<T>(), align_of::<T>());
|
||||
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
|
||||
/// memory after calling.
|
||||
unsafe fn alloc_raw(&self, size: usize, alignment: usize) -> *mut u8 {
|
||||
assert!(size > 0);
|
||||
assert!(alignment > 0);
|
||||
|
||||
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 size > self.large_alloc_threshold {
|
||||
else if size > self.large_alloc_threshold {
|
||||
blocks.push(Vec::with_capacity(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())?;
|
||||
|
||||
// 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
|
||||
let scene_name = if let &DataTree::Internal { ident, .. } = tree {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
use std::result::Result;
|
||||
|
||||
use mem_arena::MemArena;
|
||||
|
||||
use scene::{Assembly, AssemblyBuilder, Object};
|
||||
|
||||
use super::DataTree;
|
||||
|
@ -10,8 +12,10 @@ use super::psy_mesh_surface::parse_mesh_surface;
|
|||
use super::psy::{parse_matrix, PsyParseError};
|
||||
|
||||
|
||||
pub fn parse_assembly(tree: &DataTree) -> Result<Assembly, PsyParseError> {
|
||||
let mut builder = AssemblyBuilder::new();
|
||||
pub fn parse_assembly<'a>(arena: &'a MemArena,
|
||||
tree: &'a DataTree)
|
||||
-> Result<Assembly<'a>, PsyParseError> {
|
||||
let mut builder = AssemblyBuilder::new(arena);
|
||||
|
||||
if tree.is_internal() {
|
||||
for child in tree.iter_children() {
|
||||
|
@ -19,7 +23,7 @@ pub fn parse_assembly(tree: &DataTree) -> Result<Assembly, PsyParseError> {
|
|||
// Sub-Assembly
|
||||
"Assembly" => {
|
||||
if let &DataTree::Internal { ident: Some(ident), .. } = child {
|
||||
builder.add_assembly(ident, parse_assembly(&child)?);
|
||||
builder.add_assembly(ident, parse_assembly(arena, &child)?);
|
||||
} else {
|
||||
// TODO: error condition of some kind, because no ident
|
||||
panic!();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use mem_arena::MemArena;
|
||||
|
||||
use accel::{LightAccel, LightTree};
|
||||
use accel::BVH;
|
||||
use bbox::{BBox, transform_bbox_slice_from};
|
||||
|
@ -13,17 +15,17 @@ use transform_stack::TransformStack;
|
|||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Assembly {
|
||||
pub struct Assembly<'a> {
|
||||
// Instance list
|
||||
pub instances: Vec<Instance>,
|
||||
pub light_instances: Vec<Instance>,
|
||||
pub xforms: Vec<Matrix4x4>,
|
||||
pub instances: &'a [Instance],
|
||||
pub light_instances: &'a [Instance],
|
||||
pub xforms: &'a [Matrix4x4],
|
||||
|
||||
// Object list
|
||||
pub objects: Vec<Object>,
|
||||
|
||||
// Assembly list
|
||||
pub assemblies: Vec<Assembly>,
|
||||
pub assemblies: Vec<Assembly<'a>>,
|
||||
|
||||
// Object accel
|
||||
pub object_accel: BVH,
|
||||
|
@ -32,7 +34,7 @@ pub struct Assembly {
|
|||
pub light_accel: LightTree,
|
||||
}
|
||||
|
||||
impl Assembly {
|
||||
impl<'a> Assembly<'a> {
|
||||
// Returns (light_color, shadow_vector, pdf, selection_pdf)
|
||||
pub fn sample_lights(&self,
|
||||
xform_stack: &mut TransformStack,
|
||||
|
@ -119,15 +121,17 @@ impl Assembly {
|
|||
}
|
||||
}
|
||||
|
||||
impl Boundable for Assembly {
|
||||
fn bounds<'a>(&'a self) -> &'a [BBox] {
|
||||
impl<'a> Boundable for Assembly<'a> {
|
||||
fn bounds<'b>(&'b self) -> &'b [BBox] {
|
||||
self.object_accel.bounds()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssemblyBuilder {
|
||||
pub struct AssemblyBuilder<'a> {
|
||||
arena: &'a MemArena,
|
||||
|
||||
// Instance list
|
||||
instances: Vec<Instance>,
|
||||
xforms: Vec<Matrix4x4>,
|
||||
|
@ -137,14 +141,15 @@ pub struct AssemblyBuilder {
|
|||
object_map: HashMap<String, usize>, // map Name -> Index
|
||||
|
||||
// Assembly list
|
||||
assemblies: Vec<Assembly>,
|
||||
assemblies: Vec<Assembly<'a>>,
|
||||
assembly_map: HashMap<String, usize>, // map Name -> Index
|
||||
}
|
||||
|
||||
|
||||
impl AssemblyBuilder {
|
||||
pub fn new() -> AssemblyBuilder {
|
||||
impl<'a> AssemblyBuilder<'a> {
|
||||
pub fn new(arena: &'a MemArena) -> AssemblyBuilder<'a> {
|
||||
AssemblyBuilder {
|
||||
arena: arena,
|
||||
instances: Vec::new(),
|
||||
xforms: Vec::new(),
|
||||
objects: Vec::new(),
|
||||
|
@ -165,7 +170,7 @@ impl AssemblyBuilder {
|
|||
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.
|
||||
if self.name_exists(name) {
|
||||
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)
|
||||
}
|
||||
|
||||
pub fn build(mut self) -> Assembly {
|
||||
// Shrink storage to minimum.
|
||||
self.instances.shrink_to_fit();
|
||||
self.xforms.shrink_to_fit();
|
||||
self.objects.shrink_to_fit();
|
||||
self.assemblies.shrink_to_fit();
|
||||
|
||||
pub fn build(mut self) -> Assembly<'a> {
|
||||
// Calculate instance bounds, used for building object accel and light accel.
|
||||
let (bis, bbs) = self.instance_bounds();
|
||||
|
||||
|
@ -276,9 +275,9 @@ impl AssemblyBuilder {
|
|||
});
|
||||
|
||||
Assembly {
|
||||
instances: self.instances,
|
||||
light_instances: light_instances,
|
||||
xforms: self.xforms,
|
||||
instances: self.arena.copy_slice(&self.instances),
|
||||
light_instances: self.arena.copy_slice(&light_instances),
|
||||
xforms: self.arena.copy_slice(&self.xforms),
|
||||
objects: self.objects,
|
||||
assemblies: self.assemblies,
|
||||
object_accel: object_accel,
|
||||
|
|
|
@ -15,7 +15,7 @@ pub struct Scene<'a> {
|
|||
pub name: Option<String>,
|
||||
pub camera: Camera<'a>,
|
||||
pub world: World<'a>,
|
||||
pub root: Assembly,
|
||||
pub root: Assembly<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Scene<'a> {
|
||||
|
|
|
@ -36,7 +36,7 @@ impl<'a> Tracer<'a> {
|
|||
}
|
||||
|
||||
struct TracerInner<'a> {
|
||||
root: &'a Assembly,
|
||||
root: &'a Assembly<'a>,
|
||||
xform_stack: TransformStack,
|
||||
isects: Vec<SurfaceIntersection>,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user