Compare commits

..

16 Commits

Author SHA1 Message Date
d1d95d2f36 Merge pull request #77 from orange-cpp/feature/formating_improvement
Feature/formating improvement
2025-09-25 22:03:47 +03:00
6409568334 added plane header 2025-09-25 21:59:59 +03:00
83ba339eb5 fix 2025-09-25 21:57:05 +03:00
c49c93d542 decomposed formatter 2025-09-25 21:55:56 +03:00
92dab52d66 improvement 2025-09-25 21:43:33 +03:00
dac3d8e43f improved encoding for formating 2025-09-25 21:06:46 +03:00
fb0b05d7ef imprvoed code style 2025-09-25 19:33:06 +03:00
993212e7ab Merge pull request #76 from orange-cpp/bugfix/projectile_pred
projectile pred look at fix
2025-09-22 02:43:04 +03:00
380a9f0a16 fix 2025-09-22 02:41:12 +03:00
ba7bce5502 ooops 2025-09-22 02:39:50 +03:00
ce40891e37 added targets specification to ci cd build 2025-09-22 02:38:25 +03:00
c4d10f8872 disable benchmark build for CI/CD 2025-09-22 02:34:52 +03:00
2bb0c82c30 added source engine benchmark 2025-09-22 02:29:36 +03:00
a4dcf8dc3b unreal engine fix 2025-09-22 02:12:20 +03:00
17eaddbc8c fix unity 2025-09-22 02:10:33 +03:00
9005c02499 opengl fix 2025-09-22 02:08:58 +03:00
18 changed files with 185 additions and 64 deletions

View File

@@ -35,11 +35,11 @@ jobs:
- name: Configure (cmake --preset)
shell: bash
run: cmake --preset linux-release -DOMATH_BUILD_TESTS=ON
run: cmake --preset linux-release -DOMATH_BUILD_TESTS=ON -DOMATH_BUILD_BENCHMARK=OFF
- name: Build
shell: bash
run: cmake --build cmake-build/build/linux-release --target all
run: cmake --build cmake-build/build/linux-release --target unit_tests omath
- name: Run unit_tests
shell: bash
@@ -68,11 +68,11 @@ jobs:
- name: Configure (cmake --preset)
shell: bash
run: cmake --preset windows-release -DOMATH_BUILD_TESTS=ON
run: cmake --preset windows-release -DOMATH_BUILD_TESTS=ON -DOMATH_BUILD_BENCHMARK=OFF
- name: Build
shell: bash
run: cmake --build cmake-build/build/windows-release --target all
run: cmake --build cmake-build/build/windows-release --target unit_tests omath
- name: Run unit_tests.exe
shell: bash

View File

@@ -39,6 +39,7 @@ else ()
add_library(${PROJECT_NAME} STATIC ${OMATH_SOURCES} ${OMATH_HEADERS})
endif ()
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_VERSION="${PROJECT_VERSION}")
@@ -98,9 +99,8 @@ endif ()
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
if (OMATH_BUILD_TESTS OR OMATH_BUILD_BENCHMARK)
add_subdirectory(extlibs)
endif ()
add_subdirectory(extlibs)
if (OMATH_BUILD_TESTS)
add_subdirectory(tests)

View File

@@ -4,7 +4,6 @@
#include <benchmark/benchmark.h>
#include <omath/omath.hpp>
#include <chrono>
using namespace omath;
@@ -17,7 +16,7 @@ void mat_float_multiplication_col_major(benchmark::State& state)
b.set(7.f);
for (auto _ : state)
for ([[maybe_unused]] const auto _ : state)
std::ignore = a * b;
}
void mat_float_multiplication_row_major(benchmark::State& state)
@@ -29,7 +28,7 @@ void mat_float_multiplication_row_major(benchmark::State& state)
b.set(7.f);
for (auto _ : state)
for ([[maybe_unused]] const auto _ : state)
std::ignore = a * b;
}
@@ -42,7 +41,7 @@ void mat_double_multiplication_row_major(benchmark::State& state)
b.set(7.f);
for (auto _ : state)
for ([[maybe_unused]] const auto _ : state)
std::ignore = a * b;
}
@@ -55,7 +54,7 @@ void mat_double_multiplication_col_major(benchmark::State& state)
b.set(7.f);
for (auto _ : state)
for ([[maybe_unused]] const auto _ : state)
std::ignore = a * b;
}

View File

