mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 23:44:38 +00:00
cleanup
This commit is contained in:
parent
fd9bf16871
commit
f82cf7fa85
4 changed files with 80 additions and 70 deletions
|
@ -481,6 +481,7 @@ fn update_attributes_for_held_item(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
fn update_attributes_for_gamemode(
|
fn update_attributes_for_gamemode(
|
||||||
query: Query<(&mut Attributes, &LocalGameMode), (With<LocalEntity>, Changed<LocalGameMode>)>,
|
query: Query<(&mut Attributes, &LocalGameMode), (With<LocalEntity>, Changed<LocalGameMode>)>,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -64,18 +64,17 @@ pub fn update_hit_result_component(
|
||||||
};
|
};
|
||||||
let world = world_lock.read();
|
let world = world_lock.read();
|
||||||
|
|
||||||
let aabb = &physics.bounding_box;
|
let hit_result = pick(PickOpts {
|
||||||
let hit_result = pick(
|
source_entity: entity,
|
||||||
entity,
|
look_direction: *look_direction,
|
||||||
*look_direction,
|
|
||||||
eye_position,
|
eye_position,
|
||||||
aabb,
|
aabb: &physics.bounding_box,
|
||||||
&world,
|
world: &world,
|
||||||
entity_pick_range,
|
entity_pick_range,
|
||||||
block_pick_range,
|
block_pick_range,
|
||||||
&physics_query,
|
physics_query: &physics_query,
|
||||||
&pickable_query,
|
pickable_query: &pickable_query,
|
||||||
);
|
});
|
||||||
if let Some(mut hit_result_ref) = hit_result_ref {
|
if let Some(mut hit_result_ref) = hit_result_ref {
|
||||||
**hit_result_ref = hit_result;
|
**hit_result_ref = hit_result;
|
||||||
} else {
|
} else {
|
||||||
|
@ -93,6 +92,18 @@ pub type PickableEntityQuery<'world, 'state, 'a> = Query<
|
||||||
(Without<Dead>, Without<Marker>, Without<LocalEntity>),
|
(Without<Dead>, Without<Marker>, Without<LocalEntity>),
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
pub struct PickOpts<'world, 'state, 'a, 'b, 'c> {
|
||||||
|
source_entity: Entity,
|
||||||
|
look_direction: LookDirection,
|
||||||
|
eye_position: Vec3,
|
||||||
|
aabb: &'a AABB,
|
||||||
|
world: &'a Instance,
|
||||||
|
entity_pick_range: f64,
|
||||||
|
block_pick_range: f64,
|
||||||
|
physics_query: &'a PhysicsQuery<'world, 'state, 'b>,
|
||||||
|
pickable_query: &'a PickableEntityQuery<'world, 'state, 'c>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the block or entity that a player would be looking at if their eyes were
|
/// Get the block or entity that a player would be looking at if their eyes were
|
||||||
/// at the given direction and position.
|
/// at the given direction and position.
|
||||||
///
|
///
|
||||||
|
@ -100,44 +111,40 @@ pub type PickableEntityQuery<'world, 'state, 'a> = Query<
|
||||||
/// [`HitResultComponent`].
|
/// [`HitResultComponent`].
|
||||||
///
|
///
|
||||||
/// Also see [`pick_block`].
|
/// Also see [`pick_block`].
|
||||||
///
|
pub fn pick(opts: PickOpts<'_, '_, '_, '_, '_>) -> HitResult {
|
||||||
/// TODO: does not currently check for entities
|
|
||||||
pub fn pick(
|
|
||||||
source_entity: Entity,
|
|
||||||
look_direction: LookDirection,
|
|
||||||
eye_position: Vec3,
|
|
||||||
aabb: &AABB,
|
|
||||||
world: &Instance,
|
|
||||||
entity_pick_range: f64,
|
|
||||||
block_pick_range: f64,
|
|
||||||
physics_query: &PhysicsQuery,
|
|
||||||
pickable_query: &PickableEntityQuery,
|
|
||||||
) -> HitResult {
|
|
||||||
// vanilla does extra math here to calculate the pick result in between ticks by
|
// vanilla does extra math here to calculate the pick result in between ticks by
|
||||||
// interpolating, but since clients can still only interact on exact ticks, that
|
// interpolating, but since clients can still only interact on exact ticks, that
|
||||||
// isn't relevant for us.
|
// isn't relevant for us.
|
||||||
|
|
||||||
let mut max_range = entity_pick_range.max(block_pick_range);
|
let mut max_range = opts.entity_pick_range.max(opts.block_pick_range);
|
||||||
let mut max_range_squared = max_range.powi(2);
|
let mut max_range_squared = max_range.powi(2);
|
||||||
|
|
||||||
let block_hit_result = pick_block(look_direction, eye_position, &world.chunks, max_range);
|
let block_hit_result = pick_block(
|
||||||
let block_hit_result_dist_squared = block_hit_result.location.distance_squared_to(eye_position);
|
opts.look_direction,
|
||||||
|
opts.eye_position,
|
||||||
|
&opts.world.chunks,
|
||||||
|
max_range,
|
||||||
|
);
|
||||||
|
let block_hit_result_dist_squared = block_hit_result
|
||||||
|
.location
|
||||||
|
.distance_squared_to(opts.eye_position);
|
||||||
if !block_hit_result.miss {
|
if !block_hit_result.miss {
|
||||||
max_range_squared = block_hit_result_dist_squared;
|
max_range_squared = block_hit_result_dist_squared;
|
||||||
max_range = block_hit_result_dist_squared.sqrt();
|
max_range = block_hit_result_dist_squared.sqrt();
|
||||||
}
|
}
|
||||||
|
|
||||||
let view_vector = view_vector(look_direction);
|
let view_vector = view_vector(opts.look_direction);
|
||||||
let end_position = eye_position + (view_vector * max_range);
|
let end_position = opts.eye_position + (view_vector * max_range);
|
||||||
let inflate_by = 1.;
|
let inflate_by = 1.;
|
||||||
let pick_aabb = aabb
|
let pick_aabb = opts
|
||||||
|
.aabb
|
||||||
.expand_towards(view_vector * max_range)
|
.expand_towards(view_vector * max_range)
|
||||||
.inflate_all(inflate_by);
|
.inflate_all(inflate_by);
|
||||||
|
|
||||||
let is_pickable = |entity: Entity| {
|
let is_pickable = |entity: Entity| {
|
||||||
// TODO: ender dragon and projectiles have extra logic here. also, we shouldn't
|
// TODO: ender dragon and projectiles have extra logic here. also, we shouldn't
|
||||||
// be able to pick spectators.
|
// be able to pick spectators.
|
||||||
if let Ok(armor_stand_marker) = pickable_query.get(entity) {
|
if let Ok(armor_stand_marker) = opts.pickable_query.get(entity) {
|
||||||
if let Some(armor_stand_marker) = armor_stand_marker
|
if let Some(armor_stand_marker) = armor_stand_marker
|
||||||
&& armor_stand_marker.0
|
&& armor_stand_marker.0
|
||||||
{
|
{
|
||||||
|
@ -149,32 +156,33 @@ pub fn pick(
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let entity_hit_result = pick_entity(
|
let entity_hit_result = pick_entity(PickEntityOpts {
|
||||||
source_entity,
|
source_entity: opts.source_entity,
|
||||||
eye_position,
|
eye_position: opts.eye_position,
|
||||||
end_position,
|
end_position,
|
||||||
world,
|
world: opts.world,
|
||||||
max_range_squared,
|
pick_range_squared: max_range_squared,
|
||||||
&is_pickable,
|
predicate: &is_pickable,
|
||||||
&pick_aabb,
|
aabb: &pick_aabb,
|
||||||
physics_query,
|
physics_query: opts.physics_query,
|
||||||
);
|
});
|
||||||
|
|
||||||
// TODO
|
|
||||||
if let Some(entity_hit_result) = entity_hit_result
|
if let Some(entity_hit_result) = entity_hit_result
|
||||||
&& entity_hit_result.location.distance_squared_to(eye_position)
|
&& entity_hit_result
|
||||||
|
.location
|
||||||
|
.distance_squared_to(opts.eye_position)
|
||||||
< block_hit_result_dist_squared
|
< block_hit_result_dist_squared
|
||||||
{
|
{
|
||||||
filter_hit_result(
|
filter_hit_result(
|
||||||
HitResult::Entity(entity_hit_result),
|
HitResult::Entity(entity_hit_result),
|
||||||
eye_position,
|
opts.eye_position,
|
||||||
entity_pick_range,
|
opts.entity_pick_range,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
filter_hit_result(
|
filter_hit_result(
|
||||||
HitResult::Block(block_hit_result),
|
HitResult::Block(block_hit_result),
|
||||||
eye_position,
|
opts.eye_position,
|
||||||
block_pick_range,
|
opts.block_pick_range,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,40 +221,46 @@ pub fn pick_block(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// port of getEntityHitResult
|
struct PickEntityOpts<'world, 'state, 'a, 'b> {
|
||||||
fn pick_entity(
|
|
||||||
source_entity: Entity,
|
source_entity: Entity,
|
||||||
eye_position: Vec3,
|
eye_position: Vec3,
|
||||||
end_position: Vec3,
|
end_position: Vec3,
|
||||||
world: &azalea_world::Instance,
|
world: &'a azalea_world::Instance,
|
||||||
pick_range_squared: f64,
|
pick_range_squared: f64,
|
||||||
predicate: &dyn Fn(Entity) -> bool,
|
predicate: &'a dyn Fn(Entity) -> bool,
|
||||||
aabb: &AABB,
|
aabb: &'a AABB,
|
||||||
physics_query: &PhysicsQuery,
|
physics_query: &'a PhysicsQuery<'world, 'state, 'b>,
|
||||||
) -> Option<EntityHitResult> {
|
}
|
||||||
let mut picked_distance_squared = pick_range_squared;
|
|
||||||
|
// port of getEntityHitResult
|
||||||
|
fn pick_entity(opts: PickEntityOpts) -> Option<EntityHitResult> {
|
||||||
|
let mut picked_distance_squared = opts.pick_range_squared;
|
||||||
let mut result = None;
|
let mut result = None;
|
||||||
|
|
||||||
for (candidate, candidate_aabb) in
|
for (candidate, candidate_aabb) in get_entities(
|
||||||
get_entities(world, Some(source_entity), aabb, predicate, physics_query)
|
opts.world,
|
||||||
{
|
Some(opts.source_entity),
|
||||||
|
opts.aabb,
|
||||||
|
opts.predicate,
|
||||||
|
opts.physics_query,
|
||||||
|
) {
|
||||||
// TODO: if the entity is "REDIRECTABLE_PROJECTILE" then this should be 1.0.
|
// TODO: if the entity is "REDIRECTABLE_PROJECTILE" then this should be 1.0.
|
||||||
// azalea needs support for entity tags first for this to be possible. see
|
// azalea needs support for entity tags first for this to be possible. see
|
||||||
// getPickRadius in decompiled minecraft source
|
// getPickRadius in decompiled minecraft source
|
||||||
let candidate_pick_radius = 0.;
|
let candidate_pick_radius = 0.;
|
||||||
let candidate_aabb = candidate_aabb.inflate_all(candidate_pick_radius);
|
let candidate_aabb = candidate_aabb.inflate_all(candidate_pick_radius);
|
||||||
let clip_location = candidate_aabb.clip(eye_position, end_position);
|
let clip_location = candidate_aabb.clip(opts.eye_position, opts.end_position);
|
||||||
|
|
||||||
if candidate_aabb.contains(eye_position) {
|
if candidate_aabb.contains(opts.eye_position) {
|
||||||
if picked_distance_squared >= 0. {
|
if picked_distance_squared >= 0. {
|
||||||
result = Some(EntityHitResult {
|
result = Some(EntityHitResult {
|
||||||
location: clip_location.unwrap_or(eye_position),
|
location: clip_location.unwrap_or(opts.eye_position),
|
||||||
entity: candidate,
|
entity: candidate,
|
||||||
});
|
});
|
||||||
picked_distance_squared = 0.;
|
picked_distance_squared = 0.;
|
||||||
}
|
}
|
||||||
} else if let Some(clip_location) = clip_location {
|
} else if let Some(clip_location) = clip_location {
|
||||||
let distance_squared = eye_position.distance_squared_to(clip_location);
|
let distance_squared = opts.eye_position.distance_squared_to(clip_location);
|
||||||
if distance_squared < picked_distance_squared || picked_distance_squared == 0. {
|
if distance_squared < picked_distance_squared || picked_distance_squared == 0. {
|
||||||
// TODO: don't pick the entity we're riding on
|
// TODO: don't pick the entity we're riding on
|
||||||
// if candidate_root_vehicle == entity_root_vehicle {
|
// if candidate_root_vehicle == entity_root_vehicle {
|
||||||
|
|
|
@ -18,7 +18,7 @@ impl HitResult {
|
||||||
pub fn miss(&self) -> bool {
|
pub fn miss(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
HitResult::Block(r) => r.miss,
|
HitResult::Block(r) => r.miss,
|
||||||
HitResult::Entity(_) => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn location(&self) -> Vec3 {
|
pub fn location(&self) -> Vec3 {
|
||||||
|
|
|
@ -6,25 +6,20 @@ use std::{
|
||||||
|
|
||||||
pub const EPSILON: f64 = 1.0E-7;
|
pub const EPSILON: f64 = 1.0E-7;
|
||||||
|
|
||||||
pub static SIN: LazyLock<[f32; 65536]> = LazyLock::new(|| {
|
pub static SIN: LazyLock<[f32; 65536]> =
|
||||||
let mut sin = [0.0; 65536];
|
LazyLock::new(|| std::array::from_fn(|i| f64::sin((i as f64) * PI * 2. / 65536.) as f32));
|
||||||
for (i, item) in sin.iter_mut().enumerate() {
|
|
||||||
*item = f64::sin((i as f64) * PI * 2.0 / 65536.0) as f32;
|
|
||||||
}
|
|
||||||
sin
|
|
||||||
});
|
|
||||||
|
|
||||||
/// A sine function that uses a lookup table.
|
/// A sine function that uses a lookup table.
|
||||||
pub fn sin(x: f32) -> f32 {
|
pub fn sin(x: f32) -> f32 {
|
||||||
let x = x * 10430.378;
|
let x = x * 10430.378;
|
||||||
let x = x as i32 as usize & 65535;
|
let x = x as i32 as usize & 0xFFFF;
|
||||||
SIN[x]
|
SIN[x]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A cosine function that uses a lookup table.
|
/// A cosine function that uses a lookup table.
|
||||||
pub fn cos(x: f32) -> f32 {
|
pub fn cos(x: f32) -> f32 {
|
||||||
let x = x * 10430.378 + 16384.0;
|
let x = x * 10430.378 + 16384.;
|
||||||
let x = x as i32 as usize & 65535;
|
let x = x as i32 as usize & 0xFFFF;
|
||||||
SIN[x]
|
SIN[x]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue