From 12aaff89e37cc7ac522f7cc3ace7f60f6ee7c1af Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Wed, 2 Jul 2014 07:21:22 +0000 Subject: [PATCH] base: huge refactor in vector.h; GCC compilation times down by 50%. --- demos/tutorial/06_sprite.cpp | 4 +- demos/tutorial/07_input.cpp | 2 +- demos/tutorial/11_fractal.cpp | 30 +- src/debug/fps.cpp | 2 +- src/eglapp.cpp | 2 +- src/gpu/renderer.cpp | 14 +- src/image/codec/oric-image.cpp | 2 +- src/lol/math/geometry.h | 32 +- src/lol/math/vector.h | 2670 ++++++++++++++++---------------- src/math/constants.cpp | 12 +- src/math/vector.cpp | 4 +- test/meshviewer.cpp | 1 - test/unit/cmplx.cpp | 14 +- 13 files changed, 1395 insertions(+), 1394 deletions(-) diff --git a/demos/tutorial/06_sprite.cpp b/demos/tutorial/06_sprite.cpp index 0cf1beb4..c4ce4cd7 100644 --- a/demos/tutorial/06_sprite.cpp +++ b/demos/tutorial/06_sprite.cpp @@ -35,7 +35,7 @@ public: for (int i = 0; i < SPRITE_COUNT; ++i) { - m_sprites.Push(ivec3(rand(-96, 640), rand(-96, 480), 0), + m_sprites.Push(vec3(rand(-96, 640), rand(-96, 480), 0), rand(0.f, 1.f)); } @@ -78,7 +78,7 @@ public: int frame = (int)(m_sprites[i].m2 * FRAME_COUNT); // m_sprites[i].m1.z = frame; scene.AddTile(m_tileset, frame, - (ivec3)m_sprites[i].m1, 0, vec2(2.f), 0.f); + m_sprites[i].m1, 0, vec2(2.f), 0.f); } } diff --git a/demos/tutorial/07_input.cpp b/demos/tutorial/07_input.cpp index e09b79a7..4594f183 100644 --- a/demos/tutorial/07_input.cpp +++ b/demos/tutorial/07_input.cpp @@ -73,7 +73,7 @@ public: m_lines_indices << 0 << 4 << 1 << 5 << 2 << 6 << 3 << 7; m_text = new Text("", "data/font/ascii.png"); - m_text->SetPos(ivec3(5, 5, 1)); + m_text->SetPos(vec3(5, 5, 1)); Ticker::Ref(m_text); m_ready = false; diff --git a/demos/tutorial/11_fractal.cpp b/demos/tutorial/11_fractal.cpp index f3ceb53b..6a94ff1a 100644 --- a/demos/tutorial/11_fractal.cpp +++ b/demos/tutorial/11_fractal.cpp @@ -33,8 +33,8 @@ public: m_size = size; m_size.x = (m_size.x + 15) & ~15; m_size.y = (m_size.y + 15) & ~15; - m_texel_settings = vec4(1.0, 1.0, 2.0, 2.0) / m_size.xyxy; - m_screen_settings = vec4(1.0, 1.0, 0.5, 0.5) * m_size.xyxy; + m_texel_settings = vec4(1.0, 1.0, 2.0, 2.0) / (vec4)m_size.xyxy; + m_screen_settings = vec4(1.0, 1.0, 0.5, 0.5) * (vec4)m_size.xyxy; /* Window size decides the world aspect ratio. For instance, 640×480 * will be mapped to (-0.66,-0.5) - (0.66,0.5). */ @@ -105,21 +105,21 @@ public: #if !defined __native_client__ m_centertext = new Text(NULL, "data/font/ascii.png"); - m_centertext->SetPos(ivec3(5, m_window_size.y - 15, 1)); + m_centertext->SetPos(vec3(5, m_window_size.y - 15, 1)); Ticker::Ref(m_centertext); m_mousetext = new Text(NULL, "data/font/ascii.png"); - m_mousetext->SetPos(ivec3(5, m_window_size.y - 29, 1)); + m_mousetext->SetPos(vec3(5, m_window_size.y - 29, 1)); Ticker::Ref(m_mousetext); m_zoomtext = new Text(NULL, "data/font/ascii.png"); - m_zoomtext->SetPos(ivec3(5, m_window_size.y - 43, 1)); + m_zoomtext->SetPos(vec3(5, m_window_size.y - 43, 1)); Ticker::Ref(m_zoomtext); #endif - m_position = ivec3(0, 0, 0); + m_position = vec3::zero; m_bbox[0] = m_position; - m_bbox[1] = ivec3(m_window_size, 0); + m_bbox[1] = vec3((vec2)m_window_size, 0); //Input::TrackMouse(this); #if LOL_FEATURE_THREADS @@ -175,7 +175,8 @@ public: int prev_frame = (m_frame + 4) % 4; m_frame = (m_frame + 1) % 4; - rcmplx worldmouse = m_center + rcmplx(ScreenToWorldOffset(mousepos)); + rcmplx worldmouse = m_center + + rcmplx(ScreenToWorldOffset((vec2)mousepos)); uint32_t buttons = 0; //uint32_t buttons = Input::GetMouseButtons(); @@ -187,13 +188,13 @@ public: m_oldmouse = mousepos; m_drag = true; } - m_translate = ScreenToWorldOffset(m_oldmouse) - - ScreenToWorldOffset(mousepos); + m_translate = rcmplx(ScreenToWorldOffset((vec2)m_oldmouse) + - ScreenToWorldOffset((vec2)mousepos)); /* XXX: the purpose of this hack is to avoid translating by * an exact number of pixels. If this were to happen, the step() * optimisation for i915 cards in our shader would behave * incorrectly because a quarter of the pixels in the image - * would have tie rankings in the distance calculation. */ + * would have tied rankings in the distance calculation. */ m_translate *= real(1023.0 / 1024.0); m_oldmouse = mousepos; } @@ -203,7 +204,7 @@ public: if (m_translate != rcmplx(0.0, 0.0)) { m_translate *= real(std::pow(2.0, -seconds * 5.0)); - if ((double)m_translate.norm() < m_radius * 1e-4) + if ((double)norm(m_translate) < m_radius * 1e-4) m_translate = rcmplx(0.0, 0.0); } } @@ -242,7 +243,8 @@ public: #if !defined __CELLOS_LV2__ && !defined _XBOX m_center += m_translate; m_center = (m_center - worldmouse) * real(zoom) + worldmouse; - worldmouse = m_center + rcmplx(ScreenToWorldOffset(mousepos)); + worldmouse = m_center + + rcmplx(ScreenToWorldOffset((vec2)mousepos)); #endif /* Store the transformation properties to go from m_frame - 1 @@ -352,7 +354,7 @@ public: for (int i = m_frame % 2; i < m_size.x; i += 2) { double xr, yr, x0, y0, x1, y1, x2, y2, x3, y3; - dcmplx z0 = c + TexelToWorldOffset(ivec2(i, j)); + dcmplx z0 = c + TexelToWorldOffset(vec2(i, j)); //dcmplx r0(0.28693186889504513, 0.014286693904085048); //dcmplx r0(0.001643721971153, 0.822467633298876); //dcmplx r0(-1.207205434596, 0.315432814901); diff --git a/src/debug/fps.cpp b/src/debug/fps.cpp index 86755eef..519e4760 100644 --- a/src/debug/fps.cpp +++ b/src/debug/fps.cpp @@ -50,7 +50,7 @@ DebugFps::DebugFps(int x, int y) } #else data->lines[0] = new Text("", "data/font/ascii.png"); - data->lines[0]->SetPos(ivec3(x, y, 100)); + data->lines[0]->SetPos(vec3(x, y, 100)); Ticker::Ref(data->lines[0]); #endif } diff --git a/src/eglapp.cpp b/src/eglapp.cpp index 78dcc189..11e7227a 100644 --- a/src/eglapp.cpp +++ b/src/eglapp.cpp @@ -247,7 +247,7 @@ EglApp::EglApp(char const *title, ivec2 res, float fps) : # if !defined HAVE_BCM_HOST_H XWindowAttributes gwa; XGetWindowAttributes(data->dpy, data->win, &gwa); - data->screen_size = ivec2(gwa.width, gwa.height); + data->screen_size = uvec2(gwa.width, gwa.height); # endif # if defined USE_SDL diff --git a/src/gpu/renderer.cpp b/src/gpu/renderer.cpp index 37de0229..d2e36a4a 100755 --- a/src/gpu/renderer.cpp +++ b/src/gpu/renderer.cpp @@ -139,7 +139,7 @@ Renderer::Renderer(ivec2 size) /* Initialise rendering states */ m_data->m_viewport = ibox2(0, 0, 0, 0); - SetViewport(ibox2(vec2::zero, size)); + SetViewport(ibox2(ivec2::zero, size)); m_data->m_clear_color = vec4(-1.f); SetClearColor(vec4(0.1f, 0.2f, 0.3f, 1.0f)); @@ -257,17 +257,17 @@ ibox2 Renderer::GetViewport() const float Renderer::GetXYRatio() const { ibox2 a = GetViewport(); - box2 b(a.A, a.B); - vec2 s = b.B - b.A; - return s.x / s.y; + ibox2 b(a.A, a.B); + ivec2 s = b.B - b.A; + return (float)s.x / s.y; } float Renderer::GetYXRatio() const { ibox2 a = GetViewport(); - box2 b(a.A, a.B); - vec2 s = b.B - b.A; - return s.y / s.x; + ibox2 b(a.A, a.B); + ivec2 s = b.B - b.A; + return (float)s.y / s.x; } /* diff --git a/src/image/codec/oric-image.cpp b/src/image/codec/oric-image.cpp index cd1644f9..73f75737 100644 --- a/src/image/codec/oric-image.cpp +++ b/src/image/codec/oric-image.cpp @@ -500,7 +500,7 @@ void OricImageCodec::WriteScreen(Image &image, array &result) /* Recursively compute and apply best command */ int dummy; - uint8_t command = bestmove(srcl, bgfg, vec3(0), depth, + uint8_t command = bestmove(srcl, bgfg, ivec3(0), depth, 0x7fffff, &dummy, dstl); /* Propagate error */ for (int i = 0; i < 6; i++) diff --git a/src/lol/math/geometry.h b/src/lol/math/geometry.h index 76fe152c..4c217baf 100644 --- a/src/lol/math/geometry.h +++ b/src/lol/math/geometry.h @@ -49,7 +49,7 @@ template struct Box2 B(T(0)) {} - inline Box2(Vec2 const &a, Vec2 const &b) + inline Box2(vec<2,T> const &a, vec<2,T> const &b) : A(a), B(b) {} @@ -59,32 +59,32 @@ template struct Box2 B(bx, by) {} - Box2 operator +(Vec2 const &v) const + Box2 operator +(vec<2,T> const &v) const { return Box2(A + v, B + v); } - Box2 &operator +=(Vec2 const &v) + Box2 &operator +=(vec<2,T> const &v) { return *this = *this + v; } - Box2 operator -(Vec2 const &v) const + Box2 operator -(vec<2,T> const &v) const { return Box2(A - v, B - v); } - Box2 &operator -=(Vec2 const &v) + Box2 &operator -=(vec<2,T> const &v) { return *this = *this - v; } - Box2 operator *(Vec2 const &v) const + Box2 operator *(vec<2,T> const &v) const { return Box2(A * v, B * v); } - Box2 &operator *=(Vec2 const &v) + Box2 &operator *=(vec<2,T> const &v) { return *this = *this * v; } @@ -99,7 +99,7 @@ template struct Box2 return A != box.A || B != box.B; } - Vec2 A, B; + vec<2,T> A, B; }; /* @@ -113,7 +113,7 @@ template struct Box3 B(T(0)) {} - inline Box3(Vec3 const &a, Vec3 const &b) + inline Box3(vec<3,T> const &a, vec<3,T> const &b) : A(a), B(b) {} @@ -124,32 +124,32 @@ template struct Box3 B(bx, by, bz) {} - Box3 operator +(Vec3 const &v) const + Box3 operator +(vec<3,T> const &v) const { return Box3(A + v, B + v); } - Box3 &operator +=(Vec3 const &v) + Box3 &operator +=(vec<3,T> const &v) { return *this = *this + v; } - Box3 operator -(Vec3 const &v) const + Box3 operator -(vec<3,T> const &v) const { return Box3(A - v, B - v); } - Box3 &operator -=(Vec3 const &v) + Box3 &operator -=(vec<3,T> const &v) { return *this = *this - v; } - Box3 operator *(Vec3 const &v) const + Box3 operator *(vec<3,T> const &v) const { return Box3(A * v, B * v); } - Box3 &operator *=(Vec3 const &v) + Box3 &operator *=(vec<3,T> const &v) { return *this = *this * v; } @@ -164,7 +164,7 @@ template struct Box3 return A != box.A || B != box.B; } - Vec3 A, B; + vec<3,T> A, B; }; /* diff --git a/src/lol/math/vector.h b/src/lol/math/vector.h index 08220ea5..eb484a19 100644 --- a/src/lol/math/vector.h +++ b/src/lol/math/vector.h @@ -25,65 +25,16 @@ namespace lol { +#if !LOL_FEATURE_CXX11_CONSTEXPR +# define constexpr /* */ +#endif + #if !LOL_FEATURE_CXX11_RELAXED_UNIONS # define _____ const #else # define _____ /* */ #endif -/* The generic "vec" type, which is a fixed-size vector */ -template -struct vec -{ -private: - T m_data[N]; -}; - -#define LOL_VECTOR_TYPEDEFS(tname, suffix) \ - template struct tname; \ - typedef tname f16##suffix; \ - typedef tname suffix; \ - typedef tname d##suffix; \ - typedef tname f128##suffix; \ - typedef tname i8##suffix; \ - typedef tname u8##suffix; \ - typedef tname i16##suffix; \ - typedef tname u16##suffix; \ - typedef tname i##suffix; \ - typedef tname u##suffix; \ - typedef tname i64##suffix; \ - typedef tname u64##suffix; \ - typedef tname r##suffix; \ - -LOL_VECTOR_TYPEDEFS(Vec2, vec2) -LOL_VECTOR_TYPEDEFS(Cmplx, cmplx) -LOL_VECTOR_TYPEDEFS(Vec3, vec3) -LOL_VECTOR_TYPEDEFS(Vec4, vec4) -LOL_VECTOR_TYPEDEFS(Quat, quat) -LOL_VECTOR_TYPEDEFS(Mat2, mat2) -LOL_VECTOR_TYPEDEFS(Mat3, mat3) -LOL_VECTOR_TYPEDEFS(Mat4, mat4) - -#undef LOL_VECTOR_TYPEDEFS - -/* - * HLSL/Cg-compliant type names. - */ - -typedef vec2 float2; -typedef vec3 float3; -typedef vec4 float4; -typedef mat2 float2x2; -typedef mat3 float3x3; -typedef mat4 float4x4; - -typedef ivec2 int2; -typedef ivec3 int3; -typedef ivec4 int4; -typedef imat2 int2x2; -typedef imat3 int3x3; -typedef imat4 int4x4; - /* * Magic vector swizzling (part 1/2) * These vectors are empty, but thanks to static_cast we can take their @@ -98,111 +49,236 @@ typedef imat4 int4x4; * fuck it. */ -template struct XVec2 +template +struct vec { - inline XVec2& operator =(Vec2 that); + inline vec& operator =(vec that); #if LOL_FEATURE_CXX11_RELAXED_UNIONS - inline XVec2& operator =(XVec2 const &that) + inline vec& operator =(vec const &that) { - return *this = (Vec2)that; + return *this = (vec)that; } #endif inline T& operator[](size_t n) { - int i = (N >> (4 * (1 - n))) & 3; + int i = (MASK >> (4 * (N - 1 - n))) & 3; return static_cast(static_cast(this))[i]; } + inline T const& operator[](size_t n) const { - int i = (N >> (4 * (1 - n))) & 3; + int i = (MASK >> (4 * (N - 1 - n))) & 3; return static_cast(static_cast(this))[i]; } }; -template struct XVec3 +/* The generic "vec" type, which is a fixed-size vector */ +template +struct vec { - inline XVec3& operator =(Vec3 that); - -#if LOL_FEATURE_CXX11_RELAXED_UNIONS - inline XVec3& operator =(XVec3 const &that) - { - return *this = (Vec3)that; - } -#endif - - inline T& operator[](size_t n) - { - int i = (N >> (4 * (2 - n))) & 3; - return static_cast(static_cast(this))[i]; - } - inline T const& operator[](size_t n) const - { - int i = (N >> (4 * (2 - n))) & 3; - return static_cast(static_cast(this))[i]; - } +private: + T m_data[N]; }; -template struct XVec4 +/* The generic "matrix" type, which is a fixed-size matrix */ +template +struct matrix { - inline XVec4& operator =(Vec4 that); +private: + T m_data[COLS][ROWS]; +}; -#if LOL_FEATURE_CXX11_RELAXED_UNIONS - inline XVec4& operator =(XVec4 const &that) - { - return *this = (Vec4)that; +/* The generic complex and quaternion types. */ +template struct Cmplx; +template struct Quat; + +/* + * Generic GLSL-like type names + */ + +#define COMMA , + +#define LOL_VECTOR_TYPEDEFS(tleft, tright, suffix) \ + typedef tleft half tright f16##suffix; \ + typedef tleft float tright suffix; \ + typedef tleft double tright d##suffix; \ + typedef tleft ldouble tright f128##suffix; \ + typedef tleft int8_t tright i8##suffix; \ + typedef tleft uint8_t tright u8##suffix; \ + typedef tleft int16_t tright i16##suffix; \ + typedef tleft uint16_t tright u16##suffix; \ + typedef tleft int32_t tright i##suffix; \ + typedef tleft uint32_t tright u##suffix; \ + typedef tleft int64_t tright i64##suffix; \ + typedef tleft uint64_t tright u64##suffix; \ + typedef tleft real tright r##suffix; + +LOL_VECTOR_TYPEDEFS(vec<2 COMMA, >, vec2) +LOL_VECTOR_TYPEDEFS(vec<3 COMMA, >, vec3) +LOL_VECTOR_TYPEDEFS(vec<4 COMMA, >, vec4) + +LOL_VECTOR_TYPEDEFS(matrix<2 COMMA 2 COMMA, >, mat2) +LOL_VECTOR_TYPEDEFS(matrix<3 COMMA 3 COMMA, >, mat3) +LOL_VECTOR_TYPEDEFS(matrix<4 COMMA 4 COMMA, >, mat4) + +LOL_VECTOR_TYPEDEFS(Cmplx<, >, cmplx) +LOL_VECTOR_TYPEDEFS(Quat<, >, quat) + +#undef LOL_VECTOR_TYPEDEFS + +/* + * HLSL/Cg-compliant type names. + */ + +typedef vec2 float2; +typedef vec3 float3; +typedef vec4 float4; +typedef mat2 float2x2; +typedef mat3 float3x3; +typedef mat4 float4x4; + +typedef ivec2 int2; +typedef ivec3 int3; +typedef ivec4 int4; +typedef imat2 int2x2; +typedef imat3 int3x3; +typedef imat4 int4x4; + +/* + * Helper macros for vector type member functions + */ + +#define LOL_V_VV_OP(op) \ + friend inline type operator op(type const &a, type const &b) \ + { \ + type ret; \ + for (size_t i = 0; i < sizeof(type) / sizeof(T); ++i) \ + ret[i] = a[i] op b[i]; \ + return ret; \ } -#endif - inline T& operator[](size_t n) - { - int i = (N >> (4 * (3 - n))) & 3; - return static_cast(static_cast(this))[i]; +#define LOL_V_VV_ASSIGN_OP(op) \ + friend inline type &operator op##=(type &a, type const &b) \ + { \ + return a = a op b; \ } - inline T const& operator[](size_t n) const - { - int i = (N >> (4 * (3 - n))) & 3; - return static_cast(static_cast(this))[i]; + +#define LOL_V_VS_OP(op) \ + friend inline type operator op(type const &a, T const &val) \ + { \ + type ret; \ + for (size_t i = 0; i < sizeof(type) / sizeof(T); ++i) \ + ret[i] = a[i] op val; \ + return ret; \ } -}; -/* - * Helper macro for vector type member functions - */ +#define LOL_V_VS_ASSIGN_OP(op) \ + friend inline type operator op##=(type &a, T const &val) \ + { \ + return a = a op val; \ + } + +#define LOL_B_VV_OP(op, op2, ret) \ + friend inline bool operator op(type const &a, type const &b) \ + { \ + for (size_t i = 0; i < sizeof(type) / sizeof(T); ++i) \ + if (!(a[i] op2 b[i])) \ + return !ret; \ + return ret; \ + } -#define LOL_MEMBER_OPS(tname, first) \ - inline T& operator[](size_t n) { return *(&this->first + n); } \ - inline T const& operator[](size_t n) const { return *(&this->first + n); } \ +#define LOL_COMMON_MEMBER_OPS(first) \ + inline T& operator[](size_t n) { return (&this->first)[n]; } \ + inline T const& operator[](size_t n) const { return (&this->first)[n]; } \ \ /* Visual Studio insists on having an assignment operator. */ \ - inline tname const & operator =(tname const &that) \ + inline type & operator =(type const &that) \ { \ - for (size_t n = 0; n < sizeof(*this) / sizeof(T); n++) \ - (*this)[n] = that[n]; \ + for (size_t i = 0; i < sizeof(type) / sizeof(T); ++i) \ + (*this)[i] = that[i]; \ return *this; \ } \ \ - template \ - inline operator tname() const \ + void printf() const; \ + String tostring() const; \ + \ + /* vec -(vec) + * vec +(vec) */ \ + friend inline type operator -(type const &a) \ { \ - tname ret; \ - for (size_t n = 0; n < sizeof(*this) / sizeof(T); n++) \ - ret[n] = static_cast((*this)[n]); \ + type ret; \ + for (size_t i = 0; i < sizeof(type) / sizeof(T); ++i) \ + ret[i] = -a[i]; \ return ret; \ } \ \ - void printf() const; \ - String tostring() const; + friend inline type operator +(type const &a) \ + { \ + return a; \ + } \ + \ + /* vec +(vec, vec) + * vec -(vec, vec) + * vec +=(vec, vec) + * vec -=(vec, vec) */ \ + LOL_V_VV_OP(+); \ + LOL_V_VV_OP(-); \ + LOL_V_VV_ASSIGN_OP(+); \ + LOL_V_VV_ASSIGN_OP(-); \ + \ + /* vec *(vec, scalar) + * vec /(vec, scalar) + * vec *=(vec, scalar) + * vec /=(vec, scalar) */ \ + LOL_V_VS_OP(*) \ + LOL_V_VS_OP(/) \ + LOL_V_VS_ASSIGN_OP(*) \ + LOL_V_VS_ASSIGN_OP(/) \ + \ + /* bool ==(vec, vec) + * bool !=(vec, vec) */ \ + LOL_B_VV_OP(==, ==, true) \ + LOL_B_VV_OP(!=, ==, false) + +#define LOL_VECTOR_MEMBER_OPS() \ + /* vec *(vec, vec) + * vec /(vec, vec) + * vec *=(vec, vec) + * vec /=(vec, vec) */ \ + LOL_V_VV_OP(*); \ + LOL_V_VV_OP(/); \ + LOL_V_VV_ASSIGN_OP(*); \ + LOL_V_VV_ASSIGN_OP(/); \ + \ + /* bool >=(vec, vec) + * bool <=(vec, vec) + * bool >(vec, vec) + * bool <(vec, vec) */ \ + LOL_B_VV_OP(<=, <=, true) \ + LOL_B_VV_OP(>=, >=, true) \ + LOL_B_VV_OP(<, <, true) \ + LOL_B_VV_OP(>, >, true) + +#define LOL_NONVECTOR_MEMBER_OPS() \ + /* vec *(scalar, vec) (no division, it works differently) */ \ + friend inline type operator *(T const &val, type const &a) \ + { \ + type ret; \ + for (size_t i = 0; i < sizeof(type) / sizeof(T); ++i) \ + ret[i] = val * a[i]; \ + return ret; \ + } /* * 2-element vectors */ -template struct BVec2 +template struct base_vec2 { - explicit inline LOL_CONSTEXPR BVec2() {} - explicit inline LOL_CONSTEXPR BVec2(T X, T Y) : x(X), y(Y) {} + explicit inline constexpr base_vec2() {} + explicit inline constexpr base_vec2(T X, T Y) : x(X), y(Y) {} union { @@ -211,79 +287,83 @@ template struct BVec2 struct { T s, t; }; #if !_DOXYGEN_SKIP_ME - XVec2 const xx, rr, ss; - XVec2 _____ xy, rg, st; - XVec2 _____ yx, gr, ts; - XVec2 const yy, gg, tt; - - XVec3 const xxx, rrr, sss; - XVec3 const xxy, rrg, sst; - XVec3 const xyx, rgr, sts; - XVec3 const xyy, rgg, stt; - XVec3 const yxx, grr, tss; - XVec3 const yxy, grg, tst; - XVec3 const yyx, ggr, tts; - XVec3 const yyy, ggg, ttt; - - XVec4 const xxxx, rrrr, ssss; - XVec4 const xxxy, rrrg, ssst; - XVec4 const xxyx, rrgr, ssts; - XVec4 const xxyy, rrgg, sstt; - XVec4 const xyxx, rgrr, stss; - XVec4 const xyxy, rgrg, stst; - XVec4 const xyyx, rggr, stts; - XVec4 const xyyy, rggg, sttt; - XVec4 const yxxx, grrr, tsss; - XVec4 const yxxy, grrg, tsst; - XVec4 const yxyx, grgr, tsts; - XVec4 const yxyy, grgg, tstt; - XVec4 const yyxx, ggrr, ttss; - XVec4 const yyxy, ggrg, ttst; - XVec4 const yyyx, gggr, ttts; - XVec4 const yyyy, gggg, tttt; + vec<2,T,0x00> const xx, rr, ss; + vec<2,T,0x01> _____ xy, rg, st; + vec<2,T,0x10> _____ yx, gr, ts; + vec<2,T,0x11> const yy, gg, tt; + + vec<3,T,0x000> const xxx, rrr, sss; + vec<3,T,0x001> const xxy, rrg, sst; + vec<3,T,0x010> const xyx, rgr, sts; + vec<3,T,0x011> const xyy, rgg, stt; + vec<3,T,0x100> const yxx, grr, tss; + vec<3,T,0x101> const yxy, grg, tst; + vec<3,T,0x110> const yyx, ggr, tts; + vec<3,T,0x111> const yyy, ggg, ttt; + + vec<4,T,0x0000> const xxxx, rrrr, ssss; + vec<4,T,0x0001> const xxxy, rrrg, ssst; + vec<4,T,0x0010> const xxyx, rrgr, ssts; + vec<4,T,0x0011> const xxyy, rrgg, sstt; + vec<4,T,0x0100> const xyxx, rgrr, stss; + vec<4,T,0x0101> const xyxy, rgrg, stst; + vec<4,T,0x0110> const xyyx, rggr, stts; + vec<4,T,0x0111> const xyyy, rggg, sttt; + vec<4,T,0x1000> const yxxx, grrr, tsss; + vec<4,T,0x1001> const yxxy, grrg, tsst; + vec<4,T,0x1010> const yxyx, grgr, tsts; + vec<4,T,0x1011> const yxyy, grgg, tstt; + vec<4,T,0x1100> const yyxx, ggrr, ttss; + vec<4,T,0x1101> const yyxy, ggrg, ttst; + vec<4,T,0x1110> const yyyx, gggr, ttts; + vec<4,T,0x1111> const yyyy, gggg, tttt; #endif }; }; -template <> struct BVec2 +template <> struct base_vec2 { - explicit inline BVec2() {} - explicit inline BVec2(half X, half Y) : x(X), y(Y) {} + explicit inline base_vec2() {} + explicit inline base_vec2(half X, half Y) : x(X), y(Y) {} half x, y; }; -template <> struct BVec2 +template <> struct base_vec2 { - explicit inline BVec2() {} - explicit inline BVec2(real X, real Y) : x(X), y(Y) {} + explicit inline base_vec2() {} + explicit inline base_vec2(real X, real Y) : x(X), y(Y) {} real x, y; }; -template struct Vec2 : BVec2 +template +struct vec<2,T> : base_vec2 { - inline LOL_CONSTEXPR Vec2() {} - inline LOL_CONSTEXPR Vec2(T X, T Y) : BVec2(X, Y) {} + typedef vec<2,T> type; - explicit LOL_CONSTEXPR inline Vec2(T X) : BVec2(X, X) {} + inline constexpr vec() {} + inline constexpr vec(T X, T Y) : base_vec2(X, Y) {} - template - inline LOL_CONSTEXPR Vec2(XVec2 const &v) - : BVec2(v[0], v[1]) {} + explicit inline constexpr vec(T X) : base_vec2(X, X) {} - template - explicit inline LOL_CONSTEXPR Vec2(XVec2 const &v) - : BVec2(v[0], v[1]) {} + template + inline constexpr vec(vec<2, T, MASK> const &v) + : base_vec2(v[0], v[1]) {} - LOL_MEMBER_OPS(Vec2, x) + template + explicit inline constexpr vec(vec<2, U, MASK> const &v) + : base_vec2(v[0], v[1]) {} - static const Vec2 zero; - static const Vec2 axis_x; - static const Vec2 axis_y; + LOL_COMMON_MEMBER_OPS(x) + LOL_VECTOR_MEMBER_OPS() + + static const vec<2,T> zero; + static const vec<2,T> axis_x; + static const vec<2,T> axis_y; template - friend std::ostream &operator<<(std::ostream &stream, Vec2 const &v); + friend std::ostream &operator<<(std::ostream &stream, vec<2,U> const &v); }; /* @@ -292,11 +372,18 @@ template struct Vec2 : BVec2 template struct Cmplx { - inline LOL_CONSTEXPR Cmplx() {} - inline LOL_CONSTEXPR Cmplx(T X) : x(X), y(0) {} - inline LOL_CONSTEXPR Cmplx(T X, T Y) : x(X), y(Y) {} + typedef Cmplx type; + + inline constexpr Cmplx() {} + inline constexpr Cmplx(T X) : x(X), y(0) {} + inline constexpr Cmplx(T X, T Y) : x(X), y(Y) {} - LOL_MEMBER_OPS(Cmplx, x) + template + explicit inline constexpr Cmplx(Cmplx const &z) + : Cmplx(z[0], z[1]) {} + + LOL_COMMON_MEMBER_OPS(x) + LOL_NONVECTOR_MEMBER_OPS() inline Cmplx operator *(Cmplx const &val) const { @@ -313,7 +400,6 @@ template struct Cmplx return Cmplx(x, -y); } - inline T norm() const { return length(*this); } template friend std::ostream &operator<<(std::ostream &stream, Cmplx const &v); @@ -321,9 +407,44 @@ template struct Cmplx }; template -static inline Cmplx re(Cmplx const &val) +static inline T dot(Cmplx const &q1, Cmplx const &q2) +{ + T ret(0); + for (size_t i = 0; i < sizeof(ret) / sizeof(T); ++i) + ret += q1[i] * q2[i]; + return ret; +} + +template +static inline T sqlength(Cmplx const &q) +{ + return dot(q, q); +} + +template +static inline T length(Cmplx const &q) +{ + /* FIXME: this is not very nice */ + return (T)sqrt((double)sqlength(q)); +} + +template +static inline T norm(Cmplx const &z) +{ + return length(z); +} + +template +static inline Cmplx re(Cmplx const &z) +{ + return ~z / sqlength(z); +} + +template +static inline Cmplx normalize(Cmplx const &z) { - return ~val / sqlength(val); + T norm = (T)length(z); + return norm ? z / norm : Cmplx(T(0)); } template @@ -360,10 +481,10 @@ static inline bool operator !=(T a, Cmplx const &b) { return b != a; } * 3-element vectors */ -template struct BVec3 +template struct base_vec3 { - explicit inline LOL_CONSTEXPR BVec3() {} - explicit inline LOL_CONSTEXPR BVec3(T X, T Y, T Z) : x(X), y(Y), z(Z) {} + explicit inline constexpr base_vec3() {} + explicit inline constexpr base_vec3(T X, T Y, T Z) : x(X), y(Y), z(Z) {} union { @@ -372,196 +493,222 @@ template struct BVec3 struct { T s, t, p; }; #if !_DOXYGEN_SKIP_ME - XVec2 const xx, rr, ss; - XVec2 _____ xy, rg, st; - XVec2 _____ xz, rb, sp; - XVec2 _____ yx, gr, ts; - XVec2 const yy, gg, tt; - XVec2 _____ yz, gb, tp; - XVec2 _____ zx, br, ps; - XVec2 _____ zy, bg, pt; - XVec2 const zz, bb, pp; - - XVec3 const xxx, rrr, sss; - XVec3 const xxy, rrg, sst; - XVec3 const xxz, rrb, ssp; - XVec3 const xyx, rgr, sts; - XVec3 const xyy, rgg, stt; - XVec3 _____ xyz, rgb, stp; - XVec3 const xzx, rbr, sps; - XVec3 _____ xzy, rbg, spt; - XVec3 const xzz, rbb, spp; - XVec3 const yxx, grr, tss; - XVec3 const yxy, grg, tst; - XVec3 _____ yxz, grb, tsp; - XVec3 const yyx, ggr, tts; - XVec3 const yyy, ggg, ttt; - XVec3 const yyz, ggb, ttp; - XVec3 _____ yzx, gbr, tps; - XVec3 const yzy, gbg, tpt; - XVec3 const yzz, gbb, tpp; - XVec3 const zxx, brr, pss; - XVec3 _____ zxy, brg, pst; - XVec3 const zxz, brb, psp; - XVec3 _____ zyx, bgr, pts; - XVec3 const zyy, bgg, ptt; - XVec3 const zyz, bgb, ptp; - XVec3 const zzx, bbr, pps; - XVec3 const zzy, bbg, ppt; - XVec3 const zzz, bbb, ppp; - - XVec4 const xxxx, rrrr, ssss; - XVec4 const xxxy, rrrg, ssst; - XVec4 const xxxz, rrrb, sssp; - XVec4 const xxyx, rrgr, ssts; - XVec4 const xxyy, rrgg, sstt; - XVec4 const xxyz, rrgb, sstp; - XVec4 const xxzx, rrbr, ssps; - XVec4 const xxzy, rrbg, sspt; - XVec4 const xxzz, rrbb, sspp; - XVec4 const xyxx, rgrr, stss; - XVec4 const xyxy, rgrg, stst; - XVec4 const xyxz, rgrb, stsp; - XVec4 const xyyx, rggr, stts; - XVec4 const xyyy, rggg, sttt; - XVec4 const xyyz, rggb, sttp; - XVec4 const xyzx, rgbr, stps; - XVec4 const xyzy, rgbg, stpt; - XVec4 const xyzz, rgbb, stpp; - XVec4 const xzxx, rbrr, spss; - XVec4 const xzxy, rbrg, spst; - XVec4 const xzxz, rbrb, spsp; - XVec4 const xzyx, rbgr, spts; - XVec4 const xzyy, rbgg, sptt; - XVec4 const xzyz, rbgb, sptp; - XVec4 const xzzx, rbbr, spps; - XVec4 const xzzy, rbbg, sppt; - XVec4 const xzzz, rbbb, sppp; - XVec4 const yxxx, grrr, tsss; - XVec4 const yxxy, grrg, tsst; - XVec4 const yxxz, grrb, tssp; - XVec4 const yxyx, grgr, tsts; - XVec4 const yxyy, grgg, tstt; - XVec4 const yxyz, grgb, tstp; - XVec4 const yxzx, grbr, tsps; - XVec4 const yxzy, grbg, tspt; - XVec4 const yxzz, grbb, tspp; - XVec4 const yyxx, ggrr, ttss; - XVec4 const yyxy, ggrg, ttst; - XVec4 const yyxz, ggrb, ttsp; - XVec4 const yyyx, gggr, ttts; - XVec4 const yyyy, gggg, tttt; - XVec4 const yyyz, gggb, tttp; - XVec4 const yyzx, ggbr, ttps; - XVec4 const yyzy, ggbg, ttpt; - XVec4 const yyzz, ggbb, ttpp; - XVec4 const yzxx, gbrr, tpss; - XVec4 const yzxy, gbrg, tpst; - XVec4 const yzxz, gbrb, tpsp; - XVec4 const yzyx, gbgr, tpts; - XVec4 const yzyy, gbgg, tptt; - XVec4 const yzyz, gbgb, tptp; - XVec4 const yzzx, gbbr, tpps; - XVec4 const yzzy, gbbg, tppt; - XVec4 const yzzz, gbbb, tppp; - XVec4 const zxxx, brrr, psss; - XVec4 const zxxy, brrg, psst; - XVec4 const zxxz, brrb, pssp; - XVec4 const zxyx, brgr, psts; - XVec4 const zxyy, brgg, pstt; - XVec4 const zxyz, brgb, pstp; - XVec4 const zxzx, brbr, psps; - XVec4 const zxzy, brbg, pspt; - XVec4 const zxzz, brbb, pspp; - XVec4 const zyxx, bgrr, ptss; - XVec4 const zyxy, bgrg, ptst; - XVec4 const zyxz, bgrb, ptsp; - XVec4 const zyyx, bggr, ptts; - XVec4 const zyyy, bggg, pttt; - XVec4 const zyyz, bggb, pttp; - XVec4 const zyzx, bgbr, ptps; - XVec4 const zyzy, bgbg, ptpt; - XVec4 const zyzz, bgbb, ptpp; - XVec4 const zzxx, bbrr, ppss; - XVec4 const zzxy, bbrg, ppst; - XVec4 const zzxz, bbrb, ppsp; - XVec4 const zzyx, bbgr, ppts; - XVec4 const zzyy, bbgg, pptt; - XVec4 const zzyz, bbgb, pptp; - XVec4 const zzzx, bbbr, ppps; - XVec4 const zzzy, bbbg, pppt; - XVec4 const zzzz, bbbb, pppp; + vec<2,T,0x00> const xx, rr, ss; + vec<2,T,0x01> _____ xy, rg, st; + vec<2,T,0x02> _____ xz, rb, sp; + vec<2,T,0x10> _____ yx, gr, ts; + vec<2,T,0x11> const yy, gg, tt; + vec<2,T,0x12> _____ yz, gb, tp; + vec<2,T,0x20> _____ zx, br, ps; + vec<2,T,0x21> _____ zy, bg, pt; + vec<2,T,0x22> const zz, bb, pp; + + vec<3,T,0x000> const xxx, rrr, sss; + vec<3,T,0x001> const xxy, rrg, sst; + vec<3,T,0x002> const xxz, rrb, ssp; + vec<3,T,0x010> const xyx, rgr, sts; + vec<3,T,0x011> const xyy, rgg, stt; + vec<3,T,0x012> _____ xyz, rgb, stp; + vec<3,T,0x020> const xzx, rbr, sps; + vec<3,T,0x021> _____ xzy, rbg, spt; + vec<3,T,0x022> const xzz, rbb, spp; + vec<3,T,0x100> const yxx, grr, tss; + vec<3,T,0x101> const yxy, grg, tst; + vec<3,T,0x102> _____ yxz, grb, tsp; + vec<3,T,0x110> const yyx, ggr, tts; + vec<3,T,0x111> const yyy, ggg, ttt; + vec<3,T,0x112> const yyz, ggb, ttp; + vec<3,T,0x120> _____ yzx, gbr, tps; + vec<3,T,0x121> const yzy, gbg, tpt; + vec<3,T,0x122> const yzz, gbb, tpp; + vec<3,T,0x200> const zxx, brr, pss; + vec<3,T,0x201> _____ zxy, brg, pst; + vec<3,T,0x202> const zxz, brb, psp; + vec<3,T,0x210> _____ zyx, bgr, pts; + vec<3,T,0x211> const zyy, bgg, ptt; + vec<3,T,0x212> const zyz, bgb, ptp; + vec<3,T,0x220> const zzx, bbr, pps; + vec<3,T,0x221> const zzy, bbg, ppt; + vec<3,T,0x222> const zzz, bbb, ppp; + + vec<4,T,0x0000> const xxxx, rrrr, ssss; + vec<4,T,0x0001> const xxxy, rrrg, ssst; + vec<4,T,0x0002> const xxxz, rrrb, sssp; + vec<4,T,0x0010> const xxyx, rrgr, ssts; + vec<4,T,0x0011> const xxyy, rrgg, sstt; + vec<4,T,0x0012> const xxyz, rrgb, sstp; + vec<4,T,0x0020> const xxzx, rrbr, ssps; + vec<4,T,0x0021> const xxzy, rrbg, sspt; + vec<4,T,0x0022> const xxzz, rrbb, sspp; + vec<4,T,0x0100> const xyxx, rgrr, stss; + vec<4,T,0x0101> const xyxy, rgrg, stst; + vec<4,T,0x0102> const xyxz, rgrb, stsp; + vec<4,T,0x0110> const xyyx, rggr, stts; + vec<4,T,0x0111> const xyyy, rggg, sttt; + vec<4,T,0x0112> const xyyz, rggb, sttp; + vec<4,T,0x0120> const xyzx, rgbr, stps; + vec<4,T,0x0121> const xyzy, rgbg, stpt; + vec<4,T,0x0122> const xyzz, rgbb, stpp; + vec<4,T,0x0200> const xzxx, rbrr, spss; + vec<4,T,0x0201> const xzxy, rbrg, spst; + vec<4,T,0x0202> const xzxz, rbrb, spsp; + vec<4,T,0x0210> const xzyx, rbgr, spts; + vec<4,T,0x0211> const xzyy, rbgg, sptt; + vec<4,T,0x0212> const xzyz, rbgb, sptp; + vec<4,T,0x0220> const xzzx, rbbr, spps; + vec<4,T,0x0221> const xzzy, rbbg, sppt; + vec<4,T,0x0222> const xzzz, rbbb, sppp; + vec<4,T,0x1000> const yxxx, grrr, tsss; + vec<4,T,0x1001> const yxxy, grrg, tsst; + vec<4,T,0x1002> const yxxz, grrb, tssp; + vec<4,T,0x1010> const yxyx, grgr, tsts; + vec<4,T,0x1011> const yxyy, grgg, tstt; + vec<4,T,0x1012> const yxyz, grgb, tstp; + vec<4,T,0x1020> const yxzx, grbr, tsps; + vec<4,T,0x1021> const yxzy, grbg, tspt; + vec<4,T,0x1022> const yxzz, grbb, tspp; + vec<4,T,0x1100> const yyxx, ggrr, ttss; + vec<4,T,0x1101> const yyxy, ggrg, ttst; + vec<4,T,0x1102> const yyxz, ggrb, ttsp; + vec<4,T,0x1110> const yyyx, gggr, ttts; + vec<4,T,0x1111> const yyyy, gggg, tttt; + vec<4,T,0x1112> const yyyz, gggb, tttp; + vec<4,T,0x1120> const yyzx, ggbr, ttps; + vec<4,T,0x1121> const yyzy, ggbg, ttpt; + vec<4,T,0x1122> const yyzz, ggbb, ttpp; + vec<4,T,0x1200> const yzxx, gbrr, tpss; + vec<4,T,0x1201> const yzxy, gbrg, tpst; + vec<4,T,0x1202> const yzxz, gbrb, tpsp; + vec<4,T,0x1210> const yzyx, gbgr, tpts; + vec<4,T,0x1211> const yzyy, gbgg, tptt; + vec<4,T,0x1212> const yzyz, gbgb, tptp; + vec<4,T,0x1220> const yzzx, gbbr, tpps; + vec<4,T,0x1221> const yzzy, gbbg, tppt; + vec<4,T,0x1222> const yzzz, gbbb, tppp; + vec<4,T,0x2000> const zxxx, brrr, psss; + vec<4,T,0x2001> const zxxy, brrg, psst; + vec<4,T,0x2002> const zxxz, brrb, pssp; + vec<4,T,0x2010> const zxyx, brgr, psts; + vec<4,T,0x2011> const zxyy, brgg, pstt; + vec<4,T,0x2012> const zxyz, brgb, pstp; + vec<4,T,0x2020> const zxzx, brbr, psps; + vec<4,T,0x2021> const zxzy, brbg, pspt; + vec<4,T,0x2022> const zxzz, brbb, pspp; + vec<4,T,0x2100> const zyxx, bgrr, ptss; + vec<4,T,0x2101> const zyxy, bgrg, ptst; + vec<4,T,0x2102> const zyxz, bgrb, ptsp; + vec<4,T,0x2110> const zyyx, bggr, ptts; + vec<4,T,0x2111> const zyyy, bggg, pttt; + vec<4,T,0x2112> const zyyz, bggb, pttp; + vec<4,T,0x2120> const zyzx, bgbr, ptps; + vec<4,T,0x2121> const zyzy, bgbg, ptpt; + vec<4,T,0x2122> const zyzz, bgbb, ptpp; + vec<4,T,0x2200> const zzxx, bbrr, ppss; + vec<4,T,0x2201> const zzxy, bbrg, ppst; + vec<4,T,0x2202> const zzxz, bbrb, ppsp; + vec<4,T,0x2210> const zzyx, bbgr, ppts; + vec<4,T,0x2211> const zzyy, bbgg, pptt; + vec<4,T,0x2212> const zzyz, bbgb, pptp; + vec<4,T,0x2220> const zzzx, bbbr, ppps; + vec<4,T,0x2221> const zzzy, bbbg, pppt; + vec<4,T,0x2222> const zzzz, bbbb, pppp; #endif }; }; -template <> struct BVec3 +template <> struct base_vec3 { - explicit inline BVec3() {} - explicit inline BVec3(half X, half Y, half Z) + explicit inline base_vec3() {} + explicit inline base_vec3(half X, half Y, half Z) : x(X), y(Y), z(Z) {} half x, y, z; }; -template <> struct BVec3 +template <> struct base_vec3 { - explicit inline BVec3() {} - explicit inline BVec3(real X, real Y, real Z) : x(X), y(Y), z(Z) {} + explicit inline base_vec3() {} + explicit inline base_vec3(real X, real Y, real Z) : x(X), y(Y), z(Z) {} real x, y, z; }; -template struct Vec3 : BVec3 +template +struct vec<3,T> : base_vec3 { - inline LOL_CONSTEXPR Vec3() {} - inline LOL_CONSTEXPR Vec3(T X, T Y, T Z) : BVec3(X, Y, Z) {} - inline LOL_CONSTEXPR Vec3(Vec2 XY, T Z) : BVec3(XY.x, XY.y, Z) {} - inline LOL_CONSTEXPR Vec3(T X, Vec2 YZ) : BVec3(X, YZ.x, YZ.y) {} - - explicit inline LOL_CONSTEXPR Vec3(T X) : BVec3(X, X, X) {} - - template - inline LOL_CONSTEXPR Vec3(XVec3 const &v) - : BVec3(v[0], v[1], v[2]) {} - - template - explicit inline LOL_CONSTEXPR Vec3(XVec3 const &v) - : BVec3(v[0], v[1], v[2]) {} - - static Vec3 toeuler_xyx(Quat const &q); - static Vec3 toeuler_xzx(Quat const &q); - static Vec3 toeuler_yxy(Quat const &q); - static Vec3 toeuler_yzy(Quat const &q); - static Vec3 toeuler_zxz(Quat const &q); - static Vec3 toeuler_zyz(Quat const &q); - - static Vec3 toeuler_xyz(Quat const &q); - static Vec3 toeuler_xzy(Quat const &q); - static Vec3 toeuler_yxz(Quat const &q); - static Vec3 toeuler_yzx(Quat const &q); - static Vec3 toeuler_zxy(Quat const &q); - static Vec3 toeuler_zyx(Quat const &q); - - LOL_MEMBER_OPS(Vec3, x) - - static const Vec3 zero; - static const Vec3 axis_x; - static const Vec3 axis_y; - static const Vec3 axis_z; + typedef vec<3,T> type; + + inline constexpr vec() {} + inline constexpr vec(T X, T Y, T Z) : base_vec3(X, Y, Z) {} + inline constexpr vec(vec<2,T> XY, T Z) : base_vec3(XY.x, XY.y, Z) {} + inline constexpr vec(T X, vec<2,T> YZ) : base_vec3(X, YZ.x, YZ.y) {} + + explicit inline constexpr vec(T X) : base_vec3(X, X, X) {} + + template + inline constexpr vec(vec<3, T, MASK> const &v) + : base_vec3(v[0], v[1], v[2]) {} + + template + explicit inline constexpr vec(vec<3, U, MASK> const &v) + : base_vec3(v[0], v[1], v[2]) {} + + LOL_COMMON_MEMBER_OPS(x) + LOL_VECTOR_MEMBER_OPS() + + static vec<3,T> toeuler_xyx(Quat const &q); + static vec<3,T> toeuler_xzx(Quat const &q); + static vec<3,T> toeuler_yxy(Quat const &q); + static vec<3,T> toeuler_yzy(Quat const &q); + static vec<3,T> toeuler_zxz(Quat const &q); + static vec<3,T> toeuler_zyz(Quat const &q); + + static vec<3,T> toeuler_xyz(Quat const &q); + static vec<3,T> toeuler_xzy(Quat const &q); + static vec<3,T> toeuler_yxz(Quat const &q); + static vec<3,T> toeuler_yzx(Quat const &q); + static vec<3,T> toeuler_zxy(Quat const &q); + static vec<3,T> toeuler_zyx(Quat const &q); + + /* Return the cross product (vector product) of "a" and "b" */ \ + friend inline type cross(type const &a, type const &b) + { + return type(a.y * b.z - a.z * b.y, + a.z * b.x - a.x * b.z, + a.x * b.y - a.y * b.x); + } + + /* Return a vector that is orthogonal to "a" */ + friend inline type orthogonal(type const &a) + { + return lol::abs(a.x) > lol::abs(a.z) + ? type(-a.y, a.x, (T)0) + : type((T)0, -a.z, a.y); + } + + /* Return a vector that is orthonormal to "a" */ + friend inline type orthonormal(type const &a) + { + return normalize(orthogonal(a)); + } + + static const vec<3,T> zero; + static const vec<3,T> axis_x; + static const vec<3,T> axis_y; + static const vec<3,T> axis_z; template - friend std::ostream &operator<<(std::ostream &stream, Vec3 const &v); + friend std::ostream &operator<<(std::ostream &stream, vec<3,U> const &v); }; /* * 4-element vectors */ -template struct BVec4 +template struct base_vec4 { - explicit inline LOL_CONSTEXPR BVec4() {} - explicit inline LOL_CONSTEXPR BVec4(T X, T Y, T Z, T W) + explicit inline constexpr base_vec4() {} + explicit inline constexpr base_vec4(T X, T Y, T Z, T W) : x(X), y(Y), z(Z), w(W) {} union @@ -571,404 +718,408 @@ template struct BVec4 struct { T s, t, p, q; }; #if !_DOXYGEN_SKIP_ME - XVec2 const xx, rr, ss; - XVec2 _____ xy, rg, st; - XVec2 _____ xz, rb, sp; - XVec2 _____ xw, ra, sq; - XVec2 _____ yx, gr, ts; - XVec2 const yy, gg, tt; - XVec2 _____ yz, gb, tp; - XVec2 _____ yw, ga, tq; - XVec2 _____ zx, br, ps; - XVec2 _____ zy, bg, pt; - XVec2 const zz, bb, pp; - XVec2 _____ zw, ba, pq; - XVec2 _____ wx, ar, qs; - XVec2 _____ wy, ag, qt; - XVec2 _____ wz, ab, qp; - XVec2 const ww, aa, qq; - - XVec3 const xxx, rrr, sss; - XVec3 const xxy, rrg, sst; - XVec3 const xxz, rrb, ssp; - XVec3 const xxw, rra, ssq; - XVec3 const xyx, rgr, sts; - XVec3 const xyy, rgg, stt; - XVec3 _____ xyz, rgb, stp; - XVec3 _____ xyw, rga, stq; - XVec3 const xzx, rbr, sps; - XVec3 _____ xzy, rbg, spt; - XVec3 const xzz, rbb, spp; - XVec3 _____ xzw, rba, spq; - XVec3 const xwx, rar, sqs; - XVec3 _____ xwy, rag, sqt; - XVec3 _____ xwz, rab, sqp; - XVec3 const xww, raa, sqq; - XVec3 const yxx, grr, tss; - XVec3 const yxy, grg, tst; - XVec3 _____ yxz, grb, tsp; - XVec3 _____ yxw, gra, tsq; - XVec3 const yyx, ggr, tts; - XVec3 const yyy, ggg, ttt; - XVec3 const yyz, ggb, ttp; - XVec3 const yyw, gga, ttq; - XVec3 _____ yzx, gbr, tps; - XVec3 const yzy, gbg, tpt; - XVec3 const yzz, gbb, tpp; - XVec3 _____ yzw, gba, tpq; - XVec3 _____ ywx, gar, tqs; - XVec3 const ywy, gag, tqt; - XVec3 _____ ywz, gab, tqp; - XVec3 const yww, gaa, tqq; - XVec3 const zxx, brr, pss; - XVec3 _____ zxy, brg, pst; - XVec3 const zxz, brb, psp; - XVec3 _____ zxw, bra, psq; - XVec3 _____ zyx, bgr, pts; - XVec3 const zyy, bgg, ptt; - XVec3 const zyz, bgb, ptp; - XVec3 _____ zyw, bga, ptq; - XVec3 const zzx, bbr, pps; - XVec3 const zzy, bbg, ppt; - XVec3 const zzz, bbb, ppp; - XVec3 const zzw, bba, ppq; - XVec3 _____ zwx, bar, pqs; - XVec3 _____ zwy, bag, pqt; - XVec3 const zwz, bab, pqp; - XVec3 const zww, baa, pqq; - XVec3 const wxx, arr, qss; - XVec3 _____ wxy, arg, qst; - XVec3 _____ wxz, arb, qsp; - XVec3 const wxw, ara, qsq; - XVec3 _____ wyx, agr, qts; - XVec3 const wyy, agg, qtt; - XVec3 _____ wyz, agb, qtp; - XVec3 const wyw, aga, qtq; - XVec3 _____ wzx, abr, qps; - XVec3 _____ wzy, abg, qpt; - XVec3 const wzz, abb, qpp; - XVec3 const wzw, aba, qpq; - XVec3 const wwx, aar, qqs; - XVec3 const wwy, aag, qqt; - XVec3 const wwz, aab, qqp; - XVec3 const www, aaa, qqq; - - XVec4 const xxxx, rrrr, ssss; - XVec4 const xxxy, rrrg, ssst; - XVec4 const xxxz, rrrb, sssp; - XVec4 const xxxw, rrra, sssq; - XVec4 const xxyx, rrgr, ssts; - XVec4 const xxyy, rrgg, sstt; - XVec4 const xxyz, rrgb, sstp; - XVec4 const xxyw, rrga, sstq; - XVec4 const xxzx, rrbr, ssps; - XVec4 const xxzy, rrbg, sspt; - XVec4 const xxzz, rrbb, sspp; - XVec4 const xxzw, rrba, sspq; - XVec4 const xxwx, rrar, ssqs; - XVec4 const xxwy, rrag, ssqt; - XVec4 const xxwz, rrab, ssqp; - XVec4 const xxww, rraa, ssqq; - XVec4 const xyxx, rgrr, stss; - XVec4 const xyxy, rgrg, stst; - XVec4 const xyxz, rgrb, stsp; - XVec4 const xyxw, rgra, stsq; - XVec4 const xyyx, rggr, stts; - XVec4 const xyyy, rggg, sttt; - XVec4 const xyyz, rggb, sttp; - XVec4 const xyyw, rgga, sttq; - XVec4 const xyzx, rgbr, stps; - XVec4 const xyzy, rgbg, stpt; - XVec4 const xyzz, rgbb, stpp; - XVec4 _____ xyzw, rgba, stpq; - XVec4 const xywx, rgar, stqs; - XVec4 const xywy, rgag, stqt; - XVec4 _____ xywz, rgab, stqp; - XVec4 const xyww, rgaa, stqq; - XVec4 const xzxx, rbrr, spss; - XVec4 const xzxy, rbrg, spst; - XVec4 const xzxz, rbrb, spsp; - XVec4 const xzxw, rbra, spsq; - XVec4 const xzyx, rbgr, spts; - XVec4 const xzyy, rbgg, sptt; - XVec4 const xzyz, rbgb, sptp; - XVec4 _____ xzyw, rbga, sptq; - XVec4 const xzzx, rbbr, spps; - XVec4 const xzzy, rbbg, sppt; - XVec4 const xzzz, rbbb, sppp; - XVec4 const xzzw, rbba, sppq; - XVec4 const xzwx, rbar, spqs; - XVec4 _____ xzwy, rbag, spqt; - XVec4 const xzwz, rbab, spqp; - XVec4 const xzww, rbaa, spqq; - XVec4 const xwxx, rarr, sqss; - XVec4 const xwxy, rarg, sqst; - XVec4 const xwxz, rarb, sqsp; - XVec4 const xwxw, rara, sqsq; - XVec4 const xwyx, ragr, sqts; - XVec4 const xwyy, ragg, sqtt; - XVec4 _____ xwyz, ragb, sqtp; - XVec4 const xwyw, raga, sqtq; - XVec4 const xwzx, rabr, sqps; - XVec4 _____ xwzy, rabg, sqpt; - XVec4 const xwzz, rabb, sqpp; - XVec4 const xwzw, raba, sqpq; - XVec4 const xwwx, raar, sqqs; - XVec4 const xwwy, raag, sqqt; - XVec4 const xwwz, raab, sqqp; - XVec4 const xwww, raaa, sqqq; - XVec4 const yxxx, grrr, tsss; - XVec4 const yxxy, grrg, tsst; - XVec4 const yxxz, grrb, tssp; - XVec4 const yxxw, grra, tssq; - XVec4 const yxyx, grgr, tsts; - XVec4 const yxyy, grgg, tstt; - XVec4 const yxyz, grgb, tstp; - XVec4 const yxyw, grga, tstq; - XVec4 const yxzx, grbr, tsps; - XVec4 const yxzy, grbg, tspt; - XVec4 const yxzz, grbb, tspp; - XVec4 _____ yxzw, grba, tspq; - XVec4 const yxwx, grar, tsqs; - XVec4 const yxwy, grag, tsqt; - XVec4 _____ yxwz, grab, tsqp; - XVec4 const yxww, graa, tsqq; - XVec4 const yyxx, ggrr, ttss; - XVec4 const yyxy, ggrg, ttst; - XVec4 const yyxz, ggrb, ttsp; - XVec4 const yyxw, ggra, ttsq; - XVec4 const yyyx, gggr, ttts; - XVec4 const yyyy, gggg, tttt; - XVec4 const yyyz, gggb, tttp; - XVec4 const yyyw, ggga, tttq; - XVec4 const yyzx, ggbr, ttps; - XVec4 const yyzy, ggbg, ttpt; - XVec4 const yyzz, ggbb, ttpp; - XVec4 const yyzw, ggba, ttpq; - XVec4 const yywx, ggar, ttqs; - XVec4 const yywy, ggag, ttqt; - XVec4 const yywz, ggab, ttqp; - XVec4 const yyww, ggaa, ttqq; - XVec4 const yzxx, gbrr, tpss; - XVec4 const yzxy, gbrg, tpst; - XVec4 const yzxz, gbrb, tpsp; - XVec4 _____ yzxw, gbra, tpsq; - XVec4 const yzyx, gbgr, tpts; - XVec4 const yzyy, gbgg, tptt; - XVec4 const yzyz, gbgb, tptp; - XVec4 const yzyw, gbga, tptq; - XVec4 const yzzx, gbbr, tpps; - XVec4 const yzzy, gbbg, tppt; - XVec4 const yzzz, gbbb, tppp; - XVec4 const yzzw, gbba, tppq; - XVec4 _____ yzwx, gbar, tpqs; - XVec4 const yzwy, gbag, tpqt; - XVec4 const yzwz, gbab, tpqp; - XVec4 const yzww, gbaa, tpqq; - XVec4 const ywxx, garr, tqss; - XVec4 const ywxy, garg, tqst; - XVec4 _____ ywxz, garb, tqsp; - XVec4 const ywxw, gara, tqsq; - XVec4 const ywyx, gagr, tqts; - XVec4 const ywyy, gagg, tqtt; - XVec4 const ywyz, gagb, tqtp; - XVec4 const ywyw, gaga, tqtq; - XVec4 _____ ywzx, gabr, tqps; - XVec4 const ywzy, gabg, tqpt; - XVec4 const ywzz, gabb, tqpp; - XVec4 const ywzw, gaba, tqpq; - XVec4 const ywwx, gaar, tqqs; - XVec4 const ywwy, gaag, tqqt; - XVec4 const ywwz, gaab, tqqp; - XVec4 const ywww, gaaa, tqqq; - XVec4 const zxxx, brrr, psss; - XVec4 const zxxy, brrg, psst; - XVec4 const zxxz, brrb, pssp; - XVec4 const zxxw, brra, pssq; - XVec4 const zxyx, brgr, psts; - XVec4 const zxyy, brgg, pstt; - XVec4 const zxyz, brgb, pstp; - XVec4 _____ zxyw, brga, pstq; - XVec4 const zxzx, brbr, psps; - XVec4 const zxzy, brbg, pspt; - XVec4 const zxzz, brbb, pspp; - XVec4 const zxzw, brba, pspq; - XVec4 const zxwx, brar, psqs; - XVec4 _____ zxwy, brag, psqt; - XVec4 const zxwz, brab, psqp; - XVec4 const zxww, braa, psqq; - XVec4 const zyxx, bgrr, ptss; - XVec4 const zyxy, bgrg, ptst; - XVec4 const zyxz, bgrb, ptsp; - XVec4 _____ zyxw, bgra, ptsq; - XVec4 const zyyx, bggr, ptts; - XVec4 const zyyy, bggg, pttt; - XVec4 const zyyz, bggb, pttp; - XVec4 const zyyw, bgga, pttq; - XVec4 const zyzx, bgbr, ptps; - XVec4 const zyzy, bgbg, ptpt; - XVec4 const zyzz, bgbb, ptpp; - XVec4 const zyzw, bgba, ptpq; - XVec4 _____ zywx, bgar, ptqs; - XVec4 const zywy, bgag, ptqt; - XVec4 const zywz, bgab, ptqp; - XVec4 const zyww, bgaa, ptqq; - XVec4 const zzxx, bbrr, ppss; - XVec4 const zzxy, bbrg, ppst; - XVec4 const zzxz, bbrb, ppsp; - XVec4 const zzxw, bbra, ppsq; - XVec4 const zzyx, bbgr, ppts; - XVec4 const zzyy, bbgg, pptt; - XVec4 const zzyz, bbgb, pptp; - XVec4 const zzyw, bbga, pptq; - XVec4 const zzzx, bbbr, ppps; - XVec4 const zzzy, bbbg, pppt; - XVec4 const zzzz, bbbb, pppp; - XVec4 const zzzw, bbba, pppq; - XVec4 const zzwx, bbar, ppqs; - XVec4 const zzwy, bbag, ppqt; - XVec4 const zzwz, bbab, ppqp; - XVec4 const zzww, bbaa, ppqq; - XVec4 const zwxx, barr, pqss; - XVec4 _____ zwxy, barg, pqst; - XVec4 const zwxz, barb, pqsp; - XVec4 const zwxw, bara, pqsq; - XVec4 _____ zwyx, bagr, pqts; - XVec4 const zwyy, bagg, pqtt; - XVec4 const zwyz, bagb, pqtp; - XVec4 const zwyw, baga, pqtq; - XVec4 const zwzx, babr, pqps; - XVec4 const zwzy, babg, pqpt; - XVec4 const zwzz, babb, pqpp; - XVec4 const zwzw, baba, pqpq; - XVec4 const zwwx, baar, pqqs; - XVec4 const zwwy, baag, pqqt; - XVec4 const zwwz, baab, pqqp; - XVec4 const zwww, baaa, pqqq; - XVec4 const wxxx, arrr, qsss; - XVec4 const wxxy, arrg, qsst; - XVec4 const wxxz, arrb, qssp; - XVec4 const wxxw, arra, qssq; - XVec4 const wxyx, argr, qsts; - XVec4 const wxyy, argg, qstt; - XVec4 _____ wxyz, argb, qstp; - XVec4 const wxyw, arga, qstq; - XVec4 const wxzx, arbr, qsps; - XVec4 _____ wxzy, arbg, qspt; - XVec4 const wxzz, arbb, qspp; - XVec4 const wxzw, arba, qspq; - XVec4 const wxwx, arar, qsqs; - XVec4 const wxwy, arag, qsqt; - XVec4 const wxwz, arab, qsqp; - XVec4 const wxww, araa, qsqq; - XVec4 const wyxx, agrr, qtss; - XVec4 const wyxy, agrg, qtst; - XVec4 _____ wyxz, agrb, qtsp; - XVec4 const wyxw, agra, qtsq; - XVec4 const wyyx, aggr, qtts; - XVec4 const wyyy, aggg, qttt; - XVec4 const wyyz, aggb, qttp; - XVec4 const wyyw, agga, qttq; - XVec4 _____ wyzx, agbr, qtps; - XVec4 const wyzy, agbg, qtpt; - XVec4 const wyzz, agbb, qtpp; - XVec4 const wyzw, agba, qtpq; - XVec4 const wywx, agar, qtqs; - XVec4 const wywy, agag, qtqt; - XVec4 const wywz, agab, qtqp; - XVec4 const wyww, agaa, qtqq; - XVec4 const wzxx, abrr, qpss; - XVec4 _____ wzxy, abrg, qpst; - XVec4 const wzxz, abrb, qpsp; - XVec4 const wzxw, abra, qpsq; - XVec4 _____ wzyx, abgr, qpts; - XVec4 const wzyy, abgg, qptt; - XVec4 const wzyz, abgb, qptp; - XVec4 const wzyw, abga, qptq; - XVec4 const wzzx, abbr, qpps; - XVec4 const wzzy, abbg, qppt; - XVec4 const wzzz, abbb, qppp; - XVec4 const wzzw, abba, qppq; - XVec4 const wzwx, abar, qpqs; - XVec4 const wzwy, abag, qpqt; - XVec4 const wzwz, abab, qpqp; - XVec4 const wzww, abaa, qpqq; - XVec4 const wwxx, aarr, qqss; - XVec4 const wwxy, aarg, qqst; - XVec4 const wwxz, aarb, qqsp; - XVec4 const wwxw, aara, qqsq; - XVec4 const wwyx, aagr, qqts; - XVec4 const wwyy, aagg, qqtt; - XVec4 const wwyz, aagb, qqtp; - XVec4 const wwyw, aaga, qqtq; - XVec4 const wwzx, aabr, qqps; - XVec4 const wwzy, aabg, qqpt; - XVec4 const wwzz, aabb, qqpp; - XVec4 const wwzw, aaba, qqpq; - XVec4 const wwwx, aaar, qqqs; - XVec4 const wwwy, aaag, qqqt; - XVec4 const wwwz, aaab, qqqp; - XVec4 const wwww, aaaa, qqqq; + vec<2,T,0x00> const xx, rr, ss; + vec<2,T,0x01> _____ xy, rg, st; + vec<2,T,0x02> _____ xz, rb, sp; + vec<2,T,0x03> _____ xw, ra, sq; + vec<2,T,0x10> _____ yx, gr, ts; + vec<2,T,0x11> const yy, gg, tt; + vec<2,T,0x12> _____ yz, gb, tp; + vec<2,T,0x13> _____ yw, ga, tq; + vec<2,T,0x20> _____ zx, br, ps; + vec<2,T,0x21> _____ zy, bg, pt; + vec<2,T,0x22> const zz, bb, pp; + vec<2,T,0x23> _____ zw, ba, pq; + vec<2,T,0x30> _____ wx, ar, qs; + vec<2,T,0x31> _____ wy, ag, qt; + vec<2,T,0x32> _____ wz, ab, qp; + vec<2,T,0x33> const ww, aa, qq; + + vec<3,T,0x000> const xxx, rrr, sss; + vec<3,T,0x001> const xxy, rrg, sst; + vec<3,T,0x002> const xxz, rrb, ssp; + vec<3,T,0x003> const xxw, rra, ssq; + vec<3,T,0x010> const xyx, rgr, sts; + vec<3,T,0x011> const xyy, rgg, stt; + vec<3,T,0x012> _____ xyz, rgb, stp; + vec<3,T,0x013> _____ xyw, rga, stq; + vec<3,T,0x020> const xzx, rbr, sps; + vec<3,T,0x021> _____ xzy, rbg, spt; + vec<3,T,0x022> const xzz, rbb, spp; + vec<3,T,0x023> _____ xzw, rba, spq; + vec<3,T,0x030> const xwx, rar, sqs; + vec<3,T,0x031> _____ xwy, rag, sqt; + vec<3,T,0x032> _____ xwz, rab, sqp; + vec<3,T,0x033> const xww, raa, sqq; + vec<3,T,0x100> const yxx, grr, tss; + vec<3,T,0x101> const yxy, grg, tst; + vec<3,T,0x102> _____ yxz, grb, tsp; + vec<3,T,0x103> _____ yxw, gra, tsq; + vec<3,T,0x110> const yyx, ggr, tts; + vec<3,T,0x111> const yyy, ggg, ttt; + vec<3,T,0x112> const yyz, ggb, ttp; + vec<3,T,0x113> const yyw, gga, ttq; + vec<3,T,0x120> _____ yzx, gbr, tps; + vec<3,T,0x121> const yzy, gbg, tpt; + vec<3,T,0x122> const yzz, gbb, tpp; + vec<3,T,0x123> _____ yzw, gba, tpq; + vec<3,T,0x130> _____ ywx, gar, tqs; + vec<3,T,0x131> const ywy, gag, tqt; + vec<3,T,0x132> _____ ywz, gab, tqp; + vec<3,T,0x133> const yww, gaa, tqq; + vec<3,T,0x200> const zxx, brr, pss; + vec<3,T,0x201> _____ zxy, brg, pst; + vec<3,T,0x202> const zxz, brb, psp; + vec<3,T,0x203> _____ zxw, bra, psq; + vec<3,T,0x210> _____ zyx, bgr, pts; + vec<3,T,0x211> const zyy, bgg, ptt; + vec<3,T,0x212> const zyz, bgb, ptp; + vec<3,T,0x213> _____ zyw, bga, ptq; + vec<3,T,0x220> const zzx, bbr, pps; + vec<3,T,0x221> const zzy, bbg, ppt; + vec<3,T,0x222> const zzz, bbb, ppp; + vec<3,T,0x223> const zzw, bba, ppq; + vec<3,T,0x230> _____ zwx, bar, pqs; + vec<3,T,0x231> _____ zwy, bag, pqt; + vec<3,T,0x232> const zwz, bab, pqp; + vec<3,T,0x233> const zww, baa, pqq; + vec<3,T,0x300> const wxx, arr, qss; + vec<3,T,0x301> _____ wxy, arg, qst; + vec<3,T,0x302> _____ wxz, arb, qsp; + vec<3,T,0x303> const wxw, ara, qsq; + vec<3,T,0x310> _____ wyx, agr, qts; + vec<3,T,0x311> const wyy, agg, qtt; + vec<3,T,0x312> _____ wyz, agb, qtp; + vec<3,T,0x313> const wyw, aga, qtq; + vec<3,T,0x320> _____ wzx, abr, qps; + vec<3,T,0x321> _____ wzy, abg, qpt; + vec<3,T,0x322> const wzz, abb, qpp; + vec<3,T,0x323> const wzw, aba, qpq; + vec<3,T,0x330> const wwx, aar, qqs; + vec<3,T,0x331> const wwy, aag, qqt; + vec<3,T,0x332> const wwz, aab, qqp; + vec<3,T,0x333> const www, aaa, qqq; + + vec<4,T,0x0000> const xxxx, rrrr, ssss; + vec<4,T,0x0001> const xxxy, rrrg, ssst; + vec<4,T,0x0002> const xxxz, rrrb, sssp; + vec<4,T,0x0003> const xxxw, rrra, sssq; + vec<4,T,0x0010> const xxyx, rrgr, ssts; + vec<4,T,0x0011> const xxyy, rrgg, sstt; + vec<4,T,0x0012> const xxyz, rrgb, sstp; + vec<4,T,0x0013> const xxyw, rrga, sstq; + vec<4,T,0x0020> const xxzx, rrbr, ssps; + vec<4,T,0x0021> const xxzy, rrbg, sspt; + vec<4,T,0x0022> const xxzz, rrbb, sspp; + vec<4,T,0x0023> const xxzw, rrba, sspq; + vec<4,T,0x0030> const xxwx, rrar, ssqs; + vec<4,T,0x0031> const xxwy, rrag, ssqt; + vec<4,T,0x0032> const xxwz, rrab, ssqp; + vec<4,T,0x0033> const xxww, rraa, ssqq; + vec<4,T,0x0100> const xyxx, rgrr, stss; + vec<4,T,0x0101> const xyxy, rgrg, stst; + vec<4,T,0x0102> const xyxz, rgrb, stsp; + vec<4,T,0x0103> const xyxw, rgra, stsq; + vec<4,T,0x0110> const xyyx, rggr, stts; + vec<4,T,0x0111> const xyyy, rggg, sttt; + vec<4,T,0x0112> const xyyz, rggb, sttp; + vec<4,T,0x0113> const xyyw, rgga, sttq; + vec<4,T,0x0120> const xyzx, rgbr, stps; + vec<4,T,0x0121> const xyzy, rgbg, stpt; + vec<4,T,0x0122> const xyzz, rgbb, stpp; + vec<4,T,0x0123> _____ xyzw, rgba, stpq; + vec<4,T,0x0130> const xywx, rgar, stqs; + vec<4,T,0x0131> const xywy, rgag, stqt; + vec<4,T,0x0132> _____ xywz, rgab, stqp; + vec<4,T,0x0133> const xyww, rgaa, stqq; + vec<4,T,0x0200> const xzxx, rbrr, spss; + vec<4,T,0x0201> const xzxy, rbrg, spst; + vec<4,T,0x0202> const xzxz, rbrb, spsp; + vec<4,T,0x0203> const xzxw, rbra, spsq; + vec<4,T,0x0210> const xzyx, rbgr, spts; + vec<4,T,0x0211> const xzyy, rbgg, sptt; + vec<4,T,0x0212> const xzyz, rbgb, sptp; + vec<4,T,0x0213> _____ xzyw, rbga, sptq; + vec<4,T,0x0220> const xzzx, rbbr, spps; + vec<4,T,0x0221> const xzzy, rbbg, sppt; + vec<4,T,0x0222> const xzzz, rbbb, sppp; + vec<4,T,0x0223> const xzzw, rbba, sppq; + vec<4,T,0x0230> const xzwx, rbar, spqs; + vec<4,T,0x0231> _____ xzwy, rbag, spqt; + vec<4,T,0x0232> const xzwz, rbab, spqp; + vec<4,T,0x0233> const xzww, rbaa, spqq; + vec<4,T,0x0300> const xwxx, rarr, sqss; + vec<4,T,0x0301> const xwxy, rarg, sqst; + vec<4,T,0x0302> const xwxz, rarb, sqsp; + vec<4,T,0x0303> const xwxw, rara, sqsq; + vec<4,T,0x0310> const xwyx, ragr, sqts; + vec<4,T,0x0311> const xwyy, ragg, sqtt; + vec<4,T,0x0312> _____ xwyz, ragb, sqtp; + vec<4,T,0x0313> const xwyw, raga, sqtq; + vec<4,T,0x0320> const xwzx, rabr, sqps; + vec<4,T,0x0321> _____ xwzy, rabg, sqpt; + vec<4,T,0x0322> const xwzz, rabb, sqpp; + vec<4,T,0x0323> const xwzw, raba, sqpq; + vec<4,T,0x0330> const xwwx, raar, sqqs; + vec<4,T,0x0331> const xwwy, raag, sqqt; + vec<4,T,0x0332> const xwwz, raab, sqqp; + vec<4,T,0x0333> const xwww, raaa, sqqq; + vec<4,T,0x1000> const yxxx, grrr, tsss; + vec<4,T,0x1001> const yxxy, grrg, tsst; + vec<4,T,0x1002> const yxxz, grrb, tssp; + vec<4,T,0x1003> const yxxw, grra, tssq; + vec<4,T,0x1010> const yxyx, grgr, tsts; + vec<4,T,0x1011> const yxyy, grgg, tstt; + vec<4,T,0x1012> const yxyz, grgb, tstp; + vec<4,T,0x1013> const yxyw, grga, tstq; + vec<4,T,0x1020> const yxzx, grbr, tsps; + vec<4,T,0x1021> const yxzy, grbg, tspt; + vec<4,T,0x1022> const yxzz, grbb, tspp; + vec<4,T,0x1023> _____ yxzw, grba, tspq; + vec<4,T,0x1030> const yxwx, grar, tsqs; + vec<4,T,0x1031> const yxwy, grag, tsqt; + vec<4,T,0x1032> _____ yxwz, grab, tsqp; + vec<4,T,0x1033> const yxww, graa, tsqq; + vec<4,T,0x1100> const yyxx, ggrr, ttss; + vec<4,T,0x1101> const yyxy, ggrg, ttst; + vec<4,T,0x1102> const yyxz, ggrb, ttsp; + vec<4,T,0x1103> const yyxw, ggra, ttsq; + vec<4,T,0x1110> const yyyx, gggr, ttts; + vec<4,T,0x1111> const yyyy, gggg, tttt; + vec<4,T,0x1112> const yyyz, gggb, tttp; + vec<4,T,0x1113> const yyyw, ggga, tttq; + vec<4,T,0x1120> const yyzx, ggbr, ttps; + vec<4,T,0x1121> const yyzy, ggbg, ttpt; + vec<4,T,0x1122> const yyzz, ggbb, ttpp; + vec<4,T,0x1123> const yyzw, ggba, ttpq; + vec<4,T,0x1130> const yywx, ggar, ttqs; + vec<4,T,0x1131> const yywy, ggag, ttqt; + vec<4,T,0x1132> const yywz, ggab, ttqp; + vec<4,T,0x1133> const yyww, ggaa, ttqq; + vec<4,T,0x1200> const yzxx, gbrr, tpss; + vec<4,T,0x1201> const yzxy, gbrg, tpst; + vec<4,T,0x1202> const yzxz, gbrb, tpsp; + vec<4,T,0x1203> _____ yzxw, gbra, tpsq; + vec<4,T,0x1210> const yzyx, gbgr, tpts; + vec<4,T,0x1211> const yzyy, gbgg, tptt; + vec<4,T,0x1212> const yzyz, gbgb, tptp; + vec<4,T,0x1213> const yzyw, gbga, tptq; + vec<4,T,0x1220> const yzzx, gbbr, tpps; + vec<4,T,0x1221> const yzzy, gbbg, tppt; + vec<4,T,0x1222> const yzzz, gbbb, tppp; + vec<4,T,0x1223> const yzzw, gbba, tppq; + vec<4,T,0x1230> _____ yzwx, gbar, tpqs; + vec<4,T,0x1231> const yzwy, gbag, tpqt; + vec<4,T,0x1232> const yzwz, gbab, tpqp; + vec<4,T,0x1233> const yzww, gbaa, tpqq; + vec<4,T,0x1300> const ywxx, garr, tqss; + vec<4,T,0x1301> const ywxy, garg, tqst; + vec<4,T,0x1302> _____ ywxz, garb, tqsp; + vec<4,T,0x1303> const ywxw, gara, tqsq; + vec<4,T,0x1310> const ywyx, gagr, tqts; + vec<4,T,0x1311> const ywyy, gagg, tqtt; + vec<4,T,0x1312> const ywyz, gagb, tqtp; + vec<4,T,0x1313> const ywyw, gaga, tqtq; + vec<4,T,0x1320> _____ ywzx, gabr, tqps; + vec<4,T,0x1321> const ywzy, gabg, tqpt; + vec<4,T,0x1322> const ywzz, gabb, tqpp; + vec<4,T,0x1323> const ywzw, gaba, tqpq; + vec<4,T,0x1330> const ywwx, gaar, tqqs; + vec<4,T,0x1331> const ywwy, gaag, tqqt; + vec<4,T,0x1332> const ywwz, gaab, tqqp; + vec<4,T,0x1333> const ywww, gaaa, tqqq; + vec<4,T,0x2000> const zxxx, brrr, psss; + vec<4,T,0x2001> const zxxy, brrg, psst; + vec<4,T,0x2002> const zxxz, brrb, pssp; + vec<4,T,0x2003> const zxxw, brra, pssq; + vec<4,T,0x2010> const zxyx, brgr, psts; + vec<4,T,0x2011> const zxyy, brgg, pstt; + vec<4,T,0x2012> const zxyz, brgb, pstp; + vec<4,T,0x2013> _____ zxyw, brga, pstq; + vec<4,T,0x2020> const zxzx, brbr, psps; + vec<4,T,0x2021> const zxzy, brbg, pspt; + vec<4,T,0x2022> const zxzz, brbb, pspp; + vec<4,T,0x2023> const zxzw, brba, pspq; + vec<4,T,0x2030> const zxwx, brar, psqs; + vec<4,T,0x2031> _____ zxwy, brag, psqt; + vec<4,T,0x2032> const zxwz, brab, psqp; + vec<4,T,0x2033> const zxww, braa, psqq; + vec<4,T,0x2100> const zyxx, bgrr, ptss; + vec<4,T,0x2101> const zyxy, bgrg, ptst; + vec<4,T,0x2102> const zyxz, bgrb, ptsp; + vec<4,T,0x2103> _____ zyxw, bgra, ptsq; + vec<4,T,0x2110> const zyyx, bggr, ptts; + vec<4,T,0x2111> const zyyy, bggg, pttt; + vec<4,T,0x2112> const zyyz, bggb, pttp; + vec<4,T,0x2113> const zyyw, bgga, pttq; + vec<4,T,0x2120> const zyzx, bgbr, ptps; + vec<4,T,0x2121> const zyzy, bgbg, ptpt; + vec<4,T,0x2122> const zyzz, bgbb, ptpp; + vec<4,T,0x2123> const zyzw, bgba, ptpq; + vec<4,T,0x2130> _____ zywx, bgar, ptqs; + vec<4,T,0x2131> const zywy, bgag, ptqt; + vec<4,T,0x2132> const zywz, bgab, ptqp; + vec<4,T,0x2133> const zyww, bgaa, ptqq; + vec<4,T,0x2200> const zzxx, bbrr, ppss; + vec<4,T,0x2201> const zzxy, bbrg, ppst; + vec<4,T,0x2202> const zzxz, bbrb, ppsp; + vec<4,T,0x2203> const zzxw, bbra, ppsq; + vec<4,T,0x2210> const zzyx, bbgr, ppts; + vec<4,T,0x2211> const zzyy, bbgg, pptt; + vec<4,T,0x2212> const zzyz, bbgb, pptp; + vec<4,T,0x2213> const zzyw, bbga, pptq; + vec<4,T,0x2220> const zzzx, bbbr, ppps; + vec<4,T,0x2221> const zzzy, bbbg, pppt; + vec<4,T,0x2222> const zzzz, bbbb, pppp; + vec<4,T,0x2223> const zzzw, bbba, pppq; + vec<4,T,0x2230> const zzwx, bbar, ppqs; + vec<4,T,0x2231> const zzwy, bbag, ppqt; + vec<4,T,0x2232> const zzwz, bbab, ppqp; + vec<4,T,0x2233> const zzww, bbaa, ppqq; + vec<4,T,0x2300> const zwxx, barr, pqss; + vec<4,T,0x2301> _____ zwxy, barg, pqst; + vec<4,T,0x2302> const zwxz, barb, pqsp; + vec<4,T,0x2303> const zwxw, bara, pqsq; + vec<4,T,0x2310> _____ zwyx, bagr, pqts; + vec<4,T,0x2311> const zwyy, bagg, pqtt; + vec<4,T,0x2312> const zwyz, bagb, pqtp; + vec<4,T,0x2313> const zwyw, baga, pqtq; + vec<4,T,0x2320> const zwzx, babr, pqps; + vec<4,T,0x2321> const zwzy, babg, pqpt; + vec<4,T,0x2322> const zwzz, babb, pqpp; + vec<4,T,0x2323> const zwzw, baba, pqpq; + vec<4,T,0x2330> const zwwx, baar, pqqs; + vec<4,T,0x2331> const zwwy, baag, pqqt; + vec<4,T,0x2332> const zwwz, baab, pqqp; + vec<4,T,0x2333> const zwww, baaa, pqqq; + vec<4,T,0x3000> const wxxx, arrr, qsss; + vec<4,T,0x3001> const wxxy, arrg, qsst; + vec<4,T,0x3002> const wxxz, arrb, qssp; + vec<4,T,0x3003> const wxxw, arra, qssq; + vec<4,T,0x3010> const wxyx, argr, qsts; + vec<4,T,0x3011> const wxyy, argg, qstt; + vec<4,T,0x3012> _____ wxyz, argb, qstp; + vec<4,T,0x3013> const wxyw, arga, qstq; + vec<4,T,0x3020> const wxzx, arbr, qsps; + vec<4,T,0x3021> _____ wxzy, arbg, qspt; + vec<4,T,0x3022> const wxzz, arbb, qspp; + vec<4,T,0x3023> const wxzw, arba, qspq; + vec<4,T,0x3030> const wxwx, arar, qsqs; + vec<4,T,0x3031> const wxwy, arag, qsqt; + vec<4,T,0x3032> const wxwz, arab, qsqp; + vec<4,T,0x3033> const wxww, araa, qsqq; + vec<4,T,0x3100> const wyxx, agrr, qtss; + vec<4,T,0x3101> const wyxy, agrg, qtst; + vec<4,T,0x3102> _____ wyxz, agrb, qtsp; + vec<4,T,0x3103> const wyxw, agra, qtsq; + vec<4,T,0x3110> const wyyx, aggr, qtts; + vec<4,T,0x3111> const wyyy, aggg, qttt; + vec<4,T,0x3112> const wyyz, aggb, qttp; + vec<4,T,0x3113> const wyyw, agga, qttq; + vec<4,T,0x3120> _____ wyzx, agbr, qtps; + vec<4,T,0x3121> const wyzy, agbg, qtpt; + vec<4,T,0x3122> const wyzz, agbb, qtpp; + vec<4,T,0x3123> const wyzw, agba, qtpq; + vec<4,T,0x3130> const wywx, agar, qtqs; + vec<4,T,0x3131> const wywy, agag, qtqt; + vec<4,T,0x3132> const wywz, agab, qtqp; + vec<4,T,0x3133> const wyww, agaa, qtqq; + vec<4,T,0x3200> const wzxx, abrr, qpss; + vec<4,T,0x3201> _____ wzxy, abrg, qpst; + vec<4,T,0x3202> const wzxz, abrb, qpsp; + vec<4,T,0x3203> const wzxw, abra, qpsq; + vec<4,T,0x3210> _____ wzyx, abgr, qpts; + vec<4,T,0x3211> const wzyy, abgg, qptt; + vec<4,T,0x3212> const wzyz, abgb, qptp; + vec<4,T,0x3213> const wzyw, abga, qptq; + vec<4,T,0x3220> const wzzx, abbr, qpps; + vec<4,T,0x3221> const wzzy, abbg, qppt; + vec<4,T,0x3222> const wzzz, abbb, qppp; + vec<4,T,0x3223> const wzzw, abba, qppq; + vec<4,T,0x3230> const wzwx, abar, qpqs; + vec<4,T,0x3231> const wzwy, abag, qpqt; + vec<4,T,0x3232> const wzwz, abab, qpqp; + vec<4,T,0x3233> const wzww, abaa, qpqq; + vec<4,T,0x3300> const wwxx, aarr, qqss; + vec<4,T,0x3301> const wwxy, aarg, qqst; + vec<4,T,0x3302> const wwxz, aarb, qqsp; + vec<4,T,0x3303> const wwxw, aara, qqsq; + vec<4,T,0x3310> const wwyx, aagr, qqts; + vec<4,T,0x3311> const wwyy, aagg, qqtt; + vec<4,T,0x3312> const wwyz, aagb, qqtp; + vec<4,T,0x3313> const wwyw, aaga, qqtq; + vec<4,T,0x3320> const wwzx, aabr, qqps; + vec<4,T,0x3321> const wwzy, aabg, qqpt; + vec<4,T,0x3322> const wwzz, aabb, qqpp; + vec<4,T,0x3323> const wwzw, aaba, qqpq; + vec<4,T,0x3330> const wwwx, aaar, qqqs; + vec<4,T,0x3331> const wwwy, aaag, qqqt; + vec<4,T,0x3332> const wwwz, aaab, qqqp; + vec<4,T,0x3333> const wwww, aaaa, qqqq; #endif }; }; -template <> struct BVec4 +template <> struct base_vec4 { - explicit inline BVec4() {} - explicit inline BVec4(half X, half Y, half Z, half W) + explicit inline base_vec4() {} + explicit inline base_vec4(half X, half Y, half Z, half W) : x(X), y(Y), z(Z), w(W) {} half x, y, z, w; }; -template <> struct BVec4 +template <> struct base_vec4 { - explicit inline BVec4() {} - explicit inline BVec4(real X, real Y, real Z, real W) + explicit inline base_vec4() {} + explicit inline base_vec4(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 +template +struct vec<4,T> : base_vec4 { - inline LOL_CONSTEXPR Vec4() {} - inline LOL_CONSTEXPR Vec4(T X, T Y, T Z, T W) - : BVec4(X, Y, Z, W) {} - inline LOL_CONSTEXPR Vec4(Vec2 XY, T Z, T W) - : BVec4(XY.x, XY.y, Z, W) {} - inline LOL_CONSTEXPR Vec4(T X, Vec2 YZ, T W) - : BVec4(X, YZ.x, YZ.y, W) {} - inline LOL_CONSTEXPR Vec4(T X, T Y, Vec2 ZW) - : BVec4(X, Y, ZW.x, ZW.y) {} - inline LOL_CONSTEXPR Vec4(Vec2 XY, Vec2 ZW) - : BVec4(XY.x, XY.y, ZW.x, ZW.y) {} - inline LOL_CONSTEXPR Vec4(Vec3 XYZ, T W) - : BVec4(XYZ.x, XYZ.y, XYZ.z, W) {} - inline LOL_CONSTEXPR Vec4(T X, Vec3 YZW) - : BVec4(X, YZW.x, YZW.y, YZW.z) {} - - explicit inline LOL_CONSTEXPR Vec4(T X) : BVec4(X, X, X, X) {} - - template - inline LOL_CONSTEXPR Vec4(XVec4 const &v) - : BVec4(v[0], v[1], v[2], v[3]) {} - - template - explicit inline LOL_CONSTEXPR Vec4(XVec4 const &v) - : BVec4(v[0], v[1], v[2], v[3]) {} - - LOL_MEMBER_OPS(Vec4, x) - - static const Vec4 zero; - static const Vec4 axis_x; - static const Vec4 axis_y; - static const Vec4 axis_z; - static const Vec4 axis_w; + typedef vec<4,T> type; + + inline constexpr vec() {} + inline constexpr vec(T X, T Y, T Z, T W) + : base_vec4(X, Y, Z, W) {} + inline constexpr vec(vec<2,T> XY, T Z, T W) + : base_vec4(XY.x, XY.y, Z, W) {} + inline constexpr vec(T X, vec<2,T> YZ, T W) + : base_vec4(X, YZ.x, YZ.y, W) {} + inline constexpr vec(T X, T Y, vec<2,T> ZW) + : base_vec4(X, Y, ZW.x, ZW.y) {} + inline constexpr vec(vec<2,T> XY, vec<2,T> ZW) + : base_vec4(XY.x, XY.y, ZW.x, ZW.y) {} + inline constexpr vec(vec<3,T> XYZ, T W) + : base_vec4(XYZ.x, XYZ.y, XYZ.z, W) {} + inline constexpr vec(T X, vec<3,T> YZW) + : base_vec4(X, YZW.x, YZW.y, YZW.z) {} + + explicit inline constexpr vec(T X) : base_vec4(X, X, X, X) {} + + template + inline constexpr vec(vec<4, T, MASK> const &v) + : base_vec4(v[0], v[1], v[2], v[3]) {} + + template + explicit inline constexpr vec(vec<4, U, MASK> const &v) + : base_vec4(v[0], v[1], v[2], v[3]) {} + + LOL_COMMON_MEMBER_OPS(x) + LOL_VECTOR_MEMBER_OPS() + + static const vec<4,T> zero; + static const vec<4,T> axis_x; + static const vec<4,T> axis_y; + static const vec<4,T> axis_z; + static const vec<4,T> axis_w; template - friend std::ostream &operator<<(std::ostream &stream, Vec4 const &v); + friend std::ostream &operator<<(std::ostream &stream, vec<4,U> const &v); }; /* @@ -977,33 +1128,40 @@ template struct Vec4 : BVec4 template struct Quat { - inline LOL_CONSTEXPR Quat() {} - inline LOL_CONSTEXPR Quat(T W) : w(W), x(0), y(0), z(0) {} - inline LOL_CONSTEXPR Quat(T W, T X, T Y, T Z) : w(W), x(X), y(Y), z(Z) {} + typedef Quat type; + + inline constexpr Quat() {} + inline constexpr Quat(T W) : w(W), x(0), y(0), z(0) {} + inline constexpr Quat(T W, T X, T Y, T Z) : w(W), x(X), y(Y), z(Z) {} - Quat(Mat3 const &m); - Quat(Mat4 const &m); + template + explicit inline constexpr Quat(Quat const &q) + : Quat(q[0], q[1], q[2], q[3]) {} - LOL_MEMBER_OPS(Quat, w) + Quat(matrix<3,3,T> const &m); + Quat(matrix<4,4,T> const &m); + + LOL_COMMON_MEMBER_OPS(w) + LOL_NONVECTOR_MEMBER_OPS() /* Create a unit quaternion representing a rotation around an axis. */ static Quat rotate(T degrees, T x, T y, T z); - static Quat rotate(T degrees, Vec3 const &v); + static Quat rotate(T degrees, vec<3,T> const &v); /* Create a unit quaternion representing a rotation between two vectors. * Input vectors need not be normalised. */ - static Quat rotate(Vec3 const &src, Vec3 const &dst); + static Quat rotate(vec<3,T> const &src, vec<3,T> const &dst); /* Convert from Euler angles. The axes in fromeuler_xyx are * x, then y', then x", ie. the axes are attached to the model. * If you want to rotate around static axes, just reverse the order * of the arguments. Angle values are in degrees. */ - static Quat fromeuler_xyx(Vec3 const &v); - static Quat fromeuler_xzx(Vec3 const &v); - static Quat fromeuler_yxy(Vec3 const &v); - static Quat fromeuler_yzy(Vec3 const &v); - static Quat fromeuler_zxz(Vec3 const &v); - static Quat fromeuler_zyz(Vec3 const &v); + static Quat fromeuler_xyx(vec<3,T> const &v); + static Quat fromeuler_xzx(vec<3,T> const &v); + static Quat fromeuler_yxy(vec<3,T> const &v); + static Quat fromeuler_yzy(vec<3,T> const &v); + static Quat fromeuler_zxz(vec<3,T> const &v); + static Quat fromeuler_zyz(vec<3,T> const &v); static Quat fromeuler_xyx(T phi, T theta, T psi); static Quat fromeuler_xzx(T phi, T theta, T psi); static Quat fromeuler_yxy(T phi, T theta, T psi); @@ -1019,12 +1177,12 @@ template struct Quat * If you want to rotate around static axes, reverse the order in * the function name (_zyx instead of _xyz) AND reverse the order * of the arguments. */ - static Quat fromeuler_xyz(Vec3 const &v); - static Quat fromeuler_xzy(Vec3 const &v); - static Quat fromeuler_yxz(Vec3 const &v); - static Quat fromeuler_yzx(Vec3 const &v); - static Quat fromeuler_zxy(Vec3 const &v); - static Quat fromeuler_zyx(Vec3 const &v); + static Quat fromeuler_xyz(vec<3,T> const &v); + static Quat fromeuler_xzy(vec<3,T> const &v); + static Quat fromeuler_yxz(vec<3,T> const &v); + static Quat fromeuler_yzx(vec<3,T> const &v); + static Quat fromeuler_zxy(vec<3,T> const &v); + static Quat fromeuler_zyx(vec<3,T> const &v); static Quat fromeuler_xyz(T phi, T theta, T psi); static Quat fromeuler_xzy(T phi, T theta, T psi); static Quat fromeuler_yxz(T phi, T theta, T psi); @@ -1044,42 +1202,42 @@ template struct Quat return Quat(w, -x, -y, -z); } - inline Vec3 transform(Vec3 const &v) const + inline vec<3,T> transform(vec<3,T> const &v) const { Quat p = Quat(0, v.x, v.y, v.z); Quat q = *this * p / *this; - return Vec3(q.x, q.y, q.z); + return vec<3,T>(q.x, q.y, q.z); } - inline Vec4 transform(Vec4 const &v) const + inline vec<4,T> transform(vec<4,T> const &v) const { Quat p = Quat(0, v.x, v.y, v.z); Quat q = *this * p / *this; - return Vec4(q.x, q.y, q.z, v.w); + return vec<4,T>(q.x, q.y, q.z, v.w); } - inline Vec3 operator *(Vec3 const &v) const + inline vec<3,T> operator *(vec<3,T> const &v) const { return transform(v); } - inline Vec4 operator *(Vec4 const &v) const + inline vec<4,T> operator *(vec<4,T> const &v) const { return transform(v); } - inline Vec3 axis() + inline vec<3,T> axis() { - Vec3 v(x, y, z); + vec<3,T> v(x, y, z); T n2 = sqlength(v); if (n2 <= (T)1e-6) - return Vec3::axis_x; + return vec<3,T>::axis_x; return normalize(v); } inline T angle() { - Vec3 v(x, y, z); + vec<3,T> v(x, y, z); T n2 = sqlength(v); if (n2 <= (T)1e-6) return (T)0; @@ -1094,15 +1252,44 @@ template struct Quat }; template -inline T norm(Quat const &val) +static inline T dot(Quat const &q1, Quat const &q2) +{ + T ret(0); + for (size_t i = 0; i < sizeof(ret) / sizeof(T); ++i) + ret += q1[i] * q2[i]; + return ret; +} + +template +static inline T sqlength(Quat const &q) +{ + return dot(q, q); +} + +template +static inline T length(Quat const &q) +{ + /* FIXME: this is not very nice */ + return (T)sqrt((double)sqlength(q)); +} + +template +static inline T norm(Quat const &q) { - return length(val); + return length(q); } template -static inline Quat re(Quat const &val) +static inline Quat re(Quat const &q) { - return ~val / sqlength(val); + return ~q / sqlength(q); +} + +template +static inline Quat normalize(Quat const &q) +{ + T norm = (T)length(q); + return norm ? q / norm : Quat(T(0)); } template @@ -1121,444 +1308,255 @@ template extern Quat slerp(Quat const &qa, Quat const &qb, T f); /* - * Common operators for all vector types, including quaternions + * Clean up our ugly macros. */ -/* - * vec +(vec, vec) (also complex & quaternion) - * vec -(vec, vec) (also complex & quaternion) - * vec *(vec, vec) - * vec /(vec, vec) - */ -#define LOL_VECTOR_VECTOR_OP(tname, op, tprefix, type) \ - tprefix \ - inline tname operator op(tname const &a, tname const &b) \ - { \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = a[n] op b[n]; \ - return ret; \ - } +#undef LOL_COMMON_MEMBER_OPS +#undef LOL_VECTOR_MEMBER_OPS +#undef LOL_NONVECTOR_MEMBER_OPS -/* - * vec +=(vec, vec) (also complex & quaternion) - * vec -=(vec, vec) (also complex & quaternion) - * vec *=(vec, vec) - * vec /=(vec, vec) - */ -#define LOL_VECTOR_VECTOR_NONCONST_OP(tname, op, tprefix, type) \ - tprefix \ - inline tname operator op##=(tname &a, tname const &b) \ - { \ - return a = a op b; \ - } +#undef LOL_V_VV_OP +#undef LOL_V_VV_ASSIGN_OP +#undef LOL_V_VS_OP +#undef LOL_V_VS_ASSIGN_OP +#undef LOL_B_VV_OP /* - * vec min(vec, vec) (also max, fmod) - * vec min(vec, scalar) (also max, fmod) - * vec min(scalar, vec) (also max, fmod) + * Operators for swizzled vectors. Since template deduction cannot be + * done for two arbitrary vec<> values, we help the compiler understand + * the expected type. */ -#define LOL_VECTOR_MINMAX_FUN(tname, op, tprefix, type) \ - tprefix \ - inline tname op(tname const &a, tname const &b) \ - { \ - using lol::op; \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = op(a[n], b[n]); \ - return ret; \ - } \ - \ - tprefix \ - inline tname op(tname const &a, type const &b) \ + +template +static inline bool operator ==(vec const &a, + vec const &b) +{ + for (size_t i = 0; i < N; ++i) + if (!(a[i] == b[i])) + return false; + return true; +} + +template +static inline bool operator !=(vec const &a, + vec const &b) +{ + for (size_t i = 0; i < N; ++i) + if (a[i] != b[i]) + return true; + return false; +} + +#define LOL_SWIZZLE_V_VV_OP(op) \ + template \ + inline vec operator op(vec const &a, \ + vec const &b) \ { \ - using lol::op; \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = op(a[n], b); \ - return ret; \ + return vec(a) op vec(b); \ } \ \ - tprefix \ - inline tname op(type const &a, tname const &b) \ + template \ + inline vec operator op(vec a, T const &b) \ { \ - using lol::op; \ - tname ret; \ - for (size_t n = 0; n < sizeof(b) / sizeof(type); n++) \ - ret[n] = op(a, b[n]); \ - return ret; \ + return vec(a) op b; \ } +LOL_SWIZZLE_V_VV_OP(+) +LOL_SWIZZLE_V_VV_OP(-) +LOL_SWIZZLE_V_VV_OP(*) +LOL_SWIZZLE_V_VV_OP(/) + +#undef LOL_SWIZZLE_V_VV_OP + +template +static inline vec operator *(T const &val, vec const &a) +{ + vec ret; + for (size_t i = 0; i < N; ++i) + ret[i] = val * a[i]; + return ret; +} + /* - * vec clamp(vec, vec, vec) - * vec clamp(vec, vec, scalar) - * vec clamp(vec, scalar, vec) - * vec clamp(vec, scalar, scalar) + * vec min|max|fmod(vec, vec|scalar) + * vec min|max|fmod(scalar, vec) */ -#define LOL_VECTOR_CLAMP_FUN(tname, tprefix, type) \ - tprefix \ - inline tname clamp(tname const &x, \ - tname const &a, tname const &b) \ - { \ - return max(min(x, b), a); \ - } \ - \ - tprefix \ - inline tname clamp(tname const &x, \ - type const &a, tname const &b) \ + +#define LOL_SWIZZLE_V_VV_FUN(fun) \ + template \ + inline vec fun(vec const &a, vec const &b) \ { \ - return max(min(x, b), a); \ + using lol::fun; \ + vec ret; \ + for (size_t i = 0; i < N; ++i) \ + ret[i] = fun(a[i], b[i]); \ + return ret; \ } \ \ - tprefix \ - inline tname clamp(tname const &x, \ - tname const &a, type const &b) \ + template \ + inline vec fun(vec const &a, T const &b) \ { \ - return max(min(x, b), a); \ + using lol::fun; \ + vec ret; \ + for (size_t i = 0; i < N; ++i) \ + ret[i] = fun(a[i], b); \ + return ret; \ } \ \ - tprefix \ - inline tname clamp(tname const &x, \ - type const &a, type const &b) \ + template \ + inline vec fun(T const &a, vec const &b) \ { \ - return max(min(x, b), a); \ + using lol::fun; \ + vec ret; \ + for (size_t i = 0; i < N; ++i) \ + ret[i] = fun(a, b[i]); \ + return ret; \ } -/* - * vec mix(vec, vec, vec) - * vec mix(vec, vec, scalar) - */ -#define LOL_VECTOR_MIX_FUN(tname, tprefix, type) \ - tprefix \ - inline tname mix(tname const &x, \ - tname const &y, tname const &a) \ - { \ - return x + a * (y - x); \ - } \ - \ - tprefix \ - inline tname mix(tname const &x, \ - tname const &y, type const &a) \ - { \ - return x + a * (y - x); \ - } +LOL_SWIZZLE_V_VV_FUN(min) +LOL_SWIZZLE_V_VV_FUN(max) +LOL_SWIZZLE_V_VV_FUN(fmod) -/* - * bool ==(vec, vec) (also complex & quaternion) - * bool !=(vec, vec) (also complex & quaternion) - * bool >=(vec, vec) - * bool <=(vec, vec) - * bool >(vec, vec) - * bool <(vec, vec) - */ -#define LOL_VECTOR_VECTOR_BOOL_OP(tname, op, op2, ret, tprefix, type) \ - tprefix \ - inline bool operator op(tname const &a, tname const &b) \ - { \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - if (!(a[n] op2 b[n])) \ - return !ret; \ - return ret; \ - } +#undef LOL_SWIZZLE_V_VV_FUN /* - * vec *(vec, scalar) (also complex & quaternion) - * vec /(vec, scalar) (also complex & quaternion) + * vec clamp(vec, vec|scalar, vec|scalar) + * vec mix(vec, vec, vec|scalar) */ -#define LOL_VECTOR_SCALAR_OP(tname, op, tprefix, type) \ - tprefix \ - inline tname operator op(tname const &a, type const &val) \ - { \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = a[n] op val; \ - return ret; \ - } -/* - * vec *(scalar, vec) (also complex & quaternion) - * vec /(scalar, vec) (NOT for complex & quaternion!) - */ -#define LOL_SCALAR_VECTOR_OP(tname, op, tprefix, type) \ - tprefix \ - inline tname operator op(type const &val, tname const &a) \ - { \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = a[n] op val; \ - return ret; \ - } +template +static inline vec clamp(vec const &x, + vec const &a, + vec const &b) +{ + return max(min(x, b), a); +} + +template +static inline vec clamp(vec const &x, + T const &a, + vec const &b) +{ + return max(min(x, b), a); +} + +template +static inline vec clamp(vec const &x, + vec const &a, + T const &b) +{ + return max(min(x, b), a); +} + +template +static inline vec clamp(vec const &x, + T const &a, + T const &b) +{ + return max(min(x, b), a); +} + +template +static inline vec mix(vec const &x, + vec const &y, + vec const &a) +{ + return x + a * (y - x); +} + +template +static inline vec mix(vec const &x, + vec const &y, + T const &a) +{ + return x + a * (y - x); +} /* - * vec *=(vec, scalar) (also complex & quaternion) - * vec /=(vec, scalar) (also complex & quaternion) + * Some GLSL-like functions. */ -#define LOL_VECTOR_SCALAR_NONCONST_OP(tname, op, tprefix, type) \ - tprefix \ - inline tname operator op##=(tname &a, type const &val) \ - { \ - return a = a op val; \ - } -#define LOL_UNARY_OPS(tname, tprefix, type) \ - tprefix \ - inline tname operator -(tname const &a) \ - { \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = -a[n]; \ - return ret; \ - } \ - \ - tprefix \ - inline tname operator +(tname const &a) \ - { \ - return a; \ - } +template +static inline T dot(vec const &a, vec const &b) +{ + T ret(0); + for (size_t i = 0; i < N; ++i) + ret += a[i] * b[i]; + return ret; +} -#define LOL_UNARY_FUNS(tname, tprefix, type) \ - tprefix \ - inline type sqlength(tname const &a) \ - { \ - type acc = 0; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - acc += a[n] * a[n]; \ - return acc; \ - } \ - \ - tprefix \ - inline type length(tname const &a) \ - { \ - return (type)sqrt((double)sqlength(a)); \ - } \ - \ - tprefix \ - inline type distance(tname const &a, tname const &b) \ - { \ - return length(a - b); \ - } \ - \ - tprefix \ - inline tname fract(tname const &a) \ - { \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = fract(a[n]); \ - return ret; \ - } \ - \ - tprefix \ - inline tname normalize(tname const &a) \ - { \ - type norm = (type)length(a); \ - return norm ? a / norm : a * (type)0; \ - } \ - \ - tprefix \ - inline tname abs(tname const &a) \ - { \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = lol::abs(a[n]); \ - return ret; \ - } \ - \ - tprefix \ - inline tname degrees(tname const &a) \ - { \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = lol::degrees(a[n]); \ - return ret; \ - } \ - \ - tprefix \ - inline tname radians(tname const &a) \ - { \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = lol::radians(a[n]); \ - return ret; \ - } +template +static inline T sqlength(vec const &a) +{ + return dot(a, a); +} -#define LOL_BINARY_NONVECTOR_FUNS(tname, tprefix, type) \ - tprefix \ - inline type dot(tname const &a, tname const &b) \ - { \ - type ret = 0; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret += a[n] * b[n]; \ - return ret; \ - } \ - \ - tprefix \ - inline tname lerp(tname const &a, \ - tname const &b, type x) \ - { \ - tname ret; \ - for (size_t n = 0; n < sizeof(a) / sizeof(type); n++) \ - ret[n] = a[n] + (b[n] - a[n]) * x; \ - return ret; \ - } +template +static inline T length(vec const &a) +{ + /* FIXME: this is not very nice */ + return (T)sqrt((double)sqlength(a)); +} -#define LOL_VEC_3_FUNS(tname, tprefix, type) \ - /* Return the cross product (vector product) of "a" and "b" */ \ - tprefix \ - inline tname cross(tname const &a, tname const &b) \ - { \ - return tname((type)(a.y * b.z - a.z * b.y), \ - (type)(a.z * b.x - a.x * b.z), \ - (type)(a.x * b.y - a.y * b.x)); \ - } \ - \ - /* Return a vector that is orthogonal to "a" */ \ - tprefix \ - inline tname orthogonal(tname const &a) \ - { \ - return lol::abs(a.x) > lol::abs(a.z) \ - ? tname(-a.y, a.x, (type)0) \ - : tname((type)0, -a.z, a.y); \ - } \ - \ - /* Return a vector that is orthonormal to "a" */ \ - tprefix \ - inline tname orthonormal(tname const &a) \ - { \ - return normalize(orthogonal(a)); \ - } +template +static inline vec lerp(vec const &a, + vec const &b, + T const &s) +{ + vec ret; + for (size_t i = 0; i < N; ++i) + ret[i] = a[i] + s * (b[i] - a[i]); + return ret; +} -#define LOL_BINARY_NONVECTOR_OPS(tname, tprefix, type) \ - LOL_VECTOR_VECTOR_OP(tname, -, tprefix, type) \ - LOL_VECTOR_VECTOR_OP(tname, +, tprefix, type) \ - LOL_VECTOR_SCALAR_OP(tname, *, tprefix, type) \ - LOL_VECTOR_SCALAR_OP(tname, /, tprefix, type) \ - LOL_SCALAR_VECTOR_OP(tname, *, tprefix, type) \ - \ - LOL_VECTOR_VECTOR_NONCONST_OP(tname, -, tprefix, type) \ - LOL_VECTOR_VECTOR_NONCONST_OP(tname, +, tprefix, type) \ - LOL_VECTOR_SCALAR_NONCONST_OP(tname, *, tprefix, type) \ - LOL_VECTOR_SCALAR_NONCONST_OP(tname, /, tprefix, type) \ - \ - LOL_VECTOR_VECTOR_BOOL_OP(tname, ==, ==, true, tprefix, type) \ - LOL_VECTOR_VECTOR_BOOL_OP(tname, !=, ==, false, tprefix, type) - -#define LOL_BINARY_VECTOR_OPS(tname, tprefix, type) \ - LOL_SCALAR_VECTOR_OP(tname, /, tprefix, type) - -#define LOL_BINARY_VECTOR_FUNS(tname, tprefix, type) \ - LOL_VECTOR_MINMAX_FUN(tname, min, tprefix, type) \ - LOL_VECTOR_MINMAX_FUN(tname, max, tprefix, type) \ - LOL_VECTOR_MINMAX_FUN(tname, fmod, tprefix, type) \ - LOL_VECTOR_CLAMP_FUN(tname, tprefix, type) \ - LOL_VECTOR_MIX_FUN(tname, tprefix, type) \ - \ - LOL_VECTOR_VECTOR_BOOL_OP(tname, <=, <=, true, tprefix, type) \ - LOL_VECTOR_VECTOR_BOOL_OP(tname, >=, >=, true, tprefix, type) \ - LOL_VECTOR_VECTOR_BOOL_OP(tname, <, <, true, tprefix, type) \ - LOL_VECTOR_VECTOR_BOOL_OP(tname, >, >, true, tprefix, type) - -#define LOL_VECTOR_OPS(tname, tprefix, type) \ - LOL_VECTOR_VECTOR_OP(tname, *, tprefix, type) \ - LOL_VECTOR_VECTOR_OP(tname, /, tprefix, type) \ - \ - LOL_VECTOR_VECTOR_NONCONST_OP(tname, *, tprefix, type) \ - LOL_VECTOR_VECTOR_NONCONST_OP(tname, /, tprefix, type) - -#define LOL_ALL_NONVECTOR_OPS_AND_FUNS(tname) \ - LOL_BINARY_NONVECTOR_OPS(tname, template static, T) \ - LOL_BINARY_NONVECTOR_FUNS(tname, template static, T) \ - LOL_UNARY_OPS(tname, template static, T) \ - LOL_UNARY_FUNS(tname, template static, T) - -#define LOL_ALL_VECTOR_OPS_INNER(tname, type) \ - LOL_BINARY_VECTOR_OPS(tname, static, type) \ - LOL_BINARY_NONVECTOR_OPS(tname, static, type) \ - LOL_UNARY_OPS(tname, static, type) \ - LOL_VECTOR_OPS(tname, static, type) - -#define LOL_ALL_VECTOR_FUNS_INNER(tname, type) \ - LOL_BINARY_VECTOR_FUNS(tname, static, type) \ - LOL_BINARY_NONVECTOR_FUNS(tname, static, type) \ - LOL_UNARY_FUNS(tname, static, type) - -/* HACK: This trick fails with Apple’s clang++, which sometimes fails to deduce - * the arguments for simple stuff such as vec3 + vec3. Disable it for now. - * Note that llvm-g++ doesn’t have the problem. */ -#if defined __clang__ -# define LOL_OPEN_NAMESPACE(x) -# define LOL_CLOSE_NAMESPACE(x) -#else -# define LOL_OPEN_NAMESPACE(x) namespace x { -# define LOL_CLOSE_NAMESPACE(x) } using namespace x; -#endif +template +static inline T distance(vec const &a, vec const &b) +{ + return length(a - b); +} -#define LOL_ALL_VECTOR_OPS_AND_FUNS(type) \ - LOL_OPEN_NAMESPACE(x##type) \ - LOL_ALL_VECTOR_OPS_INNER(Vec2, type) \ - LOL_ALL_VECTOR_OPS_INNER(Vec3, type) \ - LOL_ALL_VECTOR_OPS_INNER(Vec4, type) \ - LOL_CLOSE_NAMESPACE(x##type) \ - LOL_ALL_VECTOR_FUNS_INNER(Vec2, type) \ - LOL_ALL_VECTOR_FUNS_INNER(Vec3, type) \ - LOL_ALL_VECTOR_FUNS_INNER(Vec4, type) \ - LOL_VEC_3_FUNS(Vec3, static, type) - -LOL_ALL_NONVECTOR_OPS_AND_FUNS(Cmplx) -LOL_ALL_NONVECTOR_OPS_AND_FUNS(Quat) - -/* Disable warning about unary operator applied to unsigned type */ -#if defined _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4146) -#endif +template +static inline vec fract(vec const &a) +{ + vec ret; + for (size_t i = 0; i < N; ++i) + ret[i] = fract(a[i]); + return ret; +} -LOL_ALL_VECTOR_OPS_AND_FUNS(half) -LOL_ALL_VECTOR_OPS_AND_FUNS(float) -LOL_ALL_VECTOR_OPS_AND_FUNS(double) -LOL_ALL_VECTOR_OPS_AND_FUNS(ldouble) -LOL_ALL_VECTOR_OPS_AND_FUNS(real) - -LOL_ALL_VECTOR_OPS_AND_FUNS(int8_t) -LOL_ALL_VECTOR_OPS_AND_FUNS(uint8_t) -LOL_ALL_VECTOR_OPS_AND_FUNS(int16_t) -LOL_ALL_VECTOR_OPS_AND_FUNS(uint16_t) -LOL_ALL_VECTOR_OPS_AND_FUNS(int32_t) -LOL_ALL_VECTOR_OPS_AND_FUNS(uint32_t) -LOL_ALL_VECTOR_OPS_AND_FUNS(int64_t) -LOL_ALL_VECTOR_OPS_AND_FUNS(uint64_t) - -#if defined _MSC_VER -# pragma warning(pop) -#endif +template +static inline vec normalize(vec const &a) +{ + T norm = (T)length(a); + return norm ? a / norm : vec(T(0)); +} + +template +static inline vec abs(vec const &a) +{ + vec ret; + for (size_t i = 0; i < N; ++i) + ret[i] = lol::abs(a[i]); + return ret; +} -#undef LOL_MEMBER_OPS - -#undef LOL_VECTOR_VECTOR_OP -#undef LOL_VECTOR_VECTOR_NONCONST_OP -#undef LOL_VECTOR_MINMAX_FUN -#undef LOL_VECTOR_CLAMP_FUN -#undef LOL_VECTOR_MIX_FUN -#undef LOL_VECTOR_VECTOR_BOOL_OP -#undef LOL_VECTOR_SCALAR_OP -#undef LOL_SCALAR_VECTOR_OP -#undef LOL_VECTOR_SCALAR_OP - -#undef LOL_BINARY_VECTOR_OPS -#undef LOL_BINARY_VECTOR_FUNS -#undef LOL_BINARY_NONVECTOR_OPS -#undef LOL_BINARY_NONVECTOR_FUNS -#undef LOL_UNARY_OPS -#undef LOL_UNARY_FUNS -#undef LOL_VEC_3_FUNS -#undef LOL_VECTOR_OPS - -#undef LOL_ALL_NONVECTOR_OPS_AND_FUNS -#undef LOL_ALL_VECTOR_OPS_INNER -#undef LOL_ALL_VECTOR_FUNS_INNER -#undef LOL_ALL_VECTOR_OPS_AND_FUNS - -#undef LOL_OPEN_NAMESPACE -#undef LOL_CLOSE_NAMESPACE +template +static inline vec degrees(vec const &a) +{ + vec ret; + for (size_t i = 0; i < N; ++i) + ret[i] = lol::degrees(a[i]); + return ret; +} + +template +static inline vec radians(vec const &a) +{ + vec ret; + for (size_t i = 0; i < N; ++i) + ret[i] = lol::radians(a[i]); + return ret; +} /* * Definition of additional functions requiring vector functions @@ -1568,9 +1566,9 @@ template inline Quat Quat::operator *(Quat const &val) const { Quat ret; - Vec3 v1(x, y, z); - Vec3 v2(val.x, val.y, val.z); - Vec3 v3 = cross(v1, v2) + w * v2 + val.w * v1; + vec<3,T> v1(x, y, z); + vec<3,T> v2(val.x, val.y, val.z); + vec<3,T> v3 = cross(v1, v2) + w * v2 + val.w * v1; return Quat(w * val.w - dot(v1, v2), v3.x, v3.y, v3.z); } @@ -1578,54 +1576,43 @@ inline Quat Quat::operator *(Quat const &val) const * Magic vector swizzling (part 2/2) */ -template -inline XVec2& XVec2::operator =(Vec2 that) -{ - for (int i = 0; i < 2; i++) - (*this)[i] = that[i]; - return *this; -} - -template -inline XVec3& XVec3::operator =(Vec3 that) -{ - for (int i = 0; i < 3; i++) - (*this)[i] = that[i]; - return *this; -} - -template -inline XVec4& XVec4::operator =(Vec4 that) +#if LOL_FEATURE_CXX11_RELAXED_UNIONS +template +inline vec& vec::operator =(vec that) { - for (int i = 0; i < 4; i++) + for (int i = 0; i < N; ++i) (*this)[i] = that[i]; return *this; } +#endif /* * 2×2-element matrices */ -template struct Mat2 +template +struct matrix<2, 2, T> { - inline Mat2() {} - inline Mat2(Vec2 V0, Vec2 V1) + typedef matrix<2,2,T> type; + + inline matrix() {} + inline matrix(vec<2,T> V0, vec<2,T> V1) : v0(V0), v1(V1) {} - explicit inline Mat2(T val) + explicit inline matrix(T val) : v0(val, (T)0), v1((T)0, val) {} - explicit inline Mat2(Mat4 const &mat) + explicit inline matrix(matrix<4,4,T> const &mat) : v0(mat[0].xy), v1(mat[1].xy) {} - inline Vec2& operator[](size_t n) { return (&v0)[n]; } - inline Vec2 const& operator[](size_t n) const { return (&v0)[n]; } + inline vec<2,T>& operator[](size_t n) { return (&v0)[n]; } + inline vec<2,T> const& operator[](size_t n) const { return (&v0)[n]; } /* Helpers for transformation matrices */ - static Mat2 rotate(T degrees); - static inline Mat2 rotate(Mat2 mat, T degrees) + static matrix<2,2,T> rotate(T degrees); + static inline matrix<2,2,T> rotate(matrix<2,2,T> mat, T degrees) { return rotate(degrees) * mat; } @@ -1634,41 +1621,42 @@ template struct Mat2 String tostring() const; template - friend std::ostream &operator<<(std::ostream &stream, Mat2 const &m); + friend std::ostream &operator<<(std::ostream &stream, + matrix<2,2,U> const &m); - inline Mat2 operator +(Mat2 const m) const + inline matrix<2,2,T> operator +(matrix<2,2,T> const m) const { - return Mat2(v0 + m[0], v1 + m[1]); + return matrix<2,2,T>(v0 + m[0], v1 + m[1]); } - inline Mat2 operator +=(Mat2 const m) + inline matrix<2,2,T> operator +=(matrix<2,2,T> const m) { return *this = *this + m; } - inline Mat2 operator -(Mat2 const m) const + inline matrix<2,2,T> operator -(matrix<2,2,T> const m) const { - return Mat2(v0 - m[0], v1 - m[1]); + return matrix<2,2,T>(v0 - m[0], v1 - m[1]); } - inline Mat2 operator -=(Mat2 const m) + inline matrix<2,2,T> operator -=(matrix<2,2,T> const m) { return *this = *this - m; } - inline Mat2 operator *(Mat2 const m) const + inline matrix<2,2,T> operator *(matrix<2,2,T> const m) const { - return Mat2(*this * m[0], *this * m[1]); + return matrix<2,2,T>(*this * m[0], *this * m[1]); } - inline Mat2 operator *=(Mat2 const m) + inline matrix<2,2,T> operator *=(matrix<2,2,T> const m) { return *this = *this * m; } - inline Vec2 operator *(Vec2 const m) const + inline vec<2,T> operator *(vec<2,T> const m) const { - Vec2 ret; + vec<2,T> ret; for (int j = 0; j < 2; j++) { T tmp = 0; @@ -1679,80 +1667,83 @@ template struct Mat2 return ret; } - Vec2 v0, v1; + vec<2,T> v0, v1; - static const Mat2 identity; + static const matrix<2,2,T> identity; }; /* * 3×3-element matrices */ -template struct Mat3 +template +struct matrix<3,3,T> { - inline Mat3() {} - inline Mat3(Vec3 V0, Vec3 V1, Vec3 V2) + typedef matrix<3,3,T> type; + + inline matrix() {} + inline matrix(vec<3,T> V0, vec<3,T> V1, vec<3,T> V2) : v0(V0), v1(V1), v2(V2) {} - explicit inline Mat3(T val) + explicit inline matrix(T val) : v0(val, (T)0, (T)0), v1((T)0, val, (T)0), v2((T)0, (T)0, val) {} - explicit inline Mat3(Mat2 mat) + explicit inline matrix(matrix<2,2,T> mat) : v0(mat[0], (T)0), v1(mat[1], (T)0), v2((T)0, (T)0, (T)0) {} - explicit inline Mat3(Mat2 mat, T val) - : v0(Vec3(mat[0], (T)0)), - v1(Vec3(mat[1], (T)0)), + explicit inline matrix(matrix<2,2,T> mat, T val) + : v0(vec<3,T>(mat[0], (T)0)), + v1(vec<3,T>(mat[1], (T)0)), v2((T)0, (T)0, val) {} - explicit inline Mat3(Mat4 const &mat) + explicit inline matrix(matrix<4,4,T> const &mat) : v0(mat[0].xyz), v1(mat[1].xyz), v2(mat[2].xyz) {} - explicit Mat3(Quat const &q); + explicit matrix(Quat const &q); - inline Vec3& operator[](size_t n) { return (&v0)[n]; } - inline Vec3 const& operator[](size_t n) const { return (&v0)[n]; } + inline vec<3,T>& operator[](size_t n) { return (&v0)[n]; } + inline vec<3,T> const& operator[](size_t n) const { return (&v0)[n]; } /* Helpers for transformation matrices */ - static Mat3 scale(T x); - static Mat3 scale(T x, T y, T z); - static Mat3 scale(Vec3 v); - static Mat3 rotate(T degrees, T x, T y, T z); - static Mat3 rotate(T degrees, Vec3 v); - - static Mat3 fromeuler_xyz(Vec3 const &v); - static Mat3 fromeuler_xzy(Vec3 const &v); - static Mat3 fromeuler_yxz(Vec3 const &v); - static Mat3 fromeuler_yzx(Vec3 const &v); - static Mat3 fromeuler_zxy(Vec3 const &v); - static Mat3 fromeuler_zyx(Vec3 const &v); - static Mat3 fromeuler_xyz(T phi, T theta, T psi); - static Mat3 fromeuler_xzy(T phi, T theta, T psi); - static Mat3 fromeuler_yxz(T phi, T theta, T psi); - static Mat3 fromeuler_yzx(T phi, T theta, T psi); - static Mat3 fromeuler_zxy(T phi, T theta, T psi); - static Mat3 fromeuler_zyx(T phi, T theta, T psi); - - static Mat3 fromeuler_xyx(Vec3 const &v); - static Mat3 fromeuler_xzx(Vec3 const &v); - static Mat3 fromeuler_yxy(Vec3 const &v); - static Mat3 fromeuler_yzy(Vec3 const &v); - static Mat3 fromeuler_zxz(Vec3 const &v); - static Mat3 fromeuler_zyz(Vec3 const &v); - static Mat3 fromeuler_xyx(T phi, T theta, T psi); - static Mat3 fromeuler_xzx(T phi, T theta, T psi); - static Mat3 fromeuler_yxy(T phi, T theta, T psi); - static Mat3 fromeuler_yzy(T phi, T theta, T psi); - static Mat3 fromeuler_zxz(T phi, T theta, T psi); - static Mat3 fromeuler_zyz(T phi, T theta, T psi); - - static inline Mat3 rotate(Mat3 mat, T degrees, Vec3 v) + static matrix<3,3,T> scale(T x); + static matrix<3,3,T> scale(T x, T y, T z); + static matrix<3,3,T> scale(vec<3,T> v); + static matrix<3,3,T> rotate(T degrees, T x, T y, T z); + static matrix<3,3,T> rotate(T degrees, vec<3,T> v); + + static matrix<3,3,T> fromeuler_xyz(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_xzy(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_yxz(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_yzx(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_zxy(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_zyx(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_xyz(T phi, T theta, T psi); + static matrix<3,3,T> fromeuler_xzy(T phi, T theta, T psi); + static matrix<3,3,T> fromeuler_yxz(T phi, T theta, T psi); + static matrix<3,3,T> fromeuler_yzx(T phi, T theta, T psi); + static matrix<3,3,T> fromeuler_zxy(T phi, T theta, T psi); + static matrix<3,3,T> fromeuler_zyx(T phi, T theta, T psi); + + static matrix<3,3,T> fromeuler_xyx(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_xzx(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_yxy(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_yzy(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_zxz(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_zyz(vec<3,T> const &v); + static matrix<3,3,T> fromeuler_xyx(T phi, T theta, T psi); + static matrix<3,3,T> fromeuler_xzx(T phi, T theta, T psi); + static matrix<3,3,T> fromeuler_yxy(T phi, T theta, T psi); + static matrix<3,3,T> fromeuler_yzy(T phi, T theta, T psi); + static matrix<3,3,T> fromeuler_zxz(T phi, T theta, T psi); + static matrix<3,3,T> fromeuler_zyz(T phi, T theta, T psi); + + static inline matrix<3,3,T> rotate(matrix<3,3,T> mat, T degrees, vec<3,T> v) { return rotate(degrees, v) * mat; } @@ -1761,41 +1752,42 @@ template struct Mat3 String tostring() const; template - friend std::ostream &operator<<(std::ostream &stream, Mat3 const &m); + friend std::ostream &operator<<(std::ostream &stream, + matrix<3,3,U> const &m); - inline Mat3 operator +(Mat3 const m) const + inline matrix<3,3,T> operator +(matrix<3,3,T> const m) const { - return Mat3(v0 + m[0], v1 + m[1], v2 + m[2]); + return matrix<3,3,T>(v0 + m[0], v1 + m[1], v2 + m[2]); } - inline Mat3 operator +=(Mat3 const m) + inline matrix<3,3,T> operator +=(matrix<3,3,T> const m) { return *this = *this + m; } - inline Mat3 operator -(Mat3 const m) const + inline matrix<3,3,T> operator -(matrix<3,3,T> const m) const { - return Mat3(v0 - m[0], v1 - m[1], v2 - m[2]); + return matrix<3,3,T>(v0 - m[0], v1 - m[1], v2 - m[2]); } - inline Mat3 operator -=(Mat3 const m) + inline matrix<3,3,T> operator -=(matrix<3,3,T> const m) { return *this = *this - m; } - inline Mat3 operator *(Mat3 const m) const + inline matrix<3,3,T> operator *(matrix<3,3,T> const m) const { - return Mat3(*this * m[0], *this * m[1], *this * m[2]); + return matrix<3,3,T>(*this * m[0], *this * m[1], *this * m[2]); } - inline Mat3 operator *=(Mat3 const m) + inline matrix<3,3,T> operator *=(matrix<3,3,T> const m) { return *this = *this * m; } - inline Vec3 operator *(Vec3 const m) const + inline vec<3,T> operator *(vec<3,T> const m) const { - Vec3 ret; + vec<3,T> ret; for (int j = 0; j < 3; j++) { T tmp = 0; @@ -1806,170 +1798,174 @@ template struct Mat3 return ret; } - Vec3 v0, v1, v2; + vec<3,T> v0, v1, v2; - static const Mat3 identity; + static const matrix<3,3,T> identity; }; /* * 4×4-element matrices */ -template struct Mat4 +template +struct matrix<4, 4, T> { - inline Mat4() {} - inline Mat4(Vec4 V0, Vec4 V1, Vec4 V2, Vec4 V3) + typedef matrix<4,4,T> type; + + inline matrix() {} + inline matrix(vec<4,T> V0, vec<4,T> V1, vec<4,T> V2, vec<4,T> V3) : v0(V0), v1(V1), v2(V2), v3(V3) {} - explicit inline Mat4(T val) + explicit inline matrix(T val) : v0(val, (T)0, (T)0, (T)0), v1((T)0, val, (T)0, (T)0), v2((T)0, (T)0, val, (T)0), v3((T)0, (T)0, (T)0, val) {} - explicit inline Mat4(Mat2 mat) + explicit inline matrix(matrix<2,2,T> mat) : v0(mat[0], (T)0, (T)0), v1(mat[1], (T)0, (T)0), v2((T)0, (T)0, (T)0, (T)0), v3((T)0, (T)0, (T)0, (T)0) {} - explicit inline Mat4(Mat2 mat, T val1, T val2) + explicit inline matrix(matrix<2,2,T> mat, T val1, T val2) : v0(mat[0], (T)0, (T)0), v1(mat[1], (T)0, (T)0), v2((T)0, (T)0, val1, (T)0), v3((T)0, (T)0, (T)0, val2) {} - explicit inline Mat4(Mat3 mat) + explicit inline matrix(matrix<3,3,T> mat) : v0(mat[0], (T)0), v1(mat[1], (T)0), v2(mat[2], (T)0), v3((T)0, (T)0, (T)0, (T)0) {} - explicit inline Mat4(Mat3 mat, T val) + explicit inline matrix(matrix<3,3,T> mat, T val) : v0(mat[0], (T)0), v1(mat[1], (T)0), v2(mat[2], (T)0), v3((T)0, (T)0, (T)0, val) {} - explicit Mat4(Quat const &q); + explicit matrix(Quat const &q); - inline Vec4& operator[](size_t n) { return (&v0)[n]; } - inline Vec4 const& operator[](size_t n) const { return (&v0)[n]; } + inline vec<4,T>& operator[](size_t n) { return (&v0)[n]; } + inline vec<4,T> const& operator[](size_t n) const { return (&v0)[n]; } /* Helpers for transformation matrices */ - static Mat4 translate(T x, T y, T z); - static Mat4 translate(Vec3 v); + static matrix<4,4,T> translate(T x, T y, T z); + static matrix<4,4,T> translate(vec<3,T> v); - static inline Mat4 scale(T x) + static inline matrix<4,4,T> scale(T x) { - return Mat4(Mat3::scale(x), (T)1); + return matrix<4,4,T>(matrix<3,3,T>::scale(x), (T)1); } - static inline Mat4 scale(T x, T y, T z) + static inline matrix<4,4,T> scale(T x, T y, T z) { - return Mat4(Mat3::scale(x, y, z), (T)1); + return matrix<4,4,T>(matrix<3,3,T>::scale(x, y, z), (T)1); } - static inline Mat4 scale(Vec3 v) + static inline matrix<4,4,T> scale(vec<3,T> v) { - return Mat4(Mat3::scale(v), (T)1); + return matrix<4,4,T>(matrix<3,3,T>::scale(v), (T)1); } - static inline Mat4 translate(Mat4 const &mat, Vec3 v) + static inline matrix<4,4,T> translate(matrix<4,4,T> const &mat, vec<3,T> v) { return translate(v) * mat; } - static inline Mat4 rotate(T degrees, T x, T y, T z) + static inline matrix<4,4,T> rotate(T degrees, T x, T y, T z) { - return Mat4(Mat3::rotate(degrees, x, y, z), (T)1); + return matrix<4,4,T>(matrix<3,3,T>::rotate(degrees, x, y, z), (T)1); } - static inline Mat4 rotate(T degrees, Vec3 v) + static inline matrix<4,4,T> rotate(T degrees, vec<3,T> v) { - return Mat4(Mat3::rotate(degrees, v), (T)1); + return matrix<4,4,T>(matrix<3,3,T>::rotate(degrees, v), (T)1); } - static inline Mat4 rotate(Mat4 &mat, T degrees, Vec3 v) + static inline matrix<4,4,T> rotate(matrix<4,4,T> &mat, T degrees, vec<3,T> v) { return rotate(degrees, v) * mat; } - static Mat4 fromeuler_xyz(Vec3 const &v); - static Mat4 fromeuler_xzy(Vec3 const &v); - static Mat4 fromeuler_yxz(Vec3 const &v); - static Mat4 fromeuler_yzx(Vec3 const &v); - static Mat4 fromeuler_zxy(Vec3 const &v); - static Mat4 fromeuler_zyx(Vec3 const &v); - static Mat4 fromeuler_xyz(T phi, T theta, T psi); - static Mat4 fromeuler_xzy(T phi, T theta, T psi); - static Mat4 fromeuler_yxz(T phi, T theta, T psi); - static Mat4 fromeuler_yzx(T phi, T theta, T psi); - static Mat4 fromeuler_zxy(T phi, T theta, T psi); - static Mat4 fromeuler_zyx(T phi, T theta, T psi); - - static Mat4 fromeuler_xyx(Vec3 const &v); - static Mat4 fromeuler_xzx(Vec3 const &v); - static Mat4 fromeuler_yxy(Vec3 const &v); - static Mat4 fromeuler_yzy(Vec3 const &v); - static Mat4 fromeuler_zxz(Vec3 const &v); - static Mat4 fromeuler_zyz(Vec3 const &v); - static Mat4 fromeuler_xyx(T phi, T theta, T psi); - static Mat4 fromeuler_xzx(T phi, T theta, T psi); - static Mat4 fromeuler_yxy(T phi, T theta, T psi); - static Mat4 fromeuler_yzy(T phi, T theta, T psi); - static Mat4 fromeuler_zxz(T phi, T theta, T psi); - static Mat4 fromeuler_zyz(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_xyz(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_xzy(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_yxz(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_yzx(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_zxy(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_zyx(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_xyz(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_xzy(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_yxz(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_yzx(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_zxy(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_zyx(T phi, T theta, T psi); + + static matrix<4,4,T> fromeuler_xyx(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_xzx(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_yxy(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_yzy(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_zxz(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_zyz(vec<3,T> const &v); + static matrix<4,4,T> fromeuler_xyx(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_xzx(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_yxy(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_yzy(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_zxz(T phi, T theta, T psi); + static matrix<4,4,T> fromeuler_zyz(T phi, T theta, T psi); /* Helpers for view matrices */ - static Mat4 lookat(Vec3 eye, Vec3 center, Vec3 up); + static matrix<4,4,T> lookat(vec<3,T> eye, vec<3,T> center, vec<3,T> up); /* Helpers for projection matrices */ - static Mat4 ortho(T left, T right, T bottom, T top, T near, T far); - static Mat4 ortho(T width, T height, T near, T far); - static Mat4 frustum(T left, T right, T bottom, T top, T near, T far); - static Mat4 perspective(T fov_y, T width, T height, T near, T far); - static Mat4 shifted_perspective(T fov_y, T screen_size, T screen_ratio_yx, T near, T far); + static matrix<4,4,T> ortho(T left, T right, T bottom, T top, T near, T far); + static matrix<4,4,T> ortho(T width, T height, T near, T far); + static matrix<4,4,T> frustum(T left, T right, T bottom, T top, T near, T far); + static matrix<4,4,T> perspective(T fov_y, T width, T height, T near, T far); + static matrix<4,4,T> shifted_perspective(T fov_y, T screen_size, T screen_ratio_yx, T near, T far); void printf() const; String tostring() const; template - friend std::ostream &operator<<(std::ostream &stream, Mat4 const &m); + friend std::ostream &operator<<(std::ostream &stream, + matrix<4,4,U> const &m); - inline Mat4 operator +(Mat4 const &m) const + inline matrix<4,4,T> operator +(matrix<4,4,T> const &m) const { - return Mat4(v0 + m[0], v1 + m[1], v2 + m[2], v3 + m[3]); + return matrix<4,4,T>(v0 + m[0], v1 + m[1], v2 + m[2], v3 + m[3]); } - inline Mat4 operator +=(Mat4 const &m) + inline matrix<4,4,T> operator +=(matrix<4,4,T> const &m) { return *this = *this + m; } - inline Mat4 operator -(Mat4 const &m) const + inline matrix<4,4,T> operator -(matrix<4,4,T> const &m) const { - return Mat4(v0 - m[0], v1 - m[1], v2 - m[2], v3 - m[3]); + return matrix<4,4,T>(v0 - m[0], v1 - m[1], v2 - m[2], v3 - m[3]); } - inline Mat4 operator -=(Mat4 const &m) + inline matrix<4,4,T> operator -=(matrix<4,4,T> const &m) { return *this = *this - m; } - inline Mat4 operator *(Mat4 const &m) const + inline matrix<4,4,T> operator *(matrix<4,4,T> const &m) const { - return Mat4(*this * m[0], *this * m[1], *this * m[2], *this * m[3]); + return matrix<4,4,T>(*this * m[0], *this * m[1], *this * m[2], *this * m[3]); } - inline Mat4 operator *=(Mat4 const &m) + inline matrix<4,4,T> operator *=(matrix<4,4,T> const &m) { return *this = *this * m; } - inline Vec4 operator *(Vec4 const &m) const + inline vec<4,T> operator *(vec<4,T> const &m) const { - Vec4 ret; + vec<4,T> ret; for (int j = 0; j < 4; j++) { T tmp = 0; @@ -1980,22 +1976,26 @@ template struct Mat4 return ret; } - Vec4 v0, v1, v2, v3; + vec<4,T> v0, v1, v2, v3; - static const Mat4 identity; + static const matrix<4,4,T> identity; }; -template T determinant(Mat2 const &); -template T determinant(Mat3 const &); -template T determinant(Mat4 const &); +template T determinant(matrix<2,2,T> const &); +template T determinant(matrix<3,3,T> const &); +template T determinant(matrix<4,4,T> const &); -template Mat2 transpose(Mat2 const &); -template Mat3 transpose(Mat3 const &); -template Mat4 transpose(Mat4 const &); +template matrix<2,2,T> transpose(matrix<2,2,T> const &); +template matrix<3,3,T> transpose(matrix<3,3,T> const &); +template matrix<4,4,T> transpose(matrix<4,4,T> const &); -template Mat2 inverse(Mat2 const &); -template Mat3 inverse(Mat3 const &); -template Mat4 inverse(Mat4 const &); +template matrix<2,2,T> inverse(matrix<2,2,T> const &); +template matrix<3,3,T> inverse(matrix<3,3,T> const &); +template matrix<4,4,T> inverse(matrix<4,4,T> const &); + +#if !LOL_FEATURE_CXX11_CONSTEXPR +#undef constexpr +#endif } /* namespace lol */ diff --git a/src/math/constants.cpp b/src/math/constants.cpp index de130023..47caebeb 100644 --- a/src/math/constants.cpp +++ b/src/math/constants.cpp @@ -18,25 +18,25 @@ namespace lol { #define LOL_VEC_2_CONST(type, name, a, b) \ template<> \ - Vec2 const Vec2::name = Vec2((type)a, (type)b); + vec<2,type> const vec<2,type>::name = vec<2,type>((type)a, (type)b); #define LOL_VEC_3_CONST(type, name, a, b, c) \ template<> \ - Vec3 const Vec3::name = Vec3((type)a, (type)b, (type)c); + vec<3,type> const vec<3,type>::name = vec<3,type>((type)a, (type)b, (type)c); #define LOL_VEC_4_CONST(type, name, a, b, c, d) \ template<> \ - Vec4 const Vec4::name = Vec4((type)a, (type)b, (type)c, (type)d); + vec<4,type> const vec<4,type>::name = vec<4,type>((type)a, (type)b, (type)c, (type)d); #define LOL_MAT_CONST(type, name, a) \ template<> \ - Mat2 const Mat2::name = Mat2((type)a); \ + matrix<2,2,type> const matrix<2,2,type>::name = matrix<2,2,type>((type)a); \ \ template<> \ - Mat3 const Mat3::name = Mat3((type)a); \ + matrix<3,3,type> const matrix<3,3,type>::name = matrix<3,3,type>((type)a); \ \ template<> \ - Mat4 const Mat4::name = Mat4((type)a); + matrix<4,4,type> const matrix<4,4,type>::name = matrix<4,4,type>((type)a); #define LOL_ALL_CONST_INNER(type) \ LOL_VEC_2_CONST(type, zero, 0, 0) \ diff --git a/src/math/vector.cpp b/src/math/vector.cpp index c73e55f9..8844438c 100644 --- a/src/math/vector.cpp +++ b/src/math/vector.cpp @@ -407,7 +407,7 @@ template<> mat3 mat3::rotate(float degrees, vec3 v) return rotate(degrees, v.x, v.y, v.z); } -template<> mat3::Mat3(quat const &q) +template<> mat3::matrix(quat const &q) { float n = norm(q); @@ -434,7 +434,7 @@ template<> mat3::Mat3(quat const &q) v2[2] = 1.0f - s * (q.x * q.x + q.y * q.y); } -template<> mat4::Mat4(quat const &q) +template<> mat4::matrix(quat const &q) { *this = mat4(mat3(q), 1.f); } diff --git a/test/meshviewer.cpp b/test/meshviewer.cpp index f428ba2f..fc3cb104 100644 --- a/test/meshviewer.cpp +++ b/test/meshviewer.cpp @@ -19,7 +19,6 @@ #include #include "scenesetup.h" -using namespace std; using namespace lol; static int const TEXTURE_WIDTH = 256; diff --git a/test/unit/cmplx.cpp b/test/unit/cmplx.cpp index ddadf9df..7805bfa2 100644 --- a/test/unit/cmplx.cpp +++ b/test/unit/cmplx.cpp @@ -61,17 +61,17 @@ LOLUNIT_FIXTURE(ComplexTest) { cmplx a(3.0f, -4.0f); - LOLUNIT_ASSERT_EQUAL(a.norm(), 5.0f); + LOLUNIT_ASSERT_EQUAL(norm(a), 5.0f); cmplx b = a * ~a; - cmplx c = a.norm() * a.norm(); + cmplx c = norm(a) * norm(a); LOLUNIT_ASSERT_EQUAL(b, c); cmplx d(5.0f, 12.0f); - LOLUNIT_ASSERT_EQUAL(d.norm(), 13.0f); - LOLUNIT_ASSERT_EQUAL((a * d).norm(), a.norm() * d.norm()); + LOLUNIT_ASSERT_EQUAL(norm(d), 13.0f); + LOLUNIT_ASSERT_EQUAL(norm(a * d), norm(a) * norm(d)); } LOLUNIT_TEST(Base) @@ -79,8 +79,8 @@ LOLUNIT_FIXTURE(ComplexTest) cmplx one(1.0f, 0.0f); cmplx i(0.0f, 1.0f); - LOLUNIT_ASSERT_EQUAL(one.norm(), 1.0f); - LOLUNIT_ASSERT_EQUAL(i.norm(), 1.0f); + LOLUNIT_ASSERT_EQUAL(norm(one), 1.0f); + LOLUNIT_ASSERT_EQUAL(norm(i), 1.0f); LOLUNIT_ASSERT_EQUAL(i * i, -one); } @@ -90,7 +90,7 @@ LOLUNIT_FIXTURE(ComplexTest) cmplx a(3.0f, -4.0f); cmplx 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)