mirror of
https://github.com/orange-cpp/omath.git
synced 2026-04-18 13:43:26 +00:00
fixed unreal bug, improved interface
This commit is contained in:
@@ -9,5 +9,5 @@
|
||||
|
||||
namespace omath::cry_engine
|
||||
{
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, false, NDCDepthRange::ZERO_TO_ONE>;
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, NDCDepthRange::ZERO_TO_ONE>;
|
||||
} // namespace omath::cry_engine
|
||||
@@ -9,5 +9,5 @@
|
||||
|
||||
namespace omath::frostbite_engine
|
||||
{
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, false, NDCDepthRange::ZERO_TO_ONE>;
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, NDCDepthRange::ZERO_TO_ONE>;
|
||||
} // namespace omath::unity_engine
|
||||
@@ -9,5 +9,5 @@
|
||||
|
||||
namespace omath::iw_engine
|
||||
{
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, false, NDCDepthRange::ZERO_TO_ONE>;
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, NDCDepthRange::ZERO_TO_ONE>;
|
||||
} // namespace omath::iw_engine
|
||||
@@ -8,5 +8,5 @@
|
||||
|
||||
namespace omath::opengl_engine
|
||||
{
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, true, NDCDepthRange::NEGATIVE_ONE_TO_ONE>;
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, NDCDepthRange::NEGATIVE_ONE_TO_ONE, {.inverted_forward = true}>;
|
||||
} // namespace omath::opengl_engine
|
||||
@@ -7,5 +7,5 @@
|
||||
#include "traits/camera_trait.hpp"
|
||||
namespace omath::source_engine
|
||||
{
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, false, NDCDepthRange::ZERO_TO_ONE>;
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, NDCDepthRange::ZERO_TO_ONE>;
|
||||
} // namespace omath::source_engine
|
||||
@@ -9,5 +9,5 @@
|
||||
|
||||
namespace omath::unity_engine
|
||||
{
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, true, NDCDepthRange::ZERO_TO_ONE>;
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, NDCDepthRange::ZERO_TO_ONE, {.inverted_forward = true}>;
|
||||
} // namespace omath::unity_engine
|
||||
@@ -9,5 +9,5 @@
|
||||
|
||||
namespace omath::unreal_engine
|
||||
{
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, false, NDCDepthRange::ZERO_TO_ONE>;
|
||||
using Camera = projection::Camera<Mat4X4, ViewAngles, CameraTrait, NDCDepthRange::ZERO_TO_ONE, {.inverted_right = true}>;
|
||||
} // namespace omath::unreal_engine
|
||||
@@ -42,6 +42,12 @@ namespace omath::projection
|
||||
AUTO,
|
||||
MANUAL,
|
||||
};
|
||||
struct CameraAxes
|
||||
{
|
||||
bool inverted_forward = false;
|
||||
bool inverted_right = false;
|
||||
};
|
||||
|
||||
template<class T, class MatType, class ViewAnglesType>
|
||||
concept CameraEngineConcept =
|
||||
requires(const Vector3<float>& cam_origin, const Vector3<float>& look_at, const ViewAnglesType& angles,
|
||||
@@ -58,8 +64,9 @@ namespace omath::projection
|
||||
requires noexcept(T::calc_projection_matrix(fov, viewport, znear, zfar, ndc_depth_range));
|
||||
};
|
||||
|
||||
template<class Mat4X4Type, class ViewAnglesType, class TraitClass, bool inverted_z = false,
|
||||
NDCDepthRange depth_range = NDCDepthRange::NEGATIVE_ONE_TO_ONE>
|
||||
template<class Mat4X4Type, class ViewAnglesType, class TraitClass,
|
||||
NDCDepthRange depth_range = NDCDepthRange::NEGATIVE_ONE_TO_ONE,
|
||||
CameraAxes axes = {}>
|
||||
requires CameraEngineConcept<TraitClass, Mat4X4Type, ViewAnglesType>
|
||||
class Camera final
|
||||
{
|
||||
@@ -87,7 +94,7 @@ namespace omath::projection
|
||||
static ViewAnglesType calc_view_angles_from_view_matrix(const Mat4X4Type& view_matrix) noexcept
|
||||
{
|
||||
Vector3<float> forward_vector = {view_matrix[2, 0], view_matrix[2, 1], view_matrix[2, 2]};
|
||||
if constexpr (inverted_z)
|
||||
if constexpr (axes.inverted_forward)
|
||||
forward_vector = -forward_vector;
|
||||
return TraitClass::calc_look_at_angle({}, forward_vector);
|
||||
}
|
||||
@@ -121,7 +128,7 @@ namespace omath::projection
|
||||
{
|
||||
const auto& view_matrix = get_view_matrix();
|
||||
|
||||
if constexpr (inverted_z)
|
||||
if constexpr (axes.inverted_forward)
|
||||
return -Vector3<float>{view_matrix[2, 0], view_matrix[2, 1], view_matrix[2, 2]};
|
||||
return {view_matrix[2, 0], view_matrix[2, 1], view_matrix[2, 2]};
|
||||
}
|
||||
@@ -130,6 +137,8 @@ namespace omath::projection
|
||||
Vector3<float> get_right() const noexcept
|
||||
{
|
||||
const auto& view_matrix = get_view_matrix();
|
||||
if constexpr (axes.inverted_right)
|
||||
return -Vector3<float>{view_matrix[0, 0], view_matrix[0, 1], view_matrix[0, 2]};
|
||||
return {view_matrix[0, 0], view_matrix[0, 1], view_matrix[0, 2]};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,12 @@
|
||||
#include <complex>
|
||||
#include <gtest/gtest.h>
|
||||
#include <omath/3d_primitives/aabb.hpp>
|
||||
#include <omath/engines/cry_engine/camera.hpp>
|
||||
#include <omath/engines/frostbite_engine/camera.hpp>
|
||||
#include <omath/engines/iw_engine/camera.hpp>
|
||||
#include <omath/engines/opengl_engine/camera.hpp>
|
||||
#include <omath/engines/source_engine/camera.hpp>
|
||||
#include <omath/engines/unreal_engine/camera.hpp>
|
||||
#include <omath/projection/camera.hpp>
|
||||
#include <print>
|
||||
#include <random>
|
||||
@@ -781,4 +785,159 @@ TEST(UnitTestProjection, Unity_CalcOriginFromViewMatrix_WithRotation)
|
||||
EXPECT_NEAR(origin.x, 300.f, k_eps);
|
||||
EXPECT_NEAR(origin.y, -100.f, k_eps);
|
||||
EXPECT_NEAR(origin.z, 75.f, k_eps);
|
||||
}
|
||||
}
|
||||
// ---- Camera basis vectors at zero angles ----
|
||||
|
||||
TEST(UnitTestProjection, SourceEngine_ZeroAngles_BasisVectors)
|
||||
{
|
||||
constexpr float k_eps = 1e-5f;
|
||||
const auto cam = omath::source_engine::Camera({}, {}, {1920.f, 1080.f},
|
||||
omath::projection::FieldOfView::from_degrees(90.f), 0.01f, 1000.f);
|
||||
const auto fwd = cam.get_forward();
|
||||
const auto right = cam.get_right();
|
||||
const auto up = cam.get_up();
|
||||
|
||||
EXPECT_NEAR(fwd.x, omath::source_engine::k_abs_forward.x, k_eps);
|
||||
EXPECT_NEAR(fwd.y, omath::source_engine::k_abs_forward.y, k_eps);
|
||||
EXPECT_NEAR(fwd.z, omath::source_engine::k_abs_forward.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(right.x, omath::source_engine::k_abs_right.x, k_eps);
|
||||
EXPECT_NEAR(right.y, omath::source_engine::k_abs_right.y, k_eps);
|
||||
EXPECT_NEAR(right.z, omath::source_engine::k_abs_right.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(up.x, omath::source_engine::k_abs_up.x, k_eps);
|
||||
EXPECT_NEAR(up.y, omath::source_engine::k_abs_up.y, k_eps);
|
||||
EXPECT_NEAR(up.z, omath::source_engine::k_abs_up.z, k_eps);
|
||||
}
|
||||
|
||||
TEST(UnitTestProjection, UnityEngine_ZeroAngles_BasisVectors)
|
||||
{
|
||||
constexpr float k_eps = 1e-5f;
|
||||
const auto cam = omath::unity_engine::Camera({}, {}, {1280.f, 720.f},
|
||||
omath::projection::FieldOfView::from_degrees(60.f), 0.03f, 1000.f);
|
||||
const auto fwd = cam.get_forward();
|
||||
const auto right = cam.get_right();
|
||||
const auto up = cam.get_up();
|
||||
|
||||
EXPECT_NEAR(fwd.x, omath::unity_engine::k_abs_forward.x, k_eps);
|
||||
EXPECT_NEAR(fwd.y, omath::unity_engine::k_abs_forward.y, k_eps);
|
||||
EXPECT_NEAR(fwd.z, omath::unity_engine::k_abs_forward.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(right.x, omath::unity_engine::k_abs_right.x, k_eps);
|
||||
EXPECT_NEAR(right.y, omath::unity_engine::k_abs_right.y, k_eps);
|
||||
EXPECT_NEAR(right.z, omath::unity_engine::k_abs_right.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(up.x, omath::unity_engine::k_abs_up.x, k_eps);
|
||||
EXPECT_NEAR(up.y, omath::unity_engine::k_abs_up.y, k_eps);
|
||||
EXPECT_NEAR(up.z, omath::unity_engine::k_abs_up.z, k_eps);
|
||||
}
|
||||
|
||||
TEST(UnitTestProjection, OpenGLEngine_ZeroAngles_BasisVectors)
|
||||
{
|
||||
constexpr float k_eps = 1e-5f;
|
||||
const auto cam = omath::opengl_engine::Camera({}, {}, {1920.f, 1080.f},
|
||||
omath::projection::FieldOfView::from_degrees(90.f), 0.01f, 1000.f);
|
||||
const auto fwd = cam.get_forward();
|
||||
const auto right = cam.get_right();
|
||||
const auto up = cam.get_up();
|
||||
|
||||
EXPECT_NEAR(fwd.x, omath::opengl_engine::k_abs_forward.x, k_eps);
|
||||
EXPECT_NEAR(fwd.y, omath::opengl_engine::k_abs_forward.y, k_eps);
|
||||
EXPECT_NEAR(fwd.z, omath::opengl_engine::k_abs_forward.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(right.x, omath::opengl_engine::k_abs_right.x, k_eps);
|
||||
EXPECT_NEAR(right.y, omath::opengl_engine::k_abs_right.y, k_eps);
|
||||
EXPECT_NEAR(right.z, omath::opengl_engine::k_abs_right.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(up.x, omath::opengl_engine::k_abs_up.x, k_eps);
|
||||
EXPECT_NEAR(up.y, omath::opengl_engine::k_abs_up.y, k_eps);
|
||||
EXPECT_NEAR(up.z, omath::opengl_engine::k_abs_up.z, k_eps);
|
||||
}
|
||||
|
||||
TEST(UnitTestProjection, UnrealEngine_ZeroAngles_BasisVectors)
|
||||
{
|
||||
constexpr float k_eps = 1e-5f;
|
||||
const auto cam = omath::unreal_engine::Camera({}, {}, {1920.f, 1080.f},
|
||||
omath::projection::FieldOfView::from_degrees(90.f), 0.01f, 1000.f);
|
||||
const auto fwd = cam.get_forward();
|
||||
const auto right = cam.get_right();
|
||||
const auto up = cam.get_up();
|
||||
|
||||
EXPECT_NEAR(fwd.x, omath::unreal_engine::k_abs_forward.x, k_eps);
|
||||
EXPECT_NEAR(fwd.y, omath::unreal_engine::k_abs_forward.y, k_eps);
|
||||
EXPECT_NEAR(fwd.z, omath::unreal_engine::k_abs_forward.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(right.x, omath::unreal_engine::k_abs_right.x, k_eps);
|
||||
EXPECT_NEAR(right.y, omath::unreal_engine::k_abs_right.y, k_eps);
|
||||
EXPECT_NEAR(right.z, omath::unreal_engine::k_abs_right.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(up.x, omath::unreal_engine::k_abs_up.x, k_eps);
|
||||
EXPECT_NEAR(up.y, omath::unreal_engine::k_abs_up.y, k_eps);
|
||||
EXPECT_NEAR(up.z, omath::unreal_engine::k_abs_up.z, k_eps);
|
||||
}
|
||||
|
||||
TEST(UnitTestProjection, FrostbiteEngine_ZeroAngles_BasisVectors)
|
||||
{
|
||||
constexpr float k_eps = 1e-5f;
|
||||
const auto cam = omath::frostbite_engine::Camera({}, {}, {1920.f, 1080.f},
|
||||
omath::projection::FieldOfView::from_degrees(90.f), 0.01f, 1000.f);
|
||||
const auto fwd = cam.get_forward();
|
||||
const auto right = cam.get_right();
|
||||
const auto up = cam.get_up();
|
||||
|
||||
EXPECT_NEAR(fwd.x, omath::frostbite_engine::k_abs_forward.x, k_eps);
|
||||
EXPECT_NEAR(fwd.y, omath::frostbite_engine::k_abs_forward.y, k_eps);
|
||||
EXPECT_NEAR(fwd.z, omath::frostbite_engine::k_abs_forward.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(right.x, omath::frostbite_engine::k_abs_right.x, k_eps);
|
||||
EXPECT_NEAR(right.y, omath::frostbite_engine::k_abs_right.y, k_eps);
|
||||
EXPECT_NEAR(right.z, omath::frostbite_engine::k_abs_right.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(up.x, omath::frostbite_engine::k_abs_up.x, k_eps);
|
||||
EXPECT_NEAR(up.y, omath::frostbite_engine::k_abs_up.y, k_eps);
|
||||
EXPECT_NEAR(up.z, omath::frostbite_engine::k_abs_up.z, k_eps);
|
||||
}
|
||||
|
||||
TEST(UnitTestProjection, CryEngine_ZeroAngles_BasisVectors)
|
||||
{
|
||||
constexpr float k_eps = 1e-5f;
|
||||
const auto cam = omath::cry_engine::Camera({}, {}, {1920.f, 1080.f},
|
||||
omath::projection::FieldOfView::from_degrees(90.f), 0.01f, 1000.f);
|
||||
const auto fwd = cam.get_forward();
|
||||
const auto right = cam.get_right();
|
||||
const auto up = cam.get_up();
|
||||
|
||||
EXPECT_NEAR(fwd.x, omath::cry_engine::k_abs_forward.x, k_eps);
|
||||
EXPECT_NEAR(fwd.y, omath::cry_engine::k_abs_forward.y, k_eps);
|
||||
EXPECT_NEAR(fwd.z, omath::cry_engine::k_abs_forward.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(right.x, omath::cry_engine::k_abs_right.x, k_eps);
|
||||
EXPECT_NEAR(right.y, omath::cry_engine::k_abs_right.y, k_eps);
|
||||
EXPECT_NEAR(right.z, omath::cry_engine::k_abs_right.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(up.x, omath::cry_engine::k_abs_up.x, k_eps);
|
||||
EXPECT_NEAR(up.y, omath::cry_engine::k_abs_up.y, k_eps);
|
||||
EXPECT_NEAR(up.z, omath::cry_engine::k_abs_up.z, k_eps);
|
||||
}
|
||||
|
||||
TEST(UnitTestProjection, IWEngine_ZeroAngles_BasisVectors)
|
||||
{
|
||||
constexpr float k_eps = 1e-5f;
|
||||
const auto cam = omath::iw_engine::Camera({}, {}, {1920.f, 1080.f},
|
||||
omath::projection::FieldOfView::from_degrees(90.f), 0.01f, 1000.f);
|
||||
const auto fwd = cam.get_forward();
|
||||
const auto right = cam.get_right();
|
||||
const auto up = cam.get_up();
|
||||
|
||||
EXPECT_NEAR(fwd.x, omath::iw_engine::k_abs_forward.x, k_eps);
|
||||
EXPECT_NEAR(fwd.y, omath::iw_engine::k_abs_forward.y, k_eps);
|
||||
EXPECT_NEAR(fwd.z, omath::iw_engine::k_abs_forward.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(right.x, omath::iw_engine::k_abs_right.x, k_eps);
|
||||
EXPECT_NEAR(right.y, omath::iw_engine::k_abs_right.y, k_eps);
|
||||
EXPECT_NEAR(right.z, omath::iw_engine::k_abs_right.z, k_eps);
|
||||
|
||||
EXPECT_NEAR(up.x, omath::iw_engine::k_abs_up.x, k_eps);
|
||||
EXPECT_NEAR(up.y, omath::iw_engine::k_abs_up.y, k_eps);
|
||||
EXPECT_NEAR(up.z, omath::iw_engine::k_abs_up.z, k_eps);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user