@@ -1,3 +1,23 @@
//
// Created by Vlad on 9/18/2025.
//
#include <benchmark/benchmark.h>
#include <omath/omath.hpp>
using namespace omath;
using namespace omath::projectile_prediction;
constexpr float simulation_time_step = 1.f / 1000.f;
constexpr float hit_distance_tolerance = 5.f;
void source_engine_projectile_prediction(benchmark::State& state)
{
constexpr Target target{.m_origin = {100, 0, 90}, .m_velocity = {0, 0, 0}, .m_is_airborne = false};
constexpr Projectile projectile = {.m_origin = {3, 2, 1}, .m_launch_speed = 5000, .m_gravity_scale = 0.4};
for ([[maybe_unused]] const auto _: state)
std::ignore = ProjPredEngineLegacy(400, simulation_time_step, 50, hit_distance_tolerance)
.maybe_calculate_aim_point(projectile, target);
}
BENCHMARK(source_engine_projectile_prediction)->Iterations(10'000);

View File

@@ -1,2 +1,9 @@
add_subdirectory(googletest)
add_subdirectory(benchmark)
if (OMATH_BUILD_TESTS)
add_subdirectory(googletest)
endif ()
if (OMATH_BUILD_BENCHMARK)
set(BENCHMARK_ENABLE_TESTING OFF)
add_subdirectory(benchmark)
endif ()

View File

@@ -162,6 +162,7 @@ struct std::formatter<omath::Angle<T, MinV, MaxV, F>, char> // NOLINT(*-dcl58-cp
}
template<class FormatContext>
[[nodiscard]]
auto format(const AngleT& a, FormatContext& ctx) const
{
static_assert(std::is_same_v<typename FormatContext::char_type, char>);
@@ -181,9 +182,30 @@ struct std::formatter<omath::Angle<T, MinV, MaxV, F>, wchar_t> // NOLINT(*-dcl58
}
template<class FormatContext>
[[nodiscard]]
auto format(const AngleT& a, FormatContext& ctx) const
{
static_assert(std::is_same_v<typename FormatContext::char_type, wchar_t>);
return std::format_to(ctx.out(), L"{}deg", a.as_degrees());
}
};
// wchar_t formatter
template<class T, T MinV, T MaxV, omath::AngleFlags F>
struct std::formatter<omath::Angle<T, MinV, MaxV, F>, char8_t> // NOLINT(*-dcl58-cpp)
{
using AngleT = omath::Angle<T, MinV, MaxV, F>;
static constexpr auto parse(std::wformat_parse_context& ctx)
{
return ctx.begin();
}
template<class FormatContext>
[[nodiscard]]
auto format(const AngleT& a, FormatContext& ctx) const
{
static_assert(std::is_same_v<typename FormatContext::char_type, char8_t>);
return std::format_to(ctx.out(), u8"{}deg", a.as_degrees());
}
};

View File

@@ -164,6 +164,26 @@ namespace omath
return {to_im_vec4()};
}
#endif
[[nodiscard]] std::string to_string() const noexcept
{
return std::format("[r:{}, g:{}, b:{}, a:{}]",
static_cast<int>(x * 255.f),
static_cast<int>(y * 255.f),
static_cast<int>(z * 255.f),
static_cast<int>(w * 255.f));
}
[[nodiscard]] std::wstring to_wstring() const noexcept
{
const auto ascii_string = to_string();
return {ascii_string.cbegin(), ascii_string.cend()};
}
// ReSharper disable once CppInconsistentNaming
[[nodiscard]] std::u8string to_u8string() const noexcept
{
const auto ascii_string = to_string();
return {ascii_string.cbegin(), ascii_string.cend()};
}
};
} // namespace omath
template<>
@@ -174,13 +194,19 @@ struct std::formatter<omath::Color> // NOLINT(*-dcl58-cpp)
{
return ctx.begin();
}
template<class FormatContext>
[[nodiscard]]
static auto format(const omath::Color& col, std::format_context& ctx)
static auto format(const omath::Color& col, FormatContext& ctx)
{
return std::format_to(ctx.out(), "[r:{}, g:{}, b:{}, a:{}]",
static_cast<int>(col.x * 255.f),
static_cast<int>(col.y * 255.f),
static_cast<int>(col.z * 255.f),
static_cast<int>(col.w * 255.f));
if constexpr (std::is_same_v<typename FormatContext::char_type, char>)
return std::format_to(ctx.out(), "{}", col.to_string());
if constexpr (std::is_same_v<typename FormatContext::char_type, wchar_t>)
return std::format_to(ctx.out(), L"{}", col.to_wstring());
if constexpr (std::is_same_v<typename FormatContext::char_type, char8_t>)
return std::format_to(ctx.out(), u8"{}", col.to_u8string());
return std::unreachable();
}
};

