mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-13 15:03:27 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f1984fbe46 | |||
| f1fbea21a7 | |||
| 4b44ce0667 | |||
| 231ef35a0a | |||
| 1aa62cb396 | |||
| 8e411771c2 | |||
| d65852d1a4 | |||
| 21f5e82a20 | |||
|
|
851ec37350 | ||
| f1cd9dbeb3 | |||
| 7a1c7d6cc4 | |||
| cb704b3621 | |||
|
|
646d295876 | ||
| 8e09556c25 | |||
| 7dbebc996d | |||
| 278ffba0ff | |||
| 647cf02a38 | |||
| 4be2986681 |
@@ -14,6 +14,8 @@ option(OMATH_BUILD_EXAMPLES "Build example projects with you can learn & play" O
|
||||
option(OMATH_STATIC_MSVC_RUNTIME_LIBRARY "Force Omath to link static runtime" OFF)
|
||||
option(OMATH_SUPRESS_SAFETY_CHECKS "Supress some safety checks in release build to improve general performance" ON)
|
||||
option(OMATH_USE_UNITY_BUILD "Will enable unity build to speed up compilation" ON)
|
||||
option(OMATH_ENABLE_LEGACY "Will enable legacy classes that MUST be used ONLY for backward compatibility" OFF)
|
||||
|
||||
|
||||
file(GLOB_RECURSE OMATH_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")
|
||||
file(GLOB_RECURSE OMATH_HEADERS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp")
|
||||
@@ -56,6 +58,10 @@ if (OMATH_SUPRESS_SAFETY_CHECKS)
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_SUPRESS_SAFETY_CHECKS)
|
||||
endif ()
|
||||
|
||||
if (OMATH_ENABLE_LEGACY)
|
||||
target_compile_options(${PROJECT_NAME} PUBLIC OMATH_ENABLE_LEGACY)
|
||||
endif ()
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}"
|
||||
|
||||
14
INSTALL.md
14
INSTALL.md
@@ -14,6 +14,20 @@ target_link_libraries(main PRIVATE omath::omath)
|
||||
```
|
||||
For detailed commands on installing different versions and more information, please refer to Microsoft's [official instructions](https://learn.microsoft.com/en-us/vcpkg/get_started/overview).
|
||||
|
||||
## <img width="28px" src="https://xmake.io/assets/img/logo.svg" /> Using xrepo
|
||||
**Note**: Support xrepo for package management
|
||||
1. Install [xmake](https://xmake.io/)
|
||||
2. Run the following command to install the omath package:
|
||||
```
|
||||
xrepo install omath
|
||||
```
|
||||
xmake.lua
|
||||
```xmake
|
||||
add_requires("omath")
|
||||
target("...")
|
||||
add_packages("omath")
|
||||
```
|
||||
|
||||
## <img width="28px" src="https://upload.wikimedia.org/wikipedia/commons/e/ef/CMake_logo.svg?" /> Build from source using CMake
|
||||
1. **Preparation**
|
||||
|
||||
|
||||
13
README.md
13
README.md
@@ -7,11 +7,22 @@
|
||||

|
||||
[](https://www.codefactor.io/repository/github/orange-cpp/omath)
|
||||

|
||||
[](https://repology.org/project/orange-math/versions)
|
||||

|
||||
</div>
|
||||
|
||||
Oranges's Math Library (omath) is a comprehensive, open-source library aimed at providing efficient, reliable, and versatile mathematical functions and algorithms. Developed primarily in C++, this library is designed to cater to a wide range of mathematical operations essential in scientific computing, engineering, and academic research.
|
||||
|
||||
<div align = center>
|
||||
<a href="https://www.star-history.com/#orange-cpp/omath&Date">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=orange-cpp/omath&type=Date&theme=dark" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=orange-cpp/omath&type=Date" />
|
||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=orange-cpp/omath&type=Date" />
|
||||
</picture>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## 👁🗨 Features
|
||||
- **Efficiency**: Optimized for performance, ensuring quick computations using AVX2.
|
||||
- **Versatility**: Includes a wide array of mathematical functions and algorithms.
|
||||
@@ -71,7 +82,7 @@ Or even advanced projectile aimbot
|
||||
Contributions to `omath` are welcome! Please read `CONTRIBUTING.md` for details on our code of conduct and the process for submitting pull requests.
|
||||
|
||||
## 📜 License
|
||||
This project is licensed under the MIT - see the `LICENSE` file for details.
|
||||
This project is licensed under the ZLIB - see the `LICENSE` file for details.
|
||||
|
||||
## 💘 Acknowledgments
|
||||
- [All contributors](https://github.com/orange-cpp/omath/graphs/contributors)
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef OMATH_ENABLE_LEGACY
|
||||
|
||||
#include "omath/vector3.hpp"
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
@@ -106,3 +109,4 @@ namespace omath
|
||||
std::unique_ptr<float[]> m_data;
|
||||
};
|
||||
} // namespace omath
|
||||
#endif
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
namespace omath::projectile_prediction
|
||||
{
|
||||
class ProjPredEngine
|
||||
class ProjPredEngineInterface
|
||||
{
|
||||
public:
|
||||
[[nodiscard]]
|
||||
virtual std::optional<Vector3<float>> maybe_calculate_aim_point(const Projectile& projectile,
|
||||
const Target& target) const = 0;
|
||||
virtual ~ProjPredEngine() = default;
|
||||
virtual ~ProjPredEngineInterface() = default;
|
||||
};
|
||||
} // namespace omath::projectile_prediction
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace omath::projectile_prediction
|
||||
{
|
||||
class ProjPredEngineAvx2 final : public ProjPredEngine
|
||||
class ProjPredEngineAvx2 final : public ProjPredEngineInterface
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] std::optional<Vector3<float>>
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
|
||||
namespace omath::projectile_prediction
|
||||
{
|
||||
class ProjPredEngineLegacy final : public ProjPredEngine
|
||||
// ReSharper disable once CppClassCanBeFinal
|
||||
class ProjPredEngineLegacy : public ProjPredEngineInterface
|
||||
{
|
||||
public:
|
||||
explicit ProjPredEngineLegacy(float gravity_constant, float simulation_time_step, float maximum_simulation_time,
|
||||
@@ -28,6 +29,18 @@ namespace omath::projectile_prediction
|
||||
const float m_maximum_simulation_time;
|
||||
const float m_distance_tolerance;
|
||||
|
||||
// Realization of this formula:
|
||||
// https://stackoverflow.com/questions/54917375/how-to-calculate-the-angle-to-shoot-a-bullet-in-order-to-hit-a-moving-target
|
||||
/*
|
||||
\[
|
||||
\theta \;=\; \arctan\!\Biggl(
|
||||
\frac{%
|
||||
v^{2}\;\pm\;\sqrt{\,v^{4}-g\!\left(gx^{2}+2yv^{2}\right)\,}
|
||||
}{%
|
||||
gx
|
||||
}\Biggr)
|
||||
\]
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<float>
|
||||
maybe_calculate_projectile_launch_pitch_angle(const Projectile& projectile,
|
||||
@@ -36,5 +49,25 @@ namespace omath::projectile_prediction
|
||||
[[nodiscard]]
|
||||
bool is_projectile_reached_target(const Vector3<float>& target_position, const Projectile& projectile,
|
||||
float pitch, float time) const noexcept;
|
||||
|
||||
protected:
|
||||
// NOTE: Override this if you need to use engine with different coordinate system
|
||||
// Like where Z is not height coordinate
|
||||
// ===============================================================================================
|
||||
[[nodiscard]]
|
||||
virtual float calc_vector_2d_distance(const Vector3<float>& delta) const;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual float get_vector_height_coordinate(const Vector3<float>& vec) const;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Vector3<float> calc_viewpoint_from_angles(const Projectile& projectile,
|
||||
Vector3<float> predicted_target_position,
|
||||
std::optional<float> projectile_pitch) const;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Vector3<float> predict_projectile_position(const Projectile& projectile, float pitch, float yaw,
|
||||
float time, float gravity) const;
|
||||
// ===============================================================================================
|
||||
};
|
||||
} // namespace omath::projectile_prediction
|
||||
|
||||
@@ -10,9 +10,6 @@ namespace omath::projectile_prediction
|
||||
class Projectile final
|
||||
{
|
||||
public:
|
||||
[[nodiscard]]
|
||||
Vector3<float> predict_position(float pitch, float yaw, float time, float gravity) const noexcept;
|
||||
|
||||
Vector3<float> m_origin;
|
||||
float m_launch_speed{};
|
||||
float m_gravity_scale{};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifdef OMATH_ENABLE_LEGACY
|
||||
|
||||
#include "omath/matrix.hpp"
|
||||
#include "omath/angles.hpp"
|
||||
#include "omath/vector3.hpp"
|
||||
@@ -359,3 +361,4 @@ namespace omath
|
||||
m_data = nullptr;
|
||||
}
|
||||
} // namespace omath
|
||||
#endif
|
||||
|
||||
@@ -27,10 +27,7 @@ namespace omath::projectile_prediction
|
||||
if (!is_projectile_reached_target(predicted_target_position, projectile, projectile_pitch.value(), time))
|
||||
continue;
|
||||
|
||||
const auto delta2d = (predicted_target_position - projectile.m_origin).length_2d();
|
||||
const auto height = delta2d * std::tan(angles::degrees_to_radians(projectile_pitch.value()));
|
||||
|
||||
return Vector3(predicted_target_position.x, predicted_target_position.y, projectile.m_origin.z + height);
|
||||
return calc_viewpoint_from_angles(projectile, predicted_target_position, projectile_pitch);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -41,12 +38,14 @@ namespace omath::projectile_prediction
|
||||
const auto bullet_gravity = m_gravity_constant * projectile.m_gravity_scale;
|
||||
const auto delta = target_position - projectile.m_origin;
|
||||
|
||||
const auto distance2d = delta.length_2d();
|
||||
const auto distance2d = calc_vector_2d_distance(delta);
|
||||
const auto distance2d_sqr = distance2d * distance2d;
|
||||
const auto launch_speed_sqr = projectile.m_launch_speed * projectile.m_launch_speed;
|
||||
|
||||
float root = launch_speed_sqr * launch_speed_sqr
|
||||
- bullet_gravity * (bullet_gravity * distance2d_sqr + 2.0f * delta.z * launch_speed_sqr);
|
||||
- bullet_gravity
|
||||
* (bullet_gravity * distance2d_sqr
|
||||
+ 2.0f * get_vector_height_coordinate(delta) * launch_speed_sqr);
|
||||
|
||||
if (root < 0.0f) [[unlikely]]
|
||||
return std::nullopt;
|
||||
@@ -62,8 +61,40 @@ namespace omath::projectile_prediction
|
||||
const float time) const noexcept
|
||||
{
|
||||
const auto yaw = projectile.m_origin.view_angle_to(target_position).y;
|
||||
const auto projectile_position = projectile.predict_position(pitch, yaw, time, m_gravity_constant);
|
||||
const auto projectile_position = predict_projectile_position(projectile, pitch, yaw, time, m_gravity_constant);
|
||||
|
||||
return projectile_position.distance_to(target_position) <= m_distance_tolerance;
|
||||
}
|
||||
|
||||
float ProjPredEngineLegacy::calc_vector_2d_distance(const Vector3<float>& delta) const
|
||||
{
|
||||
return std::sqrt(delta.x * delta.x + delta.y * delta.y);
|
||||
}
|
||||
|
||||
float ProjPredEngineLegacy::get_vector_height_coordinate(const Vector3<float>& vec) const
|
||||
{
|
||||
return vec.z;
|
||||
}
|
||||
Vector3<float> ProjPredEngineLegacy::calc_viewpoint_from_angles(const Projectile& projectile,
|
||||
const Vector3<float> predicted_target_position,
|
||||
const std::optional<float> projectile_pitch) const
|
||||
{
|
||||
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};
|
||||
}
|
||||
Vector3<float> ProjPredEngineLegacy::predict_projectile_position(const Projectile& projectile, const float pitch,
|
||||
const float yaw, const float time,
|
||||
const float gravity) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
} // namespace omath::projectile_prediction
|
||||
|
||||
@@ -7,16 +7,4 @@
|
||||
|
||||
namespace omath::projectile_prediction
|
||||
{
|
||||
Vector3<float> Projectile::predict_position(const float pitch, const float yaw, const float time,
|
||||
const float gravity) const noexcept
|
||||
{
|
||||
auto current_pos = m_origin
|
||||
+ source_engine::forward_vector({source_engine::PitchAngle::from_degrees(-pitch),
|
||||
source_engine::YawAngle::from_degrees(yaw),
|
||||
source_engine::RollAngle::from_degrees(0)})
|
||||
* m_launch_speed * time;
|
||||
current_pos.z -= (gravity * m_gravity_scale) * (time * time) * 0.5f;
|
||||
|
||||
return current_pos;
|
||||
}
|
||||
} // namespace omath::projectile_prediction
|
||||
|
||||
@@ -31,10 +31,10 @@ namespace
|
||||
// -----------------------------------------------------------------------------
|
||||
// Fixture with one canonical right‑angled triangle in the XY plane.
|
||||
// -----------------------------------------------------------------------------
|
||||
class lline_tracer_fixture : public ::testing::Test
|
||||
class line_tracer_fixture : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
lline_tracer_fixture() :
|
||||
line_tracer_fixture() :
|
||||
triangle({0.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, {0.f, 1.f, 0.f})
|
||||
{
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace
|
||||
bool expected_clear; // true => segment does NOT hit the triangle
|
||||
};
|
||||
|
||||
class CanTraceLineParam : public lline_tracer_fixture,
|
||||
class CanTraceLineParam : public line_tracer_fixture,
|
||||
public ::testing::WithParamInterface<TraceCase>
|
||||
{
|
||||
};
|
||||
@@ -79,7 +79,7 @@ namespace
|
||||
// -----------------------------------------------------------------------------
|
||||
// Validate that the reported hit point is correct for a genuine intersection.
|
||||
// -----------------------------------------------------------------------------
|
||||
TEST_F(lline_tracer_fixture, HitPointCorrect)
|
||||
TEST_F(line_tracer_fixture, HitPointCorrect)
|
||||
{
|
||||
constexpr Ray ray{{0.3f, 0.3f, -1.f}, {0.3f, 0.3f, 1.f}};
|
||||
constexpr Vec3 expected{0.3f, 0.3f, 0.f};
|
||||
@@ -92,7 +92,7 @@ namespace
|
||||
// -----------------------------------------------------------------------------
|
||||
// Triangle far beyond the ray should not block.
|
||||
// -----------------------------------------------------------------------------
|
||||
TEST_F(lline_tracer_fixture, DistantTriangleClear)
|
||||
TEST_F(line_tracer_fixture, DistantTriangleClear)
|
||||
{
|
||||
constexpr Ray short_ray{{0.f, 0.f, 0.f}, {0.f, 0.f, 1.f}};
|
||||
constexpr Triangle<Vec3> distant{{1000.f, 1000.f, 1000.f},
|
||||
|
||||
@@ -167,8 +167,8 @@ TEST_F(unit_test_mat, StaticMethod_ToScreenMat)
|
||||
TEST_F(unit_test_mat, Method_At_OutOfRange)
|
||||
{
|
||||
#if !defined(NDEBUG) && defined(OMATH_SUPRESS_SAFETY_CHECKS)
|
||||
EXPECT_THROW(std::ignore = m2.At(2, 0), std::out_of_range);
|
||||
EXPECT_THROW(std::ignore = m2.At(0, 2), std::out_of_range);
|
||||
EXPECT_THROW(std::ignore = m2.at(2, 0), std::out_of_range);
|
||||
EXPECT_THROW(std::ignore = m2.at(0, 2), std::out_of_range);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
//
|
||||
// Created by vlad on 5/18/2024.
|
||||
//
|
||||
|
||||
#ifdef OMATH_ENABLE_LEGACY
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <omath/matrix.hpp>
|
||||
#include "omath/vector3.hpp"
|
||||
@@ -177,4 +180,5 @@ TEST_F(UnitTestMatrix, AssignmentOperator_Move)
|
||||
EXPECT_FLOAT_EQ(m3.at(0, 0), 1.0f);
|
||||
EXPECT_EQ(m2.row_count(), 0); // m2 should be empty after the move
|
||||
EXPECT_EQ(m2.columns_count(), 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user