Compare commits

...

4 Commits

Author SHA1 Message Date
orange 306096af14 fixed stuffed 2026-06-22 06:31:56 +03:00
orange 502cfb431c added final 2026-06-22 06:21:54 +03:00
orange 8ccc9459d4 added additional method 2026-06-22 06:07:56 +03:00
orange 2ee485297f added more nodiscard messages 2026-06-22 03:48:44 +03:00
9 changed files with 75 additions and 13 deletions
+1 -1
View File
@@ -1 +1 @@
5.3.0
5.4.0
+1 -1
View File
@@ -873,7 +873,7 @@ namespace omath
} // namespace omath
template<size_t Rows, size_t Columns, class Type, omath::MatStoreType StoreType>
struct std::formatter<omath::Mat<Rows, Columns, Type, StoreType>> // NOLINT(*-dcl58-cpp)
struct std::formatter<omath::Mat<Rows, Columns, Type, StoreType>> final // NOLINT(*-dcl58-cpp)
{
using MatType = omath::Mat<Rows, Columns, Type, StoreType>;
[[nodiscard("You must use parse iterator")]]
+2 -2
View File
@@ -266,7 +266,7 @@ namespace omath
} // namespace omath
template<class Type>
struct std::hash<omath::Vector2<Type>> // NOLINT(*-dcl58-cpp)
struct std::hash<omath::Vector2<Type>> final // NOLINT(*-dcl58-cpp)
{
[[nodiscard("You must use hash value")]]
std::size_t operator()(const omath::Vector2<Type>& vec) const noexcept
@@ -282,7 +282,7 @@ struct std::hash<omath::Vector2<Type>> // NOLINT(*-dcl58-cpp)
};
template<class Type>
struct std::formatter<omath::Vector2<Type>> // NOLINT(*-dcl58-cpp)
struct std::formatter<omath::Vector2<Type>> final // NOLINT(*-dcl58-cpp)
{
[[nodiscard("You must use parse iterator")]]
static constexpr auto parse(std::format_parse_context& ctx) noexcept
+2 -2
View File
@@ -319,7 +319,7 @@ namespace omath
} // namespace omath
template<class Type>
struct std::hash<omath::Vector3<Type>> // NOLINT(*-dcl58-cpp)
struct std::hash<omath::Vector3<Type>> final // NOLINT(*-dcl58-cpp)
{
// NOTE: Cannot be constexpr because of MSVC
[[nodiscard("You must use hash value")]]
@@ -337,7 +337,7 @@ struct std::hash<omath::Vector3<Type>> // NOLINT(*-dcl58-cpp)
};
template<class Type>
struct std::formatter<omath::Vector3<Type>> // NOLINT(*-dcl58-cpp)
struct std::formatter<omath::Vector3<Type>> final // NOLINT(*-dcl58-cpp)
{
[[nodiscard("You must use parse iterator")]]
static constexpr auto parse(std::format_parse_context& ctx) noexcept
+2 -2
View File
@@ -226,7 +226,7 @@ namespace omath
} // namespace omath
template<class Type>
struct std::hash<omath::Vector4<Type>> // NOLINT(*-dcl58-cpp)
struct std::hash<omath::Vector4<Type>> final // NOLINT(*-dcl58-cpp)
{
[[nodiscard("You must use hash value")]]
std::size_t operator()(const omath::Vector4<Type>& vec) const noexcept
@@ -242,7 +242,7 @@ struct std::hash<omath::Vector4<Type>> // NOLINT(*-dcl58-cpp)
}
};
template<class Type>
struct std::formatter<omath::Vector4<Type>> // NOLINT(*-dcl58-cpp)
struct std::formatter<omath::Vector4<Type>> final // NOLINT(*-dcl58-cpp)
{
[[nodiscard("You must use parse iterator")]]
static constexpr auto parse(std::format_parse_context& ctx) noexcept
+2 -2
View File
@@ -13,12 +13,12 @@ namespace omath::pathfinding
class Astar final
{
public:
[[nodiscard]]
[[nodiscard("You forgot to use returned path")]]
static std::vector<Vector3<float>> find_path(const Vector3<float>& start, const Vector3<float>& end,
const NavigationMesh& nav_mesh) noexcept;
private:
[[nodiscard]]
[[nodiscard("You forgot to use reconstructed path")]]
static std::vector<Vector3<float>>
reconstruct_final_path(const std::unordered_map<Vector3<float>, PathNode>& closed_list,
const Vector3<float>& current) noexcept;
+17
View File
@@ -466,6 +466,23 @@ namespace omath::projection
return false;
}
[[nodiscard("You must view camera space coordinates")]]
constexpr Vector3<NumericType> world_to_view_coordinates(const Vector3<NumericType>& world_coordinates) const noexcept
{
if consteval
{
const auto view_coordinates =
calc_view_matrix()
* mat_column_from_vector<NumericType, Mat4X4Type::get_store_ordering()>(world_coordinates);
return {view_coordinates.at(0, 0), view_coordinates.at(1, 0), view_coordinates.at(2, 0)};
}
const auto view_coordinates =
get_view_matrix()
* mat_column_from_vector<NumericType, Mat4X4Type::get_store_ordering()>(world_coordinates);
return {view_coordinates.at(0, 0), view_coordinates.at(1, 0), view_coordinates.at(2, 0)};
}
[[nodiscard("You must use view port position")]] constexpr std::expected<Vector3<NumericType>, Error>
world_to_view_port(const Vector3<NumericType>& world_position,
const ViewPortClipping& clipping = ViewPortClipping::AUTO) const noexcept
+6 -3
View File
@@ -154,10 +154,11 @@ namespace omath
} // namespace omath
template<class T, T MinV, T MaxV, omath::AngleFlags F>
struct std::formatter<omath::Angle<T, MinV, MaxV, F>, char> // NOLINT(*-dcl58-cpp)
struct std::formatter<omath::Angle<T, MinV, MaxV, F>, char> final // NOLINT(*-dcl58-cpp)
{
using AngleT = omath::Angle<T, MinV, MaxV, F>;
[[nodiscard]]
static constexpr auto parse(std::format_parse_context& ctx)
{
return ctx.begin();
@@ -174,10 +175,11 @@ struct std::formatter<omath::Angle<T, MinV, MaxV, F>, char> // NOLINT(*-dcl58-cp
// wchar_t formatter
template<class T, T MinV, T MaxV, omath::AngleFlags F>
struct std::formatter<omath::Angle<T, MinV, MaxV, F>, wchar_t> // NOLINT(*-dcl58-cpp)
struct std::formatter<omath::Angle<T, MinV, MaxV, F>, wchar_t> final // NOLINT(*-dcl58-cpp)
{
using AngleT = omath::Angle<T, MinV, MaxV, F>;
[[nodiscard]]
static constexpr auto parse(std::wformat_parse_context& ctx)
{
return ctx.begin();
@@ -194,10 +196,11 @@ struct std::formatter<omath::Angle<T, MinV, MaxV, F>, wchar_t> // NOLINT(*-dcl58
// 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)
struct std::formatter<omath::Angle<T, MinV, MaxV, F>, char8_t> final // NOLINT(*-dcl58-cpp)
{
using AngleT = omath::Angle<T, MinV, MaxV, F>;
[[nodiscard]]
static constexpr auto parse(std::wformat_parse_context& ctx)
{
return ctx.begin();
+42
View File
@@ -580,6 +580,48 @@ TEST(UnitTestProjection, AabbUnityEngineStraddlesNearNotCulled)
EXPECT_FALSE(cam.is_aabb_culled_by_frustum(aabb));
}
TEST(UnitTestProjection, WorldToViewCoordinates_TranslatedSourceCamera)
{
constexpr float k_eps = 1e-4f;
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
auto cam = omath::source_engine::Camera({10.f, 20.f, 30.f}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
const auto view_coordinates = cam.world_to_view_coordinates({15.f, 12.f, 37.f});
EXPECT_NEAR(view_coordinates.x, 8.f, k_eps);
EXPECT_NEAR(view_coordinates.y, 7.f, k_eps);
EXPECT_NEAR(view_coordinates.z, 5.f, k_eps);
}
TEST(UnitTestProjection, WorldToViewCoordinates_RotatedSourceCamera)
{
constexpr float k_eps = 1e-4f;
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
const omath::source_engine::ViewAngles angles{omath::source_engine::PitchAngle::from_degrees(0.f),
omath::source_engine::YawAngle::from_degrees(90.f),
omath::source_engine::RollAngle::from_degrees(0.f)};
auto cam = omath::source_engine::Camera({10.f, 20.f, 30.f}, angles, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
const auto view_coordinates = cam.world_to_view_coordinates({14.f, 26.f, 38.f});
EXPECT_NEAR(view_coordinates.x, 4.f, k_eps);
EXPECT_NEAR(view_coordinates.y, 8.f, k_eps);
EXPECT_NEAR(view_coordinates.z, 6.f, k_eps);
}
TEST(UnitTestProjection, WorldToViewCoordinates_ColumnMajorOpenGlCamera)
{
constexpr float k_eps = 1e-4f;
constexpr auto fov = omath::projection::FieldOfView::from_degrees(90.f);
auto cam = omath::opengl_engine::Camera({10.f, 20.f, 30.f}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
const auto view_coordinates = cam.world_to_view_coordinates({14.f, 26.f, 22.f});
EXPECT_NEAR(view_coordinates.x, 4.f, k_eps);
EXPECT_NEAR(view_coordinates.y, 6.f, k_eps);
EXPECT_NEAR(view_coordinates.z, -8.f, k_eps);
}
TEST(UnitTestProjection, CalcViewAnglesFromViewMatrix_LookingForward)
{
constexpr float k_eps = 1e-4f;