mirror of
https://github.com/BlackMATov/vmath.hpp.git
synced 2025-12-15 04:35:25 +07:00
normalize axis in rotate function, little style fixes
This commit is contained in:
@@ -213,26 +213,27 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> rotate(T angle, const vec<T, 3>& axis) {
|
[[nodiscard]] mat<T, 4> rotate(T angle, const vec<T, 3>& axis) {
|
||||||
const T x = axis.x;
|
const auto [s, c] = sincos(angle);
|
||||||
const T y = axis.y;
|
const auto [x, y, z] = normalize(axis);
|
||||||
const T z = axis.z;
|
|
||||||
const T px = x * x;
|
const T xx = x * x;
|
||||||
const T py = y * y;
|
const T yy = y * y;
|
||||||
const T pz = z * z;
|
const T zz = z * z;
|
||||||
const T cs = cos(angle);
|
|
||||||
const T sn = sin(angle);
|
const T xs = x * s;
|
||||||
const T ics = T(1) - cs;
|
const T ys = y * s;
|
||||||
const T xym = x * y * ics;
|
const T zs = z * s;
|
||||||
const T xzm = x * z * ics;
|
|
||||||
const T yzm = y * z * ics;
|
const T ic = T(1) - c;
|
||||||
const T xsn = x * sn;
|
const T xym = x * y * ic;
|
||||||
const T ysn = y * sn;
|
const T xzm = x * z * ic;
|
||||||
const T zsn = z * sn;
|
const T yzm = y * z * ic;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
px * ics + cs, xym + zsn, xzm - ysn, 0,
|
xx * ic + c, xym + zs, xzm - ys, 0,
|
||||||
xym - zsn, py * ics + cs, yzm + xsn, 0,
|
xym - zs, yy * ic + c, yzm + xs, 0,
|
||||||
xzm + ysn, yzm - xsn, pz * ics + cs, 0,
|
xzm + ys, yzm - xs, zz * ic + c, 0,
|
||||||
0, 0, 0, 1};
|
0, 0, 0, 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -242,13 +243,12 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> rotate_x(T angle) {
|
[[nodiscard]] mat<T, 4> rotate_x(T angle) {
|
||||||
const T cs = cos(angle);
|
const auto [s, c] = sincos(angle);
|
||||||
const T sn = sin(angle);
|
|
||||||
return {
|
return {
|
||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
0, cs, sn, 0,
|
0, c, s, 0,
|
||||||
0, -sn, cs, 0,
|
0, -s, c, 0,
|
||||||
0, 0, 0, 1};
|
0, 0, 0, 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -258,13 +258,12 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> rotate_y(T angle) {
|
[[nodiscard]] mat<T, 4> rotate_y(T angle) {
|
||||||
const T cs = cos(angle);
|
const auto [s, c] = sincos(angle);
|
||||||
const T sn = sin(angle);
|
|
||||||
return {
|
return {
|
||||||
cs, 0, -sn, 0,
|
c, 0, -s, 0,
|
||||||
0, 1, 0, 0,
|
0, 1, 0, 0,
|
||||||
sn, 0, cs, 0,
|
s, 0, c, 0,
|
||||||
0, 0, 0, 1};
|
0, 0, 0, 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -274,13 +273,12 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> rotate_z(T angle) {
|
[[nodiscard]] mat<T, 4> rotate_z(T angle) {
|
||||||
const T cs = cos(angle);
|
const auto [s, c] = sincos(angle);
|
||||||
const T sn = sin(angle);
|
|
||||||
return {
|
return {
|
||||||
cs, sn, 0, 0,
|
c, s, 0, 0,
|
||||||
-sn, cs, 0, 0,
|
-s, c, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, 0, 1};
|
0, 0, 0, 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -321,9 +319,11 @@ namespace vmath_hpp
|
|||||||
const vec<T, 3> az = normalize(at - eye);
|
const vec<T, 3> az = normalize(at - eye);
|
||||||
const vec<T, 3> ax = normalize(cross(up, az));
|
const vec<T, 3> ax = normalize(cross(up, az));
|
||||||
const vec<T, 3> ay = cross(az, ax);
|
const vec<T, 3> ay = cross(az, ax);
|
||||||
|
|
||||||
const T dx = dot(ax, eye);
|
const T dx = dot(ax, eye);
|
||||||
const T dy = dot(ay, eye);
|
const T dy = dot(ay, eye);
|
||||||
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, 0,
|
||||||
ax.y, ay.y, az.y, 0,
|
ax.y, ay.y, az.y, 0,
|
||||||
@@ -336,9 +336,11 @@ namespace vmath_hpp
|
|||||||
const vec<T, 3> az = normalize(eye - at);
|
const vec<T, 3> az = normalize(eye - at);
|
||||||
const vec<T, 3> ax = normalize(cross(up, az));
|
const vec<T, 3> ax = normalize(cross(up, az));
|
||||||
const vec<T, 3> ay = cross(az, ax);
|
const vec<T, 3> ay = cross(az, ax);
|
||||||
|
|
||||||
const T dx = dot(ax, eye);
|
const T dx = dot(ax, eye);
|
||||||
const T dy = dot(ay, eye);
|
const T dy = dot(ay, eye);
|
||||||
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, 0,
|
||||||
ax.y, ay.y, az.y, 0,
|
ax.y, ay.y, az.y, 0,
|
||||||
@@ -382,12 +384,11 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 3> rotate(T angle) {
|
[[nodiscard]] mat<T, 3> rotate(T angle) {
|
||||||
const T cs = cos(angle);
|
const auto [s, c] = sincos(angle);
|
||||||
const T sn = sin(angle);
|
|
||||||
return {
|
return {
|
||||||
cs, sn, 0,
|
c, s, 0,
|
||||||
-sn, cs, 0,
|
-s, c, 0,
|
||||||
0, 0, 1};
|
0, 0, 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -482,9 +483,9 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> orthographic_lh_zo(T left, T right, T bottom, T top, T znear, T zfar) {
|
[[nodiscard]] mat<T, 4> orthographic_lh_zo(T left, T right, T bottom, T top, T znear, T zfar) {
|
||||||
const T sx = T(2) / (right - left);
|
const T sx = T(2) * reciprocal(right - left);
|
||||||
const T sy = T(2) / (top - bottom);
|
const T sy = T(2) * reciprocal(top - bottom);
|
||||||
const T sz = T(1) / (zfar - znear);
|
const T sz = T(1) * reciprocal(zfar - znear);
|
||||||
|
|
||||||
const T tx = - (right + left) / (right - left);
|
const T tx = - (right + left) / (right - left);
|
||||||
const T ty = - (top + bottom) / (top - bottom);
|
const T ty = - (top + bottom) / (top - bottom);
|
||||||
@@ -499,9 +500,9 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> orthographic_lh_no(T left, T right, T bottom, T top, T znear, T zfar) {
|
[[nodiscard]] mat<T, 4> orthographic_lh_no(T left, T right, T bottom, T top, T znear, T zfar) {
|
||||||
const T sx = T(2) / (right - left);
|
const T sx = T(2) * reciprocal(right - left);
|
||||||
const T sy = T(2) / (top - bottom);
|
const T sy = T(2) * reciprocal(top - bottom);
|
||||||
const T sz = T(2) / (zfar - znear);
|
const T sz = T(2) * reciprocal(zfar - znear);
|
||||||
|
|
||||||
const T tx = - (right + left) / (right - left);
|
const T tx = - (right + left) / (right - left);
|
||||||
const T ty = - (top + bottom) / (top - bottom);
|
const T ty = - (top + bottom) / (top - bottom);
|
||||||
@@ -516,9 +517,9 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> orthographic_rh_zo(T left, T right, T bottom, T top, T znear, T zfar) {
|
[[nodiscard]] mat<T, 4> orthographic_rh_zo(T left, T right, T bottom, T top, T znear, T zfar) {
|
||||||
const T sx = T(2) / (right - left);
|
const T sx = T(2) * reciprocal(right - left);
|
||||||
const T sy = T(2) / (top - bottom);
|
const T sy = T(2) * reciprocal(top - bottom);
|
||||||
const T sz = -T(1) / (zfar - znear);
|
const T sz = -T(1) * reciprocal(zfar - znear);
|
||||||
|
|
||||||
const T tx = - (right + left) / (right - left);
|
const T tx = - (right + left) / (right - left);
|
||||||
const T ty = - (top + bottom) / (top - bottom);
|
const T ty = - (top + bottom) / (top - bottom);
|
||||||
@@ -533,9 +534,9 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> orthographic_rh_no(T left, T right, T bottom, T top, T znear, T zfar) {
|
[[nodiscard]] mat<T, 4> orthographic_rh_no(T left, T right, T bottom, T top, T znear, T zfar) {
|
||||||
const T sx = T(2) / (right - left);
|
const T sx = T(2) * reciprocal(right - left);
|
||||||
const T sy = T(2) / (top - bottom);
|
const T sy = T(2) * reciprocal(top - bottom);
|
||||||
const T sz = -T(2) / (zfar - znear);
|
const T sz = -T(2) * reciprocal(zfar - znear);
|
||||||
|
|
||||||
const T tx = - (right + left) / (right - left);
|
const T tx = - (right + left) / (right - left);
|
||||||
const T ty = - (top + bottom) / (top - bottom);
|
const T ty = - (top + bottom) / (top - bottom);
|
||||||
@@ -552,7 +553,7 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> perspective_lh_zo(T fov, T aspect, T znear, T zfar) {
|
[[nodiscard]] mat<T, 4> perspective_lh_zo(T fov, T aspect, T znear, T zfar) {
|
||||||
const T sy = T(1) / tan(fov * T(0.5));
|
const T sy = reciprocal(tan(fov * T(0.5)));
|
||||||
const T sx = sy / aspect;
|
const T sx = sy / aspect;
|
||||||
const T sz = zfar / (zfar - znear);
|
const T sz = zfar / (zfar - znear);
|
||||||
const T tz = (znear * zfar) / (znear - zfar);
|
const T tz = (znear * zfar) / (znear - zfar);
|
||||||
@@ -565,7 +566,7 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> perspective_lh_no(T fov, T aspect, T znear, T zfar) {
|
[[nodiscard]] mat<T, 4> perspective_lh_no(T fov, T aspect, T znear, T zfar) {
|
||||||
const T sy = T(1) / tan(fov * T(0.5));
|
const T sy = reciprocal(tan(fov * T(0.5)));
|
||||||
const T sx = sy / aspect;
|
const T sx = sy / aspect;
|
||||||
const T sz = (zfar + znear) / (zfar - znear);
|
const T sz = (zfar + znear) / (zfar - znear);
|
||||||
const T tz = (T(2) * znear * zfar) / (znear - zfar);
|
const T tz = (T(2) * znear * zfar) / (znear - zfar);
|
||||||
@@ -578,28 +579,28 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> perspective_rh_zo(T fov, T aspect, T znear, T zfar) {
|
[[nodiscard]] mat<T, 4> perspective_rh_zo(T fov, T aspect, T znear, T zfar) {
|
||||||
const T sy = T(1) / tan(fov * T(0.5));
|
const T sy = reciprocal(tan(fov * T(0.5)));
|
||||||
const T sx = sy / aspect;
|
const T sx = sy / aspect;
|
||||||
const T sz = zfar / (znear - zfar);
|
const T sz = zfar / (znear - zfar);
|
||||||
const T tz = (znear * zfar) / (znear - zfar);
|
const T tz = (znear * zfar) / (znear - zfar);
|
||||||
return {
|
return {
|
||||||
sx, 0, 0, 0,
|
sx, 0, 0, 0,
|
||||||
0, sy, 0, 0,
|
0, sy, 0, 0,
|
||||||
0, 0, sz, -1,
|
0, 0, sz, -1,
|
||||||
0, 0, tz, 0};
|
0, 0, tz, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] mat<T, 4> perspective_rh_no(T fov, T aspect, T znear, T zfar) {
|
[[nodiscard]] mat<T, 4> perspective_rh_no(T fov, T aspect, T znear, T zfar) {
|
||||||
const T sy = T(1) / tan(fov * T(0.5));
|
const T sy = reciprocal(tan(fov * T(0.5)));
|
||||||
const T sx = sy / aspect;
|
const T sx = sy / aspect;
|
||||||
const T sz = (zfar + znear) / (znear - zfar);
|
const T sz = (zfar + znear) / (znear - zfar);
|
||||||
const T tz = (T(2) * znear * zfar) / (znear - zfar);
|
const T tz = (T(2) * znear * zfar) / (znear - zfar);
|
||||||
return {
|
return {
|
||||||
sx, 0, 0, 0,
|
sx, 0, 0, 0,
|
||||||
0, sy, 0, 0,
|
0, sy, 0, 0,
|
||||||
0, 0, sz, -1,
|
0, 0, sz, -1,
|
||||||
0, 0, tz, 0};
|
0, 0, tz, 0};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,11 +621,10 @@ namespace vmath_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
[[nodiscard]] vec<T, 2> rotate(const vec<T, 2>& v, T angle) {
|
[[nodiscard]] vec<T, 2> rotate(const vec<T, 2>& v, T angle) {
|
||||||
const T cs = cos(angle);
|
const auto [s, c] = sincos(angle);
|
||||||
const T sn = sin(angle);
|
|
||||||
return {
|
return {
|
||||||
v.x * cs - v.y * sn,
|
v.x * c - v.y * s,
|
||||||
v.x * sn + v.y * cs};
|
v.x * s + v.y * c};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
|
|||||||
@@ -8,6 +8,158 @@
|
|||||||
|
|
||||||
#include "vmath_fwd.hpp"
|
#include "vmath_fwd.hpp"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common Functions
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace vmath_hpp
|
||||||
|
{
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_unsigned_v<T>, T>
|
||||||
|
constexpr abs(T x) noexcept {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_signed_v<T>, T>
|
||||||
|
constexpr abs(T x) noexcept {
|
||||||
|
return x >= T(0) ? x : -x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
||||||
|
constexpr sign(T x) noexcept {
|
||||||
|
return static_cast<T>((T(0) < x) - (x < T(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
constexpr reciprocal(T x) noexcept {
|
||||||
|
return T(1) / x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
floor(T x) noexcept {
|
||||||
|
return std::floor(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
trunc(T x) noexcept {
|
||||||
|
return std::trunc(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
round(T x) noexcept {
|
||||||
|
return std::round(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
ceil(T x) noexcept {
|
||||||
|
return std::ceil(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
fract(T x) noexcept {
|
||||||
|
return x - floor(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
fmod(T x, T y) noexcept {
|
||||||
|
return std::fmod(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
modf(T x, T* y) noexcept {
|
||||||
|
return std::modf(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
||||||
|
constexpr min(T x, T y) noexcept {
|
||||||
|
return x < y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
||||||
|
constexpr max(T x, T y) noexcept {
|
||||||
|
return x < y ? y : x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
||||||
|
constexpr clamp(T x, T min_x, T max_x) noexcept {
|
||||||
|
return min(max(x, min_x), max_x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
||||||
|
constexpr saturate(T x) noexcept {
|
||||||
|
return clamp(x, T(0), T(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
constexpr lerp(T x, T y, T a) noexcept {
|
||||||
|
return x * (T(1) - a) + y * a;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
constexpr step(T edge, T x) noexcept {
|
||||||
|
return x < edge ? T(0) : T(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
constexpr smoothstep(T edge0, T edge1, T x) noexcept {
|
||||||
|
const T t = clamp((x - edge0) / (edge1 - edge0), T(0), T(1));
|
||||||
|
return t * t * (T(3) - T(2) * t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||||
|
isnan(T x) noexcept {
|
||||||
|
return std::isnan(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||||
|
isinf(T x) noexcept {
|
||||||
|
return std::isinf(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
||||||
|
isfinite(T x) noexcept {
|
||||||
|
return std::isfinite(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
fma(T x, T y, T z) noexcept {
|
||||||
|
return std::fma(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
frexp(T x, int* exp) noexcept {
|
||||||
|
return std::frexp(x, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||||
|
ldexp(T x, int exp) noexcept {
|
||||||
|
return std::ldexp(x, exp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Angle and Trigonometry Functions
|
// Angle and Trigonometry Functions
|
||||||
//
|
//
|
||||||
@@ -163,159 +315,7 @@ 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>
|
||||||
rsqrt(T x) noexcept {
|
rsqrt(T x) noexcept {
|
||||||
return T(1) / sqrt(x);
|
return reciprocal(sqrt(x));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Common Functions
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace vmath_hpp
|
|
||||||
{
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_unsigned_v<T>, T>
|
|
||||||
constexpr abs(T x) noexcept {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_signed_v<T>, T>
|
|
||||||
constexpr abs(T x) noexcept {
|
|
||||||
return x >= T(0) ? x : -x;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
|
||||||
constexpr sign(T x) noexcept {
|
|
||||||
return static_cast<T>((T(0) < x) - (x < T(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
constexpr reciprocal(T x) noexcept {
|
|
||||||
return T(1) / x;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
floor(T x) noexcept {
|
|
||||||
return std::floor(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
trunc(T x) noexcept {
|
|
||||||
return std::trunc(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
round(T x) noexcept {
|
|
||||||
return std::round(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
ceil(T x) noexcept {
|
|
||||||
return std::ceil(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
fract(T x) noexcept {
|
|
||||||
return x - floor(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
fmod(T x, T y) noexcept {
|
|
||||||
return std::fmod(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
modf(T x, T* y) noexcept {
|
|
||||||
return std::modf(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
|
||||||
constexpr min(T x, T y) noexcept {
|
|
||||||
return x < y ? x : y;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
|
||||||
constexpr max(T x, T y) noexcept {
|
|
||||||
return x < y ? y : x;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
|
||||||
constexpr clamp(T x, T min_x, T max_x) noexcept {
|
|
||||||
return min(max(x, min_x), max_x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
|
|
||||||
constexpr saturate(T x) noexcept {
|
|
||||||
return clamp(x, T(0), T(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
constexpr lerp(T x, T y, T a) noexcept {
|
|
||||||
return x * (T(1) - a) + y * a;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
constexpr step(T edge, T x) noexcept {
|
|
||||||
return x < edge ? T(0) : T(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
constexpr smoothstep(T edge0, T edge1, T x) noexcept {
|
|
||||||
const T t = clamp((x - edge0) / (edge1 - edge0), T(0), T(1));
|
|
||||||
return t * t * (T(3) - T(2) * t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
|
||||||
isnan(T x) noexcept {
|
|
||||||
return std::isnan(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
|
||||||
isinf(T x) noexcept {
|
|
||||||
return std::isinf(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
|
|
||||||
isfinite(T x) noexcept {
|
|
||||||
return std::isfinite(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
fma(T x, T y, T z) noexcept {
|
|
||||||
return std::fma(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
frexp(T x, int* exp) noexcept {
|
|
||||||
return std::frexp(x, exp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
|
|
||||||
ldexp(T x, int exp) noexcept {
|
|
||||||
return std::ldexp(x, exp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user