diff options
author | Hans Goudey <h.goudey@me.com> | 2022-02-16 19:28:18 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-02-16 19:28:26 +0300 |
commit | 399168f3c13fadb41c9fbec8a1b5c56cb6609343 (patch) | |
tree | 6642554c8927280a8ba49bd9c329f2a133afa60a /source/blender/blenlib/BLI_math_base.hh | |
parent | 5b3a415a59cef7183a2539fcc12de8fd1ebf8814 (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.
The existing vector math header is changed to use the `vec_base` type
more explicitly, to allow the compiler's generic function overload resolution
to determine which implementation of each math function to use.
This is a relatively large change, but it also makes the file significantly
easier to understand by reducing the use of macros.
Differential Revision: https://developer.blender.org/D14113
Diffstat (limited to 'source/blender/blenlib/BLI_math_base.hh')
-rw-r--r-- | source/blender/blenlib/BLI_math_base.hh | 104 |
1 files changed, 104 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..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 |