diff --git a/src/debug/quad.cpp b/src/debug/quad.cpp index eacd6d9b..1e4d7c8d 100644 --- a/src/debug/quad.cpp +++ b/src/debug/quad.cpp @@ -200,7 +200,7 @@ void DebugQuad::TickDraw(float deltams) /* Prepare our quad coordinates */ ivec2 const layout(7, 5); - data->step = vec2(2.0f, -2.0f) / (4 * layout + ivec2(1)); + data->step = vec2(2.0f, -2.0f) / vec2(4 * layout + ivec2(1)); data->orig = vec2(-1.0f, 1.0f) + data->step; data->aa = data->orig; data->bb = data->orig + 3.0f * data->step; diff --git a/src/input.cpp b/src/input.cpp index b9c4a555..c759e283 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -134,7 +134,7 @@ void Input::SetMousePos(ivec2 coord) { if (data->entities[n] == top) { - data->entities[n]->mousepos = coord - top->bbox[0].xy(); + data->entities[n]->mousepos = coord - (ivec2)top->bbox[0].xy(); if (top != data->lastfocus) data->entities[n]->pressed = data->buttons; else diff --git a/src/lol/math/matrix.h b/src/lol/math/matrix.h index 66d2b563..eb80e403 100644 --- a/src/lol/math/matrix.h +++ b/src/lol/math/matrix.h @@ -49,78 +49,10 @@ VECTOR_TYPES(Vec4, vec4) VECTOR_TYPES(Quat, quat) VECTOR_TYPES(Mat4, mat4) -#define VECTOR_OP(op) \ - inline type_t operator op(type_t const &val) const \ - { \ - type_t ret; \ - for (size_t n = 0; n < sizeof(*this) / sizeof(T); n++) \ - ret[n] = (*this)[n] op val[n]; \ - return ret; \ - } \ - \ - inline type_t operator op##=(type_t const &val) \ - { \ - return *this = (*this) op val; \ - } - -#define BOOL_OP(op, op2, ret) \ - inline bool operator op(type_t const &val) const \ - { \ - for (size_t n = 0; n < sizeof(*this) / sizeof(T); n++) \ - if (!((*this)[n] op2 val[n])) \ - return !ret; \ - return ret; \ - } - -#define SCALAR_OP(op) \ - inline type_t operator op(T const &val) const \ - { \ - type_t ret; \ - for (size_t n = 0; n < sizeof(*this) / sizeof(T); n++) \ - ret[n] = (*this)[n] op val; \ - return ret; \ - } \ - \ - inline type_t operator op##=(T const &val) \ - { \ - return *this = (*this) op val; \ - } - -#define LINEAR_OPS() \ +#define MEMBER_OPS() \ inline T& operator[](int n) { return *(&x + n); } \ inline T const& operator[](int n) const { return *(&x + n); } \ \ - VECTOR_OP(-) \ - VECTOR_OP(+) \ - \ - BOOL_OP(==, ==, true) \ - BOOL_OP(!=, ==, false) \ - \ - SCALAR_OP(*) \ - SCALAR_OP(/) \ - \ - inline type_t operator -() const \ - { \ - type_t ret; \ - for (size_t n = 0; n < sizeof(*this) / sizeof(T); n++) \ - ret[n] = -(*this)[n]; \ - return ret; \ - } \ - \ - inline T sqlen() const \ - { \ - T acc = 0; \ - for (size_t n = 0; n < sizeof(*this) / sizeof(T); n++) \ - acc += (*this)[n] * (*this)[n]; \ - return acc; \ - } \ - \ - inline double len() const \ - { \ - using namespace std; \ - return sqrt((double)sqlen()); \ - } \ - \ void printf() const; #define COMPLEX_OPS() \ @@ -139,7 +71,7 @@ VECTOR_TYPES(Mat4, mat4) return type_t(x, -y); \ } \ \ - inline T norm() const { return len(); } + inline T norm() const { return len(*this); } #define QUATERNION_OPS() \ inline type_t operator *(type_t const &val) const \ @@ -167,19 +99,9 @@ VECTOR_TYPES(Mat4, mat4) ret[n] = -(*this)[n]; \ ret[3] = (*this)[3]; \ return ret; \ - } \ - \ - inline T norm() const { return sqlen(); } + } -#define OTHER_OPS(tname) \ - VECTOR_OP(*) \ - VECTOR_OP(/) \ - \ - BOOL_OP(<=, <=, true) \ - BOOL_OP(>=, >=, true) \ - BOOL_OP(<, <, true) \ - BOOL_OP(>, >, true) \ - \ +#define OTHER_MEMBER_OPS(tname) \ template \ inline operator tname() const \ { \ @@ -187,10 +109,7 @@ VECTOR_TYPES(Mat4, mat4) for (size_t n = 0; n < sizeof(*this) / sizeof(T); n++) \ ret[n] = static_cast((*this)[n]); \ return ret; \ - } \ - \ - template \ - friend U dot(tname, tname); + } #define SWIZZLE2(e1, e2) \ inline Vec2 e1##e2() const \ @@ -265,8 +184,8 @@ template struct Vec2 explicit inline Vec2(T val) { x = y = val; } inline Vec2(T _x, T _y) { x = _x; y = _y; } - LINEAR_OPS() - OTHER_OPS(Vec2) + MEMBER_OPS() + OTHER_MEMBER_OPS(Vec2) SWIZZLE22(x); SWIZZLE22(y); SWIZZLE322(x); SWIZZLE322(y); @@ -297,7 +216,8 @@ template struct Cmplx inline Cmplx(T val) : x(val), y(0) { } inline Cmplx(T _x, T _y) : x(_x), y(_y) { } - LINEAR_OPS() + MEMBER_OPS() + COMPLEX_OPS() #if !defined __ANDROID__ @@ -311,21 +231,39 @@ template struct Cmplx template static inline Cmplx re(Cmplx const &val) { - return ~val / val.sqlen(); + return ~val / sqlen(val); } template -static inline Cmplx operator /(T x, Cmplx const &y) +static inline Cmplx operator /(T a, Cmplx const &b) { - return x * re(y); + return a * re(b); } template -static inline Cmplx operator /(Cmplx x, Cmplx const &y) +static inline Cmplx operator /(Cmplx a, Cmplx const &b) { - return x * re(y); + return a * re(b); } +template +static inline bool operator ==(Cmplx const &a, T b) +{ + return (a.x == b) && !a.y; +} + +template +static inline bool operator !=(Cmplx const &a, T b) +{ + return (a.x != b) || a.y; +} + +template +static inline bool operator ==(T a, Cmplx const &b) { return b == a; } + +template +static inline bool operator !=(T a, Cmplx const &b) { return b != a; } + /* * 3-element vectors */ @@ -340,8 +278,8 @@ template struct Vec3 inline Vec3(Vec2 _xy, T _z) { x = _xy.x; y = _xy.y; z = _z; } inline Vec3(T _x, Vec2 _yz) { x = _x; y = _yz.x; z = _yz.y; } - LINEAR_OPS() - OTHER_OPS(Vec3) + MEMBER_OPS() + OTHER_MEMBER_OPS(Vec3) SWIZZLE23(x); SWIZZLE23(y); SWIZZLE23(z); SWIZZLE333(x); SWIZZLE333(y); SWIZZLE333(z); @@ -381,8 +319,8 @@ template struct Vec4 inline Vec4(Vec3 _xyz, T _w) : x(_xyz.x), y(_xyz.y), z(_xyz.z), w(_w) { } inline Vec4(T _x, Vec3 _yzw) : x(_x), y(_yzw.x), z(_yzw.y), w(_yzw.z) { } - LINEAR_OPS() - OTHER_OPS(Vec4) + MEMBER_OPS() + OTHER_MEMBER_OPS(Vec4) SWIZZLE24(x); SWIZZLE24(y); SWIZZLE24(z); SWIZZLE24(w); SWIZZLE344(x); SWIZZLE344(y); SWIZZLE344(z); SWIZZLE344(w); @@ -415,7 +353,8 @@ template struct Quat Quat(Mat4 const &m); - LINEAR_OPS() + MEMBER_OPS() + QUATERNION_OPS() #if !defined __ANDROID__ @@ -426,10 +365,16 @@ template struct Quat T x, y, z, w; }; +template +inline T norm(Quat const &val) +{ + return sqlen(val); +} + template static inline Quat re(Quat const &val) { - return ~val / val.norm(); + return ~val / norm(val); } template @@ -448,29 +393,107 @@ static inline Quat operator /(Quat x, Quat const &y) * Common operators for all vector types, including quaternions */ -#define SCALAR_GLOBAL(tname, op, U) \ +#define VECTOR_OP(tname, op) \ template \ - static inline tname operator op(U const &val, tname const &that) \ + inline tname operator op(tname const &a, tname const &b) \ { \ - tname ret; \ - for (size_t n = 0; n < sizeof(that) / sizeof(that[0]); n++) \ - ret[n] = val op that[n]; \ + tname ret; \ + for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \ + ret[n] = a[n] op b[n]; \ + return ret; \ + } \ + \ + template \ + inline tname operator op##=(tname &a, tname const &b) \ + { \ + return a = a op b; \ + } + +#define BOOL_OP(tname, op, op2, ret) \ + template \ + inline bool operator op(tname const &a, tname const &b) \ + { \ + for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \ + if (!(a[n] op2 b[n])) \ + return !ret; \ return ret; \ } -#define SCALAR_GLOBAL2(tname, op) \ - SCALAR_GLOBAL(tname, op, int) \ - SCALAR_GLOBAL(tname, op, float) \ - SCALAR_GLOBAL(tname, op, double) +#define SCALAR_OP(tname, op) \ + template \ + inline tname operator op##=(tname &a, T const &val) \ + { \ + return a = a op val; \ + } \ + \ + template \ + static inline tname operator op(tname const &a, T const &val) \ + { \ + tname ret; \ + for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \ + ret[n] = a[n] op val; \ + return ret; \ + } + +#define SCALAR_PROMOTE_OP(tname, op, U) \ + template \ + static inline tname operator op(U const &val, tname const &a) \ + { \ + tname ret; \ + for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \ + ret[n] = val op a[n]; \ + return ret; \ + } #define GLOBALS(tname) \ - SCALAR_GLOBAL2(tname, *) \ + SCALAR_OP(tname, *) \ + SCALAR_OP(tname, /) \ + \ + SCALAR_PROMOTE_OP(tname, *, int) \ + SCALAR_PROMOTE_OP(tname, *, float) \ + SCALAR_PROMOTE_OP(tname, *, double) \ + \ + VECTOR_OP(tname, -) \ + VECTOR_OP(tname, +) \ + \ + BOOL_OP(tname, ==, ==, true) \ + BOOL_OP(tname, !=, ==, false) \ + \ + template \ + inline tname operator -(tname const &a) \ + { \ + tname ret; \ + for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \ + ret[n] = -a[n]; \ + return ret; \ + } \ + \ + template \ + inline T sqlen(tname const &a) \ + { \ + T acc = 0; \ + for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \ + acc += a[n] * a[n]; \ + return acc; \ + } \ + \ + template \ + inline double len(tname const &a) \ + { \ + using namespace std; \ + return sqrt((double)sqlen(a)); \ + } \ + \ + /* dot() does not take const refs because the function is not inlined, \ + * so we try to avoid carrying a shitty pointer around. */ \ + template \ + T dot(tname a, tname b); \ \ template \ static inline tname normalize(tname const &val) \ { \ - T norm = val.len(); \ - return norm ? val / norm : val * 0; \ + T norm = len(val); \ + return norm ? val / norm : val * (T)0; \ } GLOBALS(Vec2) @@ -479,6 +502,19 @@ GLOBALS(Vec3) GLOBALS(Vec4) GLOBALS(Quat) +#define OTHER_OPS(tname) \ + VECTOR_OP(tname, *) \ + VECTOR_OP(tname, /) \ + \ + BOOL_OP(tname, <=, <=, true) \ + BOOL_OP(tname, >=, >=, true) \ + BOOL_OP(tname, <, <, true) \ + BOOL_OP(tname, >, >, true) + +OTHER_OPS(Vec2) +OTHER_OPS(Vec3) +OTHER_OPS(Vec4) + /* * 4×4-element matrices */ diff --git a/src/matrix.cpp b/src/matrix.cpp index 6110e325..bee608a9 100644 --- a/src/matrix.cpp +++ b/src/matrix.cpp @@ -276,7 +276,7 @@ template<> mat4 mat4::rotate(float angle, vec3 v) template<> mat4 mat4::rotate(quat q) { mat4 ret(1.0f); - float n = q.norm(); + float n = norm(q); if (!n) return ret; diff --git a/test/tutorial/tut03.cpp b/test/tutorial/tut03.cpp index 408d55cd..030f7b62 100644 --- a/test/tutorial/tut03.cpp +++ b/test/tutorial/tut03.cpp @@ -71,7 +71,8 @@ public: m_window2world = 0.5 / m_window_size.y; else m_window2world = 0.5 / m_window_size.x; - m_texel2world = (vec2)m_window_size / (vec2)m_size * m_window2world; + m_texel2world = (vec2)m_window_size / (vec2)m_size + * (vec2)m_window2world; m_oldmouse = ivec2(0, 0); @@ -368,7 +369,7 @@ public: z2 = z1 * z1 + r0; z3 = z2 * z2 + r0; z0 = z3 * z3 + r0; - if (z0.sqlen() >= maxsqlen) + if (sqlen(z0) >= maxsqlen) break; iter -= 4; if (iter < 4) @@ -377,11 +378,11 @@ public: if (iter) { - double n = z0.sqlen(); + double n = sqlen(z0); - if (z1.sqlen() >= maxsqlen) { iter += 3; n = z1.sqlen(); } - else if (z2.sqlen() >= maxsqlen) { iter += 2; n = z2.sqlen(); } - else if (z3.sqlen() >= maxsqlen) { iter += 1; n = z3.sqlen(); } + if (sqlen(z1) >= maxsqlen) { iter += 3; n = sqlen(z1); } + else if (sqlen(z2) >= maxsqlen) { iter += 2; n = sqlen(z2); } + else if (sqlen(z3) >= maxsqlen) { iter += 1; n = sqlen(z3); } if (n > maxsqlen * maxsqlen) n = maxsqlen * maxsqlen; diff --git a/test/unit/quat.cpp b/test/unit/quat.cpp index 403da31b..ee6cbb90 100644 --- a/test/unit/quat.cpp +++ b/test/unit/quat.cpp @@ -67,16 +67,16 @@ LOLUNIT_FIXTURE(QuaternionTest) { quat a(2.0f, -2.0f, -8.0f, 3.0f); - LOLUNIT_ASSERT_EQUAL(a.norm(), 81.0f); + LOLUNIT_ASSERT_EQUAL(norm(a), 81.0f); quat b = a * ~a; - quat c(0.0f, 0.0f, 0.0f, a.norm()); + quat c(0.0f, 0.0f, 0.0f, norm(a)); LOLUNIT_ASSERT_EQUAL(b, c); quat d(2.0f, 3.0f, -4.0f, -1.0f); - LOLUNIT_ASSERT_EQUAL((a * d).norm(), a.norm() * d.norm()); + LOLUNIT_ASSERT_EQUAL(norm(a * d), norm(a) * norm(d)); } LOLUNIT_TEST(Base) @@ -86,10 +86,10 @@ LOLUNIT_FIXTURE(QuaternionTest) quat k(0.0f, 0.0f, 1.0f, 0.0f); quat one(0.0f, 0.0f, 0.0f, 1.0f); - LOLUNIT_ASSERT_EQUAL(i.norm(), 1.0f); - LOLUNIT_ASSERT_EQUAL(j.norm(), 1.0f); - LOLUNIT_ASSERT_EQUAL(k.norm(), 1.0f); - LOLUNIT_ASSERT_EQUAL(one.norm(), 1.0f); + LOLUNIT_ASSERT_EQUAL(norm(i), 1.0f); + LOLUNIT_ASSERT_EQUAL(norm(j), 1.0f); + LOLUNIT_ASSERT_EQUAL(norm(k), 1.0f); + LOLUNIT_ASSERT_EQUAL(norm(one), 1.0f); LOLUNIT_ASSERT_EQUAL(i * i, -one); LOLUNIT_ASSERT_EQUAL(j * j, -one); @@ -109,7 +109,7 @@ LOLUNIT_FIXTURE(QuaternionTest) quat a(2.0f, -2.0f, -8.0f, 3.0f); quat b = normalize(a); - LOLUNIT_ASSERT_DOUBLES_EQUAL(b.norm(), 1.0, 1e-8); + LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(b), 1.0, 1e-8); } LOLUNIT_TEST(Reciprocal)