Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-02-15 01:54:07 +0300
committerHans Goudey <h.goudey@me.com>2022-02-15 01:54:07 +0300
commitce570dd434f8395bb9e1d2746aaab1c93a0d0a27 (patch)
treebf4de2b0f9f07a2c0e660a47f0b371d509d925ff /source/blender/blenlib/BLI_math_base.hh
parent8a9a7199abbe83f6d2d7ceeec9052b50cd4202a9 (diff)
BLI: Implement templated math functions for basic types
This is meant to complement the `blender::math` functions recently added by D13791. It's sometimes desired to template an operation to work on vector types, but also basic types like `float` and `int`. This patch adds that ability with a new `BLI_math_base.hh` header. Particularly useful examples are `midpoint` and `interpolate`, but I'm sure others will be added in the future. Implementing the functions separately, rather than as `if constexpr` branches in the existing header is meant to be more scalable, for the possibility of even more math types in the future.
Diffstat (limited to 'source/blender/blenlib/BLI_math_base.hh')
-rw-r--r--source/blender/blenlib/BLI_math_base.hh113
1 files changed, 113 insertions, 0 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..9684867afd3
--- /dev/null
+++ b/source/blender/blenlib/BLI_math_base.hh
@@ -0,0 +1,113 @@
+/* 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_vector.h"
+#include "BLI_utildefines.h"
+
+#ifdef WITH_GMP
+# include "BLI_math_mpq.hh"
+#endif
+
+namespace blender::math {
+
+#ifdef WITH_GMP
+# define BLI_ENABLE_IF_FLT(T) \
+ BLI_ENABLE_IF((std::is_floating_point_v<T> || std::is_same_v<T, mpq_class>))
+#else
+# define BLI_ENABLE_IF_FLT(T) BLI_ENABLE_IF((std::is_floating_point_v<T>))
+#endif
+
+#define BLI_ENABLE_IF_INT(T) BLI_ENABLE_IF((std::is_integral_v<T>))
+
+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_FLT(T)> inline T mod(const T &a, const T &b)
+{
+ return std::fmod(a, b);
+}
+
+template<typename T, BLI_ENABLE_IF_FLT(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 &vector, T &min_vec, T &max_vec)
+{
+ min_vec = min(vector, min_vec);
+ max_vec = max(vector, max_vec);
+}
+
+template<typename T, BLI_ENABLE_IF_FLT(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_FLT(T)> inline T floor(const T &a)
+{
+ return std::floor(a);
+}
+
+template<typename T, BLI_ENABLE_IF_FLT(T)> inline T ceil(const T &a)
+{
+ return std::ceil(a);
+}
+
+template<typename T, BLI_ENABLE_IF_FLT(T)> inline T fract(const T &a)
+{
+ return a - std::floor(a);
+}
+
+template<typename T, typename FactorT, BLI_ENABLE_IF_FLT(T), BLI_ENABLE_IF_FLT(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_FLT(T)> inline T midpoint(const T &a, const T &b)
+{
+ return (a + b) * 0.5;
+}
+
+#undef BLI_ENABLE_IF_FLT
+#undef BLI_ENABLE_IF_INT
+
+} // namespace blender::math