瀏覽代碼

math: move most vector and matrix member functions to global functions.

legacy
Sam Hocevar sam 13 年之前
父節點
當前提交
d38a79ee3d
共有 6 個檔案被更改,包括 166 行新增129 行删除
  1. +1
    -1
      src/debug/quad.cpp
  2. +1
    -1
      src/input.cpp
  3. +148
    -112
      src/lol/math/matrix.h
  4. +1
    -1
      src/matrix.cpp
  5. +7
    -6
      test/tutorial/tut03.cpp
  6. +8
    -8
      test/unit/quat.cpp

+ 1
- 1
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;


+ 1
- 1
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


+ 148
- 112
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<typename U> \
inline operator tname<U>() const \
{ \
@@ -187,10 +109,7 @@ VECTOR_TYPES(Mat4, mat4)
for (size_t n = 0; n < sizeof(*this) / sizeof(T); n++) \
ret[n] = static_cast<U>((*this)[n]); \
return ret; \
} \
\
template<typename U> \
friend U dot(tname<U>, tname<U>);
}

#define SWIZZLE2(e1, e2) \
inline Vec2<T> e1##e2() const \
@@ -265,8 +184,8 @@ template <typename T> 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 <typename T> 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 <typename T> struct Cmplx
template<typename T>
static inline Cmplx<T> re(Cmplx<T> const &val)
{
return ~val / val.sqlen();
return ~val / sqlen(val);
}

template<typename T>
static inline Cmplx<T> operator /(T x, Cmplx<T> const &y)
static inline Cmplx<T> operator /(T a, Cmplx<T> const &b)
{
return x * re(y);
return a * re(b);
}

template<typename T>
static inline Cmplx<T> operator /(Cmplx<T> x, Cmplx<T> const &y)
static inline Cmplx<T> operator /(Cmplx<T> a, Cmplx<T> const &b)
{
return x * re(y);
return a * re(b);
}

template<typename T>
static inline bool operator ==(Cmplx<T> const &a, T b)
{
return (a.x == b) && !a.y;
}

template<typename T>
static inline bool operator !=(Cmplx<T> const &a, T b)
{
return (a.x != b) || a.y;
}

template<typename T>
static inline bool operator ==(T a, Cmplx<T> const &b) { return b == a; }

template<typename T>
static inline bool operator !=(T a, Cmplx<T> const &b) { return b != a; }

/*
* 3-element vectors
*/
@@ -340,8 +278,8 @@ template <typename T> struct Vec3
inline Vec3(Vec2<T> _xy, T _z) { x = _xy.x; y = _xy.y; z = _z; }
inline Vec3(T _x, Vec2<T> _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 <typename T> struct Vec4
inline Vec4(Vec3<T> _xyz, T _w) : x(_xyz.x), y(_xyz.y), z(_xyz.z), w(_w) { }
inline Vec4(T _x, Vec3<T> _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 <typename T> struct Quat

Quat(Mat4<T> const &m);

LINEAR_OPS()
MEMBER_OPS()

QUATERNION_OPS()

#if !defined __ANDROID__
@@ -426,10 +365,16 @@ template <typename T> struct Quat
T x, y, z, w;
};

template<typename T>
inline T norm(Quat<T> const &val)
{
return sqlen(val);
}

template<typename T>
static inline Quat<T> re(Quat<T> const &val)
{
return ~val / val.norm();
return ~val / norm(val);
}

template<typename T>
@@ -448,29 +393,107 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)
* Common operators for all vector types, including quaternions
*/

#define SCALAR_GLOBAL(tname, op, U) \
#define VECTOR_OP(tname, op) \
template<typename T> \
static inline tname<U> operator op(U const &val, tname<T> const &that) \
inline tname<T> operator op(tname<T> const &a, tname<T> const &b) \
{ \
tname<U> ret; \
for (size_t n = 0; n < sizeof(that) / sizeof(that[0]); n++) \
ret[n] = val op that[n]; \
tname<T> ret; \
for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
ret[n] = a[n] op b[n]; \
return ret; \
} \
\
template<typename T> \
inline tname<T> operator op##=(tname<T> &a, tname<T> const &b) \
{ \
return a = a op b; \
}

#define BOOL_OP(tname, op, op2, ret) \
template<typename T> \
inline bool operator op(tname<T> const &a, tname<T> 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<typename T> \
inline tname<T> operator op##=(tname<T> &a, T const &val) \
{ \
return a = a op val; \
} \
\
template<typename T> \
static inline tname<T> operator op(tname<T> const &a, T const &val) \
{ \
tname<T> 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<typename T> \
static inline tname<U> operator op(U const &val, tname<T> const &a) \
{ \
tname<U> 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<typename T> \
inline tname<T> operator -(tname<T> const &a) \
{ \
tname<T> ret; \
for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
ret[n] = -a[n]; \
return ret; \
} \
\
template<typename T> \
inline T sqlen(tname<T> const &a) \
{ \
T acc = 0; \
for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
acc += a[n] * a[n]; \
return acc; \
} \
\
template<typename T> \
inline double len(tname<T> 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<typename T> \
T dot(tname<T> a, tname<T> b); \
\
template<typename T> \
static inline tname<T> normalize(tname<T> 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
*/


+ 1
- 1
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;


+ 7
- 6
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;


+ 8
- 8
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)


Loading…
取消
儲存