View File

@@ -62,17 +62,15 @@ namespace omath::opengl_engine
[[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.y / distance));
const auto direction = (view_to - origin).normalized();
return angles::radians_to_degrees(std::asin(direction.y));
}
[[nodiscard]]
static float calc_direct_yaw_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
{
const auto delta = view_to - origin;
const auto direction = (view_to - origin).normalized();
return angles::radians_to_degrees(std::atan2(delta.z, delta.x));
return angles::radians_to_degrees(-std::atan2(direction.x, -direction.z));
};
};
} // namespace omath::opengl_engine

View File

@@ -62,17 +62,15 @@ namespace omath::unity_engine
[[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.y / distance));
const auto direction = (view_to - origin).normalized();
return angles::radians_to_degrees(std::asin(direction.y));
}
[[nodiscard]]
static float calc_direct_yaw_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
{
const auto delta = view_to - origin;
const auto direction = (view_to - origin).normalized();
return angles::radians_to_degrees(std::atan2(delta.z, delta.x));
return angles::radians_to_degrees(std::atan2(direction.x, direction.z));
};
};
} // namespace omath::unity_engine

View File

@@ -62,17 +62,16 @@ namespace omath::unreal_engine
[[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;
const auto direction = (view_to - origin).normalized();
return angles::radians_to_degrees(std::asin(delta.z / distance));
return angles::radians_to_degrees(std::asin(direction.z));
}
[[nodiscard]]
static float calc_direct_yaw_angle(const Vector3<float>& origin, const Vector3<float>& view_to) noexcept
{
const auto delta = view_to - origin;
const auto direction = (view_to - origin).normalized();
return angles::radians_to_degrees(std::atan2(delta.y, delta.x));
return angles::radians_to_degrees(std::atan2(direction.y, direction.x));
};
};
} // namespace omath::unreal_engine

View File

@@ -328,6 +328,21 @@ namespace omath
return oss.str();
}
[[nodiscard]]
std::wstring to_wstring() const noexcept
{
const auto ascii_string = to_string();
return {ascii_string.cbegin(), ascii_string.cend()};
}
[[nodiscard]]
// ReSharper disable once CppInconsistentNaming
std::u8string to_u8string() const noexcept
{
const auto ascii_string = to_string();
return {ascii_string.cbegin(), ascii_string.cend()};
}
[[nodiscard]]
bool operator==(const Mat& mat) const
{
@@ -425,7 +440,7 @@ namespace omath
for (std::size_t k = 0; k < Columns; ++k)
{
const float bkj = reinterpret_cast<const float*>(other_mat_data)[k + j * Columns];
__m256 bkjv = _mm256_set1_ps(bkj);
const __m256 bkj_vec = _mm256_set1_ps(bkj);
const auto* a_col_k = reinterpret_cast<const float*>(this_mat_data + k * Rows);
@@ -433,8 +448,8 @@ namespace omath
for (; i + vector_size <= Rows; i += vector_size)
{
__m256 cvec = _mm256_loadu_ps(c_col + i);
__m256 avec = _mm256_loadu_ps(a_col_k + i);
cvec = _mm256_fmadd_ps(avec, bkjv, cvec);
const __m256 a_vec = _mm256_loadu_ps(a_col_k + i);
cvec = _mm256_fmadd_ps(a_vec, bkj_vec, cvec);
_mm256_storeu_ps(c_col + i, cvec);
}
for (; i < Rows; ++i)
@@ -452,7 +467,7 @@ namespace omath
for (std::size_t k = 0; k < Columns; ++k)
{
const double bkj = reinterpret_cast<const double*>(other_mat_data)[k + j * Columns];
__m256d bkjv = _mm256_set1_pd(bkj);
const __m256d bkj_vec = _mm256_set1_pd(bkj);
const auto* a_col_k = reinterpret_cast<const double*>(this_mat_data + k * Rows);
@@ -460,8 +475,8 @@ namespace omath
for (; i + vector_size <= Rows; i += vector_size)
{
__m256d cvec = _mm256_loadu_pd(c_col + i);
__m256d avec = _mm256_loadu_pd(a_col_k + i);
cvec = _mm256_fmadd_pd(avec, bkjv, cvec);
const __m256d a_vec = _mm256_loadu_pd(a_col_k + i);
cvec = _mm256_fmadd_pd(a_vec, bkj_vec, cvec);
_mm256_storeu_pd(c_col + i, cvec);
}
for (; i < Rows; ++i)
@@ -495,15 +510,15 @@ namespace omath
for (std::size_t k = 0; k < Columns; ++k)
{
const auto aik = static_cast<float>(this_mat_data[i * Columns + k]);
__m256 aikv = _mm256_set1_ps(aik);
const __m256 aik_vec = _mm256_set1_ps(aik);
const auto* b_row = reinterpret_cast<const float*>(other_mat_data + k * OtherColumns);
std::size_t j = 0;
for (; j + vector_size <= OtherColumns; j += vector_size)
{
__m256 cvec = _mm256_loadu_ps(c_row + j);
__m256 bvec = _mm256_loadu_ps(b_row + j);
cvec = _mm256_fmadd_ps(bvec, aikv, cvec);
const __m256 b_vec = _mm256_loadu_ps(b_row + j);
cvec = _mm256_fmadd_ps(b_vec, aik_vec, cvec);
_mm256_storeu_ps(c_row + j, cvec);
}
@@ -522,15 +537,15 @@ namespace omath
for (std::size_t k = 0; k < Columns; ++k)
{
const auto aik = static_cast<double>(this_mat_data[i * Columns + k]);
__m256d aikv = _mm256_set1_pd(aik);
const __m256d aik_vec = _mm256_set1_pd(aik);
const auto* b_row = reinterpret_cast<const double*>(other_mat_data + k * OtherColumns);
std::size_t j = 0;
for (; j + vector_size <= OtherColumns; j += vector_size)
{
__m256d cvec = _mm256_loadu_pd(c_row + j);
__m256d bvec = _mm256_loadu_pd(b_row + j);
cvec = _mm256_fmadd_pd(bvec, aikv, cvec);
const __m256d b_vec = _mm256_loadu_pd(b_row + j);
cvec = _mm256_fmadd_pd(b_vec, aik_vec, cvec);
_mm256_storeu_pd(c_row + j, cvec);
}
@@ -706,9 +721,18 @@ struct std::formatter<omath::Mat<Rows, Columns, Type, StoreType>> // NOLINT(*-dc
{
return ctx.begin();
}
template<class FormatContext>
[[nodiscard]]
static auto format(const MatType& mat, std::format_context& ctx)
static auto format(const MatType& mat, FormatContext& ctx)
{
return std::format_to(ctx.out(), "{}", mat.to_string());
if constexpr (std::is_same_v<typename FormatContext::char_type, char>)
return std::format_to(ctx.out(), "{}", mat.to_string());
if constexpr (std::is_same_v<typename FormatContext::char_type, wchar_t>)
return std::format_to(ctx.out(), L"{}", mat.to_wstring());
if constexpr (std::is_same_v<typename FormatContext::char_type, char8_t>)
return std::format_to(ctx.out(), u8"{}", mat.to_u8string());
}
};

View File

@@ -242,9 +242,18 @@ struct std::formatter<omath::Vector2<Type>> // NOLINT(*-dcl58-cpp)
{
return ctx.begin();
}
template<class FormatContext>
[[nodiscard]]
static auto format(const omath::Vector2<Type>& vec, std::format_context& ctx)
static auto format(const omath::Vector2<Type>& vec, FormatContext& ctx)
{
return std::format_to(ctx.out(), "[{}, {}]", vec.x, vec.y);
if constexpr (std::is_same_v<typename FormatContext::char_type, char>)
return std::format_to(ctx.out(), "[{}, {}]", vec.x, vec.y);
if constexpr (std::is_same_v<typename FormatContext::char_type, wchar_t>)
return std::format_to(ctx.out(), L"[{}, {}]", vec.x, vec.y);
if constexpr (std::is_same_v<typename FormatContext::char_type, char8_t>)
return std::format_to(ctx.out(), u8"[{}, {}]", vec.x, vec.y);
}
};

View File

@@ -303,9 +303,18 @@ struct std::formatter<omath::Vector3<Type>> // NOLINT(*-dcl58-cpp)
{
return ctx.begin();
}
template<class FormatContext>
[[nodiscard]]
static auto format(const omath::Vector3<Type>& vec, std::format_context& ctx)
static auto format(const omath::Vector3<Type>& vec, FormatContext& ctx)
{
return std::format_to(ctx.out(), "[{}, {}, {}]", vec.x, vec.y, vec.z);
if constexpr (std::is_same_v<typename FormatContext::char_type, char>)
return std::format_to(ctx.out(), "[{}, {}, {}]", vec.x, vec.y, vec.z);
if constexpr (std::is_same_v<typename FormatContext::char_type, wchar_t>)
return std::format_to(ctx.out(), L"[{}, {}, {}]", vec.x, vec.y, vec.z);
if constexpr (std::is_same_v<typename FormatContext::char_type, char8_t>)
return std::format_to(ctx.out(), u8"[{}, {}, {}]", vec.x, vec.y, vec.z);
}
};

View File

@@ -210,9 +210,17 @@ struct std::formatter<omath::Vector4<Type>> // NOLINT(*-dcl58-cpp)
{
return ctx.begin();
}
template<class FormatContext>
[[nodiscard]]
static auto format(const omath::Vector4<Type>& vec, std::format_context& ctx)
static auto format(const omath::Vector4<Type>& vec, FormatContext& ctx)
{
return std::format_to(ctx.out(), "[{}, {}, {}, {}]", vec.x, vec.y, vec.z, vec.w);
if constexpr (std::is_same_v<typename FormatContext::char_type, char>)
return std::format_to(ctx.out(), "[{}, {}, {}, {}]", vec.x, vec.y, vec.z, vec.w);
if constexpr (std::is_same_v<typename FormatContext::char_type, wchar_t>)
return std::format_to(ctx.out(), L"[{}, {}, {}, {}]", vec.x, vec.y, vec.z, vec.w);
if constexpr (std::is_same_v<typename FormatContext::char_type, char8_t>)
return std::format_to(ctx.out(), u8"[{}, {}, {}, {}]", vec.x, vec.y, vec.z, vec.w);
}
};

View File

@@ -26,6 +26,7 @@
// 3D primitives
#include "omath/3d_primitives/box.hpp"
#include "omath/3d_primitives/plane.hpp"
// Collision detection
#include "omath/collision/line_tracer.hpp"

View File

@@ -4,8 +4,8 @@
#pragma once
#include "omath/linear_algebra/vector3.hpp"
#include "omath/engines/source_engine/traits/pred_engine_trait.hpp"
#include "omath/linear_algebra/vector3.hpp"
#include "omath/projectile_prediction/proj_pred_engine.hpp"
#include "omath/projectile_prediction/projectile.hpp"
#include "omath/projectile_prediction/target.hpp"
@@ -20,7 +20,9 @@ namespace omath::projectile_prediction
Vector3<float> v3, // by-value for calc_viewpoint_from_angles
float pitch, float yaw, float time, float gravity, std::optional<float> maybe_pitch) {
// Presence + return types
{ T::predict_projectile_position(projectile, pitch, yaw, time, gravity) } -> std::same_as<Vector3<float>>;
{
T::predict_projectile_position(projectile, pitch, yaw, time, gravity)
} -> std::same_as<Vector3<float>>;
{ T::predict_target_position(target, time, gravity) } -> std::same_as<Vector3<float>>;
{ T::calc_vector_2d_distance(vec_a) } -> std::same_as<float>;
{ T::get_vector_height_coordinate(vec_b) } -> std::same_as<float>;

View File

@@ -8,11 +8,10 @@ namespace omath::unity_engine
ViewAngles CameraTrait::calc_look_at_angle(const Vector3<float>& cam_origin, const Vector3<float>& look_at) noexcept
{
const auto distance = cam_origin.distance_to(look_at);
const auto delta = look_at - cam_origin;
const auto direction = (look_at - cam_origin).normalized();
return {PitchAngle::from_radians(-std::asin(delta.y / distance)),
YawAngle::from_radians(std::atan2(delta.x, delta.z)), RollAngle::from_radians(0.f)};
return {PitchAngle::from_radians(-std::asin(direction.y)),
YawAngle::from_radians(std::atan2(direction.x, direction.z)), RollAngle::from_radians(0.f)};
}
Mat4X4 CameraTrait::calc_view_matrix(const ViewAngles& angles, const Vector3<float>& cam_origin) noexcept
{

View File

@@ -7,7 +7,7 @@ include(GoogleTest)
file(GLOB_RECURSE UNIT_TESTS_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
add_executable(${PROJECT_NAME} ${UNIT_TESTS_SOURCES})
set_target_properties(unit_tests PROPERTIES
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}"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}"