Merge pull request #28 from BlackMATov/dev

Dev
This commit is contained in:
2023-02-28 08:53:14 +07:00
committed by GitHub
9 changed files with 330 additions and 506 deletions

View File

@@ -1,9 +1,6 @@
add_library(${PROJECT_NAME}.setup_targets INTERFACE) add_library(${PROJECT_NAME}.setup_targets INTERFACE)
add_library(${PROJECT_NAME}::setup_targets ALIAS ${PROJECT_NAME}.setup_targets) add_library(${PROJECT_NAME}::setup_targets ALIAS ${PROJECT_NAME}.setup_targets)
target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE
vmath.hpp.vendors::doctest)
target_compile_options(${PROJECT_NAME}.setup_targets INTERFACE target_compile_options(${PROJECT_NAME}.setup_targets INTERFACE
$<$<CXX_COMPILER_ID:MSVC>: $<$<CXX_COMPILER_ID:MSVC>:
/WX /W4> /WX /W4>
@@ -20,26 +17,13 @@ target_compile_options(${PROJECT_NAME}.setup_targets INTERFACE
-Wno-unknown-warning-option -Wno-unknown-warning-option
>) >)
if(BUILD_WITH_COVERAGE) target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE
target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE $<$<BOOL:${BUILD_WITH_COVERAGE}>:
vmath.hpp::enable_gcov) vmath.hpp::enable_gcov>
endif() $<$<BOOL:${BUILD_WITH_SANITIZERS}>:
if(BUILD_WITH_SANITIZERS)
target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE
vmath.hpp::enable_asan vmath.hpp::enable_asan
vmath.hpp::enable_ubsan) vmath.hpp::enable_ubsan>
endif() $<$<BOOL:${BUILD_WITH_NO_EXCEPTIONS}>:
vmath.hpp::disable_exceptions>
if(BUILD_WITH_NO_EXCEPTIONS) $<$<BOOL:${BUILD_WITH_NO_RTTI}>:
target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE vmath.hpp::disable_rtti>)
vmath.hpp::disable_exceptions)
target_compile_definitions(${PROJECT_NAME}.setup_targets INTERFACE
DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS)
endif()
if(BUILD_WITH_NO_RTTI)
target_link_libraries(${PROJECT_NAME}.setup_targets INTERFACE
vmath.hpp::disable_rtti)
endif()

View File

@@ -13,10 +13,13 @@ set(VMATH_HPP_SINGLES_SCRIPT "${VMATH_HPP_ROOT_DIR}/develop/singles/scripts/buil
file(GLOB_RECURSE VMATH_SINGLES_DEPENDS CONFIGURE_DEPENDS "${VMATH_HPP_ROOT_DIR}/headers/*.hpp") file(GLOB_RECURSE VMATH_SINGLES_DEPENDS CONFIGURE_DEPENDS "${VMATH_HPP_ROOT_DIR}/headers/*.hpp")
add_custom_command(OUTPUT "${VMATH_HPP_SINGLES_OUTPUT}" add_custom_command(OUTPUT "${VMATH_HPP_SINGLES_OUTPUT}"
COMMAND "${Python3_EXECUTABLE}" "${VMATH_HPP_SINGLES_SCRIPT}" COMMAND
"${VMATH_HPP_SINGLES_INPUT}" "${VMATH_HPP_SINGLES_OUTPUT}" "${Python3_EXECUTABLE}" "${VMATH_HPP_SINGLES_SCRIPT}"
DEPENDS ${VMATH_SINGLES_DEPENDS} "${VMATH_HPP_SINGLES_INPUT}" "${VMATH_HPP_SINGLES_OUTPUT}"
WORKING_DIRECTORY "${VMATH_HPP_ROOT_DIR}") DEPENDS
"${VMATH_HPP_SINGLES_SCRIPT}" ${VMATH_SINGLES_DEPENDS}
WORKING_DIRECTORY
"${VMATH_HPP_ROOT_DIR}")
add_custom_target(${PROJECT_NAME}.generate add_custom_target(${PROJECT_NAME}.generate
DEPENDS "${VMATH_HPP_SINGLES_OUTPUT}") DEPENDS "${VMATH_HPP_SINGLES_OUTPUT}")

View File

@@ -4,6 +4,8 @@
* Copyright (C) 2020-2023, by Matvey Cherevko (blackmatov@gmail.com) * Copyright (C) 2020-2023, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/ ******************************************************************************/
#pragma once
#include <cmath> #include <cmath>
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
@@ -148,49 +150,49 @@ 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>
floor(T x) noexcept { constexpr floor(T x) noexcept {
return std::floor(x); return std::floor(x);
} }
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>
trunc(T x) noexcept { constexpr trunc(T x) noexcept {
return std::trunc(x); return std::trunc(x);
} }
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>
round(T x) noexcept { constexpr round(T x) noexcept {
return std::round(x); return std::round(x);
} }
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>
ceil(T x) noexcept { constexpr ceil(T x) noexcept {
return std::ceil(x); return std::ceil(x);
} }
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>
fract(T x) noexcept { constexpr fract(T x) noexcept {
return x - floor(x); return x - floor(x);
} }
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>
fmod(T x, T y) noexcept { constexpr fmod(T x, T y) noexcept {
return std::fmod(x, y); return std::fmod(x, y);
} }
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>
modf(T x, T* y) noexcept { constexpr modf(T x, T* y) noexcept {
return std::modf(x, y); return std::modf(x, y);
} }
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>
copysign(T x, T s) noexcept { constexpr copysign(T x, T s) noexcept {
return std::copysign(x, s); return std::copysign(x, s);
} }
@@ -264,91 +266,91 @@ 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>
sin(T x) noexcept { constexpr sin(T x) noexcept {
return std::sin(x); return std::sin(x);
} }
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>
cos(T x) noexcept { constexpr cos(T x) noexcept {
return std::cos(x); return std::cos(x);
} }
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>
tan(T x) noexcept { constexpr tan(T x) noexcept {
return std::tan(x); return std::tan(x);
} }
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>
asin(T x) noexcept { constexpr asin(T x) noexcept {
return std::asin(x); return std::asin(x);
} }
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>
acos(T x) noexcept { constexpr acos(T x) noexcept {
return std::acos(x); return std::acos(x);
} }
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>
atan(T x) noexcept { constexpr atan(T x) noexcept {
return std::atan(x); return std::atan(x);
} }
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>
atan2(T y, T x) noexcept { constexpr atan2(T y, T x) noexcept {
return std::atan2(y, x); return std::atan2(y, x);
} }
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>
sinh(T x) noexcept { constexpr sinh(T x) noexcept {
return std::sinh(x); return std::sinh(x);
} }
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>
cosh(T x) noexcept { constexpr cosh(T x) noexcept {
return std::cosh(x); return std::cosh(x);
} }
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>
tanh(T x) noexcept { constexpr tanh(T x) noexcept {
return std::tanh(x); return std::tanh(x);
} }
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>
asinh(T x) noexcept { constexpr asinh(T x) noexcept {
return std::asinh(x); return std::asinh(x);
} }
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>
acosh(T x) noexcept { constexpr acosh(T x) noexcept {
return std::acosh(x); return std::acosh(x);
} }
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>
atanh(T x) noexcept { constexpr atanh(T x) noexcept {
return std::atanh(x); return std::atanh(x);
} }
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, std::pair<T, T>> [[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, std::pair<T, T>>
sincos(T x) noexcept { constexpr sincos(T x) noexcept {
return { sin(x), cos(x) }; return { sin(x), cos(x) };
} }
template < typename T > template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, void> std::enable_if_t<std::is_floating_point_v<T>, void>
sincos(T x, T* s, T* c) noexcept { constexpr sincos(T x, T* s, T* c) noexcept {
*s = sin(x); *s = sin(x);
*c = cos(x); *c = cos(x);
} }
@@ -362,43 +364,43 @@ 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>
pow(T x, T y) noexcept { constexpr pow(T x, T y) noexcept {
return std::pow(x, y); return std::pow(x, y);
} }
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>
exp(T x) noexcept { constexpr exp(T x) noexcept {
return std::exp(x); return std::exp(x);
} }
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>
log(T x) noexcept { constexpr log(T x) noexcept {
return std::log(x); return std::log(x);
} }
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>
exp2(T x) noexcept { constexpr exp2(T x) noexcept {
return std::exp2(x); return std::exp2(x);
} }
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>
log2(T x) noexcept { constexpr log2(T x) noexcept {
return std::log2(x); return std::log2(x);
} }
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>
sqrt(T x) noexcept { constexpr sqrt(T x) noexcept {
return std::sqrt(x); return std::sqrt(x);
} }
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 { constexpr rsqrt(T x) noexcept {
return rcp(sqrt(x)); return rcp(sqrt(x));
} }
} }
@@ -481,7 +483,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>
refract(T i, T n, T eta) noexcept { constexpr refract(T i, T n, T eta) noexcept {
const T d = dot(n, i); const T d = dot(n, i);
const T k = T{1} - sqr(eta) * (T{1} - sqr(d)); const T k = T{1} - sqr(eta) * (T{1} - sqr(d));
return k < T{0} ? T{0} : (eta * i - (eta * d + sqrt(k)) * n); return k < T{0} ? T{0} : (eta * i - (eta * d + sqrt(k)) * n);
@@ -2874,226 +2876,139 @@ namespace vmath_hpp
// transpose // transpose
// //
namespace impl template < typename T >
{ [[nodiscard]] constexpr mat<T, 2> transpose(const mat<T, 2>& _m) {
template < typename T > // NOLINTNEXTLINE(*-isolate-declaration)
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE const T a = _m[0][0], b = _m[0][1],
mat<T, 2> transpose_2x2_impl( c = _m[1][0], d = _m[1][1];
T a, T c, return {
T b, T d) a, c,
{ b, d};
return {
a, b,
c, d};
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<T, 3> transpose_3x3_impl(
T a, T d, T g,
T b, T e, T h,
T c, T f, T i)
{
return {
a, b, c,
d, e, f,
g, h, i};
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<T, 4> transpose_4x4_impl(
T a, T e, T i, T m,
T b, T f, T j, T n,
T c, T g, T k, T o,
T d, T h, T l, T p)
{
return {
a, b, c, d,
e, f, g, h,
i, j, k, l,
m, n, o, p};
}
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr mat<T, 2> transpose(const mat<T, 2>& m) { [[nodiscard]] constexpr mat<T, 3> transpose(const mat<T, 3>& _m) {
return impl::transpose_2x2_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], const T a = _m[0][0], b = _m[0][1], c = _m[0][2],
m[1][0], m[1][1]); d = _m[1][0], e = _m[1][1], f = _m[1][2],
g = _m[2][0], h = _m[2][1], i = _m[2][2];
return {
a, d, g,
b, e, h,
c, f, i};
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr mat<T, 3> transpose(const mat<T, 3>& m) { [[nodiscard]] constexpr mat<T, 4> transpose(const mat<T, 4>& _m) {
return impl::transpose_3x3_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], m[0][2], const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3],
m[1][0], m[1][1], m[1][2], e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3],
m[2][0], m[2][1], m[2][2]); i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3],
} m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3];
return {
template < typename T > a, e, i, m,
[[nodiscard]] constexpr mat<T, 4> transpose(const mat<T, 4>& m) { b, f, j, n,
return impl::transpose_4x4_impl( c, g, k, o,
m[0][0], m[0][1], m[0][2], m[0][3], d, h, l, p};
m[1][0], m[1][1], m[1][2], m[1][3],
m[2][0], m[2][1], m[2][2], m[2][3],
m[3][0], m[3][1], m[3][2], m[3][3]);
} }
// //
// adjugate // adjugate
// //
namespace impl template < typename T >
{ [[nodiscard]] constexpr mat<T, 2> adjugate(const mat<T, 2>& _m) {
template < typename T > // NOLINTNEXTLINE(*-isolate-declaration)
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE const T a = _m[0][0], b = _m[0][1],
mat<T, 2> adjugate_2x2_impl( c = _m[1][0], d = _m[1][1];
T a, T b, return {
T c, T d) +d,
{ -b,
return { -c,
+d, -b, +a};
-c, +a};
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<T, 3> adjugate_3x3_impl(
T a, T b, T c,
T d, T e, T f,
T g, T h, T i)
{
return {
e * i - f * h,
c * h - b * i,
b * f - c * e,
f * g - d * i,
a * i - c * g,
c * d - a * f,
d * h - e * g,
b * g - a * h,
a * e - b * d};
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<T, 4> adjugate_4x4_impl(
T a, T b, T c, T d,
T e, T f, T g, T h,
T i, T j, T k, T l,
T m, T n, T o, T p)
{
return {
f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n),
j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n),
n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f),
b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k),
g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p),
k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p),
o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h),
c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k),
h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p),
l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p),
p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h),
d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i),
e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n),
i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n),
m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f),
a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i)};
}
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr mat<T, 2> adjugate(const mat<T, 2>& m) { [[nodiscard]] constexpr mat<T, 3> adjugate(const mat<T, 3>& _m) {
return impl::adjugate_2x2_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], const T a = _m[0][0], b = _m[0][1], c = _m[0][2],
m[1][0], m[1][1]); d = _m[1][0], e = _m[1][1], f = _m[1][2],
g = _m[2][0], h = _m[2][1], i = _m[2][2];
return {
e * i - f * h,
c * h - b * i,
b * f - c * e,
f * g - d * i,
a * i - c * g,
c * d - a * f,
d * h - e * g,
b * g - a * h,
a * e - b * d};
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr mat<T, 3> adjugate(const mat<T, 3>& m) { [[nodiscard]] constexpr mat<T, 4> adjugate(const mat<T, 4>& _m) {
return impl::adjugate_3x3_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], m[0][2], const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3],
m[1][0], m[1][1], m[1][2], e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3],
m[2][0], m[2][1], m[2][2]); i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3],
} m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3];
return {
template < typename T > f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n),
[[nodiscard]] constexpr mat<T, 4> adjugate(const mat<T, 4>& m) { j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n),
return impl::adjugate_4x4_impl( n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f),
m[0][0], m[0][1], m[0][2], m[0][3], b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k),
m[1][0], m[1][1], m[1][2], m[1][3], g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p),
m[2][0], m[2][1], m[2][2], m[2][3], k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p),
m[3][0], m[3][1], m[3][2], m[3][3]); o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h),
c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k),
h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p),
l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p),
p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h),
d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i),
e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n),
i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n),
m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f),
a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i)};
} }
// //
// determinant // determinant
// //
namespace impl template < typename T >
{ [[nodiscard]] constexpr T determinant(const mat<T, 2>& _m) {
template < typename T > // NOLINTNEXTLINE(*-isolate-declaration)
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE const T a = _m[0][0], b = _m[0][1],
T determinant_2x2_impl( c = _m[1][0], d = _m[1][1];
T a, T b, return
T c, T d) a * d - b * c;
{
return a * d - b * c;
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
T determinant_3x3_impl(
T a, T b, T c,
T d, T e, T f,
T g, T h, T i)
{
return
+ a * (e * i - f * h)
- b * (d * i - f * g)
+ c * (d * h - e * g);
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
T determinant_4x4_impl(
T a, T b, T c, T d,
T e, T f, T g, T h,
T i, T j, T k, T l,
T m, T n, T o, T p)
{
return
+ a * (f * (k * p - l * o) - (j * (g * p - h * o)) + (n * (g * l - h * k)))
- b * (e * (k * p - l * o) - (i * (g * p - h * o)) + (m * (g * l - h * k)))
+ c * (e * (j * p - l * n) - (i * (f * p - h * n)) + (m * (f * l - h * j)))
- d * (e * (j * o - k * n) - (i * (f * o - g * n)) + (m * (f * k - g * j)));
}
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr T determinant(const mat<T, 2>& m) { [[nodiscard]] constexpr T determinant(const mat<T, 3>& _m) {
return impl::determinant_2x2_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], const T a = _m[0][0], b = _m[0][1], c = _m[0][2],
m[1][0], m[1][1]); d = _m[1][0], e = _m[1][1], f = _m[1][2],
g = _m[2][0], h = _m[2][1], i = _m[2][2];
return
+ a * (e * i - f * h)
- b * (d * i - f * g)
+ c * (d * h - e * g);
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr T determinant(const mat<T, 3>& m) { [[nodiscard]] constexpr T determinant(const mat<T, 4>& _m) {
return impl::determinant_3x3_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], m[0][2], const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3],
m[1][0], m[1][1], m[1][2], e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3],
m[2][0], m[2][1], m[2][2]); i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3],
} m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3];
return
template < typename T > + a * (f * (k * p - l * o) - (j * (g * p - h * o)) + (n * (g * l - h * k)))
[[nodiscard]] constexpr T determinant(const mat<T, 4>& m) { - b * (e * (k * p - l * o) - (i * (g * p - h * o)) + (m * (g * l - h * k)))
return impl::determinant_4x4_impl( + c * (e * (j * p - l * n) - (i * (f * p - h * n)) + (m * (f * l - h * j)))
m[0][0], m[0][1], m[0][2], m[0][3], - d * (e * (j * o - k * n) - (i * (f * o - g * n)) + (m * (f * k - g * j)));
m[1][0], m[1][1], m[1][2], m[1][3],
m[2][0], m[2][1], m[2][2], m[2][3],
m[3][0], m[3][1], m[3][2], m[3][3]);
} }
// //
@@ -3661,12 +3576,12 @@ namespace vmath_hpp::detail
} }
}; };
template < typename T, size_t Size > template < typename T, std::size_t Size >
[[nodiscard]] std::size_t hash(const vec<T, Size>& v) noexcept { [[nodiscard]] std::size_t hash(const vec<T, Size>& v) noexcept {
return fold_join(hash_combiner{}, std::size_t{}, v); return fold_join(hash_combiner{}, std::size_t{}, v);
} }
template < typename T, size_t Size > template < typename T, std::size_t Size >
[[nodiscard]] std::size_t hash(const mat<T, Size>& m) noexcept { [[nodiscard]] std::size_t hash(const mat<T, Size>& m) noexcept {
return fold_join(hash_combiner{}, std::size_t{}, m); return fold_join(hash_combiner{}, std::size_t{}, m);
} }

