Compare commits

..

30 Commits

Author SHA1 Message Date
d12b236e56 Refactors target position prediction
Moves target prediction logic into engine traits, improving modularity.

This change consolidates target position prediction within the engine traits,
allowing for a more flexible and maintainable design.

This eliminates redundant code and simplifies the core prediction engine by
delegating target movement calculations to the appropriate trait.
2025-08-04 03:16:04 +03:00
7a5090d9f6 Marks legacy engine class as final
Prevents further inheritance from the legacy projectile prediction engine class.
2025-08-04 01:12:22 +03:00
ec76a7239c 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.
2025-08-04 01:11:11 +03:00
2758f549a3 Updates project version and removes legacy code
Updates the project version to prepare for a new release.

Removes the legacy projectile prediction engine, which is no longer needed.
2025-08-03 18:35:52 +03:00
493931ef0f Ignores vcpkg directory
Excludes the vcpkg directory from being tracked by Git.

This prevents accidental commits of external library files
managed by vcpkg, keeping the repository cleaner.
2025-08-03 18:31:02 +03:00
9e1990942b Refactors projectile prediction engine
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.
2025-08-03 18:28:47 +03:00
f1984fbe46 Merge pull request #51 from orange-cpp/feature/projectile_pred_custom
Refactors projectile prediction engine
2025-08-03 17:38:08 +03:00
f1fbea21a7 Refactors projectile prediction engine
Refactors the projectile prediction engine by introducing an interface
and making the legacy implementation more flexible.

The legacy engine is updated to allow for coordinate system customization
through virtual methods, enabling usage in different game environments.

Also introduces vcpkg support for easier dependency management and adds boost-asio as a dependency.
2025-08-03 17:33:22 +03:00
4b44ce0667 Documents projectile launch angle formula
Adds a comment documenting the formula used for calculating the projectile launch pitch angle.

The comment includes a link to the Stack Overflow discussion where the formula was found and the LaTeX representation of the formula for clarity.
2025-07-31 21:52:16 +03:00
231ef35a0a Merge pull request #49 from orange-cpp/feature/legacy_option
Adds option to enable legacy classes
2025-07-15 11:52:36 +03:00
1aa62cb396 Enables legacy code compilation
The changes encapsulate the matrix tests within an `#ifdef` block, allowing conditional compilation based on whether `OMATH_ENABLE_LEGACY` is defined. This enables the legacy code to be compiled only when needed.
2025-07-15 11:51:14 +03:00
8e411771c2 Adds option to enable legacy classes
Introduces a CMake option to enable legacy classes,
allowing for backward compatibility with older code.
This ensures that older codebases can still function
while new development can utilize updated classes.
2025-07-15 11:48:33 +03:00
d65852d1a4 Update README.md 2025-07-14 23:11:46 +03:00
21f5e82a20 Merge pull request #48 from luadebug/patch-1
Update INSTALL.md
2025-07-14 23:10:39 +03:00
Saikari
851ec37350 Update INSTALL.md 2025-07-14 18:53:41 +03:00
f1cd9dbeb3 Update README.md
fixed ordering
2025-07-14 17:39:16 +03:00
7a1c7d6cc4 Update README.md
made badge in read me smaller
2025-07-14 17:38:50 +03:00
cb704b3621 Merge pull request #47 from luadebug/patch-1
Update README.md

Thx for vcpkg port update <3 u r already in CREDITS.md
2025-07-14 17:37:12 +03:00
Saikari
646d295876 Update README.md 2025-07-14 16:25:16 +03:00
8e09556c25 Update README.md 2025-07-08 17:14:52 +03:00
7dbebc996d Update README.md 2025-07-08 17:13:24 +03:00
278ffba0ff Update README.md 2025-07-08 17:01:56 +03:00
647cf02a38 Renames test fixture for clarity.
Updates the name of the test fixture from "lline_tracer_fixture" to "line_tracer_fixture" for improved readability and consistency in the test code.
2025-07-07 08:28:29 +03:00
4be2986681 Fixes potential compile error
Corrects the usage of `At` method within the unit tests to `at` to resolve a potential compile error due to incorrect case sensitivity.
2025-07-07 08:18:00 +03:00
06d9b4c910 fixed naming in tests 2025-07-07 08:02:35 +03:00
a074fdcb92 Merge pull request #45 from luadebug/patch-1
Check for ImGUI dependency in omathConfig.cmake.in
2025-07-07 05:30:19 +03:00
Saikari
8241d9c355 Update omathConfig.cmake.in 2025-07-07 04:53:56 +03:00
66258f0f6d Updates CMake export target and namespace.
Updates the CMake export target and namespace to use the project name,
improving consistency and avoiding naming conflicts.

Adds a simple diagram to the triangle header file.
2025-07-06 11:14:46 +03:00
65541fa2c7 Renames library target to project name
Updates the CMakeLists.txt to use the project name as the library target name instead of hardcoding "omath".

This change ensures consistency and avoids potential conflicts when integrating the library into other projects.
It also aligns the target naming with CMake best practices.
2025-07-06 11:07:15 +03:00
7e4a6134bf added new method 2025-06-23 06:14:17 +03:00
26 changed files with 326 additions and 216 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
/cmake-build/
/.idea
/out
*.DS_Store
*.DS_Store
/extlibs/vcpkg

View File

