From d27443a5d7050283b537b6fa4ea5d802576ee5da Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 25 Feb 2012 20:20:26 +0000 Subject: [PATCH] math: allow vectors of half and real; they don't support swizzling or rgba getter aliases. --- src/lol/math/vector.h | 209 ++++++++++++++++++++++++++++-------------- 1 file changed, 139 insertions(+), 70 deletions(-) diff --git a/src/lol/math/vector.h b/src/lol/math/vector.h index 885bb903..3bdace44 100644 --- a/src/lol/math/vector.h +++ b/src/lol/math/vector.h @@ -22,12 +22,12 @@ # include #endif +#include "half.h" +#include "lol/math/real.h" + namespace lol { -class half; -class real; - #define DECLARE_VECTOR_TYPEDEFS(tname, suffix) \ template struct tname; \ typedef tname f16##suffix; \ @@ -40,7 +40,8 @@ class real; typedef tname i##suffix; \ typedef tname u##suffix; \ typedef tname i64##suffix; \ - typedef tname u64##suffix; + typedef tname u64##suffix; \ + typedef tname r##suffix; \ DECLARE_VECTOR_TYPEDEFS(Vec2, vec2) DECLARE_VECTOR_TYPEDEFS(Cmplx, cmplx) @@ -90,8 +91,8 @@ template struct XVec4 */ #define DECLARE_MEMBER_OPS(tname) \ - inline T& operator[](int n) { return *(&x + n); } \ - inline T const& operator[](int n) const { return *(&x + n); } \ + inline T& operator[](int n) { return *(&this->x + n); } \ + inline T const& operator[](int n) const { return *(&this->x + n); } \ \ void printf() const; \ \ @@ -108,27 +109,10 @@ template struct XVec4 * 2-element vectors */ -template struct Vec2 +template struct BVec2 { - inline Vec2() {} - inline Vec2(T X, T Y) : x(X), y(Y) {} - - explicit inline Vec2(T X) : x(X), y(X) {} - - template - inline Vec2(XVec2 const &v) - : x(v.ptr[v.I]), y(v.ptr[v.J]) {} - - template - explicit inline Vec2(XVec2 const &v) - : x(v.ptr[v.I]), y(v.ptr[v.J]) {} - - DECLARE_MEMBER_OPS(Vec2) - -#if !defined __ANDROID__ - template - friend std::ostream &operator<<(std::ostream &stream, Vec2 const &v); -#endif + explicit inline BVec2() {} + explicit inline BVec2(T X, T Y) : x(X), y(Y) {} union { @@ -169,6 +153,45 @@ template struct Vec2 }; }; +template <> struct BVec2 +{ + explicit inline BVec2() {} + explicit inline BVec2(half X, half Y) : x(X), y(Y) {} + + half x, y; +}; + +template <> struct BVec2 +{ + explicit inline BVec2() {} + explicit inline BVec2(real X, real Y) : x(X), y(Y) {} + + real x, y; +}; + +template struct Vec2 : BVec2 +{ + inline Vec2() {} + inline Vec2(T X, T Y) : BVec2(X, Y) {} + + explicit inline Vec2(T X) : BVec2(X, X) {} + + template + inline Vec2(XVec2 const &v) + : BVec2(v.ptr[v.I], v.ptr[v.J]) {} + + template + explicit inline Vec2(XVec2 const &v) + : BVec2(v.ptr[v.I], v.ptr[v.J]) {} + + DECLARE_MEMBER_OPS(Vec2) + +#if !defined __ANDROID__ + template + friend std::ostream &operator<<(std::ostream &stream, Vec2 const &v); +#endif +}; + /* * 2-element complexes */ @@ -245,32 +268,10 @@ static inline bool operator !=(T a, Cmplx const &b) { return b != a; } * 3-element vectors */ -template struct Vec3 +template struct BVec3 { - inline Vec3() {} - inline Vec3(T X, T Y, T Z) : x(X), y(Y), z(Z) {} - 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) {} - - explicit inline Vec3(T X) : x(X), y(X), z(X) {} - - template - inline Vec3(XVec3 const &v) - : x(v.ptr[v.I]), y(v.ptr[v.J]), z(v.ptr[v.K]) {} - - template - explicit inline Vec3(XVec3 const &v) - : x(v.ptr[v.I]), y(v.ptr[v.J]), z(v.ptr[v.K]) {} - - DECLARE_MEMBER_OPS(Vec3) - - template - friend Vec3 cross(Vec3, Vec3); - -#if !defined __ANDROID__ - template - friend std::ostream &operator<<(std::ostream &stream, Vec3 const &v); -#endif + explicit inline BVec3() {} + explicit inline BVec3(T X, T Y, T Z) : x(X), y(Y), z(Z) {} union { @@ -400,37 +401,58 @@ template struct Vec3 }; }; -/* - * 4-element vectors - */ +template <> struct BVec3 +{ + explicit inline BVec3() {} + explicit inline BVec3(half X, half Y, half Z) : x(X), y(Y), z(Z) {} + + half x, y, z; +}; -template struct Vec4 +template <> struct BVec3 { - inline Vec4() {} - inline Vec4(T X, T Y, T Z, T W) : x(X), y(Y), z(Z), w(W) {} - inline Vec4(Vec2 XY, T Z, T W) : x(XY.x), y(XY.y), z(Z), w(W) {} - inline Vec4(T X, Vec2 YZ, T W) : x(X), y(YZ.x), z(YZ.y), w(W) {} - inline Vec4(T X, T Y, Vec2 ZW) : x(X), y(Y), z(ZW.x), w(ZW.y) {} - inline Vec4(Vec2 XY, Vec2 ZW) : x(XY.x), y(XY.y), z(ZW.x), w(ZW.y) {} - 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) {} + explicit inline BVec3() {} + explicit inline BVec3(real X, real Y, real Z) : x(X), y(Y), z(Z) {} - explicit inline Vec4(T X) : x(X), y(X), z(X), w(X) {} + real x, y, z; +}; + +template struct Vec3 : BVec3 +{ + inline Vec3() {} + inline Vec3(T X, T Y, T Z) : BVec3(X, Y, Z) {} + inline Vec3(Vec2 XY, T Z) : BVec3(XY.x, XY.y, Z) {} + inline Vec3(T X, Vec2 YZ) : BVec3(X, YZ.x, YZ.y) {} + + explicit inline Vec3(T X) : BVec3(X, X, X) {} template - inline Vec4(XVec4 const &v) - : x(v.ptr[v.I]), y(v.ptr[v.J]), z(v.ptr[v.K]), w(v.ptr[v.L]) {} + inline Vec3(XVec3 const &v) + : BVec3(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K]) {} template - explicit inline Vec4(XVec4 const &v) - : x(v.ptr[v.I]), y(v.ptr[v.J]), z(v.ptr[v.K]), w(v.ptr[v.L]) {} + explicit inline Vec3(XVec3 const &v) + : BVec3(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K]) {} - DECLARE_MEMBER_OPS(Vec4) + DECLARE_MEMBER_OPS(Vec3) + + template + friend Vec3 cross(Vec3, Vec3); #if !defined __ANDROID__ template - friend std::ostream &operator<<(std::ostream &stream, Vec4 const &v); + friend std::ostream &operator<<(std::ostream &stream, Vec3 const &v); #endif +}; + +/* + * 4-element vectors + */ + +template struct BVec4 +{ + explicit inline BVec4() {} + explicit inline BVec4(T X, T Y, T Z, T W) : x(X), y(Y), z(Z), w(W) {} union { @@ -779,6 +801,53 @@ template struct Vec4 }; }; +template <> struct BVec4 +{ + explicit inline BVec4() {} + explicit inline BVec4(half X, half Y, half Z, half W) + : x(X), y(Y), z(Z), w(W) {} + + half x, y, z, w; +}; + +template <> struct BVec4 +{ + explicit inline BVec4() {} + explicit inline BVec4(real X, real Y, real Z, real W) + : x(X), y(Y), z(Z), w(W) {} + + real x, y, z, w; +}; + +template struct Vec4 : BVec4 +{ + inline Vec4() {} + inline Vec4(T X, T Y, T Z, T W) : BVec4(X, Y, Z, W) {} + inline Vec4(Vec2 XY, T Z, T W) : BVec4(XY.x, XY.y, Z, W) {} + inline Vec4(T X, Vec2 YZ, T W) : BVec4(X, YZ.x, YZ.y, W) {} + inline Vec4(T X, T Y, Vec2 ZW) : BVec4(X, Y, ZW.x, ZW.y) {} + inline Vec4(Vec2 XY, Vec2 ZW) : BVec4(XY.x, XY.y, ZW.x, ZW.y) {} + inline Vec4(Vec3 XYZ, T W) : BVec4(XYZ.x, XYZ.y, XYZ.z, W) {} + inline Vec4(T X, Vec3 YZW) : BVec4(X, YZW.x, YZW.y, YZW.z) {} + + explicit inline Vec4(T X) : BVec4(X, X, X, X) {} + + template + inline Vec4(XVec4 const &v) + : BVec4(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K], v.ptr[v.L]) {} + + template + explicit inline Vec4(XVec4 const &v) + : BVec4(v.ptr[v.I], v.ptr[v.J], v.ptr[v.K], v.ptr[v.L]) {} + + DECLARE_MEMBER_OPS(Vec4) + +#if !defined __ANDROID__ + template + friend std::ostream &operator<<(std::ostream &stream, Vec4 const &v); +#endif +}; + /* * 4-element quaternions */