View File

@@ -5,10 +5,6 @@ import os
import re import re
import sys import sys
#
#
#
EMPTY_MATCHER = re.compile(r'^\s*$') EMPTY_MATCHER = re.compile(r'^\s*$')
C_COMMENT_MATCHER = re.compile(r'^/\*.*\*/', re.S) C_COMMENT_MATCHER = re.compile(r'^/\*.*\*/', re.S)
@@ -19,9 +15,6 @@ USER_INCLUDE_MATCHER = re.compile(r'#\s*include\s*\"(.*)\"')
SYSTEM_INCLUDE_MATCHER = re.compile(r'#\s*include\s*<(.*)>') SYSTEM_INCLUDE_MATCHER = re.compile(r'#\s*include\s*<(.*)>')
PRAGMA_ONCE_MATCHER = re.compile(r'#\s*pragma\s+once') PRAGMA_ONCE_MATCHER = re.compile(r'#\s*pragma\s+once')
#
#
#
def CollectLicenseComment(headerPath): def CollectLicenseComment(headerPath):
with open(headerPath, "r") as headerStream: with open(headerPath, "r") as headerStream:
@@ -29,7 +22,8 @@ def CollectLicenseComment(headerPath):
commentMatch = re.match(C_COMMENT_MATCHER, headerContent) commentMatch = re.match(C_COMMENT_MATCHER, headerContent)
return commentMatch.group() if commentMatch else "" return commentMatch.group() if commentMatch else ""
def CollectSystemIncludes(headerPath, parsedHeaders = set()):
def CollectSystemIncludes(headerPath, parsedHeaders=set()):
with open(headerPath, "r") as headerStream: with open(headerPath, "r") as headerStream:
headerContent = headerStream.read().strip() headerContent = headerStream.read().strip()
@@ -50,8 +44,10 @@ def CollectSystemIncludes(headerPath, parsedHeaders = set()):
includeMatch = USER_INCLUDE_MATCHER.findall(headerLine) includeMatch = USER_INCLUDE_MATCHER.findall(headerLine)
if includeMatch and ifdefScopeLevel == 0: if includeMatch and ifdefScopeLevel == 0:
internalHeaderPath = os.path.abspath(os.path.join(os.path.dirname(headerPath), includeMatch[0])) internalHeaderPath = os.path.abspath(os.path.join(
headerIncludes = headerIncludes.union(CollectSystemIncludes(internalHeaderPath, parsedHeaders)) os.path.dirname(headerPath), includeMatch[0]))
headerIncludes = headerIncludes.union(
CollectSystemIncludes(internalHeaderPath, parsedHeaders))
includeMatch = SYSTEM_INCLUDE_MATCHER.findall(headerLine) includeMatch = SYSTEM_INCLUDE_MATCHER.findall(headerLine)
if includeMatch and ifdefScopeLevel == 0: if includeMatch and ifdefScopeLevel == 0:
@@ -59,7 +55,8 @@ def CollectSystemIncludes(headerPath, parsedHeaders = set()):
return headerIncludes return headerIncludes
def ParseHeader(headerPath, parsedHeaders = set()):
def ParseHeader(headerPath, parsedHeaders=set()):
with open(headerPath, "r") as headerStream: with open(headerPath, "r") as headerStream:
headerContent = headerStream.read().strip() headerContent = headerStream.read().strip()
headerContent = re.sub(C_COMMENT_MATCHER, '', headerContent) headerContent = re.sub(C_COMMENT_MATCHER, '', headerContent)
@@ -89,8 +86,10 @@ def ParseHeader(headerPath, parsedHeaders = set()):
includeMatch = USER_INCLUDE_MATCHER.findall(headerLine) includeMatch = USER_INCLUDE_MATCHER.findall(headerLine)
if includeMatch and ifdefScopeLevel == 0: if includeMatch and ifdefScopeLevel == 0:
internalHeaderPath = os.path.abspath(os.path.join(os.path.dirname(headerPath), includeMatch[0])) internalHeaderPath = os.path.abspath(os.path.join(
internalHeaderContent = ParseHeader(internalHeaderPath, parsedHeaders) os.path.dirname(headerPath), includeMatch[0]))
internalHeaderContent = ParseHeader(
internalHeaderPath, parsedHeaders)
outputContent += internalHeaderContent outputContent += internalHeaderContent
shouldSkipNextEmptyLines = True shouldSkipNextEmptyLines = True
@@ -106,9 +105,6 @@ def ParseHeader(headerPath, parsedHeaders = set()):
return "{}\n".format(outputContent) return "{}\n".format(outputContent)
#
#
#
inputHeaderPath = os.path.abspath(sys.argv[1]) inputHeaderPath = os.path.abspath(sys.argv[1])
outputHeaderPath = os.path.abspath(sys.argv[2]) outputHeaderPath = os.path.abspath(sys.argv[2])
@@ -118,13 +114,20 @@ os.makedirs(os.path.dirname(outputHeaderPath), exist_ok=True)
with open(outputHeaderPath, "w") as outputHeaderStream: with open(outputHeaderPath, "w") as outputHeaderStream:
licenseComment = CollectLicenseComment(inputHeaderPath) licenseComment = CollectLicenseComment(inputHeaderPath)
systemIncludes = CollectSystemIncludes(inputHeaderPath) systemIncludes = CollectSystemIncludes(inputHeaderPath)
headersContent = ParseHeader(inputHeaderPath)
outputHeaderStream.write("{}\n".format(licenseComment)) if licenseComment:
outputHeaderStream.write("{}\n".format(licenseComment))
outputHeaderStream.write("\n")
outputHeaderStream.write("#pragma once\n")
outputHeaderStream.write("\n") outputHeaderStream.write("\n")
for systemInclude in sorted(systemIncludes): if systemIncludes:
outputHeaderStream.write("#include <{}>\n".format(systemInclude)) for systemInclude in sorted(systemIncludes):
outputHeaderStream.write("\n") outputHeaderStream.write("#include <{}>\n".format(systemInclude))
outputHeaderStream.write("\n")
outputHeaderStream.write(ParseHeader(inputHeaderPath).strip()) if headersContent:
outputHeaderStream.write("\n") outputHeaderStream.write(headersContent.strip())
outputHeaderStream.write("\n")

