Bunch of code quality improvements based on running clippy.
None of them change behavior, just make the code cleaner.
This commit is contained in:
parent
3cb684514a
commit
c0a26819c6
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
target
|
||||
*.rs.bk
|
||||
clippy.toml
|
||||
|
||||
# Python Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
|
|
|
@ -48,7 +48,7 @@ impl<'a> BVH<'a> {
|
|||
where
|
||||
F: 'b + Fn(&T) -> &'b [BBox],
|
||||
{
|
||||
if objects.len() == 0 {
|
||||
if objects.is_empty() {
|
||||
BVH {
|
||||
root: None,
|
||||
depth: 0,
|
||||
|
@ -96,8 +96,8 @@ impl<'a> BVH<'a> {
|
|||
|
||||
while stack_ptr > 0 {
|
||||
node_tests += ray_i_stack[stack_ptr] as u64;
|
||||
match node_stack[stack_ptr] {
|
||||
&BVHNode::Internal {
|
||||
match *node_stack[stack_ptr] {
|
||||
BVHNode::Internal {
|
||||
children,
|
||||
bounds_start,
|
||||
bounds_len,
|
||||
|
@ -124,7 +124,7 @@ impl<'a> BVH<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
&BVHNode::Leaf {
|
||||
BVHNode::Leaf {
|
||||
object_range,
|
||||
bounds_start,
|
||||
bounds_len,
|
||||
|
@ -161,13 +161,14 @@ impl<'a> BVH<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(mut_from_ref))]
|
||||
fn construct_from_base(
|
||||
arena: &'a MemArena,
|
||||
base: &BVHBase,
|
||||
node_index: usize,
|
||||
) -> &'a mut BVHNode<'a> {
|
||||
match &base.nodes[node_index] {
|
||||
&BVHBaseNode::Internal {
|
||||
match base.nodes[node_index] {
|
||||
BVHBaseNode::Internal {
|
||||
bounds_range,
|
||||
children_indices,
|
||||
split_axis,
|
||||
|
@ -188,10 +189,10 @@ impl<'a> BVH<'a> {
|
|||
children: (child1, child2),
|
||||
};
|
||||
|
||||
return node;
|
||||
node
|
||||
}
|
||||
|
||||
&BVHBaseNode::Leaf {
|
||||
BVHBaseNode::Leaf {
|
||||
bounds_range,
|
||||
object_range,
|
||||
} => {
|
||||
|
@ -204,7 +205,7 @@ impl<'a> BVH<'a> {
|
|||
object_range: object_range,
|
||||
};
|
||||
|
||||
return node;
|
||||
node
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,18 +216,17 @@ lazy_static! {
|
|||
}
|
||||
|
||||
impl<'a> Boundable for BVH<'a> {
|
||||
fn bounds<'b>(&'b self) -> &'b [BBox] {
|
||||
fn bounds(&self) -> &[BBox] {
|
||||
match self.root {
|
||||
None => &DEGENERATE_BOUNDS[..],
|
||||
Some(root) => {
|
||||
match root {
|
||||
&BVHNode::Internal {
|
||||
match *root {
|
||||
BVHNode::Internal {
|
||||
bounds_start,
|
||||
bounds_len,
|
||||
..
|
||||
} => unsafe { std::slice::from_raw_parts(bounds_start, bounds_len as usize) },
|
||||
|
||||
&BVHNode::Leaf {
|
||||
} |
|
||||
BVHNode::Leaf {
|
||||
bounds_start,
|
||||
bounds_len,
|
||||
..
|
||||
|
|
|
@ -49,7 +49,7 @@ impl<'a> BVH4<'a> {
|
|||
where
|
||||
F: 'b + Fn(&T) -> &'b [BBox],
|
||||
{
|
||||
if objects.len() == 0 {
|
||||
if objects.is_empty() {
|
||||
BVH4 {
|
||||
root: None,
|
||||
depth: 0,
|
||||
|
@ -100,8 +100,8 @@ impl<'a> BVH4<'a> {
|
|||
|
||||
while stack_ptr > 0 {
|
||||
node_tests += ray_i_stack[stack_ptr] as u64;
|
||||
match node_stack[stack_ptr] {
|
||||
&BVH4Node::Inner {
|
||||
match *node_stack[stack_ptr] {
|
||||
BVH4Node::Inner {
|
||||
traversal_code,
|
||||
bounds_start,
|
||||
bounds_len,
|
||||
|
@ -167,7 +167,7 @@ impl<'a> BVH4<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
&BVH4Node::Leaf {
|
||||
BVH4Node::Leaf {
|
||||
object_range,
|
||||
bounds_start,
|
||||
bounds_len,
|
||||
|
@ -210,8 +210,8 @@ impl<'a> BVH4<'a> {
|
|||
node_index: usize,
|
||||
node_mem: &mut BVH4Node<'a>,
|
||||
) {
|
||||
match &base.nodes[node_index] {
|
||||
&BVHBaseNode::Internal {
|
||||
match base.nodes[node_index] {
|
||||
BVHBaseNode::Internal {
|
||||
bounds_range,
|
||||
children_indices,
|
||||
split_axis,
|
||||
|
@ -223,14 +223,14 @@ impl<'a> BVH4<'a> {
|
|||
let child_count: usize;
|
||||
let child_indices: [usize; 4];
|
||||
let split_info: SplitAxes;
|
||||
match child_l {
|
||||
&BVHBaseNode::Internal {
|
||||
match *child_l {
|
||||
BVHBaseNode::Internal {
|
||||
children_indices: i_l,
|
||||
split_axis: s_l,
|
||||
..
|
||||
} => {
|
||||
match child_r {
|
||||
&BVHBaseNode::Internal {
|
||||
match *child_r {
|
||||
BVHBaseNode::Internal {
|
||||
children_indices: i_r,
|
||||
split_axis: s_r,
|
||||
..
|
||||
|
@ -240,7 +240,7 @@ impl<'a> BVH4<'a> {
|
|||
child_indices = [i_l.0, i_l.1, i_r.0, i_r.1];
|
||||
split_info = SplitAxes::Full((split_axis, s_l, s_r));
|
||||
}
|
||||
&BVHBaseNode::Leaf { .. } => {
|
||||
BVHBaseNode::Leaf { .. } => {
|
||||
// Three nodes with left split
|
||||
child_count = 3;
|
||||
child_indices = [i_l.0, i_l.1, children_indices.1, 0];
|
||||
|
@ -248,9 +248,9 @@ impl<'a> BVH4<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
&BVHBaseNode::Leaf { .. } => {
|
||||
match child_r {
|
||||
&BVHBaseNode::Internal {
|
||||
BVHBaseNode::Leaf { .. } => {
|
||||
match *child_r {
|
||||
BVHBaseNode::Internal {
|
||||
children_indices: i_r,
|
||||
split_axis: s_r,
|
||||
..
|
||||
|
@ -260,7 +260,7 @@ impl<'a> BVH4<'a> {
|
|||
child_indices = [children_indices.0, i_r.0, i_r.1, 0];
|
||||
split_info = SplitAxes::Right((split_axis, s_r));
|
||||
}
|
||||
&BVHBaseNode::Leaf { .. } => {
|
||||
BVHBaseNode::Leaf { .. } => {
|
||||
// Two nodes
|
||||
child_count = 2;
|
||||
child_indices = [children_indices.0, children_indices.1, 0, 0];
|
||||
|
@ -293,7 +293,7 @@ impl<'a> BVH4<'a> {
|
|||
};
|
||||
}
|
||||
|
||||
&BVHBaseNode::Leaf {
|
||||
BVHBaseNode::Leaf {
|
||||
bounds_range,
|
||||
object_range,
|
||||
} => {
|
||||
|
@ -314,18 +314,17 @@ lazy_static! {
|
|||
}
|
||||
|
||||
impl<'a> Boundable for BVH4<'a> {
|
||||
fn bounds<'b>(&'b self) -> &'b [BBox] {
|
||||
fn bounds(&self) -> &[BBox] {
|
||||
match self.root {
|
||||
None => &DEGENERATE_BOUNDS[..],
|
||||
Some(root) => {
|
||||
match root {
|
||||
&BVH4Node::Inner {
|
||||
match *root {
|
||||
BVH4Node::Inner {
|
||||
bounds_start,
|
||||
bounds_len,
|
||||
..
|
||||
} => unsafe { std::slice::from_raw_parts(bounds_start, bounds_len as usize) },
|
||||
|
||||
&BVH4Node::Leaf {
|
||||
} |
|
||||
BVH4Node::Leaf {
|
||||
bounds_start,
|
||||
bounds_len,
|
||||
..
|
||||
|
|
|
@ -40,9 +40,9 @@ pub enum BVHBaseNode {
|
|||
|
||||
impl BVHBaseNode {
|
||||
pub fn bounds_range(&self) -> (usize, usize) {
|
||||
match self {
|
||||
&BVHBaseNode::Internal { bounds_range, .. } => bounds_range,
|
||||
&BVHBaseNode::Leaf { bounds_range, .. } => bounds_range,
|
||||
match *self {
|
||||
BVHBaseNode::Internal { bounds_range, .. } |
|
||||
BVHBaseNode::Leaf { bounds_range, .. } => bounds_range,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ impl BVHBase {
|
|||
|
||||
for obj in objects.iter() {
|
||||
let bounds = bounder(obj);
|
||||
debug_assert!(bounds.len() > 0);
|
||||
debug_assert!(!bounds.is_empty());
|
||||
if bounds.len() == max_len {
|
||||
for i in 0..bounds.len() {
|
||||
self.bounds_cache[i] |= bounds[i];
|
||||
|
@ -109,7 +109,7 @@ impl BVHBase {
|
|||
{
|
||||
let me = self.nodes.len();
|
||||
|
||||
if objects.len() == 0 {
|
||||
if objects.is_empty() {
|
||||
return (0, (0, 0));
|
||||
} else if objects.len() <= objects_per_leaf {
|
||||
// Leaf node
|
||||
|
|
|
@ -53,7 +53,7 @@ impl<'a> LightAccel for LightArray<'a> {
|
|||
|
||||
assert!(n >= 0.0 && n <= 1.0);
|
||||
|
||||
if self.indices.len() == 0 {
|
||||
if self.indices.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,23 +37,23 @@ enum Node<'a> {
|
|||
|
||||
impl<'a> Node<'a> {
|
||||
fn bounds(&self) -> &'a [BBox] {
|
||||
match self {
|
||||
&Node::Inner { ref bounds, .. } => bounds,
|
||||
&Node::Leaf { ref bounds, .. } => bounds,
|
||||
match *self {
|
||||
Node::Inner { bounds, .. } |
|
||||
Node::Leaf { bounds, .. } => bounds,
|
||||
}
|
||||
}
|
||||
|
||||
fn energy(&self) -> f32 {
|
||||
match self {
|
||||
&Node::Inner { energy, .. } => energy,
|
||||
&Node::Leaf { energy, .. } => energy,
|
||||
match *self {
|
||||
Node::Inner { energy, .. } |
|
||||
Node::Leaf { energy, .. } => energy,
|
||||
}
|
||||
}
|
||||
|
||||
fn light_index(&self) -> usize {
|
||||
match self {
|
||||
&Node::Inner { .. } => panic!(),
|
||||
&Node::Leaf { light_index, .. } => light_index,
|
||||
match *self {
|
||||
Node::Inner { .. } => panic!(),
|
||||
Node::Leaf { light_index, .. } => light_index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ impl<'a> LightTree<'a> {
|
|||
where
|
||||
F: 'b + Fn(&T) -> (&'b [BBox], f32),
|
||||
{
|
||||
if objects.len() == 0 {
|
||||
if objects.is_empty() {
|
||||
LightTree {
|
||||
root: None,
|
||||
depth: 0,
|
||||
|
@ -170,8 +170,7 @@ impl<'a> LightAccel for LightTree<'a> {
|
|||
let mut node = self.root.unwrap();
|
||||
let mut tot_prob = 1.0;
|
||||
let mut n = n;
|
||||
loop {
|
||||
if let Node::Inner { children, .. } = *node {
|
||||
while let Node::Inner { children, .. } = *node {
|
||||
// Calculate the relative probabilities of the children
|
||||
let ps = {
|
||||
let mut ps = [0.0; ARITY];
|
||||
|
@ -188,7 +187,7 @@ impl<'a> LightAccel for LightTree<'a> {
|
|||
}
|
||||
} else {
|
||||
for prob in &mut ps[..] {
|
||||
*prob = *prob / total;
|
||||
*prob /= total;
|
||||
}
|
||||
}
|
||||
ps
|
||||
|
@ -206,9 +205,6 @@ impl<'a> LightAccel for LightTree<'a> {
|
|||
base += p;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Found our light!
|
||||
|
@ -216,7 +212,7 @@ impl<'a> LightAccel for LightTree<'a> {
|
|||
}
|
||||
|
||||
fn approximate_energy(&self) -> f32 {
|
||||
if let Some(ref node) = self.root {
|
||||
if let Some(node) = self.root {
|
||||
node.energy()
|
||||
} else {
|
||||
0.0
|
||||
|
@ -270,17 +266,18 @@ impl LightTreeBuilder {
|
|||
pub fn node_child_count_recurse(&self, level_collapse: usize, node_index: usize) -> usize {
|
||||
if level_collapse > 0 {
|
||||
if self.nodes[node_index].is_leaf {
|
||||
return 1;
|
||||
1
|
||||
} else {
|
||||
let a = self.node_child_count_recurse(level_collapse - 1, node_index + 1);
|
||||
let b = self.node_child_count_recurse(
|
||||
level_collapse - 1,
|
||||
self.nodes[node_index].child_index,
|
||||
);
|
||||
return a + b;
|
||||
|
||||
a + b
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,7 +317,7 @@ impl LightTreeBuilder {
|
|||
{
|
||||
let me_index = self.nodes.len();
|
||||
|
||||
if objects.len() == 0 {
|
||||
if objects.is_empty() {
|
||||
return (0, (0, 0));
|
||||
} else if objects.len() == 1 {
|
||||
// Leaf node
|
||||
|
|
|
@ -170,7 +170,7 @@ where
|
|||
// Pre-calc SAH div points
|
||||
let sah_divs = {
|
||||
let mut sah_divs = [[0.0f32; SAH_BIN_COUNT - 1]; 3];
|
||||
for d in 0..3 {
|
||||
for d in 0..sah_divs.len() {
|
||||
let extent = bounds.max.get_n(d) - bounds.min.get_n(d);
|
||||
for div in 0..(SAH_BIN_COUNT - 1) {
|
||||
let part = extent * ((div + 1) as f32 / SAH_BIN_COUNT as f32);
|
||||
|
|
|
@ -16,7 +16,7 @@ pub fn weighted_choice<T, F>(slc: &[T], n: f32, weight: F) -> (usize, f32)
|
|||
where
|
||||
F: Fn(&T) -> f32,
|
||||
{
|
||||
assert!(slc.len() > 0);
|
||||
assert!(!slc.is_empty());
|
||||
|
||||
let total_weight = slc.iter().fold(0.0, |sum, v| sum + weight(v));
|
||||
let n = n * total_weight;
|
||||
|
@ -147,7 +147,7 @@ pub fn partition_pair<A, B, F>(slc1: &mut [A], slc2: &mut [B], mut pred: F) -> u
|
|||
where
|
||||
F: FnMut(usize, &mut A, &mut B) -> bool,
|
||||
{
|
||||
assert!(slc1.len() == slc2.len());
|
||||
assert_eq!(slc1.len(), slc2.len());
|
||||
|
||||
// This version uses raw pointers and pointer arithmetic to squeeze more
|
||||
// performance out of the code.
|
||||
|
@ -233,7 +233,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Merges two slices of things, appending the result to vec_out
|
||||
/// Merges two slices of things, appending the result to `vec_out`
|
||||
pub fn merge_slices_append<T: Lerp + Copy, F>(
|
||||
slice1: &[T],
|
||||
slice2: &[T],
|
||||
|
@ -243,7 +243,7 @@ pub fn merge_slices_append<T: Lerp + Copy, F>(
|
|||
F: Fn(&T, &T) -> T,
|
||||
{
|
||||
// Transform the bounding boxes
|
||||
if slice1.len() == 0 || slice2.len() == 0 {
|
||||
if slice1.is_empty() || slice2.is_empty() {
|
||||
return;
|
||||
} else if slice1.len() == slice2.len() {
|
||||
for (xf1, xf2) in Iterator::zip(slice1.iter(), slice2.iter()) {
|
||||
|
@ -264,16 +264,16 @@ pub fn merge_slices_append<T: Lerp + Copy, F>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Merges two slices of things, storing the result in slice_out.
|
||||
/// Panics if slice_out is not the right size.
|
||||
/// Merges two slices of things, storing the result in `slice_out`.
|
||||
/// Panics if `slice_out` is not the right size.
|
||||
pub fn merge_slices_to<T: Lerp + Copy, F>(slice1: &[T], slice2: &[T], slice_out: &mut [T], merge: F)
|
||||
where
|
||||
F: Fn(&T, &T) -> T,
|
||||
{
|
||||
assert!(slice_out.len() == cmp::max(slice1.len(), slice2.len()));
|
||||
assert_eq!(slice_out.len(), cmp::max(slice1.len(), slice2.len()));
|
||||
|
||||
// Transform the bounding boxes
|
||||
if slice1.len() == 0 || slice2.len() == 0 {
|
||||
if slice1.is_empty() || slice2.is_empty() {
|
||||
return;
|
||||
} else if slice1.len() == slice2.len() {
|
||||
for (xfo, (xf1, xf2)) in
|
||||
|
|
14
src/bbox.rs
14
src/bbox.rs
|
@ -52,7 +52,7 @@ impl BBox {
|
|||
let near_hit_t = near_t.h_max();
|
||||
|
||||
// Did we hit?
|
||||
return near_hit_t <= far_hit_t;
|
||||
near_hit_t <= far_hit_t
|
||||
}
|
||||
|
||||
// Creates a new BBox transformed into a different space.
|
||||
|
@ -71,13 +71,13 @@ impl BBox {
|
|||
|
||||
// Transform BBox corners and make new bbox
|
||||
let mut b = BBox::new();
|
||||
for v in vs.iter() {
|
||||
for v in &vs {
|
||||
let v = *v * xform;
|
||||
b.min = v.min(b.min);
|
||||
b.max = v.max(b.max);
|
||||
}
|
||||
|
||||
return b;
|
||||
b
|
||||
}
|
||||
|
||||
pub fn surface_area(&self) -> f32 {
|
||||
|
@ -95,7 +95,7 @@ impl BBox {
|
|||
}
|
||||
|
||||
|
||||
/// Union of two BBoxes.
|
||||
/// Union of two `BBox`es.
|
||||
impl BitOr for BBox {
|
||||
type Output = BBox;
|
||||
|
||||
|
@ -113,7 +113,7 @@ impl BitOrAssign for BBox {
|
|||
}
|
||||
}
|
||||
|
||||
/// Expand BBox by a point.
|
||||
/// Expand `BBox` by a point.
|
||||
impl BitOr<Point> for BBox {
|
||||
type Output = BBox;
|
||||
|
||||
|
@ -146,8 +146,8 @@ pub fn transform_bbox_slice_from(bbs_in: &[BBox], xforms: &[Matrix4x4], bbs_out:
|
|||
bbs_out.clear();
|
||||
|
||||
// Transform the bounding boxes
|
||||
if xforms.len() == 0 {
|
||||
return;
|
||||
if xforms.is_empty() {
|
||||
bbs_out.extend_from_slice(bbs_in);
|
||||
} else if bbs_in.len() == xforms.len() {
|
||||
for (bb, xf) in Iterator::zip(bbs_in.iter(), xforms.iter()) {
|
||||
bbs_out.push(bb.transformed(xf.inverse()));
|
||||
|
|
|
@ -4,5 +4,5 @@ use bbox::BBox;
|
|||
|
||||
|
||||
pub trait Boundable {
|
||||
fn bounds<'a>(&'a self) -> &'a [BBox];
|
||||
fn bounds(&self) -> &[BBox];
|
||||
}
|
||||
|
|
|
@ -25,20 +25,20 @@ impl<'a> Camera<'a> {
|
|||
mut aperture_radii: Vec<f32>,
|
||||
mut focus_distances: Vec<f32>,
|
||||
) -> Camera<'a> {
|
||||
assert!(transforms.len() != 0, "Camera has no transform(s)!");
|
||||
assert!(fovs.len() != 0, "Camera has no fov(s)!");
|
||||
assert!(!transforms.is_empty(), "Camera has no transform(s)!");
|
||||
assert!(!fovs.is_empty(), "Camera has no fov(s)!");
|
||||
|
||||
// Aperture needs focus distance and vice-versa.
|
||||
if aperture_radii.len() == 0 || focus_distances.len() == 0 {
|
||||
if aperture_radii.is_empty() || focus_distances.is_empty() {
|
||||
aperture_radii = vec![0.0];
|
||||
focus_distances = vec![1.0];
|
||||
|
||||
if aperture_radii.len() == 0 && focus_distances.len() != 0 {
|
||||
if aperture_radii.is_empty() && !focus_distances.is_empty() {
|
||||
println!(
|
||||
"WARNING: camera has aperture radius but no focus distance. Disabling \
|
||||
focal blur."
|
||||
);
|
||||
} else if aperture_radii.len() != 0 && focus_distances.len() == 0 {
|
||||
} else if !aperture_radii.is_empty() && focus_distances.is_empty() {
|
||||
println!(
|
||||
"WARNING: camera has focus distance but no aperture radius. Disabling \
|
||||
focal blur."
|
||||
|
@ -71,10 +71,10 @@ impl<'a> Camera<'a> {
|
|||
|
||||
pub fn generate_ray(&self, x: f32, y: f32, time: f32, u: f32, v: f32) -> Ray {
|
||||
// Get time-interpolated camera settings
|
||||
let transform = lerp_slice(&self.transforms, time);
|
||||
let tfov = lerp_slice(&self.tfovs, time);
|
||||
let aperture_radius = lerp_slice(&self.aperture_radii, time);
|
||||
let focus_distance = lerp_slice(&self.focus_distances, time);
|
||||
let transform = lerp_slice(self.transforms, time);
|
||||
let tfov = lerp_slice(self.tfovs, time);
|
||||
let aperture_radius = lerp_slice(self.aperture_radii, time);
|
||||
let focus_distance = lerp_slice(self.focus_distances, time);
|
||||
|
||||
// Ray origin
|
||||
let orig = {
|
||||
|
|
|
@ -85,7 +85,7 @@ impl SpectralSample {
|
|||
impl Add for SpectralSample {
|
||||
type Output = SpectralSample;
|
||||
fn add(self, rhs: SpectralSample) -> Self::Output {
|
||||
assert!(self.hero_wavelength == rhs.hero_wavelength);
|
||||
assert_eq!(self.hero_wavelength, rhs.hero_wavelength);
|
||||
SpectralSample {
|
||||
e: self.e + rhs.e,
|
||||
hero_wavelength: self.hero_wavelength,
|
||||
|
@ -95,7 +95,7 @@ impl Add for SpectralSample {
|
|||
|
||||
impl AddAssign for SpectralSample {
|
||||
fn add_assign(&mut self, rhs: SpectralSample) {
|
||||
assert!(self.hero_wavelength == rhs.hero_wavelength);
|
||||
assert_eq!(self.hero_wavelength, rhs.hero_wavelength);
|
||||
self.e = self.e + rhs.e;
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ impl AddAssign for SpectralSample {
|
|||
impl Mul for SpectralSample {
|
||||
type Output = SpectralSample;
|
||||
fn mul(self, rhs: SpectralSample) -> Self::Output {
|
||||
assert!(self.hero_wavelength == rhs.hero_wavelength);
|
||||
assert_eq!(self.hero_wavelength, rhs.hero_wavelength);
|
||||
SpectralSample {
|
||||
e: self.e * rhs.e,
|
||||
hero_wavelength: self.hero_wavelength,
|
||||
|
@ -113,7 +113,7 @@ impl Mul for SpectralSample {
|
|||
|
||||
impl MulAssign for SpectralSample {
|
||||
fn mul_assign(&mut self, rhs: SpectralSample) {
|
||||
assert!(self.hero_wavelength == rhs.hero_wavelength);
|
||||
assert_eq!(self.hero_wavelength, rhs.hero_wavelength);
|
||||
self.e = self.e * rhs.e;
|
||||
}
|
||||
}
|
||||
|
|
11
src/hash.rs
11
src/hash.rs
|
@ -2,26 +2,24 @@ use std;
|
|||
|
||||
pub fn hash_u32(n: u32, seed: u32) -> u32 {
|
||||
let mut hash = n;
|
||||
|
||||
for _ in 0..3 {
|
||||
hash = hash.wrapping_mul(1936502639);
|
||||
hash ^= hash.wrapping_shr(16);
|
||||
hash = hash.wrapping_add(seed);
|
||||
}
|
||||
|
||||
return hash;
|
||||
hash
|
||||
}
|
||||
|
||||
pub fn hash_u64(n: u64, seed: u64) -> u64 {
|
||||
let mut hash = n;
|
||||
|
||||
for _ in 0..4 {
|
||||
hash = hash.wrapping_mul(32416190071 * 314604959);
|
||||
hash ^= hash.wrapping_shr(32);
|
||||
hash = hash.wrapping_add(seed);
|
||||
}
|
||||
|
||||
return hash;
|
||||
hash
|
||||
}
|
||||
|
||||
/// Returns a random float in [0, 1] based on 'n' and a seed.
|
||||
|
@ -29,13 +27,12 @@ pub fn hash_u64(n: u64, seed: u64) -> u64 {
|
|||
/// numbers, and use seed to vary between runs.
|
||||
pub fn hash_u32_to_f32(n: u32, seed: u32) -> f32 {
|
||||
let mut hash = n;
|
||||
|
||||
for _ in 0..3 {
|
||||
hash = hash.wrapping_mul(1936502639);
|
||||
hash ^= hash.wrapping_shr(16);
|
||||
hash = hash.wrapping_add(seed);
|
||||
}
|
||||
|
||||
const INV_MAX: f32 = 1.0 / std::u32::MAX as f32;
|
||||
return hash as f32 * INV_MAX;
|
||||
|
||||
hash as f32 * INV_MAX
|
||||
}
|
||||
|
|
|
@ -4,14 +4,13 @@ const N: u32 = 1 << 16;
|
|||
|
||||
// Utility function used by the functions below.
|
||||
fn hil_rot(n: u32, rx: u32, ry: u32, x: &mut u32, y: &mut u32) {
|
||||
use std::mem;
|
||||
if ry == 0 {
|
||||
if rx == 1 {
|
||||
*x = (n - 1).wrapping_sub(*x);
|
||||
*y = (n - 1).wrapping_sub(*y);
|
||||
}
|
||||
let t = *x;
|
||||
*x = *y;
|
||||
*y = t;
|
||||
mem::swap(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
src/image.rs
18
src/image.rs
|
@ -47,7 +47,7 @@ impl Image {
|
|||
assert!(x < self.res.0);
|
||||
assert!(y < self.res.1);
|
||||
|
||||
let data: &Vec<XYZ> = unsafe { mem::transmute(self.data.get()) };
|
||||
let data: &Vec<XYZ> = unsafe { &*self.data.get() };
|
||||
data[self.res.0 * y + x]
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ impl Image {
|
|||
assert!(x < self.res.0);
|
||||
assert!(y < self.res.1);
|
||||
|
||||
let data: &mut Vec<XYZ> = unsafe { mem::transmute(self.data.get()) };
|
||||
let data: &mut Vec<XYZ> = unsafe { &mut *self.data.get() };
|
||||
data[self.res.0 * y + x] = value;
|
||||
}
|
||||
|
||||
|
@ -187,11 +187,11 @@ impl Image {
|
|||
let mut fb = {
|
||||
// Create the frame buffer
|
||||
let mut fb = openexr::FrameBuffer::new(self.res.0, self.res.1);
|
||||
fb.insert_channels(&["R", "G", "B"], &mut image);
|
||||
fb.insert_channels(&["R", "G", "B"], &image);
|
||||
fb
|
||||
};
|
||||
|
||||
wr.write_pixels(&mut fb).unwrap();
|
||||
wr.write_pixels(&fb).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,8 +208,8 @@ impl<'a> Bucket<'a> {
|
|||
assert!(x >= self.min.0 && x < self.max.0);
|
||||
assert!(y >= self.min.1 && y < self.max.1);
|
||||
|
||||
let img: &mut Image = unsafe { mem::transmute(self.img) };
|
||||
let data: &Vec<XYZ> = unsafe { mem::transmute(img.data.get()) };
|
||||
let img: &mut Image = unsafe { &mut *self.img };
|
||||
let data: &Vec<XYZ> = unsafe { &mut *img.data.get() };
|
||||
|
||||
data[img.res.0 * y as usize + x as usize]
|
||||
}
|
||||
|
@ -218,8 +218,8 @@ impl<'a> Bucket<'a> {
|
|||
assert!(x >= self.min.0 && x < self.max.0);
|
||||
assert!(y >= self.min.1 && y < self.max.1);
|
||||
|
||||
let img: &mut Image = unsafe { mem::transmute(self.img) };
|
||||
let data: &mut Vec<XYZ> = unsafe { mem::transmute(img.data.get()) };
|
||||
let img: &mut Image = unsafe { &mut *self.img };
|
||||
let data: &mut Vec<XYZ> = unsafe { &mut *img.data.get() };
|
||||
|
||||
data[img.res.0 * y as usize + x as usize] = value;
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ impl<'a> Bucket<'a> {
|
|||
|
||||
impl<'a> Drop for Bucket<'a> {
|
||||
fn drop(&mut self) {
|
||||
let img: &mut Image = unsafe { mem::transmute(self.img) };
|
||||
let img: &mut Image = unsafe { &mut *self.img };
|
||||
let tmp = img.checked_out_blocks.lock().unwrap();
|
||||
let mut bucket_list = tmp.borrow_mut();
|
||||
|
||||
|
|
12
src/lerp.rs
12
src/lerp.rs
|
@ -21,19 +21,19 @@ pub fn lerp<T: Lerp>(a: T, b: T, alpha: f32) -> T {
|
|||
/// Interpolates a slice of data as if each adjecent pair of elements
|
||||
/// represent a linear segment.
|
||||
pub fn lerp_slice<T: Lerp + Copy>(s: &[T], alpha: f32) -> T {
|
||||
debug_assert!(s.len() > 0);
|
||||
debug_assert!(!s.is_empty());
|
||||
debug_assert!(alpha >= 0.0);
|
||||
debug_assert!(alpha <= 1.0);
|
||||
|
||||
if s.len() == 1 || alpha == 1.0 {
|
||||
return *s.last().unwrap();
|
||||
*s.last().unwrap()
|
||||
} else {
|
||||
let tmp = alpha * ((s.len() - 1) as f32);
|
||||
let i1 = tmp as usize;
|
||||
let i2 = i1 + 1;
|
||||
let alpha2 = tmp - (i1 as f32);
|
||||
|
||||
return lerp(s[i1], s[i2], alpha2);
|
||||
lerp(s[i1], s[i2], alpha2)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,19 +42,19 @@ where
|
|||
T: Copy,
|
||||
F: Fn(T, T, f32) -> T,
|
||||
{
|
||||
debug_assert!(s.len() > 0);
|
||||
debug_assert!(!s.is_empty());
|
||||
debug_assert!(alpha >= 0.0);
|
||||
debug_assert!(alpha <= 1.0);
|
||||
|
||||
if s.len() == 1 || alpha == 1.0 {
|
||||
return *s.last().unwrap();
|
||||
*s.last().unwrap()
|
||||
} else {
|
||||
let tmp = alpha * ((s.len() - 1) as f32);
|
||||
let i1 = tmp as usize;
|
||||
let i2 = i1 + 1;
|
||||
let alpha2 = tmp - (i1 as f32);
|
||||
|
||||
return f(s[i1], s[i2], alpha2);
|
||||
f(s[i1], s[i2], alpha2)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ impl<'a> DistantDiskLight<'a> {
|
|||
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;
|
||||
let direction = lerp_slice(&self.directions, time);
|
||||
let col = lerp_slice(&self.colors, time);
|
||||
let radius: f64 = lerp_slice(self.radii, time) as f64;
|
||||
let direction = lerp_slice(self.directions, time);
|
||||
let col = lerp_slice(self.colors, time);
|
||||
let solid_angle_inv = 1.0 / (2.0 * PI_64 * (1.0 - radius.cos()));
|
||||
|
||||
// Create a coordinate system from the vector pointing at the center of
|
||||
|
@ -53,25 +53,26 @@ impl<'a> WorldLightSource for DistantDiskLight<'a> {
|
|||
let spectral_sample = (col * solid_angle_inv as f32).to_spectral_sample(wavelength);
|
||||
let shadow_vec = (x * sample.x()) + (y * sample.y()) + (z * sample.z());
|
||||
let pdf = uniform_sample_cone_pdf(cos_theta_max);
|
||||
|
||||
return (spectral_sample, shadow_vec, pdf as f32);
|
||||
(spectral_sample, shadow_vec, pdf as f32)
|
||||
}
|
||||
|
||||
fn sample_pdf(&self, sample_dir: Vector, wavelength: f32, time: f32) -> f32 {
|
||||
// We're not using these, silence warnings
|
||||
let _ = (sample_dir, wavelength);
|
||||
|
||||
let radius: f64 = lerp_slice(&self.radii, time) as f64;
|
||||
return uniform_sample_cone_pdf(radius.cos()) as f32;
|
||||
let radius: f64 = lerp_slice(self.radii, time) as f64;
|
||||
|
||||
uniform_sample_cone_pdf(radius.cos()) as f32
|
||||
}
|
||||
|
||||
fn outgoing(&self, dir: Vector, wavelength: f32, time: f32) -> SpectralSample {
|
||||
// We're not using this, silence warning
|
||||
let _ = dir;
|
||||
|
||||
let radius = lerp_slice(&self.radii, time) as f64;
|
||||
let col = lerp_slice(&self.colors, time);
|
||||
let radius = lerp_slice(self.radii, time) as f64;
|
||||
let col = lerp_slice(self.colors, time);
|
||||
let solid_angle = 2.0 * PI_64 * (1.0 - radius.cos());
|
||||
|
||||
(col / solid_angle as f32).to_spectral_sample(wavelength)
|
||||
}
|
||||
|
||||
|
|
|
@ -51,8 +51,8 @@ impl<'a> LightSource for RectangleLight<'a> {
|
|||
time: f32,
|
||||
) -> (SpectralSample, Vector, f32) {
|
||||
// Calculate time interpolated values
|
||||
let dim = lerp_slice(&self.dimensions, time);
|
||||
let col = lerp_slice(&self.colors, time);
|
||||
let dim = lerp_slice(self.dimensions, time);
|
||||
let col = lerp_slice(self.colors, time);
|
||||
|
||||
// TODO: Is this right? Do we need to get the surface area post-transform?
|
||||
let surface_area_inv: f64 = 1.0 / (dim.0 as f64 * dim.1 as f64);
|
||||
|
@ -105,7 +105,7 @@ impl<'a> LightSource for RectangleLight<'a> {
|
|||
let pdf = 1.0 / (area_1 + area_2); // PDF of the ray direction being sampled
|
||||
let spectral_sample = (col * surface_area_inv as f32 * 0.5).to_spectral_sample(wavelength);
|
||||
|
||||
return (spectral_sample, shadow_vec, pdf as f32);
|
||||
(spectral_sample, shadow_vec, pdf as f32)
|
||||
}
|
||||
|
||||
fn sample_pdf(
|
||||
|
@ -121,7 +121,7 @@ impl<'a> LightSource for RectangleLight<'a> {
|
|||
// We're not using these, silence warnings
|
||||
let _ = (sample_dir, sample_u, sample_v, wavelength);
|
||||
|
||||
let dim = lerp_slice(&self.dimensions, time);
|
||||
let dim = lerp_slice(self.dimensions, time);
|
||||
|
||||
// Get the four corners of the rectangle, transformed into world space
|
||||
let space_inv = space.inverse();
|
||||
|
@ -156,8 +156,8 @@ impl<'a> LightSource for RectangleLight<'a> {
|
|||
// We're not using these, silence warnings
|
||||
let _ = (space, dir, u, v);
|
||||
|
||||
let dim = lerp_slice(&self.dimensions, time);
|
||||
let col = lerp_slice(&self.colors, time);
|
||||
let dim = lerp_slice(self.dimensions, time);
|
||||
let col = lerp_slice(self.colors, time);
|
||||
|
||||
// TODO: Is this right? Do we need to get the surface area post-transform?
|
||||
let surface_area_inv: f64 = 1.0 / (dim.0 as f64 * dim.1 as f64);
|
||||
|
@ -179,7 +179,7 @@ impl<'a> LightSource for RectangleLight<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Boundable for RectangleLight<'a> {
|
||||
fn bounds<'b>(&'b self) -> &'b [BBox] {
|
||||
&self.bounds_
|
||||
fn bounds(&self) -> &[BBox] {
|
||||
self.bounds_
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,8 +54,8 @@ impl<'a> LightSource for SphereLight<'a> {
|
|||
let pos = Point::new(0.0, 0.0, 0.0);
|
||||
|
||||
// Calculate time interpolated values
|
||||
let radius: f64 = lerp_slice(&self.radii, time) as f64;
|
||||
let col = lerp_slice(&self.colors, time);
|
||||
let radius: f64 = lerp_slice(self.radii, time) as f64;
|
||||
let col = lerp_slice(self.colors, time);
|
||||
let surface_area_inv: f64 = 1.0 / (4.0 * PI_64 * radius * radius);
|
||||
|
||||
|
||||
|
@ -131,7 +131,7 @@ impl<'a> LightSource for SphereLight<'a> {
|
|||
|
||||
let arr = arr * *space;
|
||||
let pos = Point::new(0.0, 0.0, 0.0);
|
||||
let radius: f64 = lerp_slice(&self.radii, time) as f64;
|
||||
let radius: f64 = lerp_slice(self.radii, time) as f64;
|
||||
|
||||
let d2: f64 = (pos - arr).length2() as f64; // Distance from center of sphere squared
|
||||
let d: f64 = d2.sqrt(); // Distance from center of sphere
|
||||
|
@ -142,9 +142,9 @@ impl<'a> LightSource for SphereLight<'a> {
|
|||
let cos_theta_max2: f64 = 1.0 - sin_theta_max2;
|
||||
let cos_theta_max: f64 = cos_theta_max2.sqrt();
|
||||
|
||||
return uniform_sample_cone_pdf(cos_theta_max) as f32;
|
||||
uniform_sample_cone_pdf(cos_theta_max) as f32
|
||||
} else {
|
||||
return (1.0 / (4.0 * PI_64)) as f32;
|
||||
(1.0 / (4.0 * PI_64)) as f32
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,8 +161,8 @@ impl<'a> LightSource for SphereLight<'a> {
|
|||
let _ = (space, dir, u, v);
|
||||
|
||||
// TODO: use transform space correctly
|
||||
let radius = lerp_slice(&self.radii, time) as f64;
|
||||
let col = lerp_slice(&self.colors, time);
|
||||
let radius = lerp_slice(self.radii, time) as f64;
|
||||
let col = lerp_slice(self.colors, time);
|
||||
let surface_area = 4.0 * PI_64 * radius * radius;
|
||||
(col / surface_area as f32).to_spectral_sample(wavelength)
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ impl<'a> LightSource for SphereLight<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Boundable for SphereLight<'a> {
|
||||
fn bounds<'b>(&'b self) -> &'b [BBox] {
|
||||
&self.bounds_
|
||||
fn bounds(&self) -> &[BBox] {
|
||||
self.bounds_
|
||||
}
|
||||
}
|
||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -1,3 +1,11 @@
|
|||
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(inline_always))]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(many_single_char_names))]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(needless_return))]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(or_fun_call))]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
|
||||
|
||||
extern crate bvh_order;
|
||||
extern crate color as color_util;
|
||||
extern crate float4;
|
||||
|
@ -274,18 +282,18 @@ fn main() {
|
|||
if !args.is_present("serialized_output") {
|
||||
println!("\tOverriding scene spp: {}", spp);
|
||||
}
|
||||
r.spp = usize::from_str(&spp).unwrap();
|
||||
r.spp = usize::from_str(spp).unwrap();
|
||||
}
|
||||
|
||||
let max_samples_per_bucket =
|
||||
if let Some(max_samples_per_bucket) = args.value_of("max_bucket_samples") {
|
||||
u32::from_str(&max_samples_per_bucket).unwrap()
|
||||
u32::from_str(max_samples_per_bucket).unwrap()
|
||||
} else {
|
||||
4096
|
||||
};
|
||||
|
||||
let thread_count = if let Some(threads) = args.value_of("threads") {
|
||||
u32::from_str(&threads).unwrap()
|
||||
u32::from_str(threads).unwrap()
|
||||
} else {
|
||||
num_cpus::get() as u32
|
||||
};
|
||||
|
|
16
src/math.rs
16
src/math.rs
|
@ -1,6 +1,10 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use std::f32;
|
||||
|
||||
pub use math3d::{Matrix4x4, Normal, Point, Vector, DotProduct, dot, CrossProduct, cross};
|
||||
|
||||
|
||||
/// Clamps a value between a min and max.
|
||||
pub fn clamp<T: PartialOrd>(v: T, lower: T, upper: T) -> T {
|
||||
if v < lower {
|
||||
|
@ -49,7 +53,7 @@ pub fn log2_64(mut value: u64) -> u64 {
|
|||
(1, (1 << 1) - 1),
|
||||
];
|
||||
|
||||
for &(i, j) in POWERS.iter() {
|
||||
for &(i, j) in &POWERS {
|
||||
let tmp = value >> i;
|
||||
if tmp != 0 {
|
||||
log += i;
|
||||
|
@ -112,7 +116,7 @@ pub fn logit(p: f32, width: f32) -> f32 {
|
|||
pub fn fast_logit(p: f32, width: f32) -> f32 {
|
||||
let n = 0.001 + (p * 0.998);
|
||||
|
||||
fast_ln((n / (1.0 - n))) * width * (0.6266 / 4.0)
|
||||
fast_ln(n / (1.0 - n)) * width * (0.6266 / 4.0)
|
||||
}
|
||||
|
||||
|
||||
|
@ -124,7 +128,7 @@ pub fn fast_ln(x: f32) -> f32 {
|
|||
|
||||
let mut y = unsafe { transmute_copy::<f32, u32>(&x) as f32 };
|
||||
y *= 8.2629582881927490e-8;
|
||||
return y - 87.989971088;
|
||||
y - 87.989971088
|
||||
}
|
||||
|
||||
pub fn fast_pow2(p: f32) -> f32 {
|
||||
|
@ -149,11 +153,11 @@ pub fn fast_log2(x: f32) -> f32 {
|
|||
let y = xi as f32 * 1.1920928955078125e-7;
|
||||
let mx = unsafe { transmute_copy::<u32, f32>(&((xi & 0x007FFFFF) | 0x3f000000)) };
|
||||
|
||||
return y - 124.22551499 - 1.498030302 * mx - 1.72587999 / (0.3520887068 + mx);
|
||||
y - 124.22551499 - 1.498030302 * mx - 1.72587999 / (0.3520887068 + mx)
|
||||
}
|
||||
|
||||
pub fn fast_exp(p: f32) -> f32 {
|
||||
fast_pow2(1.442695040 * p)
|
||||
fast_pow2(f32::consts::LOG2_E * p)
|
||||
}
|
||||
|
||||
pub fn fast_pow(x: f32, p: f32) -> f32 {
|
||||
|
@ -170,7 +174,7 @@ pub fn faster_pow2(p: f32) -> f32 {
|
|||
}
|
||||
|
||||
pub fn faster_exp(p: f32) -> f32 {
|
||||
faster_pow2(1.442695040 * p)
|
||||
faster_pow2(f32::consts::LOG2_E * p)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ impl<'a> DataTree<'a> {
|
|||
|
||||
remaining_text = skip_ws_and_comments(remaining_text);
|
||||
|
||||
if remaining_text.1.len() == 0 {
|
||||
if remaining_text.1.is_empty() {
|
||||
return Ok(DataTree::Internal {
|
||||
type_name: "ROOT",
|
||||
ident: None,
|
||||
|
@ -48,42 +48,42 @@ impl<'a> DataTree<'a> {
|
|||
}
|
||||
|
||||
pub fn type_name(&'a self) -> &'a str {
|
||||
match self {
|
||||
&DataTree::Internal { type_name, .. } => type_name,
|
||||
&DataTree::Leaf { type_name, .. } => type_name,
|
||||
match *self {
|
||||
DataTree::Internal { type_name, .. } |
|
||||
DataTree::Leaf { type_name, .. } => type_name,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn byte_offset(&'a self) -> usize {
|
||||
match self {
|
||||
&DataTree::Internal { byte_offset, .. } => byte_offset,
|
||||
&DataTree::Leaf { byte_offset, .. } => byte_offset,
|
||||
match *self {
|
||||
DataTree::Internal { byte_offset, .. } |
|
||||
DataTree::Leaf { byte_offset, .. } => byte_offset,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_internal(&self) -> bool {
|
||||
match self {
|
||||
&DataTree::Internal { .. } => true,
|
||||
&DataTree::Leaf { .. } => false,
|
||||
match *self {
|
||||
DataTree::Internal { .. } => true,
|
||||
DataTree::Leaf { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_leaf(&self) -> bool {
|
||||
match self {
|
||||
&DataTree::Internal { .. } => false,
|
||||
&DataTree::Leaf { .. } => true,
|
||||
match *self {
|
||||
DataTree::Internal { .. } => false,
|
||||
DataTree::Leaf { .. } => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn leaf_contents(&'a self) -> Option<&'a str> {
|
||||
match self {
|
||||
&DataTree::Internal { .. } => None,
|
||||
&DataTree::Leaf { contents, .. } => Some(contents),
|
||||
match *self {
|
||||
DataTree::Internal { .. } => None,
|
||||
DataTree::Leaf { contents, .. } => Some(contents),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter_children(&'a self) -> slice::Iter<'a, DataTree<'a>> {
|
||||
if let &DataTree::Internal { ref children, .. } = self {
|
||||
if let DataTree::Internal { ref children, .. } = *self {
|
||||
children.iter()
|
||||
} else {
|
||||
[].iter()
|
||||
|
@ -91,7 +91,7 @@ impl<'a> DataTree<'a> {
|
|||
}
|
||||
|
||||
pub fn iter_children_with_type(&'a self, type_name: &'static str) -> DataTreeFilterIter<'a> {
|
||||
if let &DataTree::Internal { ref children, .. } = self {
|
||||
if let DataTree::Internal { ref children, .. } = *self {
|
||||
DataTreeFilterIter {
|
||||
type_name: type_name,
|
||||
iter: children.iter(),
|
||||
|
@ -108,7 +108,7 @@ impl<'a> DataTree<'a> {
|
|||
&'a self,
|
||||
type_name: &'static str,
|
||||
) -> DataTreeFilterInternalIter<'a> {
|
||||
if let &DataTree::Internal { ref children, .. } = self {
|
||||
if let DataTree::Internal { ref children, .. } = *self {
|
||||
DataTreeFilterInternalIter {
|
||||
type_name: type_name,
|
||||
iter: children.iter(),
|
||||
|
@ -125,7 +125,7 @@ impl<'a> DataTree<'a> {
|
|||
&'a self,
|
||||
type_name: &'static str,
|
||||
) -> DataTreeFilterLeafIter<'a> {
|
||||
if let &DataTree::Internal { ref children, .. } = self {
|
||||
if let DataTree::Internal { ref children, .. } = *self {
|
||||
DataTreeFilterLeafIter {
|
||||
type_name: type_name,
|
||||
iter: children.iter(),
|
||||
|
@ -167,7 +167,7 @@ impl<'a> DataTree<'a> {
|
|||
}
|
||||
|
||||
|
||||
/// An iterator over the children of a DataTree node that filters out the
|
||||
/// An iterator over the children of a `DataTree` node that filters out the
|
||||
/// children not matching a specified type name.
|
||||
pub struct DataTreeFilterIter<'a> {
|
||||
type_name: &'a str,
|
||||
|
@ -193,7 +193,7 @@ impl<'a> Iterator for DataTreeFilterIter<'a> {
|
|||
}
|
||||
|
||||
|
||||
/// An iterator over the children of a DataTree node that filters out the
|
||||
/// An iterator over the children of a `DataTree` node that filters out the
|
||||
/// children that aren't internal nodes and that don't match a specified
|
||||
/// type name.
|
||||
pub struct DataTreeFilterInternalIter<'a> {
|
||||
|
@ -233,7 +233,7 @@ impl<'a> Iterator for DataTreeFilterInternalIter<'a> {
|
|||
}
|
||||
|
||||
|
||||
/// An iterator over the children of a DataTree node that filters out the
|
||||
/// An iterator over the children of a `DataTree` node that filters out the
|
||||
/// children that aren't internal nodes and that don't match a specified
|
||||
/// type name.
|
||||
pub struct DataTreeFilterLeafIter<'a> {
|
||||
|
@ -387,7 +387,7 @@ fn parse_node<'a>(source_text: (usize, &'a str)) -> ParseResult<'a> {
|
|||
}
|
||||
|
||||
|
||||
fn parse_leaf_content<'a>(source_text: (usize, &'a str)) -> (&'a str, (usize, &'a str)) {
|
||||
fn parse_leaf_content(source_text: (usize, &str)) -> (&str, (usize, &str)) {
|
||||
let mut si = 1;
|
||||
let mut escaped = false;
|
||||
let mut reached_end = true;
|
||||
|
@ -521,7 +521,7 @@ fn is_ident_char(c: char) -> bool {
|
|||
!is_ws(c) && !is_reserved_char(c)
|
||||
}
|
||||
|
||||
fn skip_ws<'a>(text: &'a str) -> &'a str {
|
||||
fn skip_ws(text: &str) -> &str {
|
||||
let mut si = 0;
|
||||
let mut reached_end = true;
|
||||
for (i, c) in text.char_indices() {
|
||||
|
@ -539,7 +539,7 @@ fn skip_ws<'a>(text: &'a str) -> &'a str {
|
|||
return &text[si..];
|
||||
}
|
||||
|
||||
fn skip_comment<'a>(text: &'a str) -> &'a str {
|
||||
fn skip_comment(text: &str) -> &str {
|
||||
let mut si = 0;
|
||||
if Some('#') == text.chars().nth(0) {
|
||||
let mut reached_end = true;
|
||||
|
@ -559,7 +559,7 @@ fn skip_comment<'a>(text: &'a str) -> &'a str {
|
|||
return &text[si..];
|
||||
}
|
||||
|
||||
fn skip_ws_and_comments<'a>(text: (usize, &'a str)) -> (usize, &'a str) {
|
||||
fn skip_ws_and_comments(text: (usize, &str)) -> (usize, &str) {
|
||||
let mut remaining_text = text.1;
|
||||
|
||||
loop {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use std::result::Result;
|
||||
use std::f32;
|
||||
|
||||
use nom;
|
||||
use nom::IResult;
|
||||
|
@ -37,8 +38,8 @@ pub enum PsyParseError {
|
|||
|
||||
impl PsyParseError {
|
||||
pub fn print(&self, psy_content: &str) {
|
||||
match self {
|
||||
&PsyParseError::UnknownError(offset) => {
|
||||
match *self {
|
||||
PsyParseError::UnknownError(offset) => {
|
||||
let line = line_count_to_byte_offset(psy_content, offset);
|
||||
println!(
|
||||
"Line {}: Unknown parse error. If you get this message, please report \
|
||||
|
@ -47,37 +48,37 @@ impl PsyParseError {
|
|||
);
|
||||
}
|
||||
|
||||
&PsyParseError::UnknownVariant(offset, error) => {
|
||||
PsyParseError::UnknownVariant(offset, error) => {
|
||||
let line = line_count_to_byte_offset(psy_content, offset);
|
||||
println!("Line {}: {}", line, error);
|
||||
}
|
||||
|
||||
&PsyParseError::ExpectedInternalNode(offset, error) => {
|
||||
PsyParseError::ExpectedInternalNode(offset, error) => {
|
||||
let line = line_count_to_byte_offset(psy_content, offset);
|
||||
println!("Line {}: {}", line, error);
|
||||
}
|
||||
|
||||
&PsyParseError::ExpectedLeafNode(offset, error) => {
|
||||
PsyParseError::ExpectedLeafNode(offset, error) => {
|
||||
let line = line_count_to_byte_offset(psy_content, offset);
|
||||
println!("Line {}: {}", line, error);
|
||||
}
|
||||
|
||||
&PsyParseError::MissingNode(offset, error) => {
|
||||
PsyParseError::MissingNode(offset, error) => {
|
||||
let line = line_count_to_byte_offset(psy_content, offset);
|
||||
println!("Line {}: {}", line, error);
|
||||
}
|
||||
|
||||
&PsyParseError::IncorrectLeafData(offset, error) => {
|
||||
PsyParseError::IncorrectLeafData(offset, error) => {
|
||||
let line = line_count_to_byte_offset(psy_content, offset);
|
||||
println!("Line {}: {}", line, error);
|
||||
}
|
||||
|
||||
&PsyParseError::WrongNodeCount(offset, error, count) => {
|
||||
PsyParseError::WrongNodeCount(offset, error, count) => {
|
||||
let line = line_count_to_byte_offset(psy_content, offset);
|
||||
println!("Line {}: {} Found: {}", line, error, count);
|
||||
}
|
||||
|
||||
&PsyParseError::InstancedMissingData(offset, error, ref data_name) => {
|
||||
PsyParseError::InstancedMissingData(offset, error, ref data_name) => {
|
||||
let line = line_count_to_byte_offset(psy_content, offset);
|
||||
println!("Line {}: {} Data name: '{}'", line, error, data_name);
|
||||
}
|
||||
|
@ -86,11 +87,11 @@ impl PsyParseError {
|
|||
}
|
||||
|
||||
fn line_count_to_byte_offset(text: &str, offset: usize) -> usize {
|
||||
text[..offset].matches("\n").count() + 1
|
||||
text[..offset].matches('\n').count() + 1
|
||||
}
|
||||
|
||||
|
||||
/// Takes in a DataTree representing a Scene node and returns
|
||||
/// Takes in a `DataTree` representing a Scene node and returns
|
||||
pub fn parse_scene<'a>(
|
||||
arena: &'a MemArena,
|
||||
tree: &'a DataTree,
|
||||
|
@ -167,7 +168,7 @@ pub fn parse_scene<'a>(
|
|||
)?;
|
||||
|
||||
// Put scene together
|
||||
let scene_name = if let &DataTree::Internal { ident, .. } = tree {
|
||||
let scene_name = if let DataTree::Internal { ident, .. } = *tree {
|
||||
if let Some(name) = ident {
|
||||
Some(name.to_string())
|
||||
} else {
|
||||
|
@ -202,13 +203,13 @@ pub fn parse_scene<'a>(
|
|||
|
||||
|
||||
fn parse_output_info(tree: &DataTree) -> Result<String, PsyParseError> {
|
||||
if let &DataTree::Internal { ref children, .. } = tree {
|
||||
if let DataTree::Internal { ref children, .. } = *tree {
|
||||
let mut found_path = false;
|
||||
let mut path = String::new();
|
||||
|
||||
for child in children {
|
||||
match child {
|
||||
&DataTree::Leaf {
|
||||
match *child {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -243,7 +244,7 @@ fn parse_output_info(tree: &DataTree) -> Result<String, PsyParseError> {
|
|||
}
|
||||
|
||||
if found_path {
|
||||
return Ok((path));
|
||||
return Ok(path);
|
||||
} else {
|
||||
return Err(PsyParseError::MissingNode(
|
||||
tree.byte_offset(),
|
||||
|
@ -263,7 +264,7 @@ fn parse_output_info(tree: &DataTree) -> Result<String, PsyParseError> {
|
|||
|
||||
|
||||
fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyParseError> {
|
||||
if let &DataTree::Internal { ref children, .. } = tree {
|
||||
if let DataTree::Internal { ref children, .. } = *tree {
|
||||
let mut found_res = false;
|
||||
let mut found_spp = false;
|
||||
let mut res = (0, 0);
|
||||
|
@ -271,9 +272,9 @@ fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyP
|
|||
let mut seed = 0;
|
||||
|
||||
for child in children {
|
||||
match child {
|
||||
match *child {
|
||||
// Resolution
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -294,7 +295,7 @@ fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyP
|
|||
}
|
||||
|
||||
// SamplesPerPixel
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -314,7 +315,7 @@ fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyP
|
|||
}
|
||||
|
||||
// Seed
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -359,7 +360,7 @@ fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyP
|
|||
|
||||
|
||||
fn parse_camera<'a>(arena: &'a MemArena, tree: &'a DataTree) -> Result<Camera<'a>, PsyParseError> {
|
||||
if let &DataTree::Internal { ref children, .. } = tree {
|
||||
if let DataTree::Internal { ref children, .. } = *tree {
|
||||
let mut mats = Vec::new();
|
||||
let mut fovs = Vec::new();
|
||||
let mut focus_distances = Vec::new();
|
||||
|
@ -367,15 +368,15 @@ fn parse_camera<'a>(arena: &'a MemArena, tree: &'a DataTree) -> Result<Camera<'a
|
|||
|
||||
// Parse
|
||||
for child in children.iter() {
|
||||
match child {
|
||||
match *child {
|
||||
// Fov
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
} if type_name == "Fov" => {
|
||||
if let IResult::Done(_, fov) = ws_f32(contents.as_bytes()) {
|
||||
fovs.push(fov * (3.1415926536 / 180.0));
|
||||
fovs.push(fov * (f32::consts::PI / 180.0));
|
||||
} else {
|
||||
// Found Fov, but its contents is not in the right format
|
||||
return Err(PsyParseError::IncorrectLeafData(
|
||||
|
@ -388,7 +389,7 @@ fn parse_camera<'a>(arena: &'a MemArena, tree: &'a DataTree) -> Result<Camera<'a
|
|||
}
|
||||
|
||||
// FocalDistance
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -407,7 +408,7 @@ fn parse_camera<'a>(arena: &'a MemArena, tree: &'a DataTree) -> Result<Camera<'a
|
|||
}
|
||||
|
||||
// ApertureRadius
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -426,7 +427,7 @@ fn parse_camera<'a>(arena: &'a MemArena, tree: &'a DataTree) -> Result<Camera<'a
|
|||
}
|
||||
|
||||
// Transform
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -490,8 +491,8 @@ fn parse_world<'a>(arena: &'a MemArena, tree: &'a DataTree) -> Result<World<'a>,
|
|||
bgs.iter_children_with_type("Type").count(),
|
||||
));
|
||||
}
|
||||
if let &DataTree::Leaf { contents, .. } =
|
||||
bgs.iter_children_with_type("Type").nth(0).unwrap()
|
||||
if let DataTree::Leaf { contents, .. } =
|
||||
*bgs.iter_children_with_type("Type").nth(0).unwrap()
|
||||
{
|
||||
contents.trim()
|
||||
} else {
|
||||
|
@ -544,9 +545,9 @@ fn parse_world<'a>(arena: &'a MemArena, tree: &'a DataTree) -> Result<World<'a>,
|
|||
|
||||
// Parse light sources
|
||||
for child in tree.iter_children() {
|
||||
match child {
|
||||
&DataTree::Internal { type_name, .. } if type_name == "DistantDiskLight" => {
|
||||
lights.push(arena.alloc(parse_distant_disk_light(arena, &child)?));
|
||||
match *child {
|
||||
DataTree::Internal { type_name, .. } if type_name == "DistantDiskLight" => {
|
||||
lights.push(arena.alloc(parse_distant_disk_light(arena, child)?));
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
@ -619,9 +620,9 @@ pub fn parse_matrix(contents: &str) -> Result<Matrix4x4, PsyParseError> {
|
|||
}
|
||||
|
||||
pub fn make_transform_format_error(byte_offset: usize) -> PsyParseError {
|
||||
return PsyParseError::IncorrectLeafData(
|
||||
PsyParseError::IncorrectLeafData(
|
||||
byte_offset,
|
||||
"Transform should be sixteen integers specified in \
|
||||
the form '[# # # # # # # # # # # # # # # #]'.",
|
||||
);
|
||||
)
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ pub fn parse_assembly<'a>(
|
|||
match child.type_name() {
|
||||
// Sub-Assembly
|
||||
"Assembly" => {
|
||||
if let &DataTree::Internal { ident: Some(ident), .. } = child {
|
||||
builder.add_assembly(ident, parse_assembly(arena, &child)?);
|
||||
if let DataTree::Internal { ident: Some(ident), .. } = *child {
|
||||
builder.add_assembly(ident, parse_assembly(arena, child)?);
|
||||
} else {
|
||||
return Err(PsyParseError::UnknownError(child.byte_offset()));
|
||||
}
|
||||
|
@ -68,10 +68,10 @@ pub fn parse_assembly<'a>(
|
|||
|
||||
// MeshSurface
|
||||
"MeshSurface" => {
|
||||
if let &DataTree::Internal { ident: Some(ident), .. } = child {
|
||||
if let DataTree::Internal { ident: Some(ident), .. } = *child {
|
||||
builder.add_object(
|
||||
ident,
|
||||
Object::Surface(arena.alloc(parse_mesh_surface(arena, &child)?)),
|
||||
Object::Surface(arena.alloc(parse_mesh_surface(arena, child)?)),
|
||||
);
|
||||
} else {
|
||||
// TODO: error condition of some kind, because no ident
|
||||
|
@ -85,10 +85,10 @@ pub fn parse_assembly<'a>(
|
|||
|
||||
// Sphere Light
|
||||
"SphereLight" => {
|
||||
if let &DataTree::Internal { ident: Some(ident), .. } = child {
|
||||
if let DataTree::Internal { ident: Some(ident), .. } = *child {
|
||||
builder.add_object(
|
||||
ident,
|
||||
Object::Light(arena.alloc(parse_sphere_light(arena, &child)?)),
|
||||
Object::Light(arena.alloc(parse_sphere_light(arena, child)?)),
|
||||
);
|
||||
} else {
|
||||
// No ident
|
||||
|
@ -98,10 +98,10 @@ pub fn parse_assembly<'a>(
|
|||
|
||||
// Rectangle Light
|
||||
"RectangleLight" => {
|
||||
if let &DataTree::Internal { ident: Some(ident), .. } = child {
|
||||
if let DataTree::Internal { ident: Some(ident), .. } = *child {
|
||||
builder.add_object(
|
||||
ident,
|
||||
Object::Light(arena.alloc(parse_rectangle_light(arena, &child)?)),
|
||||
Object::Light(arena.alloc(parse_rectangle_light(arena, child)?)),
|
||||
);
|
||||
} else {
|
||||
// No ident
|
||||
|
@ -111,7 +111,7 @@ pub fn parse_assembly<'a>(
|
|||
|
||||
// Surface shader
|
||||
"SurfaceShader" => {
|
||||
if let &DataTree::Internal { ident: Some(_), .. } = child {
|
||||
if let DataTree::Internal { ident: Some(_), .. } = *child {
|
||||
// TODO
|
||||
//unimplemented!()
|
||||
} else {
|
||||
|
|
|
@ -19,16 +19,16 @@ pub fn parse_distant_disk_light<'a>(
|
|||
arena: &'a MemArena,
|
||||
tree: &'a DataTree,
|
||||
) -> Result<DistantDiskLight<'a>, PsyParseError> {
|
||||
if let &DataTree::Internal { ref children, .. } = tree {
|
||||
if let DataTree::Internal { ref children, .. } = *tree {
|
||||
let mut radii = Vec::new();
|
||||
let mut directions = Vec::new();
|
||||
let mut colors = Vec::new();
|
||||
|
||||
// Parse
|
||||
for child in children.iter() {
|
||||
match child {
|
||||
match *child {
|
||||
// Radius
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -42,7 +42,7 @@ pub fn parse_distant_disk_light<'a>(
|
|||
}
|
||||
|
||||
// Direction
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -58,7 +58,7 @@ pub fn parse_distant_disk_light<'a>(
|
|||
}
|
||||
|
||||
// Color
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -91,15 +91,15 @@ pub fn parse_sphere_light<'a>(
|
|||
arena: &'a MemArena,
|
||||
tree: &'a DataTree,
|
||||
) -> Result<SphereLight<'a>, PsyParseError> {
|
||||
if let &DataTree::Internal { ref children, .. } = tree {
|
||||
if let DataTree::Internal { ref children, .. } = *tree {
|
||||
let mut radii = Vec::new();
|
||||
let mut colors = Vec::new();
|
||||
|
||||
// Parse
|
||||
for child in children.iter() {
|
||||
match child {
|
||||
match *child {
|
||||
// Radius
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -113,7 +113,7 @@ pub fn parse_sphere_light<'a>(
|
|||
}
|
||||
|
||||
// Color
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -145,15 +145,15 @@ pub fn parse_rectangle_light<'a>(
|
|||
arena: &'a MemArena,
|
||||
tree: &'a DataTree,
|
||||
) -> Result<RectangleLight<'a>, PsyParseError> {
|
||||
if let &DataTree::Internal { ref children, .. } = tree {
|
||||
if let DataTree::Internal { ref children, .. } = *tree {
|
||||
let mut dimensions = Vec::new();
|
||||
let mut colors = Vec::new();
|
||||
|
||||
// Parse
|
||||
for child in children.iter() {
|
||||
match child {
|
||||
match *child {
|
||||
// Dimensions
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
@ -169,7 +169,7 @@ pub fn parse_rectangle_light<'a>(
|
|||
}
|
||||
|
||||
// Color
|
||||
&DataTree::Leaf {
|
||||
DataTree::Leaf {
|
||||
type_name,
|
||||
contents,
|
||||
byte_offset,
|
||||
|
|
|
@ -51,7 +51,7 @@ pub fn parse_mesh_surface<'a>(
|
|||
|
||||
// Make sure all time samples have same vert count
|
||||
if let Some(fvc) = first_vert_count {
|
||||
assert!(vert_count == fvc);
|
||||
assert_eq!(vert_count, fvc);
|
||||
} else {
|
||||
first_vert_count = Some(vert_count);
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ pub fn parse_mesh_surface<'a>(
|
|||
let mut triangles = Vec::new();
|
||||
let vert_count = first_vert_count.unwrap();
|
||||
let mut ii = 0;
|
||||
for fvc in face_vert_counts.iter() {
|
||||
for fvc in &face_vert_counts {
|
||||
if *fvc >= 3 {
|
||||
// Store the polygon, split up into triangles if >3 verts
|
||||
let v1 = ii;
|
||||
|
|
|
@ -232,12 +232,10 @@ impl<'a> Renderer<'a> {
|
|||
if let Some(b) = job_queue.try_pop() {
|
||||
bucket = b;
|
||||
break;
|
||||
} else {
|
||||
if *all_jobs_queued.read().unwrap() == true {
|
||||
} else if *all_jobs_queued.read().unwrap() {
|
||||
break 'render_loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
timer.tick();
|
||||
// Generate light paths and initial rays
|
||||
|
@ -293,7 +291,7 @@ impl<'a> Renderer<'a> {
|
|||
let min = (bucket.x, bucket.y);
|
||||
let max = (bucket.x + bucket.w, bucket.y + bucket.h);
|
||||
let mut img_bucket = image.get_bucket(min, max);
|
||||
for path in paths.iter() {
|
||||
for path in &paths {
|
||||
let path_col = SpectralSample::from_parts(path.color, path.wavelength);
|
||||
let mut col = img_bucket.get(path.pixel_co.0, path.pixel_co.1);
|
||||
col += XYZ::from_spectral_sample(&path_col) / self.spp as f32;
|
||||
|
@ -438,10 +436,10 @@ impl LightPath {
|
|||
// Result of Camera or bounce ray, prepare next bounce and light rays
|
||||
LightPathEvent::CameraRay |
|
||||
LightPathEvent::BounceRay => {
|
||||
if let &surface::SurfaceIntersection::Hit {
|
||||
if let surface::SurfaceIntersection::Hit {
|
||||
intersection_data: ref idata,
|
||||
ref closure,
|
||||
} = isect
|
||||
} = *isect
|
||||
{
|
||||
// Hit something! Do the stuff
|
||||
|
||||
|
@ -544,10 +542,7 @@ impl LightPath {
|
|||
};
|
||||
|
||||
// Book keeping for next event
|
||||
if found_light && do_bounce {
|
||||
self.event = LightPathEvent::ShadowRay;
|
||||
return true;
|
||||
} else if found_light {
|
||||
if found_light {
|
||||
self.event = LightPathEvent::ShadowRay;
|
||||
return true;
|
||||
} else if do_bounce {
|
||||
|
@ -574,7 +569,7 @@ impl LightPath {
|
|||
LightPathEvent::ShadowRay => {
|
||||
// If the light was not in shadow, add it's light to the film
|
||||
// plane.
|
||||
if let &surface::SurfaceIntersection::Miss = isect {
|
||||
if let surface::SurfaceIntersection::Miss = *isect {
|
||||
self.color += self.pending_color_addition;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ pub fn square_to_circle(x: f32, y: f32) -> (f32, f32) {
|
|||
pub fn cosine_sample_hemisphere(u: f32, v: f32) -> Vector {
|
||||
let (u, v) = square_to_circle((u * 2.0) - 1.0, (v * 2.0) - 1.0);
|
||||
let z = (1.0 - ((u * u) + (v * v))).max(0.0).sqrt();
|
||||
return Vector::new(u, v, z);
|
||||
Vector::new(u, v, z)
|
||||
}
|
||||
|
||||
pub fn uniform_sample_hemisphere(u: f32, v: f32) -> Vector {
|
||||
|
@ -61,8 +61,8 @@ pub fn uniform_sample_sphere(u: f32, v: f32) -> Vector {
|
|||
/// Samples a solid angle defined by a cone originating from (0,0,0)
|
||||
/// and pointing down the positive z-axis.
|
||||
///
|
||||
/// u, v: sampling variables, should each be in the interval [0,1]
|
||||
/// cos_theta_max: cosine of the max angle from the z-axis, defining
|
||||
/// `u`, `v`: sampling variables, should each be in the interval [0,1]
|
||||
/// `cos_theta_max`: cosine of the max angle from the z-axis, defining
|
||||
/// the outer extent of the cone.
|
||||
pub fn uniform_sample_cone(u: f32, v: f32, cos_theta_max: f64) -> Vector {
|
||||
let cos_theta = (1.0 - u as f64) + (u as f64 * cos_theta_max);
|
||||
|
|
|
@ -45,12 +45,12 @@ impl<'a> Assembly<'a> {
|
|||
time: f32,
|
||||
intr: &SurfaceIntersection,
|
||||
) -> Option<(SpectralSample, Vector, f32, f32)> {
|
||||
if let &SurfaceIntersection::Hit {
|
||||
if let SurfaceIntersection::Hit {
|
||||
intersection_data: idata,
|
||||
closure,
|
||||
} = intr
|
||||
} = *intr
|
||||
{
|
||||
let sel_xform = if xform_stack.top().len() > 0 {
|
||||
let sel_xform = if !xform_stack.top().is_empty() {
|
||||
lerp_slice(xform_stack.top(), time)
|
||||
} else {
|
||||
Matrix4x4::new()
|
||||
|
@ -69,20 +69,20 @@ impl<'a> Assembly<'a> {
|
|||
match inst.instance_type {
|
||||
|
||||
InstanceType::Object => {
|
||||
match &self.objects[inst.data_index] {
|
||||
&Object::Light(ref light) => {
|
||||
match self.objects[inst.data_index] {
|
||||
Object::Light(light) => {
|
||||
// Get the world-to-object space transform of the light
|
||||
let xform = if let Some((a, b)) = inst.transform_indices {
|
||||
let pxforms = xform_stack.top();
|
||||
let xform = lerp_slice(&self.xforms[a..b], time);
|
||||
if pxforms.len() > 0 {
|
||||
if !pxforms.is_empty() {
|
||||
lerp_slice(pxforms, time) * xform
|
||||
} else {
|
||||
xform
|
||||
}
|
||||
} else {
|
||||
let pxforms = xform_stack.top();
|
||||
if pxforms.len() > 0 {
|
||||
if !pxforms.is_empty() {
|
||||
lerp_slice(pxforms, time)
|
||||
} else {
|
||||
Matrix4x4::new()
|
||||
|
@ -117,7 +117,7 @@ impl<'a> Assembly<'a> {
|
|||
);
|
||||
|
||||
// Pop the assembly's transforms off the transform stack.
|
||||
if let Some(_) = inst.transform_indices {
|
||||
if inst.transform_indices.is_some() {
|
||||
xform_stack.pop();
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ impl<'a> Assembly<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Boundable for Assembly<'a> {
|
||||
fn bounds<'b>(&'b self) -> &'b [BBox] {
|
||||
fn bounds(&self) -> &[BBox] {
|
||||
self.object_accel.bounds()
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ impl<'a> AssemblyBuilder<'a> {
|
|||
|
||||
// Map zero-length transforms to None
|
||||
let xforms = if let Some(xf) = xforms {
|
||||
if xf.len() > 0 { Some(xf) } else { None }
|
||||
if !xf.is_empty() { Some(xf) } else { None }
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -274,7 +274,7 @@ impl<'a> AssemblyBuilder<'a> {
|
|||
.approximate_energy() > 0.0
|
||||
}
|
||||
})
|
||||
.map(|&a| a)
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
// Build light accel
|
||||
|
@ -282,7 +282,7 @@ impl<'a> AssemblyBuilder<'a> {
|
|||
let bounds = &bbs[bis[inst.id]..bis[inst.id + 1]];
|
||||
let energy = match inst.instance_type {
|
||||
InstanceType::Object => {
|
||||
if let Object::Light(ref light) = self.objects[inst.data_index] {
|
||||
if let Object::Light(light) = self.objects[inst.data_index] {
|
||||
light.approximate_energy()
|
||||
} else {
|
||||
0.0
|
||||
|
@ -316,7 +316,7 @@ impl<'a> AssemblyBuilder<'a> {
|
|||
let mut indices = vec![0];
|
||||
let mut bounds = Vec::new();
|
||||
|
||||
for inst in self.instances.iter() {
|
||||
for inst in &self.instances {
|
||||
let mut bbs = Vec::new();
|
||||
let mut bbs2 = Vec::new();
|
||||
|
||||
|
@ -325,9 +325,9 @@ impl<'a> AssemblyBuilder<'a> {
|
|||
InstanceType::Object => {
|
||||
// Push bounds onto bbs
|
||||
let obj = &self.objects[inst.data_index];
|
||||
match obj {
|
||||
&Object::Surface(ref s) => bbs.extend(s.bounds()),
|
||||
&Object::Light(ref l) => bbs.extend(l.bounds()),
|
||||
match *obj {
|
||||
Object::Surface(s) => bbs.extend(s.bounds()),
|
||||
Object::Light(l) => bbs.extend(l.bounds()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,7 +341,7 @@ impl<'a> AssemblyBuilder<'a> {
|
|||
// Transform the bounding boxes, if necessary
|
||||
if let Some((xstart, xend)) = inst.transform_indices {
|
||||
let xf = &self.xforms[xstart..xend];
|
||||
transform_bbox_slice_from(&bbs, &xf, &mut bbs2);
|
||||
transform_bbox_slice_from(&bbs, xf, &mut bbs2);
|
||||
} else {
|
||||
bbs2.clear();
|
||||
bbs2.extend(bbs);
|
||||
|
@ -352,7 +352,7 @@ impl<'a> AssemblyBuilder<'a> {
|
|||
indices.push(bounds.len());
|
||||
}
|
||||
|
||||
return (indices, bounds);
|
||||
(indices, bounds)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ impl<'a> Scene<'a> {
|
|||
if n < wl_prob {
|
||||
// World lights
|
||||
let n = n / wl_prob;
|
||||
let (i, p) = weighted_choice(&self.world.lights, n, |l| l.approximate_energy());
|
||||
let (i, p) = weighted_choice(self.world.lights, n, |l| l.approximate_energy());
|
||||
let (ss, sv, pdf) = self.world.lights[i].sample(uvw.0, uvw.1, wavelength, time);
|
||||
return Some((ss, sv, pdf, p * wl_prob, true));
|
||||
} else {
|
||||
|
|
|
@ -20,10 +20,10 @@ pub enum SurfaceClosureUnion {
|
|||
|
||||
impl SurfaceClosureUnion {
|
||||
pub fn as_surface_closure(&self) -> &SurfaceClosure {
|
||||
match self {
|
||||
&SurfaceClosureUnion::EmitClosure(ref closure) => closure as &SurfaceClosure,
|
||||
&SurfaceClosureUnion::LambertClosure(ref closure) => closure as &SurfaceClosure,
|
||||
&SurfaceClosureUnion::GTRClosure(ref closure) => closure as &SurfaceClosure,
|
||||
match *self {
|
||||
SurfaceClosureUnion::EmitClosure(ref closure) => closure as &SurfaceClosure,
|
||||
SurfaceClosureUnion::LambertClosure(ref closure) => closure as &SurfaceClosure,
|
||||
SurfaceClosureUnion::GTRClosure(ref closure) => closure as &SurfaceClosure,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,9 +86,9 @@ pub trait SurfaceClosure {
|
|||
/// Utility function that calculates the fresnel reflection factor of a given
|
||||
/// incoming ray against a surface with the given ior outside/inside ratio.
|
||||
///
|
||||
/// ior_ratio: The ratio of the outside material ior (probably 1.0 for air)
|
||||
/// `ior_ratio`: The ratio of the outside material ior (probably 1.0 for air)
|
||||
/// over the inside ior.
|
||||
/// c: The cosine of the angle between the incoming light and the
|
||||
/// `c`: The cosine of the angle between the incoming light and the
|
||||
/// surface's normal. Probably calculated e.g. with a normalized
|
||||
/// dot product.
|
||||
#[allow(dead_code)]
|
||||
|
@ -103,29 +103,30 @@ fn dielectric_fresnel(ior_ratio: f32, c: f32) -> f32 {
|
|||
let f5 = (c * f1) + 1.0;
|
||||
let f6 = 1.0 + ((f4 * f4) / (f5 * f5));
|
||||
|
||||
return 0.5 * f3 * f6;
|
||||
0.5 * f3 * f6
|
||||
}
|
||||
|
||||
|
||||
/// Schlick's approximation of the fresnel reflection factor.
|
||||
///
|
||||
/// Same interface as dielectric_fresnel(), above.
|
||||
/// Same interface as `dielectric_fresnel()`, above.
|
||||
#[allow(dead_code)]
|
||||
fn schlick_fresnel(ior_ratio: f32, c: f32) -> f32 {
|
||||
let f1 = (1.0 - ior_ratio) / (1.0 + ior_ratio);
|
||||
let f2 = f1 * f1;
|
||||
let c1 = 1.0 - c;
|
||||
let c2 = c1 * c1;
|
||||
return f2 + ((1.0 - f2) * c1 * c2 * c2);
|
||||
|
||||
f2 + ((1.0 - f2) * c1 * c2 * c2)
|
||||
}
|
||||
|
||||
|
||||
/// Utility function that calculates the fresnel reflection factor of a given
|
||||
/// incoming ray against a surface with the given normal-reflectance factor.
|
||||
///
|
||||
/// frensel_fac: The ratio of light reflected back if the ray were to
|
||||
/// `frensel_fac`: The ratio of light reflected back if the ray were to
|
||||
/// hit the surface head-on (perpendicular to the surface).
|
||||
/// c The cosine of the angle between the incoming light and the
|
||||
/// `c`: The cosine of the angle between the incoming light and the
|
||||
/// surface's normal. Probably calculated e.g. with a normalized
|
||||
/// dot product.
|
||||
#[allow(dead_code)]
|
||||
|
@ -142,16 +143,16 @@ fn dielectric_fresnel_from_fac(fresnel_fac: f32, c: f32) -> f32 {
|
|||
let ior_ratio = tmp2 * tmp2;
|
||||
|
||||
// Calculate fresnel factor
|
||||
return dielectric_fresnel(ior_ratio, c);
|
||||
dielectric_fresnel(ior_ratio, c)
|
||||
}
|
||||
|
||||
|
||||
/// Schlick's approximation version of dielectric_fresnel_from_fac() above.
|
||||
/// Schlick's approximation version of `dielectric_fresnel_from_fac()` above.
|
||||
#[allow(dead_code)]
|
||||
fn schlick_fresnel_from_fac(frensel_fac: f32, c: f32) -> f32 {
|
||||
let c1 = 1.0 - c;
|
||||
let c2 = c1 * c1;
|
||||
return frensel_fac + ((1.0 - frensel_fac) * c1 * c2 * c2);
|
||||
frensel_fac + ((1.0 - frensel_fac) * c1 * c2 * c2)
|
||||
}
|
||||
|
||||
|
||||
|
@ -429,14 +430,12 @@ impl GTRClosure {
|
|||
let roughness2 = rough * rough;
|
||||
|
||||
// Calculate D - Distribution
|
||||
let dist = if nh <= 0.0 {
|
||||
if nh <= 0.0 {
|
||||
0.0
|
||||
} else {
|
||||
let nh2 = nh * nh;
|
||||
self.normalization_factor / (1.0 + ((roughness2 - 1.0) * nh2)).powf(self.tail_shape)
|
||||
};
|
||||
|
||||
dist
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,7 +566,7 @@ impl SurfaceClosure for GTRClosure {
|
|||
};
|
||||
|
||||
// Final result
|
||||
return col_f * (dist * g1 * g2) * INV_PI;
|
||||
col_f * (dist * g1 * g2) * INV_PI
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,7 +587,7 @@ impl SurfaceClosure for GTRClosure {
|
|||
// Calculate needed dot products
|
||||
let nh = clamp(dot(nn, hh), -1.0, 1.0);
|
||||
|
||||
return self.dist(nh, self.roughness) * INV_PI;
|
||||
self.dist(nh, self.roughness) * INV_PI
|
||||
}
|
||||
|
||||
|
||||
|
@ -639,6 +638,6 @@ impl SurfaceClosure for GTRClosure {
|
|||
(1.0f32).min(self.roughness.sqrt() + (2.0 * theta / PI_32)),
|
||||
);
|
||||
|
||||
return fac * (1.0f32).min(1.0 - cos_theta) * INV_PI;
|
||||
fac * (1.0f32).min(1.0 - cos_theta) * INV_PI
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,9 +83,9 @@ pub fn intersect_ray(ray: &Ray, tri: (Point, Point, Point)) -> Option<(f32, f32,
|
|||
let t_scaled = (e0 * p0z) + (e1 * p1z) + (e2 * p2z);
|
||||
|
||||
// Check if the hitpoint t is within ray min/max t.
|
||||
if det > 0.0 && (t_scaled <= 0.0 || t_scaled > (ray.max_t * det)) {
|
||||
return None;
|
||||
} else if det < 0.0 && (t_scaled >= 0.0 || t_scaled < (ray.max_t * det)) {
|
||||
if (det > 0.0 && (t_scaled <= 0.0 || t_scaled > (ray.max_t * det))) ||
|
||||
(det < 0.0 && (t_scaled >= 0.0 || t_scaled < (ray.max_t * det)))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ impl<'a> TriangleMesh<'a> {
|
|||
time_samples: usize,
|
||||
triangles: Vec<(Point, Point, Point)>,
|
||||
) -> TriangleMesh<'b> {
|
||||
assert!(triangles.len() % time_samples == 0);
|
||||
assert_eq!(triangles.len() % time_samples, 0);
|
||||
|
||||
let mut indices: Vec<usize> = (0..(triangles.len() / time_samples))
|
||||
.map(|n| n * time_samples)
|
||||
|
@ -38,7 +38,7 @@ impl<'a> TriangleMesh<'a> {
|
|||
|
||||
let bounds = {
|
||||
let mut bounds = Vec::new();
|
||||
for tri in triangles.iter() {
|
||||
for tri in &triangles {
|
||||
let minimum = tri.0.min(tri.1.min(tri.2));
|
||||
let maximum = tri.0.max(tri.1.max(tri.2));
|
||||
bounds.push(BBox::from_points(minimum, maximum));
|
||||
|
@ -60,7 +60,7 @@ impl<'a> TriangleMesh<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Boundable for TriangleMesh<'a> {
|
||||
fn bounds<'b>(&'b self) -> &'b [BBox] {
|
||||
fn bounds(&self) -> &[BBox] {
|
||||
self.accel.bounds()
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ impl<'a> Surface for TriangleMesh<'a> {
|
|||
|
||||
self.accel
|
||||
.traverse(
|
||||
&mut accel_rays[..], &self.indices, |tri_i, rs| {
|
||||
&mut accel_rays[..], self.indices, |tri_i, rs| {
|
||||
for r in rs {
|
||||
let wr = &wrays[r.id as usize];
|
||||
|
||||
|
@ -96,7 +96,7 @@ impl<'a> Surface for TriangleMesh<'a> {
|
|||
|
||||
// Transform triangle as necessary, and get transform
|
||||
// space.
|
||||
let (mat_space, tri) = if space.len() > 0 {
|
||||
let (mat_space, tri) = if !space.is_empty() {
|
||||
if space.len() > 1 {
|
||||
// Per-ray transform, for motion blur
|
||||
let mat_space = lerp_slice(space, wr.time).inverse();
|
||||
|
|
|
@ -33,7 +33,7 @@ impl<'a> Tracer<'a> {
|
|||
|wr| AccelRay::new(wr, ids.next().unwrap()),
|
||||
));
|
||||
|
||||
return self.inner.trace(wrays, &mut self.rays[..]);
|
||||
self.inner.trace(wrays, &mut self.rays[..])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,11 +56,11 @@ impl<'a> TracerInner<'a> {
|
|||
);
|
||||
|
||||
let mut ray_sets = split_rays_by_direction(&mut rays[..]);
|
||||
for ray_set in ray_sets.iter_mut().filter(|ray_set| ray_set.len() > 0) {
|
||||
for ray_set in ray_sets.iter_mut().filter(|ray_set| !ray_set.is_empty()) {
|
||||
self.trace_assembly(self.root, wrays, ray_set);
|
||||
}
|
||||
|
||||
return &self.isects;
|
||||
&self.isects
|
||||
}
|
||||
|
||||
fn trace_assembly<'b>(
|
||||
|
@ -102,7 +102,7 @@ impl<'a> TracerInner<'a> {
|
|||
// TODO: do this in a way that's less confusing. Probably split
|
||||
// the tracing code out into a trace_instance() method or
|
||||
// something.
|
||||
let mut tmp = if let Some(_) = inst.transform_indices {
|
||||
let mut tmp = if inst.transform_indices.is_some() {
|
||||
split_rays_by_direction(rs)
|
||||
} else {
|
||||
[
|
||||
|
@ -116,14 +116,14 @@ impl<'a> TracerInner<'a> {
|
|||
&mut [],
|
||||
]
|
||||
};
|
||||
let mut ray_sets = if let Some(_) = inst.transform_indices {
|
||||
let mut ray_sets = if inst.transform_indices.is_some() {
|
||||
&mut tmp[..]
|
||||
} else {
|
||||
&mut tmp[..1]
|
||||
};
|
||||
|
||||
// Loop through the split ray slices and trace them
|
||||
for ray_set in ray_sets.iter_mut().filter(|ray_set| ray_set.len() > 0) {
|
||||
for ray_set in ray_sets.iter_mut().filter(|ray_set| !ray_set.is_empty()) {
|
||||
match inst.instance_type {
|
||||
InstanceType::Object => {
|
||||
self.trace_object(
|
||||
|
@ -145,13 +145,13 @@ impl<'a> TracerInner<'a> {
|
|||
}
|
||||
|
||||
// Un-transform rays if needed
|
||||
if let Some(_) = inst.transform_indices {
|
||||
if inst.transform_indices.is_some() {
|
||||
// Pop transforms off stack
|
||||
self.xform_stack.pop();
|
||||
|
||||
// Undo transforms
|
||||
let xforms = self.xform_stack.top();
|
||||
if xforms.len() > 0 {
|
||||
if !xforms.is_empty() {
|
||||
for ray in &mut rs[..] {
|
||||
let id = ray.id;
|
||||
let t = ray.time;
|
||||
|
@ -172,12 +172,12 @@ impl<'a> TracerInner<'a> {
|
|||
}
|
||||
|
||||
fn trace_object<'b>(&'b mut self, obj: &Object, wrays: &[Ray], rays: &mut [AccelRay]) {
|
||||
match obj {
|
||||
&Object::Surface(ref surface) => {
|
||||
match *obj {
|
||||
Object::Surface(surface) => {
|
||||
surface.intersect_rays(rays, wrays, &mut self.isects, self.xform_stack.top());
|
||||
}
|
||||
|
||||
&Object::Light(_) => {
|
||||
Object::Light(_) => {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,9 @@ impl TransformStack {
|
|||
}
|
||||
|
||||
pub fn push(&mut self, xforms: &[Matrix4x4]) {
|
||||
assert!(xforms.len() > 0);
|
||||
assert!(!xforms.is_empty());
|
||||
|
||||
if self.stack.len() == 0 {
|
||||
if self.stack.is_empty() {
|
||||
self.stack.extend(xforms);
|
||||
} else {
|
||||
let sil = self.stack_indices.len();
|
||||
|
@ -66,7 +66,7 @@ impl TransformStack {
|
|||
self.stack_indices.pop();
|
||||
}
|
||||
|
||||
pub fn top<'a>(&'a self) -> &'a [Matrix4x4] {
|
||||
pub fn top(&self) -> &[Matrix4x4] {
|
||||
let sil = self.stack_indices.len();
|
||||
let i1 = self.stack_indices[sil - 2];
|
||||
let i2 = self.stack_indices[sil - 1];
|
||||
|
|
Loading…
Reference in New Issue
Block a user