math::project with inverted projection instead original projection

This commit is contained in:
2020-01-30 19:01:18 +07:00
parent f80614d802
commit 8e4ca369ea
3 changed files with 132 additions and 113 deletions

View File

@@ -589,6 +589,24 @@ namespace e2d::math
#endif #endif
} }
template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
make_orthographic_lh_matrix4(const vec2<T>& lb, const vec2<T>& rt, T znear, T zfar) noexcept {
return make_orthographic_lh_matrix4(lb.x, rt.x, lb.y, rt.y, znear, zfar);
}
template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
make_orthographic_lh_matrix4(const vec2<T>& size, T znear, T zfar) noexcept {
return make_orthographic_lh_matrix4(size * T(-0.5), size * T(0.5), znear, zfar);
}
template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
make_orthographic_lh_matrix4(T width, T height, T znear, T zfar) noexcept {
return make_orthographic_lh_matrix4(vec2<T>(width, height), znear, zfar);
}
// //
// make_orthographic_rh_matrix4 // make_orthographic_rh_matrix4
// //
@@ -652,6 +670,24 @@ namespace e2d::math
#endif #endif
} }
template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
make_orthographic_rh_matrix4(const vec2<T>& lb, const vec2<T>& rt, T znear, T zfar) noexcept {
return make_orthographic_rh_matrix4(lb.x, rt.x, lb.y, rt.y, znear, zfar);
}
template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
make_orthographic_rh_matrix4(const vec2<T>& size, T znear, T zfar) noexcept {
return make_orthographic_rh_matrix4(size * T(-0.5), size * T(0.5), znear, zfar);
}
template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
make_orthographic_rh_matrix4(T width, T height, T znear, T zfar) noexcept {
return make_orthographic_rh_matrix4(vec2<T>(width, height), znear, zfar);
}
// //
// make_perspective_lh_matrix4 // make_perspective_lh_matrix4
// //
@@ -871,12 +907,11 @@ namespace e2d::math
template < typename T > template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>> std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>>
project_zo( project_zo(
const vec3<T>& v, const vec3<T>& world,
const mat4<T>& model,
const mat4<T>& projection, const mat4<T>& projection,
const rect<T>& viewport) noexcept const rect<T>& viewport) noexcept
{ {
const vec4<T> t4 = vec4<T>(v, T(1)) * model * projection; const vec4<T> t4 = vec4<T>(world, T(1)) * projection;
if ( math::is_near_zero(t4.w, T(0)) ) { if ( math::is_near_zero(t4.w, T(0)) ) {
return std::make_pair(vec3<T>::zero(), false); return std::make_pair(vec3<T>::zero(), false);
@@ -896,12 +931,11 @@ namespace e2d::math
template < typename T > template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>> std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>>
project_no( project_no(
const vec3<T>& v, const vec3<T>& world,
const mat4<T>& model,
const mat4<T>& projection, const mat4<T>& projection,
const rect<T>& viewport) noexcept const rect<T>& viewport) noexcept
{ {
const vec4<T> t4 = vec4<T>(v, T(1)) * model * projection; const vec4<T> t4 = vec4<T>(world, T(1)) * projection;
if ( math::is_near_zero(t4.w, T(0)) ) { if ( math::is_near_zero(t4.w, T(0)) ) {
return std::make_pair(vec3<T>::zero(), false); return std::make_pair(vec3<T>::zero(), false);
@@ -923,14 +957,13 @@ namespace e2d::math
template < typename T > template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>> std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>>
project( project(
const vec3<T>& v, const vec3<T>& world,
const mat4<T>& model,
const mat4<T>& projection, const mat4<T>& projection,
const rect<T>& viewport) noexcept { const rect<T>& viewport) noexcept {
#if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO #if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO
return impl::project_zo(v, model, projection, viewport); return impl::project_zo(world, projection, viewport);
#elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO #elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO
return impl::project_no(v, model, projection, viewport); return impl::project_no(world, projection, viewport);
#else #else
# error "E2D_CLIPPING_MODE not detected" # error "E2D_CLIPPING_MODE not detected"
#endif #endif
@@ -945,18 +978,15 @@ namespace e2d::math
template < typename T > template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>> std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>>
unproject_zo( unproject_zo(
const vec3<T>& v, const vec3<T>& screen,
const mat4<T>& model, const mat4<T>& inv_projection,
const mat4<T>& projection,
const rect<T>& viewport) noexcept const rect<T>& viewport) noexcept
{ {
const std::pair<mat4<T>, bool> inv_matrix = math::inversed(model * projection); if ( math::is_near_zero(math::area(viewport), T(0)) ) {
if ( !inv_matrix.second || math::is_near_zero(math::area(viewport), T(0)) ) {
return std::make_pair(vec3<T>::zero(), false); return std::make_pair(vec3<T>::zero(), false);
} }
vec4<T> t4 = vec4<T>(v, T(1)); vec4<T> t4 = vec4<T>(screen, T(1));
t4.x = (t4.x - viewport.position.x) / viewport.size.x; t4.x = (t4.x - viewport.position.x) / viewport.size.x;
t4.y = (t4.y - viewport.position.y) / viewport.size.y; t4.y = (t4.y - viewport.position.y) / viewport.size.y;
@@ -964,7 +994,7 @@ namespace e2d::math
t4.x = t4.x * T(2) - T(1); t4.x = t4.x * T(2) - T(1);
t4.y = t4.y * T(2) - T(1); t4.y = t4.y * T(2) - T(1);
t4 = t4 * inv_matrix.first; t4 = t4 * inv_projection;
return math::is_near_zero(t4.w, T(0)) return math::is_near_zero(t4.w, T(0))
? std::make_pair(vec3<T>::zero(), false) ? std::make_pair(vec3<T>::zero(), false)
@@ -974,18 +1004,15 @@ namespace e2d::math
template < typename T > template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>> std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>>
unproject_no( unproject_no(
const vec3<T>& v, const vec3<T>& screen,
const mat4<T>& model, const mat4<T>& inv_projection,
const mat4<T>& projection,
const rect<T>& viewport) noexcept const rect<T>& viewport) noexcept
{ {
const std::pair<mat4<T>, bool> inv_matrix = math::inversed(model * projection); if ( math::is_near_zero(math::area(viewport), T(0)) ) {
if ( !inv_matrix.second || math::is_near_zero(math::area(viewport), T(0)) ) {
return std::make_pair(vec3<T>::zero(), false); return std::make_pair(vec3<T>::zero(), false);
} }
vec4<T> t4 = vec4<T>(v, T(1)); vec4<T> t4 = vec4<T>(screen, T(1));
t4.x = (t4.x - viewport.position.x) / viewport.size.x; t4.x = (t4.x - viewport.position.x) / viewport.size.x;
t4.y = (t4.y - viewport.position.y) / viewport.size.y; t4.y = (t4.y - viewport.position.y) / viewport.size.y;
@@ -994,7 +1021,7 @@ namespace e2d::math
t4.y = t4.y * T(2) - T(1); t4.y = t4.y * T(2) - T(1);
t4.z = t4.z * T(2) - T(1); t4.z = t4.z * T(2) - T(1);
t4 = t4 * inv_matrix.first; t4 = t4 * inv_projection;
return math::is_near_zero(t4.w, T(0)) return math::is_near_zero(t4.w, T(0))
? std::make_pair(vec3<T>::zero(), false) ? std::make_pair(vec3<T>::zero(), false)
@@ -1005,14 +1032,13 @@ namespace e2d::math
template < typename T > template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>> std::enable_if_t<std::is_floating_point_v<T>, std::pair<vec3<T>, bool>>
unproject( unproject(
const vec3<T>& v, const vec3<T>& screen,
const mat4<T>& model, const mat4<T>& inv_projection,
const mat4<T>& projection,
const rect<T>& viewport) noexcept { const rect<T>& viewport) noexcept {
#if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO #if defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_ZO
return impl::unproject_zo(v, model, projection, viewport); return impl::unproject_zo(screen, inv_projection, viewport);
#elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO #elif defined(E2D_CLIPPING_MODE) && E2D_CLIPPING_MODE == E2D_CLIPPING_MODE_NO
return impl::unproject_no(v, model, projection, viewport); return impl::unproject_no(screen, inv_projection, viewport);
#else #else
# error "E2D_CLIPPING_MODE not detected" # error "E2D_CLIPPING_MODE not detected"
#endif #endif

View File

@@ -50,21 +50,18 @@ function m4f.make_look_at_lh(eye, at, up) end
---@return m4f ---@return m4f
function m4f.make_look_at_rh(eye, at, up) end function m4f.make_look_at_rh(eye, at, up) end
---@param left number
---@param right number
---@param bottom number
---@param top number
---@param znear number
---@param zfar number
---@return m4f
function m4f.make_orthographic_lh(left, right, bottom, top, znear, zfar) end
---@param left number ---@overload fun(left: number, right: number, bottom: number, top: number, znear: number, zfar: number): m4f
---@param right number ---@overload fun(lb: v2f, rt: v2f, znear: number, zfar: number): m4f
---@param bottom number ---@overload fun(size: v2f, znear: number, zfar: number): m4f
---@param top number ---@overload fun(width: number, height: number, znear: number, zfar: number): m4f
---@param znear number ---@return m4f
---@param zfar number function m4f.make_orthographic_lh() end
---@overload fun(left: number, right: number, bottom: number, top: number, znear: number, zfar: number): m4f
---@overload fun(lb: v2f, rt: v2f, znear: number, zfar: number): m4f
---@overload fun(size: v2f, znear: number, zfar: number): m4f
---@overload fun(width: number, height: number, znear: number, zfar: number): m4f
---@return m4f ---@return m4f
function m4f.make_orthographic_rh(left, right, bottom, top, znear, zfar) end function m4f.make_orthographic_rh(left, right, bottom, top, znear, zfar) end

View File

@@ -36,10 +36,14 @@ TEST_CASE("mat4") {
REQUIRE(math::make_rotation_matrix4(make_rad(1.f),v3f(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),v3f(1.f,1.f,1.f)) == math::make_rotation_matrix4(make_rad(1.f), v3f::unit()));
REQUIRE(math::make_orthographic_lh_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthographic_lh_matrix4(v2f(640,480), 0.f, 1.f)); REQUIRE(math::make_orthographic_lh_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthographic_lh_matrix4(v2f(640,480), 0.f, 1.f));
REQUIRE(math::make_orthographic_lh_matrix4(-320.f, 320.f, -240.f, 240.f, 0.f, 1.f) == math::make_orthographic_lh_matrix4(-v2f(320,240), v2f(320,240), 0.f, 1.f));
REQUIRE(math::make_orthographic_lh_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthographic_lh_matrix4(v2d(640,480), 0.0, 1.0)); REQUIRE(math::make_orthographic_lh_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthographic_lh_matrix4(v2d(640,480), 0.0, 1.0));
REQUIRE(math::make_orthographic_lh_matrix4(-320.0, 320.0, -240.0, 240.0, 0.0, 1.0) == math::make_orthographic_lh_matrix4(-v2d(320,240), v2d(320,240), 0.0, 1.0));
REQUIRE(math::make_orthographic_lh_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthographic_lh_matrix4(v2f(640,480), 0.f, 1.f)); REQUIRE(math::make_orthographic_rh_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthographic_rh_matrix4(v2f(640,480), 0.f, 1.f));
REQUIRE(math::make_orthographic_lh_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthographic_lh_matrix4(v2d(640,480), 0.0, 1.0)); REQUIRE(math::make_orthographic_rh_matrix4(-320.f, 320.f, -240.f, 240.f, 0.f, 1.f) == math::make_orthographic_rh_matrix4(-v2f(320,240), v2f(320,240), 0.f, 1.f));
REQUIRE(math::make_orthographic_rh_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthographic_rh_matrix4(v2d(640,480), 0.0, 1.0));
REQUIRE(math::make_orthographic_rh_matrix4(-320.0, 320.0, -240.0, 240.0, 0.0, 1.0) == math::make_orthographic_rh_matrix4(-v2d(320,240), v2d(320,240), 0.0, 1.0));
} }
{ {
REQUIRE(m4f(m4f::identity()) == m4f::identity()); REQUIRE(m4f(m4f::identity()) == m4f::identity());
@@ -168,62 +172,57 @@ TEST_CASE("mat4") {
} }
{ {
m4f projection = math::make_perspective_lh_matrix4(make_deg(80.f), 4.f / 3.f, 0.01f, 1.f); m4f projection = math::make_perspective_lh_matrix4(make_deg(80.f), 4.f / 3.f, 0.01f, 1.f);
const m4f inv_projection = math::inversed(projection).first;
b2f viewport = make_rect(800.f, 600.f); b2f viewport = make_rect(800.f, 600.f);
const v3f p1 = v3f(0.f,0.f,0.01f); const v3f p1 = v3f(0.f,0.f,0.01f);
const v3f p2 = v3f(+1.f,0.f,0.01f); const v3f p2 = v3f(+1.f,0.f,0.01f);
const v3f p3 = v3f(-1.f,0.f,0.01f); const v3f p3 = v3f(-1.f,0.f,0.01f);
REQUIRE(math::project(p1, m4f::identity(), projection, viewport).second); REQUIRE(math::project(p1, projection, viewport).second);
REQUIRE(math::project(p2, m4f::identity(), projection, viewport).second); REQUIRE(math::project(p2, projection, viewport).second);
REQUIRE(math::project(p3, m4f::identity(), projection, viewport).second); REQUIRE(math::project(p3, projection, viewport).second);
REQUIRE(math::impl::project_zo(p1, m4f::identity(), projection, viewport).second); REQUIRE(math::impl::project_zo(p1, projection, viewport).second);
REQUIRE(math::impl::project_zo(p2, m4f::identity(), projection, viewport).second); REQUIRE(math::impl::project_zo(p2, projection, viewport).second);
REQUIRE(math::impl::project_zo(p3, m4f::identity(), projection, viewport).second); REQUIRE(math::impl::project_zo(p3, projection, viewport).second);
REQUIRE(math::impl::project_no(p1, m4f::identity(), projection, viewport).second); REQUIRE(math::impl::project_no(p1, projection, viewport).second);
REQUIRE(math::impl::project_no(p2, m4f::identity(), projection, viewport).second); REQUIRE(math::impl::project_no(p2, projection, viewport).second);
REQUIRE(math::impl::project_no(p3, m4f::identity(), projection, viewport).second); REQUIRE(math::impl::project_no(p3, projection, viewport).second);
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p1, m4f::identity(), projection, viewport).first, math::project(p1, projection, viewport).first,
m4f::identity(), inv_projection,
projection,
viewport).second); viewport).second);
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p2, m4f::identity(), projection, viewport).first, math::project(p2, projection, viewport).first,
m4f::identity(), inv_projection,
projection,
viewport).second); viewport).second);
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p3, m4f::identity(), projection, viewport).first, math::project(p3, projection, viewport).first,
m4f::identity(), inv_projection,
projection,
viewport).second); viewport).second);
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p1, m4f::identity(), projection, viewport).first, math::project(p1, projection, viewport).first,
m4f::identity(), inv_projection,
projection,
viewport).first == v3f(p1)); viewport).first == v3f(p1));
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p2, m4f::identity(), projection, viewport).first, math::project(p2, projection, viewport).first,
m4f::identity(), inv_projection,
projection,
viewport).first == v3f(p2)); viewport).first == v3f(p2));
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p3, m4f::identity(), projection, viewport).first, math::project(p3, projection, viewport).first,
m4f::identity(), inv_projection,
projection,
viewport).first == v3f(p3)); viewport).first == v3f(p3));
} }
{ {
m4f projection = math::make_orthographic_lh_matrix4({400.f, 300.f}, 0.f, 1.f); m4f projection = math::make_orthographic_lh_matrix4(-200.f, 200.f, -300.f, 300.f, 0.f, 1.f);
m4f model = math::make_scale_matrix4(2.f, 2.f); m4f model = math::make_scale_matrix4(2.f, 2.f);
b2f viewport = make_rect(800.f, 600.f); b2f viewport = make_rect(800.f, 600.f);
@@ -231,93 +230,90 @@ TEST_CASE("mat4") {
const v3f p2 = v3f(+1.f,0.f,0.f); const v3f p2 = v3f(+1.f,0.f,0.f);
const v3f p3 = v3f(-1.f,0.f,0.f); const v3f p3 = v3f(-1.f,0.f,0.f);
REQUIRE(math::project(p1, model, projection, viewport).second); REQUIRE(math::project(p1, model * projection, viewport).second);
REQUIRE(math::project(p2, model, projection, viewport).second); REQUIRE(math::project(p2, model * projection, viewport).second);
REQUIRE(math::project(p3, model, projection, viewport).second); REQUIRE(math::project(p3, model * projection, viewport).second);
m4f projection_zo = math::impl::make_orthographic_lh_zo_matrix4(400.f, 300.f, 0.f, 1.f); m4f projection_zo = math::impl::make_orthographic_lh_zo_matrix4(-200.f, 200.f, -150.f, 150.f, 0.f, 1.f);
REQUIRE(math::impl::project_zo(p1, model, projection_zo, viewport).second); REQUIRE(math::impl::project_zo(p1, model * projection_zo, viewport).second);
REQUIRE(math::impl::project_zo(p2, model, projection_zo, viewport).second); REQUIRE(math::impl::project_zo(p2, model * projection_zo, viewport).second);
REQUIRE(math::impl::project_zo(p3, model, projection_zo, viewport).second); REQUIRE(math::impl::project_zo(p3, model * projection_zo, viewport).second);
m4f projection_no = math::impl::make_orthographic_lh_no_matrix4(400.f, 300.f, 0.f, 1.f); m4f projection_no = math::impl::make_orthographic_lh_no_matrix4(-200.f, 200.f, -150.f, 150.f, 0.f, 1.f);
REQUIRE(math::impl::project_no(p1, model, projection_no, viewport).second); REQUIRE(math::impl::project_no(p1, model * projection_no, viewport).second);
REQUIRE(math::impl::project_no(p2, model, projection_no, viewport).second); REQUIRE(math::impl::project_no(p2, model * projection_no, viewport).second);
REQUIRE(math::impl::project_no(p3, model, projection_no, viewport).second); REQUIRE(math::impl::project_no(p3, model * projection_no, viewport).second);
REQUIRE(math::approximately( REQUIRE(math::approximately(
math::project(p1, model, projection, viewport).first, math::project(p1, model * projection, viewport).first,
v3f(400.f, 300.f, 0.f), v3f(400.f, 300.f, 0.f),
0.01f)); 0.01f));
REQUIRE(math::approximately( REQUIRE(math::approximately(
math::project(p2, model, projection, viewport).first, math::project(p2, model * projection, viewport).first,
v3f(404.f, 300.f, 0.f), v3f(404.f, 300.f, 0.f),
0.01f)); 0.01f));
REQUIRE(math::approximately( REQUIRE(math::approximately(
math::project(p3, model, projection, viewport).first, math::project(p3, model * projection, viewport).first,
v3f(396.f, 300.f, 0.f), v3f(396.f, 300.f, 0.f),
0.01f)); 0.01f));
REQUIRE(math::approximately( REQUIRE(math::approximately(
math::impl::project_zo(p1, model, projection_zo, viewport).first, math::impl::project_zo(p1, model * projection_zo, viewport).first,
v3f(400.f, 300.f, 0.f), v3f(400.f, 300.f, 0.f),
0.01f)); 0.01f));
REQUIRE(math::approximately( REQUIRE(math::approximately(
math::impl::project_zo(p2, model, projection_zo, viewport).first, math::impl::project_zo(p2, model * projection_zo, viewport).first,
v3f(404.f, 300.f, 0.f), v3f(404.f, 300.f, 0.f),
0.01f)); 0.01f));
REQUIRE(math::approximately( REQUIRE(math::approximately(
math::impl::project_zo(p3, model, projection_zo, viewport).first, math::impl::project_zo(p3, model * projection_zo, viewport).first,
v3f(396.f, 300.f, 0.f), v3f(396.f, 300.f, 0.f),
0.01f)); 0.01f));
REQUIRE(math::approximately( REQUIRE(math::approximately(
math::impl::project_no(p1, model, projection_no, viewport).first, math::impl::project_no(p1, model * projection_no, viewport).first,
v3f(400.f, 300.f, 0.f), v3f(400.f, 300.f, 0.f),
0.01f)); 0.01f));
REQUIRE(math::approximately( REQUIRE(math::approximately(
math::impl::project_no(p2, model, projection_no, viewport).first, math::impl::project_no(p2, model * projection_no, viewport).first,
v3f(404.f, 300.f, 0.f), v3f(404.f, 300.f, 0.f),
0.01f)); 0.01f));
REQUIRE(math::approximately( REQUIRE(math::approximately(
math::impl::project_no(p3, model, projection_no, viewport).first, math::impl::project_no(p3, model * projection_no, viewport).first,
v3f(396.f, 300.f, 0.f), v3f(396.f, 300.f, 0.f),
0.01f)); 0.01f));
const m4f inv_project = math::inversed(model * projection).first;
REQUIRE(math::inversed(model * projection).second);
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p1, model, projection, viewport).first, math::project(p1, inv_project, viewport).first,
model, model * projection,
projection,
viewport).second); viewport).second);
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p2, model, projection, viewport).first, math::project(p2, inv_project, viewport).first,
model, model * projection,
projection,
viewport).second); viewport).second);
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p3, model, projection, viewport).first, math::project(p3, inv_project, viewport).first,
model, model * projection,
projection,
viewport).second); viewport).second);
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p1, model, projection, viewport).first, math::project(p1, inv_project, viewport).first,
model, model * projection,
projection,
viewport).first == v3f(p1)); viewport).first == v3f(p1));
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p2, model, projection, viewport).first, math::project(p2, inv_project, viewport).first,
model, model * projection,
projection,
viewport).first == v3f(p2)); viewport).first == v3f(p2));
REQUIRE(math::unproject( REQUIRE(math::unproject(
math::project(p3, model, projection, viewport).first, math::project(p3, inv_project, viewport).first,
model, model * projection,
projection,
viewport).first == v3f(p3)); viewport).first == v3f(p3));
} }
} }