allow reuse of angular diameter calculation code
This commit is contained in:
parent
5de4b0bac3
commit
f682f1d6c0
|
@ -344,6 +344,7 @@ fn apply_input_to_player(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the closest world object that the player is looking at
|
// Find the closest world object that the player is looking at
|
||||||
|
#[inline]
|
||||||
pub fn find_closest_target<TargetSpecifier>(
|
pub fn find_closest_target<TargetSpecifier>(
|
||||||
objects: Vec<(TargetSpecifier, &Transform)>,
|
objects: Vec<(TargetSpecifier, &Transform)>,
|
||||||
camera_transform: &Transform,
|
camera_transform: &Transform,
|
||||||
|
@ -352,24 +353,13 @@ pub fn find_closest_target<TargetSpecifier>(
|
||||||
{
|
{
|
||||||
let mut closest_entity: Option<TargetSpecifier> = None;
|
let mut closest_entity: Option<TargetSpecifier> = None;
|
||||||
let mut closest_distance: f32 = f32::MAX;
|
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();
|
.normalize_or_zero();
|
||||||
for (entity, trans) in objects {
|
for (entity, trans) in objects {
|
||||||
// Use Transform instead of Position because we're basing this
|
// 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.
|
// not on the player mesh but on the camera, which doesn't have a position.
|
||||||
let pos_vector = (trans.translation - camera_transform.translation)
|
let (angular_diameter, angle, distance) = calc_angular_diameter_known_target_vector(
|
||||||
.normalize_or_zero();
|
trans, camera_transform, &target_vector);
|
||||||
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
|
|
||||||
};
|
|
||||||
if angle <= angular_diameter.clamp(0.001, PI) {
|
if angle <= angular_diameter.clamp(0.001, PI) {
|
||||||
// It's in the field of view!
|
// It's in the field of view!
|
||||||
//commands.entity(entity).insert(IsTargeted);
|
//commands.entity(entity).insert(IsTargeted);
|
||||||
|
@ -381,3 +371,35 @@ pub fn find_closest_target<TargetSpecifier>(
|
||||||
}
|
}
|
||||||
return (closest_entity, closest_distance);
|
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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue