allow reuse of angular diameter calculation code

This commit is contained in:
yuni 2024-04-05 22:06:58 +02:00
parent 5de4b0bac3
commit f682f1d6c0

View file

@ -344,6 +344,7 @@ fn apply_input_to_player(
}
// Find the closest world object that the player is looking at
#[inline]
pub fn find_closest_target<TargetSpecifier>(
objects: Vec<(TargetSpecifier, &Transform)>,
camera_transform: &Transform,
@ -352,24 +353,13 @@ pub fn find_closest_target<TargetSpecifier>(
{
let mut closest_entity: Option<TargetSpecifier> = None;
let mut closest_distance: f32 = f32::MAX;
let target_vector = (camera_transform.rotation * Vec3::new(0.0, 0.0, -1.0))
let target_vector: Vec3 = (camera_transform.rotation * Vec3::new(0.0, 0.0, -1.0))
.normalize_or_zero();
for (entity, trans) in objects {
// Use Transform instead of Position because we're basing this
// not on the player mesh but on the camera, which doesn't have a position.
let pos_vector = (trans.translation - camera_transform.translation)
.normalize_or_zero();
let cosine_of_angle = target_vector.dot(pos_vector);
let angle = cosine_of_angle.acos();
let distance = trans.translation.distance(camera_transform.translation);
let leeway = 1.3;
let angular_diameter = if distance > 0.0 {
// Angular Diameter
leeway * (trans.scale[0] / distance).asin()
}
else {
0.0
};
let (angular_diameter, angle, distance) = calc_angular_diameter_known_target_vector(
trans, camera_transform, &target_vector);
if angle <= angular_diameter.clamp(0.001, PI) {
// It's in the field of view!
//commands.entity(entity).insert(IsTargeted);
@ -381,3 +371,35 @@ pub fn find_closest_target<TargetSpecifier>(
}
return (closest_entity, closest_distance);
}
#[inline]
pub fn calc_angular_diameter_known_target_vector(
target: &Transform,
camera: &Transform,
target_vector: &Vec3,
) -> (f32, f32, f32) {
let pos_vector: Vec3 = (target.translation - camera.translation)
.normalize_or_zero();
let cosine_of_angle: f32 = target_vector.dot(pos_vector);
let angle: f32 = cosine_of_angle.acos();
let distance: f32 = target.translation.distance(camera.translation);
let leeway: f32 = 1.3;
let angular_diameter: f32 = if distance > 0.0 {
// Angular Diameter
leeway * (target.scale[0] / distance).asin()
}
else {
0.0
};
return (angular_diameter, angle, distance);
}
#[inline]
pub fn calc_angular_diameter(
target: &Transform,
camera: &Transform,
) -> (f32, f32, f32) {
let target_vector: Vec3 = (camera.rotation * Vec3::new(0.0, 0.0, -1.0))
.normalize_or_zero();
return calc_angular_diameter_known_target_vector(target, camera, &target_vector);
}