Pārlūkot izejas kodu

math: finally get the GLSL-like swizzling to work.

legacy
Sam Hocevar sam pirms 13 gadiem
vecāks
revīzija
c8d5630e4e
3 mainītis faili ar 97 papildinājumiem un 64 dzēšanām
  1. Binārs
      gfx/font/ascii.png
  2. +94
    -61
      src/lol/math/matrix.h
  3. +3
    -3
      src/matrix.cpp

Binārs
gfx/font/ascii.png Parādīt failu

Pirms Pēc
Platums: 112  |  Augstums: 240  |  Izmērs: 4.7 KiB Platums: 112  |  Augstums: 240  |  Izmērs: 4.7 KiB

+ 94
- 61
src/lol/math/matrix.h Parādīt failu

@@ -76,6 +76,10 @@ template<typename T, int I, int J, int K, int L> struct MagicVec4
: J > K ? J > L ? J : L : K > L ? K : L)];
};

/*
* Helper macros for vector type member functions
*/

#define MEMBER_OPS() \
inline T& operator[](int n) { return *(&x + n); } \
inline T const& operator[](int n) const { return *(&x + n); } \
@@ -151,7 +155,11 @@ template <typename T> struct Vec2
inline Vec2(T _x, T _y) { x = _x; y = _y; }

template<int I, int J>
inline Vec2<T>(MagicVec2<T, I, J> const &v)
inline Vec2(MagicVec2<T, I, J> const &v)
: x(v.ptr[I]), y(v.ptr[J]) {}

template<typename U, int I, int J>
explicit inline Vec2(MagicVec2<U, I, J> const &v)
: x(v.ptr[I]), y(v.ptr[J]) {}

MEMBER_OPS()
@@ -274,7 +282,11 @@ template <typename T> struct Vec3
inline Vec3(T _x, Vec2<T> _yz) { x = _x; y = _yz.x; z = _yz.y; }

template<int I, int J, int K>
inline Vec3<T>(MagicVec3<T, I, J, K> const &v)
inline Vec3(MagicVec3<T, I, J, K> const &v)
: x(v.ptr[I]), y(v.ptr[J]), z(v.ptr[K]) {}

template<typename U, int I, int J, int K>
explicit inline Vec3(MagicVec3<U, I, J, K> const &v)
: x(v.ptr[I]), y(v.ptr[J]), z(v.ptr[K]) {}

MEMBER_OPS()
@@ -433,11 +445,11 @@ template <typename T> struct Vec4
inline Vec4(T _x, Vec3<T> _yzw) : x(_x), y(_yzw.x), z(_yzw.y), w(_yzw.z) { }

template<int I, int J, int K, int L>
inline Vec4<T>(MagicVec4<T, I, J, K, L> const &v)
inline Vec4(MagicVec4<T, I, J, K, L> const &v)
: x(v.ptr[I]), y(v.ptr[J]), z(v.ptr[K]), w(v.ptr[L]) {}

template<typename U, int I, int J, int K, int L>
explicit inline Vec4<T>(MagicVec4<U, I, J, K, L> const &v)
explicit inline Vec4(MagicVec4<U, I, J, K, L> const &v)
: x(v.ptr[I]), y(v.ptr[J]), z(v.ptr[K]), w(v.ptr[L]) {}

MEMBER_OPS()
@@ -793,11 +805,6 @@ template <typename T> struct Vec4
};
};

inline Vec2<float> operator /(Vec2<float> a, Vec2<float> b)
{
return Vec2<float>(a.x / b.x, a.y / b.y);
}

/*
* 4-element quaternions
*/
@@ -852,9 +859,9 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)
* Common operators for all vector types, including quaternions
*/

#define VECTOR_OP(tname, op) \
template<typename T> \
inline tname<T> operator op(tname<T> const &a, tname<T> const &b) \
#define VECTOR_OP(tname, op, tprefix, T) \
tprefix \
static inline tname<T> operator op(tname<T> const &a, tname<T> const &b) \
{ \
tname<T> ret; \
for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
@@ -862,15 +869,15 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)
return ret; \
} \
\
template<typename T> \
inline tname<T> operator op##=(tname<T> &a, tname<T> const &b) \
tprefix \
static 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) \
#define BOOL_OP(tname, op, op2, ret, tprefix, T) \
tprefix \
static 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])) \
@@ -878,20 +885,29 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)
return ret; \
}

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

#define SCALAR_PROMOTE_OP(tname, op, U) \
@@ -904,22 +920,18 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)
return ret; \
}

