Merge pull request #117 from luadebug/mingw

Add MinGW support
This commit is contained in:
2025-12-19 23:21:31 +03:00
committed by GitHub
5 changed files with 427 additions and 15 deletions

View File

@@ -380,7 +380,9 @@ namespace omath
{
const auto det = determinant();
if (det == 0)
constexpr Type det_epsilon = static_cast<Type>(1e-6);
if (std::abs(det) < det_epsilon)
return std::nullopt;
const auto transposed_mat = transposed();

View File

@@ -8,6 +8,7 @@
#include "omath/linear_algebra/triangle.hpp"
#include "omath/linear_algebra/vector3.hpp"
#include "omath/projection/error_codes.hpp"
#include <cmath>
#include <expected>
#include <omath/trigonometry/angle.hpp>
#include <type_traits>
@@ -229,13 +230,17 @@ namespace omath::projection
auto projected = get_view_projection_matrix()
* mat_column_from_vector<float, Mat4X4Type::get_store_ordering()>(world_position);
if (projected.at(3, 0) == 0.0f)
constexpr float w_epsilon = 1e-6f;
const auto w = projected.at(3, 0);
if (w <= w_epsilon) {
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
}
projected /= projected.at(3, 0);
projected /= w;
if (is_ndc_out_of_bounds(projected))
if (is_ndc_out_of_bounds(projected)) {
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
}
return Vector3<float>{projected.at(0, 0), projected.at(1, 0), projected.at(2, 0)};
}
@@ -244,19 +249,33 @@ namespace omath::projection
{
const auto inv_view_proj = get_view_projection_matrix().inverted();
if (!inv_view_proj)
if (!inv_view_proj) {
return std::unexpected(Error::INV_VIEW_PROJ_MAT_DET_EQ_ZERO);
}
auto inverted_projection =
inv_view_proj.value() * mat_column_from_vector<float, Mat4X4Type::get_store_ordering()>(ndc);
if (!inverted_projection.at(3, 0))
constexpr float w_epsilon = 1e-6f;
const auto w = inverted_projection.at(3, 0);
if (std::abs(w) < w_epsilon) {
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
}
inverted_projection /= inverted_projection.at(3, 0);
inverted_projection /= w;
return Vector3<float>{inverted_projection.at(0, 0), inverted_projection.at(1, 0),
inverted_projection.at(2, 0)};
const Vector3<float> world_pos{inverted_projection.at(0, 0), inverted_projection.at(1, 0),
inverted_projection.at(2, 0)};
// Validate that the computed world position is reasonable
constexpr float max_reasonable_component = 1e6f;
if (!std::isfinite(world_pos.x) || !std::isfinite(world_pos.y)
|| !std::isfinite(world_pos.z) || std::abs(world_pos.x) > max_reasonable_component
|| std::abs(world_pos.y) > max_reasonable_component || std::abs(world_pos.z) > max_reasonable_component) {
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
}
return world_pos;
}
template<ScreenStart screen_start = ScreenStart::TOP_LEFT_CORNER>
@@ -290,7 +309,8 @@ namespace omath::projection
template<class Type>
[[nodiscard]] constexpr static bool is_ndc_out_of_bounds(const Type& ndc) noexcept
{
return std::ranges::any_of(ndc.raw_array(), [](const auto& val) { return val < -1 || val > 1; });
constexpr float eps = 1e-5f;
return std::ranges::any_of(ndc.raw_array(), [](const auto& val) { return val < -1.0f - eps || val > 1.0f + eps; });
}
// NDC REPRESENTATION:
@@ -347,7 +367,7 @@ namespace omath::projection
if constexpr (screen_start == ScreenStart::TOP_LEFT_CORNER)
return {screen_pos.x / m_view_port.m_width * 2.f - 1.f, 1.f - screen_pos.y / m_view_port.m_height * 2.f,
screen_pos.z};
else if (screen_start == ScreenStart::BOTTOM_LEFT_CORNER)
else if constexpr (screen_start == ScreenStart::BOTTOM_LEFT_CORNER)
return {screen_pos.x / m_view_port.m_width * 2.f - 1.f,
(screen_pos.y / m_view_port.m_height - 0.5f) * 2.f, screen_pos.z};
else