@@ -1,11 +1,11 @@
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)
option(OMATH_BUILD_TESTS "Build unit tests" OFF)
option(OMATH_BUILD_TESTS "Build unit tests" ${PROJECT_IS_TOP_LEVEL})
option(OMATH_THREAT_WARNING_AS_ERROR "Set highest level of warnings and force compiler to treat them as errors" ON)
option(OMATH_BUILD_AS_SHARED_LIBRARY "Build Omath as .so or .dll" OFF)
option(OMATH_USE_AVX2 "Omath will use AVX2 to boost performance" ON)
@@ -14,26 +14,29 @@ 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")
if (OMATH_BUILD_AS_SHARED_LIBRARY)
add_library(omath SHARED ${OMATH_SOURCES} ${OMATH_HEADERS})
add_library(${PROJECT_NAME} SHARED ${OMATH_SOURCES} ${OMATH_HEADERS})
else ()
add_library(omath STATIC ${OMATH_SOURCES} ${OMATH_HEADERS})
add_library(${PROJECT_NAME} STATIC ${OMATH_SOURCES} ${OMATH_HEADERS})
endif ()
message(STATUS "Building on ${CMAKE_HOST_SYSTEM_NAME}")
add_library(omath::omath ALIAS omath)
message(STATUS "[OMATH]: Building on ${CMAKE_HOST_SYSTEM_NAME}")
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
if (OMATH_IMGUI_INTEGRATION)
target_compile_definitions(omath PUBLIC OMATH_IMGUI_INTEGRATION)
target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_IMGUI_INTEGRATION)
# IMGUI is being linked as submodule
if (TARGET imgui)
target_link_libraries(omath PUBLIC imgui)
target_link_libraries(${PROJECT_NAME} PUBLIC imgui)
install(TARGETS imgui
EXPORT omathTargets
ARCHIVE DESTINATION lib
@@ -42,42 +45,46 @@ if (OMATH_IMGUI_INTEGRATION)
else ()
# Assume that IMGUI linked via VCPKG.
find_package(imgui CONFIG REQUIRED)
target_link_libraries(omath PUBLIC imgui::imgui)
target_link_libraries(${PROJECT_NAME} PUBLIC imgui::imgui)
endif ()
endif ()
if (OMATH_USE_AVX2)
target_compile_definitions(omath PUBLIC OMATH_USE_AVX2)
target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_USE_AVX2)
endif ()
if (OMATH_SUPRESS_SAFETY_CHECKS)
target_compile_definitions(omath PUBLIC OMATH_SUPRESS_SAFETY_CHECKS)
target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_SUPRESS_SAFETY_CHECKS)
endif ()
set_target_properties(omath PROPERTIES
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}"
CXX_STANDARD 23
CXX_STANDARD_REQUIRED ON)
if (OMATH_USE_UNITY_BUILD)
set_target_properties(omath PROPERTIES
set_target_properties(${PROJECT_NAME} PROPERTIES
UNITY_BUILD ON
UNITY_BUILD_BATCH_SIZE 20)
endif ()
if (OMATH_STATIC_MSVC_RUNTIME_LIBRARY)
set_target_properties(omath PROPERTIES
set_target_properties(${PROJECT_NAME} PROPERTIES
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
)
endif ()
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_options(omath PRIVATE -mavx2 -mfma)
target_compile_options(${PROJECT_NAME} PRIVATE -mavx2 -mfma)
endif ()
target_compile_features(omath PUBLIC cxx_std_23)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
if (OMATH_BUILD_TESTS)
@@ -90,12 +97,12 @@ if (OMATH_BUILD_EXAMPLES)
endif ()
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND OMATH_THREAT_WARNING_AS_ERROR)
target_compile_options(omath PRIVATE /W4 /WX)
target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX)
elseif (OMATH_THREAT_WARNING_AS_ERROR)
target_compile_options(omath PRIVATE -Wall -Wextra -Wpedantic -Werror)
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic -Werror)
endif ()
target_include_directories(omath
target_include_directories(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> # Use this path when building the project
$<INSTALL_INTERFACE:include> # Use this path when the project is installed
@@ -105,21 +112,21 @@ target_include_directories(omath
# Installation rules
# Install the library
install(TARGETS omath
EXPORT omathTargets
ARCHIVE DESTINATION lib COMPONENT omath # For static libraries
LIBRARY DESTINATION lib COMPONENT omath # For shared libraries
RUNTIME DESTINATION bin COMPONENT omath # For executables (on Windows)
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
ARCHIVE DESTINATION lib COMPONENT ${PROJECT_NAME} # For static libraries
LIBRARY DESTINATION lib COMPONENT ${PROJECT_NAME} # For shared libraries
RUNTIME DESTINATION bin COMPONENT ${PROJECT_NAME} # For executables (on Windows)
)
# Install headers as part of omath_component
install(DIRECTORY include/ DESTINATION include COMPONENT omath)
install(DIRECTORY include/ DESTINATION include COMPONENT ${PROJECT_NAME})
# Export omath target for CMake find_package support, also under omath_component
install(EXPORT omathTargets
FILE omathTargets.cmake
NAMESPACE omath::
DESTINATION lib/cmake/omath COMPONENT omath
install(EXPORT ${PROJECT_NAME}Targets
FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION lib/cmake/${PROJECT_NAME} COMPONENT ${PROJECT_NAME}
)
@@ -134,12 +141,12 @@ write_basic_package_version_file(
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/omathConfig.cmake.in" # Path to the .in file
"${CMAKE_CURRENT_BINARY_DIR}/omathConfig.cmake" # Output path for the generated file
INSTALL_DESTINATION lib/cmake/omath
INSTALL_DESTINATION lib/cmake/${PROJECT_NAME}
)
# Install the generated config files
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/omathConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/omathConfigVersion.cmake"
DESTINATION lib/cmake/omath
DESTINATION lib/cmake/${PROJECT_NAME}
)

View File

@@ -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**

View File

@@ -7,11 +7,22 @@
![GitHub top language](https://img.shields.io/github/languages/top/orange-cpp/omath)
[![CodeFactor](https://www.codefactor.io/repository/github/orange-cpp/omath/badge)](https://www.codefactor.io/repository/github/orange-cpp/omath)
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/orange-cpp/omath/cmake-multi-platform.yml)
[![Vcpkg package](https://repology.org/badge/version-for-repo/vcpkg/orange-math.svg)](https://repology.org/project/orange-math/versions)
![GitHub forks](https://img.shields.io/github/forks/orange-cpp/omath)
</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)

View File

@@ -2,6 +2,10 @@
include(CMakeFindDependencyMacro)
if (@OMATH_IMGUI_INTEGRATION@)
find_dependency(imgui CONFIG)
endif()
# Load the targets for the omath library
include("${CMAKE_CURRENT_LIST_DIR}/omathTargets.cmake")
check_required_components(omath)

View File

@@ -166,5 +166,12 @@ namespace omath
{
return {0.f, 0.f, 1.f, 1.f};
}
#ifdef OMATH_IMGUI_INTEGRATION
[[nodiscard]]
ImColor to_im_color() const noexcept
{
return {to_im_vec4()};
}
#endif
};
} // namespace omath

View File

@@ -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

View File

@@ -0,0 +1,80 @@
//
// Created by Vlad on 8/3/2025.
//
#pragma once
#include "omath/engines/source_engine/formulas.hpp"
#include "omath/projectile_prediction/projectile.hpp"
#include "omath/projectile_prediction/target.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;
}
[[nodiscard]]
static constexpr Vector3<float> predict_target_position(const Target& target, const float time,
const float gravity) noexcept
{
auto predicted = target.m_origin + target.m_velocity * time;
if (target.m_is_airborne)
predicted.z -= gravity * (time * time) * 0.5f;
return predicted;
}
[[nodiscard]]
static float calc_vector_2d_distance(const Vector3<float>& delta) noexcept
{
return std::sqrt(delta.x * delta.x + delta.y * delta.y);
}
[[nodiscard]]
constexpr static float get_vector_height_coordinate(const Vector3<float>& vec) noexcept
{
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) noexcept
{
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};
}
// 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

View File

@@ -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

View File

@@ -6,7 +6,7 @@
namespace omath::projectile_prediction
{
class ProjPredEngineAvx2 final : public ProjPredEngine
class ProjPredEngineAvx2 final : public ProjPredEngineInterface
{
public:
[[nodiscard]] std::optional<Vector3<float>>

View File

@@ -4,6 +4,7 @@
#pragma once
#include "engine_traits/source_engine_trait.hpp"
#include "omath/projectile_prediction/proj_pred_engine.hpp"
#include "omath/projectile_prediction/projectile.hpp"
#include "omath/projectile_prediction/target.hpp"
@@ -12,15 +13,40 @@
namespace omath::projectile_prediction
{
class ProjPredEngineLegacy final : public ProjPredEngine
template<class EngineTrait = traits::SourceEngineTrait>
class ProjPredEngineLegacy final : public ProjPredEngineInterface
{
public:
explicit ProjPredEngineLegacy(float gravity_constant, float simulation_time_step, float maximum_simulation_time,
float distance_tolerance);
explicit ProjPredEngineLegacy(const float gravity_constant, const float simulation_time_step,
const float maximum_simulation_time, const float distance_tolerance)
: m_gravity_constant(gravity_constant), m_simulation_time_step(simulation_time_step),
m_maximum_simulation_time(maximum_simulation_time), m_distance_tolerance(distance_tolerance)
{
}
[[nodiscard]]
std::optional<Vector3<float>> maybe_calculate_aim_point(const Projectile& projectile,
const Target& target) const override;
const Target& target) const override
{
for (float time = 0.f; time < m_maximum_simulation_time; time += m_simulation_time_step)
{
const auto predicted_target_position =
EngineTrait::predict_target_position(target, time, m_gravity_constant);
const auto projectile_pitch =
maybe_calculate_projectile_launch_pitch_angle(projectile, predicted_target_position);
if (!projectile_pitch.has_value()) [[unlikely]]
continue;
if (!is_projectile_reached_target(predicted_target_position, projectile, projectile_pitch.value(),
time))
continue;
return EngineTrait::calc_viewpoint_from_angles(projectile, predicted_target_position, projectile_pitch);
}
return std::nullopt;
}
private:
const float m_gravity_constant;
@@ -28,13 +54,56 @@ 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,
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;
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 distance2d = EngineTrait::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 * EngineTrait::get_vector_height_coordinate(delta) * launch_speed_sqr);
if (root < 0.0f) [[unlikely]]
return std::nullopt;
root = std::sqrt(root);
const float angle = std::atan((launch_speed_sqr - root) / (bullet_gravity * distance2d));
return angles::radians_to_degrees(angle);
}
[[nodiscard]]
bool is_projectile_reached_target(const Vector3<float>& target_position, const Projectile& projectile,
float pitch, float time) const noexcept;
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

View File

@@ -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{};

View File

@@ -10,17 +10,6 @@ namespace omath::projectile_prediction
class Target final
{
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_velocity;
bool m_is_airborne{};

View File

@@ -7,11 +7,12 @@
namespace omath
{
/*
v1
|\
| \
a | \ hypot
| \
-----
v2 ----- v3
b
*/

View File

@@ -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

View File

@@ -1,69 +0,0 @@
#include "omath/projectile_prediction/proj_pred_engine_legacy.hpp"
#include <cmath>
#include <omath/angles.hpp>
namespace omath::projectile_prediction
{
ProjPredEngineLegacy::ProjPredEngineLegacy(const float gravity_constant, const float simulation_time_step,
const float maximum_simulation_time, const float distance_tolerance)
: m_gravity_constant(gravity_constant), m_simulation_time_step(simulation_time_step),
m_maximum_simulation_time(maximum_simulation_time), m_distance_tolerance(distance_tolerance)
{
}
std::optional<Vector3<float>> ProjPredEngineLegacy::maybe_calculate_aim_point(const Projectile& projectile,
const Target& target) const
{
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 projectile_pitch =
maybe_calculate_projectile_launch_pitch_angle(projectile, predicted_target_position);
if (!projectile_pitch.has_value()) [[unlikely]]
continue;
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 std::nullopt;
}
std::optional<float> ProjPredEngineLegacy::maybe_calculate_projectile_launch_pitch_angle(
const Projectile& projectile, const Vector3<float>& target_position) const noexcept
{
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_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);
if (root < 0.0f) [[unlikely]]
return std::nullopt;
root = std::sqrt(root);
const float angle = std::atan((launch_speed_sqr - root) / (bullet_gravity * distance2d));
return angles::radians_to_degrees(angle);
}
bool ProjPredEngineLegacy::is_projectile_reached_target(const Vector3<float>& target_position,
const Projectile& projectile, const float pitch,
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);
return projectile_position.distance_to(target_position) <= m_distance_tolerance;
}
} // namespace omath::projectile_prediction

View File

@@ -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

View File

@@ -5,7 +5,7 @@ project(unit_tests)
include(GoogleTest)
file(GLOB_RECURSE UNIT_TESTS_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
add_executable(unit_tests ${UNIT_TESTS_SOURCES})
add_executable(${PROJECT_NAME} ${UNIT_TESTS_SOURCES})
set_target_properties(unit_tests PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}"
@@ -17,6 +17,6 @@ set_target_properties(unit_tests PROPERTIES
CXX_STANDARD_REQUIRED ON)
target_link_libraries(unit_tests PRIVATE gtest gtest_main omath::omath)
target_link_libraries(${PROJECT_NAME} PRIVATE gtest gtest_main omath::omath)
gtest_discover_tests(unit_tests)
gtest_discover_tests(${PROJECT_NAME})

View File

@@ -7,27 +7,27 @@
#include <omath/engines/iw_engine/formulas.hpp>
TEST(UnitTestIwEngine, ForwardVector)
TEST(unit_test_iw_engine, ForwardVector)
{
const auto forward = omath::iw_engine::forward_vector({});
EXPECT_EQ(forward, omath::iw_engine::k_abs_forward);
}
TEST(UnitTestIwEngine, RightVector)
TEST(unit_test_iw_engine, RightVector)
{
const auto right = omath::iw_engine::right_vector({});
EXPECT_EQ(right, omath::iw_engine::k_abs_right);
}
TEST(UnitTestIwEngine, UpVector)
TEST(unit_test_iw_engine, UpVector)
{
const auto up = omath::iw_engine::up_vector({});
EXPECT_EQ(up, omath::iw_engine::k_abs_up);
}
TEST(UnitTestIwEngine, ForwardVectorRotationYaw)
TEST(unit_test_iw_engine, ForwardVectorRotationYaw)
{
omath::iw_engine::ViewAngles angles;
@@ -39,7 +39,7 @@ TEST(UnitTestIwEngine, ForwardVectorRotationYaw)
EXPECT_NEAR(forward.z, omath::iw_engine::k_abs_right.z, 0.00001f);
}
TEST(UnitTestIwEngine, ForwardVectorRotationPitch)
TEST(unit_test_iw_engine, ForwardVectorRotationPitch)
{
omath::iw_engine::ViewAngles angles;
@@ -51,7 +51,7 @@ TEST(UnitTestIwEngine, ForwardVectorRotationPitch)
EXPECT_NEAR(forward.z, omath::iw_engine::k_abs_up.z, 0.01f);
}
TEST(UnitTestIwEngine, ForwardVectorRotationRoll)
TEST(unit_test_iw_engine, ForwardVectorRotationRoll)
{
omath::iw_engine::ViewAngles angles;
@@ -63,7 +63,7 @@ TEST(UnitTestIwEngine, ForwardVectorRotationRoll)
EXPECT_NEAR(forward.z, omath::iw_engine::k_abs_right.z, 0.00001f);
}
TEST(UnitTestIwEngine, ProjectTargetMovedFromCamera)
TEST(unit_test_iw_engine, ProjectTargetMovedFromCamera)
{
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
const auto cam = omath::iw_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
@@ -83,7 +83,7 @@ TEST(UnitTestIwEngine, ProjectTargetMovedFromCamera)
}
}
TEST(UnitTestIwEngine, CameraSetAndGetFov)
TEST(unit_test_iw_engine, CameraSetAndGetFov)
{
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
auto cam = omath::iw_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
@@ -94,7 +94,7 @@ TEST(UnitTestIwEngine, CameraSetAndGetFov)
EXPECT_EQ(cam.get_field_of_view().as_degrees(), 50.f);
}
TEST(UnitTestIwEngine, CameraSetAndGetOrigin)
TEST(unit_test_iw_engine, CameraSetAndGetOrigin)
{
auto cam = omath::iw_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f);

View File

@@ -7,25 +7,25 @@
#include <omath/engines/opengl_engine/formulas.hpp>
TEST(UnitTestOpenGL, ForwardVector)
TEST(unit_test_opengl, ForwardVector)
{
const auto forward = omath::opengl_engine::forward_vector({});
EXPECT_EQ(forward, omath::opengl_engine::k_abs_forward);
}
TEST(UnitTestOpenGL, RightVector)
TEST(unit_test_opengl, RightVector)
{
const auto right = omath::opengl_engine::right_vector({});
EXPECT_EQ(right, omath::opengl_engine::k_abs_right);
}
TEST(UnitTestOpenGL, UpVector)
TEST(unit_test_opengl, UpVector)
{
const auto up = omath::opengl_engine::up_vector({});
EXPECT_EQ(up, omath::opengl_engine::k_abs_up);
}
TEST(UnitTestOpenGL, ForwardVectorRotationYaw)
TEST(unit_test_opengl, ForwardVectorRotationYaw)
{
omath::opengl_engine::ViewAngles angles;
@@ -39,7 +39,7 @@ TEST(UnitTestOpenGL, ForwardVectorRotationYaw)
TEST(UnitTestOpenGL, ForwardVectorRotationPitch)
TEST(unit_test_opengl, ForwardVectorRotationPitch)
{
omath::opengl_engine::ViewAngles angles;
@@ -51,7 +51,7 @@ TEST(UnitTestOpenGL, ForwardVectorRotationPitch)
EXPECT_NEAR(forward.z, omath::opengl_engine::k_abs_up.z, 0.00001f);
}
TEST(UnitTestOpenGL, ForwardVectorRotationRoll)
TEST(unit_test_opengl, ForwardVectorRotationRoll)
{
omath::opengl_engine::ViewAngles angles;
@@ -63,7 +63,7 @@ TEST(UnitTestOpenGL, ForwardVectorRotationRoll)
EXPECT_NEAR(forward.z, omath::opengl_engine::k_abs_right.z, 0.00001f);
}
TEST(UnitTestOpenGL, ProjectTargetMovedFromCamera)
TEST(unit_test_opengl, ProjectTargetMovedFromCamera)
{
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
const auto cam = omath::opengl_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
@@ -83,7 +83,7 @@ TEST(UnitTestOpenGL, ProjectTargetMovedFromCamera)
}
}
TEST(UnitTestOpenGL, CameraSetAndGetFov)
TEST(unit_test_opengl, CameraSetAndGetFov)
{
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
auto cam = omath::opengl_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
@@ -94,7 +94,7 @@ TEST(UnitTestOpenGL, CameraSetAndGetFov)
EXPECT_EQ(cam.get_field_of_view().as_degrees(), 50.f);
}
TEST(UnitTestOpenGL, CameraSetAndGetOrigin)
TEST(unit_test_opengl, CameraSetAndGetOrigin)
{
auto cam = omath::opengl_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f);

View File

@@ -7,27 +7,27 @@
#include <omath/engines/source_engine/formulas.hpp>
TEST(UnitTestSourceEngine, ForwardVector)
TEST(unit_test_source_engine, ForwardVector)
{
const auto forward = omath::source_engine::forward_vector({});
EXPECT_EQ(forward, omath::source_engine::k_abs_forward);
}
TEST(UnitTestSourceEngine, RightVector)
TEST(unit_test_source_engine, RightVector)
{
const auto right = omath::source_engine::right_vector({});
EXPECT_EQ(right, omath::source_engine::k_abs_right);
}
TEST(UnitTestSourceEngine, UpVector)
TEST(unit_test_source_engine, UpVector)
{
const auto up = omath::source_engine::up_vector({});
EXPECT_EQ(up, omath::source_engine::k_abs_up);
}
TEST(UnitTestSourceEngine, ForwardVectorRotationYaw)
TEST(unit_test_source_engine, ForwardVectorRotationYaw)
{
omath::source_engine::ViewAngles angles;
@@ -39,7 +39,7 @@ TEST(UnitTestSourceEngine, ForwardVectorRotationYaw)
EXPECT_NEAR(forward.z, omath::source_engine::k_abs_right.z, 0.00001f);
}
TEST(UnitTestSourceEngine, ForwardVectorRotationPitch)
TEST(unit_test_source_engine, ForwardVectorRotationPitch)
{
omath::source_engine::ViewAngles angles;
@@ -51,7 +51,7 @@ TEST(UnitTestSourceEngine, ForwardVectorRotationPitch)
EXPECT_NEAR(forward.z, omath::source_engine::k_abs_up.z, 0.01f);
}
TEST(UnitTestSourceEngine, ForwardVectorRotationRoll)
TEST(unit_test_source_engine, ForwardVectorRotationRoll)
{
omath::source_engine::ViewAngles angles;
@@ -63,7 +63,7 @@ TEST(UnitTestSourceEngine, ForwardVectorRotationRoll)
EXPECT_NEAR(forward.z, omath::source_engine::k_abs_right.z, 0.00001f);
}
TEST(UnitTestSourceEngine, ProjectTargetMovedFromCamera)
TEST(unit_test_source_engine, ProjectTargetMovedFromCamera)
{
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
const auto cam = omath::source_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
@@ -83,7 +83,7 @@ TEST(UnitTestSourceEngine, ProjectTargetMovedFromCamera)
}
}
TEST(UnitTestSourceEngine, ProjectTargetMovedUp)
TEST(unit_test_source_engine, ProjectTargetMovedUp)
{
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
const auto cam = omath::source_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
@@ -103,7 +103,7 @@ TEST(UnitTestSourceEngine, ProjectTargetMovedUp)
}
}
TEST(UnitTestSourceEngine, CameraSetAndGetFov)
TEST(unit_test_source_engine, CameraSetAndGetFov)
{
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
auto cam = omath::source_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
@@ -114,7 +114,7 @@ TEST(UnitTestSourceEngine, CameraSetAndGetFov)
EXPECT_EQ(cam.get_field_of_view().as_degrees(), 50.f);
}
TEST(UnitTestSourceEngine, CameraSetAndGetOrigin)
TEST(unit_test_source_engine, CameraSetAndGetOrigin)
{
auto cam = omath::source_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f);

View File

@@ -7,14 +7,14 @@
#include <omath/engines/unity_engine/formulas.hpp>
#include <print>
TEST(UnitTestUnityEngine, ForwardVector)
TEST(unit_test_unity_engine, ForwardVector)
{
const auto forward = omath::unity_engine::forward_vector({});
EXPECT_EQ(forward, omath::unity_engine::k_abs_forward);
}
TEST(UnitTestUnityEngine, ForwardVectorRotationYaw)
TEST(unit_test_unity_engine, ForwardVectorRotationYaw)
{
omath::unity_engine::ViewAngles angles;
@@ -26,7 +26,7 @@ TEST(UnitTestUnityEngine, ForwardVectorRotationYaw)
EXPECT_NEAR(forward.z, omath::unity_engine::k_abs_right.z, 0.00001f);
}
TEST(UnitTestUnityEngine, ForwardVectorRotationPitch)
TEST(unit_test_unity_engine, ForwardVectorRotationPitch)
{
omath::unity_engine::ViewAngles angles;
@@ -38,7 +38,7 @@ TEST(UnitTestUnityEngine, ForwardVectorRotationPitch)
EXPECT_NEAR(forward.z, omath::unity_engine::k_abs_up.z, 0.00001f);
}
TEST(UnitTestUnityEngine, ForwardVectorRotationRoll)
TEST(unit_test_unity_engine, ForwardVectorRotationRoll)
{
omath::unity_engine::ViewAngles angles;
@@ -50,20 +50,20 @@ TEST(UnitTestUnityEngine, ForwardVectorRotationRoll)
EXPECT_NEAR(forward.z, omath::unity_engine::k_abs_right.z, 0.00001f);
}
TEST(UnitTestUnityEngine, RightVector)
TEST(unit_test_unity_engine, RightVector)
{
const auto right = omath::unity_engine::right_vector({});
EXPECT_EQ(right, omath::unity_engine::k_abs_right);
}
TEST(UnitTestUnityEngine, UpVector)
TEST(unit_test_unity_engine, UpVector)
{
const auto up = omath::unity_engine::up_vector({});
EXPECT_EQ(up, omath::unity_engine::k_abs_up);
}
TEST(UnitTestUnityEngine, ProjectTargetMovedFromCamera)
TEST(unit_test_unity_engine, ProjectTargetMovedFromCamera)
{
constexpr auto fov = omath::projection::FieldOfView::from_degrees(60.f);
const auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1280.f, 720.f}, fov, 0.01f, 1000.f);
@@ -82,7 +82,7 @@ TEST(UnitTestUnityEngine, ProjectTargetMovedFromCamera)
EXPECT_NEAR(projected->y, 360, 0.00001f);
}
}
TEST(UnitTestUnityEngine, Project)
TEST(unit_test_unity_engine, Project)
{
constexpr auto fov = omath::projection::FieldOfView::from_degrees(60.f);
@@ -91,7 +91,7 @@ TEST(UnitTestUnityEngine, Project)
std::println("{} {}", proj->x, proj->y);
}
TEST(UnitTestUnityEngine, CameraSetAndGetFov)
TEST(unit_test_unity_engine, CameraSetAndGetFov)
{
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
@@ -102,7 +102,7 @@ TEST(UnitTestUnityEngine, CameraSetAndGetFov)
EXPECT_EQ(cam.get_field_of_view().as_degrees(), 50.f);
}
TEST(UnitTestUnityEngine, CameraSetAndGetOrigin)
TEST(unit_test_unity_engine, CameraSetAndGetOrigin)
{
auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f);