View File

@@ -8,11 +8,13 @@ add_executable(${PROJECT_NAME}.singles ${UNTESTS_SOURCES})
target_link_libraries(${PROJECT_NAME} PRIVATE target_link_libraries(${PROJECT_NAME} PRIVATE
vmath.hpp::vmath.hpp vmath.hpp::vmath.hpp
vmath.hpp::setup_targets) vmath.hpp::setup_targets
vmath.hpp.vendors::doctest)
target_link_libraries(${PROJECT_NAME}.singles PRIVATE target_link_libraries(${PROJECT_NAME}.singles PRIVATE
vmath.hpp::singles vmath.hpp::singles
vmath.hpp::setup_targets) vmath.hpp::setup_targets
vmath.hpp.vendors::doctest)
add_test(${PROJECT_NAME} ${PROJECT_NAME}) add_test(${PROJECT_NAME} ${PROJECT_NAME})
add_test(${PROJECT_NAME} ${PROJECT_NAME}.singles) add_test(${PROJECT_NAME} ${PROJECT_NAME}.singles)

View File

@@ -322,34 +322,38 @@ TEST_CASE("vmath/mat_fun") {
constexpr fmat4 rm1 = inverse(m1); constexpr fmat4 rm1 = inverse(m1);
STATIC_CHECK(all(approx( STATIC_CHECK(all(approx(
unit4_z<float> * m1 * rm1, unit4_z<float> * m1 * rm1,
unit4_z<float>))); unit4_z<float>,
0.00001f)));
} }
{ {
const fvec3 axis2 = normalize(fvec3(1.f, 2.f, 3.f)); const fvec3 axis2 = normalize(fvec3(1.f, 2.f, 3.f));
const fmat4 m2 = fmat4(rotate(0.5f,axis2)); const fmat4 m2 = perspective_lh(800.f, 600.f, -1.f, 1.f) * translate(fvec3(1.f, 2.f, 3.f)) * scale4(fvec3(2.f, 3.f, 4.f)) * fmat4(rotate(0.5f,axis2));
const fmat4 rm2 = inverse(m2); const fmat4 rm2 = inverse(m2);
CHECK(all(approx( CHECK(all(approx(
unit4_z<float> * m2 * rm2, unit4_z<float> * m2 * rm2,
unit4_z<float>))); unit4_z<float>,
0.00001f)));
} }
{ {
const fvec3 axis3 = normalize(fvec3(1.f, 2.f, 3.f)); const fvec3 axis3 = normalize(fvec3(1.f, 2.f, 3.f));
const fmat3 m3 = fmat3(rotate(0.5f,axis3)); const fmat3 m3 = translate(fvec2(1.f, 2.f)) * scale(fvec3(2.f, 3.f, 4.f)) * fmat3(rotate(0.5f,axis3));
const fmat3 rm3 = inverse(m3); const fmat3 rm3 = inverse(m3);
CHECK(all(approx( CHECK(all(approx(
unit3_z<float> * m3 * rm3, unit3_z<float> * m3 * rm3,
unit3_z<float>))); unit3_z<float>,
0.00001f)));
} }
{ {
const fvec3 axis4 = normalize(fvec3(0.f, 0.f, 3.f)); const fvec3 axis4 = normalize(fvec3(0.f, 0.f, 3.f));
const fmat2 m4 = fmat2(rotate(0.5f,axis4)); const fmat2 m4 = scale(fvec2(2.f, 3.f)) * fmat2(rotate(0.5f,axis4));
const fmat2 rm4 = inverse(m4); const fmat2 rm4 = inverse(m4);
CHECK(all(approx( CHECK(all(approx(
unit2_y<float> * m4 * rm4, unit2_y<float> * m4 * rm4,
unit2_y<float>))); unit2_y<float>,
0.00001f)));
} }
} }
} }

