| @@ -43,7 +43,7 @@ liblolcore_headers = \ | |||||
| lol/math/all.h \ | lol/math/all.h \ | ||||
| lol/math/functions.h lol/math/vector.h lol/math/half.h lol/math/real.h \ | lol/math/functions.h lol/math/vector.h lol/math/half.h lol/math/real.h \ | ||||
| lol/math/geometry.h lol/math/interp.h lol/math/rand.h lol/math/array2d.h \ | lol/math/geometry.h lol/math/interp.h lol/math/rand.h lol/math/array2d.h \ | ||||
| lol/math/array3d.h lol/math/constants.h \ | |||||
| lol/math/array3d.h lol/math/constants.h lol/math/matrix.h \ | |||||
| \ | \ | ||||
| lol/algorithm/all.h \ | lol/algorithm/all.h \ | ||||
| lol/algorithm/sort.h lol/algorithm/portal.h lol/algorithm/aabb_tree.h \ | lol/algorithm/sort.h lol/algorithm/portal.h lol/algorithm/aabb_tree.h \ | ||||
| @@ -28,6 +28,10 @@ typedef Real<16> real; | |||||
| /* The “half” type used for 16-bit floating point numbers. */ | /* The “half” type used for 16-bit floating point numbers. */ | ||||
| class half; | class half; | ||||
| /* Forward declaration of vec and matrix */ | |||||
| template<int N, typename T, int MASK> struct vec; | |||||
| template<int COLS, int ROWS, typename T> struct matrix; | |||||
| } /* namespace lol */ | } /* namespace lol */ | ||||
| #endif // __LOL_BASE_TYPES_H__ | #endif // __LOL_BASE_TYPES_H__ | ||||
| @@ -16,6 +16,7 @@ | |||||
| #include <lol/math/half.h> | #include <lol/math/half.h> | ||||
| #include <lol/math/real.h> | #include <lol/math/real.h> | ||||
| #include <lol/math/vector.h> | #include <lol/math/vector.h> | ||||
| #include <lol/math/matrix.h> | |||||
| #include <lol/math/array2d.h> | #include <lol/math/array2d.h> | ||||
| #include <lol/math/array3d.h> | #include <lol/math/array3d.h> | ||||
| #include <lol/math/geometry.h> | #include <lol/math/geometry.h> | ||||
| @@ -0,0 +1,427 @@ | |||||
| // | |||||
| // Lol Engine | |||||
| // | |||||
| // Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://www.wtfpl.net/ for more details. | |||||
| // | |||||
| // | |||||
| // The matrix classes | |||||
| // ------------------ | |||||
| // | |||||
| #if !defined __LOL_MATH_MATRIX_H__ | |||||
| #define __LOL_MATH_MATRIX_H__ | |||||
| #include <stdint.h> | |||||
| #include <ostream> | |||||
| #include <lol/math/vector.h> | |||||
| namespace lol | |||||
| { | |||||
| #if !LOL_FEATURE_CXX11_CONSTEXPR | |||||
| # define constexpr /* */ | |||||
| #endif | |||||
| /* The generic "matrix" type, which is a fixed-size matrix */ | |||||
| template<int COLS, int ROWS, typename T> | |||||
| struct matrix | |||||
| { | |||||
| typedef matrix<COLS,ROWS,T> type; | |||||
| inline matrix() {} | |||||
| explicit inline matrix(T const &val) | |||||
| { | |||||
| T const zero = T(0); | |||||
| for (int i = 0; i < COLS; ++i) | |||||
| for (int j = 0; j < ROWS; ++j) | |||||
| m_data[i][j] = i == j ? val : zero; | |||||
| } | |||||
| inline vec<ROWS,T>& operator[](size_t n) { return m_data[n]; } | |||||
| inline vec<ROWS,T> const& operator[](size_t n) const { return m_data[n]; } | |||||
| private: | |||||
| vec<ROWS,T> m_data[COLS]; | |||||
| }; | |||||
| /* | |||||
| * 2×2-element matrices | |||||
| */ | |||||
| template <typename T> | |||||
| struct matrix<2, 2, T> | |||||
| { | |||||
| typedef matrix<2,2,T> type; | |||||
| inline matrix() {} | |||||
| inline matrix(vec<2,T> V0, vec<2,T> V1) | |||||
| : v0(V0), v1(V1) {} | |||||
| explicit inline matrix(T const &val) | |||||
| : v0(val, (T)0), | |||||
| v1((T)0, val) {} | |||||
| explicit inline matrix(matrix<4,4,T> const &mat) | |||||
| : v0(mat[0].xy), | |||||
| v1(mat[1].xy) {} | |||||
| 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 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; | |||||
| } | |||||
| void printf() const; | |||||
| String tostring() const; | |||||
| template<class U> | |||||
| friend std::ostream &operator<<(std::ostream &stream, | |||||
| matrix<2,2,U> const &m); | |||||
| vec<2,T> v0, v1; | |||||
| static const matrix<2,2,T> identity; | |||||
| }; | |||||
| /* | |||||
| * 3×3-element matrices | |||||
| */ | |||||
| template <typename T> | |||||
| struct matrix<3,3,T> | |||||
| { | |||||
| 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 matrix(T const &val) | |||||
| : v0(val, (T)0, (T)0), | |||||
| v1((T)0, val, (T)0), | |||||
| v2((T)0, (T)0, val) {} | |||||
| 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 matrix(matrix<2,2,T> mat, T const &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 matrix(matrix<4,4,T> const &mat) | |||||
| : v0(mat[0].xyz), | |||||
| v1(mat[1].xyz), | |||||
| v2(mat[2].xyz) {} | |||||
| explicit matrix(Quat<T> const &q); | |||||
| 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 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; | |||||
| } | |||||
| void printf() const; | |||||
| String tostring() const; | |||||
| template<class U> | |||||
| friend std::ostream &operator<<(std::ostream &stream, | |||||
| matrix<3,3,U> const &m); | |||||
| vec<3,T> v0, v1, v2; | |||||
| static const matrix<3,3,T> identity; | |||||
| }; | |||||
| /* | |||||
| * 4×4-element matrices | |||||
| */ | |||||
| template <typename T> | |||||
| struct matrix<4, 4, T> | |||||
| { | |||||
| 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 matrix(T const &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 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 matrix(matrix<2,2,T> mat, T const &val1, T const &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 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 matrix(matrix<3,3,T> mat, T const &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 matrix(Quat<T> const &q); | |||||
| 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 matrix<4,4,T> translate(T x, T y, T z); | |||||
| static matrix<4,4,T> translate(vec<3,T> v); | |||||
| static inline matrix<4,4,T> scale(T x) | |||||
| { | |||||
| return matrix<4,4,T>(matrix<3,3,T>::scale(x), (T)1); | |||||
| } | |||||
| static inline matrix<4,4,T> scale(T x, T y, T z) | |||||
| { | |||||
| return matrix<4,4,T>(matrix<3,3,T>::scale(x, y, z), (T)1); | |||||
| } | |||||
| static inline matrix<4,4,T> scale(vec<3,T> v) | |||||
| { | |||||
| return matrix<4,4,T>(matrix<3,3,T>::scale(v), (T)1); | |||||
| } | |||||
| static inline matrix<4,4,T> translate(matrix<4,4,T> const &mat, vec<3,T> v) | |||||
| { | |||||
| return translate(v) * mat; | |||||
| } | |||||
| static inline matrix<4,4,T> rotate(T degrees, T x, T y, T z) | |||||
| { | |||||
| return matrix<4,4,T>(matrix<3,3,T>::rotate(degrees, x, y, z), (T)1); | |||||
| } | |||||
| static inline matrix<4,4,T> rotate(T degrees, vec<3,T> v) | |||||
| { | |||||
| return matrix<4,4,T>(matrix<3,3,T>::rotate(degrees, v), (T)1); | |||||
| } | |||||
| static inline matrix<4,4,T> rotate(matrix<4,4,T> &mat, T degrees, vec<3,T> v) | |||||
| { | |||||
| return rotate(degrees, v) * mat; | |||||
| } | |||||
| 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 matrix<4,4,T> lookat(vec<3,T> eye, vec<3,T> center, vec<3,T> up); | |||||
| /* Helpers for projection matrices */ | |||||
| 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<class U> | |||||
| friend std::ostream &operator<<(std::ostream &stream, | |||||
| matrix<4,4,U> const &m); | |||||
| vec<4,T> v0, v1, v2, v3; | |||||
| static const matrix<4,4,T> identity; | |||||
| }; | |||||
| template<typename T> T determinant(matrix<2,2,T> const &); | |||||
| template<typename T> T determinant(matrix<3,3,T> const &); | |||||
| template<typename T> T determinant(matrix<4,4,T> const &); | |||||
| template<typename T> matrix<2,2,T> transpose(matrix<2,2,T> const &); | |||||
| template<typename T> matrix<3,3,T> transpose(matrix<3,3,T> const &); | |||||
| template<typename T> matrix<4,4,T> transpose(matrix<4,4,T> const &); | |||||
| template<typename T> matrix<2,2,T> inverse(matrix<2,2,T> const &); | |||||
| template<typename T> matrix<3,3,T> inverse(matrix<3,3,T> const &); | |||||
| template<typename T> matrix<4,4,T> inverse(matrix<4,4,T> const &); | |||||
| /* | |||||
| * Addition/subtraction/unary | |||||
| */ | |||||
| template<int COLS, int ROWS, typename T> | |||||
| static inline matrix<COLS, ROWS, T> &operator +=(matrix<COLS, ROWS, T> &a, | |||||
| matrix<COLS, ROWS, T> const &b) | |||||
| { | |||||
| for (int i = 0; i < COLS; ++i) | |||||
| a[i] += b[i]; | |||||
| return a; | |||||
| } | |||||
| template<int COLS, int ROWS, typename T> | |||||
| static inline matrix<COLS, ROWS, T> operator +(matrix<COLS, ROWS, T> const &a, | |||||
| matrix<COLS, ROWS, T> const &b) | |||||
| { | |||||
| matrix<COLS, ROWS, T> ret = a; | |||||
| return ret += b; | |||||
| } | |||||
| template<int COLS, int ROWS, typename T> | |||||
| static inline matrix<COLS, ROWS, T> operator +(matrix<COLS, ROWS, T> const &m) | |||||
| { | |||||
| return m; | |||||
| } | |||||
| template<int COLS, int ROWS, typename T> | |||||
| static inline matrix<COLS, ROWS, T> &operator -=(matrix<COLS, ROWS, T> &a, | |||||
| matrix<COLS, ROWS, T> const &b) | |||||
| { | |||||
| for (int i = 0; i < COLS; ++i) | |||||
| a[i] -= b[i]; | |||||
| return a; | |||||
| } | |||||
| template<int COLS, int ROWS, typename T> | |||||
| static inline matrix<COLS, ROWS, T> operator -(matrix<COLS, ROWS, T> const &a, | |||||
| matrix<COLS, ROWS, T> const &b) | |||||
| { | |||||
| matrix<COLS, ROWS, T> ret = a; | |||||
| return ret -= b; | |||||
| } | |||||
| template<int COLS, int ROWS, typename T> | |||||
| static inline matrix<COLS, ROWS, T> operator -(matrix<COLS, ROWS, T> const &m) | |||||
| { | |||||
| matrix<COLS, ROWS, T> ret; | |||||
| for (int i = 0; i < COLS; ++i) | |||||
| ret[i] = -m[i]; | |||||
| return ret; | |||||
| } | |||||
| /* | |||||
| * Matrix-vector multiplication | |||||
| */ | |||||
| template<int COLS, int ROWS, int MASK, typename T> | |||||
| static inline vec<ROWS, T> operator *(matrix<COLS, ROWS, T> const &m, | |||||
| vec<COLS, T, MASK> const &v) | |||||
| { | |||||
| vec<ROWS, T> ret(T(0)); | |||||
| for (int i = 0; i < COLS; ++i) | |||||
| ret += m[i] * v[i]; | |||||
| return ret; | |||||
| } | |||||
| /* | |||||
| * Matrix-matrix multiplication | |||||
| */ | |||||
| template<int COLS, int N, int ROWS, typename T> | |||||
| static inline matrix<COLS, ROWS, T> operator *(matrix<N, ROWS, T> const &a, | |||||
| matrix<COLS, N, T> const &b) | |||||
| { | |||||
| matrix<COLS, ROWS, T> ret; | |||||
| for (int i = 0; i < COLS; ++i) | |||||
| ret[i] = a * b[i]; | |||||
| return ret; | |||||
| } | |||||
| template<int N, typename T> | |||||
| static inline matrix<N, N, T> &operator *=(matrix<N, N, T> &a, | |||||
| matrix<N, N, T> const &b) | |||||
| { | |||||
| return a = a * b; | |||||
| } | |||||
| #if !LOL_FEATURE_CXX11_CONSTEXPR | |||||
| #undef constexpr | |||||
| #endif | |||||
| } /* namespace lol */ | |||||
| #endif // __LOL_MATH_MATRIX_H__ | |||||
| @@ -52,6 +52,8 @@ namespace lol | |||||
| template<int N, typename T, int MASK = -1> | template<int N, typename T, int MASK = -1> | ||||
| struct vec | struct vec | ||||
| { | { | ||||
| typedef vec<N,T> type; | |||||
| inline vec<N, T, MASK>& operator =(vec<N, T> that); | inline vec<N, T, MASK>& operator =(vec<N, T> that); | ||||
| #if LOL_FEATURE_CXX11_RELAXED_UNIONS | #if LOL_FEATURE_CXX11_RELAXED_UNIONS | ||||
| @@ -78,16 +80,13 @@ struct vec | |||||
| template<int N, typename T> | template<int N, typename T> | ||||
| struct vec<N, T, -1> | struct vec<N, T, -1> | ||||
| { | { | ||||
| private: | |||||
| T m_data[N]; | |||||
| }; | |||||
| typedef vec<N,T> type; | |||||
| inline T& operator[](size_t n) { return m_data[n]; } | |||||
| inline T const& operator[](size_t n) const { return m_data[n]; } | |||||
| /* The generic "matrix" type, which is a fixed-size matrix */ | |||||
| template<int COLS, int ROWS, typename T> | |||||
| struct matrix | |||||
| { | |||||
| private: | private: | ||||
| T m_data[COLS][ROWS]; | |||||
| T m_data[N]; | |||||
| }; | }; | ||||
| /* The generic complex and quaternion types. */ | /* The generic complex and quaternion types. */ | ||||
| @@ -99,7 +98,6 @@ template<typename T> struct Quat; | |||||
| */ | */ | ||||
| #define COMMA , | #define COMMA , | ||||
| #define LOL_VECTOR_TYPEDEFS(tleft, tright, suffix) \ | #define LOL_VECTOR_TYPEDEFS(tleft, tright, suffix) \ | ||||
| typedef tleft half tright f16##suffix; \ | typedef tleft half tright f16##suffix; \ | ||||
| typedef tleft float tright suffix; \ | typedef tleft float tright suffix; \ | ||||
| @@ -134,6 +132,7 @@ LOL_VECTOR_TYPEDEFS(Cmplx<, >, cmplx) | |||||
| LOL_VECTOR_TYPEDEFS(Quat<, >, quat) | LOL_VECTOR_TYPEDEFS(Quat<, >, quat) | ||||
| #undef LOL_VECTOR_TYPEDEFS | #undef LOL_VECTOR_TYPEDEFS | ||||
| #undef COMMA | |||||
| /* | /* | ||||
| * HLSL/Cg-compliant type names. | * HLSL/Cg-compliant type names. | ||||
| @@ -1612,413 +1611,6 @@ inline vec<N, T, MASK>& vec<N, T, MASK>::operator =(vec<N,T> that) | |||||
| } | } | ||||
| #endif | #endif | ||||
| /* | |||||
| * 2×2-element matrices | |||||
| */ | |||||
| template <typename T> | |||||
| struct matrix<2, 2, T> | |||||
| { | |||||
| typedef matrix<2,2,T> type; | |||||
| inline matrix() {} | |||||
| inline matrix(vec<2,T> V0, vec<2,T> V1) | |||||
| : v0(V0), v1(V1) {} | |||||
| explicit inline matrix(T val) | |||||
| : v0(val, (T)0), | |||||
| v1((T)0, val) {} | |||||
| explicit inline matrix(matrix<4,4,T> const &mat) | |||||
| : v0(mat[0].xy), | |||||
| v1(mat[1].xy) {} | |||||
| 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 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; | |||||
| } | |||||
| void printf() const; | |||||
| String tostring() const; | |||||
| template<class U> | |||||
| friend std::ostream &operator<<(std::ostream &stream, | |||||
| matrix<2,2,U> const &m); | |||||
| inline matrix<2,2,T> operator +(matrix<2,2,T> const m) const | |||||
| { | |||||
| return matrix<2,2,T>(v0 + m[0], v1 + m[1]); | |||||
| } | |||||
| inline matrix<2,2,T> operator +=(matrix<2,2,T> const m) | |||||
| { | |||||
| return *this = *this + m; | |||||
| } | |||||
| inline matrix<2,2,T> operator -(matrix<2,2,T> const m) const | |||||
| { | |||||
| return matrix<2,2,T>(v0 - m[0], v1 - m[1]); | |||||
| } | |||||
| inline matrix<2,2,T> operator -=(matrix<2,2,T> const m) | |||||
| { | |||||
| return *this = *this - m; | |||||
| } | |||||
| inline matrix<2,2,T> operator *(matrix<2,2,T> const m) const | |||||
| { | |||||
| return matrix<2,2,T>(*this * m[0], *this * m[1]); | |||||
| } | |||||
| inline matrix<2,2,T> operator *=(matrix<2,2,T> const m) | |||||
| { | |||||
| return *this = *this * m; | |||||
| } | |||||
| inline vec<2,T> operator *(vec<2,T> const m) const | |||||
| { | |||||
| vec<2,T> 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; | |||||
| } | |||||
| vec<2,T> v0, v1; | |||||
| static const matrix<2,2,T> identity; | |||||
| }; | |||||
| /* | |||||
| * 3×3-element matrices | |||||
| */ | |||||
| template <typename T> | |||||
| struct matrix<3,3,T> | |||||
| { | |||||
| 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 matrix(T val) | |||||
| : v0(val, (T)0, (T)0), | |||||
| v1((T)0, val, (T)0), | |||||
| v2((T)0, (T)0, val) {} | |||||
| 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 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 matrix(matrix<4,4,T> const &mat) | |||||
| : v0(mat[0].xyz), | |||||
| v1(mat[1].xyz), | |||||
| v2(mat[2].xyz) {} | |||||
| explicit matrix(Quat<T> const &q); | |||||
| 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 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; | |||||
| } | |||||
| void printf() const; | |||||
| String tostring() const; | |||||
| template<class U> | |||||
| friend std::ostream &operator<<(std::ostream &stream, | |||||
| matrix<3,3,U> const &m); | |||||
| inline matrix<3,3,T> operator +(matrix<3,3,T> const m) const | |||||
| { | |||||
| return matrix<3,3,T>(v0 + m[0], v1 + m[1], v2 + m[2]); | |||||
| } | |||||
| inline matrix<3,3,T> operator +=(matrix<3,3,T> const m) | |||||
| { | |||||
| return *this = *this + m; | |||||
| } | |||||
| inline matrix<3,3,T> operator -(matrix<3,3,T> const m) const | |||||
| { | |||||
| return matrix<3,3,T>(v0 - m[0], v1 - m[1], v2 - m[2]); | |||||
| } | |||||
| inline matrix<3,3,T> operator -=(matrix<3,3,T> const m) | |||||
| { | |||||
| return *this = *this - m; | |||||
| } | |||||
| inline matrix<3,3,T> operator *(matrix<3,3,T> const m) const | |||||
| { | |||||
| return matrix<3,3,T>(*this * m[0], *this * m[1], *this * m[2]); | |||||
| } | |||||
| inline matrix<3,3,T> operator *=(matrix<3,3,T> const m) | |||||
| { | |||||
| return *this = *this * m; | |||||
| } | |||||
| inline vec<3,T> operator *(vec<3,T> const m) const | |||||
| { | |||||
| vec<3,T> 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; | |||||
| } | |||||
| vec<3,T> v0, v1, v2; | |||||
| static const matrix<3,3,T> identity; | |||||
| }; | |||||
| /* | |||||
| * 4×4-element matrices | |||||
| */ | |||||
| template <typename T> | |||||
| struct matrix<4, 4, T> | |||||
| { | |||||
| 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 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 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 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 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 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 matrix(Quat<T> const &q); | |||||
| 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 matrix<4,4,T> translate(T x, T y, T z); | |||||
| static matrix<4,4,T> translate(vec<3,T> v); | |||||
| static inline matrix<4,4,T> scale(T x) | |||||
| { | |||||
| return matrix<4,4,T>(matrix<3,3,T>::scale(x), (T)1); | |||||
| } | |||||
| static inline matrix<4,4,T> scale(T x, T y, T z) | |||||
| { | |||||
| return matrix<4,4,T>(matrix<3,3,T>::scale(x, y, z), (T)1); | |||||
| } | |||||
| static inline matrix<4,4,T> scale(vec<3,T> v) | |||||
| { | |||||
| return matrix<4,4,T>(matrix<3,3,T>::scale(v), (T)1); | |||||
| } | |||||
| static inline matrix<4,4,T> translate(matrix<4,4,T> const &mat, vec<3,T> v) | |||||
| { | |||||
| return translate(v) * mat; | |||||
| } | |||||
| static inline matrix<4,4,T> rotate(T degrees, T x, T y, T z) | |||||
| { | |||||
| return matrix<4,4,T>(matrix<3,3,T>::rotate(degrees, x, y, z), (T)1); | |||||
| } | |||||
| static inline matrix<4,4,T> rotate(T degrees, vec<3,T> v) | |||||
| { | |||||
| return matrix<4,4,T>(matrix<3,3,T>::rotate(degrees, v), (T)1); | |||||
| } | |||||
| static inline matrix<4,4,T> rotate(matrix<4,4,T> &mat, T degrees, vec<3,T> v) | |||||
| { | |||||
| return rotate(degrees, v) * mat; | |||||
| } | |||||
| 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 matrix<4,4,T> lookat(vec<3,T> eye, vec<3,T> center, vec<3,T> up); | |||||
| /* Helpers for projection matrices */ | |||||
| 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<class U> | |||||
| friend std::ostream &operator<<(std::ostream &stream, | |||||
| matrix<4,4,U> const &m); | |||||
| inline matrix<4,4,T> operator +(matrix<4,4,T> const &m) const | |||||
| { | |||||
| return matrix<4,4,T>(v0 + m[0], v1 + m[1], v2 + m[2], v3 + m[3]); | |||||
| } | |||||
| inline matrix<4,4,T> operator +=(matrix<4,4,T> const &m) | |||||
| { | |||||
| return *this = *this + m; | |||||
| } | |||||
| inline matrix<4,4,T> operator -(matrix<4,4,T> const &m) const | |||||
| { | |||||
| return matrix<4,4,T>(v0 - m[0], v1 - m[1], v2 - m[2], v3 - m[3]); | |||||
| } | |||||
| inline matrix<4,4,T> operator -=(matrix<4,4,T> const &m) | |||||
| { | |||||
| return *this = *this - m; | |||||
| } | |||||
| inline matrix<4,4,T> operator *(matrix<4,4,T> const &m) const | |||||
| { | |||||
| return matrix<4,4,T>(*this * m[0], *this * m[1], *this * m[2], *this * m[3]); | |||||
| } | |||||
| inline matrix<4,4,T> operator *=(matrix<4,4,T> const &m) | |||||
| { | |||||
| return *this = *this * m; | |||||
| } | |||||
| inline vec<4,T> operator *(vec<4,T> const &m) const | |||||
| { | |||||
| vec<4,T> ret; | |||||
| for (int j = 0; j < 4; j++) | |||||
| { | |||||
| T tmp = 0; | |||||
| for (int k = 0; k < 4; k++) | |||||
| tmp += (*this)[k][j] * m[k]; | |||||
| ret[j] = tmp; | |||||
| } | |||||
| return ret; | |||||
| } | |||||
| vec<4,T> v0, v1, v2, v3; | |||||
| static const matrix<4,4,T> identity; | |||||
| }; | |||||
| template<typename T> T determinant(matrix<2,2,T> const &); | |||||
| template<typename T> T determinant(matrix<3,3,T> const &); | |||||
| template<typename T> T determinant(matrix<4,4,T> const &); | |||||
| template<typename T> matrix<2,2,T> transpose(matrix<2,2,T> const &); | |||||
| template<typename T> matrix<3,3,T> transpose(matrix<3,3,T> const &); | |||||
| template<typename T> matrix<4,4,T> transpose(matrix<4,4,T> const &); | |||||
| template<typename T> matrix<2,2,T> inverse(matrix<2,2,T> const &); | |||||
| template<typename T> matrix<3,3,T> inverse(matrix<3,3,T> const &); | |||||
| template<typename T> matrix<4,4,T> inverse(matrix<4,4,T> const &); | |||||
| #if !LOL_FEATURE_CXX11_CONSTEXPR | #if !LOL_FEATURE_CXX11_CONSTEXPR | ||||
| #undef constexpr | #undef constexpr | ||||
| #endif | #endif | ||||
| @@ -326,6 +326,7 @@ | |||||
| <ClInclude Include="lol\math\geometry.h" /> | <ClInclude Include="lol\math\geometry.h" /> | ||||
| <ClInclude Include="lol\math\half.h" /> | <ClInclude Include="lol\math\half.h" /> | ||||
| <ClInclude Include="lol\math\interp.h" /> | <ClInclude Include="lol\math\interp.h" /> | ||||
| <ClInclude Include="lol\math\matrix.h" /> | |||||
| <ClInclude Include="lol\math\rand.h" /> | <ClInclude Include="lol\math\rand.h" /> | ||||
| <ClInclude Include="lol\math\real.h" /> | <ClInclude Include="lol\math\real.h" /> | ||||
| <ClInclude Include="lol\math\remez.h" /> | <ClInclude Include="lol\math\remez.h" /> | ||||
| @@ -438,6 +438,9 @@ | |||||
| <ClInclude Include="lol\math\all.h"> | <ClInclude Include="lol\math\all.h"> | ||||
| <Filter>lol\math</Filter> | <Filter>lol\math</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| <ClInclude Include="lol\math\matrix.h"> | |||||
| <Filter>lol\math</Filter> | |||||
| </ClInclude> | |||||
| <ClInclude Include="lol\math\rand.h"> | <ClInclude Include="lol\math\rand.h"> | ||||
| <Filter>lol\math</Filter> | <Filter>lol\math</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||