mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-16 18:43:25 +00:00
Migrates projectile prediction logic to leverage engine traits for improved flexibility and testability. This change decouples core prediction algorithms from specific engine implementations, allowing for easier adaptation to different game engines or simulation environments.
62 lines
2.9 KiB
C++
62 lines
2.9 KiB
C++
//
|
|
// Created by Vlad on 8/3/2025.
|
|
//
|
|
|
|
#pragma once
|
|
#include "omath/engines/source_engine/formulas.hpp"
|
|
#include "omath/projectile_prediction/projectile.hpp"
|
|
#include <optional>
|
|
|
|
namespace omath::projectile_prediction::traits
|
|
{
|
|
class SourceEngineTrait final
|
|
{
|
|
public:
|
|
constexpr static Vector3<float> predict_projectile_position(const Projectile& projectile, const float pitch,
|
|
const float yaw, const float time,
|
|
const float gravity) noexcept
|
|
{
|
|
auto current_pos = projectile.m_origin
|
|
+ source_engine::forward_vector({source_engine::PitchAngle::from_degrees(-pitch),
|
|
source_engine::YawAngle::from_degrees(yaw),
|
|
source_engine::RollAngle::from_degrees(0)})
|
|
* projectile.m_launch_speed * time;
|
|
current_pos.z -= (gravity * projectile.m_gravity_scale) * (time * time) * 0.5f;
|
|
|
|
return current_pos;
|
|
}
|
|
|
|
static bool is_projectile_reached_target(const Vector3<float>& target_position,
|
|
const Projectile& projectile, const float pitch,
|
|
const float time, const float gravity,
|
|
const float tolerance) noexcept
|
|
{
|
|
const auto yaw = projectile.m_origin.view_angle_to(target_position).y;
|
|
const auto projectile_position = predict_projectile_position(projectile, pitch, yaw, time, gravity);
|
|
|
|
return projectile_position.distance_to(target_position) <= tolerance;
|
|
}
|
|
[[nodiscard]]
|
|
static float calc_vector_2d_distance(const Vector3<float>& delta)
|
|
{
|
|
return std::sqrt(delta.x * delta.x + delta.y * delta.y);
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr static float get_vector_height_coordinate(const Vector3<float>& vec)
|
|
{
|
|
return vec.z;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
static Vector3<float> calc_viewpoint_from_angles(const Projectile& projectile,
|
|
Vector3<float> predicted_target_position,
|
|
const std::optional<float> projectile_pitch)
|
|
{
|
|
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()));
|
|
|
|
return {predicted_target_position.x, predicted_target_position.y, projectile.m_origin.z + height};
|
|
}
|
|
};
|
|
} // namespace omath::projectile_prediction::traits
|