diff --git a/src/assembly.rs b/src/assembly.rs index f6f1918..6708057 100644 --- a/src/assembly.rs +++ b/src/assembly.rs @@ -65,6 +65,7 @@ impl Assembly { InstanceType::Assembly => { // TODO: recursive light selection inside assemblies unimplemented!() + } } } else { diff --git a/src/main.rs b/src/main.rs index 64127ee..92cb5fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,6 +39,7 @@ mod sampling; mod hash; mod color; mod shading; +mod transform_stack; use std::mem; use std::io; diff --git a/src/tracer.rs b/src/tracer.rs index 1d8790b..5d171ce 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -1,12 +1,11 @@ use std::iter; -use std::cmp; -use algorithm::{partition, merge_slices_to}; -use math::Matrix4x4; +use algorithm::partition; use lerp::lerp_slice; use assembly::{Assembly, Object, InstanceType}; use ray::{Ray, AccelRay}; use surface::SurfaceIntersection; +use transform_stack::TransformStack; pub struct Tracer<'a> { rays: Vec, @@ -175,68 +174,3 @@ fn split_rays_by_direction(rays: &mut [AccelRay]) -> [&mut [AccelRay]; 8] { [rs0, rs1, rs2, rs3, rs4, rs5, rs6, rs7] } - - -struct TransformStack { - stack: Vec, - stack_indices: Vec, -} - -impl TransformStack { - fn new() -> TransformStack { - let mut ts = TransformStack { - stack: Vec::new(), - stack_indices: Vec::new(), - }; - - ts.stack_indices.push(0); - ts.stack_indices.push(0); - - ts - } - - fn push(&mut self, xforms: &[Matrix4x4]) { - assert!(xforms.len() > 0); - - if self.stack.len() == 0 { - self.stack.extend(xforms); - } else { - let sil = self.stack_indices.len(); - let i1 = self.stack_indices[sil - 2]; - let i2 = self.stack_indices[sil - 1]; - // Reserve stack space for the new transforms. - // Note this leaves exposed uninitialized memory. The subsequent call to - // merge_slices_to() fills that memory in. - { - let maxlen = cmp::max(xforms.len(), i2 - i1); - self.stack.reserve(maxlen); - let l = self.stack.len(); - unsafe { self.stack.set_len(l + maxlen) }; - } - let (xfs1, xfs2) = self.stack.split_at_mut(i2); - merge_slices_to(&xfs1[i1..i2], xforms, xfs2, |xf1, xf2| *xf1 * *xf2); - } - - self.stack_indices.push(self.stack.len()); - } - - fn pop(&mut self) { - assert!(self.stack_indices.len() > 1); - - let sl = self.stack.len(); - let sil = self.stack_indices.len(); - let i1 = self.stack_indices[sil - 2]; - let i2 = self.stack_indices[sil - 1]; - - self.stack.truncate(sl - (i2 - i1)); - self.stack_indices.pop(); - } - - fn top<'a>(&'a self) -> &'a [Matrix4x4] { - let sil = self.stack_indices.len(); - let i1 = self.stack_indices[sil - 2]; - let i2 = self.stack_indices[sil - 1]; - - &self.stack[i1..i2] - } -} diff --git a/src/transform_stack.rs b/src/transform_stack.rs new file mode 100644 index 0000000..1f0ec03 --- /dev/null +++ b/src/transform_stack.rs @@ -0,0 +1,75 @@ +use std::cmp; + +use math::Matrix4x4; +use algorithm::merge_slices_to; + +pub struct TransformStack { + stack: Vec, + stack_indices: Vec, +} + +impl TransformStack { + pub fn new() -> TransformStack { + let mut ts = TransformStack { + stack: Vec::new(), + stack_indices: Vec::new(), + }; + + ts.stack_indices.push(0); + ts.stack_indices.push(0); + + ts + } + + pub fn clear(&mut self) { + self.stack.clear(); + self.stack_indices.clear(); + self.stack_indices.push(0); + self.stack_indices.push(0); + } + + pub fn push(&mut self, xforms: &[Matrix4x4]) { + assert!(xforms.len() > 0); + + if self.stack.len() == 0 { + self.stack.extend(xforms); + } else { + let sil = self.stack_indices.len(); + let i1 = self.stack_indices[sil - 2]; + let i2 = self.stack_indices[sil - 1]; + // Reserve stack space for the new transforms. + // Note this leaves exposed uninitialized memory. The subsequent call to + // merge_slices_to() fills that memory in. + { + let maxlen = cmp::max(xforms.len(), i2 - i1); + self.stack.reserve(maxlen); + let l = self.stack.len(); + unsafe { self.stack.set_len(l + maxlen) }; + } + let (xfs1, xfs2) = self.stack.split_at_mut(i2); + merge_slices_to(&xfs1[i1..i2], xforms, xfs2, |xf1, xf2| *xf1 * *xf2); + } + + self.stack_indices.push(self.stack.len()); + } + + pub fn pop(&mut self) { + assert!(self.stack_indices.len() > 2); + + let sl = self.stack.len(); + let sil = self.stack_indices.len(); + let i1 = self.stack_indices[sil - 2]; + let i2 = self.stack_indices[sil - 1]; + + self.stack.truncate(sl - (i2 - i1)); + self.stack_indices.pop(); + } + + pub fn top<'a>(&'a self) -> &'a [Matrix4x4] { + let sil = self.stack_indices.len(); + let i1 = self.stack_indices[sil - 2]; + let i2 = self.stack_indices[sil - 1]; + + &self.stack[i1..i2] + } +}