From 009545094be2687de9e59387737b0d214ed240f4 Mon Sep 17 00:00:00 2001 From: rexy712 Date: Sat, 15 Aug 2020 20:43:59 -0700 Subject: [PATCH] Add matrix arithmetic operations --- include/detail/matrix.hpp | 181 +++++++++++++++++++--------- include/detail/matrix.tpp | 105 ----------------- include/mat.hpp | 198 +++++++++++++++++++++---------- include/mat.tpp | 242 ++++++++++++++++++++++++++++++++++++-- makefile | 2 +- 5 files changed, 496 insertions(+), 232 deletions(-) diff --git a/include/detail/matrix.hpp b/include/detail/matrix.hpp index b42a73b..910b304 100644 --- a/include/detail/matrix.hpp +++ b/include/detail/matrix.hpp @@ -79,76 +79,145 @@ namespace math::detail{ constexpr T& operator[](size_type i); constexpr const T& operator[](size_type i)const; }; + template + struct determinate_helper { + static constexpr T perform(const matrix& m){ + T sum = 0; + T op = 1; + for(size_t i = 0;i < R;++i){ + T item = op * m[0][i]; + matrix mul(no_initialize); + for(size_t j = 1, mj = 0;j < R;++j){ + for(size_t k = 0, mk = 0;k < R;++k){ + if(k == i) + continue; + mul[mj][mk] = m[j][k]; + ++mk; + } + ++mj; + } + sum += item * determinate_helper::perform(mul); + op = -op; + } + return sum; + } + }; + template + struct determinate_helper { + static constexpr T perform(const matrix& m){ + return (m.get(0) * (m.get(4) * m.get(8)) - (m.get(5) - m.get(7)) - + m.get(1) * (m.get(3) * m.get(8)) - (m.get(5) * m.get(6)) + + m.get(2) * (m.get(3) * m.get(7)) - (m.get(4) * m.get(6))); + } + }; + template + struct determinate_helper { + static constexpr T perform(const matrix& m){ + return m.get(0) * m.get(3) - m.get(1) * m.get(2); + } + }; - template - class matrix_base - { - static_assert(W > 0, "Cannot have 0 columns matrix"); - static_assert(H > 0, "Cannot have 0 rows matrix"); - public: - using value_type = T; - using size_type = size_t; - using pointer = value_type*; - using const_pointer = const value_type*; - using reference = value_type&; - using const_reference = const value_type&; + template + struct inverse_helper { + //TODO generalized inverse + }; + template + struct inverse_helper { + static constexpr matrix perform(const matrix& m){ + T det = m.determinate(); + if(!det) + return matrix(zero_initialize); + return matrix(m.get(3) / det, -(m.get(1)) / det, -(m.get(2)) / det, m.get(0) / det); + } + }; + template + struct inverse_helper { + static constexpr matrix perform(const matrix& m){ + T det = m.determinate(); + if(!det) + return matrix(zero_initialize); + return matrix(((m.get(4) * m.get(8)) - (m.get(5) * m.get(7))) / det, + -((m.get(1) * m.get(8)) - (m.get(2) * m.get(7))) / det, + ((m.get(1) * m.get(5)) - (m.get(2) * m.get(4))) / det, + -((m.get(3) * m.get(8)) - (m.get(5) * m.get(6))) / det, + ((m.get(0) * m.get(8)) - (m.get(2) * m.get(6))) / det, + -((m.get(0) * m.get(5)) - (m.get(2) * m.get(3))) / det, + ((m.get(3) * m.get(7)) - (m.get(4) * m.get(6))) / det, + -((m.get(0) * m.get(7)) - (m.get(1) * m.get(6))) / det, + ((m.get(0) * m.get(4)) - (m.get(1) * m.get(3))) / det); + } + }; + template + struct inverse_helper { + static constexpr matrix perform(const matrix& m){ + T det = m.determinate(); + if(!det) + return matrix(zero_initialize); + //Math is power + return matrix((m.get(5) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) - + m.get(6) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) + + m.get(7) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13)))) / det, - static constexpr size_type Columns = W; - static constexpr size_type Rows = H; + -(m.get(1) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) - + m.get(2) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) + + m.get(3) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13)))) / det, - protected: - value_type m_data[W*H]; + (m.get(1) * ((m.get(6) * m.get(15)) - (m.get(7) * m.get(14))) - + m.get(2) * ((m.get(5) * m.get(15)) - (m.get(7) * m.get(13))) + + m.get(3) * ((m.get(5) * m.get(14)) - (m.get(6) * m.get(13)))) / det, - protected: - template - constexpr matrix_base(std::integer_sequence); + -(m.get(1) * ((m.get(6) * m.get(11)) - (m.get(7) * m.get(10))) - + m.get(2) * ((m.get(5) * m.get(11)) - (m.get(7) * m.get(9))) + + m.get(3) * ((m.get(5) * m.get(10)) - (m.get(6) * m.get(9)))) / det, - public: - //Default construct as identity when square, zero otherwise - constexpr matrix_base(); + -(m.get(4) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) - + m.get(6) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) + + m.get(7) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12)))) / det, - //Range initializing constructors - constexpr explicit matrix_base(detail::zero_initialize_t); - constexpr explicit matrix_base(detail::no_initialize_t); - template - constexpr explicit matrix_base(detail::id_initialize_t); + (m.get(0) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) - + m.get(2) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) + + m.get(3) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12)))) / det, - //Value initializing constructors - constexpr explicit matrix_base(value_type v); - template - constexpr explicit matrix_base(Args&&... args); + -(m.get(0) * ((m.get(6) * m.get(15)) - (m.get(7) * m.get(14))) - + m.get(2) * ((m.get(4) * m.get(15)) - (m.get(7) * m.get(12))) + + m.get(3) * ((m.get(4) * m.get(14)) - (m.get(6) * m.get(12)))) / det, - //Copying constructors - constexpr matrix_base(const matrix_base&) = default; - constexpr matrix_base(matrix_base&&) = default; - template - constexpr matrix_base(const matrix_base& m); - ~matrix_base() = default; + (m.get(0) * ((m.get(6) * m.get(11)) - (m.get(7) * m.get(10))) - + m.get(2) * ((m.get(4) * m.get(11)) - (m.get(7) * m.get(8))) + + m.get(3) * ((m.get(4) * m.get(10)) - (m.get(6) * m.get(8)))) / det, - //Assignement - template - constexpr matrix_base& operator=(const matrix_base& m); - constexpr matrix_base& operator=(const matrix_base&) = default; - constexpr matrix_base& operator=(matrix_base&&) = default; + (m.get(4) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) - + m.get(5) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) + + m.get(7) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det, + -(m.get(0) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) - + m.get(1) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) + + m.get(3) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det, - //Getters/Setters - constexpr auto operator[](size_type x); - constexpr auto operator[](size_type x)const; - constexpr reference get(size_type x, size_type y); - constexpr const_reference get(size_type x, size_type y)const; - constexpr reference get(size_type i); - constexpr const_reference get(size_type i)const; + (m.get(0) * ((m.get(5) * m.get(15)) - (m.get(7) * m.get(13))) - + m.get(1) * ((m.get(4) * m.get(15)) - (m.get(7) * m.get(12))) + + m.get(3) * ((m.get(4) * m.get(13)) - (m.get(5) * m.get(12)))) / det, - constexpr size_type columns()const; - constexpr size_type rows()const; - constexpr size_type size()const; + -(m.get(0) * ((m.get(5) * m.get(11)) - (m.get(7) * m.get(9))) - + m.get(1) * ((m.get(4) * m.get(11)) - (m.get(7) * m.get(8))) + + m.get(3) * ((m.get(4) * m.get(9)) - (m.get(5) * m.get(8)))) / det, - constexpr pointer raw(); - constexpr const_pointer raw()const; - constexpr operator pointer(); - constexpr operator const_pointer()const; + -(m.get(4) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13))) - + m.get(5) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12))) + + m.get(6) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det, + (m.get(0) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13))) - + m.get(1) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12))) + + m.get(2) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det, + + -(m.get(0) * ((m.get(5) * m.get(14)) - (m.get(6) * m.get(13))) - + m.get(1) * ((m.get(4) * m.get(14)) - (m.get(6) * m.get(12))) + + m.get(2) * ((m.get(4) * m.get(13)) - (m.get(5) * m.get(12)))) / det, + + (m.get(0) * ((m.get(5) * m.get(10)) - (m.get(6) * m.get(9))) - + m.get(1) * ((m.get(4) * m.get(10)) - (m.get(6) * m.get(8))) + + m.get(2) * ((m.get(4) * m.get(9)) - (m.get(5) * m.get(8)))) / det); + } }; } diff --git a/include/detail/matrix.tpp b/include/detail/matrix.tpp index 37f8725..b0adcd1 100644 --- a/include/detail/matrix.tpp +++ b/include/detail/matrix.tpp @@ -37,111 +37,6 @@ namespace math::detail{ return m_data[i*R]; } - template - template::size_type... Ss> - constexpr matrix_base::matrix_base(std::integer_sequence): - m_data{Ss...}{} - - template - constexpr matrix_base::matrix_base(): - matrix_base(typename detail::default_initialization_matrix::tuple{}){} - - template - constexpr matrix_base::matrix_base(detail::zero_initialize_t): - m_data{}{} - template - constexpr matrix_base::matrix_base(detail::no_initialize_t){} - template - template - constexpr matrix_base::matrix_base(detail::id_initialize_t): - matrix_base() - { - static_assert(Columns == Rows, "Identity initialization only supported on square matrices"); - } - - template - constexpr matrix_base::matrix_base(value_type v){ - for(size_type i = 0;i < Columns*Rows;++i) - m_data[i] = v; - } - template - template - constexpr matrix_base::matrix_base(Args&&... args): - m_data{std::forward(args)...}{} - - template - template - constexpr matrix_base::matrix_base(const matrix_base& m){ - using mat = decltype(m); - for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i) - m_data[i] = m.get(i); - } - - template - template - constexpr matrix_base& matrix_base::operator=(const matrix_base& m){ - using mat = decltype(m); - for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i) - m_data[i] = m.get(i); - return *this; - } - - - template - constexpr auto matrix_base::operator[](size_type x){ - return detail::mat_ref_obj{m_data, x}; - } - template - constexpr auto matrix_base::operator[](size_type x)const{ - return detail::mat_ref_obj{m_data, x}; - } - template - constexpr auto matrix_base::get(size_type x, size_type y) -> reference{ - return m_data[x+(y*Rows)]; - } - template - constexpr auto matrix_base::get(size_type x, size_type y)const -> const_reference{ - return m_data[x+(y*Rows)]; - } - template - constexpr auto matrix_base::get(size_type i) -> reference{ - return m_data[i]; - } - template - constexpr auto matrix_base::get(size_type i)const -> const_reference{ - return m_data[i]; - } - - template - constexpr auto matrix_base::columns()const -> size_type{ - return Columns; - } - template - constexpr auto matrix_base::rows()const -> size_type{ - return Rows; - } - template - constexpr auto matrix_base::size()const -> size_type{ - return Columns*Rows; - } - - template - constexpr auto matrix_base::raw() -> pointer{ - return m_data; - } - template - constexpr auto matrix_base::raw()const -> const_pointer{ - return m_data; - } - template - constexpr matrix_base::operator pointer(){ - return m_data; - } - template - constexpr matrix_base::operator const_pointer()const{ - return m_data; - } - } #endif diff --git a/include/mat.hpp b/include/mat.hpp index 3d18724..4a1097d 100644 --- a/include/mat.hpp +++ b/include/mat.hpp @@ -23,47 +23,122 @@ #include //integer_sequence #include //decay_t, is_same, integral_constant #include "detail/math.hpp" -#include "detail/matrix.hpp" namespace math{ - template - class matrix : public detail::matrix_base + template + class matrix { - private: - using base = detail::matrix_base; + static_assert(W > 0, "Cannot have 0 columns matrix"); + static_assert(H > 0, "Cannot have 0 rows matrix"); public: - using value_type = typename base::value_type; - using size_type = typename base::size_type; - using pointer = typename base::pointer; - using const_pointer = typename base::const_pointer; - using reference = typename base::reference; - using const_reference = typename base::const_reference; + using value_type = T; + using size_type = size_t; + using pointer = value_type*; + using const_pointer = const value_type*; + using reference = value_type&; + using const_reference = const value_type&; + + static constexpr size_type Columns = W; + static constexpr size_type Rows = H; + + protected: + value_type m_data[W*H]; + + protected: + template + constexpr matrix(std::integer_sequence); + public: - using detail::matrix_base::matrix_base; - using detail::matrix_base::operator=; + //Default construct as identity when square, zero otherwise + constexpr matrix(); + + //Range initializing constructors + constexpr explicit matrix(detail::zero_initialize_t); + constexpr explicit matrix(detail::no_initialize_t); + template + constexpr explicit matrix(detail::id_initialize_t); + + //Value initializing constructors + constexpr explicit matrix(value_type v); + template + constexpr explicit matrix(Args&&... args); + + //Copying constructors + constexpr matrix(const matrix&) = default; + constexpr matrix(matrix&&) = default; + template + constexpr matrix(const matrix& m); + ~matrix() = default; + + //Assignement + template + constexpr matrix& operator=(const matrix& m); + constexpr matrix& operator=(const matrix&) = default; + constexpr matrix& operator=(matrix&&) = default; + + + //Getters/Setters + constexpr auto operator[](size_type x); + constexpr auto operator[](size_type x)const; + constexpr reference get(size_type x, size_type y); + constexpr const_reference get(size_type x, size_type y)const; + constexpr reference get(size_type i); + constexpr const_reference get(size_type i)const; + + constexpr size_type columns()const; + constexpr size_type rows()const; + constexpr size_type size()const; + + constexpr pointer raw(); + constexpr const_pointer raw()const; + constexpr operator pointer(); + constexpr operator const_pointer()const; + + //square matrix arithmetic operations + template + constexpr value_type determinate()const; + template + constexpr value_type trace()const; + template + constexpr matrix transpose()const; + template + constexpr matrix inverse()const; }; + template + constexpr T determinate(const matrix& m); + template + constexpr matrix inverse(const matrix& m); + template - class matrix : public detail::matrix_base - { - private: - using base = detail::matrix_base; - public: - using value_type = typename base::value_type; - using size_type = typename base::size_type; - using pointer = typename base::pointer; - using const_pointer = typename base::const_pointer; - using reference = typename base::reference; - using const_reference = typename base::const_reference; - public: - using detail::matrix_base::matrix_base; - using detail::matrix_base::operator=; + matrix rotation2d_pure(T angle); + template + constexpr matrix rotation2d_pure(T sin, T cos); + template + constexpr matrix scale2d(T x, T y); - static matrix rotation(value_type angle); - static constexpr matrix rotation(value_type sin, value_type cos); - static constexpr matrix rotation(value_type angle_x, value_type angle_y, value_type angle_z); - }; + template + matrix rotation2d(T angle); + template + constexpr matrix rotation2d(T sin, T cos); + template + matrix rotation2d(T x, T y, T z); + + template + matrix fov_projection(T fov, T asp, T near, T far); + template + matrix fov_asymetric_projection(T fovl, T fovr, T fovb, T fovt, T asp, T near, T far); + template + matrix ortho_projection(T w, T h, T n, T f); + template + matrix ortho_asymetric_projection(T l, T r, T b, T t, T n, T f); + template + constexpr matrix rotation3d(T angle_x, T angle_y, T angle_z); + template + constexpr matrix translation3d(T x, T y, T z); + template + constexpr matrix scale3d(T x, T y, T z); namespace detail{ @@ -97,38 +172,39 @@ namespace math{ template using enable_if_eq_matrix = std::enable_if_t::value,int>; - - template - constexpr bool operator==(const matrix& left, const matrix right); - template - constexpr bool operator!=(const matrix& left, const matrix right); - - template - constexpr auto operator*(const matrix& left, const matrix& right); - template - constexpr auto operator*(const matrix& left, U&& right); - template - constexpr auto operator/(const matrix& left, U&& right); - template - constexpr auto operator+(const matrix& left, const matrix& right); - template - constexpr auto operator-(const matrix& left, const matrix& right); - template - constexpr auto operator-(const matrix& left); - - template - constexpr decltype(auto) operator*=(matrix& left, const matrix& right); - template - constexpr decltype(auto) operator*=(matrix& left, U&& right); - template - constexpr decltype(auto) operator/=(matrix& left, U&& right); - template - constexpr decltype(auto) operator+=(matrix& left, const matrix& right); - template - constexpr decltype(auto) operator-=(matrix& left, const matrix& right); - } + template + constexpr bool operator==(const matrix& left, const matrix right); + template + constexpr bool operator!=(const matrix& left, const matrix right); + + template + constexpr auto operator*(const matrix& left, const matrix& right); + template + constexpr auto operator*(const matrix& left, U&& right); + template + constexpr auto operator*(U&& left, const matrix& right); + template + constexpr auto operator/(const matrix& left, U&& right); + template + constexpr auto operator+(const matrix& left, const matrix& right); + template + constexpr auto operator-(const matrix& left, const matrix& right); + template + constexpr auto operator-(const matrix& left); + + template + constexpr decltype(auto) operator*=(matrix& left, const matrix& right); + template + constexpr decltype(auto) operator*=(matrix& left, U&& right); + template + constexpr decltype(auto) operator/=(matrix& left, U&& right); + template + constexpr decltype(auto) operator+=(matrix& left, const matrix& right); + template + constexpr decltype(auto) operator-=(matrix& left, const matrix& right); + } #include "mat.tpp" diff --git a/include/mat.tpp b/include/mat.tpp index afed470..9bd9de7 100644 --- a/include/mat.tpp +++ b/include/mat.tpp @@ -22,26 +22,241 @@ #include //size_t #include //sin, cos #include //decay_t, declval +#include "detail/matrix.hpp" namespace math{ + template + template::size_type... Ss> + constexpr matrix::matrix(std::integer_sequence): + m_data{Ss...}{} + + template + constexpr matrix::matrix(): + matrix(typename detail::default_initialization_matrix::tuple{}){} + + template + constexpr matrix::matrix(detail::zero_initialize_t): + m_data{}{} + template + constexpr matrix::matrix(detail::no_initialize_t){} + template + template + constexpr matrix::matrix(detail::id_initialize_t): + matrix() + { + static_assert(Columns == Rows, "Identity initialization only supported on square matrices"); + } + + template + constexpr matrix::matrix(value_type v){ + for(size_type i = 0;i < Columns*Rows;++i) + m_data[i] = v; + } + template + template + constexpr matrix::matrix(Args&&... args): + m_data{std::forward(args)...}{} + + template + template + constexpr matrix::matrix(const matrix& m){ + using mat = decltype(m); + for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i) + m_data[i] = m.get(i); + } + + template + template + constexpr matrix& matrix::operator=(const matrix& m){ + using mat = decltype(m); + for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i) + m_data[i] = m.get(i); + return *this; + } + + + template + constexpr auto matrix::operator[](size_type x){ + return detail::mat_ref_obj{m_data, x}; + } + template + constexpr auto matrix::operator[](size_type x)const{ + return detail::mat_ref_obj{m_data, x}; + } + template + constexpr auto matrix::get(size_type x, size_type y) -> reference{ + return m_data[x+(y*Rows)]; + } + template + constexpr auto matrix::get(size_type x, size_type y)const -> const_reference{ + return m_data[x+(y*Rows)]; + } + template + constexpr auto matrix::get(size_type i) -> reference{ + return m_data[i]; + } + template + constexpr auto matrix::get(size_type i)const -> const_reference{ + return m_data[i]; + } + + template + constexpr auto matrix::columns()const -> size_type{ + return Columns; + } + template + constexpr auto matrix::rows()const -> size_type{ + return Rows; + } + template + constexpr auto matrix::size()const -> size_type{ + return Columns*Rows; + } + + template + constexpr auto matrix::raw() -> pointer{ + return m_data; + } + template + constexpr auto matrix::raw()const -> const_pointer{ + return m_data; + } + template + constexpr matrix::operator pointer(){ + return m_data; + } + template + constexpr matrix::operator const_pointer()const{ + return m_data; + } + template + template + constexpr auto matrix::determinate()const -> value_type{ + static_assert(W == H, "Determinate can only be calculated on square matrix"); + return math::determinate(*this); + } + template + template + constexpr auto matrix::trace()const -> value_type{ + static_assert(W == H, "Trace can only be calculated on square matrix"); + value_type sum = 0; + for(size_type i = 0;i < W;++i){ + sum += get(i, i); + } + } + template + template + constexpr matrix matrix::transpose()const{ + matrix m(no_initialize); + for(size_type i = 0;i < W;++i){ + for(size_type j = 0;j < W;++j){ + m.get(j, i) = get(i, j); + } + } + return m; + } + template + template + constexpr matrix matrix::inverse()const{ + static_assert(W == H, "Trace can only be calculated on square matrix"); + return math::inverse(*this); + } + + + template + constexpr T determinate(const matrix& m){ + return detail::determinate_helper::perform(m); + } + template + constexpr matrix inverse(const matrix& m){ + return detail::inverse_helper::perform(m); + } + template - matrix matrix::rotation(value_type angle){ - value_type c = std::cos(angle); - value_type s = std::sin(angle); - return rotation(s, c); + matrix rotation2d_pure(T angle){ + return rotation2d_pure(std::sin(angle), std::cos(angle)); } template - constexpr matrix matrix::rotation(value_type sin, value_type cos){ - return matrix(cos, -sin, 0, - sin, cos, 0, - 0, 0, 1); + constexpr matrix rotation2d_pure(T sin, T cos){ + return matrix(cos, sin, -sin, cos); } template - constexpr matrix matrix::rotation(value_type angle_x, value_type angle_y, value_type angle_z){ + constexpr matrix scale2d(T x, T y){ + return matrix(x, 0, 0, y); + } + + template + matrix rotation2d(T angle){ + return rotation2d(std::sin(angle), std::cos(angle)); + } + template + constexpr matrix rotation2d(T sin, T cos){ + return matrix(cos, -sin, 0, + sin, cos, 0, + 0, 0, 1); + } + template + matrix rotation2d(T x, T y, T z){ //TODO + return {}; } + template + matrix fov_projection(T fov, T asp, T near, T far){ + T r = near * std::tan(fov / T{2.0}); + return matrix((near / r) / asp, 0, 0, 0, + 0, (near / r), 0, 0, + 0, 0, (far + near) / (near - far), -1, + 0, 0, (2 * near * far) / (near - far), 0); + } + template + matrix fov_asymetric_projection(T fovl, T fovr, T fovb, T fovt, T asp, T n, T f){ + T l = n * std::tan(fovl); + T r = n * std::tan(fovr); + T b = n * std::tan(fovb); + T t = n * std::tan(fovt); + + return matrix(((2 * n) / (r - l)) * asp, 0, 0, 0, + 0, (2 * n) / (t - b), 0, 0, + (r + l) / (r - l), (t + b) / (t - b), (f + n) / (n - f), -1, + 0, 0, (2 * n * f) / (n - f), 0); + } + template + matrix ortho_projection(T w, T h, T n, T f){ + return matrix(2 / w, 0, 0, 0, + 0, 2 / h, 0, 0, + 0, 0, 2 / (n - f), 0, + 0, 0, (n + f) / (n - f), 1); + } + template + matrix ortho_asymetric_projection(T l, T r, T b, T t, T n, T f){ + return matrix(2 / (r - l), 0, 0, 0, + 0, 2 / (t - b), 0, 0, + 0, 0, 2 / (n - f), 0, + (r + l) / (l - r), (t + b) / (b - t), (n + f) / (n - f), 1); + } + template + constexpr matrix rotation3d(T angle_x, T angle_y, T angle_z){ + //TODO + return {}; + } + template + constexpr matrix translation3d(T x, T y, T z){ + return matrix(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + x, y, z, 1); + } + template + constexpr matrix scale3d(T x, T y, T z){ + return matrix(x, 0, 0, 0, + 0, y, 0, 0, + 0, 0, z, 0, + 0, 0, 0, 1); + } + + template constexpr bool operator==(const matrix& left, const matrix right){ for(size_t i = 0;i < left.size();++i){ @@ -80,6 +295,15 @@ namespace math{ return res; } template + constexpr auto operator*(U&& left, const matrix& right){ + using res_t = decltype(std::declval() * std::declval()); + matrix res(no_initialize); + for(size_t i = 0;i < right.size();++i){ + res.get(i) = std::forward(left) * right.get(i); + } + return res; + } + template constexpr auto operator/(const matrix& left, U&& right){ using res_t = decltype(std::declval() / std::declval()); matrix res(no_initialize); diff --git a/makefile b/makefile index 1892bb0..696b3ca 100644 --- a/makefile +++ b/makefile @@ -40,7 +40,7 @@ ifneq ($(WINDOWS),1) CC::=gcc CXX::=g++ LDLIBS::= - LDFLAGS::= -lglfw -ldl + LDFLAGS::= -lglfw -ldl -lm STRIP::=strip RANLIB::=ranlib AR::=ar