azalea_physics/collision/
entity_collisions.rs1use azalea_core::aabb::AABB;
2use azalea_entity::{
3 LocalEntity, Physics,
4 metadata::{AbstractBoat, Shulker},
5};
6use azalea_world::Instance;
7use bevy_ecs::{
8 entity::Entity,
9 query::{Or, With, Without},
10 system::Query,
11};
12use tracing::error;
13
14use super::VoxelShape;
15
16pub type CollidableEntityQuery<'world, 'state> = Query<'world, 'state, (), CollidableEntityFilter>;
22pub type CollidableEntityFilter = Or<(With<AbstractBoat>, With<Shulker>)>;
28
29pub type PhysicsQuery<'world, 'state, 'a> =
30 Query<'world, 'state, &'a Physics, Without<LocalEntity>>;
31
32pub fn get_entity_collisions(
33 world: &Instance,
34 aabb: &AABB,
35 source_entity: Option<Entity>,
36 physics_query: &PhysicsQuery,
37 collidable_entity_query: &CollidableEntityQuery,
38) -> Vec<VoxelShape> {
39 if aabb.size() < 1.0E-7 {
40 return vec![];
41 }
42
43 let collision_predicate = |entity| collidable_entity_query.get(entity).is_ok();
44
45 let collidable_entities = get_entities(
46 world,
47 source_entity,
48 &aabb.inflate_all(1.0E-7),
49 &collision_predicate,
50 physics_query,
51 );
52
53 collidable_entities
54 .into_iter()
55 .map(|(_entity, aabb)| VoxelShape::from(aabb))
56 .collect()
57}
58
59pub fn get_entities(
65 world: &Instance,
66 source_entity: Option<Entity>,
67 aabb: &AABB,
68 predicate: &dyn Fn(Entity) -> bool,
69 physics_query: &PhysicsQuery,
70) -> Vec<(Entity, AABB)> {
71 let mut matches = Vec::new();
72
73 super::world_collisions::for_entities_in_chunks_colliding_with(
74 world,
75 aabb,
76 |_chunk_pos, entities_in_chunk| {
77 for &candidate in entities_in_chunk {
79 if Some(candidate) != source_entity && predicate(candidate) {
80 let Ok(physics) = physics_query.get(candidate) else {
81 error!(
82 "Entity {candidate} (found from for_entities_in_chunks_colliding_with) is missing required components."
83 );
84 continue;
85 };
86
87 let candidate_aabb = physics.bounding_box;
88 if aabb.intersects_aabb(&candidate_aabb) {
89 matches.push((candidate, physics.bounding_box));
90 }
91 }
92 }
93 },
94 );
95
96 matches
97}