1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

collide_x but it doesn't work yet

This commit is contained in:
mat 2022-06-29 17:41:00 -05:00
parent 11c5f6f237
commit 2782a2dd13
3 changed files with 125 additions and 17 deletions

View file

@ -12,18 +12,32 @@ pub enum Direction {
East = 5, East = 5,
} }
#[derive(Clone, Copy, Debug)]
pub enum Axis { pub enum Axis {
X, X,
Y, Y,
Z, Z,
} }
#[derive(Clone, Copy, Debug)]
pub enum AxisCycle { pub enum AxisCycle {
None, None,
Forward, Forward,
Backward, Backward,
} }
impl Axis {
/// Pick x, y, or z from the arguments depending on the axis.
#[inline]
pub fn choose<T>(&self, x: T, y: T, z: T) -> T {
match self {
Axis::X => x,
Axis::Y => y,
Axis::Z => z,
}
}
}
impl AxisCycle { impl AxisCycle {
pub fn from_ordinal(ordinal: u32) -> Self { pub fn from_ordinal(ordinal: u32) -> Self {
match ordinal { match ordinal {
@ -36,4 +50,18 @@ impl AxisCycle {
pub fn between(axis0: Axis, axis1: Axis) -> Self { pub fn between(axis0: Axis, axis1: Axis) -> Self {
Self::from_ordinal(floor_mod(axis1 as i32 - axis0 as i32, 3)) Self::from_ordinal(floor_mod(axis1 as i32 - axis0 as i32, 3))
} }
pub fn inverse(self) -> Self {
match self {
Self::None => Self::None,
Self::Forward => Self::Backward,
Self::Backward => Self::Forward,
}
}
pub fn cycle(self, axis: Axis) -> Self {
match self {
Self::None => Self::None,
Self::Forward => Self::from_ordinal(floor_mod(axis as i32 + 1, 3)),
Self::Backward => Self::from_ordinal(floor_mod(axis as i32 - 1, 3)),
}
}
} }

View file

@ -1,5 +1,5 @@
use crate::BlockHitResult; use crate::BlockHitResult;
use azalea_core::{BlockPos, Direction, PositionXYZ, Vec3}; use azalea_core::{Axis, BlockPos, Direction, PositionXYZ, Vec3};
pub const EPSILON: f64 = 1.0E-7; pub const EPSILON: f64 = 1.0E-7;
@ -193,20 +193,18 @@ impl AABB {
} }
pub fn size(&self) -> f64 { pub fn size(&self) -> f64 {
let x = self.get_xsize(); let x = self.get_size(Axis::X);
let y = self.get_ysize(); let y = self.get_size(Axis::Y);
let z = self.get_zsize(); let z = self.get_size(Axis::Z);
(x + y + z) / 3.0 (x + y + z) / 3.0
} }
pub fn get_xsize(&self) -> f64 { pub fn get_size(&self, axis: Axis) -> f64 {
self.max_x - self.min_x axis.choose(
} self.max_x - self.min_x,
pub fn get_ysize(&self) -> f64 { self.max_y - self.min_y,
self.max_y - self.min_y self.max_z - self.min_z,
} )
pub fn get_zsize(&self) -> f64 {
self.max_z - self.min_z
} }
pub fn deflate(&mut self, x: f64, y: f64, z: f64) -> AABB { pub fn deflate(&mut self, x: f64, y: f64, z: f64) -> AABB {
@ -437,4 +435,11 @@ impl AABB {
max_z: center.z + dz / 2.0, max_z: center.z + dz / 2.0,
} }
} }
pub fn max(&self, axis: &Axis) -> f64 {
axis.choose(self.max_x, self.max_y, self.max_z)
}
pub fn min(&self, axis: &Axis) -> f64 {
axis.choose(self.min_x, self.min_y, self.min_z)
}
} }

View file

@ -1,4 +1,4 @@
use azalea_core::Axis; use azalea_core::{Axis, AxisCycle};
use crate::{BitSetDiscreteVoxelShape, DiscreteVoxelShape, AABB, EPSILON}; use crate::{BitSetDiscreteVoxelShape, DiscreteVoxelShape, AABB, EPSILON};
use std::ops::Add; use std::ops::Add;
@ -20,7 +20,8 @@ pub fn empty_shape() -> Box<dyn VoxelShape> {
} }
impl Shapes { impl Shapes {
pub fn collide_x( pub fn collide(
axis: &Axis,
entity_box: &AABB, entity_box: &AABB,
collision_boxes: &Vec<Box<dyn VoxelShape>>, collision_boxes: &Vec<Box<dyn VoxelShape>>,
movement: f64, movement: f64,
@ -30,7 +31,7 @@ impl Shapes {
if movement.abs() < EPSILON { if movement.abs() < EPSILON {
return 0.; return 0.;
} }
movement = shape.collide_x(entity_box, movement); movement = shape.collide(axis, entity_box, movement);
} }
movement movement
} }
@ -57,8 +58,82 @@ pub trait VoxelShape {
)) ))
} }
fn collide(axis: &Axis, entity_box: &AABB, movement: f64) { fn collide(&self, axis: &Axis, entity_box: &AABB, movement: f64) -> f64 {
self.collide_x() self.collide_x(AxisCycle::between(*axis, Axis::X), entity_box, movement)
}
fn collide_x(&self, axis_cycle: AxisCycle, entity_box: &AABB, movement: f64) -> f64 {
if self.shape().is_empty() {
return movement;
}
if movement.abs() < EPSILON {
return 0.;
}
let inverse_axis_cycle = axis_cycle.inverse();
// probably not good names but idk what this does
let x_axis = inverse_axis_cycle.cycle(Axis::X);
let y_axis = inverse_axis_cycle.cycle(Axis::Y);
let z_axis = inverse_axis_cycle.cycle(Axis::Z);
// i gave up on names at this point (these are the obfuscated names from fernflower)
let var9 = entity_box.max(x_axis);
let var11 = entity_box.min(x_axis);
let var13 = self.find_index(x_axis, var11 + EPSILON);
let var14 = self.find_index(x_axis, var9 - EPSILON);
let var15 = cmp::max(0, self.find_index(y_axis, entity_box.min(y_axis) + EPSILON));
let var16 = cmp::min(
self.shape().get_size(y_axis),
self.find_index(y_axis, entity_box.max(y_axis) - EPSILON) + 1,
);
let var17 = cmp::max(0, self.find_index(z_axis, entity_box.min(z_axis) + EPSILON));
let var18 = cmp::min(
self.shape().get_size(z_axis),
self.find_index(z_axis, entity_box.max(z_axis) - EPSILON) + 1,
);
let var19 = self.shape().get_size(x_axis);
if movement > 0. {
for var20 in var14 + 1..var19 {
for var21 in var15..var16 {
for var22 in var17..var18 {
if self
.shape()
.is_full_wide(inverse_axis_cycle, var20, var21, var22)
{
let var23 = self.get(x_axis, var20) - var9;
if var23 >= -EPSILON {
movement = cmp::min(movement, var23);
}
return movement;
}
}
}
}
} else if movement < 0. {
for var20 in (var13 - 1)..=0 {
for var21 in var15..var16 {
for var22 in var17..var18 {
if self
.shape()
.is_full_wide(inverse_axis_cycle, var20, var21, var22)
{
let var23 = self.get(x_axis, var20 + 1) - var11;
if var23 <= EPSILON {
movement = cmp::max(movement, var23);
}
return movement;
}
}
}
}
}
return movement;
} }
} }