diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_math_base.hh | 104 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_vec_types.hh | 19 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.hh | 245 | ||||
-rw-r--r-- | source/blender/blenlib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/delaunay_2d.cc | 4 | ||||
-rw-r--r-- | source/blender/blenlib/tests/BLI_math_base_test.cc | 21 |
6 files changed, 275 insertions, 119 deletions
diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh new file mode 100644 index 00000000000..6a988eda8a9 --- /dev/null +++ b/source/blender/blenlib/BLI_math_base.hh @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. */ + +#pragma once + +/** \file + * \ingroup bli + */ + +#include <algorithm> +#include <cmath> +#include <type_traits> + +#include "BLI_math_base_safe.h" +#include "BLI_math_vec_types.hh" +#include "BLI_utildefines.h" + +#ifdef WITH_GMP +# include "BLI_math_mpq.hh" +#endif + +namespace blender::math { + +template<typename T> inline bool is_zero(const T &a) +{ + return a == T(0); +} + +template<typename T> inline bool is_any_zero(const T &a) +{ + return is_zero(a); +} + +template<typename T> inline T abs(const T &a) +{ + return std::abs(a); +} + +template<typename T> inline T min(const T &a, const T &b) +{ + return std::min(a, b); +} + +template<typename T> inline T max(const T &a, const T &b) +{ + return std::max(a, b); +} + +template<typename T> inline T clamp(const T &a, const T &min, const T &max) +{ + return std::clamp(a, min, max); +} + +template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T mod(const T &a, const T &b) +{ + return std::fmod(a, b); +} + +template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T safe_mod(const T &a, const T &b) +{ + return (b != 0) ? std::fmod(a, b) : 0; +} + +template<typename T> inline void min_max(const T &value, T &min, T &max) +{ + min = math::min(value, min); + max = math::max(value, max); +} + +template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T safe_divide(const T &a, const T &b) +{ + return (b != 0) ? a / b : T(0.0f); +} + +template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T floor(const T &a) +{ + return std::floor(a); +} + +template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T ceil(const T &a) +{ + return std::ceil(a); +} + +template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T fract(const T &a) +{ + return a - std::floor(a); +} + +template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T interpolate(const T &a, const T &b, const T &t) +{ + return a * (1 - t) + b * t; +} + +template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T midpoint(const T &a, const T &b) +{ + return (a + b) * T(0.5); +} + +} // namespace blender::math diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh index 8d6f04ab15f..b6b3d15aefe 100644 --- a/source/blender/blenlib/BLI_math_vec_types.hh +++ b/source/blender/blenlib/BLI_math_vec_types.hh @@ -14,6 +14,10 @@ #include "BLI_utildefines.h" +#ifdef WITH_GMP +# include "BLI_math_mpq.hh" +#endif + namespace blender { /* clang-format off */ @@ -60,10 +64,10 @@ template<typename T> uint64_t vector_hash(const T &vec) return result; } -template<typename T> inline bool is_any_zero(const T &a) +template<typename T, int Size> inline bool is_any_zero(const vec_struct_base<T, Size> &a) { - for (int i = 0; i < T::type_length; i++) { - if (a[i] == typename T::base_type(0)) { + for (int i = 0; i < Size; i++) { + if (a[i] == T(0)) { return true; } } @@ -579,4 +583,13 @@ using double2 = vec_base<double, 2>; using double3 = vec_base<double, 3>; using double4 = vec_base<double, 4>; +template<typename T> +inline constexpr bool is_math_float_type = (std::is_floating_point_v<T> +#ifdef WITH_GMP + || std::is_same_v<T, mpq_class> +#endif +); + +template<typename T> inline constexpr bool is_math_integral_type = std::is_integral_v<T>; + } // namespace blender diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index d2ef2a1c5c8..3bb89bb26b2 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -15,10 +15,6 @@ #include "BLI_span.hh" #include "BLI_utildefines.h" -#ifdef WITH_GMP -# include "BLI_math_mpq.hh" -#endif - namespace blender::math { #ifndef NDEBUG @@ -33,277 +29,293 @@ namespace blender::math { # define BLI_ASSERT_UNIT(v) (void)(v) #endif -#define bT typename T::base_type - -#ifdef WITH_GMP -# define BLI_ENABLE_IF_FLT_VEC(T) \ - BLI_ENABLE_IF((std::is_floating_point_v<typename T::base_type> || \ - std::is_same_v<typename T::base_type, mpq_class>)) -#else -# define BLI_ENABLE_IF_FLT_VEC(T) BLI_ENABLE_IF((std::is_floating_point_v<typename T::base_type>)) -#endif - -#define BLI_ENABLE_IF_INT_VEC(T) BLI_ENABLE_IF((std::is_integral_v<typename T::base_type>)) - -template<typename T> inline bool is_zero(const T &a) +template<typename T, int Size> inline bool is_zero(const vec_base<T, Size> &a) { - for (int i = 0; i < T::type_length; i++) { - if (a[i] != bT(0)) { + for (int i = 0; i < Size; i++) { + if (a[i] != T(0)) { return false; } } return true; } -template<typename T> inline T abs(const T &a) +template<typename T, int Size> inline vec_base<T, Size> abs(const vec_base<T, Size> &a) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = a[i] >= 0 ? a[i] : -a[i]; } return result; } -template<typename T> inline T min(const T &a, const T &b) +template<typename T, int Size> +inline vec_base<T, Size> min(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = a[i] < b[i] ? a[i] : b[i]; } return result; } -template<typename T> inline T max(const T &a, const T &b) +template<typename T, int Size> +inline vec_base<T, Size> max(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = a[i] > b[i] ? a[i] : b[i]; } return result; } -template<typename T> inline T clamp(const T &a, const T &min_v, const T &max_v) +template<typename T, int Size> +inline T clamp(const vec_base<T, Size> &a, + const vec_base<T, Size> &min, + const vec_base<T, Size> &max) { - T result = a; - for (int i = 0; i < T::type_length; i++) { - CLAMP(result[i], min_v[i], max_v[i]); + vec_base<T, Size> result = a; + for (int i = 0; i < Size; i++) { + std::clamp(result[i], min[i], max[i]); } return result; } -template<typename T> inline T clamp(const T &a, const bT &min_v, const bT &max_v) +template<typename T, int Size> +inline vec_base<T, Size> clamp(const vec_base<T, Size> &a, const T &min, const T &max) { - T result = a; - for (int i = 0; i < T::type_length; i++) { - CLAMP(result[i], min_v, max_v); + vec_base<T, Size> result = a; + for (int i = 0; i < Size; i++) { + std::clamp(result[i], min, max); } return result; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T mod(const T &a, const T &b) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> mod(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; 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) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> mod(const vec_base<T, Size> &a, const T &b) { BLI_assert(b != 0); - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; 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) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T safe_mod(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = (b[i] != 0) ? std::fmod(a[i], b[i]) : 0; } return result; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_mod(const T &a, bT b) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T safe_mod(const vec_base<T, Size> &a, const T &b) { if (b == 0) { - return T(0.0f); + return vec_base<T, Size>(0); } - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = std::fmod(a[i], b); } return result; } -template<typename T> inline void min_max(const T &vector, T &min_vec, T &max_vec) +template<typename T, int Size> +inline void min_max(const vec_base<T, Size> &vector, + vec_base<T, Size> &min, + vec_base<T, Size> &max) { - min_vec = min(vector, min_vec); - max_vec = max(vector, max_vec); + min = math::min(vector, min); + max = math::max(vector, max); } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_divide(const T &a, const T &b) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> safe_divide(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = (b[i] == 0) ? 0 : a[i] / b[i]; } return result; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_divide(const T &a, const bT b) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> safe_divide(const vec_base<T, Size> &a, const T &b) { - return (b != 0) ? a / b : T(0.0f); + return (b != 0) ? a / b : vec_base<T, Size>(0.0f); } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T floor(const T &a) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> floor(const vec_base<T, Size> &a) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = std::floor(a[i]); } return result; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T ceil(const T &a) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> ceil(const vec_base<T, Size> &a) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = std::ceil(a[i]); } return result; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T fract(const T &a) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> fract(const vec_base<T, Size> &a) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = a[i] - std::floor(a[i]); } return result; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT dot(const T &a, const T &b) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T dot(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { - bT result = a[0] * b[0]; - for (int i = 1; i < T::type_length; i++) { + T result = a[0] * b[0]; + for (int i = 1; i < Size; i++) { result += a[i] * b[i]; } return result; } -template<typename T> inline bT length_manhattan(const T &a) +template<typename T, int Size> inline T length_manhattan(const vec_base<T, Size> &a) { - bT result = std::abs(a[0]); - for (int i = 1; i < T::type_length; i++) { + T result = std::abs(a[0]); + for (int i = 1; i < Size; i++) { result += std::abs(a[i]); } return result; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT length_squared(const T &a) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T length_squared(const vec_base<T, Size> &a) { return dot(a, a); } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT length(const T &a) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T length(const vec_base<T, Size> &a) { return std::sqrt(length_squared(a)); } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance_manhattan(const T &a, const T &b) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T distance_manhattan(const vec_base<T, Size> &a, const vec_base<T, Size> &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) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T distance_squared(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { return length_squared(a - b); } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance(const T &a, const T &b) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline T distance(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { return length(a - b); } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T reflect(const T &incident, const T &normal) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> reflect(const vec_base<T, Size> &incident, + const vec_base<T, Size> &normal) { BLI_ASSERT_UNIT(normal); return incident - 2.0 * dot(normal, incident) * normal; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> -inline T refract(const T &incident, const T &normal, const bT eta) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> refract(const vec_base<T, Size> &incident, + const vec_base<T, Size> &normal, + const T &eta) { float dot_ni = dot(normal, incident); float k = 1.0f - eta * eta * (1.0f - dot_ni * dot_ni); if (k < 0.0f) { - return T(0.0f); + return vec_base<T, Size>(0.0f); } return eta * incident - (eta * dot_ni + sqrt(k)) * normal; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T project(const T &p, const T &v_proj) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> project(const vec_base<T, Size> &p, const vec_base<T, Size> &v_proj) { if (UNLIKELY(is_zero(v_proj))) { - return T(0.0f); + return vec_base<T, Size>(0.0f); } return v_proj * (dot(p, v_proj) / dot(v_proj, v_proj)); } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> -inline T normalize_and_get_length(const T &v, bT &out_length) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> normalize_and_get_length(const vec_base<T, Size> &v, T &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_v<bT, double> ? 1.0e-70 : 1.0e-35f; + constexpr T threshold = std::is_same_v<T, double> ? 1.0e-70 : 1.0e-35f; if (out_length > threshold) { out_length = sqrt(out_length); return v / out_length; } /* Either the vector is small or one of it's values contained `nan`. */ out_length = 0.0; - return T(0.0); + return vec_base<T, Size>(0.0); } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T normalize(const T &v) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> normalize(const vec_base<T, Size> &v) { - bT len; + T len; return normalize_and_get_length(v, len); } -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) +template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, 3> cross(const vec_base<T, 3> &a, const vec_base<T, 3> &b) { 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>)), - BLI_ENABLE_IF((T::type_length == 3))> -inline T cross_high_precision(const T &a, const T &b) +inline vec_base<float, 3> cross_high_precision(const vec_base<float, 3> &a, + const vec_base<float, 3> &b) { 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_ENABLE_IF_FLT_VEC(T), BLI_ENABLE_IF((T::type_length == 3))> -inline T cross_poly(Span<T> poly) +template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, 3> cross_poly(Span<vec_base<T, 3>> poly) { /* Newell's Method. */ int nv = static_cast<int>(poly.size()); if (nv < 3) { - return T(0, 0, 0); + return vec_base<T, 3>(0, 0, 0); } - const T *v_prev = &poly[nv - 1]; - const T *v_curr = &poly[0]; - T n(0, 0, 0); + const vec_base<T, 3> *v_prev = &poly[nv - 1]; + const vec_base<T, 3> *v_curr = &poly[0]; + vec_base<T, 3> n(0, 0, 0); for (int i = 0; i < nv;) { n[0] = n[0] + ((*v_prev)[1] - (*v_curr)[1]) * ((*v_prev)[2] + (*v_curr)[2]); n[1] = n[1] + ((*v_prev)[2] - (*v_curr)[2]) * ((*v_prev)[0] + (*v_curr)[0]); @@ -317,25 +329,31 @@ inline T cross_poly(Span<T> poly) return n; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T interpolate(const T &a, const T &b, bT t) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> interpolate(const vec_base<T, Size> &a, + const vec_base<T, Size> &b, + const T &t) { return a * (1 - t) + b * t; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T midpoint(const T &a, const T &b) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> midpoint(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { return (a + b) * 0.5; } -template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> -inline T faceforward(const T &vector, const T &incident, const T &reference) +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +inline vec_base<T, Size> faceforward(const vec_base<T, Size> &vector, + const vec_base<T, Size> &incident, + const vec_base<T, Size> &reference) { return (dot(reference, incident) < 0) ? vector : -vector; } -template<typename T> inline int dominant_axis(const T &a) +template<typename T> inline int dominant_axis(const vec_base<T, 3> &a) { - T b = abs(a); + vec_base<T, 3> b = abs(a); return ((b.x > b.y) ? ((b.x > b.z) ? 0 : 2) : ((b.y > b.z) ? 1 : 2)); } @@ -348,14 +366,13 @@ template<typename T> struct isect_result { LINE_LINE_EXACT = 1, LINE_LINE_CROSS = 2, } kind; - bT lambda; + typename T::base_type lambda; }; -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_ENABLE_IF_FLT_VEC -#undef BLI_ENABLE_IF_INT_VEC -#undef bT +template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))> +isect_result<vec_base<T, Size>> isect_seg_seg(const vec_base<T, Size> &v1, + const vec_base<T, Size> &v2, + const vec_base<T, Size> &v3, + const vec_base<T, Size> &v4); } // namespace blender::math diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 29015084679..e67d673eb73 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -220,6 +220,7 @@ set(SRC BLI_map.hh BLI_map_slots.hh BLI_math.h + BLI_math_base.hh BLI_math_base.h BLI_math_base_safe.h BLI_math_bits.h diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc index cb0ba763c94..cc5550ee34a 100644 --- a/source/blender/blenlib/intern/delaunay_2d.cc +++ b/source/blender/blenlib/intern/delaunay_2d.cc @@ -1691,7 +1691,7 @@ void fill_crossdata_for_intersect(const FatCo<T> &curco, BLI_assert(se_vcva->vert == vc && se_vcva->next->vert == va); BLI_assert(se_vcvb->vert == vc && se_vcvb->next->vert == vb); UNUSED_VARS_NDEBUG(vc); - auto isect = isect_seg_seg<vec2<T>>(va->co.exact, vb->co.exact, curco.exact, v2->co.exact); + auto isect = isect_seg_seg(va->co.exact, vb->co.exact, curco.exact, v2->co.exact); T &lambda = isect.lambda; switch (isect.kind) { case isect_result<vec2<T>>::LINE_LINE_CROSS: { @@ -2556,7 +2556,7 @@ template<typename T> void detect_holes(CDT_state<T> *cdt_state) if (e->symedges[0].face->visit_index == e->symedges[1].face->visit_index) { continue; /* Don't count hits on edges between faces in same region. */ } - auto isect = isect_seg_seg<vec2<T>>(ray_end.exact, + auto isect = isect_seg_seg(ray_end.exact, mid.exact, e->symedges[0].vert->co.exact, e->symedges[1].vert->co.exact); diff --git a/source/blender/blenlib/tests/BLI_math_base_test.cc b/source/blender/blenlib/tests/BLI_math_base_test.cc index 33acefeeac2..62f2b2775d0 100644 --- a/source/blender/blenlib/tests/BLI_math_base_test.cc +++ b/source/blender/blenlib/tests/BLI_math_base_test.cc @@ -3,6 +3,10 @@ #include "testing/testing.h" #include "BLI_math.h" +#include "BLI_math_base.hh" +#include "BLI_math_vector.hh" + +namespace blender::tests { /* In tests below, when we are using -1.0f as max_diff value, we actually turn the function into a * pure-ULP one. */ @@ -131,3 +135,20 @@ TEST(math_base, FloorPowerOf10) EXPECT_NEAR(floor_power_of_10(100.1f), 100.0f, 1e-4f); EXPECT_NEAR(floor_power_of_10(99.9f), 10.0f, 1e-4f); } + +TEST(math_base, MinVectorAndFloat) +{ + EXPECT_EQ(math::min(1.0f, 2.0f), 1.0f); +} + +TEST(math_base, ClampInt) +{ + EXPECT_EQ(math::clamp(111, -50, 101), 101); +} + +TEST(math_base, Midpoint) +{ + EXPECT_NEAR(math::midpoint(100.0f, 200.0f), 150.0f, 1e-4f); +} + +} // namespace blender::tests |