mirror of
https://github.com/BlackMATov/vmath.hpp.git
synced 2025-12-16 14:11:28 +07:00
look_at matrix functions
This commit is contained in:
@@ -181,36 +181,26 @@ namespace vmath_hpp
|
|||||||
// translate
|
// translate
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
constexpr mat<T, 4> translate(T x, T y, T z) {
|
constexpr mat<T, 4> translate(const vec<T, 3>& v) {
|
||||||
return {
|
return {
|
||||||
{1, 0, 0, 0},
|
{ 1, 0, 0, 0},
|
||||||
{0, 1, 0, 0},
|
{ 0, 1, 0, 0},
|
||||||
{0, 0, 1, 0},
|
{ 0, 0, 1, 0},
|
||||||
{x, y, z, 1}};
|
{v.x, v.y, v.z, 1}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
constexpr mat<T, 4> translate(const vec<T, 3>& xyz) {
|
constexpr mat<T, 4> translate(const mat<T, 4>& m, const vec<T, 3>& v) {
|
||||||
return translate(xyz.x, xyz.y, xyz.z);
|
return m * translate(v);
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
constexpr mat<T, 4> translate(const mat<T, 4>& m, T x, T y, T z) {
|
|
||||||
return m * translate(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
constexpr mat<T, 4> translate(const mat<T, 4>& m, const vec<T, 3>& xyz) {
|
|
||||||
return m * translate(xyz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// rotate
|
// rotate
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
mat<T, 4> rotate(T angle, T axis_x, T axis_y, T axis_z) {
|
mat<T, 4> rotate(T angle, const vec<T, 3>& axis) {
|
||||||
const T x = axis_x;
|
const T x = axis.x;
|
||||||
const T y = axis_y;
|
const T y = axis.y;
|
||||||
const T z = axis_z;
|
const T z = axis.z;
|
||||||
const T px = x * x;
|
const T px = x * x;
|
||||||
const T py = y * y;
|
const T py = y * y;
|
||||||
const T pz = z * z;
|
const T pz = z * z;
|
||||||
@@ -230,16 +220,6 @@ namespace vmath_hpp
|
|||||||
0, 0, 0, 1};
|
0, 0, 0, 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
mat<T, 4> rotate(T angle, const vec<T, 3>& axis) {
|
|
||||||
return rotate(angle, axis.x, axis.y, axis.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
mat<T, 4> rotate(const mat<T, 4>& 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 >
|
template < typename T >
|
||||||
mat<T, 4> rotate(const mat<T, 4>& m, T angle, const vec<T, 3>& axis) {
|
mat<T, 4> rotate(const mat<T, 4>& m, T angle, const vec<T, 3>& axis) {
|
||||||
return m * rotate(angle, axis);
|
return m * rotate(angle, axis);
|
||||||
@@ -248,27 +228,49 @@ namespace vmath_hpp
|
|||||||
// scale
|
// scale
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
constexpr mat<T, 4> scale(T x, T y, T z) {
|
constexpr mat<T, 4> scale(const vec<T, 3>& v) {
|
||||||
return {
|
return {
|
||||||
{x, 0, 0, 0},
|
{v.x, 0, 0, 0},
|
||||||
{0, y, 0, 0},
|
{ 0, v.y, 0, 0},
|
||||||
{0, 0, z, 0},
|
{ 0, 0, v.z, 0},
|
||||||
{0, 0, 0, 1}};
|
{ 0, 0, 0, 1}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
constexpr mat<T, 4> scale(const vec<T, 3>& xyz) {
|
constexpr mat<T, 4> scale(const mat<T, 4>& m, const vec<T, 3>& v) {
|
||||||
return scale(xyz.x, xyz.y, xyz.z);
|
return m * scale(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// look_at
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
constexpr mat<T, 4> look_at_lh(const vec<T, 3>& eye, const vec<T, 3>& at, const vec<T, 3>& up) {
|
||||||
|
const vec<T, 3> az = normalize(at - eye);
|
||||||
|
const vec<T, 3> ax = normalize(cross(up, az));
|
||||||
|
const vec<T, 3> 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 >
|
template < typename T >
|
||||||
constexpr mat<T, 4> scale(const mat<T, 4>& m, T x, T y, T z) {
|
constexpr mat<T, 4> look_at_rh(const vec<T, 3>& eye, const vec<T, 3>& at, const vec<T, 3>& up) {
|
||||||
return m * scale(x, y, z);
|
const vec<T, 3> az = normalize(eye - at);
|
||||||
}
|
const vec<T, 3> ax = normalize(cross(up, az));
|
||||||
|
const vec<T, 3> ay = cross(az, ax);
|
||||||
template < typename T >
|
const T dx = dot(ax, eye);
|
||||||
constexpr mat<T, 4> scale(const mat<T, 4>& m, const vec<T, 3>& xyz) {
|
const T dy = dot(ay, eye);
|
||||||
return m * scale(xyz);
|
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};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,30 +108,32 @@ TEST_CASE("vmath/ext") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("matrix translate") {
|
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(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(float3{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(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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("matrix rotate") {
|
SECTION("matrix rotate") {
|
||||||
constexpr float pi = radians(180.f);
|
constexpr float pi = radians(180.f);
|
||||||
constexpr float pi_2 = radians(90.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(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,{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,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") {
|
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(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(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(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}), 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") {
|
SECTION("vector angle") {
|
||||||
|
|||||||
@@ -88,23 +88,23 @@ TEST_CASE("vmath/mat_fun") {
|
|||||||
|
|
||||||
{
|
{
|
||||||
float4 v{0.f, 0.f, 0.f, 1.f};
|
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));
|
REQUIRE(v == approx4(1.f,2.f,3.f,1.f));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
float3 v{1.f, 2.f, 3.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));
|
REQUIRE(v == approx3(2.f,6.f,12.f));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
float4x4 v = translate(1.f, 2.f, 3.f);
|
float4x4 v = translate(float3{1.f, 2.f, 3.f});
|
||||||
REQUIRE(&v == &(v *= translate(1.f,2.f,3.f)));
|
REQUIRE(&v == &(v *= translate(float3{1.f,2.f,3.f})));
|
||||||
REQUIRE(v == approx4x4(translate(2.f,4.f,6.f)));
|
REQUIRE(v == approx4x4(translate(float3{2.f,4.f,6.f})));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
float3x3 v = float3x3(scale(1.f, 2.f, 3.f));
|
float3x3 v = float3x3(scale(float3{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 == approx3x3(float3x3(scale(2.f,6.f,12.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(float3x3(0.5)) == float3x3(2.f));
|
||||||
STATIC_REQUIRE(inverse(float4x4(0.5)) == float4x4(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(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})))));
|
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})))));
|
||||||
|
|||||||
Reference in New Issue
Block a user