diff options
Diffstat (limited to 'azalea-physics/src')
| -rw-r--r-- | azalea-physics/src/collision/discrete_voxel_shape.rs | 137 | ||||
| -rw-r--r-- | azalea-physics/src/collision/mod.rs | 1 | ||||
| -rw-r--r-- | azalea-physics/src/collision/shape.rs | 36 |
3 files changed, 84 insertions, 90 deletions
diff --git a/azalea-physics/src/collision/discrete_voxel_shape.rs b/azalea-physics/src/collision/discrete_voxel_shape.rs index 033d1225..1d8de4db 100644 --- a/azalea-physics/src/collision/discrete_voxel_shape.rs +++ b/azalea-physics/src/collision/discrete_voxel_shape.rs @@ -3,6 +3,7 @@ use std::cmp; use azalea_core::{ bitset::BitSet, direction::{Axis, AxisCycle}, + position::Vec3i, }; use super::mergers::IndexMerger; @@ -47,22 +48,22 @@ impl DiscreteVoxelShape { false } - pub fn is_full_wide(&self, x: i32, y: i32, z: i32) -> bool { - if x < 0 || y < 0 || z < 0 { + pub fn is_full_wide(&self, pos: Vec3i) -> bool { + if pos.x < 0 || pos.y < 0 || pos.z < 0 { return false; } - let (x, y, z) = (x as u32, y as u32, z as u32); + let (x, y, z) = (pos.x as u32, pos.y as u32, pos.z as u32); (x < self.size(Axis::X) && y < self.size(Axis::Y) && z < self.size(Axis::Z)) && (self.is_full(x, y, z)) } - pub fn is_full_wide_axis_cycle(&self, axis_cycle: AxisCycle, x: i32, y: i32, z: i32) -> bool { - self.is_full_wide( - axis_cycle.cycle_xyz(x, y, z, Axis::X), - axis_cycle.cycle_xyz(x, y, z, Axis::Y), - axis_cycle.cycle_xyz(x, y, z, Axis::Z), - ) + pub fn is_full_wide_axis_cycle(&self, axis_cycle: AxisCycle, pos: Vec3i) -> bool { + self.is_full_wide(Vec3i { + x: axis_cycle.cycle_xyz(pos, Axis::X), + y: axis_cycle.cycle_xyz(pos, Axis::Y), + z: axis_cycle.cycle_xyz(pos, Axis::Z), + }) } pub fn is_full(&self, x: u32, y: u32, z: u32) -> bool { @@ -83,12 +84,8 @@ pub struct BitSetDiscreteVoxelShape { z_size: u32, storage: BitSet, - x_min: i32, - y_min: i32, - z_min: i32, - x_max: i32, - y_max: i32, - z_max: i32, + min: Vec3i, + max: Vec3i, } impl BitSetDiscreteVoxelShape { @@ -99,12 +96,12 @@ impl BitSetDiscreteVoxelShape { z_size: z_min, storage: BitSet::new((x_min * y_min * z_min).try_into().unwrap()), - x_min: z_min.try_into().unwrap(), - y_min: z_min.try_into().unwrap(), - z_min: z_min.try_into().unwrap(), - x_max: 0, - y_max: 0, - z_max: 0, + min: Vec3i { + x: z_min.try_into().unwrap(), + y: z_min.try_into().unwrap(), + z: z_min.try_into().unwrap(), + }, + max: Vec3i::ZERO, } } @@ -114,24 +111,16 @@ impl BitSetDiscreteVoxelShape { x_size: u32, y_size: u32, z_size: u32, - x_min: i32, - y_min: i32, - z_min: i32, - x_max: i32, - y_max: i32, - z_max: i32, + min: Vec3i, + max: Vec3i, ) -> Self { let mut shape = BitSetDiscreteVoxelShape::new(x_size, y_size, z_size); - shape.x_min = x_min; - shape.y_min = y_min; - shape.z_min = z_min; - shape.x_max = x_max; - shape.y_max = y_max; - shape.z_max = z_max; - - for x in x_min..x_max { - for y in y_min..y_max { - for z in z_min..z_max { + shape.min = min; + shape.max = max; + + for x in min.x..max.x { + for y in min.y..max.y { + for z in min.z..max.z { shape.fill_update_bounds( x.try_into().unwrap(), y.try_into().unwrap(), @@ -148,12 +137,10 @@ impl BitSetDiscreteVoxelShape { fn fill_update_bounds(&mut self, x: u32, y: u32, z: u32, update: bool) { self.storage.set(self.get_index(x, y, z)); if update { - self.x_min = cmp::min(self.x_min, x as i32); - self.y_min = cmp::min(self.y_min, y as i32); - self.z_min = cmp::min(self.z_min, z as i32); - self.x_max = cmp::max(self.x_max, (x + 1) as i32); - self.y_max = cmp::max(self.y_max, (y + 1) as i32); - self.z_max = cmp::max(self.z_max, (z + 1) as i32); + let candidate_min = Vec3i::new(x as i32, y as i32, z as i32); + self.min = self.min.min(candidate_min); + let candidate_max = Vec3i::new((x + 1) as i32, (y + 1) as i32, (z + 1) as i32); + self.max = self.max.max(candidate_max); } } @@ -174,7 +161,7 @@ impl BitSetDiscreteVoxelShape { var2: &IndexMerger, var3: &IndexMerger, var4: &IndexMerger, - var5: impl Fn(bool, bool) -> bool, + op: impl Fn(bool, bool) -> bool, ) -> Self { let mut var6 = BitSetDiscreteVoxelShape::new( (var2.size() - 1) as u32, @@ -189,48 +176,48 @@ impl BitSetDiscreteVoxelShape { -2147483648, -2147483648, ]; - var2.for_merged_indexes(|var7x: i32, var8: i32, var9: i32| { + var2.for_merged_indexes(|x1: i32, x2: i32, x3: i32| { let mut var10 = [false]; - var3.for_merged_indexes(|var10x: i32, var11: i32, var12: i32| { + var3.for_merged_indexes(|y1: i32, y2: i32, y3: i32| { let mut var13 = [false]; - var4.for_merged_indexes(|var12x: i32, var13x: i32, var14: i32| { - if var5( - var0.is_full_wide(var7x, var10x, var12x), - var1.is_full_wide(var8, var11, var13x), + var4.for_merged_indexes(|z1: i32, z2: i32, z3: i32| { + if op( + var0.is_full_wide(Vec3i::new(x1, y1, z1)), + var1.is_full_wide(Vec3i::new(x2, y2, z2)), ) { var6.storage.set(var6.get_index( - var9.try_into().unwrap(), - var12.try_into().unwrap(), - var14.try_into().unwrap(), + x3.try_into().unwrap(), + y3.try_into().unwrap(), + z3.try_into().unwrap(), )); - var7[2] = cmp::min(var7[2], var14); - var7[5] = cmp::max(var7[5], var14); + var7[2] = cmp::min(var7[2], z3); + var7[5] = cmp::max(var7[5], z3); var13[0] = true; } true }); if var13[0] { - var7[1] = cmp::min(var7[1], var12); - var7[4] = cmp::max(var7[4], var12); + var7[1] = cmp::min(var7[1], y3); + var7[4] = cmp::max(var7[4], y3); var10[0] = true; } true }); if var10[0] { - var7[0] = cmp::min(var7[0], var9); - var7[3] = cmp::max(var7[3], var9); + var7[0] = cmp::min(var7[0], x3); + var7[3] = cmp::max(var7[3], x3); } true }); - var6.x_min = var7[0]; - var6.y_min = var7[1]; - var6.z_min = var7[2]; - var6.x_max = var7[3] + 1; - var6.y_max = var7[4] + 1; - var6.z_max = var7[5] + 1; + var6.min.x = var7[0]; + var6.min.y = var7[1]; + var6.min.z = var7[2]; + var6.max.x = var7[3] + 1; + var6.max.y = var7[4] + 1; + var6.max.z = var7[5] + 1; var6 } @@ -306,11 +293,11 @@ impl BitSetDiscreteVoxelShape { } fn first_full(&self, axis: Axis) -> i32 { - axis.choose(self.x_min, self.y_min, self.z_min) + axis.choose(self.min.x, self.min.y, self.min.z) } fn last_full(&self, axis: Axis) -> i32 { - axis.choose(self.x_max, self.y_max, self.z_max) + axis.choose(self.max.x, self.max.y, self.max.z) } fn is_full(&self, x: u32, y: u32, z: u32) -> bool { @@ -351,12 +338,16 @@ impl From<&DiscreteVoxelShape> for BitSetDiscreteVoxelShape { y_size, z_size, storage, - x_min: shape.first_full(Axis::X), - y_min: shape.first_full(Axis::Y), - z_min: shape.first_full(Axis::Z), - x_max: shape.last_full(Axis::X), - y_max: shape.last_full(Axis::Y), - z_max: shape.last_full(Axis::Z), + min: Vec3i { + x: shape.first_full(Axis::X), + y: shape.first_full(Axis::Y), + z: shape.first_full(Axis::Z), + }, + max: Vec3i { + x: shape.last_full(Axis::X), + y: shape.last_full(Axis::Y), + z: shape.last_full(Axis::Z), + }, } } } diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs index 10b607f2..e6423fc4 100644 --- a/azalea-physics/src/collision/mod.rs +++ b/azalea-physics/src/collision/mod.rs @@ -129,7 +129,6 @@ pub struct MoveCtx<'world, 'state, 'a, 'b> { /// Move an entity by a given delta, checking for collisions. /// /// In Mojmap, this is `Entity.move`. -#[allow(clippy::too_many_arguments)] pub fn move_colliding(ctx: &mut MoveCtx, mut movement: Vec3) { // TODO: do all these diff --git a/azalea-physics/src/collision/shape.rs b/azalea-physics/src/collision/shape.rs index 96506922..fedc8a79 100644 --- a/azalea-physics/src/collision/shape.rs +++ b/azalea-physics/src/collision/shape.rs @@ -4,7 +4,7 @@ use azalea_core::{ direction::{Axis, AxisCycle, Direction}, hit_result::BlockHitResult, math::{EPSILON, binary_search}, - position::{BlockPos, Vec3}, + position::{BlockPos, Vec3, Vec3i}, }; use super::mergers::IndexMerger; @@ -56,12 +56,16 @@ pub fn box_shape( x_bits, y_bits, z_bits, - (min_x * x_bits as f64).round() as i32, - (min_y * y_bits as f64).round() as i32, - (min_z * z_bits as f64).round() as i32, - (max_x * x_bits as f64).round() as i32, - (max_y * y_bits as f64).round() as i32, - (max_z * z_bits as f64).round() as i32, + Vec3i { + x: (min_x * x_bits as f64).round() as i32, + y: (min_y * y_bits as f64).round() as i32, + z: (min_z * z_bits as f64).round() as i32, + }, + Vec3i { + x: (max_x * x_bits as f64).round() as i32, + y: (max_y * y_bits as f64).round() as i32, + z: (max_z * z_bits as f64).round() as i32, + }, ); VoxelShape::Cube(CubeVoxelShape::new(DiscreteVoxelShape::BitSet(shape))) } @@ -262,12 +266,12 @@ impl Shapes { shape2: DiscreteVoxelShape, op: impl Fn(bool, bool) -> bool, ) -> bool { - !merged_x.for_merged_indexes(|var5x, var6, _var7| { - merged_y.for_merged_indexes(|var6x, var7x, _var8| { - merged_z.for_merged_indexes(|var7, var8x, _var9| { + !merged_x.for_merged_indexes(|x, x2, _x3| { + merged_y.for_merged_indexes(|y, y2, _y3| { + merged_z.for_merged_indexes(|z, z2, _z3| { !op( - shape1.is_full_wide(var5x, var6x, var7), - shape2.is_full_wide(var6, var7x, var8x), + shape1.is_full_wide(Vec3i::new(x, y, z)), + shape2.is_full_wide(Vec3i::new(x2, y2, z2)), ) }) }) @@ -418,11 +422,11 @@ impl VoxelShape { } let right_after_start = from + (vector * 0.001); - if self.shape().is_full_wide( + if self.shape().is_full_wide(Vec3i::new( self.find_index(Axis::X, right_after_start.x - block_pos.x as f64), self.find_index(Axis::Y, right_after_start.y - block_pos.y as f64), self.find_index(Axis::Z, right_after_start.z - block_pos.z as f64), - ) { + )) { Some(BlockHitResult { block_pos, direction: Direction::nearest(vector).opposite(), @@ -483,7 +487,7 @@ impl VoxelShape { for z in z_min_index..z_max_index { if self .shape() - .is_full_wide_axis_cycle(inverse_axis_cycle, x, y, z) + .is_full_wide_axis_cycle(inverse_axis_cycle, Vec3i { x, y, z }) { let var23 = self.get(x_axis, x as usize) - max_x; if var23 >= -EPSILON { @@ -500,7 +504,7 @@ impl VoxelShape { for z in z_min_index..z_max_index { if self .shape() - .is_full_wide_axis_cycle(inverse_axis_cycle, x, y, z) + .is_full_wide_axis_cycle(inverse_axis_cycle, Vec3i { x, y, z }) { let var23 = self.get(x_axis, (x + 1) as usize) - min_x; if var23 <= EPSILON { |
