diff --git a/src/lol/math/matrix.h b/src/lol/math/matrix.h index 678578c0..12c85ef6 100644 --- a/src/lol/math/matrix.h +++ b/src/lol/math/matrix.h @@ -33,7 +33,7 @@ namespace lol */ template -struct mat_t +struct mat_t : public linear_ops::base { typedef mat_t type; @@ -59,7 +59,7 @@ private: */ template -struct mat_t +struct mat_t : public linear_ops::base { typedef mat_t type; @@ -124,7 +124,7 @@ private: */ template -struct mat_t +struct mat_t : public linear_ops::base { typedef mat_t type; @@ -235,7 +235,7 @@ private: */ template -struct mat_t +struct mat_t : public linear_ops::base { typedef mat_t type; @@ -427,12 +427,6 @@ static inline mat_t operator +(mat_t const &a, return ret += b; } -template -static inline mat_t operator +(mat_t const &m) -{ - return m; -} - template static inline mat_t &operator -=(mat_t &a, mat_t const &b) diff --git a/src/lol/math/transform.h b/src/lol/math/transform.h index 5a7a0708..0d191d88 100644 --- a/src/lol/math/transform.h +++ b/src/lol/math/transform.h @@ -30,7 +30,7 @@ namespace lol */ template -struct cmplx_t +struct cmplx_t : public linear_ops::base { typedef cmplx_t type; @@ -71,7 +71,7 @@ struct cmplx_t */ template -struct quat_t +struct quat_t : public linear_ops::base { typedef quat_t type; diff --git a/src/lol/math/vector.h b/src/lol/math/vector.h index 96aa6e1b..f953c025 100644 --- a/src/lol/math/vector.h +++ b/src/lol/math/vector.h @@ -17,6 +17,7 @@ #define __LOL_MATH_VECTOR_H__ #include +#include #include #include @@ -34,6 +35,169 @@ namespace lol # define _____ /* */ #endif +/* + * Utility namespaces for traits + */ + +namespace swizzle_ops +{ + + + +} + + +namespace linear_ops +{ + +struct base {}; + +/* + * Unary plus and minus + */ + +template +static inline typename std::enable_if::value, V>::type +operator +(V const &v) +{ + return v; +} + +template +static inline typename std::enable_if::value, V>::type +operator -(V const &v) +{ + V ret; + for (size_t i = 0; i < sizeof(ret) / sizeof(ret[0]); ++i) + ret[i] = -v[i]; + return ret; +} + +/* + * Addition and subtraction + */ + +template +static inline typename std::enable_if::value, V>::type +operator +(V const &a, V const &b) +{ + V ret; + for (size_t i = 0; i < sizeof(ret) / sizeof(ret[0]); ++i) + ret[i] = a[i] + b[i]; + return ret; +} + +template +static inline typename std::enable_if::value, V>::type +&operator +=(V &a, V const &b) +{ + return a = a + b; +} + +template +static inline typename std::enable_if::value, V>::type +operator -(V const &a, V const &b) +{ + V ret; + for (size_t i = 0; i < sizeof(ret) / sizeof(ret[0]); ++i) + ret[i] = a[i] - b[i]; + return ret; +} + +template +static inline typename std::enable_if::value, V>::type +&operator -=(V &a, V const &b) +{ + return a = a - b; +} + +} /* namespace linear_ops */ + +namespace componentwise_ops +{ + +struct base {}; + +template +static inline typename std::enable_if::value, V>::type +operator *(V const &a, V const &b) +{ + V ret; + for (size_t i = 0; i < sizeof(ret) / sizeof(ret[0]); ++i) + ret[i] = a[i] * b[i]; + return ret; +} + +template +static inline typename std::enable_if::value, V>::type +&operator *=(V &a, V const &b) +{ + return a = a * b; +} + +template +static inline typename std::enable_if::value, V>::type +operator /(V const &a, V const &b) +{ + V ret; + for (size_t i = 0; i < sizeof(ret) / sizeof(ret[0]); ++i) + ret[i] = a[i] / b[i]; + return ret; +} + +template +static inline typename std::enable_if::value, V>::type +&operator /=(V &a, V const &b) +{ + return a = a / b; +} + +/* + * Comparisons + */ + +template +static inline typename std::enable_if::value, bool>::type +operator <(V const &a, V const &b) +{ + for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i) + if (!(a[i] < b[i])) + return false; + return true; +} + +template +static inline typename std::enable_if::value, bool>::type +operator >(V const &a, V const &b) +{ + for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i) + if (!(a[i] > b[i])) + return false; + return true; +} + +template +static inline typename std::enable_if::value, bool>::type +operator <=(V const &a, V const &b) +{ + for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i) + if (!(a[i] <= b[i])) + return false; + return true; +} + +template +static inline typename std::enable_if::value, bool>::type +operator >=(V const &a, V const &b) +{ + for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i) + if (!(a[i] >= b[i])) + return false; + return true; +} + +} /* namespace componentwise_ops */ + /* * Magic vector swizzling (part 1/2) * These vectors are empty, but thanks to static_cast we can take their @@ -79,7 +243,9 @@ struct vec_t /* The generic “vec_t” type, which is a fixed-size vector with no * swizzling. There's an override for N=2, N=3, N=4 that has swizzling. */ template -struct vec_t +struct vec_t + : public linear_ops::base, + public componentwise_ops::base { typedef vec_t type; @@ -94,21 +260,6 @@ private: * Helper macros for vector type member functions */ -#define LOL_V_VV_OP(op) \ - friend inline type operator op(type const &a, type const &b) \ - { \ - type ret; \ - for (size_t i = 0; i < sizeof(type) / sizeof(T); ++i) \ - ret[i] = a[i] op b[i]; \ - return ret; \ - } - -#define LOL_V_VV_ASSIGN_OP(op) \ - friend inline type &operator op##=(type &a, type const &b) \ - { \ - return a = a op b; \ - } - #define LOL_V_VS_OP(op) \ friend inline type operator op(type const &a, T const &val) \ { \ @@ -148,30 +299,6 @@ private: void printf() const; \ String tostring() const; \ \ - /* vec_t -(vec_t) - * vec_t +(vec_t) */ \ - friend inline type operator -(type const &a) \ - { \ - type ret; \ - for (size_t i = 0; i < sizeof(type) / sizeof(T); ++i) \ - ret[i] = -a[i]; \ - return ret; \ - } \ - \ - friend inline type operator +(type const &a) \ - { \ - return a; \ - } \ - \ - /* vec_t +(vec_t, vec_t) - * vec_t -(vec_t, vec_t) - * vec_t +=(vec_t, vec_t) - * vec_t -=(vec_t, vec_t) */ \ - LOL_V_VV_OP(+); \ - LOL_V_VV_OP(-); \ - LOL_V_VV_ASSIGN_OP(+); \ - LOL_V_VV_ASSIGN_OP(-); \ - \ /* vec_t *(vec_t, scalar) * vec_t /(vec_t, scalar) * vec_t *=(vec_t, scalar) @@ -186,25 +313,6 @@ private: LOL_B_VV_OP(==, ==, true) \ LOL_B_VV_OP(!=, ==, false) -#define LOL_VECTOR_MEMBER_OPS() \ - /* vec_t *(vec_t, vec_t) - * vec_t /(vec_t, vec_t) - * vec_t *=(vec_t, vec_t) - * vec_t /=(vec_t, vec_t) */ \ - LOL_V_VV_OP(*); \ - LOL_V_VV_OP(/); \ - LOL_V_VV_ASSIGN_OP(*); \ - LOL_V_VV_ASSIGN_OP(/); \ - \ - /* bool >=(vec_t, vec_t) - * bool <=(vec_t, vec_t) - * bool >(vec_t, vec_t) - * bool <(vec_t, vec_t) */ \ - LOL_B_VV_OP(<=, <=, true) \ - LOL_B_VV_OP(>=, >=, true) \ - LOL_B_VV_OP(<, <, true) \ - LOL_B_VV_OP(>, >, true) - #define LOL_NONVECTOR_MEMBER_OPS() \ /* vec_t *(scalar, vec_t) (no division, it works differently) */ \ friend inline type operator *(T const &val, type const &a) \ @@ -221,6 +329,8 @@ private: template struct vec_t + : public linear_ops::base, + public componentwise_ops::base { typedef vec_t type; @@ -246,7 +356,6 @@ struct vec_t : x(X), y(X) {} LOL_COMMON_MEMBER_OPS(x) - LOL_VECTOR_MEMBER_OPS() static const vec_t zero; static const vec_t axis_x; @@ -302,6 +411,8 @@ struct vec_t template struct vec_t + : public linear_ops::base, + public componentwise_ops::base { typedef vec_t type; @@ -331,7 +442,6 @@ struct vec_t : x(X), y(YZ.x), z(YZ.y) {} LOL_COMMON_MEMBER_OPS(x) - LOL_VECTOR_MEMBER_OPS() static vec_t toeuler_xyx(quat_t const &q); static vec_t toeuler_xzx(quat_t const &q); @@ -513,6 +623,8 @@ struct vec_t template struct vec_t + : public linear_ops::base, + public componentwise_ops::base { typedef vec_t type; @@ -551,7 +663,6 @@ struct vec_t : x(X), y(YZW.x), z(YZW.y), w(YZW.z) {} LOL_COMMON_MEMBER_OPS(x) - LOL_VECTOR_MEMBER_OPS() static const vec_t zero; static const vec_t axis_x; @@ -939,13 +1050,23 @@ static inline bool operator !=(vec_t const &a, #define LOL_SWIZZLE_V_VV_OP(op) \ template \ - inline vec_t operator op(vec_t const &a, \ - vec_t const &b) \ + inline typename std::enable_if>::type \ + operator op(vec_t const &a, \ + vec_t const &b) \ { \ return vec_t(a) op vec_t(b); \ } \ \ template \ + inline typename std::enable_if>::type & \ + operator op##=(vec_t &a, \ + vec_t const &b) \ + { \ + return a op##= vec_t(b); \ + } \ + \ + template \ inline vec_t operator op(vec_t a, T const &b) \ { \ return vec_t(a) op b; \