BLI: Adjust interpolation to support integers, other tweaks
In order to allow interpolation of integers with a float, add a separate template parameter for the factor and multiplication types. Also move some helper constexpr variables to the "base" header (reversing the dependency to "base" -> "vector"). This also adds a distance function for scalar types, which is helpful to allow sharing code between vectors and basic types. Differential Revision: https://developer.blender.org/D14446
This commit is contained in:
parent
1243cb803e
commit
378022c797
|
@ -12,7 +12,6 @@
|
|||
#include <type_traits>
|
||||
|
||||
#include "BLI_math_base_safe.h"
|
||||
#include "BLI_math_vec_types.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#ifdef WITH_GMP
|
||||
|
@ -21,6 +20,15 @@
|
|||
|
||||
namespace blender::math {
|
||||
|
||||
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>;
|
||||
|
||||
template<typename T> inline bool is_zero(const T &a)
|
||||
{
|
||||
return a == T(0);
|
||||
|
@ -84,19 +92,23 @@ template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T ceil(const
|
|||
return std::ceil(a);
|
||||
}
|
||||
|
||||
template<typename T> inline T distance(const T &a, const T &b)
|
||||
{
|
||||
return std::abs(a - b);
|
||||
}
|
||||
|
||||
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)
|
||||
template<typename T, typename FactorT, BLI_ENABLE_IF((is_math_float_type<FactorT>))>
|
||||
inline T interpolate(const T &a, const T &b, const FactorT &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)
|
||||
template<typename T> inline T midpoint(const T &a, const T &b)
|
||||
{
|
||||
return (a + b) * T(0.5);
|
||||
}
|
||||
|
|
|
@ -321,7 +321,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
|
|||
BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b[i]);
|
||||
}
|
||||
|
||||
friend vec_base operator*(const vec_base &a, T b)
|
||||
template<typename FactorT> friend vec_base operator*(const vec_base &a, FactorT b)
|
||||
{
|
||||
BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b);
|
||||
}
|
||||
|
@ -579,13 +579,4 @@ 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
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include "BLI_math_base_safe.h"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_vec_types.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
@ -339,10 +339,10 @@ inline vec_base<T, 3> cross_poly(Span<vec_base<T, 3>> poly)
|
|||
return n;
|
||||
}
|
||||
|
||||
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
|
||||
template<typename T, typename FactorT, int Size, BLI_ENABLE_IF((is_math_float_type<FactorT>))>
|
||||
inline vec_base<T, Size> interpolate(const vec_base<T, Size> &a,
|
||||
const vec_base<T, Size> &b,
|
||||
const T &t)
|
||||
const FactorT &t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
|
|
@ -151,4 +151,9 @@ TEST(math_base, Midpoint)
|
|||
EXPECT_NEAR(math::midpoint(100.0f, 200.0f), 150.0f, 1e-4f);
|
||||
}
|
||||
|
||||
TEST(math_base, InterpolateInt)
|
||||
{
|
||||
EXPECT_EQ(math::interpolate(100, 200, 0.4f), 140);
|
||||
}
|
||||
|
||||
} // namespace blender::tests
|
||||
|
|
|
@ -85,4 +85,24 @@ TEST(math_vector, Clamp)
|
|||
EXPECT_EQ(result_2.z, -50);
|
||||
}
|
||||
|
||||
TEST(math_vector, InterpolateInt)
|
||||
{
|
||||
const int3 a(0, -100, 50);
|
||||
const int3 b(0, 100, 100);
|
||||
const int3 result = math::interpolate(a, b, 0.75);
|
||||
EXPECT_EQ(result.x, 0);
|
||||
EXPECT_EQ(result.y, 50);
|
||||
EXPECT_EQ(result.z, 87);
|
||||
}
|
||||
|
||||
TEST(math_vector, InterpolateFloat)
|
||||
{
|
||||
const float3 a(40.0f, -100.0f, 50.0f);
|
||||
const float3 b(20.0f, 100.0f, 100.0f);
|
||||
const float3 result = math::interpolate(a, b, 0.5);
|
||||
EXPECT_FLOAT_EQ(result.x, 30.0f);
|
||||
EXPECT_FLOAT_EQ(result.y, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.z, 75.0f);
|
||||
}
|
||||
|
||||
} // namespace blender::tests
|
||||
|
|
Loading…
Reference in New Issue