mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-13 23:13:26 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d12b236e56 | |||
| 7a5090d9f6 | |||
| ec76a7239c | |||
| 2758f549a3 | |||
| 493931ef0f |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
/cmake-build/
|
/cmake-build/
|
||||||
/.idea
|
/.idea
|
||||||
/out
|
/out
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
|
/extlibs/vcpkg
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.26)
|
cmake_minimum_required(VERSION 3.26)
|
||||||
|
|
||||||
project(omath VERSION 3.0.2 LANGUAGES CXX)
|
project(omath VERSION 3.0.4.1 LANGUAGES CXX)
|
||||||
|
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "omath/engines/source_engine/formulas.hpp"
|
#include "omath/engines/source_engine/formulas.hpp"
|
||||||
#include "omath/projectile_prediction/projectile.hpp"
|
#include "omath/projectile_prediction/projectile.hpp"
|
||||||
|
#include "omath/projectile_prediction/target.hpp"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
namespace omath::projectile_prediction::traits
|
namespace omath::projectile_prediction::traits
|
||||||
@@ -25,25 +26,25 @@ namespace omath::projectile_prediction::traits
|
|||||||
|
|
||||||
return current_pos;
|
return current_pos;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]]
|
||||||
static bool is_projectile_reached_target(const Vector3<float>& target_position,
|
static constexpr Vector3<float> predict_target_position(const Target& target, const float time,
|
||||||
const Projectile& projectile, const float pitch,
|
const float gravity) noexcept
|
||||||
const float time, const float gravity,
|
|
||||||
const float tolerance) noexcept
|
|
||||||
{
|
{
|
||||||
const auto yaw = projectile.m_origin.view_angle_to(target_position).y;
|
auto predicted = target.m_origin + target.m_velocity * time;
|
||||||
const auto projectile_position = predict_projectile_position(projectile, pitch, yaw, time, gravity);
|
|
||||||
|
|
||||||
return projectile_position.distance_to(target_position) <= tolerance;
|
if (target.m_is_airborne)
|
||||||
|
predicted.z -= gravity * (time * time) * 0.5f;
|
||||||
|
|
||||||
|
return predicted;
|
||||||
}
|
}
|
||||||
[[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 +52,29 @@ 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));
|
||||||
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
static float calc_direct_yaw_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
|
||||||
|
{
|
||||||
|
const auto delta = view_to - origin;
|
||||||
|
|
||||||
|
return angles::radians_to_degrees(std::atan2(delta.y, delta.x));
|
||||||
|
};
|
||||||
};
|
};
|
||||||
} // namespace omath::projectile_prediction::traits
|
} // namespace omath::projectile_prediction::traits
|
||||||
@@ -13,9 +13,8 @@
|
|||||||
|
|
||||||
namespace omath::projectile_prediction
|
namespace omath::projectile_prediction
|
||||||
{
|
{
|
||||||
// ReSharper disable once CppClassCanBeFinal
|
|
||||||
template<class EngineTrait = traits::SourceEngineTrait>
|
template<class EngineTrait = traits::SourceEngineTrait>
|
||||||
class ProjPredEngineLegacy : public ProjPredEngineInterface
|
class ProjPredEngineLegacy final : public ProjPredEngineInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ProjPredEngineLegacy(const float gravity_constant, const float simulation_time_step,
|
explicit ProjPredEngineLegacy(const float gravity_constant, const float simulation_time_step,
|
||||||
@@ -31,7 +30,8 @@ namespace omath::projectile_prediction
|
|||||||
{
|
{
|
||||||
for (float time = 0.f; time < m_maximum_simulation_time; time += m_simulation_time_step)
|
for (float time = 0.f; time < m_maximum_simulation_time; time += m_simulation_time_step)
|
||||||
{
|
{
|
||||||
const auto predicted_target_position = target.predict_position(time, m_gravity_constant);
|
const auto predicted_target_position =
|
||||||
|
EngineTrait::predict_target_position(target, time, m_gravity_constant);
|
||||||
|
|
||||||
const auto projectile_pitch =
|
const auto projectile_pitch =
|
||||||
maybe_calculate_projectile_launch_pitch_angle(projectile, predicted_target_position);
|
maybe_calculate_projectile_launch_pitch_angle(projectile, predicted_target_position);
|
||||||
@@ -39,9 +39,8 @@ namespace omath::projectile_prediction
|
|||||||
if (!projectile_pitch.has_value()) [[unlikely]]
|
if (!projectile_pitch.has_value()) [[unlikely]]
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!EngineTrait::is_projectile_reached_target(predicted_target_position, projectile,
|
if (!is_projectile_reached_target(predicted_target_position, projectile, projectile_pitch.value(),
|
||||||
projectile_pitch.value(), time, m_gravity_constant,
|
time))
|
||||||
m_distance_tolerance))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return EngineTrait::calc_viewpoint_from_angles(projectile, predicted_target_position, projectile_pitch);
|
return EngineTrait::calc_viewpoint_from_angles(projectile, predicted_target_position, projectile_pitch);
|
||||||
@@ -73,6 +72,10 @@ 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);
|
||||||
@@ -92,5 +95,15 @@ namespace omath::projectile_prediction
|
|||||||
|
|
||||||
return angles::radians_to_degrees(angle);
|
return angles::radians_to_degrees(angle);
|
||||||
}
|
}
|
||||||
|
[[nodiscard]]
|
||||||
|
bool is_projectile_reached_target(const Vector3<float>& target_position, const Projectile& projectile,
|
||||||
|
const float pitch, const float time) const noexcept
|
||||||
|
{
|
||||||
|
const auto yaw = EngineTrait::calc_direct_yaw_angle(projectile.m_origin, target_position);
|
||||||
|
const auto projectile_position =
|
||||||
|
EngineTrait::predict_projectile_position(projectile, pitch, yaw, time, m_gravity_constant);
|
||||||
|
|
||||||
|
return projectile_position.distance_to(target_position) <= m_distance_tolerance;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace omath::projectile_prediction
|
} // namespace omath::projectile_prediction
|
||||||
|
|||||||
@@ -10,17 +10,6 @@ namespace omath::projectile_prediction
|
|||||||
class Target final
|
class Target final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
[[nodiscard]]
|
|
||||||
constexpr Vector3<float> predict_position(const float time, const float gravity) const noexcept
|
|
||||||
{
|
|
||||||
auto predicted = m_origin + m_velocity * time;
|
|
||||||
|
|
||||||
if (m_is_airborne)
|
|
||||||
predicted.z -= gravity * (time*time) * 0.5f;
|
|
||||||
|
|
||||||
return predicted;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3<float> m_origin;
|
Vector3<float> m_origin;
|
||||||
Vector3<float> m_velocity;
|
Vector3<float> m_velocity;
|
||||||
bool m_is_airborne{};
|
bool m_is_airborne{};
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#include "omath/projectile_prediction/proj_pred_engine_legacy.hpp"
|
|
||||||
#include <cmath>
|
|
||||||
#include <omath/angles.hpp>
|
|
||||||
|
|
||||||
namespace omath::projectile_prediction
|
|
||||||
{
|
|
||||||
|
|
||||||
} // namespace omath::projectile_prediction
|
|
||||||
Reference in New Issue
Block a user