diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-01-10 21:20:59 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-01-10 22:11:44 +0300 |
commit | 243296db6a55d43e39a028a2478359de4dc18dab (patch) | |
tree | c923d6eb97e8adf27e469ca732a62def77c5304e | |
parent | 4c95619a78a3504ae623c223afce6ac4ac4ba1b9 (diff) |
Rework macro name and add manhattan distance & Length functions
-rw-r--r-- | source/blender/blenlib/BLI_math_vec_types.hh | 150 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.hh | 104 |
2 files changed, 144 insertions, 110 deletions
diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh index 9ba29d41684..ae8cb0056bb 100644 --- a/source/blender/blenlib/BLI_math_vec_types.hh +++ b/source/blender/blenlib/BLI_math_vec_types.hh @@ -93,22 +93,22 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> } /* Workaround issue with template. */ -#define BLI_VEC_ENABLE_IF(_size, _test) int S = _size, BLI_ENABLE_IF((S _test)) +#define BLI_ENABLE_IF_VEC(_size, _test) int S = _size, BLI_ENABLE_IF((S _test)) - template<BLI_VEC_ENABLE_IF(Size, == 2)> vec_base(T _x, T _y) + template<BLI_ENABLE_IF_VEC(Size, == 2)> vec_base(T _x, T _y) { (*this)[0] = _x; (*this)[1] = _y; } - template<BLI_VEC_ENABLE_IF(Size, == 3)> vec_base(T _x, T _y, T _z) + template<BLI_ENABLE_IF_VEC(Size, == 3)> vec_base(T _x, T _y, T _z) { (*this)[0] = _x; (*this)[1] = _y; (*this)[2] = _z; } - template<BLI_VEC_ENABLE_IF(Size, == 4)> vec_base(T _x, T _y, T _z, T _w) + template<BLI_ENABLE_IF_VEC(Size, == 4)> vec_base(T _x, T _y, T _z, T _w) { (*this)[0] = _x; (*this)[1] = _y; @@ -118,52 +118,52 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> /** Mixed scalar-vector constructors. */ - template<typename U, BLI_VEC_ENABLE_IF(Size, == 3)> + template<typename U, BLI_ENABLE_IF_VEC(Size, == 3)> constexpr vec_base(const vec_base<U, 2> &xy, T z) : vec_base(static_cast<T>(xy.x), static_cast<T>(xy.y), z) { } - template<typename U, BLI_VEC_ENABLE_IF(Size, == 3)> + template<typename U, BLI_ENABLE_IF_VEC(Size, == 3)> constexpr vec_base(T x, const vec_base<U, 2> &yz) : vec_base(x, static_cast<T>(yz.x), static_cast<T>(yz.y)) { } - template<typename U, BLI_VEC_ENABLE_IF(Size, == 4)> + template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)> vec_base(vec_base<U, 3> xyz, T w) : vec_base( static_cast<T>(xyz.x), static_cast<T>(xyz.y), static_cast<T>(xyz.z), static_cast<T>(w)) { } - template<typename U, BLI_VEC_ENABLE_IF(Size, == 4)> + template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)> vec_base(T x, vec_base<U, 3> yzw) : vec_base( static_cast<T>(x), static_cast<T>(yzw.x), static_cast<T>(yzw.y), static_cast<T>(yzw.z)) { } - template<typename U, BLI_VEC_ENABLE_IF(Size, == 4)> + template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)> vec_base(vec_base<U, 2> xy, vec_base<U, 2> zw) : vec_base( static_cast<T>(xy.x), static_cast<T>(xy.y), static_cast<T>(zw.x), static_cast<T>(zw.y)) { } - template<typename U, BLI_VEC_ENABLE_IF(Size, == 4)> + template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)> vec_base(vec_base<U, 2> xy, T z, T w) : vec_base(static_cast<T>(xy.x), static_cast<T>(xy.y), static_cast<T>(z), static_cast<T>(w)) { } - template<typename U, BLI_VEC_ENABLE_IF(Size, == 4)> + template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)> vec_base(T x, vec_base<U, 2> yz, T w) : vec_base(static_cast<T>(x), static_cast<T>(yz.x), static_cast<T>(yz.y), static_cast<T>(w)) { } - template<typename U, BLI_VEC_ENABLE_IF(Size, == 4)> + template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)> vec_base(T x, T y, vec_base<U, 2> zw) : vec_base(static_cast<T>(x), static_cast<T>(y), static_cast<T>(zw.x), static_cast<T>(zw.y)) { @@ -171,17 +171,17 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> /** Masking. */ - template<BLI_VEC_ENABLE_IF(Size, >= 3)> explicit operator vec_base<T, 2>() const + template<BLI_ENABLE_IF_VEC(Size, >= 3)> explicit operator vec_base<T, 2>() const { return vec_base<T, 2>(UNPACK2(*this)); } - template<BLI_VEC_ENABLE_IF(Size, >= 4)> explicit operator vec_base<T, 3>() const + template<BLI_ENABLE_IF_VEC(Size, >= 4)> explicit operator vec_base<T, 3>() const { return vec_base<T, 3>(UNPACK3(*this)); } -#undef BLI_VEC_ENABLE_IF +#undef BLI_ENABLE_IF_VEC /** Conversion from pointers (from C-style vectors). */ @@ -235,16 +235,16 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> /** Internal Operators Macro. */ -#define VEC_INT_OP(_T) template<typename U = _T, BLI_ENABLE_IF((std::is_integral_v<U>))> +#define BLI_INT_OP(_T) template<typename U = _T, BLI_ENABLE_IF((std::is_integral_v<U>))> -#define BLI_VEC_OP(_result, _i, _op) \ +#define BLI_VEC_OP_IMPL(_result, _i, _op) \ vec_base _result; \ for (int _i = 0; _i < Size; _i++) { \ _op; \ } \ return _result; -#define BLI_VEC_OP_SELF(_i, _op) \ +#define BLI_VEC_OP_IMPL_SELF(_i, _op) \ for (int _i = 0; _i < Size; _i++) { \ _op; \ } \ @@ -254,12 +254,12 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> friend vec_base operator+(const vec_base &a, const vec_base &b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] + b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] + b[i]); } friend vec_base operator+(const vec_base &a, const T &b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] + b); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] + b); } friend vec_base operator+(const T &a, const vec_base &b) @@ -269,52 +269,52 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> vec_base &operator+=(const vec_base &b) { - BLI_VEC_OP_SELF(i, (*this)[i] += b[i]); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] += b[i]); } vec_base &operator+=(const T &b) { - BLI_VEC_OP_SELF(i, (*this)[i] += b); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] += b); } friend vec_base operator-(const vec_base &a) { - BLI_VEC_OP(ret, i, ret[i] = -a[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = -a[i]); } friend vec_base operator-(const vec_base &a, const vec_base &b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] - b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] - b[i]); } friend vec_base operator-(const vec_base &a, const T &b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] - b); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] - b); } friend vec_base operator-(const T &a, const vec_base &b) { - BLI_VEC_OP(ret, i, ret[i] = a - b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a - b[i]); } vec_base &operator-=(const vec_base &b) { - BLI_VEC_OP_SELF(i, (*this)[i] -= b[i]); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] -= b[i]); } vec_base &operator-=(const T &b) { - BLI_VEC_OP_SELF(i, (*this)[i] -= b); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] -= b); } friend vec_base operator*(const vec_base &a, const vec_base &b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] * b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b[i]); } friend vec_base operator*(const vec_base &a, T b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] * b); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b); } friend vec_base operator*(T a, const vec_base &b) @@ -324,146 +324,146 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> vec_base &operator*=(T b) { - BLI_VEC_OP_SELF(i, (*this)[i] *= b); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] *= b); } vec_base &operator*=(const vec_base &b) { - BLI_VEC_OP_SELF(i, (*this)[i] *= b[i]); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] *= b[i]); } friend vec_base operator/(const vec_base &a, const vec_base &b) { BLI_assert(!b.is_any_zero()); - BLI_VEC_OP(ret, i, ret[i] = a[i] / b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] / b[i]); } friend vec_base operator/(const vec_base &a, T b) { BLI_assert(b != T(0)); - BLI_VEC_OP(ret, i, ret[i] = a[i] / b); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] / b); } friend vec_base operator/(T a, const vec_base &b) { BLI_assert(!b.is_any_zero()); - BLI_VEC_OP(ret, i, ret[i] = a / b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a / b[i]); } vec_base &operator/=(T b) { BLI_assert(b != T(0)); - BLI_VEC_OP_SELF(i, (*this)[i] /= b); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b); } vec_base &operator/=(const vec_base &b) { BLI_assert(!b.is_any_zero()); - BLI_VEC_OP_SELF(i, (*this)[i] /= b[i]); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b[i]); } /** Binary operators. */ - VEC_INT_OP(T) friend vec_base operator&(const vec_base &a, const vec_base &b) + BLI_INT_OP(T) friend vec_base operator&(const vec_base &a, const vec_base &b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] & b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] & b[i]); } - VEC_INT_OP(T) friend vec_base operator&(const vec_base &a, T b) + BLI_INT_OP(T) friend vec_base operator&(const vec_base &a, T b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] & b); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] & b); } - VEC_INT_OP(T) friend vec_base operator&(T a, const vec_base &b) + BLI_INT_OP(T) friend vec_base operator&(T a, const vec_base &b) { return b & a; } - VEC_INT_OP(T) vec_base &operator&=(T b) + BLI_INT_OP(T) vec_base &operator&=(T b) { - BLI_VEC_OP_SELF(i, (*this)[i] &= b); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] &= b); } - VEC_INT_OP(T) vec_base &operator&=(const vec_base &b) + BLI_INT_OP(T) vec_base &operator&=(const vec_base &b) { - BLI_VEC_OP_SELF(i, (*this)[i] &= b[i]); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] &= b[i]); } - VEC_INT_OP(T) friend vec_base operator|(const vec_base &a, const vec_base &b) + BLI_INT_OP(T) friend vec_base operator|(const vec_base &a, const vec_base &b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] | b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] | b[i]); } - VEC_INT_OP(T) friend vec_base operator|(const vec_base &a, T b) + BLI_INT_OP(T) friend vec_base operator|(const vec_base &a, T b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] | b); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] | b); } - VEC_INT_OP(T) friend vec_base operator|(T a, const vec_base &b) + BLI_INT_OP(T) friend vec_base operator|(T a, const vec_base &b) { return b | a; } - VEC_INT_OP(T) vec_base &operator|=(T b) + BLI_INT_OP(T) vec_base &operator|=(T b) { - BLI_VEC_OP_SELF(i, (*this)[i] |= b); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] |= b); } - VEC_INT_OP(T) vec_base &operator|=(const vec_base &b) + BLI_INT_OP(T) vec_base &operator|=(const vec_base &b) { - BLI_VEC_OP_SELF(i, (*this)[i] |= b[i]); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] |= b[i]); } - VEC_INT_OP(T) friend vec_base operator^(const vec_base &a, const vec_base &b) + BLI_INT_OP(T) friend vec_base operator^(const vec_base &a, const vec_base &b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] ^ b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] ^ b[i]); } - VEC_INT_OP(T) friend vec_base operator^(const vec_base &a, T b) + BLI_INT_OP(T) friend vec_base operator^(const vec_base &a, T b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] ^ b); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] ^ b); } - VEC_INT_OP(T) friend vec_base operator^(T a, const vec_base &b) + BLI_INT_OP(T) friend vec_base operator^(T a, const vec_base &b) { return b ^ a; } - VEC_INT_OP(T) vec_base &operator^=(T b) + BLI_INT_OP(T) vec_base &operator^=(T b) { - BLI_VEC_OP_SELF(i, (*this)[i] ^= b); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] ^= b); } - VEC_INT_OP(T) vec_base &operator^=(const vec_base &b) + BLI_INT_OP(T) vec_base &operator^=(const vec_base &b) { - BLI_VEC_OP_SELF(i, (*this)[i] ^= b[i]); + BLI_VEC_OP_IMPL_SELF(i, (*this)[i] ^= b[i]); } - VEC_INT_OP(T) friend vec_base operator~(const vec_base &a) + BLI_INT_OP(T) friend vec_base operator~(const vec_base &a) { - BLI_VEC_OP(ret, i, ret[i] = ~a[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = ~a[i]); } /** Modulo operators. */ - VEC_INT_OP(T) friend vec_base operator%(const vec_base &a, const vec_base &b) + BLI_INT_OP(T) friend vec_base operator%(const vec_base &a, const vec_base &b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] % b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] % b[i]); } - VEC_INT_OP(T) friend vec_base operator%(const vec_base &a, T b) + BLI_INT_OP(T) friend vec_base operator%(const vec_base &a, T b) { - BLI_VEC_OP(ret, i, ret[i] = a[i] % b); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] % b); } - VEC_INT_OP(T) friend vec_base operator%(T a, const vec_base &b) + BLI_INT_OP(T) friend vec_base operator%(T a, const vec_base &b) { - BLI_VEC_OP(ret, i, ret[i] = a % b[i]); + BLI_VEC_OP_IMPL(ret, i, ret[i] = a % b[i]); } -#undef VEC_INT_OP -#undef BLI_VEC_OP -#undef BLI_VEC_OP_SELF +#undef BLI_INT_OP +#undef BLI_VEC_OP_IMPL +#undef BLI_VEC_OP_IMPL_SELF /** Compare. */ diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index 2d486783624..c547110a3de 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -33,6 +33,8 @@ # include "BLI_math_mpq.hh" #endif +namespace blender::math { + #ifndef NDEBUG # define BLI_ASSERT_UNIT(v) \ { \ @@ -45,19 +47,18 @@ # define BLI_ASSERT_UNIT(v) (void)(v) #endif -namespace blender::math { - #define bT typename T::base_type #ifdef WITH_GMP -# define BLI_IS_FLT_VEC(T) \ +# define BLI_ENABLE_IF_FLT_VEC(T) \ BLI_ENABLE_IF((std::disjunction_v<std::is_floating_point<typename T::base_type>, \ std::is_same<typename T::base_type, mpq_class>>)) #else -# define BLI_IS_FLT_VEC(T) BLI_ENABLE_IF((std::is_floating_point<typename T::base_type>::value)) +# define BLI_ENABLE_IF_FLT_VEC(T) \ + BLI_ENABLE_IF((std::is_floating_point<typename T::base_type>::value)) #endif -#define BLI_IS_INT_VEC BLI_ENABLE_IF((std::is_integral<bT>::value)) +#define BLI_ENABLE_IF_INT_VEC(T) BLI_ENABLE_IF((std::is_integral<typename T::base_type>::value)) template<typename T> inline T abs(const T &a) { @@ -86,8 +87,27 @@ template<typename T> inline T max(const T &a, const T &b) return result; } -/* Always safe. */ -template<typename T, BLI_IS_FLT_VEC(T)> inline T mod(const T &a, const T &b) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T mod(const T &a, const T &b) +{ + T result; + for (int i = 0; i < T::type_length; i++) { + BLI_assert(b[i] != 0); + result[i] = std::fmod(a[i], b[i]); + } + return result; +} + +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T mod(const T &a, bT b) +{ + BLI_assert(b != 0); + T result; + for (int i = 0; i < T::type_length; i++) { + result[i] = std::fmod(a[i], b); + } + return result; +} + +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_mod(const T &a, const T &b) { T result; for (int i = 0; i < T::type_length; i++) { @@ -96,8 +116,7 @@ template<typename T, BLI_IS_FLT_VEC(T)> inline T mod(const T &a, const T &b) return result; } -/* Always safe. */ -template<typename T, BLI_IS_FLT_VEC(T)> inline T mod(const T &a, bT b) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_mod(const T &a, bT b) { if (b == 0) { return T(0.0f); @@ -115,7 +134,7 @@ template<typename T> inline void min_max(const T &vector, T &min_vec, T &max_vec max_vec = max(vector, max_vec); } -template<typename T, BLI_IS_FLT_VEC(T)> inline T safe_divide(const T &a, const T &b) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_divide(const T &a, const T &b) { T result; for (int i = 0; i < T::type_length; i++) { @@ -124,12 +143,12 @@ template<typename T, BLI_IS_FLT_VEC(T)> inline T safe_divide(const T &a, const T return result; } -template<typename T, BLI_IS_FLT_VEC(T)> inline T safe_divide(const T &a, const bT b) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_divide(const T &a, const bT b) { return (b != 0) ? a / b : T(0.0f); } -template<typename T, BLI_IS_FLT_VEC(T)> inline T floor(const T &a) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T floor(const T &a) { T result; for (int i = 0; i < T::type_length; i++) { @@ -138,7 +157,7 @@ template<typename T, BLI_IS_FLT_VEC(T)> inline T floor(const T &a) return result; } -template<typename T, BLI_IS_FLT_VEC(T)> inline T ceil(const T &a) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T ceil(const T &a) { T result; for (int i = 0; i < T::type_length; i++) { @@ -147,7 +166,7 @@ template<typename T, BLI_IS_FLT_VEC(T)> inline T ceil(const T &a) return result; } -template<typename T, BLI_IS_FLT_VEC(T)> inline T fract(const T &a) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T fract(const T &a) { T result; for (int i = 0; i < T::type_length; i++) { @@ -156,7 +175,7 @@ template<typename T, BLI_IS_FLT_VEC(T)> inline T fract(const T &a) return result; } -template<typename T, BLI_IS_FLT_VEC(T)> inline bT dot(const T &a, const T &b) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT dot(const T &a, const T &b) { bT result = a[0] * b[0]; for (int i = 1; i < T::type_length; i++) { @@ -165,22 +184,36 @@ template<typename T, BLI_IS_FLT_VEC(T)> inline bT dot(const T &a, const T &b) return result; } -template<typename T, BLI_IS_FLT_VEC(T)> inline bT length_squared(const T &a) +template<typename T> inline bT length_manhattan(const T &a) +{ + bT result = std::abs(a[0]); + for (int i = 1; i < T::type_length; i++) { + result += std::abs(a[i]); + } + return result; +} + +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT length_squared(const T &a) { return dot(a, a); } -template<typename T, BLI_IS_FLT_VEC(T)> inline bT length(const T &a) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT length(const T &a) { return std::sqrt(length_squared(a)); } -template<typename T, BLI_IS_FLT_VEC(T)> inline bT distance_squared(const T &a, const T &b) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance_manhattan(const T &a, const T &b) +{ + return length_manhattan(a - b); +} + +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance_squared(const T &a, const T &b) { return length_squared(a - b); } -template<typename T, BLI_IS_FLT_VEC(T)> inline bT distance(const T &a, const T &b) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance(const T &a, const T &b) { return length(a - b); } @@ -203,13 +236,13 @@ template<typename T> uint64_t vector_hash(const T &vec) return result; } -template<typename T, BLI_IS_FLT_VEC(T)> inline T reflect(const T &incident, const T &normal) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T reflect(const T &incident, const T &normal) { BLI_ASSERT_UNIT(normal); return incident - 2.0 * dot(normal, incident) * normal; } -template<typename T, BLI_IS_FLT_VEC(T)> +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T refract(const T &incident, const T &normal, const bT eta) { float dot_ni = dot(normal, incident); @@ -220,7 +253,7 @@ inline T refract(const T &incident, const T &normal, const bT eta) return eta * incident - (eta * dot_ni + sqrt(k)) * normal; } -template<typename T, BLI_IS_FLT_VEC(T)> inline T project(const T &p, const T &v_proj) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T project(const T &p, const T &v_proj) { if (UNLIKELY(v_proj.is_zero())) { return T(0.0f); @@ -228,12 +261,12 @@ template<typename T, BLI_IS_FLT_VEC(T)> inline T project(const T &p, const T &v_ return v_proj * (dot(p, v_proj) / dot(v_proj, v_proj)); } -template<typename T, BLI_IS_FLT_VEC(T)> +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T normalize_and_get_length(const T &v, bT &out_length) { out_length = length_squared(v); /* A larger value causes normalize errors in a scaled down models with camera extreme close. */ - constexpr bT threshold = std::is_same<bT, double>::value ? 1.0e-70 : 1.0e-35f; + constexpr bT threshold = std::is_same_v<bT, double> ? 1.0e-70 : 1.0e-35f; if (out_length > threshold) { out_length = sqrt(out_length); return v / out_length; @@ -243,33 +276,34 @@ inline T normalize_and_get_length(const T &v, bT &out_length) return T(0.0); } -template<typename T, BLI_IS_FLT_VEC(T)> inline T normalize(const T &v) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T normalize(const T &v) { bT len; return normalize_and_get_length(v, len); } -template<typename T, BLI_IS_FLT_VEC(T)> inline T cross(const T &a, const T &b) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T), BLI_ENABLE_IF((T::type_length == 3))> +inline T cross(const T &a, const T &b) { - BLI_STATIC_ASSERT(T::type_length == 3, ""); return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; } -template<typename T, BLI_ENABLE_IF((std::is_same_v<bT, float>))> +template<typename T, + BLI_ENABLE_IF((std::is_same_v<bT, float>)), + BLI_ENABLE_IF((T::type_length == 3))> inline T cross_high_precision(const T &a, const T &b) { - BLI_STATIC_ASSERT(T::type_length == 3, ""); return {(float)((double)a.y * b.z - (double)a.z * b.y), (float)((double)a.z * b.x - (double)a.x * b.z), (float)((double)a.x * b.y - (double)a.y * b.x)}; } -template<typename T, BLI_IS_FLT_VEC(T)> inline T interpolate(const T &a, const T &b, bT t) +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T interpolate(const T &a, const T &b, bT t) { return a * (1 - t) + b * t; } -template<typename T, BLI_IS_FLT_VEC(T)> +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T faceforward(const T &vector, const T &incident, const T &reference) { return (dot(reference, incident) < 0) ? vector : -vector; @@ -283,7 +317,7 @@ template<typename T> inline int dominant_axis(const T &a) /** Intersections. */ -template<typename T, BLI_IS_FLT_VEC(T)> struct isect_result { +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> struct isect_result { enum { LINE_LINE_COLINEAR = -1, LINE_LINE_NONE = 0, @@ -293,11 +327,11 @@ template<typename T, BLI_IS_FLT_VEC(T)> struct isect_result { bT lambda; }; -template<typename T, BLI_IS_FLT_VEC(T)> +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> isect_result<T> isect_seg_seg(const T &v1, const T &v2, const T &v3, const T &v4); -#undef BLI_IS_FLT_VEC -#undef BLI_IS_INT_VEC +#undef BLI_ENABLE_IF_FLT_VEC +#undef BLI_ENABLE_IF_INT_VEC #undef bT } // namespace blender::math |