diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index 652a448..3a911ef 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -181,36 +181,26 @@ namespace vmath_hpp // translate template < typename T > - constexpr mat translate(T x, T y, T z) { + constexpr mat translate(const vec& v) { return { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {x, y, z, 1}}; + { 1, 0, 0, 0}, + { 0, 1, 0, 0}, + { 0, 0, 1, 0}, + {v.x, v.y, v.z, 1}}; } template < typename T > - constexpr mat translate(const vec& xyz) { - return translate(xyz.x, xyz.y, xyz.z); - } - - template < typename T > - constexpr mat translate(const mat& m, T x, T y, T z) { - return m * translate(x, y, z); - } - - template < typename T > - constexpr mat translate(const mat& m, const vec& xyz) { - return m * translate(xyz); + constexpr mat translate(const mat& m, const vec& v) { + return m * translate(v); } // rotate template < typename T > - mat rotate(T angle, T axis_x, T axis_y, T axis_z) { - const T x = axis_x; - const T y = axis_y; - const T z = axis_z; + mat rotate(T angle, const vec& axis) { + const T x = axis.x; + const T y = axis.y; + const T z = axis.z; const T px = x * x; const T py = y * y; const T pz = z * z; @@ -230,16 +220,6 @@ namespace vmath_hpp 0, 0, 0, 1}; } - template < typename T > - mat rotate(T angle, const vec& axis) { - return rotate(angle, axis.x, axis.y, axis.z); - } - - template < typename T > - mat rotate(const mat& m, T angle, T axis_x, T axis_y, T axis_z) { - return m * rotate(angle, axis_x, axis_y, axis_z); - } - template < typename T > mat rotate(const mat& m, T angle, const vec& axis) { return m * rotate(angle, axis); @@ -248,27 +228,49 @@ namespace vmath_hpp // scale template < typename T > - constexpr mat scale(T x, T y, T z) { + constexpr mat scale(const vec& v) { return { - {x, 0, 0, 0}, - {0, y, 0, 0}, - {0, 0, z, 0}, - {0, 0, 0, 1}}; + {v.x, 0, 0, 0}, + { 0, v.y, 0, 0}, + { 0, 0, v.z, 0}, + { 0, 0, 0, 1}}; } template < typename T > - constexpr mat scale(const vec& xyz) { - return scale(xyz.x, xyz.y, xyz.z); + constexpr mat scale(const mat& m, const vec& v) { + return m * scale(v); + } + + // look_at + + template < typename T > + constexpr 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); + const T dx = dot(ax, eye); + const T dy = dot(ay, eye); + const T dz = dot(az, eye); + return { + ax.x, ay.x, az.x, 0, + ax.y, ay.y, az.y, 0, + ax.z, ay.z, az.z, 0, + -dx, -dy, -dz, 1}; } template < typename T > - constexpr mat scale(const mat& m, T x, T y, T z) { - return m * scale(x, y, z); - } - - template < typename T > - constexpr mat scale(const mat& m, const vec& xyz) { - return m * scale(xyz); + constexpr 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); + const T dx = dot(ax, eye); + const T dy = dot(ay, eye); + const T dz = dot(az, eye); + return { + ax.x, ay.x, az.x, 0, + ax.y, ay.y, az.y, 0, + ax.z, ay.z, az.z, 0, + -dx, -dy, -dz, 1}; } } diff --git a/untests/vmath_ext_tests.cpp b/untests/vmath_ext_tests.cpp index 1944be6..7097873 100644 --- a/untests/vmath_ext_tests.cpp +++ b/untests/vmath_ext_tests.cpp @@ -108,30 +108,32 @@ TEST_CASE("vmath/ext") { } SECTION("matrix translate") { - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(1.f,2.f,3.f) == approx4(3.f,5.f,7.f,1.f)); STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(float3{1.f,2.f,3.f}) == approx4(3.f,5.f,7.f,1.f)); - - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(translate(1.f,2.f,3.f), 1.f,2.f,3.f) == approx4(4.f,7.f,10.f,1.f)); - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(translate(1.f,2.f,3.f), float3{1.f,2.f,3.f}) == approx4(4.f,7.f,10.f,1.f)); + STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(translate(float3{1.f,2.f,3.f}), float3{1.f,2.f,3.f}) == approx4(4.f,7.f,10.f,1.f)); } SECTION("matrix rotate") { constexpr float pi = radians(180.f); constexpr float pi_2 = radians(90.f); - REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,0.f,0.f,1.f) == approx4(-2.f,-3.f,4.f,1.f)); + REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f)); REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,float3{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f)); - REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,0.f,0.f,1.f),pi_2,0.f,0.f,1.f) == approx4(-2.f,-3.f,4.f,1.f)); - REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,0.f,0.f,1.f),pi_2,float3{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f)); + REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,{0.f,0.f,1.f}),pi_2,{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f)); + REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,float3{0.f,0.f,1.f}),pi_2,float3{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f)); } SECTION("matrix scale") { - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(2.f,3.f,4.f) == approx4(4.f,9.f,16.f,1.f)); + STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(float3{2.f,3.f,4.f}) == approx4(4.f,9.f,16.f,1.f)); STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(float3{2.f,3.f,4.f}) == approx4(4.f,9.f,16.f,1.f)); - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(2.f,2.f,2.f), 2.f,3.f,4.f) == approx4(8.f,18.f,32.f,1.f)); - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(2.f,2.f,2.f), float3{2.f,3.f,4.f}) == approx4(8.f,18.f,32.f,1.f)); + STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(float3{2.f,2.f,2.f}), {2.f,3.f,4.f}) == approx4(8.f,18.f,32.f,1.f)); + STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(float3{2.f,2.f,2.f}), float3{2.f,3.f,4.f}) == approx4(8.f,18.f,32.f,1.f)); + } + + 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)); } SECTION("vector angle") { diff --git a/untests/vmath_mat_fun_tests.cpp b/untests/vmath_mat_fun_tests.cpp index f1b19bb..4edfae7 100644 --- a/untests/vmath_mat_fun_tests.cpp +++ b/untests/vmath_mat_fun_tests.cpp @@ -88,23 +88,23 @@ TEST_CASE("vmath/mat_fun") { { float4 v{0.f, 0.f, 0.f, 1.f}; - REQUIRE(&v == &(v *= translate(1.f,2.f,3.f))); + REQUIRE(&v == &(v *= translate(float3{1.f,2.f,3.f}))); REQUIRE(v == approx4(1.f,2.f,3.f,1.f)); } { float3 v{1.f, 2.f, 3.f}; - REQUIRE(&v == &(v *= float3x3(scale(2.f,3.f,4.f)))); + REQUIRE(&v == &(v *= float3x3(scale(float3{2.f,3.f,4.f})))); REQUIRE(v == approx3(2.f,6.f,12.f)); } { - float4x4 v = translate(1.f, 2.f, 3.f); - REQUIRE(&v == &(v *= translate(1.f,2.f,3.f))); - REQUIRE(v == approx4x4(translate(2.f,4.f,6.f))); + float4x4 v = translate(float3{1.f, 2.f, 3.f}); + REQUIRE(&v == &(v *= translate(float3{1.f,2.f,3.f}))); + REQUIRE(v == approx4x4(translate(float3{2.f,4.f,6.f}))); } { - float3x3 v = float3x3(scale(1.f, 2.f, 3.f)); - REQUIRE(&v == &(v *= float3x3(scale(2.f,3.f,4.f)))); - REQUIRE(v == approx3x3(float3x3(scale(2.f,6.f,12.f)))); + float3x3 v = float3x3(scale(float3{1.f, 2.f, 3.f})); + REQUIRE(&v == &(v *= float3x3(scale(float3{2.f,3.f,4.f})))); + REQUIRE(v == approx3x3(float3x3(scale(float3{2.f,6.f,12.f})))); } } @@ -165,7 +165,7 @@ TEST_CASE("vmath/mat_fun") { STATIC_REQUIRE(inverse(float3x3(0.5)) == float3x3(2.f)); STATIC_REQUIRE(inverse(float4x4(0.5)) == float4x4(2.f)); - STATIC_REQUIRE(inverse(translate(1.f,2.f,3.f)) == approx4x4(translate(-1.f,-2.f,-3.f))); + STATIC_REQUIRE(inverse(translate(float3{1.f,2.f,3.f})) == approx4x4(translate(float3{-1.f,-2.f,-3.f}))); REQUIRE(inverse(rotate(0.5f,normalize(float3{1.f,2.f,3.f}))) == approx4x4(rotate(-0.5f,normalize(float3{1.f,2.f,3.f})))); REQUIRE(inverse(float3x3(rotate(0.5f,normalize(float3{1.f,2.f,3.f})))) == approx3x3(float3x3(rotate(-0.5f,normalize(float3{1.f,2.f,3.f})))));