diff --git a/src/lol/math/vector.h b/src/lol/math/vector.h index b594218d..6811dd71 100644 --- a/src/lol/math/vector.h +++ b/src/lol/math/vector.h @@ -56,6 +56,8 @@ DECLARE_VECTOR_TYPEDEFS(Cmplx, cmplx) DECLARE_VECTOR_TYPEDEFS(Vec3, vec3) DECLARE_VECTOR_TYPEDEFS(Vec4, vec4) DECLARE_VECTOR_TYPEDEFS(Quat, quat) +DECLARE_VECTOR_TYPEDEFS(Mat2, mat2) +DECLARE_VECTOR_TYPEDEFS(Mat3, mat3) DECLARE_VECTOR_TYPEDEFS(Mat4, mat4) /* @@ -910,6 +912,7 @@ template struct Quat inline Quat(T X) : x(0), y(0), z(0), w(X) {} inline Quat(T X, T Y, T Z, T W) : x(X), y(Y), z(Z), w(W) {} + Quat(Mat3 const &m); Quat(Mat4 const &m); DECLARE_MEMBER_OPS(Quat) @@ -1334,6 +1337,171 @@ inline Vec4 XVec4::operator =(Vec4 const &that) return *this; } +/* + * 2×2-element matrices + */ + +template struct Mat2 +{ + inline Mat2() {} + inline Mat2(Vec2 V0, Vec2 V1) + : v0(V0), v1(V1) {} + + explicit inline Mat2(T val) + : v0(val, (T)0), + v1((T)0, val) {} + + inline Vec2& operator[](size_t n) { return (&v0)[n]; } + inline Vec2 const& operator[](size_t n) const { return (&v0)[n]; } + + T det() const; + Mat2 invert() const; + + /* Helpers for transformation matrices */ + static Mat2 rotate(T angle); + + static inline Mat2 rotate(Mat2 mat, T angle) + { + return rotate(angle) * mat; + } + + void printf() const; + +#if !defined __ANDROID__ + template + friend std::ostream &operator<<(std::ostream &stream, Mat2 const &m); +#endif + + inline Mat2 operator +(Mat2 const m) const + { + return Mat2(v0 + m[0], v1 + m[1]); + } + + inline Mat2 operator +=(Mat2 const m) + { + return *this = *this + m; + } + + inline Mat2 operator -(Mat2 const m) const + { + return Mat2(v0 - m[0], v1 - m[1]); + } + + inline Mat2 operator -=(Mat2 const m) + { + return *this = *this - m; + } + + inline Mat2 operator *(Mat2 const m) const + { + return Mat2(*this * m[0], *this * m[1]); + } + + inline Mat2 operator *=(Mat2 const m) + { + return *this = *this * m; + } + + inline Vec2 operator *(Vec2 const m) const + { + Vec2 ret; + for (int j = 0; j < 2; j++) + { + T tmp = 0; + for (int k = 0; k < 2; k++) + tmp += (*this)[k][j] * m[k]; + ret[j] = tmp; + } + return ret; + } + + Vec2 v0, v1; +}; + +/* + * 3×3-element matrices + */ + +template struct Mat3 +{ + inline Mat3() {} + inline Mat3(Vec3 V0, Vec3 V1, Vec3 V2) + : v0(V0), v1(V1), v2(V2) {} + + explicit inline Mat3(T val) + : v0(val, (T)0, (T)0), + v1((T)0, val, (T)0), + v2((T)0, (T)0, val) {} + + inline Vec3& operator[](size_t n) { return (&v0)[n]; } + inline Vec3 const& operator[](size_t n) const { return (&v0)[n]; } + + T det() const; + Mat3 invert() const; + + /* Helpers for transformation matrices */ + static Mat3 rotate(T angle, T x, T y, T z); + static Mat3 rotate(T angle, Vec3 v); + static Mat3 rotate(Quat q); + + static inline Mat3 rotate(Mat3 mat, T angle, Vec3 v) + { + return rotate(angle, v) * mat; + } + + void printf() const; + +#if !defined __ANDROID__ + template + friend std::ostream &operator<<(std::ostream &stream, Mat3 const &m); +#endif + + inline Mat3 operator +(Mat3 const m) const + { + return Mat3(v0 + m[0], v1 + m[1], v2 + m[2]); + } + + inline Mat3 operator +=(Mat3 const m) + { + return *this = *this + m; + } + + inline Mat3 operator -(Mat3 const m) const + { + return Mat3(v0 - m[0], v1 - m[1], v2 - m[2]); + } + + inline Mat3 operator -=(Mat3 const m) + { + return *this = *this - m; + } + + inline Mat3 operator *(Mat3 const m) const + { + return Mat3(*this * m[0], *this * m[1], *this * m[2]); + } + + inline Mat3 operator *=(Mat3 const m) + { + return *this = *this * m; + } + + inline Vec3 operator *(Vec3 const m) const + { + Vec3 ret; + for (int j = 0; j < 3; j++) + { + T tmp = 0; + for (int k = 0; k < 3; k++) + tmp += (*this)[k][j] * m[k]; + ret[j] = tmp; + } + return ret; + } + + Vec3 v0, v1, v2; +}; + /* * 4×4-element matrices */