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:
parent
11c5f6f237
commit
2782a2dd13
3 changed files with 125 additions and 17 deletions
|
@ -12,18 +12,32 @@ pub enum Direction {
|
|||
East = 5,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Axis {
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum AxisCycle {
|
||||
None,
|
||||
Forward,
|
||||
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 {
|
||||
pub fn from_ordinal(ordinal: u32) -> Self {
|
||||
match ordinal {
|
||||
|
@ -36,4 +50,18 @@ impl AxisCycle {
|
|||
pub fn between(axis0: Axis, axis1: Axis) -> Self {
|
||||
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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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;
|
||||
|
||||
|
@ -193,20 +193,18 @@ impl AABB {
|
|||
}
|
||||
|
||||
pub fn size(&self) -> f64 {
|
||||
let x = self.get_xsize();
|
||||
let y = self.get_ysize();
|
||||
let z = self.get_zsize();
|
||||
let x = self.get_size(Axis::X);
|
||||
let y = self.get_size(Axis::Y);
|
||||
let z = self.get_size(Axis::Z);
|
||||
(x + y + z) / 3.0
|
||||
}
|
||||
|
||||
pub fn get_xsize(&self) -> f64 {
|
||||
self.max_x - self.min_x
|
||||
}
|
||||
pub fn get_ysize(&self) -> f64 {
|
||||
self.max_y - self.min_y
|
||||
}
|
||||
pub fn get_zsize(&self) -> f64 {
|
||||
self.max_z - self.min_z
|
||||
pub fn get_size(&self, axis: Axis) -> f64 {
|
||||
axis.choose(
|
||||
self.max_x - self.min_x,
|
||||
self.max_y - self.min_y,
|
||||
self.max_z - self.min_z,
|
||||
)
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use azalea_core::Axis;
|
||||
use azalea_core::{Axis, AxisCycle};
|
||||
|
||||
use crate::{BitSetDiscreteVoxelShape, DiscreteVoxelShape, AABB, EPSILON};
|
||||
use std::ops::Add;
|
||||
|
@ -20,7 +20,8 @@ pub fn empty_shape() -> Box<dyn VoxelShape> {
|
|||
}
|
||||
|
||||
impl Shapes {
|
||||
pub fn collide_x(
|
||||
pub fn collide(
|
||||
axis: &Axis,
|
||||
entity_box: &AABB,
|
||||
collision_boxes: &Vec<Box<dyn VoxelShape>>,
|
||||
movement: f64,
|
||||
|
@ -30,7 +31,7 @@ impl Shapes {
|
|||
if movement.abs() < EPSILON {
|
||||
return 0.;
|
||||
}
|
||||
movement = shape.collide_x(entity_box, movement);
|
||||
movement = shape.collide(axis, entity_box, movement);
|
||||
}
|
||||
movement
|
||||
}
|
||||
|
@ -57,8 +58,82 @@ pub trait VoxelShape {
|
|||
))
|
||||
}
|
||||
|
||||
fn collide(axis: &Axis, entity_box: &AABB, movement: f64) {
|
||||
self.collide_x()
|
||||
fn collide(&self, axis: &Axis, entity_box: &AABB, movement: f64) -> f64 {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue