diff --git a/src/octree/convert/magicavoxel.rs b/src/octree/convert/magicavoxel.rs index 6f0e542..0fa44fc 100644 --- a/src/octree/convert/magicavoxel.rs +++ b/src/octree/convert/magicavoxel.rs @@ -108,10 +108,7 @@ where } } -fn iterate_vox_tree, &Matrix3) -> ()>( - vox_tree: &DotVoxData, - mut fun: F, -) { +fn iterate_vox_tree, &Matrix3)>(vox_tree: &DotVoxData, mut fun: F) { let mut node_stack: Vec<(u32, V3c, Matrix3, u32)> = Vec::new(); match &vox_tree.scenes[0] { @@ -128,7 +125,7 @@ fn iterate_vox_tree, &Matrix3) -> ()>( } } - while 0 < node_stack.len() { + while !node_stack.is_empty() { let (current_node, translation, rotation, index) = *node_stack.last().unwrap(); match &vox_tree.scenes[current_node as usize] { SceneNode::Transform { @@ -251,7 +248,7 @@ where .max(position.z + model_size_half_lyup.z) .max(position.z - model_size_half_lyup.z); }); - max_position_lyup = max_position_lyup - min_position_lyup; + max_position_lyup -= min_position_lyup; let max_dimension = max_position_lyup .x .max(max_position_lyup.y) @@ -265,7 +262,7 @@ where CoordinateSystemType::RZUP, CoordinateSystemType::LYUP, ); - let position = V3c::from(*position); + let position = *position; let position_lyup = convert_coordinate( position, CoordinateSystemType::RZUP, @@ -279,7 +276,7 @@ where if model_size_lyup.z < 0 { -1 } else { 0 }, ); - let mut vmin = V3c::unit(max_dimension as u32); + let mut vmin = V3c::unit(max_dimension); let mut vmax = V3c::unit(0u32); for voxel in &model.voxels { let voxel_position = convert_coordinate( @@ -297,7 +294,7 @@ where shocovox_octree .insert( - &V3c::::from(current_position + voxel_position.into()), + &V3c::::from(current_position + voxel_position), T::new(vox_tree.palette[voxel.i as usize].into(), 0), ) .ok() diff --git a/src/octree/mod.rs b/src/octree/mod.rs index aa9991b..42046b2 100644 --- a/src/octree/mod.rs +++ b/src/octree/mod.rs @@ -125,7 +125,7 @@ where return None; } BrickData::Solid(voxel) => { - return Some(&voxel); + return Some(voxel); } } } @@ -144,7 +144,7 @@ where if voxel.is_empty() { return None; } - return Some(&voxel); + return Some(voxel); } }, NodeContent::Internal(_) => { @@ -181,47 +181,39 @@ where debug_assert!(DIM < self.octree_size as usize); // Hash the position to the target child - let child_octant_at_position = child_octant_for(&bounds, position); + let child_octant_at_position = child_octant_for(bounds, position); // If the child exists, query it for the voxel match &mut bricks[child_octant_at_position as usize] { - BrickData::Empty => { - return None; - } + BrickData::Empty => None, BrickData::Parted(ref mut brick) => { - let bounds = Cube::child_bounds_for(&bounds, child_octant_at_position); + let bounds = Cube::child_bounds_for(bounds, child_octant_at_position); let mat_index = Self::mat_index(&bounds, &V3c::from(*position)); if !brick[mat_index.x][mat_index.y][mat_index.z].is_empty() { return Some(&mut brick[mat_index.x][mat_index.y][mat_index.z]); } - return None; - } - BrickData::Solid(ref mut voxel) => { - return Some(voxel); + None } + BrickData::Solid(ref mut voxel) => Some(voxel), } } NodeContent::UniformLeaf(brick) => match brick { - BrickData::Empty => { - return None; - } + BrickData::Empty => None, BrickData::Parted(brick) => { - let mat_index = Self::mat_index(&bounds, &V3c::from(*position)); + let mat_index = Self::mat_index(bounds, &V3c::from(*position)); if brick[mat_index.x][mat_index.y][mat_index.z].is_empty() { return None; } - return Some(&mut brick[mat_index.x][mat_index.y][mat_index.z]); + Some(&mut brick[mat_index.x][mat_index.y][mat_index.z]) } BrickData::Solid(voxel) => { if voxel.is_empty() { return None; } - return Some(voxel); + Some(voxel) } }, - &mut NodeContent::Nothing | &mut NodeContent::Internal(_) => { - return None; - } + &mut NodeContent::Nothing | &mut NodeContent::Internal(_) => None, } } diff --git a/src/octree/raytracing/bevy/data.rs b/src/octree/raytracing/bevy/data.rs index d532f7d..6a49775 100644 --- a/src/octree/raytracing/bevy/data.rs +++ b/src/octree/raytracing/bevy/data.rs @@ -119,8 +119,10 @@ where BrickData::Empty => (empty_marker(), false), BrickData::Solid(voxel) => { let albedo = voxel.albedo(); - if !map_to_color_index_in_palette.contains_key(&albedo) { - map_to_color_index_in_palette.insert(albedo, color_palette.len()); + if let std::collections::hash_map::Entry::Vacant(e) = + map_to_color_index_in_palette.entry(albedo) + { + e.insert(color_palette.len()); color_palette.push(Vec4::new( albedo.r as f32 / 255., albedo.g as f32 / 255., @@ -144,8 +146,10 @@ where for y in 0..DIM { for x in 0..DIM { let albedo = brick[x][y][z].albedo(); - if !map_to_color_index_in_palette.contains_key(&albedo) { - map_to_color_index_in_palette.insert(albedo, color_palette.len()); + if let std::collections::hash_map::Entry::Vacant(e) = + map_to_color_index_in_palette.entry(albedo) + { + e.insert(color_palette.len()); color_palette.push(Vec4::new( albedo.r as f32 / 255., albedo.g as f32 / 255., @@ -190,7 +194,7 @@ where let mut map_to_node_index_in_nodes_buffer = HashMap::new(); for i in 0..self.nodes.len() { if self.nodes.key_is_valid(i) { - map_to_node_index_in_nodes_buffer.insert(i as usize, nodes.len()); + map_to_node_index_in_nodes_buffer.insert(i, nodes.len()); nodes.push(Self::create_node_properties(self.nodes.get(i))); } } diff --git a/src/octree/raytracing/raytracing_on_cpu.rs b/src/octree/raytracing/raytracing_on_cpu.rs index 4dba7bb..0b56fe6 100644 --- a/src/octree/raytracing/raytracing_on_cpu.rs +++ b/src/octree/raytracing/raytracing_on_cpu.rs @@ -61,7 +61,7 @@ where } else { self.head_index -= 1; } - return Some(result); + Some(result) } } @@ -69,14 +69,14 @@ where if 0 == self.count { None } else { - return Some(&self.data[self.head_index]); + Some(&self.data[self.head_index]) } } pub(crate) fn last_mut(&mut self) -> Option<&mut T> { if 0 == self.count { None } else { - return Some(&mut self.data[self.head_index]); + Some(&mut self.data[self.head_index]) } } } @@ -101,15 +101,15 @@ where } /// https://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm) - /// Calculate the length of the ray should its iteration be stepped one unit in the [x/y/z] direction. + /// Calculate the length of the ray in case the iteration is stepped one unit in the [x/y/z] direction. /// Changes with minimum ray iteration length shall be applied + /// inputs: current distances of the 3 components of the ray, unit size, Ray, scale factors of each xyz components + /// output: the step to the next sibling /// The step is also returned in the given unit size ( based on the cell bounds ) /// * `ray` - The ray to base the step on /// * `ray_current_distance` - The distance the ray iteration is currently at /// * `current_bounds` - The cell which boundaries the current ray iteration intersects /// * `ray_scale_factors` - Pre-computed dda values for the ray - /// inputs: current distances of the 3 components of the ray, unit size, Ray, scale factors of each xyz components - /// output: the step to the next sibling pub(crate) fn dda_step_to_next_sibling( ray: &Ray, ray_current_distance: &mut f32, @@ -238,7 +238,7 @@ where current_index += V3c::::from(step); position += step * Self::UNIT_IN_BITMAP_SPACE; } - return rgb_result; + rgb_result } /// Iterates on the given ray and brick to find a potential intersection in 3D space @@ -357,20 +357,20 @@ where } BrickData::Solid(voxel) => { let impact_point = ray.point_at(*ray_current_distance); - return Some(( - &voxel, + Some(( + voxel, impact_point, - cube_impact_normal(&brick_bounds, &impact_point), - )); + cube_impact_normal(brick_bounds, &impact_point), + )) } BrickData::Parted(brick) => { if let Some(leaf_brick_hit) = Self::traverse_brick( - &ray, + ray, ray_current_distance, brick, brick_occupied_bits, - &brick_bounds, - &ray_scale_factors, + brick_bounds, + ray_scale_factors, direction_lut_index, ) { let hit_bounds = Cube { @@ -396,13 +396,13 @@ where /// return reference of the data, collision point and normal at impact, should there be any pub fn get_by_ray(&self, ray: &Ray) -> Option<(&T, V3c, V3c)> { // Pre-calculated optimization variables - let ray_scale_factors = Self::get_dda_scale_factors(&ray); + let ray_scale_factors = Self::get_dda_scale_factors(ray); let direction_lut_index = hash_direction(&ray.direction) as usize; let mut node_stack: NodeStack = NodeStack::default(); let mut current_bounds = Cube::root_bounds(self.octree_size as f32); let (mut ray_current_distance, mut target_octant) = - if let Some(root_hit) = current_bounds.intersect_ray(&ray) { + if let Some(root_hit) = current_bounds.intersect_ray(ray) { let ray_current_distance = root_hit.impact_distance.unwrap_or(0.); ( ray_current_distance, @@ -493,7 +493,7 @@ where // POP node_stack.pop(); step_vec = Self::dda_step_to_next_sibling( - &ray, + ray, &mut ray_current_distance, ¤t_bounds, &ray_scale_factors, @@ -543,7 +543,7 @@ where loop { // step the iteration to the next sibling cell! step_vec = Self::dda_step_to_next_sibling( - &ray, + ray, &mut ray_current_distance, &target_bounds, &ray_scale_factors, @@ -572,7 +572,7 @@ where } }) // In case the current node is leaf - || match self.nodes.get(current_node_key as usize) { + || match self.nodes.get(current_node_key) { // Empty or internal nodes are not evaluated in this condition; // Basically if there's no hit with a uniformleaf // | It's either because the leaf is solid empty diff --git a/src/octree/update.rs b/src/octree/update.rs index 890ad6a..0acc919 100644 --- a/src/octree/update.rs +++ b/src/octree/update.rs @@ -58,7 +58,7 @@ where "Expected Node children to be OccupancyBitmaps instead of {:?}", self.node_children[node_key].content ); - match &mut bricks[target_child_octant as usize] { + match &mut bricks[target_child_octant] { //If there is no brick in the target position of the leaf, create one BrickData::Empty => { // Create a new empty brick at the given octant @@ -76,7 +76,7 @@ where }; // update the new empty brick at the given position - let mat_index = Self::mat_index(&target_bounds, &V3c::from(*position)); + let mat_index = Self::mat_index(target_bounds, position); Self::update_brick( &mut new_brick, mat_index, @@ -84,7 +84,7 @@ where &mut new_occupied_bits[target_child_octant], data, ); - bricks[target_child_octant as usize] = BrickData::Parted(new_brick); + bricks[target_child_octant] = BrickData::Parted(new_brick); self.node_children[node_key].content = NodeChildrenArray::OccupancyBitmaps(new_occupied_bits); } @@ -92,17 +92,17 @@ where debug_assert_eq!( u64::MAX, if let NodeChildrenArray::OccupancyBitmaps(occupied_bits) = - self.node_children[node_key as usize].content + self.node_children[node_key].content { - occupied_bits[target_child_octant as usize] + occupied_bits[target_child_octant] } else { 0xD34D }, "Solid full voxel should have its occupied bits set to u64::MAX, instead of {:?}", if let NodeChildrenArray::OccupancyBitmaps(occupied_bits) = - self.node_children[node_key as usize].content + self.node_children[node_key].content { - occupied_bits[target_child_octant as usize] + occupied_bits[target_child_octant] } else { 0xD34D } @@ -111,7 +111,7 @@ where if (data.is_none() && !voxel.is_empty()) || (data.is_some() && data.unwrap() != *voxel) { - let mut new_brick = Box::new([[[voxel.clone(); DIM]; DIM]; DIM]); + let mut new_brick = Box::new([[[*voxel; DIM]; DIM]; DIM]); let mut new_occupied_bits = if let NodeChildrenArray::OccupancyBitmaps(maps) = self.node_children[node_key].content @@ -124,7 +124,7 @@ where ); }; // update the new brick at the given position - let mat_index = Self::mat_index(&target_bounds, &V3c::from(*position)); + let mat_index = Self::mat_index(target_bounds, position); Self::update_brick( &mut new_brick, mat_index, @@ -132,7 +132,7 @@ where &mut new_occupied_bits[target_child_octant], data, ); - bricks[target_child_octant as usize] = BrickData::Parted(new_brick); + bricks[target_child_octant] = BrickData::Parted(new_brick); self.node_children[node_key].content = NodeChildrenArray::OccupancyBitmaps(new_occupied_bits); } else { @@ -141,7 +141,7 @@ where } BrickData::Parted(ref mut brick) => { // Let's update the brick at the given position - let mat_index = Self::mat_index(&target_bounds, &V3c::from(*position)); + let mat_index = Self::mat_index(target_bounds, position); if let NodeChildrenArray::OccupancyBitmaps(ref mut maps) = self.node_children[node_key].content { @@ -180,7 +180,7 @@ where // Add a brick to the target octant and update with the given data let mut new_brick = Box::new([[[T::default(); DIM]; DIM]; DIM]); - let mat_index = Self::mat_index(&target_bounds, &V3c::from(*position)); + let mat_index = Self::mat_index(target_bounds, position); Self::update_brick( &mut new_brick, mat_index, @@ -215,7 +215,7 @@ where } else { u64::MAX }); - *mat = BrickData::Parted(Box::new([[[voxel.clone(); DIM]; DIM]; DIM])); + *mat = BrickData::Parted(Box::new([[[*voxel; DIM]; DIM]; DIM])); self.leaf_update( node_key, @@ -235,7 +235,7 @@ where // The target position index is to be calculated from the node bounds, // instead of the target bounds because the position should cover the whole leaf // not just one brick in it - let mat_index = Self::mat_index(&node_bounds, &V3c::from(*position)); + let mat_index = Self::mat_index(node_bounds, position); let target_voxel = brick[mat_index.x][mat_index.y][mat_index.z]; if data.is_none() && target_voxel.is_empty() || data.is_some_and(|d| d == target_voxel) @@ -290,8 +290,7 @@ where // Also update the brick if it is the target if octant == target_child_octant { - let mat_index = - Self::mat_index(&target_bounds, &V3c::from(*position)); + let mat_index = Self::mat_index(target_bounds, position); Self::update_brick( &mut new_brick, mat_index, @@ -364,12 +363,12 @@ where data: Option, ) { let size = size.min(DIM); - mat_index.cut_each_component(&(DIM - size as usize)); + mat_index.cut_each_component(&(DIM - size)); for x in mat_index.x..(mat_index.x + size) { for y in mat_index.y..(mat_index.y + size) { for z in mat_index.z..(mat_index.z + size) { if let Some(data) = data { - brick[x][y][z] = data.clone(); + brick[x][y][z] = data; } else { brick[x][y][z].clear(); } @@ -859,8 +858,8 @@ where if !self.nodes.key_is_valid(child_keys[0] as usize) { // At least try to simplify the siblings - for octant in 1..8 { - self.simplify(child_keys[octant]); + for child_key in child_keys.iter().skip(1) { + self.simplify(*child_key); } return false; } diff --git a/src/spatial/math/mod.rs b/src/spatial/math/mod.rs index da5c66e..5f74890 100644 --- a/src/spatial/math/mod.rs +++ b/src/spatial/math/mod.rs @@ -36,6 +36,7 @@ pub fn hash_region(offset: &V3c, size_half: f32) -> u8 { } /// Maps direction vector to the octant it points to +#[cfg(feature = "raytracing")] pub(crate) fn hash_direction(direction: &V3c) -> u8 { debug_assert!((1.0 - direction.length()).abs() < 0.1); let offset = V3c::unit(1.) + *direction; diff --git a/src/spatial/raytracing/lut.rs b/src/spatial/raytracing/lut.rs index ac26ab6..5ecbadb 100644 --- a/src/spatial/raytracing/lut.rs +++ b/src/spatial/raytracing/lut.rs @@ -176,7 +176,7 @@ fn generate_octant_step_result_lut() -> [[[u32; 3]; 3]; 3] { for z in -1i32..=1 { for y in -1i32..=1 { for x in -1i32..=1 { - let result_octant = octant_after_step(&V3c::new(x, y, z), octant as u8); + let result_octant = octant_after_step(&V3c::new(x, y, z), octant); lut[(x + 1) as usize][(y + 1) as usize][(z + 1) as usize] |= (result_octant as u32 & 0x0F) << octant_pos_in_32bits; let octant_in_lut = (lut[(x + 1) as usize][(y + 1) as usize][(z + 1) as usize]