Bunch of code quality improvements based on running clippy.

None of them change behavior, just make the code cleaner.
This commit is contained in:
Nathan Vegdahl 2017-07-22 17:21:11 -07:00
parent 3cb684514a
commit c0a26819c6
35 changed files with 354 additions and 353 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
target
*.rs.bk
clippy.toml
# Python Byte-compiled / optimized / DLL files
__pycache__/

View File

@ -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,
..

View File

@ -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,
..

View File

@ -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

View File

@ -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;
}

View File

@ -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,44 +170,40 @@ 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 {
// Calculate the relative probabilities of the children
let ps = {
let mut ps = [0.0; ARITY];
let mut total = 0.0;
for (i, child) in children.iter().enumerate() {
let p = node_prob(child);
ps[i] = p;
total += p;
while let Node::Inner { children, .. } = *node {
// Calculate the relative probabilities of the children
let ps = {
let mut ps = [0.0; ARITY];
let mut total = 0.0;
for (i, child) in children.iter().enumerate() {
let p = node_prob(child);
ps[i] = p;
total += p;
}
if total <= 0.0 {
let p = 1.0 / children.len() as f32;
for prob in &mut ps[..] {
*prob = p;
}
if total <= 0.0 {
let p = 1.0 / children.len() as f32;
for prob in &mut ps[..] {
*prob = p;
}
} else {
for prob in &mut ps[..] {
*prob = *prob / total;
}
}
ps
};
// Pick child and update probabilities
let mut base = 0.0;
for (i, &p) in ps.iter().enumerate() {
if (n <= base + p) || (i == children.len() - 1) {
tot_prob *= p;
node = &children[i];
n = (n - base) / p;
break;
} else {
base += p;
} else {
for prob in &mut ps[..] {
*prob /= total;
}
}
} else {
break;
ps
};
// Pick child and update probabilities
let mut base = 0.0;
for (i, &p) in ps.iter().enumerate() {
if (n <= base + p) || (i == children.len() - 1) {
tot_prob *= p;
node = &children[i];
n = (n - base) / p;
break;
} else {
base += p;
}
}
}
@ -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

View File

@ -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);

View File

@ -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

View File

@ -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()));

View File

@ -4,5 +4,5 @@ use bbox::BBox;
pub trait Boundable {
fn bounds<'a>(&'a self) -> &'a [BBox];
fn bounds(&self) -> &[BBox];
}

View File

@ -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 = {

View File

@ -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;
}
}

View File

@ -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
}

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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_
}
}

View File

@ -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_
}
}

View File

@ -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
};

View File

@ -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)
}

View File

@ -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 {

View File

@ -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 '[# # # # # # # # # # # # # # # #]'.",
);
)
}

View File

@ -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 {

View File

@ -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,

View File

@ -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;

View File

@ -232,10 +232,8 @@ impl<'a> Renderer<'a> {
if let Some(b) = job_queue.try_pop() {
bucket = b;
break;
} else {
if *all_jobs_queued.read().unwrap() == true {
break 'render_loop;
}
} else if *all_jobs_queued.read().unwrap() {
break 'render_loop;
}
}
@ -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;
}

View File

@ -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,9 +61,9 @@ 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
/// the outer extent of the cone.
/// `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);
let sin_theta = (1.0 - (cos_theta * cos_theta)).sqrt();

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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,11 +86,11 @@ 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)
/// over the inside ior.
/// c: The cosine of the angle between the incoming light and the
/// surface's normal. Probably calculated e.g. with a normalized
/// dot product.
/// `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
/// surface's normal. Probably calculated e.g. with a normalized
/// dot product.
#[allow(dead_code)]
fn dielectric_fresnel(ior_ratio: f32, c: f32) -> f32 {
let g = (ior_ratio - 1.0 + (c * c)).sqrt();
@ -103,31 +103,32 @@ 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
/// hit the surface head-on (perpendicular to the surface).
/// c The cosine of the angle between the incoming light and the
/// surface's normal. Probably calculated e.g. with a normalized
/// dot product.
/// `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
/// surface's normal. Probably calculated e.g. with a normalized
/// dot product.
#[allow(dead_code)]
fn dielectric_fresnel_from_fac(fresnel_fac: f32, c: f32) -> f32 {
let tmp1 = fresnel_fac.sqrt() - 1.0;
@ -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
}
}

View File

@ -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;
}

View File

@ -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();

View File

@ -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
}
}

View File

@ -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];