aboutsummaryrefslogtreecommitdiff
path: root/azalea-physics/src/collision
diff options
context:
space:
mode:
Diffstat (limited to 'azalea-physics/src/collision')
-rwxr-xr-xazalea-physics/src/collision/discrete_voxel_shape.rs2
-rw-r--r--azalea-physics/src/collision/mod.rs304
-rwxr-xr-xazalea-physics/src/collision/shape.rs2
-rw-r--r--azalea-physics/src/collision/world_collisions.rs39
4 files changed, 154 insertions, 193 deletions
diff --git a/azalea-physics/src/collision/discrete_voxel_shape.rs b/azalea-physics/src/collision/discrete_voxel_shape.rs
index 51d45316..4a329398 100755
--- a/azalea-physics/src/collision/discrete_voxel_shape.rs
+++ b/azalea-physics/src/collision/discrete_voxel_shape.rs
@@ -64,7 +64,7 @@ impl DiscreteVoxelShape {
}
pub fn for_all_boxes(&self, consumer: impl IntLineConsumer, swap: bool) {
- BitSetDiscreteVoxelShape::for_all_boxes(self, consumer, swap)
+ BitSetDiscreteVoxelShape::for_all_boxes(self, consumer, swap);
}
}
diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs
index 458303c5..7d934020 100644
--- a/azalea-physics/src/collision/mod.rs
+++ b/azalea-physics/src/collision/mod.rs
@@ -5,13 +5,15 @@ mod shape;
mod world_collisions;
use azalea_core::{Axis, Vec3, AABB, EPSILON};
-use azalea_world::entity::{Entity, EntityData};
-use azalea_world::{MoveEntityError, WeakWorld};
+use azalea_world::{
+ entity::{self},
+ MoveEntityError, World,
+};
pub use blocks::BlockWithShape;
pub use discrete_voxel_shape::*;
pub use shape::*;
-use std::ops::Deref;
-use world_collisions::CollisionGetter;
+
+use self::world_collisions::get_block_collisions;
pub enum MoverType {
Own,
@@ -21,192 +23,170 @@ pub enum MoverType {
Shulker,
}
-pub trait HasCollision {
- fn collide(&self, movement: &Vec3, entity: &EntityData) -> Vec3;
-}
+// private Vec3 collide(Vec3 var1) {
+// AABB var2 = this.getBoundingBox();
+// List var3 = this.level.getEntityCollisions(this,
+// var2.expandTowards(var1)); Vec3 var4 = var1.lengthSqr() == 0.0D ?
+// var1 : collideBoundingBox(this, var1, var2, this.level, var3);
+// boolean var5 = var1.x != var4.x;
+// boolean var6 = var1.y != var4.y;
+// boolean var7 = var1.z != var4.z;
+// boolean var8 = this.onGround || var6 && var1.y < 0.0D;
+// if (this.maxUpStep > 0.0F && var8 && (var5 || var7)) {
+// Vec3 var9 = collideBoundingBox(this, new Vec3(var1.x,
+// (double)this.maxUpStep, var1.z), var2, this.level, var3); Vec3
+// var10 = collideBoundingBox(this, new Vec3(0.0D, (double)this.maxUpStep,
+// 0.0D), var2.expandTowards(var1.x, 0.0D, var1.z), this.level, var3);
+// if (var10.y < (double)this.maxUpStep) {
+// Vec3 var11 = collideBoundingBox(this, new Vec3(var1.x, 0.0D,
+// var1.z), var2.move(var10), this.level, var3).add(var10); if
+// (var11.horizontalDistanceSqr() > var9.horizontalDistanceSqr()) {
+// var9 = var11;
+// }
+// }
+
+// if (var9.horizontalDistanceSqr() > var4.horizontalDistanceSqr()) {
+// return var9.add(collideBoundingBox(this, new Vec3(0.0D, -var9.y +
+// var1.y, 0.0D), var2.move(var9), this.level, var3)); }
+// }
+
+// return var4;
+// }
+fn collide(movement: &Vec3, world: &World, physics: &entity::Physics) -> Vec3 {
+ let entity_bounding_box = physics.bounding_box;
+ // TODO: get_entity_collisions
+ // let entity_collisions = world.get_entity_collisions(self,
+ // entity_bounding_box.expand_towards(movement));
+ let entity_collisions = Vec::new();
+ if movement.length_sqr() == 0.0 {
+ *movement
+ } else {
+ collide_bounding_box(movement, &entity_bounding_box, world, entity_collisions)
+ }
-pub trait MovableEntity {
- fn move_colliding(
- &mut self,
- mover_type: &MoverType,
- movement: &Vec3,
- ) -> Result<(), MoveEntityError>;
+ // TODO: stepping (for stairs and stuff)
+
+ // collided_movement
}
-impl<D: Deref<Target = WeakWorld>> HasCollision for D {
- // private Vec3 collide(Vec3 var1) {
- // AABB var2 = this.getBoundingBox();
- // List var3 = this.level.getEntityCollisions(this,
- // var2.expandTowards(var1)); Vec3 var4 = var1.lengthSqr() == 0.0D ?
- // var1 : collideBoundingBox(this, var1, var2, this.level, var3);
- // boolean var5 = var1.x != var4.x;
- // boolean var6 = var1.y != var4.y;
- // boolean var7 = var1.z != var4.z;
- // boolean var8 = this.onGround || var6 && var1.y < 0.0D;
- // if (this.maxUpStep > 0.0F && var8 && (var5 || var7)) {
- // Vec3 var9 = collideBoundingBox(this, new Vec3(var1.x,
- // (double)this.maxUpStep, var1.z), var2, this.level, var3); Vec3
- // var10 = collideBoundingBox(this, new Vec3(0.0D, (double)this.maxUpStep,
- // 0.0D), var2.expandTowards(var1.x, 0.0D, var1.z), this.level, var3);
- // if (var10.y < (double)this.maxUpStep) {
- // Vec3 var11 = collideBoundingBox(this, new Vec3(var1.x, 0.0D,
- // var1.z), var2.move(var10), this.level, var3).add(var10); if
- // (var11.horizontalDistanceSqr() > var9.horizontalDistanceSqr()) {
- // var9 = var11;
- // }
- // }
-
- // if (var9.horizontalDistanceSqr() > var4.horizontalDistanceSqr()) {
- // return var9.add(collideBoundingBox(this, new Vec3(0.0D, -var9.y +
- // var1.y, 0.0D), var2.move(var9), this.level, var3)); }
+/// Move an entity by a given delta, checking for collisions.
+pub fn move_colliding(
+ _mover_type: &MoverType,
+ movement: &Vec3,
+ world: &World,
+ position: &mut entity::Position,
+ physics: &mut entity::Physics,
+) -> Result<(), MoveEntityError> {
+ // TODO: do all these
+
+ // if self.no_physics {
+ // return;
+ // };
+
+ // if (var1 == MoverType.PISTON) {
+ // var2 = this.limitPistonMovement(var2);
+ // if (var2.equals(Vec3.ZERO)) {
+ // return;
// }
+ // }
- // return var4;
+ // if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7D) {
+ // var2 = var2.multiply(this.stuckSpeedMultiplier);
+ // this.stuckSpeedMultiplier = Vec3.ZERO;
+ // this.setDeltaMovement(Vec3.ZERO);
// }
- fn collide(&self, movement: &Vec3, entity: &EntityData) -> Vec3 {
- let entity_bounding_box = entity.bounding_box;
- // TODO: get_entity_collisions
- // let entity_collisions = world.get_entity_collisions(self,
- // entity_bounding_box.expand_towards(movement));
- let entity_collisions = Vec::new();
- if movement.length_sqr() == 0.0 {
- *movement
- } else {
- collide_bounding_box(
- Some(entity),
- movement,
- &entity_bounding_box,
- self,
- entity_collisions,
- )
- }
- // TODO: stepping (for stairs and stuff)
+ // movement = this.maybeBackOffFromEdge(movement, moverType);
- // collided_movement
- }
-}
+ let collide_result = collide(movement, world, physics);
-impl<D: Deref<Target = WeakWorld>> MovableEntity for Entity<'_, D> {
- /// Move an entity by a given delta, checking for collisions.
- fn move_colliding(
- &mut self,
- _mover_type: &MoverType,
- movement: &Vec3,
- ) -> Result<(), MoveEntityError> {
- // TODO: do all these
-
- // if self.no_physics {
- // return;
- // };
-
- // if (var1 == MoverType.PISTON) {
- // var2 = this.limitPistonMovement(var2);
- // if (var2.equals(Vec3.ZERO)) {
- // return;
- // }
- // }
-
- // if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7D) {
- // var2 = var2.multiply(this.stuckSpeedMultiplier);
- // this.stuckSpeedMultiplier = Vec3.ZERO;
- // this.setDeltaMovement(Vec3.ZERO);
- // }
-
- // movement = this.maybeBackOffFromEdge(movement, moverType);
-
- let collide_result = { self.world.collide(movement, self) };
-
- let move_distance = collide_result.length_sqr();
-
- if move_distance > EPSILON {
- // TODO: fall damage
-
- let new_pos = {
- let entity_pos = self.pos();
- Vec3 {
- x: entity_pos.x + collide_result.x,
- y: entity_pos.y + collide_result.y,
- z: entity_pos.z + collide_result.z,
- }
- };
-
- self.world.set_entity_pos(self.id, new_pos)?;
- }
+ let move_distance = collide_result.length_sqr();
+
+ if move_distance > EPSILON {
+ // TODO: fall damage
+
+ let new_pos = {
+ Vec3 {
+ x: position.x + collide_result.x,
+ y: position.y + collide_result.y,
+ z: position.z + collide_result.z,
+ }
+ };
- let x_collision = movement.x != collide_result.x;
- let z_collision = movement.z != collide_result.z;
- let horizontal_collision = x_collision || z_collision;
- let vertical_collision = movement.y != collide_result.y;
- let on_ground = vertical_collision && movement.y < 0.;
- self.on_ground = on_ground;
+ **position = new_pos;
+ }
- // TODO: minecraft checks for a "minor" horizontal collision here
+ let x_collision = movement.x != collide_result.x;
+ let z_collision = movement.z != collide_result.z;
+ let horizontal_collision = x_collision || z_collision;
+ let vertical_collision = movement.y != collide_result.y;
+ let on_ground = vertical_collision && movement.y < 0.;
+ physics.on_ground = on_ground;
- let _block_pos_below = self.on_pos_legacy();
- // let _block_state_below = self
- // .world
- // .get_block_state(&block_pos_below)
- // .expect("Couldn't get block state below");
+ // TODO: minecraft checks for a "minor" horizontal collision here
- // self.check_fall_damage(collide_result.y, on_ground, block_state_below,
- // block_pos_below);
+ let _block_pos_below = entity::on_pos_legacy(&world.chunks, position);
+ // let _block_state_below = self
+ // .world
+ // .get_block_state(&block_pos_below)
+ // .expect("Couldn't get block state below");
- // if self.isRemoved() { return; }
+ // self.check_fall_damage(collide_result.y, on_ground, block_state_below,
+ // block_pos_below);
- if horizontal_collision {
- let delta_movement = &self.delta;
- self.delta = Vec3 {
- x: if x_collision { 0. } else { delta_movement.x },
- y: delta_movement.y,
- z: if z_collision { 0. } else { delta_movement.z },
- }
- }
+ // if self.isRemoved() { return; }
- if vertical_collision {
- // blockBelow.updateEntityAfterFallOn(this.level, this);
- // the default implementation of updateEntityAfterFallOn sets the y movement to
- // 0
- self.delta.y = 0.;
+ if horizontal_collision {
+ let delta_movement = &physics.delta;
+ physics.delta = Vec3 {
+ x: if x_collision { 0. } else { delta_movement.x },
+ y: delta_movement.y,
+ z: if z_collision { 0. } else { delta_movement.z },
}
+ }
- if on_ground {
- // blockBelow.stepOn(this.level, blockPosBelow, blockStateBelow,
- // this);
- }
+ if vertical_collision {
+ // blockBelow.updateEntityAfterFallOn(this.level, this);
+ // the default implementation of updateEntityAfterFallOn sets the y movement to
+ // 0
+ physics.delta.y = 0.;
+ }
+
+ if on_ground {
+ // blockBelow.stepOn(this.level, blockPosBelow, blockStateBelow,
+ // this);
+ }
- // sounds
+ // sounds
- // this.tryCheckInsideBlocks();
+ // this.tryCheckInsideBlocks();
- // float var25 = this.getBlockSpeedFactor();
- // this.setDeltaMovement(this.getDeltaMovement().multiply((double)var25, 1.0D,
- // (double)var25)); if (this.level.getBlockStatesIfLoaded(this.
- // getBoundingBox().deflate(1.0E-6D)).noneMatch((var0) -> {
- // return var0.is(BlockTags.FIRE) || var0.is(Blocks.LAVA);
- // })) {
- // if (this.remainingFireTicks <= 0) {
- // this.setRemainingFireTicks(-this.getFireImmuneTicks());
- // }
+ // float var25 = this.getBlockSpeedFactor();
+ // this.setDeltaMovement(this.getDeltaMovement().multiply((double)var25, 1.0D,
+ // (double)var25)); if (this.level.getBlockStatesIfLoaded(this.
+ // getBoundingBox().deflate(1.0E-6D)).noneMatch((var0) -> {
+ // return var0.is(BlockTags.FIRE) || var0.is(Blocks.LAVA);
+ // })) {
+ // if (this.remainingFireTicks <= 0) {
+ // this.setRemainingFireTicks(-this.getFireImmuneTicks());
+ // }
- // if (this.wasOnFire && (this.isInPowderSnow ||
- // this.isInWaterRainOrBubble())) { this.
- // playEntityOnFireExtinguishedSound(); }
- // }
+ // if (this.wasOnFire && (this.isInPowderSnow ||
+ // this.isInWaterRainOrBubble())) { this.
+ // playEntityOnFireExtinguishedSound(); }
+ // }
- // if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble()))
- // { this.setRemainingFireTicks(-this.getFireImmuneTicks());
- // }
+ // if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble()))
+ // { this.setRemainingFireTicks(-this.getFireImmuneTicks());
+ // }
- Ok(())
- }
+ Ok(())
}
fn collide_bounding_box(
- entity: Option<&EntityData>,
movement: &Vec3,
entity_bounding_box: &AABB,
- world: &WeakWorld,
+ world: &World,
entity_collisions: Vec<VoxelShape>,
) -> Vec3 {
let mut collision_boxes: Vec<VoxelShape> = Vec::with_capacity(entity_collisions.len() + 1);
@@ -218,7 +198,7 @@ fn collide_bounding_box(
// TODO: world border
let block_collisions =
- world.get_block_collisions(entity, entity_bounding_box.expand_towards(movement));
+ get_block_collisions(world, entity_bounding_box.expand_towards(movement));
let block_collisions = block_collisions.collect::<Vec<_>>();
collision_boxes.extend(block_collisions);
collide_with_shapes(movement, *entity_bounding_box, &collision_boxes)
diff --git a/azalea-physics/src/collision/shape.rs b/azalea-physics/src/collision/shape.rs
index bb2ed2e5..cc184591 100755
--- a/azalea-physics/src/collision/shape.rs
+++ b/azalea-physics/src/collision/shape.rs
@@ -539,7 +539,7 @@ impl VoxelShape {
x_coords[var7 as usize],
y_coords[var8 as usize],
z_coords[var9 as usize],
- )
+ );
},
true,
);
diff --git a/azalea-physics/src/collision/world_collisions.rs b/azalea-physics/src/collision/world_collisions.rs
index 9e238bf9..c7b2a91b 100644
--- a/azalea-physics/src/collision/world_collisions.rs
+++ b/azalea-physics/src/collision/world_collisions.rs
@@ -1,34 +1,17 @@
+use super::Shapes;
use crate::collision::{BlockWithShape, VoxelShape, AABB};
use azalea_block::BlockState;
use azalea_core::{ChunkPos, ChunkSectionPos, Cursor3d, CursorIterationType, EPSILON};
-use azalea_world::entity::EntityData;
-use azalea_world::{Chunk, WeakWorld};
+use azalea_world::{Chunk, World};
use parking_lot::RwLock;
use std::sync::Arc;
-use super::Shapes;
-
-pub trait CollisionGetter {
- fn get_block_collisions<'a>(
- &'a self,
- entity: Option<&EntityData>,
- aabb: AABB,
- ) -> BlockCollisions<'a>;
-}
-
-impl CollisionGetter for WeakWorld {
- fn get_block_collisions<'a>(
- &'a self,
- entity: Option<&EntityData>,
- aabb: AABB,
- ) -> BlockCollisions<'a> {
- BlockCollisions::new(self, entity, aabb)
- }
+pub fn get_block_collisions(world: &World, aabb: AABB) -> BlockCollisions<'_> {
+ BlockCollisions::new(world, aabb)
}
pub struct BlockCollisions<'a> {
- pub world: &'a WeakWorld,
- // context: CollisionContext,
+ pub world: &'a World,
pub aabb: AABB,
pub entity_shape: VoxelShape,
pub cursor: Cursor3d,
@@ -36,8 +19,7 @@ pub struct BlockCollisions<'a> {
}
impl<'a> BlockCollisions<'a> {
- // TODO: the entity is stored in the context
- pub fn new(world: &'a WeakWorld, _entity: Option<&EntityData>, aabb: AABB) -> Self {
+ pub fn new(world: &'a World, aabb: AABB) -> Self {
let origin_x = (aabb.min_x - EPSILON) as i32 - 1;
let origin_y = (aabb.min_y - EPSILON) as i32 - 1;
let origin_z = (aabb.min_z - EPSILON) as i32 - 1;
@@ -75,7 +57,7 @@ impl<'a> BlockCollisions<'a> {
// return var7;
// }
- self.world.get_chunk(&chunk_pos)
+ self.world.chunks.get(&chunk_pos)
}
}
@@ -89,15 +71,14 @@ impl<'a> Iterator for BlockCollisions<'a> {
}
let chunk = self.get_chunk(item.pos.x, item.pos.z);
- let chunk = match chunk {
- Some(chunk) => chunk,
- None => continue,
+ let Some(chunk) = chunk else {
+ continue
};
let pos = item.pos;
let block_state: BlockState = chunk
.read()
- .get(&(&pos).into(), self.world.min_y())
+ .get(&(&pos).into(), self.world.chunks.min_y)
.unwrap_or(BlockState::Air);
// TODO: continue if self.only_suffocating_blocks and the block is not