diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index 3a911ef..4467307 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -244,7 +244,7 @@ namespace vmath_hpp // look_at template < typename T > - constexpr mat look_at_lh(const vec& eye, const vec& at, const vec& up) { + mat look_at_lh(const vec& eye, const vec& at, const vec& up) { const vec az = normalize(at - eye); const vec ax = normalize(cross(up, az)); const vec ay = cross(az, ax); @@ -259,7 +259,7 @@ namespace vmath_hpp } template < typename T > - constexpr mat look_at_rh(const vec& eye, const vec& at, const vec& up) { + mat look_at_rh(const vec& eye, const vec& at, const vec& up) { const vec az = normalize(eye - at); const vec ax = normalize(cross(up, az)); const vec ay = cross(az, ax); @@ -274,6 +274,137 @@ namespace vmath_hpp } } +// +// Matrix Projections +// + +namespace vmath_hpp +{ + // orthographic + + template < typename T > + mat orthographic_lh_zo(T left, T right, T bottom, T top, T znear, T zfar) { + const T sx = T(2) / (right - left); + const T sy = T(2) / (top - bottom); + const T sz = T(1) / (zfar - znear); + + const T tx = - (right + left) / (right - left); + const T ty = - (top + bottom) / (top - bottom); + const T tz = - znear / (zfar - znear); + + return { + sx, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, 0, + tx, ty, tz, 1}; + } + + template < typename T > + mat orthographic_lh_no(T left, T right, T bottom, T top, T znear, T zfar) { + const T sx = T(2) / (right - left); + const T sy = T(2) / (top - bottom); + const T sz = T(2) / (zfar - znear); + + const T tx = - (right + left) / (right - left); + const T ty = - (top + bottom) / (top - bottom); + const T tz = - (zfar + znear) / (zfar - znear); + + return { + sx, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, 0, + tx, ty, tz, 1}; + } + + template < typename T > + mat orthographic_rh_zo(T left, T right, T bottom, T top, T znear, T zfar) { + const T sx = T(2) / (right - left); + const T sy = T(2) / (top - bottom); + const T sz = -T(1) / (zfar - znear); + + const T tx = - (right + left) / (right - left); + const T ty = - (top + bottom) / (top - bottom); + const T tz = - znear / (zfar - znear); + + return { + sx, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, 0, + tx, ty, tz, 1}; + } + + template < typename T > + mat orthographic_rh_no(T left, T right, T bottom, T top, T znear, T zfar) { + const T sx = T(2) / (right - left); + const T sy = T(2) / (top - bottom); + const T sz = -T(2) / (zfar - znear); + + const T tx = - (right + left) / (right - left); + const T ty = - (top + bottom) / (top - bottom); + const T tz = - (zfar + znear) / (zfar - znear); + + return { + sx, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, 0, + tx, ty, tz, 1}; + } + + // perspective + + template < typename T > + mat perspective_lh_zo(T fov, T aspect, T znear, T zfar) { + const T sy = T(1) / tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = zfar / (zfar - znear); + const T tz = (znear * zfar) / (znear - zfar); + return { + sx, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, 1, + 0, 0, tz, 0}; + } + + template < typename T > + mat perspective_lh_no(T fov, T aspect, T znear, T zfar) { + const T sy = T(1) / tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = (zfar + znear) / (zfar - znear); + const T tz = (T(2) * znear * zfar) / (znear - zfar); + return { + sx, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, 1, + 0, 0, tz, 0}; + } + + template < typename T > + mat perspective_rh_zo(T fov, T aspect, T znear, T zfar) { + const T sy = T(1) / 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, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, -1, + 0, 0, tz, 0}; + } + + template < typename T > + mat perspective_rh_no(T fov, T aspect, T znear, T zfar) { + const T sy = T(1) / tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = (zfar + znear) / (znear - zfar); + const T tz = (T(2) * znear * zfar) / (znear - zfar); + return { + sx, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, -1, + 0, 0, tz, 0}; + } +} + // // Vector Transform // diff --git a/untests/vmath_ext_tests.cpp b/untests/vmath_ext_tests.cpp index 7097873..92d0cdc 100644 --- a/untests/vmath_ext_tests.cpp +++ b/untests/vmath_ext_tests.cpp @@ -134,6 +134,16 @@ TEST_CASE("vmath/ext") { SECTION("matrix look_at") { look_at_lh(float3(-10.f), float3(0.f), float3(0,-1,0)); look_at_rh(float3(-10.f), float3(0.f), float3(0,-1,0)); + + orthographic_lh_zo(0.f, 800.f, 0.f, 640.f, 0.f, 10.f); + orthographic_lh_no(0.f, 800.f, 0.f, 640.f, 0.f, 10.f); + orthographic_rh_zo(0.f, 800.f, 0.f, 640.f, 0.f, 10.f); + orthographic_rh_no(0.f, 800.f, 0.f, 640.f, 0.f, 10.f); + + perspective_lh_zo(1.f, 1.3f, 0.f, 10.f); + perspective_lh_no(1.f, 1.3f, 0.f, 10.f); + perspective_rh_zo(1.f, 1.3f, 0.f, 10.f); + perspective_rh_no(1.f, 1.3f, 0.f, 10.f); } SECTION("vector angle") {