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

Shapes stuff

This commit is contained in:
mat 2022-06-29 16:00:04 -05:00
parent cf3fcc2bbf
commit 11c5f6f237
5 changed files with 106 additions and 15 deletions

View file

@ -1,5 +1,7 @@
use azalea_buf::McBuf;
use crate::floor_mod;
#[derive(Clone, Copy, Debug, McBuf)]
pub enum Direction {
Down = 0,
@ -9,3 +11,29 @@ pub enum Direction {
West = 4,
East = 5,
}
pub enum Axis {
X,
Y,
Z,
}
pub enum AxisCycle {
None,
Forward,
Backward,
}
impl AxisCycle {
pub fn from_ordinal(ordinal: u32) -> Self {
match ordinal {
0 => Self::None,
1 => Self::Forward,
2 => Self::Backward,
_ => panic!("invalid ordinal"),
}
}
pub fn between(axis0: Axis, axis1: Axis) -> Self {
Self::from_ordinal(floor_mod(axis1 as i32 - axis0 as i32, 3))
}
}

View file

@ -12,13 +12,13 @@ mod game_type;
pub use game_type::*;
mod slot;
pub use slot::{Slot, SlotData};
pub use slot::*;
mod position;
pub use position::*;
mod direction;
pub use direction::Direction;
pub use direction::*;
mod delta;
pub use delta::*;
@ -31,3 +31,13 @@ pub use cursor3d::*;
mod bitset;
pub use bitset::*;
// java moment
// TODO: add tests and optimize/simplify this
pub fn floor_mod(x: i32, y: u32) -> u32 {
if x < 0 {
y - ((-x) as u32 % y)
} else {
x as u32 % y
}
}

View file

@ -100,7 +100,46 @@ impl HasPhysics for Entity {
entity_box: &AABB,
collision_boxes: &Vec<Box<dyn VoxelShape>>,
) -> Vec3 {
// TODO
*movement
if collision_boxes.is_empty() {
return *movement;
}
let mut x_movement = movement.x;
let mut y_movement = movement.y;
let mut z_movement = movement.z;
if y_movement != 0. {
y_movement = Shapes::collide_y(entity_box, collision_boxes, y_movement);
if y_movement != 0. {
*entity_box = entity_box.move_relative(0., y_movement, 0.);
}
}
// whether the player is moving more in the z axis than x
// this is done to fix a movement bug, minecraft does this too
let more_z_movement = x_movement.abs() < z_movement.abs();
if more_z_movement && z_movement != 0. {
z_movement = Shapes::collide_z(entity_box, collision_boxes, z_movement);
if z_movement != 0. {
*entity_box = entity_box.move_relative(0., 0., z_movement);
}
}
if x_movement != 0. {
x_movement = Shapes::collide_x(entity_box, collision_boxes, x_movement);
if x_movement != 0. {
*entity_box = entity_box.move_relative(x_movement, 0., 0.);
}
}
if !more_z_movement && z_movement != 0. {
z_movement = Shapes::collide_z(entity_box, collision_boxes, z_movement);
}
Vec3 {
x: x_movement,
y: y_movement,
z: z_movement,
}
}
}

View file

@ -1,4 +1,6 @@
use crate::{BitSetDiscreteVoxelShape, DiscreteVoxelShape};
use azalea_core::Axis;
use crate::{BitSetDiscreteVoxelShape, DiscreteVoxelShape, AABB, EPSILON};
use std::ops::Add;
pub struct Shapes {}
@ -17,6 +19,23 @@ pub fn empty_shape() -> Box<dyn VoxelShape> {
))
}
impl Shapes {
pub fn collide_x(
entity_box: &AABB,
collision_boxes: &Vec<Box<dyn VoxelShape>>,
movement: f64,
) -> f64 {
let mut shape: Box<dyn VoxelShape>;
for shape in collision_boxes {
if movement.abs() < EPSILON {
return 0.;
}
movement = shape.collide_x(entity_box, movement);
}
movement
}
}
pub trait VoxelShape {
fn shape(&self) -> Box<dyn DiscreteVoxelShape>;
@ -37,6 +56,10 @@ pub trait VoxelShape {
self.get_z_coords().iter().map(|c| c + z).collect(),
))
}
fn collide(axis: &Axis, entity_box: &AABB, movement: f64) {
self.collide_x()
}
}
pub struct ArrayVoxelShape {

View file

@ -3,6 +3,7 @@ use crate::palette::PalettedContainerType;
use crate::Dimension;
use azalea_block::BlockState;
use azalea_buf::{McBufReadable, McBufWritable};
use azalea_core::floor_mod;
use azalea_core::{BlockPos, ChunkBlockPos, ChunkPos, ChunkSectionBlockPos};
use std::fmt::Debug;
use std::{
@ -23,16 +24,6 @@ pub struct ChunkStorage {
chunks: Vec<Option<Arc<Mutex<Chunk>>>>,
}
// java moment
// it might be possible to replace this with just a modulo, but i copied java's floorMod just in case
fn floor_mod(x: i32, y: u32) -> u32 {
if x < 0 {
y - ((-x) as u32 % y)
} else {
x as u32 % y
}
}
impl ChunkStorage {
pub fn new(chunk_radius: u32, height: u32, min_y: i32) -> Self {
let view_range = chunk_radius * 2 + 1;