Skip to content

Instantly share code, notes, and snippets.

@Blaisorblade
Created February 8, 2012 22:42
Show Gist options
  • Save Blaisorblade/1775054 to your computer and use it in GitHub Desktop.
Save Blaisorblade/1775054 to your computer and use it in GitHub Desktop.
struct vec2;
struct vec3;
template<int I, int J> struct MagicVec2
{
friend struct vec2;
inline MagicVec2(vec3* _this);
inline vec2 operator=(const vec2& that);
inline vec2 operator=(const MagicVec2<I, J> &that);
private:
//Forbid direct assignment; only do it through implicit conversions. Does
//not work though.
//inline vec2 operator=(const MagicVec2<I, J> &that);
float *ptr;
};
struct vec2
{
inline vec2(float x, float y)
: x(x), y(y) {}
template<int I, int J>
inline vec2(MagicVec2<I, J> const &v)
: x(v.ptr[I]), y(v.ptr[J]) {}
union { float x, r; };
union { float y, g; };
union { float z, b; };
};
template<int I, int J>
inline vec2 MagicVec2<I, J>::operator=(const vec2& that)
{
ptr[I] = that.x; ptr[J] = that.y;
return *this;
}
template<int I, int J>
inline vec2 MagicVec2<I, J>::operator=(const MagicVec2<I, J> &that)
{
*this = vec2(that);
return *this;
}
struct vec3
{
inline vec3(float x, float y, float z)
: x(x), y(y), z(z),
xx(this), rr(this), ss(this),
xy(this), rg(this), st(this),
xz(this), rb(this), sp(this),
yx(this), gr(this), ts(this),
yy(this), gg(this), tt(this),
yz(this), gb(this), tp(this),
zx(this), br(this), ps(this),
zy(this), bg(this), pt(this),
zz(this), bb(this), pp(this) {}
/*template<int I, int J, int K>
inline vec3(MagicVec3<I, J, K> const &v)
: x(v.ptr[I]), y(v.ptr[J]), z(v.ptr[K]) {}
*/
union
{
struct { float x, y, z; };
struct { float r, g, b; };
struct { float s, t, p; };
float mem[3];
/* Also MagicVec3 and MagicVec4, of course */
};
MagicVec2<0,0> xx, rr, ss;
MagicVec2<0,1> xy, rg, st;
MagicVec2<0,2> xz, rb, sp;
MagicVec2<1,0> yx, gr, ts;
MagicVec2<1,1> yy, gg, tt;
MagicVec2<1,2> yz, gb, tp;
MagicVec2<2,0> zx, br, ps;
MagicVec2<2,1> zy, bg, pt;
MagicVec2<2,2> zz, bb, pp;
};
template<int I, int J> inline MagicVec2<I, J>::MagicVec2(vec3* _this): ptr(_this->mem) {};
//Test code, to verify that implicit conversions work as expected.
void foo(vec3& a, vec2 b) {
a.xx = a.rr;
a.xx = b;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment