ext funcs non-arithmetic T support

This commit is contained in:
BlackMATov
2021-02-21 01:09:25 +07:00
parent 347c721a7f
commit 8e971073af
5 changed files with 205 additions and 166 deletions

View File

@@ -1556,6 +1556,8 @@ template < typename T > inline constexpr mat<T, 4> unit4x4;
template < typename T > inline constexpr mat<T, 2> identity2x2; template < typename T > inline constexpr mat<T, 2> identity2x2;
template < typename T > inline constexpr mat<T, 3> identity3x3; template < typename T > inline constexpr mat<T, 3> identity3x3;
template < typename T > inline constexpr mat<T, 4> identity4x4; template < typename T > inline constexpr mat<T, 4> identity4x4;
template < typename T > inline constexpr qua<T> qidentity;
``` ```
### Cast ### Cast

View File

@@ -19,37 +19,72 @@
namespace vmath_hpp namespace vmath_hpp
{ {
template < typename T > inline constexpr vec<T, 2> zero2{0, 0}; template < typename T > inline constexpr vec<T, 2> zero2{T{0}, T{0}};
template < typename T > inline constexpr vec<T, 3> zero3{0, 0, 0}; template < typename T > inline constexpr vec<T, 3> zero3{T{0}, T{0}, T{0}};
template < typename T > inline constexpr vec<T, 4> zero4{0, 0, 0, 0}; template < typename T > inline constexpr vec<T, 4> zero4{T{0}, T{0}, T{0}, T{0}};
template < typename T > inline constexpr vec<T, 2> unit2{1, 1}; template < typename T > inline constexpr vec<T, 2> unit2{T{1}, T{1}};
template < typename T > inline constexpr vec<T, 3> unit3{1, 1, 1}; template < typename T > inline constexpr vec<T, 3> unit3{T{1}, T{1}, T{1}};
template < typename T > inline constexpr vec<T, 4> unit4{1, 1, 1, 1}; template < typename T > inline constexpr vec<T, 4> unit4{T{1}, T{1}, T{1}, T{1}};
template < typename T > inline constexpr vec<T, 2> unit2_x{1, 0}; template < typename T > inline constexpr vec<T, 2> unit2_x{T{1}, T{0}};
template < typename T > inline constexpr vec<T, 2> unit2_y{0, 1}; template < typename T > inline constexpr vec<T, 2> unit2_y{T{0}, T{1}};
template < typename T > inline constexpr vec<T, 3> unit3_x{1, 0, 0}; template < typename T > inline constexpr vec<T, 3> unit3_x{T{1}, T{0}, T{0}};
template < typename T > inline constexpr vec<T, 3> unit3_y{0, 1, 0}; template < typename T > inline constexpr vec<T, 3> unit3_y{T{0}, T{1}, T{0}};
template < typename T > inline constexpr vec<T, 3> unit3_z{0, 0, 1}; template < typename T > inline constexpr vec<T, 3> unit3_z{T{0}, T{0}, T{1}};
template < typename T > inline constexpr vec<T, 4> unit4_x{1, 0, 0, 0}; template < typename T > inline constexpr vec<T, 4> unit4_x{T{1}, T{0}, T{0}, T{0}};
template < typename T > inline constexpr vec<T, 4> unit4_y{0, 1, 0, 0}; template < typename T > inline constexpr vec<T, 4> unit4_y{T{0}, T{1}, T{0}, T{0}};
template < typename T > inline constexpr vec<T, 4> unit4_z{0, 0, 1, 0}; template < typename T > inline constexpr vec<T, 4> unit4_z{T{0}, T{0}, T{1}, T{0}};
template < typename T > inline constexpr vec<T, 4> unit4_w{0, 0, 0, 1}; template < typename T > inline constexpr vec<T, 4> unit4_w{T{0}, T{0}, T{0}, T{1}};
template < typename T > inline constexpr mat<T, 2> zero2x2{0, 0, 0, 0}; template < typename T > inline constexpr mat<T, 2> zero2x2{
template < typename T > inline constexpr mat<T, 3> zero3x3{0, 0, 0, 0, 0, 0, 0, 0, 0}; T{0}, T{0},
template < typename T > inline constexpr mat<T, 4> zero4x4{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; T{0}, T{0}};
template < typename T > inline constexpr mat<T, 2> unit2x2{1, 1, 1, 1}; template < typename T > inline constexpr mat<T, 3> zero3x3{
template < typename T > inline constexpr mat<T, 3> unit3x3{1, 1, 1, 1, 1, 1, 1, 1, 1}; T{0}, T{0}, T{0},
template < typename T > inline constexpr mat<T, 4> unit4x4{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; T{0}, T{0}, T{0},
T{0}, T{0}, T{0}};
template < typename T > inline constexpr mat<T, 2> identity2x2{1, 0, 0, 1}; template < typename T > inline constexpr mat<T, 4> zero4x4{
template < typename T > inline constexpr mat<T, 3> identity3x3{1, 0, 0, 0, 1, 0, 0, 0, 1}; T{0}, T{0}, T{0}, T{0},
template < typename T > inline constexpr mat<T, 4> identity4x4{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; T{0}, T{0}, T{0}, T{0},
T{0}, T{0}, T{0}, T{0},
T{0}, T{0}, T{0}, T{0}};
template < typename T > inline constexpr mat<T, 2> unit2x2{
T{1}, T{1},
T{1}, T{1}};
template < typename T > inline constexpr mat<T, 3> unit3x3{
T{1}, T{1}, T{1},
T{1}, T{1}, T{1},
T{1}, T{1}, T{1}};
template < typename T > inline constexpr mat<T, 4> unit4x4{
T{1}, T{1}, T{1}, T{1},
T{1}, T{1}, T{1}, T{1},
T{1}, T{1}, T{1}, T{1},
T{1}, T{1}, T{1}, T{1}};
template < typename T > inline constexpr mat<T, 2> identity2x2{
T{1}, T{0},
T{0}, T{1}};
template < typename T > inline constexpr mat<T, 3> identity3x3{
T{1}, T{0}, T{0},
T{0}, T{1}, T{0},
T{0}, T{0}, T{1}};
template < typename T > inline constexpr mat<T, 4> identity4x4{
T{1}, T{0}, T{0}, T{0},
T{0}, T{1}, T{0}, T{0},
T{0}, T{0}, T{1}, T{0},
T{0}, T{0}, T{0}, T{1}};
template < typename T > inline constexpr qua<T> qidentity{T{0}, T{0}, T{0}, T{1}};
} }
// //
@@ -235,10 +270,10 @@ namespace vmath_hpp
/// https://en.wikipedia.org/wiki/Translation_(geometry) /// https://en.wikipedia.org/wiki/Translation_(geometry)
return { return {
{1, 0, 0, 0}, {T{1}, T{0}, T{0}, T{0}},
{0, 1, 0, 0}, {T{0}, T{1}, T{0}, T{0}},
{0, 0, 1, 0}, {T{0}, T{0}, T{1}, T{0}},
{x, y, z, 1}}; { x, y, z, T{1}}};
} }
template < typename T > template < typename T >
@@ -265,9 +300,9 @@ namespace vmath_hpp
const auto [qv, qs] = normalize(q); const auto [qv, qs] = normalize(q);
const T x2 = qv.x * T(2); const T x2 = qv.x * T{2};
const T y2 = qv.y * T(2); const T y2 = qv.y * T{2};
const T z2 = qv.z * T(2); const T z2 = qv.z * T{2};
const T sx2 = qs * x2; const T sx2 = qs * x2;
const T sy2 = qs * y2; const T sy2 = qs * y2;
@@ -282,10 +317,10 @@ namespace vmath_hpp
const T zz2 = qv.z * z2; const T zz2 = qv.z * z2;
return { return {
T(1) - (yy2 + zz2), (xy2 + sz2), (xz2 - sy2), 0, T{1} - (yy2 + zz2), (xy2 + sz2), (xz2 - sy2), T{0},
(xy2 - sz2), T(1) - (xx2 + zz2), (yz2 + sx2), 0, (xy2 - sz2), T{1} - (xx2 + zz2), (yz2 + sx2), T{0},
(xz2 + sy2), (yz2 - sx2), T(1) - (xx2 + yy2), 0, (xz2 + sy2), (yz2 - sx2), T{1} - (xx2 + yy2), T{0},
0, 0, 0, 1}; T{0}, T{0}, T{0}, T{1}};
} }
template < typename T > template < typename T >
@@ -309,7 +344,7 @@ namespace vmath_hpp
const T ys = y * s; const T ys = y * s;
const T zs = z * s; const T zs = z * s;
const T ic = T(1) - c; const T ic = T{1} - c;
const T xxm = xx * ic; const T xxm = xx * ic;
const T yym = yy * ic; const T yym = yy * ic;
@@ -320,10 +355,10 @@ namespace vmath_hpp
const T yzm = y * z * ic; const T yzm = y * z * ic;
return { return {
xxm + c, xym + zs, xzm - ys, 0, xxm + c, xym + zs, xzm - ys, T{0},
xym - zs, yym + c, yzm + xs, 0, xym - zs, yym + c, yzm + xs, T{0},
xzm + ys, yzm - xs, zzm + c, 0, xzm + ys, yzm - xs, zzm + c, T{0},
0, 0, 0, 1}; T{0}, T{0}, T{0}, T{1}};
} }
template < typename T > template < typename T >
@@ -339,10 +374,10 @@ namespace vmath_hpp
const auto [s, c] = sincos(angle); const auto [s, c] = sincos(angle);
return { return {
1, 0, 0, 0, T{1}, T{0}, T{0}, T{0},
0, c, s, 0, T{0}, c, s, T{0},
0, -s, c, 0, T{0}, -s, c, T{0},
0, 0, 0, 1}; T{0}, T{0}, T{0}, T{1}};
} }
template < typename T > template < typename T >
@@ -358,10 +393,10 @@ namespace vmath_hpp
const auto [s, c] = sincos(angle); const auto [s, c] = sincos(angle);
return { return {
c, 0, -s, 0, c, T{0}, -s, T{0},
0, 1, 0, 0, T{0}, T{1}, T{0}, T{0},
s, 0, c, 0, s, T{0}, c, T{0},
0, 0, 0, 1}; T{0}, T{0}, T{0}, T{1}};
} }
template < typename T > template < typename T >
@@ -377,10 +412,10 @@ namespace vmath_hpp
const auto [s, c] = sincos(angle); const auto [s, c] = sincos(angle);
return { return {
c, s, 0, 0, c, s, T{0}, T{0},
-s, c, 0, 0, -s, c, T{0}, T{0},
0, 0, 1, 0, T{0}, T{0}, T{1}, T{0},
0, 0, 0, 1}; T{0}, T{0}, T{0}, T{1}};
} }
template < typename T > template < typename T >
@@ -396,10 +431,10 @@ namespace vmath_hpp
/// https://en.wikipedia.org/wiki/Scaling_(geometry) /// https://en.wikipedia.org/wiki/Scaling_(geometry)
return { return {
{x, 0, 0, 0}, { x, T{0}, T{0}, T{0}},
{0, y, 0, 0}, {T{0}, y, T{0}, T{0}},
{0, 0, z, 0}, {T{0}, T{0}, z, T{0}},
{0, 0, 0, 1}}; {T{0}, T{0}, T{0}, T{1}}};
} }
template < typename T > template < typename T >
@@ -433,10 +468,10 @@ namespace vmath_hpp
const T dz = dot(az, eye); const T dz = dot(az, eye);
return { return {
ax.x, ay.x, az.x, 0, ax.x, ay.x, az.x, T{0},
ax.y, ay.y, az.y, 0, ax.y, ay.y, az.y, T{0},
ax.z, ay.z, az.z, 0, ax.z, ay.z, az.z, T{0},
-dx, -dy, -dz, 1}; -dx, -dy, -dz, T{1}};
} }
template < typename T > template < typename T >
@@ -453,10 +488,10 @@ namespace vmath_hpp
const T dz = dot(az, eye); const T dz = dot(az, eye);
return { return {
ax.x, ay.x, az.x, 0, ax.x, ay.x, az.x, T{0},
ax.y, ay.y, az.y, 0, ax.y, ay.y, az.y, T{0},
ax.z, ay.z, az.z, 0, ax.z, ay.z, az.z, T{0},
-dx, -dy, -dz, 1}; -dx, -dy, -dz, T{1}};
} }
} }
@@ -474,9 +509,9 @@ namespace vmath_hpp
/// https://en.wikipedia.org/wiki/Translation_(geometry) /// https://en.wikipedia.org/wiki/Translation_(geometry)
return { return {
{1, 0, 0}, {T{1}, T{0}, T{0}},
{0, 1, 0}, {T{0}, T{1}, T{0}},
{x, y, 1}}; { x, y, T{1}}};
} }
template < typename T > template < typename T >
@@ -504,9 +539,9 @@ namespace vmath_hpp
const auto [s, c] = sincos(angle); const auto [s, c] = sincos(angle);
return { return {
c, s, 0, c, s, T{0},
-s, c, 0, -s, c, T{0},
0, 0, 1}; T{0}, T{0}, T{1}};
} }
template < typename T > template < typename T >
@@ -522,9 +557,9 @@ namespace vmath_hpp
/// https://en.wikipedia.org/wiki/Scaling_(geometry) /// https://en.wikipedia.org/wiki/Scaling_(geometry)
return { return {
{x, 0, 0}, { x, T{0}, T{0}},
{0, y, 0}, {T{0}, y, T{0}},
{0, 0, 1}}; {T{0}, T{0}, T{1}}};
} }
template < typename T > template < typename T >
@@ -550,9 +585,9 @@ namespace vmath_hpp
/// https://en.wikipedia.org/wiki/Shear_matrix /// https://en.wikipedia.org/wiki/Shear_matrix
return { return {
{1, y, 0}, {T{1}, y, T{0}},
{x, 1, 0}, { x, T{1}, T{0}},
{0, 0, 1}}; {T{0}, T{0}, T{1}}};
} }
template < typename T > template < typename T >
@@ -576,9 +611,9 @@ namespace vmath_hpp
/// https://en.wikipedia.org/wiki/Shear_matrix /// https://en.wikipedia.org/wiki/Shear_matrix
return { return {
{1, 0, 0}, {T{1}, T{0}, T{0}},
{x, 1, 0}, { x, T{1}, T{0}},
{0, 0, 1}}; {T{0}, T{0}, T{1}}};
} }
template < typename T > template < typename T >
@@ -592,9 +627,9 @@ namespace vmath_hpp
/// https://en.wikipedia.org/wiki/Shear_matrix /// https://en.wikipedia.org/wiki/Shear_matrix
return { return {
{1, y, 0}, {T{1}, y, T{0}},
{0, 1, 0}, {T{0}, T{1}, T{0}},
{0, 0, 1}}; {T{0}, T{0}, T{1}}};
} }
template < typename T > template < typename T >
@@ -620,16 +655,16 @@ namespace vmath_hpp
const T rheight = rcp(height); const T rheight = rcp(height);
const T frange = rcp(zfar - znear); const T frange = rcp(zfar - znear);
const T sx = T(2) * rwidth; const T sx = T{2} * rwidth;
const T sy = T(2) * rheight; const T sy = T{2} * rheight;
const T sz = frange; const T sz = frange;
const T tz = -frange * znear; const T tz = -frange * znear;
return { return {
sx, 0, 0, 0, sx, T{0}, T{0}, T{0},
0, sy, 0, 0, T{0}, sy, T{0}, T{0},
0, 0, sz, 0, T{0}, T{0}, sz, T{0},
0, 0, tz, 1}; T{0}, T{0}, tz, T{1}};
} }
template < typename T > template < typename T >
@@ -641,16 +676,16 @@ namespace vmath_hpp
const T rheight = rcp(height); const T rheight = rcp(height);
const T frange = rcp(znear - zfar); const T frange = rcp(znear - zfar);
const T sx = T(2) * rwidth; const T sx = T{2} * rwidth;
const T sy = T(2) * rheight; const T sy = T{2} * rheight;
const T sz = frange; const T sz = frange;
const T tz = frange * znear; const T tz = frange * znear;
return { return {
sx, 0, 0, 0, sx, T{0}, T{0}, T{0},
0, sy, 0, 0, T{0}, sy, T{0}, T{0},
0, 0, sz, 0, T{0}, T{0}, sz, T{0},
0, 0, tz, 1}; T{0}, T{0}, tz, T{1}};
} }
template < typename T > template < typename T >
@@ -663,10 +698,10 @@ namespace vmath_hpp
const T frange = rcp(zfar - znear); const T frange = rcp(zfar - znear);
return { return {
T(2) * rwidth, 0, 0, 0, T{2} * rwidth, T{0}, T{0}, T{0},
0, T(2) * rheight, 0, 0, T{0}, T{2} * rheight, T{0}, T{0},
0, 0, frange, 0, T{0}, T{0}, frange, T{0},
-(left + right) * rwidth, -(top + bottom) * rheight, -frange * znear, 1}; -(left + right) * rwidth, -(top + bottom) * rheight, -frange * znear, T{1}};
} }
template < typename T > template < typename T >
@@ -679,10 +714,10 @@ namespace vmath_hpp
const T frange = rcp(znear - zfar); const T frange = rcp(znear - zfar);
return { return {
T(2) * rwidth, 0, 0, 0, T{2} * rwidth, T{0}, T{0}, T{0},
0, T(2) * rheight, 0, 0, T{0}, T{2} * rheight, T{0}, T{0},
0, 0, frange, 0, T{0}, T{0}, frange, T{0},
-(left + right) * rwidth, -(top + bottom) * rheight, frange * znear, 1}; -(left + right) * rwidth, -(top + bottom) * rheight, frange * znear, T{1}};
} }
// perspective // perspective
@@ -692,16 +727,16 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivelh /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivelh
const T sx = T(2) * znear * rcp(width); const T sx = T{2} * znear * rcp(width);
const T sy = T(2) * znear * rcp(height); const T sy = T{2} * znear * rcp(height);
const T sz = zfar * rcp(zfar - znear); const T sz = zfar * rcp(zfar - znear);
const T tz = (znear * zfar) * rcp(znear - zfar); const T tz = (znear * zfar) * rcp(znear - zfar);
return { return {
sx, 0, 0, 0, T{sx}, T{0}, T{0}, T{0},
0, sy, 0, 0, T{0}, T{sy}, T{0}, T{0},
0, 0, sz, 1, T{0}, T{0}, T{sz}, T{1},
0, 0, tz, 0}; T{0}, T{0}, T{tz}, T{0}};
} }
template < typename T > template < typename T >
@@ -709,16 +744,16 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiverh /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiverh
const T sx = T(2) * znear * rcp(width); const T sx = T{2} * znear * rcp(width);
const T sy = T(2) * znear * rcp(height); const T sy = T{2} * znear * rcp(height);
const T sz = zfar * rcp(znear - zfar); const T sz = zfar * rcp(znear - zfar);
const T tz = (znear * zfar) * rcp(znear - zfar); const T tz = (znear * zfar) * rcp(znear - zfar);
return { return {
sx, 0, 0, 0, sx, T{0}, T{0}, T{0},
0, sy, 0, 0, T{0}, sy, T{0}, T{0},
0, 0, sz, -1, T{0}, T{0}, sz, -T{1},
0, 0, tz, 0}; T{0}, T{0}, tz, T{0}};
} }
template < typename T > template < typename T >
@@ -726,16 +761,16 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiveoffcenterlh /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiveoffcenterlh
const T znear2 = T(2) * znear; const T znear2 = T{2} * znear;
const T rwidth = rcp(right - left); const T rwidth = rcp(right - left);
const T rheight = rcp(top - bottom); const T rheight = rcp(top - bottom);
const T frange = zfar * rcp(zfar - znear); const T frange = zfar * rcp(zfar - znear);
return { return {
znear2 * rwidth, 0, 0, 0, znear2 * rwidth, T{0}, T{0}, T{0},
0, znear2 * rheight, 0, 0, T{0}, znear2 * rheight, T{0}, T{0},
-(left + right) * rwidth, -(top + bottom) * rheight, frange, 1, -(left + right) * rwidth, -(top + bottom) * rheight, frange, T{1},
0, 0, -frange * znear, 0}; T{0}, T{0}, -frange * znear, T{0}};
} }
template < typename T > template < typename T >
@@ -743,16 +778,16 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiveoffcenterrh /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiveoffcenterrh
const T znear2 = T(2) * znear; const T znear2 = T{2} * znear;
const T rwidth = rcp(right - left); const T rwidth = rcp(right - left);
const T rheight = rcp(top - bottom); const T rheight = rcp(top - bottom);
const T frange = zfar * rcp(znear - zfar); const T frange = zfar * rcp(znear - zfar);
return { return {
znear2 * rwidth, 0, 0, 0, znear2 * rwidth, T{0}, T{0}, T{0},
0, znear2 * rheight, 0, 0, T{0}, znear2 * rheight, T{0}, T{0},
(left + right) * rwidth, (top + bottom) * rheight, frange, -1, (left + right) * rwidth, (top + bottom) * rheight, frange, -T{1},
0, 0, frange * znear, 0}; T{0}, T{0}, frange * znear, T{0}};
} }
template < typename T > template < typename T >
@@ -760,16 +795,16 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovlh /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovlh
const T sy = rcp(tan(fovy * T(0.5))); const T sy = rcp(tan(fovy * T{0.5}));
const T sx = sy * rcp(aspect); const T sx = sy * rcp(aspect);
const T sz = zfar * rcp(zfar - znear); const T sz = zfar * rcp(zfar - znear);
const T tz = (znear * zfar) * rcp(znear - zfar); const T tz = (znear * zfar) * rcp(znear - zfar);
return { return {
sx, 0, 0, 0, sx, T{0}, T{0}, T{0},
0, sy, 0, 0, T{0}, sy, T{0}, T{0},
0, 0, sz, 1, T{0}, T{0}, sz, T{1},
0, 0, tz, 0}; T{0}, T{0}, tz, T{0}};
} }
template < typename T > template < typename T >
@@ -777,15 +812,15 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh
const T sy = rcp(tan(fovy * T(0.5))); const T sy = rcp(tan(fovy * T{0.5}));
const T sx = sy * rcp(aspect); const T sx = sy * rcp(aspect);
const T sz = zfar * rcp(znear - zfar); const T sz = zfar * rcp(znear - zfar);
const T tz = (znear * zfar) * rcp(znear - zfar); const T tz = (znear * zfar) * rcp(znear - zfar);
return { return {
sx, 0, 0, 0, sx, T{0}, T{0}, T{0},
0, sy, 0, 0, T{0}, sy, T{0}, T{0},
0, 0, sz, -1, T{0}, T{0}, sz, -T{1},
0, 0, tz, 0}; T{0}, T{0}, tz, T{0}};
} }
} }
@@ -800,7 +835,7 @@ namespace vmath_hpp
template < typename T, std::size_t Size > template < typename T, std::size_t Size >
[[nodiscard]] T angle(const vec<T, Size>& x, const vec<T, Size>& y) { [[nodiscard]] T angle(const vec<T, Size>& x, const vec<T, Size>& y) {
const T rs = rsqrt(length2(x) * length2(y)); const T rs = rsqrt(length2(x) * length2(y));
return acos(clamp(dot(x, y) * rs, T(-1), T(1))); return acos(clamp(dot(x, y) * rs, -T{1}, T{1}));
} }
// rotate // rotate
@@ -866,17 +901,17 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
auto xyzw = T(0.5) * sqrt(max(T(0), vec{ auto xyzw = T{0.5} * sqrt(max(T{0}, vec{
T(1) + m[0][0] - m[1][1] - m[2][2], T{1} + m[0][0] - m[1][1] - m[2][2],
T(1) - m[0][0] + m[1][1] - m[2][2], T{1} - m[0][0] + m[1][1] - m[2][2],
T(1) - m[0][0] - m[1][1] + m[2][2], T{1} - m[0][0] - m[1][1] + m[2][2],
T(1) + m[0][0] + m[1][1] + m[2][2]})); T{1} + m[0][0] + m[1][1] + m[2][2]}));
return qua(copysign(xyzw, { return qua(copysign(xyzw, {
m[1][2] - m[2][1], m[1][2] - m[2][1],
m[2][0] - m[0][2], m[2][0] - m[0][2],
m[0][1] - m[1][0], m[0][1] - m[1][0],
T(1)})); T{1}}));
} }
template < typename T > template < typename T >
@@ -892,10 +927,10 @@ namespace vmath_hpp
const T n = sqrt(length2(from) * length2(to)); const T n = sqrt(length2(from) * length2(to));
const T s = dot(from, to) + n; const T s = dot(from, to) + n;
if ( s < T(0.000001) * n ) { if ( s < T{0.000001} * n ) {
return abs(from.x) > abs(from.z) return abs(from.z) < abs(from.x)
? normalize(qua{vec{-from.y, from.x, T(0)}, T(0)}) ? normalize(qua{vec{-from.y, from.x, T{0}}, T{0}})
: normalize(qua{vec{T(0), -from.z, from.y}, T(0)}); : normalize(qua{vec{T{0}, -from.z, from.y}, T{0}});
} }
return normalize(qua{cross(from, to), s}); return normalize(qua{cross(from, to), s});
@@ -911,10 +946,10 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/
const auto [s, c] = sincos(angle * T(0.5)); const auto [s, c] = sincos(angle * T{0.5});
const auto [x, y, z] = normalize(axis); const auto [x, y, z] = normalize(axis);
return {vec{x,y,z} * s, c}; return {vec{x, y, z} * s, c};
} }
template < typename T > template < typename T >
@@ -927,9 +962,9 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/
const auto [s, c] = sincos(angle * T(0.5)); const auto [s, c] = sincos(angle * T{0.5});
return {s, T(0), T(0), c}; return {vec{s, T{0}, T{0}}, c};
} }
template < typename T > template < typename T >
@@ -942,9 +977,9 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/
const auto [s, c] = sincos(angle * T(0.5)); const auto [s, c] = sincos(angle * T{0.5});
return {T(0), s, T(0), c}; return {vec{T{0}, s, T{0}}, c};
} }
template < typename T > template < typename T >
@@ -957,9 +992,9 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/
const auto [s, c] = sincos(angle * T(0.5)); const auto [s, c] = sincos(angle * T{0.5});
return {T(0), T(0), s, c}; return {vec{T{0}, T{0}, s}, c};
} }
template < typename T > template < typename T >

