diff --git a/math/mat2x2.hpp b/math/mat2x2.hpp new file mode 100644 index 0000000..008ca2b --- /dev/null +++ b/math/mat2x2.hpp @@ -0,0 +1,105 @@ +#pragma once + +#include +#include "vec2.hpp" + +template +struct mat; + +// +// mat4x4 +// + +template +struct mat<2, 2, T> +{ + typedef vec<2, T> row_type; + typedef vec<2, T> col_type; + +private: + row_type value[2]; + +public: + inline constexpr mat(); + + inline constexpr mat + ( + T const& a00, T const& a01, + T const& a10, T const& a11 + ); + + inline static constexpr int length() { return 4; } + + inline constexpr typename mat<2, 2, T>::row_type const & + operator[](int i) const; + + void operator=(const mat<2, 2, T>&) = delete; + +}; + + +template +inline constexpr mat<2, 2, T>::mat() + : value{std::move(row_type(1, 0)), + std::move(row_type(0, 1))} +{ } + +template +inline constexpr mat<2, 2, T>::mat +( + T const& a00, T const& a01, + T const& a10, T const& a11 +) + : value{std::move(row_type(a00, a01)), + std::move(row_type(a10, a11))} +{ } + +template +inline constexpr typename mat<2, 2, T>::row_type const & +mat<2, 2, T>::operator[](int i) const +{ + switch (i) + { + default: [[fallthrough]]; + case 0: + return value[0]; + case 1: + return value[1]; + } +} + +template +inline constexpr mat<2, 2, T> operator*(mat<2, 2, T> const& m1, mat<2, 2, T> const& m2) +{ +#define c(i, j) ( \ + m1[i][0] * m2[0][j] \ + + m1[i][1] * m2[1][j]) + + return mat<2, 2, T>(c(0,0), c(0,1), + c(1,0), c(1,1)); +#undef c +} + +template +inline constexpr typename mat<2, 2, T>::row_type operator* +( + mat<2, 2, T> const& m, + typename mat<2, 2, T>::col_type const& v +) +{ +#define c(i) ( \ + m[i][0] * v[0] \ + + m[i][1] * v[1]) + + return typename mat<2, 2, T>::row_type(c(0), c(1)); +#undef c +} + +template +inline constexpr mat<2, 2, T> transpose(mat<2, 2, T> const& m) +{ + return mat<2, 2, T>( + m[0][0], m[1][0], + m[0][1], m[1][1] + ); +} diff --git a/math/mat3x3.hpp b/math/mat3x3.hpp index 5442125..438d4e4 100644 --- a/math/mat3x3.hpp +++ b/math/mat3x3.hpp @@ -74,6 +74,17 @@ mat<3, 3, T>::operator[](int i) const } } +template +inline constexpr mat<3, 3, T> operator+(mat<3, 3, T> const& m1, mat<3, 3, T> const& m2) +{ +#define c(i, j) ( m1[i][j] + m2[i][j] ) + + return mat<3, 3, T>(c(0,0), c(0,1), c(0,2), + c(1,0), c(1,1), c(1,2), + c(2,0), c(2,1), c(2,2)); +#undef c +} + template inline constexpr mat<3, 3, T> operator*(mat<3, 3, T> const& m1, mat<3, 3, T> const& m2) { @@ -88,6 +99,17 @@ inline constexpr mat<3, 3, T> operator*(mat<3, 3, T> const& m1, mat<3, 3, T> con #undef c } +template +inline constexpr mat<3, 3, T> operator*(mat<3, 3, T> const& m1, float s) +{ +#define c(i, j) ( m1[i][j] * s ) + + return mat<3, 3, T>(c(0,0), c(0,1), c(0,2), + c(1,0), c(1,1), c(1,2), + c(2,0), c(2,1), c(2,2)); +#undef c +} + template inline constexpr typename mat<3, 3, T>::row_type operator* ( diff --git a/math/mat4x4.hpp b/math/mat4x4.hpp index ca8a989..d65c2c2 100644 --- a/math/mat4x4.hpp +++ b/math/mat4x4.hpp @@ -35,7 +35,7 @@ public: inline constexpr typename mat<4, 4, T>::row_type const & operator[](int i) const; - void operator=(const mat<4, 4, T>&) = delete; + //void operator=(const mat<4, 4, T>&) = delete; }; @@ -80,6 +80,18 @@ mat<4, 4, T>::operator[](int i) const } } +template +inline constexpr mat<4, 4, T> operator+(mat<4, 4, T> const& m1, mat<4, 4, T> const& m2) +{ +#define c(i, j) ( m1[i][j] + m2[i][j] ) + + return mat<4, 4, T>(c(0,0), c(0,1), c(0,2), c(0,3), + c(1,0), c(1,1), c(1,2), c(1,3), + c(2,0), c(2,1), c(2,2), c(2,3), + c(3,0), c(3,1), c(3,2), c(3,3)); +#undef c +} + template inline constexpr mat<4, 4, T> operator*(mat<4, 4, T> const& m1, mat<4, 4, T> const& m2) { @@ -96,6 +108,18 @@ inline constexpr mat<4, 4, T> operator*(mat<4, 4, T> const& m1, mat<4, 4, T> con #undef c } +template +inline constexpr mat<4, 4, T> operator*(mat<4, 4, T> const& m1, float s) +{ +#define c(i, j) ( m1[i][j] * s ) + + return mat<4, 4, T>(c(0,0), c(0,1), c(0,2), c(0,3), + c(1,0), c(1,1), c(1,2), c(1,3), + c(2,0), c(2,1), c(2,2), c(2,3), + c(3,0), c(3,1), c(3,2), c(3,3)); +#undef c +} + template inline constexpr typename mat<4, 4, T>::row_type operator* ( @@ -113,6 +137,23 @@ inline constexpr typename mat<4, 4, T>::row_type operator* #undef c } +template +inline constexpr vec<3, T> operator* +( + mat<4, 4, T> const& m, + vec<3, T> const& v +) +{ +#define c(i) ( \ + m[i][0] * v[0] \ + + m[i][1] * v[1] \ + + m[i][2] * v[2] \ + + m[i][3] ) + + return vec<3, T>(c(0), c(1), c(2)); +#undef c +} + template inline constexpr mat<4, 4, T> transpose(mat<4, 4, T> const& m) { diff --git a/math/vec2.hpp b/math/vec2.hpp new file mode 100644 index 0000000..f89f179 --- /dev/null +++ b/math/vec2.hpp @@ -0,0 +1,158 @@ +#pragma once + +#include "math.hpp" +#include "vec.hpp" + +// +// vec3 +// + +template +struct vec<2, T> +{ + union { + struct { T x, y; }; + struct { T u, v; }; + }; + + inline constexpr vec(); + inline constexpr vec(T scalar); + inline constexpr vec(T _x, T _y); + + constexpr inline vec<2, T> operator-() const; + inline constexpr T const& operator[](int i) const; + inline constexpr vec<2, T>& operator=(vec<2, T> const& v); + inline constexpr vec<2, T>& operator+=(vec<2, T> const& v); + inline constexpr vec<2, T>& operator-=(vec<2, T> const& v); +}; + +template +inline constexpr vec<2, T>::vec() + : x(0), y(0) +{} + +template +inline constexpr vec<2, T>::vec(T scalar) + : x(scalar), y(scalar) +{} + +template +inline constexpr vec<2, T>::vec(T _x, T _y) + : x(_x), y(_y) +{} + +template +constexpr inline vec<2, T> vec<2, T>::operator-() const +{ + return vec<2, T>(-x, -y); +} + +template +inline constexpr T const& vec<2, T>::operator[](int i) const +{ + switch(i) + { + default: [[fallthrough]]; + case 0: return x; + case 1: return y; + } +} + +template +inline constexpr vec<2, T>& vec<2, T>::operator=(vec<2, T> const& v) +{ + this->x = static_cast(v.x); + this->y = static_cast(v.y); + return *this; +} + +template +inline constexpr vec<2, T>& vec<2, T>::operator+=(vec<2, T> const& v) +{ + *this = *this + vec<2, T>(v); + return *this; +} + +template +inline constexpr vec<2, T>& vec<2, T>::operator-=(vec<2, T> const& v) +{ + *this = *this - vec<2, T>(v); + return *this; +} + +template +inline constexpr vec<2, T> operator+(vec<2, T> const& v1, vec<2, T> const& v2) +{ + return vec<2, T>(v1.x + v2.x, + v1.y + v2.y); +} + +template +inline constexpr vec<2, T> operator-(vec<2, T> const& v1, vec<2, T> const& v2) +{ + return vec<2, T>(v1.x - v2.x, + v1.y - v2.y); +} + +template +inline constexpr vec<2, T> operator*(vec<2, T> const& v1, vec<2, T> const& v2) +{ + return vec<2, T>(v1.x * v2.x, + v1.y * v2.y); +} + +template +inline constexpr vec<2, T> operator*(vec<2, T> const& v1, T const& scalar) +{ + return v1 * vec<2, T>(scalar); +} + +template +inline constexpr vec<2, T> operator*(T const& scalar, vec<2, T> const& v1) +{ + return vec<2, T>(scalar) * v1; +} + +template +inline constexpr vec<2, T> operator/(vec<2, T> const& v1, vec<2, T> const& v2) +{ + return vec<2, T>(v1.x / v2.x, + v1.y / v2.y); +} + +template +inline constexpr vec<2, T> operator/(vec<2, T> const& v1, T const& scalar) +{ + return v1 / vec<2, T>(scalar); +} + +template +inline constexpr T dot(vec<2, T> const& v1, vec<2, T> const& v2) +{ + vec<2, T> tmp(v1 * v2); + return tmp.x + tmp.y; +} + +template +inline constexpr T cross(vec<2, T> const& v1, vec<2, T> const& v2) +{ + return v1.x * v2.y - v2.x * v1.y; +} + +template +inline constexpr vec<2, T> functor1(T (&func) (T const& x), vec<2, T> const& v) +{ + return vec<2, T>(func(v.x), func(v.y)); +} + +template +inline constexpr vec<2, U> functor1(U (&func) (T const& x), vec<2, T> const& v) +{ + return vec<2, U>(func(v.x), func(v.y)); +} + +template +inline constexpr T magnitude(vec<2, T> const& v) +{ + return sqrt(dot(v, v)); +} diff --git a/math/vec3.hpp b/math/vec3.hpp index c05dd72..5adae6b 100644 --- a/math/vec3.hpp +++ b/math/vec3.hpp @@ -10,7 +10,10 @@ template struct vec<3, T> { - T x, y, z; + union { + struct { T x, y, z; }; + struct { T r, g, b; }; + }; inline constexpr vec(); inline constexpr vec(T scalar); @@ -109,6 +112,12 @@ inline constexpr vec<3, T> operator*(vec<3, T> const& v1, T const& scalar) return v1 * vec<3, T>(scalar); } +template +inline constexpr vec<3, T> operator*(T const& scalar, vec<3, T> const& v1) +{ + return vec<3, T>(scalar) * v1; +} + template inline constexpr vec<3, T> operator/(vec<3, T> const& v1, vec<3, T> const& v2) { @@ -130,6 +139,14 @@ inline constexpr T dot(vec<3, T> const& v1, vec<3, T> const& v2) return tmp.x + tmp.y + tmp.z; } +template +inline constexpr vec<3, T> cross(vec<3, T> const& v1, vec<3, T> const& v2) +{ + return vec<3, T>(v1.y * v2.z - v2.y * v1.z, + v1.z * v2.x - v2.z * v1.x, + v1.x * v2.y - v2.x * v1.y); +} + template inline constexpr vec<3, T> functor1(T (&func) (T const& x), vec<3, T> const& v) { @@ -143,15 +160,7 @@ inline constexpr vec<3, U> functor1(U (&func) (T const& x), vec<3, T> const& v) } template -inline constexpr T length(vec<3, T> const& v) +inline constexpr T magnitude(vec<3, T> const& v) { return sqrt(dot(v, v)); } - -template -inline constexpr vec<3, T> cross(vec<3, T> const& x, vec<3, T> const& y) -{ - return vec<3, T>(x.y * y.z - y.y * x.z, - x.z * y.x - y.z * x.x, - x.x * y.y - y.x * x.y); -} diff --git a/vec4.hpp b/vec4.hpp new file mode 100644 index 0000000..9f2ec88 --- /dev/null +++ b/vec4.hpp @@ -0,0 +1,170 @@ +#pragma once + +#include "math.hpp" +#include "vec.hpp" + +// +// vec4 +// + +template +struct vec<4, T> +{ + union { + struct { T x, y, z, w; }; + struct { T a, r, g, b; }; + }; + + inline constexpr vec(); + inline constexpr vec(T scalar); + inline constexpr vec(T _x, T _y, T _z, T _w); + inline constexpr vec(const vec<3, T>& v); + + constexpr inline vec<4, T> operator-() const; + inline constexpr T const& operator[](int i) const; + inline constexpr vec<4, T>& operator=(vec<4, T> const& v); + inline constexpr vec<4, T>& operator+=(vec<4, T> const& v); + inline constexpr vec<4, T>& operator-=(vec<4, T> const& v); +}; + +template +inline constexpr vec<4, T>::vec() + : x(0), y(0), z(0), w(0) +{} + +template +inline constexpr vec<4, T>::vec(T scalar) + : x(scalar), y(scalar), z(scalar), w(scalar) +{} + +template +inline constexpr vec<4, T>::vec(T _x, T _y, T _z, T _w) + : x(_x), y(_y), z(_z), w(_w) +{} + +template +inline constexpr vec<4, T>::vec(const vec<3, T>& v) + : x(v.x), y(v.y), z(v.z), w(1.f) +{} + +template +constexpr inline vec<4, T> vec<4, T>::operator-() const +{ + return vec<4, T>(-x, -y, -z, -w); +} + +template +inline constexpr T const& vec<4, T>::operator[](int i) const +{ + switch(i) + { + default: [[fallthrough]]; + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + } +} + +template +inline constexpr vec<4, T>& vec<4, T>::operator=(vec<4, T> const& v) +{ + this->x = static_cast(v.x); + this->y = static_cast(v.y); + this->z = static_cast(v.z); + this->w = static_cast(v.w); + return *this; +} + +template +inline constexpr vec<4, T>& vec<4, T>::operator+=(vec<4, T> const& v) +{ + *this = *this + vec<4, T>(v); + return *this; +} + +template +inline constexpr vec<4, T>& vec<4, T>::operator-=(vec<4, T> const& v) +{ + *this = *this - vec<4, T>(v); + return *this; +} + +template +inline constexpr vec<4, T> operator+(vec<4, T> const& v1, vec<4, T> const& v2) +{ + return vec<4, T>(v1.x + v2.x, + v1.y + v2.y, + v1.z + v2.z, + v1.w + v2.w); +} + +template +inline constexpr vec<4, T> operator-(vec<4, T> const& v1, vec<4, T> const& v2) +{ + return vec<4, T>(v1.x - v2.x, + v1.y - v2.y, + v1.z - v2.z, + v1.w - v2.w); +} + +template +inline constexpr vec<4, T> operator*(vec<4, T> const& v1, vec<4, T> const& v2) +{ + return vec<4, T>(v1.x * v2.x, + v1.y * v2.y, + v1.z * v2.z, + v1.w * v2.w); +} + +template +inline constexpr vec<4, T> operator*(vec<4, T> const& v1, T const& scalar) +{ + return v1 * vec<4, T>(scalar); +} + +template +inline constexpr vec<4, T> operator*(T const& scalar, vec<4, T> const& v1) +{ + return vec<4, T>(scalar) * v1; +} + +template +inline constexpr vec<4, T> operator/(vec<4, T> const& v1, vec<4, T> const& v2) +{ + return vec<4, T>(v1.x / v2.x, + v1.y / v2.y, + v1.z / v2.z, + v1.w / v2.w); +} + +template +inline constexpr vec<4, T> operator/(vec<4, T> const& v1, T const& scalar) +{ + return v1 / vec<4, T>(scalar); +} + +template +inline constexpr T dot(vec<4, T> const& v1, vec<4, T> const& v2) +{ + vec<4, T> tmp(v1 * v2); + return tmp.x + tmp.y + tmp.z + tmp.w; +} + +template +inline constexpr vec<4, T> functor1(T (&func) (T const& x), vec<4, T> const& v) +{ + return vec<4, T>(func(v.x), func(v.y), func(v.z), func(v.w)); +} + +template +inline constexpr vec<4, U> functor1(U (&func) (T const& x), vec<4, T> const& v) +{ + return vec<4, U>(func(v.x), func(v.y), func(v.z), func(v.w)); +} + +template +inline constexpr T magnitude(vec<4, T> const& v) +{ + return sqrt(dot(v, v)); +}