aboutsummaryrefslogtreecommitdiff
path: root/azalea-physics/src/collision
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2024-12-27 12:30:24 +0000
committermat <git@matdoes.dev>2024-12-27 12:35:25 +0000
commit5693191b57973136188bdade2144a69ac61a9f8a (patch)
treed60611362019bc4134404ff62104743884efe4e2 /azalea-physics/src/collision
parent04036b6e4afe1e3eb59cd861a871e17ea5680f5f (diff)
downloadazalea-drasl-5693191b57973136188bdade2144a69ac61a9f8a.tar.xz
implement fluid_shape
Diffstat (limited to 'azalea-physics/src/collision')
-rw-r--r--azalea-physics/src/collision/mod.rs60
-rwxr-xr-xazalea-physics/src/collision/shape.rs2
2 files changed, 57 insertions, 5 deletions
diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs
index 913cedac..bff9d6f8 100644
--- a/azalea-physics/src/collision/mod.rs
+++ b/azalea-physics/src/collision/mod.rs
@@ -4,14 +4,21 @@ mod mergers;
mod shape;
mod world_collisions;
-use std::ops::Add;
-
-use azalea_core::{aabb::AABB, direction::Axis, math::EPSILON, position::Vec3};
-use azalea_world::{Instance, MoveEntityError};
+use std::{ops::Add, sync::LazyLock};
+
+use azalea_block::FluidState;
+use azalea_core::{
+ aabb::AABB,
+ direction::Axis,
+ math::EPSILON,
+ position::{BlockPos, Vec3},
+};
+use azalea_world::{ChunkStorage, Instance, MoveEntityError};
use bevy_ecs::world::Mut;
pub use blocks::BlockWithShape;
pub use discrete_voxel_shape::*;
pub use shape::*;
+use tracing::warn;
use self::world_collisions::get_block_collisions;
@@ -333,3 +340,48 @@ fn collide_with_shapes(
z: z_movement,
}
}
+
+/// Get the [`VoxelShape`] for the given fluid state.
+///
+/// The instance and position are required so it can check if the block above is
+/// also the same fluid type.
+pub fn fluid_shape(
+ fluid: &FluidState,
+ world: &ChunkStorage,
+ pos: &BlockPos,
+) -> &'static VoxelShape {
+ if fluid.amount == 9 {
+ let fluid_state_above = world.get_fluid_state(&pos.up(1)).unwrap_or_default();
+ if fluid_state_above.fluid == fluid.fluid {
+ return &BLOCK_SHAPE;
+ }
+ }
+
+ // pre-calculate these in a LazyLock so this function can return a
+ // reference instead
+
+ static FLUID_SHAPES: LazyLock<[VoxelShape; 10]> = LazyLock::new(|| {
+ [
+ calculate_shape_for_fluid(0),
+ calculate_shape_for_fluid(1),
+ calculate_shape_for_fluid(2),
+ calculate_shape_for_fluid(3),
+ calculate_shape_for_fluid(4),
+ calculate_shape_for_fluid(5),
+ calculate_shape_for_fluid(6),
+ calculate_shape_for_fluid(7),
+ calculate_shape_for_fluid(8),
+ calculate_shape_for_fluid(9),
+ ]
+ });
+
+ if fluid.amount > 9 {
+ warn!("Tried to calculate shape for fluid with height > 9: {fluid:?} at {pos}");
+ return &EMPTY_SHAPE;
+ }
+
+ &FLUID_SHAPES[fluid.amount as usize]
+}
+fn calculate_shape_for_fluid(amount: u8) -> VoxelShape {
+ box_shape(0.0, 0.0, 0.0, 1.0, (f32::from(amount) / 9.0) as f64, 1.0)
+}
diff --git a/azalea-physics/src/collision/shape.rs b/azalea-physics/src/collision/shape.rs
index e7ac9c2e..fb733cae 100755
--- a/azalea-physics/src/collision/shape.rs
+++ b/azalea-physics/src/collision/shape.rs
@@ -413,7 +413,7 @@ impl VoxelShape {
VoxelShape::Cube(s) => s.find_index(axis, coord),
_ => {
let upper_limit = (self.shape().size(axis) + 1) as i32;
- binary_search(0, upper_limit, &|t| coord < self.get(axis, t as usize)) - 1
+ binary_search(0, upper_limit, |t| coord < self.get(axis, t as usize)) - 1
}
}
}