mirror of
https://github.com/orange-cpp/omath.git
synced 2026-08-08 22:12:05 +00:00
Compare commits
4 Commits
6a5771e57d
...
306096af14
| Author | SHA1 | Date | |
|---|---|---|---|
| 306096af14 | |||
| 502cfb431c | |||
| 8ccc9459d4 | |||
| 2ee485297f |
@@ -873,7 +873,7 @@ namespace omath
|
|||||||
} // namespace omath
|
} // namespace omath
|
||||||
|
|
||||||
template<size_t Rows, size_t Columns, class Type, omath::MatStoreType StoreType>
|
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>;
|
using MatType = omath::Mat<Rows, Columns, Type, StoreType>;
|
||||||
[[nodiscard("You must use parse iterator")]]
|
[[nodiscard("You must use parse iterator")]]
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ namespace omath
|
|||||||
} // namespace omath
|
} // namespace omath
|
||||||
|
|
||||||
template<class Type>
|
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")]]
|
[[nodiscard("You must use hash value")]]
|
||||||
std::size_t operator()(const omath::Vector2<Type>& vec) const noexcept
|
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>
|
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")]]
|
[[nodiscard("You must use parse iterator")]]
|
||||||
static constexpr auto parse(std::format_parse_context& ctx) noexcept
|
static constexpr auto parse(std::format_parse_context& ctx) noexcept
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ namespace omath
|
|||||||
} // namespace omath
|
} // namespace omath
|
||||||
|
|
||||||
template<class Type>
|
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
|
// NOTE: Cannot be constexpr because of MSVC
|
||||||
[[nodiscard("You must use hash value")]]
|
[[nodiscard("You must use hash value")]]
|
||||||
@@ -337,7 +337,7 @@ struct std::hash<omath::Vector3<Type>> // NOLINT(*-dcl58-cpp)
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<class Type>
|
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")]]
|
[[nodiscard("You must use parse iterator")]]
|
||||||
static constexpr auto parse(std::format_parse_context& ctx) noexcept
|
static constexpr auto parse(std::format_parse_context& ctx) noexcept
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ namespace omath
|
|||||||
} // namespace omath
|
} // namespace omath
|
||||||
|
|
||||||
template<class Type>
|
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")]]
|
[[nodiscard("You must use hash value")]]
|
||||||
std::size_t operator()(const omath::Vector4<Type>& vec) const noexcept
|
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>
|
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")]]
|
[[nodiscard("You must use parse iterator")]]
|
||||||
static constexpr auto parse(std::format_parse_context& ctx) noexcept
|
static constexpr auto parse(std::format_parse_context& ctx) noexcept
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ namespace omath::pathfinding
|
|||||||
class Astar final
|
class Astar final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
[[nodiscard]]
|
[[nodiscard("You forgot to use returned path")]]
|
||||||
static std::vector<Vector3<float>> find_path(const Vector3<float>& start, const Vector3<float>& end,
|
static std::vector<Vector3<float>> find_path(const Vector3<float>& start, const Vector3<float>& end,
|
||||||
const NavigationMesh& nav_mesh) noexcept;
|
const NavigationMesh& nav_mesh) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]]
|
[[nodiscard("You forgot to use reconstructed path")]]
|
||||||
static std::vector<Vector3<float>>
|
static std::vector<Vector3<float>>
|
||||||
reconstruct_final_path(const std::unordered_map<Vector3<float>, PathNode>& closed_list,
|
reconstruct_final_path(const std::unordered_map<Vector3<float>, PathNode>& closed_list,
|
||||||
const Vector3<float>& current) noexcept;
|
const Vector3<float>& current) noexcept;
|
||||||
|
|||||||
@@ -466,6 +466,23 @@ namespace omath::projection
|
|||||||
return false;
|
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>
|
[[nodiscard("You must use view port position")]] constexpr std::expected<Vector3<NumericType>, Error>
|
||||||
world_to_view_port(const Vector3<NumericType>& world_position,
|
world_to_view_port(const Vector3<NumericType>& world_position,
|
||||||
const ViewPortClipping& clipping = ViewPortClipping::AUTO) const noexcept
|
const ViewPortClipping& clipping = ViewPortClipping::AUTO) const noexcept
|
||||||
|
|||||||
@@ -154,10 +154,11 @@ namespace omath
|
|||||||
} // namespace omath
|
} // namespace omath
|
||||||
|
|
||||||
template<class T, T MinV, T MaxV, omath::AngleFlags F>
|
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>;
|
using AngleT = omath::Angle<T, MinV, MaxV, F>;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
static constexpr auto parse(std::format_parse_context& ctx)
|
static constexpr auto parse(std::format_parse_context& ctx)
|
||||||
{
|
{
|
||||||
return ctx.begin();
|
return ctx.begin();
|
||||||
@@ -174,10 +175,11 @@ struct std::formatter<omath::Angle<T, MinV, MaxV, F>, char> // NOLINT(*-dcl58-cp
|
|||||||
|
|
||||||
// wchar_t formatter
|
// wchar_t formatter
|
||||||
template<class T, T MinV, T MaxV, omath::AngleFlags F>
|
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>;
|
using AngleT = omath::Angle<T, MinV, MaxV, F>;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
static constexpr auto parse(std::wformat_parse_context& ctx)
|
static constexpr auto parse(std::wformat_parse_context& ctx)
|
||||||
{
|
{
|
||||||
return ctx.begin();
|
return ctx.begin();
|
||||||
@@ -194,10 +196,11 @@ struct std::formatter<omath::Angle<T, MinV, MaxV, F>, wchar_t> // NOLINT(*-dcl58
|
|||||||
|
|
||||||
// wchar_t formatter
|
// wchar_t formatter
|
||||||
template<class T, T MinV, T MaxV, omath::AngleFlags F>
|
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>;
|
using AngleT = omath::Angle<T, MinV, MaxV, F>;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
static constexpr auto parse(std::wformat_parse_context& ctx)
|
static constexpr auto parse(std::wformat_parse_context& ctx)
|
||||||
{
|
{
|
||||||
return ctx.begin();
|
return ctx.begin();
|
||||||
|
|||||||
@@ -580,6 +580,48 @@ TEST(UnitTestProjection, AabbUnityEngineStraddlesNearNotCulled)
|
|||||||
EXPECT_FALSE(cam.is_aabb_culled_by_frustum(aabb));
|
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)
|
TEST(UnitTestProjection, CalcViewAnglesFromViewMatrix_LookingForward)
|
||||||
{
|
{
|
||||||
constexpr float k_eps = 1e-4f;
|
constexpr float k_eps = 1e-4f;
|
||||||
|
|||||||
Reference in New Issue
Block a user