diff options
| author | mat <git@matdoes.dev> | 2024-12-27 12:30:24 +0000 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2024-12-27 12:35:25 +0000 |
| commit | 5693191b57973136188bdade2144a69ac61a9f8a (patch) | |
| tree | d60611362019bc4134404ff62104743884efe4e2 /azalea-physics/src/collision | |
| parent | 04036b6e4afe1e3eb59cd861a871e17ea5680f5f (diff) | |
| download | azalea-drasl-5693191b57973136188bdade2144a69ac61a9f8a.tar.xz | |
implement fluid_shape
Diffstat (limited to 'azalea-physics/src/collision')
| -rw-r--r-- | azalea-physics/src/collision/mod.rs | 60 | ||||
| -rwxr-xr-x | azalea-physics/src/collision/shape.rs | 2 |
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 } } } |