#define GLOBALS(tname) \
SCALAR_OP(tname, *) \
SCALAR_OP(tname, /) \
#define GLOBAL_OPS(tname, tprefix, T) \
SCALAR_OP(tname, *, tprefix, T) \
SCALAR_OP(tname, /, tprefix, T) \
\
SCALAR_PROMOTE_OP(tname, *, int) \
SCALAR_PROMOTE_OP(tname, *, float) \
SCALAR_PROMOTE_OP(tname, *, double) \
VECTOR_OP(tname, -, tprefix, T) \
VECTOR_OP(tname, +, tprefix, T) \
\
VECTOR_OP(tname, -) \
VECTOR_OP(tname, +) \
BOOL_OP(tname, ==, ==, true, tprefix, T) \
BOOL_OP(tname, !=, ==, false, tprefix, T) \
\
BOOL_OP(tname, ==, ==, true) \
BOOL_OP(tname, !=, ==, false) \
\
template<typename T> \
inline tname<T> operator -(tname<T> const &a) \
tprefix \
static inline tname<T> operator -(tname<T> const &a) \
{ \
tname<T> ret; \
for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
@@ -927,8 +939,8 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)
return ret; \
} \
\
template<typename T> \
inline T sqlen(tname<T> const &a) \
tprefix \
static inline T sqlen(tname<T> const &a) \
{ \
T acc = 0; \
for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
@@ -936,43 +948,64 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)
return acc; \
} \
\
template<typename T> \
inline double len(tname<T> const &a) \
tprefix \
static 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); \
tprefix \
static inline T dot(tname<T> const &a, tname<T> const &b) \
{ \
T ret = 0; \
for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
ret += a[n] * b[n]; \
return ret; \
} \
\
template<typename T> \
tprefix \
static inline tname<T> normalize(tname<T> const &val) \
{ \
T norm = len(val); \
return norm ? val / norm : val * (T)0; \
}

GLOBALS(Vec2)
GLOBALS(Cmplx)
GLOBALS(Vec3)
GLOBALS(Vec4)
GLOBALS(Quat)
#define GLOBAL_TEMPLATE_OPS(tname) \
GLOBAL_OPS(tname, template<typename T>, T)

#define OTHER_OPS(tname) \
VECTOR_OP(tname, *) \
VECTOR_OP(tname, /) \
#define ALL_GLOBAL_OPS(tname, tprefix, T) \
VECTOR_OP(tname, *, tprefix, T) \
VECTOR_OP(tname, /, tprefix, T) \
\
GLOBAL_OPS(tname, tprefix, T) \
\
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)
BOOL_OP(tname, <=, <=, true, tprefix, T) \
BOOL_OP(tname, >=, >=, true, tprefix, T) \
BOOL_OP(tname, <, <, true, tprefix, T) \
BOOL_OP(tname, >, >, true, tprefix, T)

/* FIXME: a few problems need to be fixed before we can use "half" here. It
* will probably never work until we switch to C++11 because it's not really
* a POD class. */
#define GLOBAL_TYPED_OPS(tname) \
ALL_GLOBAL_OPS(tname, , float) \
ALL_GLOBAL_OPS(tname, , double) \
ALL_GLOBAL_OPS(tname, , int8_t) \
ALL_GLOBAL_OPS(tname, , uint8_t) \
ALL_GLOBAL_OPS(tname, , int16_t) \
ALL_GLOBAL_OPS(tname, , uint16_t) \
ALL_GLOBAL_OPS(tname, , int32_t) \
ALL_GLOBAL_OPS(tname, , uint32_t) \
ALL_GLOBAL_OPS(tname, , int64_t) \
ALL_GLOBAL_OPS(tname, , uint64_t)

GLOBAL_TEMPLATE_OPS(Cmplx)
GLOBAL_TEMPLATE_OPS(Quat)

GLOBAL_TYPED_OPS(Vec2)
GLOBAL_TYPED_OPS(Vec3)
GLOBAL_TYPED_OPS(Vec4)

/*
* Magic swizzling (part 2/2)


+ 3
- 3
src/matrix.cpp Parādīt failu

@@ -31,17 +31,17 @@ using namespace std;
namespace lol
{

template<> float dot(vec2 v1, vec2 v2)
float dot(vec2 v1, vec2 v2)
{
return v1.x * v2.x + v1.y * v2.y;
}

template<> float dot(vec3 v1, vec3 v2)
float dot(vec3 v1, vec3 v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}

template<> float dot(vec4 v1, vec4 v2)
float dot(vec4 v1, vec4 v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
}


Notiek ielāde…
Atcelt
Saglabāt