View File

@@ -68,12 +68,12 @@ namespace vmath_hpp::detail
} }
}; };
template < typename T, size_t Size > template < typename T, std::size_t Size >
[[nodiscard]] std::size_t hash(const vec<T, Size>& v) noexcept { [[nodiscard]] std::size_t hash(const vec<T, Size>& v) noexcept {
return fold_join(hash_combiner{}, std::size_t{}, v); return fold_join(hash_combiner{}, std::size_t{}, v);
} }
template < typename T, size_t Size > template < typename T, std::size_t Size >
[[nodiscard]] std::size_t hash(const mat<T, Size>& m) noexcept { [[nodiscard]] std::size_t hash(const mat<T, Size>& m) noexcept {
return fold_join(hash_combiner{}, std::size_t{}, m); return fold_join(hash_combiner{}, std::size_t{}, m);
} }

View File

@@ -44,49 +44,49 @@ 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>
floor(T x) noexcept { constexpr floor(T x) noexcept {
return std::floor(x); return std::floor(x);
} }
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>
trunc(T x) noexcept { constexpr trunc(T x) noexcept {
return std::trunc(x); return std::trunc(x);
} }
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>
round(T x) noexcept { constexpr round(T x) noexcept {
return std::round(x); return std::round(x);
} }
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>
ceil(T x) noexcept { constexpr ceil(T x) noexcept {
return std::ceil(x); return std::ceil(x);
} }
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>
fract(T x) noexcept { constexpr fract(T x) noexcept {
return x - floor(x); return x - floor(x);
} }
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>
fmod(T x, T y) noexcept { constexpr fmod(T x, T y) noexcept {
return std::fmod(x, y); return std::fmod(x, y);
} }
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>
modf(T x, T* y) noexcept { constexpr modf(T x, T* y) noexcept {
return std::modf(x, y); return std::modf(x, y);
} }
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>
copysign(T x, T s) noexcept { constexpr copysign(T x, T s) noexcept {
return std::copysign(x, s); return std::copysign(x, s);
} }
@@ -160,91 +160,91 @@ 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>
sin(T x) noexcept { constexpr sin(T x) noexcept {
return std::sin(x); return std::sin(x);
} }
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>
cos(T x) noexcept { constexpr cos(T x) noexcept {
return std::cos(x); return std::cos(x);
} }
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>
tan(T x) noexcept { constexpr tan(T x) noexcept {
return std::tan(x); return std::tan(x);
} }
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>
asin(T x) noexcept { constexpr asin(T x) noexcept {
return std::asin(x); return std::asin(x);
} }
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>
acos(T x) noexcept { constexpr acos(T x) noexcept {
return std::acos(x); return std::acos(x);
} }
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>
atan(T x) noexcept { constexpr atan(T x) noexcept {
return std::atan(x); return std::atan(x);
} }
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>
atan2(T y, T x) noexcept { constexpr atan2(T y, T x) noexcept {
return std::atan2(y, x); return std::atan2(y, x);
} }
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>
sinh(T x) noexcept { constexpr sinh(T x) noexcept {
return std::sinh(x); return std::sinh(x);
} }
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>
cosh(T x) noexcept { constexpr cosh(T x) noexcept {
return std::cosh(x); return std::cosh(x);
} }
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>
tanh(T x) noexcept { constexpr tanh(T x) noexcept {
return std::tanh(x); return std::tanh(x);
} }
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>
asinh(T x) noexcept { constexpr asinh(T x) noexcept {
return std::asinh(x); return std::asinh(x);
} }
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>
acosh(T x) noexcept { constexpr acosh(T x) noexcept {
return std::acosh(x); return std::acosh(x);
} }
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>
atanh(T x) noexcept { constexpr atanh(T x) noexcept {
return std::atanh(x); return std::atanh(x);
} }
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, std::pair<T, T>> [[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, std::pair<T, T>>
sincos(T x) noexcept { constexpr sincos(T x) noexcept {
return { sin(x), cos(x) }; return { sin(x), cos(x) };
} }
template < typename T > template < typename T >
std::enable_if_t<std::is_floating_point_v<T>, void> std::enable_if_t<std::is_floating_point_v<T>, void>
sincos(T x, T* s, T* c) noexcept { constexpr sincos(T x, T* s, T* c) noexcept {
*s = sin(x); *s = sin(x);
*c = cos(x); *c = cos(x);
} }
@@ -258,43 +258,43 @@ 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>
pow(T x, T y) noexcept { constexpr pow(T x, T y) noexcept {
return std::pow(x, y); return std::pow(x, y);
} }
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>
exp(T x) noexcept { constexpr exp(T x) noexcept {
return std::exp(x); return std::exp(x);
} }
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>
log(T x) noexcept { constexpr log(T x) noexcept {
return std::log(x); return std::log(x);
} }
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>
exp2(T x) noexcept { constexpr exp2(T x) noexcept {
return std::exp2(x); return std::exp2(x);
} }
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>
log2(T x) noexcept { constexpr log2(T x) noexcept {
return std::log2(x); return std::log2(x);
} }
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>
sqrt(T x) noexcept { constexpr sqrt(T x) noexcept {
return std::sqrt(x); return std::sqrt(x);
} }
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 { constexpr rsqrt(T x) noexcept {
return rcp(sqrt(x)); return rcp(sqrt(x));
} }
} }
@@ -377,7 +377,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>
refract(T i, T n, T eta) noexcept { constexpr refract(T i, T n, T eta) noexcept {
const T d = dot(n, i); const T d = dot(n, i);
const T k = T{1} - sqr(eta) * (T{1} - sqr(d)); const T k = T{1} - sqr(eta) * (T{1} - sqr(d));
return k < T{0} ? T{0} : (eta * i - (eta * d + sqrt(k)) * n); return k < T{0} ? T{0} : (eta * i - (eta * d + sqrt(k)) * n);

View File

@@ -638,226 +638,139 @@ namespace vmath_hpp
// transpose // transpose
// //
namespace impl template < typename T >
{ [[nodiscard]] constexpr mat<T, 2> transpose(const mat<T, 2>& _m) {
template < typename T > // NOLINTNEXTLINE(*-isolate-declaration)
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE const T a = _m[0][0], b = _m[0][1],
mat<T, 2> transpose_2x2_impl( c = _m[1][0], d = _m[1][1];
T a, T c, return {
T b, T d) a, c,
{ b, d};
return {
a, b,
c, d};
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<T, 3> transpose_3x3_impl(
T a, T d, T g,
T b, T e, T h,
T c, T f, T i)
{
return {
a, b, c,
d, e, f,
g, h, i};
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<T, 4> transpose_4x4_impl(
T a, T e, T i, T m,
T b, T f, T j, T n,
T c, T g, T k, T o,
T d, T h, T l, T p)
{
return {
a, b, c, d,
e, f, g, h,
i, j, k, l,
m, n, o, p};
}
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr mat<T, 2> transpose(const mat<T, 2>& m) { [[nodiscard]] constexpr mat<T, 3> transpose(const mat<T, 3>& _m) {
return impl::transpose_2x2_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], const T a = _m[0][0], b = _m[0][1], c = _m[0][2],
m[1][0], m[1][1]); d = _m[1][0], e = _m[1][1], f = _m[1][2],
g = _m[2][0], h = _m[2][1], i = _m[2][2];
return {
a, d, g,
b, e, h,
c, f, i};
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr mat<T, 3> transpose(const mat<T, 3>& m) { [[nodiscard]] constexpr mat<T, 4> transpose(const mat<T, 4>& _m) {
return impl::transpose_3x3_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], m[0][2], const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3],
m[1][0], m[1][1], m[1][2], e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3],
m[2][0], m[2][1], m[2][2]); i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3],
} m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3];
return {
template < typename T > a, e, i, m,
[[nodiscard]] constexpr mat<T, 4> transpose(const mat<T, 4>& m) { b, f, j, n,
return impl::transpose_4x4_impl( c, g, k, o,
m[0][0], m[0][1], m[0][2], m[0][3], d, h, l, p};
m[1][0], m[1][1], m[1][2], m[1][3],
m[2][0], m[2][1], m[2][2], m[2][3],
m[3][0], m[3][1], m[3][2], m[3][3]);
} }
// //
// adjugate // adjugate
// //
namespace impl template < typename T >
{ [[nodiscard]] constexpr mat<T, 2> adjugate(const mat<T, 2>& _m) {
template < typename T > // NOLINTNEXTLINE(*-isolate-declaration)
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE const T a = _m[0][0], b = _m[0][1],
mat<T, 2> adjugate_2x2_impl( c = _m[1][0], d = _m[1][1];
T a, T b, return {
T c, T d) +d,
{ -b,
return { -c,
+d, -b, +a};
-c, +a};
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<T, 3> adjugate_3x3_impl(
T a, T b, T c,
T d, T e, T f,
T g, T h, T i)
{
return {
e * i - f * h,
c * h - b * i,
b * f - c * e,
f * g - d * i,
a * i - c * g,
c * d - a * f,
d * h - e * g,
b * g - a * h,
a * e - b * d};
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
mat<T, 4> adjugate_4x4_impl(
T a, T b, T c, T d,
T e, T f, T g, T h,
T i, T j, T k, T l,
T m, T n, T o, T p)
{
return {
f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n),
j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n),
n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f),
b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k),
g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p),
k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p),
o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h),
c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k),
h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p),
l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p),
p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h),
d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i),
e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n),
i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n),
m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f),
a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i)};
}
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr mat<T, 2> adjugate(const mat<T, 2>& m) { [[nodiscard]] constexpr mat<T, 3> adjugate(const mat<T, 3>& _m) {
return impl::adjugate_2x2_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], const T a = _m[0][0], b = _m[0][1], c = _m[0][2],
m[1][0], m[1][1]); d = _m[1][0], e = _m[1][1], f = _m[1][2],
g = _m[2][0], h = _m[2][1], i = _m[2][2];
return {
e * i - f * h,
c * h - b * i,
b * f - c * e,
f * g - d * i,
a * i - c * g,
c * d - a * f,
d * h - e * g,
b * g - a * h,
a * e - b * d};
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr mat<T, 3> adjugate(const mat<T, 3>& m) { [[nodiscard]] constexpr mat<T, 4> adjugate(const mat<T, 4>& _m) {
return impl::adjugate_3x3_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], m[0][2], const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3],
m[1][0], m[1][1], m[1][2], e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3],
m[2][0], m[2][1], m[2][2]); i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3],
} m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3];
return {
template < typename T > f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n),
[[nodiscard]] constexpr mat<T, 4> adjugate(const mat<T, 4>& m) { j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n),
return impl::adjugate_4x4_impl( n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f),
m[0][0], m[0][1], m[0][2], m[0][3], b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k),
m[1][0], m[1][1], m[1][2], m[1][3], g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p),
m[2][0], m[2][1], m[2][2], m[2][3], k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p),
m[3][0], m[3][1], m[3][2], m[3][3]); o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h),
c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k),
h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p),
l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p),
p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h),
d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i),
e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n),
i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n),
m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f),
a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i)};
} }
// //
// determinant // determinant
// //
namespace impl template < typename T >
{ [[nodiscard]] constexpr T determinant(const mat<T, 2>& _m) {
template < typename T > // NOLINTNEXTLINE(*-isolate-declaration)
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE const T a = _m[0][0], b = _m[0][1],
T determinant_2x2_impl( c = _m[1][0], d = _m[1][1];
T a, T b, return
T c, T d) a * d - b * c;
{
return a * d - b * c;
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
T determinant_3x3_impl(
T a, T b, T c,
T d, T e, T f,
T g, T h, T i)
{
return
+ a * (e * i - f * h)
- b * (d * i - f * g)
+ c * (d * h - e * g);
}
template < typename T >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
T determinant_4x4_impl(
T a, T b, T c, T d,
T e, T f, T g, T h,
T i, T j, T k, T l,
T m, T n, T o, T p)
{
return
+ a * (f * (k * p - l * o) - (j * (g * p - h * o)) + (n * (g * l - h * k)))
- b * (e * (k * p - l * o) - (i * (g * p - h * o)) + (m * (g * l - h * k)))
+ c * (e * (j * p - l * n) - (i * (f * p - h * n)) + (m * (f * l - h * j)))
- d * (e * (j * o - k * n) - (i * (f * o - g * n)) + (m * (f * k - g * j)));
}
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr T determinant(const mat<T, 2>& m) { [[nodiscard]] constexpr T determinant(const mat<T, 3>& _m) {
return impl::determinant_2x2_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], const T a = _m[0][0], b = _m[0][1], c = _m[0][2],
m[1][0], m[1][1]); d = _m[1][0], e = _m[1][1], f = _m[1][2],
g = _m[2][0], h = _m[2][1], i = _m[2][2];
return
+ a * (e * i - f * h)
- b * (d * i - f * g)
+ c * (d * h - e * g);
} }
template < typename T > template < typename T >
[[nodiscard]] constexpr T determinant(const mat<T, 3>& m) { [[nodiscard]] constexpr T determinant(const mat<T, 4>& _m) {
return impl::determinant_3x3_impl( // NOLINTNEXTLINE(*-isolate-declaration)
m[0][0], m[0][1], m[0][2], const T a = _m[0][0], b = _m[0][1], c = _m[0][2], d = _m[0][3],
m[1][0], m[1][1], m[1][2], e = _m[1][0], f = _m[1][1], g = _m[1][2], h = _m[1][3],
m[2][0], m[2][1], m[2][2]); i = _m[2][0], j = _m[2][1], k = _m[2][2], l = _m[2][3],
} m = _m[3][0], n = _m[3][1], o = _m[3][2], p = _m[3][3];
return
template < typename T > + a * (f * (k * p - l * o) - (j * (g * p - h * o)) + (n * (g * l - h * k)))
[[nodiscard]] constexpr T determinant(const mat<T, 4>& m) { - b * (e * (k * p - l * o) - (i * (g * p - h * o)) + (m * (g * l - h * k)))
return impl::determinant_4x4_impl( + c * (e * (j * p - l * n) - (i * (f * p - h * n)) + (m * (f * l - h * j)))
m[0][0], m[0][1], m[0][2], m[0][3], - d * (e * (j * o - k * n) - (i * (f * o - g * n)) + (m * (f * k - g * j)));
m[1][0], m[1][1], m[1][2], m[1][3],
m[2][0], m[2][1], m[2][2], m[2][3],
m[3][0], m[3][1], m[3][2], m[3][3]);
} }
// //