View File

@@ -7,7 +7,7 @@
using namespace omath;
class UnitTestColor : public ::testing::Test
class unit_test_color : public ::testing::Test
{
protected:
Color color1;
@@ -21,7 +21,7 @@ protected:
};
// Test constructors
TEST_F(UnitTestColor, Constructor_Float)
TEST_F(unit_test_color, Constructor_Float)
{
constexpr Color color(0.5f, 0.5f, 0.5f, 1.0f);
EXPECT_FLOAT_EQ(color.x, 0.5f);
@@ -30,7 +30,7 @@ TEST_F(UnitTestColor, Constructor_Float)
EXPECT_FLOAT_EQ(color.w, 1.0f);
}
TEST_F(UnitTestColor, Constructor_Vector4)
TEST_F(unit_test_color, Constructor_Vector4)
{
constexpr omath::Vector4 vec(0.2f, 0.4f, 0.6f, 0.8f);
Color color(vec);
@@ -41,7 +41,7 @@ TEST_F(UnitTestColor, Constructor_Vector4)
}
// Test static methods for color creation
TEST_F(UnitTestColor, FromRGBA)
TEST_F(unit_test_color, FromRGBA)
{
constexpr Color color = Color::from_rgba(128, 64, 32, 255);
EXPECT_FLOAT_EQ(color.x, 128.0f / 255.0f);
@@ -50,7 +50,7 @@ TEST_F(UnitTestColor, FromRGBA)
EXPECT_FLOAT_EQ(color.w, 1.0f);
}
TEST_F(UnitTestColor, FromHSV)
TEST_F(unit_test_color, FromHSV)
{
constexpr Color color = Color::from_hsv(0.0f, 1.0f, 1.0f); // Red in HSV
EXPECT_FLOAT_EQ(color.x, 1.0f);
@@ -60,7 +60,7 @@ TEST_F(UnitTestColor, FromHSV)
}
// Test HSV conversion
TEST_F(UnitTestColor, ToHSV)
TEST_F(unit_test_color, ToHSV)
{
Hsv hsv = color1.to_hsv(); // Red color
EXPECT_FLOAT_EQ(hsv.hue, 0.0f);
@@ -69,7 +69,7 @@ TEST_F(UnitTestColor, ToHSV)
}
// Test color blending
TEST_F(UnitTestColor, Blend)
TEST_F(unit_test_color, Blend)
{
Color blended = color1.blend(color2, 0.5f);
EXPECT_FLOAT_EQ(blended.x, 0.5f);
@@ -79,7 +79,7 @@ TEST_F(UnitTestColor, Blend)
}
// Test predefined colors
TEST_F(UnitTestColor, PredefinedColors)
TEST_F(unit_test_color, PredefinedColors)
{
constexpr Color red = Color::red();
constexpr Color green = Color::green();
@@ -102,7 +102,7 @@ TEST_F(UnitTestColor, PredefinedColors)
}
// Test non-member function: Blend for Vector3
TEST_F(UnitTestColor, BlendVector3)
TEST_F(unit_test_color, BlendVector3)
{
constexpr Color v1(1.0f, 0.0f, 0.0f, 1.f); // Red
constexpr Color v2(0.0f, 1.0f, 0.0f, 1.f); // Green

View File

@@ -31,10 +31,10 @@ namespace
// -----------------------------------------------------------------------------
// Fixture with one canonical rightangled triangle in the XY plane.
// -----------------------------------------------------------------------------
class LineTracerFixture : public ::testing::Test
class line_tracer_fixture : public ::testing::Test
{
protected:
LineTracerFixture() :
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 LineTracerFixture,
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(LineTracerFixture, 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(LineTracerFixture, 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},
@@ -102,7 +102,7 @@ namespace
EXPECT_TRUE(LineTracer::can_trace_line(short_ray, distant));
}
TEST(LineTracerTraceRayEdge, CantHit)
TEST(unit_test_unity_engine, CantHit)
{
constexpr omath::Triangle<Vector3<float>> triangle{{2, 0, 0}, {2, 2, 0}, {2, 2, 2}};
@@ -110,7 +110,7 @@ namespace
EXPECT_TRUE(omath::collision::LineTracer::can_trace_line(ray, triangle));
}
TEST(LineTracerTraceRayEdge, CanHit)
TEST(unit_test_unity_engine, CanHit)
{
constexpr omath::Triangle<Vector3<float>> triangle{{2, 0, 0}, {2, 2, 0}, {2, 2, 2}};

View File

@@ -5,7 +5,7 @@
using namespace omath;
class UnitTestMat : public ::testing::Test
class unit_test_mat : public ::testing::Test
{
protected:
Mat<2, 2> m1;
@@ -19,7 +19,7 @@ protected:
};
// Test constructors
TEST_F(UnitTestMat, Constructor_Default)
TEST_F(unit_test_mat, Constructor_Default)
{
Mat<3, 3> m;
EXPECT_EQ(m.row_count(), 3);
@@ -29,7 +29,7 @@ TEST_F(UnitTestMat, Constructor_Default)
EXPECT_FLOAT_EQ(m.at(i, j), 0.0f);
}
TEST_F(UnitTestMat, Constructor_InitializerList)
TEST_F(unit_test_mat, Constructor_InitializerList)
{
constexpr Mat<2, 2> m{{1.0f, 2.0f}, {3.0f, 4.0f}};
EXPECT_EQ(m.row_count(), 2);
@@ -40,7 +40,7 @@ TEST_F(UnitTestMat, Constructor_InitializerList)
EXPECT_FLOAT_EQ(m.at(1, 1), 4.0f);
}
TEST_F(UnitTestMat, Operator_SquareBrackets)
TEST_F(unit_test_mat, Operator_SquareBrackets)
{
EXPECT_EQ((m2[0, 0]), 1.0f);
EXPECT_EQ((m2[0, 1]), 2.0f);
@@ -48,7 +48,7 @@ TEST_F(UnitTestMat, Operator_SquareBrackets)
EXPECT_EQ((m2[1, 1]), 4.0f);
}
TEST_F(UnitTestMat, Constructor_Copy)
TEST_F(unit_test_mat, Constructor_Copy)
{
Mat<2, 2> m3 = m2;
EXPECT_EQ(m3.row_count(), m2.row_count());
@@ -57,7 +57,7 @@ TEST_F(UnitTestMat, Constructor_Copy)
EXPECT_FLOAT_EQ(m3.at(1, 1), m2.at(1, 1));
}
TEST_F(UnitTestMat, Constructor_Move)
TEST_F(unit_test_mat, Constructor_Move)
{
Mat<2, 2> m3 = std::move(m2);
EXPECT_EQ(m3.row_count(), 2);
@@ -68,7 +68,7 @@ TEST_F(UnitTestMat, Constructor_Move)
}
// Test matrix operations
TEST_F(UnitTestMat, Operator_Multiplication_Matrix)
TEST_F(unit_test_mat, Operator_Multiplication_Matrix)
{
Mat<2, 2> m3 = m2 * m2;
EXPECT_EQ(m3.row_count(), 2);
@@ -79,14 +79,14 @@ TEST_F(UnitTestMat, Operator_Multiplication_Matrix)
EXPECT_FLOAT_EQ(m3.at(1, 1), 22.0f);
}
TEST_F(UnitTestMat, Operator_Multiplication_Scalar)
TEST_F(unit_test_mat, Operator_Multiplication_Scalar)
{
Mat<2, 2> m3 = m2 * 2.0f;
EXPECT_FLOAT_EQ(m3.at(0, 0), 2.0f);
EXPECT_FLOAT_EQ(m3.at(1, 1), 8.0f);
}
TEST_F(UnitTestMat, Operator_Division_Scalar)
TEST_F(unit_test_mat, Operator_Division_Scalar)
{
Mat<2, 2> m3 = m2 / 2.0f;
EXPECT_FLOAT_EQ(m3.at(0, 0), 0.5f);
@@ -94,7 +94,7 @@ TEST_F(UnitTestMat, Operator_Division_Scalar)
}
// Test matrix functions
TEST_F(UnitTestMat, Transpose)
TEST_F(unit_test_mat, Transpose)
{
Mat<2, 2> m3 = m2.transposed();
EXPECT_FLOAT_EQ(m3.at(0, 0), m2.at(0, 0));
@@ -103,19 +103,19 @@ TEST_F(UnitTestMat, Transpose)
EXPECT_FLOAT_EQ(m3.at(1, 1), m2.at(1, 1));
}
TEST_F(UnitTestMat, Determinant)
TEST_F(unit_test_mat, Determinant)
{
const float det = m2.determinant();
EXPECT_FLOAT_EQ(det, -2.0f);
}
TEST_F(UnitTestMat, Sum)
TEST_F(unit_test_mat, Sum)
{
const float sum = m2.sum();
EXPECT_FLOAT_EQ(sum, 10.0f);
}
TEST_F(UnitTestMat, Clear)
TEST_F(unit_test_mat, Clear)
{
m2.clear();
for (size_t i = 0; i < m2.row_count(); ++i)
@@ -123,7 +123,7 @@ TEST_F(UnitTestMat, Clear)
EXPECT_FLOAT_EQ(m2.at(i, j), 0.0f);
}
TEST_F(UnitTestMat, ToString)
TEST_F(unit_test_mat, ToString)
{
const std::string str = m2.to_string();
EXPECT_FALSE(str.empty());
@@ -131,7 +131,7 @@ TEST_F(UnitTestMat, ToString)
}
// Test assignment operators
TEST_F(UnitTestMat, AssignmentOperator_Copy)
TEST_F(unit_test_mat, AssignmentOperator_Copy)
{
Mat<2, 2> m3;
m3 = m2;
@@ -140,7 +140,7 @@ TEST_F(UnitTestMat, AssignmentOperator_Copy)
EXPECT_FLOAT_EQ(m3.at(0, 0), m2.at(0, 0));
}
TEST_F(UnitTestMat, AssignmentOperator_Move)
TEST_F(unit_test_mat, AssignmentOperator_Move)
{
Mat<2, 2> m3;
m3 = std::move(m2);
@@ -152,7 +152,7 @@ TEST_F(UnitTestMat, AssignmentOperator_Move)
}
// Test static methods
TEST_F(UnitTestMat, StaticMethod_ToScreenMat)
TEST_F(unit_test_mat, StaticMethod_ToScreenMat)
{
Mat<4, 4> screenMat = Mat<4, 4>::to_screen_mat(800.0f, 600.0f);
EXPECT_FLOAT_EQ(screenMat.at(0, 0), 400.0f);
@@ -164,11 +164,11 @@ TEST_F(UnitTestMat, StaticMethod_ToScreenMat)
// Test exception handling in At() method
TEST_F(UnitTestMat, Method_At_OutOfRange)
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
}

View File

@@ -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