From c3506b2a52ecab48287043b4488986df18396d89 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 16 Oct 2018 17:53:24 +0700 Subject: [PATCH] math::make_perspective_XX --- headers/enduro2d/math/mat4.hpp | 77 +++++++++++++++++++++++++-- untests/sources/untests_math/mat4.cpp | 4 +- 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/headers/enduro2d/math/mat4.hpp b/headers/enduro2d/math/mat4.hpp index 4d0e8027..fca35d63 100644 --- a/headers/enduro2d/math/mat4.hpp +++ b/headers/enduro2d/math/mat4.hpp @@ -458,12 +458,12 @@ namespace e2d { namespace math } // - // make_orthogonal_matrix + // make_orthogonal_lh_matrix4 // template < typename T > std::enable_if_t::value, mat4> - make_orthogonal_matrix4(T width, T height, T znear, T zfar) { + make_orthogonal_lh_matrix4(T width, T height, T znear, T zfar) noexcept { E2D_ASSERT(!math::is_near_zero(width, T(0))); E2D_ASSERT(!math::is_near_zero(height, T(0))); E2D_ASSERT(!math::approximately(znear, zfar, T(0))); @@ -480,8 +480,77 @@ namespace e2d { namespace math template < typename T > std::enable_if_t::value, mat4> - make_orthogonal_matrix4(const vec2& size, T znear, T zfar) { - return make_orthogonal_matrix4(size.x, size.y, znear, zfar); + make_orthogonal_lh_matrix4(const vec2& size, T znear, T zfar) { + return make_orthogonal_lh_matrix4(size.x, size.y, znear, zfar); + } + + // + // make_orthogonal_rh_matrix4 + // + + template < typename T > + std::enable_if_t::value, mat4> + make_orthogonal_rh_matrix4(T width, T height, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(width, T(0))); + E2D_ASSERT(!math::is_near_zero(height, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + const T sx = T(2) / width; + const T sy = T(2) / height; + const T sz = T(1) / (znear - zfar); + const T tz = znear * sz; + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(0), + T(0), T(0), tz, T(1)}; + } + + template < typename T > + std::enable_if_t::value, mat4> + make_orthogonal_rh_matrix4(const vec2& size, T znear, T zfar) { + return make_orthogonal_rh_matrix4(size.x, size.y, znear, zfar); + } + + // + // make_perspective_lh_matrix4 + // + + template < typename T, typename AngleTag > + std::enable_if_t::value, mat4> + make_perspective_lh_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(aspect, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + E2D_ASSERT(!math::approximately(to_rad(fov), make_rad(0), T(0))); + const T sy = T(1) / math::tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = zfar / (zfar - znear); + const T tz = -znear * zfar / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(1), + T(0), T(0), tz, T(0)}; + } + + // + // make_perspective_rh_matrix4 + // + + template < typename T, typename AngleTag > + std::enable_if_t::value, mat4> + make_perspective_rh_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(aspect, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + E2D_ASSERT(!math::approximately(to_rad(fov), make_rad(0), T(0))); + const T sy = T(1) / math::tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = zfar / (znear - zfar); + const T tz = znear * zfar / (znear - zfar); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(-1), + T(0), T(0), tz, T(0)}; } // diff --git a/untests/sources/untests_math/mat4.cpp b/untests/sources/untests_math/mat4.cpp index 09d374ac..a04eb31e 100644 --- a/untests/sources/untests_math/mat4.cpp +++ b/untests/sources/untests_math/mat4.cpp @@ -35,8 +35,8 @@ TEST_CASE("mat4") { REQUIRE(math::make_rotation_matrix4(make_rad(1.f),1.f,1.f,1.f) == math::make_rotation_matrix4(make_rad(1.f), v3f::unit())); REQUIRE(math::make_rotation_matrix4(make_rad(1.f),v2f(1.f,1.f),1.f) == math::make_rotation_matrix4(make_rad(1.f), v3f::unit())); - REQUIRE(math::make_orthogonal_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthogonal_matrix4(v2f(640,480), 0.f, 1.f)); - REQUIRE(math::make_orthogonal_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthogonal_matrix4(v2d(640,480), 0.0, 1.0)); + REQUIRE(math::make_orthogonal_lh_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthogonal_lh_matrix4(v2f(640,480), 0.f, 1.f)); + REQUIRE(math::make_orthogonal_lh_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthogonal_lh_matrix4(v2d(640,480), 0.0, 1.0)); } { REQUIRE(m4f(m4f::identity()) == m4f::identity());