diff --git a/src/lol/math/half.h b/src/lol/math/half.h index 23031e7e..531295bf 100644 --- a/src/lol/math/half.h +++ b/src/lol/math/half.h @@ -114,6 +114,15 @@ public: uint16_t bits; }; +static inline half min(half a, half b) { return a < b ? a : b; } +static inline half max(half a, half b) { return a > b ? a : b; } + +static inline half clamp(half x, half a, half b) +{ + return (x < a) ? a : (x > b) ? b : x; +} + + #define DECLARE_COERCE_HALF_NUMERIC_OPS(op, type, ret, x2, h2) \ inline ret operator op(type x, half h) { return x2 op h2; } \ inline ret operator op(half h, type x) { return h2 op x2; } \ diff --git a/src/lol/math/real.h b/src/lol/math/real.h index 6a178c6f..5546b6d0 100644 --- a/src/lol/math/real.h +++ b/src/lol/math/real.h @@ -71,6 +71,12 @@ public: bool operator !() const; operator bool() const; + /* Comparison functions */ + template<int M> friend Real<M> min(Real<M> const &a, Real<M> const &b); + template<int M> friend Real<M> max(Real<M> const &a, Real<M> const &b); + template<int M> friend Real<M> clamp(Real<M> const &x, + Real<M> const &a, Real<M> const &b); + /* Trigonometric functions */ template<int M> friend Real<M> sin(Real<M> const &x); template<int M> friend Real<M> cos(Real<M> const &x); @@ -227,6 +233,10 @@ template<> bool real::operator >=(real const &x) const; template<> bool real::operator !() const; template<> real::operator bool() const; +template<> real min(real const &a, real const &b); +template<> real max(real const &a, real const &b); +template<> real clamp(real const &x, real const &a, real const &b); + template<> real sin(real const &x); template<> real cos(real const &x); template<> real tan(real const &x); diff --git a/src/lol/math/vector.h b/src/lol/math/vector.h index 840cb946..1bf5be72 100644 --- a/src/lol/math/vector.h +++ b/src/lol/math/vector.h @@ -976,6 +976,12 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y) * Common operators for all vector types, including quaternions */ +/* + * vec +(vec, vec) (also complex & quaternion) + * vec -(vec, vec) (also complex & quaternion) + * vec *(vec, vec) + * vec /(vec, vec) + */ #define DECLARE_VECTOR_VECTOR_COERCE_OP(tname, op, tprefix, t1, t2, tf) \ tprefix \ inline tname<tf> operator op(tname<t1> const &a, tname<t2> const &b) \ @@ -986,6 +992,12 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y) return ret; \ } +/* + * vec +=(vec, vec) (also complex & quaternion) + * vec -=(vec, vec) (also complex & quaternion) + * vec *=(vec, vec) + * vec /=(vec, vec) + */ #define DECLARE_VECTOR_VECTOR_OP(tname, op, tprefix, type) \ tprefix \ inline tname<type> operator op##=(tname<type> &a, tname<type> const &b) \ @@ -993,6 +1005,77 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y) return a = a op b; \ } +/* + * vec min(vec, vec) (also max) + * vec min(vec, scalar) (also max) + * vec min(scalar, vec) (also max) + */ +#define DECLARE_VECTOR_MINMAX_OP(tname, op, tprefix, type) \ + tprefix \ + inline tname<type> op(tname<type> const &a, tname<type> const &b) \ + { \ + using std::op; \ + tname<type> ret; \ + for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ + ret[n] = op(a[n], b[n]); \ + return ret; \ + } \ + \ + tprefix \ + inline tname<type> op(tname<type> const &a, type const &b) \ + { \ + using std::op; \ + tname<type> ret; \ + for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ + ret[n] = op(a[n], b); \ + return ret; \ + } \ + \ + tprefix \ + inline tname<type> op(type const &a, tname<type> const &b) \ + { \ + using std::op; \ + tname<type> ret; \ + for (size_t n = 0; n < sizeof(b) / sizeof(type); n++) \ + ret[n] = op(a, b[n]); \ + return ret; \ + } + +/* + * vec clamp(vec, vec, vec) + * vec clamp(vec, vec, scalar) + * vec clamp(vec, scalar, vec) + */ +#define DECLARE_VECTOR_CLAMP_OP(tname, tprefix, type) \ + tprefix \ + inline tname<type> clamp(tname<type> const &x, \ + tname<type> const &a, tname<type> const &b) \ + { \ + return max(min(x, b), a); \ + } \ + \ + tprefix \ + inline tname<type> clamp(tname<type> const &x, \ + type const &a, tname<type> const &b) \ + { \ + return max(min(x, b), a); \ + } \ + \ + tprefix \ + inline tname<type> clamp(tname<type> const &x, \ + tname<type> const &a, type const &b) \ + { \ + return max(min(x, b), a); \ + } + +/* + * bool ==(vec, vec) (also complex & quaternion) + * bool !=(vec, vec) (also complex & quaternion) + * bool >=(vec, vec) + * bool <=(vec, vec) + * bool >(vec, vec) + * bool <(vec, vec) + */ #define DECLARE_VECTOR_VECTOR_BOOLOP(tname, op, op2, ret, tprefix, t1, t2) \ tprefix \ inline bool operator op(tname<t1> const &a, tname<t2> const &b) \ @@ -1003,6 +1086,12 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y) return ret; \ } +/* + * vec *(vec, scalar) (also complex & quaternion) + * vec *(scalar, vec) (also complex & quaternion) + * vec /(vec, scalar) (also complex & quaternion) + * vec /(scalar, vec) (also complex & quaternion) + */ #define DECLARE_VECTOR_SCALAR_COERCE_OP(tname, op, tprefix, t1, t2, tf) \ tprefix \ inline tname<tf> operator op(tname<t1> const &a, t2 const &val) \ @@ -1022,6 +1111,10 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y) return ret; \ } +/* + * vec *=(vec, scalar) (also complex & quaternion) + * vec /=(vec, scalar) (also complex & quaternion) + */ #define DECLARE_VECTOR_SCALAR_OP(tname, op, tprefix, type) \ tprefix \ inline tname<type> operator op##=(tname<type> &a, type const &val) \ @@ -1097,7 +1190,11 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y) DECLARE_VECTOR_SCALAR_OP(tname, /, tprefix, type) \ \ DECLARE_VECTOR_VECTOR_OP(tname, -, tprefix, type) \ - DECLARE_VECTOR_VECTOR_OP(tname, +, tprefix, type) + DECLARE_VECTOR_VECTOR_OP(tname, +, tprefix, type) \ + \ + DECLARE_VECTOR_MINMAX_OP(tname, min, tprefix, type) \ + DECLARE_VECTOR_MINMAX_OP(tname, max, tprefix, type) \ + DECLARE_VECTOR_CLAMP_OP(tname, tprefix, type) #define DECLARE_VECTOR_COERCE_OPS(tname, tprefix, t1, t2, tf) \ DECLARE_VECTOR_VECTOR_COERCE_OP(tname, *, tprefix, t1, t2, tf) \ diff --git a/src/math/real.cpp b/src/math/real.cpp index cb4def60..a66b167c 100644 --- a/src/math/real.cpp +++ b/src/math/real.cpp @@ -558,6 +558,21 @@ template<> real::operator bool() const return exponent && (~exponent || m_mantissa[0] == 0); } +template<> real min(real const &a, real const &b) +{ + return (a < b) ? a : b; +} + +template<> real max(real const &a, real const &b) +{ + return (a > b) ? a : b; +} + +template<> real clamp(real const &x, real const &a, real const &b) +{ + return (x < a) ? a : (x > b) ? b : x; +} + template<> real re(real const &x) { if (!(x.m_signexp << 1))