4
4
5
5
#pragma once
6
6
7
+ #include " engine_traits/source_engine_trait.hpp"
7
8
#include " omath/projectile_prediction/proj_pred_engine.hpp"
8
9
#include " omath/projectile_prediction/projectile.hpp"
9
10
#include " omath/projectile_prediction/target.hpp"
13
14
namespace omath ::projectile_prediction
14
15
{
15
16
// ReSharper disable once CppClassCanBeFinal
17
+ template <class EngineTrait = traits::SourceEngineTrait>
16
18
class ProjPredEngineLegacy : public ProjPredEngineInterface
17
19
{
18
20
public:
19
- explicit ProjPredEngineLegacy (float gravity_constant, float simulation_time_step, float maximum_simulation_time,
20
- float distance_tolerance);
21
+ explicit ProjPredEngineLegacy (const float gravity_constant, const float simulation_time_step,
22
+ const float maximum_simulation_time, const float distance_tolerance)
23
+ : m_gravity_constant(gravity_constant), m_simulation_time_step(simulation_time_step),
24
+ m_maximum_simulation_time(maximum_simulation_time), m_distance_tolerance(distance_tolerance)
25
+ {
26
+ }
21
27
22
28
[[nodiscard]]
23
29
std::optional<Vector3<float >> maybe_calculate_aim_point (const Projectile& projectile,
24
- const Target& target) const override ;
30
+ const Target& target) const override
31
+ {
32
+ for (float time = 0 .f ; time < m_maximum_simulation_time; time += m_simulation_time_step)
33
+ {
34
+ const auto predicted_target_position = target.predict_position (time, m_gravity_constant);
35
+
36
+ const auto projectile_pitch =
37
+ maybe_calculate_projectile_launch_pitch_angle (projectile, predicted_target_position);
38
+
39
+ if (!projectile_pitch.has_value ()) [[unlikely]]
40
+ continue ;
41
+
42
+ if (!EngineTrait::is_projectile_reached_target (predicted_target_position, projectile,
43
+ projectile_pitch.value (), time, m_gravity_constant,
44
+ m_distance_tolerance))
45
+ continue ;
46
+
47
+ return EngineTrait::calc_viewpoint_from_angles (projectile, predicted_target_position, projectile_pitch);
48
+ }
49
+ return std::nullopt;
50
+ }
25
51
26
52
private:
27
53
const float m_gravity_constant;
@@ -44,30 +70,27 @@ namespace omath::projectile_prediction
44
70
[[nodiscard]]
45
71
std::optional<float >
46
72
maybe_calculate_projectile_launch_pitch_angle (const Projectile& projectile,
47
- const Vector3<float >& target_position) const noexcept ;
73
+ const Vector3<float >& target_position) const noexcept
74
+ {
75
+ const auto bullet_gravity = m_gravity_constant * projectile.m_gravity_scale ;
76
+ const auto delta = target_position - projectile.m_origin ;
48
77
49
- [[nodiscard]]
50
- bool is_projectile_reached_target ( const Vector3< float >& target_position, const Projectile& projectile,
51
- float pitch, float time) const noexcept ;
78
+ const auto distance2d = EngineTrait::calc_vector_2d_distance (delta);
79
+ const auto distance2d_sqr = distance2d * distance2d;
80
+ const auto launch_speed_sqr = projectile. m_launch_speed * projectile. m_launch_speed ;
52
81
53
- protected:
54
- // NOTE: Override this if you need to use engine with different coordinate system
55
- // Like where Z is not height coordinate
56
- // ===============================================================================================
57
- [[nodiscard]]
58
- virtual float calc_vector_2d_distance (const Vector3<float >& delta) const ;
82
+ float root = launch_speed_sqr * launch_speed_sqr
83
+ - bullet_gravity
84
+ * (bullet_gravity * distance2d_sqr
85
+ + 2 .0f * EngineTrait::get_vector_height_coordinate (delta) * launch_speed_sqr);
59
86
60
- [[nodiscard ]]
61
- virtual float get_vector_height_coordinate ( const Vector3< float >& vec) const ;
87
+ if (root < 0 . 0f ) [[unlikely ]]
88
+ return std::nullopt ;
62
89
63
- [[nodiscard]]
64
- virtual Vector3<float > calc_viewpoint_from_angles (const Projectile& projectile,
65
- Vector3<float > predicted_target_position,
66
- std::optional<float > projectile_pitch) const ;
90
+ root = std::sqrt (root);
91
+ const float angle = std::atan ((launch_speed_sqr - root) / (bullet_gravity * distance2d));
67
92
68
- [[nodiscard]]
69
- virtual Vector3<float > predict_projectile_position (const Projectile& projectile, float pitch, float yaw,
70
- float time, float gravity) const ;
71
- // ===============================================================================================
93
+ return angles::radians_to_degrees (angle);
94
+ }
72
95
};
73
96
} // namespace omath::projectile_prediction
0 commit comments