Adds direct pitch angle calculation

Implements a direct pitch angle calculation for scenarios with zero gravity, ensuring accurate projectile trajectory predictions in such conditions.

Also marks several methods as noexcept for better performance and exception safety.
This commit is contained in:
2025-08-04 01:11:11 +03:00
parent 2758f549a3
commit ec76a7239c
2 changed files with 18 additions and 3 deletions

View File

@@ -37,13 +37,13 @@ namespace omath::projectile_prediction::traits
return projectile_position.distance_to(target_position) <= tolerance; return projectile_position.distance_to(target_position) <= tolerance;
} }
[[nodiscard]] [[nodiscard]]
static float calc_vector_2d_distance(const Vector3<float>& delta) static float calc_vector_2d_distance(const Vector3<float>& delta) noexcept
{ {
return std::sqrt(delta.x * delta.x + delta.y * delta.y); return std::sqrt(delta.x * delta.x + delta.y * delta.y);
} }
[[nodiscard]] [[nodiscard]]
constexpr static float get_vector_height_coordinate(const Vector3<float>& vec) constexpr static float get_vector_height_coordinate(const Vector3<float>& vec) noexcept
{ {
return vec.z; return vec.z;
} }
@@ -51,12 +51,22 @@ namespace omath::projectile_prediction::traits
[[nodiscard]] [[nodiscard]]
static Vector3<float> calc_viewpoint_from_angles(const Projectile& projectile, static Vector3<float> calc_viewpoint_from_angles(const Projectile& projectile,
Vector3<float> predicted_target_position, Vector3<float> predicted_target_position,
const std::optional<float> projectile_pitch) const std::optional<float> projectile_pitch) noexcept
{ {
const auto delta2d = calc_vector_2d_distance(predicted_target_position - projectile.m_origin); const auto delta2d = calc_vector_2d_distance(predicted_target_position - projectile.m_origin);
const auto height = delta2d * std::tan(angles::degrees_to_radians(projectile_pitch.value())); const auto height = delta2d * std::tan(angles::degrees_to_radians(projectile_pitch.value()));
return {predicted_target_position.x, predicted_target_position.y, projectile.m_origin.z + height}; return {predicted_target_position.x, predicted_target_position.y, projectile.m_origin.z + height};
} }
// Due to specification of maybe_calculate_projectile_launch_pitch_angle, pitch angle must be:
// 89 look up, -89 look down
[[nodiscard]]
static float calc_direct_pitch_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
{
const auto distance = origin.distance_to(view_to);
const auto delta = view_to - origin;
return angles::radians_to_degrees(std::asin(delta.z / distance));
}
}; };
} // namespace omath::projectile_prediction::traits } // namespace omath::projectile_prediction::traits

View File

@@ -73,6 +73,11 @@ namespace omath::projectile_prediction
const Vector3<float>& target_position) const noexcept const Vector3<float>& target_position) const noexcept
{ {
const auto bullet_gravity = m_gravity_constant * projectile.m_gravity_scale; const auto bullet_gravity = m_gravity_constant * projectile.m_gravity_scale;
if (bullet_gravity == 0.f)
return EngineTrait::calc_direct_pitch_angle(projectile.m_origin, target_position);
const auto delta = target_position - projectile.m_origin; const auto delta = target_position - projectile.m_origin;
const auto distance2d = EngineTrait::calc_vector_2d_distance(delta); const auto distance2d = EngineTrait::calc_vector_2d_distance(delta);