diff --git a/src/camera.rs b/src/camera.rs index 58f5f9f..d4efda2 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -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( objects: Vec<(TargetSpecifier, &Transform)>, camera_transform: &Transform, @@ -352,24 +353,13 @@ pub fn find_closest_target( { let mut closest_entity: Option = 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( } 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); +}