View File

@@ -17,7 +17,7 @@ namespace vmath_hpp
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_signed_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_signed_v<T>, T>
constexpr abs(T x) noexcept { constexpr abs(T x) noexcept {
return x >= T(0) ? x : -x; return x < T{0} ? -x : x;
} }
template < typename T > template < typename T >
@@ -35,13 +35,13 @@ namespace vmath_hpp
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
constexpr sign(T x) noexcept { constexpr sign(T x) noexcept {
return static_cast<T>((T(0) < x) - (x < T(0))); return static_cast<T>((T{0} < x) - (x < T{0}));
} }
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
constexpr rcp(T x) noexcept { constexpr rcp(T x) noexcept {
return T(1) / x; return T{1} / x;
} }
template < typename T > template < typename T >
@@ -107,13 +107,13 @@ namespace vmath_hpp
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
constexpr saturate(T x) noexcept { constexpr saturate(T x) noexcept {
return clamp(x, T(0), T(1)); return clamp(x, T{0}, T{1});
} }
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
constexpr lerp(T x, T y, T a) noexcept { constexpr lerp(T x, T y, T a) noexcept {
return x * (T(1) - a) + y * a; return x * (T{1} - a) + y * a;
} }
template < typename T > template < typename T >
@@ -125,14 +125,14 @@ namespace vmath_hpp
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
constexpr step(T edge, T x) noexcept { constexpr step(T edge, T x) noexcept {
return x < edge ? T(0) : T(1); return x < edge ? T{0} : T{1};
} }
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
constexpr smoothstep(T edge0, T edge1, T x) noexcept { constexpr smoothstep(T edge0, T edge1, T x) noexcept {
const T t = clamp((x - edge0) * rcp(edge1 - edge0), T(0), T(1)); const T t = clamp((x - edge0) * rcp(edge1 - edge0), T{0}, T{1});
return t * t * (T(3) - T(2) * t); return t * t * (T{3} - T{2} * t);
} }
template < typename T > template < typename T >
@@ -151,13 +151,13 @@ namespace vmath_hpp
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
constexpr radians(T degrees) noexcept { constexpr radians(T degrees) noexcept {
return degrees * T(0.01745329251994329576923690768489); return degrees * T{0.01745329251994329576923690768489};
} }
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
constexpr degrees(T radians) noexcept { constexpr degrees(T radians) noexcept {
return radians * T(57.295779513082320876798154814105); return radians * T{57.295779513082320876798154814105};
} }
template < typename T > template < typename T >
@@ -369,7 +369,7 @@ namespace vmath_hpp
/// REFERENCE: /// REFERENCE:
/// http://www.realtimecollisiondetection.net/pubs/Tolerances /// http://www.realtimecollisiondetection.net/pubs/Tolerances
const T epsilon = std::numeric_limits<T>::epsilon(); const T epsilon = std::numeric_limits<T>::epsilon();
return abs(x - y) <= epsilon * max(max(T(1), abs(x)), abs(y)); return abs(x - y) <= epsilon * max(max(T{1}, abs(x)), abs(y));
} else { } else {
return x == y; return x == y;
} }
@@ -381,7 +381,7 @@ namespace vmath_hpp
if constexpr ( std::is_floating_point_v<T> ) { if constexpr ( std::is_floating_point_v<T> ) {
/// REFERENCE: /// REFERENCE:
/// http://www.realtimecollisiondetection.net/pubs/Tolerances /// http://www.realtimecollisiondetection.net/pubs/Tolerances
return abs(x - y) <= epsilon * max(max(T(1), abs(x)), abs(y)); return abs(x - y) <= epsilon * max(max(T{1}, abs(x)), abs(y));
} else { } else {
return abs(x - y) <= epsilon; return abs(x - y) <= epsilon;
} }

View File

@@ -52,6 +52,8 @@ TEST_CASE("vmath/ext/units") {
STATIC_CHECK(identity2x2<int> == int2x2()); STATIC_CHECK(identity2x2<int> == int2x2());
STATIC_CHECK(identity3x3<int> == int3x3()); STATIC_CHECK(identity3x3<int> == int3x3());
STATIC_CHECK(identity4x4<int> == int4x4()); STATIC_CHECK(identity4x4<int> == int4x4());
STATIC_CHECK(qidentity<float> == qfloat());
} }
TEST_CASE("vmath/ext/hash") { TEST_CASE("vmath/ext/hash") {

View File

@@ -13,7 +13,7 @@ namespace vmath_tests
template < typename T > template < typename T >
struct uapprox_base { struct uapprox_base {
T epsilon = T(10) * std::numeric_limits<T>::epsilon(); T epsilon = T{10} * std::numeric_limits<T>::epsilon();
}; };
template < typename T > template < typename T >