diff --git a/include/detail/math.hpp b/include/detail/math.hpp deleted file mode 100644 index f5997bf..0000000 --- a/include/detail/math.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/** - This file is a part of the rexy/r0nk/atlas project - Copyright (C) 2020 rexy712 - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef REXY_DETAIL_MATH_HPP -#define REXY_DETAIL_MATH_HPP - -namespace math{ - - namespace detail{ - struct zero_initialize_t{}; - struct no_initialize_t{}; - struct id_initialize_t{}; - - } - - static inline constexpr detail::zero_initialize_t zero_initialize; - static inline constexpr detail::no_initialize_t no_initialize; - static inline constexpr detail::id_initialize_t id_initialize; - -} - -#endif diff --git a/include/detail/matrix.hpp b/include/detail/matrix.hpp deleted file mode 100644 index 419aa29..0000000 --- a/include/detail/matrix.hpp +++ /dev/null @@ -1,227 +0,0 @@ -/** - This file is a part of the rexy/r0nk/atlas project - Copyright (C) 2020 rexy712 - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef REXY_DETAIL_MATRIX_HPP -#define REXY_DETAIL_MATRIX_HPP - -#include //size_t -#include //integer_sequence - -namespace math::detail{ - - template - struct gen_id_tup { - using tup = typename gen_id_tup::tup; - }; - template - struct gen_id_tup { - using tup = typename gen_id_tup::tup; - }; - template - struct gen_id_tup { - using tup = typename gen_id_tup::tup; - }; - template - struct gen_id_tup { - using tup = std::integer_sequence; - }; - - - template - struct gen_zero_tup { - using tup = typename gen_zero_tup::tup; - }; - template - struct gen_zero_tup<0,Args...> { - using tup = std::integer_sequence; - }; - - template - struct id_initialization_matrix { - using tuple = typename gen_id_tup::tup; - }; - - - template - struct default_initialization_matrix { - using tuple = typename gen_zero_tup::tup; - }; - template - struct default_initialization_matrix { - using tuple = typename id_initialization_matrix::tuple; - }; - - template - class mat_ref_obj - { - public: - using size_type = size_t; - - protected: - T* m_data = nullptr; - public: - constexpr mat_ref_obj(T* d, size_type i); - 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 - 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, - - -(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, - - (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, - - -(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, - - -(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, - - (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, - - -(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, - - (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, - - (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, - - (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, - - -(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, - - -(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); - } - }; - -} - -#include "matrix.tpp" - -#endif diff --git a/include/detail/matrix.tpp b/include/detail/matrix.tpp deleted file mode 100644 index b0adcd1..0000000 --- a/include/detail/matrix.tpp +++ /dev/null @@ -1,42 +0,0 @@ -/** - This file is a part of the rexy/r0nk/atlas project - Copyright (C) 2020 rexy712 - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef REXY_DETAIL_MATRIX_TPP -#define REXY_DETAIL_MATRIX_TPP - -#include //size_t -#include //integer_sequence - -namespace math::detail{ - - template - constexpr mat_ref_obj::mat_ref_obj(T* d, size_type i): - m_data(d+i){} - - template - constexpr T& mat_ref_obj::operator[](size_type i){ - return m_data[i*R]; - } - template - constexpr const T& mat_ref_obj::operator[](size_type i)const{ - return m_data[i*R]; - } - -} - -#endif diff --git a/include/math/detail/matrix.hpp b/include/math/detail/matrix.hpp new file mode 100644 index 0000000..06d74a4 --- /dev/null +++ b/include/math/detail/matrix.hpp @@ -0,0 +1,116 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef REXY_DETAIL_MATRIX_HPP +#define REXY_DETAIL_MATRIX_HPP + +#include //size_t +#include //integer_sequence + +namespace math::detail{ + + template + struct gen_id_tup { + using tup = typename gen_id_tup::tup; + }; + template + struct gen_id_tup { + using tup = typename gen_id_tup::tup; + }; + template + struct gen_id_tup { + using tup = typename gen_id_tup::tup; + }; + template + struct gen_id_tup { + using tup = std::integer_sequence; + }; + + + template + struct gen_zero_tup { + using tup = typename gen_zero_tup::tup; + }; + template + struct gen_zero_tup<0,Args...> { + using tup = std::integer_sequence; + }; + + template + struct id_initialization_matrix { + using tuple = typename gen_id_tup::tup; + }; + + + template + struct default_initialization_matrix { + using tuple = typename gen_zero_tup::tup; + }; + template + struct default_initialization_matrix { + using tuple = typename id_initialization_matrix::tuple; + }; + + template + class mat_ref_obj + { + public: + using size_type = size_t; + + protected: + T* m_data = nullptr; + public: + constexpr mat_ref_obj(T* d, size_type i); + 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); + }; + template + struct determinate_helper { + static constexpr T perform(const matrix& m); + }; + template + struct determinate_helper { + static constexpr T perform(const matrix& m); + }; + + template + struct inverse_helper { + //TODO generalized inverse + }; + template + struct inverse_helper { + static constexpr matrix perform(const matrix& m); + }; + template + struct inverse_helper { + static constexpr matrix perform(const matrix& m); + }; + template + struct inverse_helper { + static constexpr matrix perform(const matrix& m); + }; + +} + +#include "matrix.tpp" + +#endif diff --git a/include/math/detail/matrix.tpp b/include/math/detail/matrix.tpp new file mode 100644 index 0000000..6a5358c --- /dev/null +++ b/include/math/detail/matrix.tpp @@ -0,0 +1,166 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef REXY_DETAIL_MATRIX_TPP +#define REXY_DETAIL_MATRIX_TPP + +#include //size_t +#include //integer_sequence + +namespace math::detail{ + + template + constexpr mat_ref_obj::mat_ref_obj(T* d, size_type i): + m_data(d+i){} + + template + constexpr T& mat_ref_obj::operator[](size_type i){ + return m_data[i*R]; + } + template + constexpr const T& mat_ref_obj::operator[](size_type i)const{ + return m_data[i*R]; + } + template + constexpr T determinate_helper::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 + constexpr T determinate_helper::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 + constexpr T determinate_helper::perform(const matrix& m){ + return m.get(0) * m.get(3) - m.get(1) * m.get(2); + } + + template + constexpr matrix inverse_helper::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 + constexpr matrix inverse_helper::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 + constexpr matrix inverse_helper::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, + + -(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, + + (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, + + -(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, + + -(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, + + (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, + + -(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, + + (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, + + (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, + + (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, + + -(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, + + -(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); + } + +} + +#endif diff --git a/include/math/fwd_declare.hpp b/include/math/fwd_declare.hpp new file mode 100644 index 0000000..c40115e --- /dev/null +++ b/include/math/fwd_declare.hpp @@ -0,0 +1,49 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef REXY_MATH_FWD_DECLARE_HPP +#define REXY_MATH_FWD_DECLARE_HPP + +#include //size_t + +namespace math{ + + template + class matrix; + template + class vector; + template + class quaternion; + + template + using mat2 = matrix; + template + using mat3 = matrix; + template + using mat4 = matrix; + + template + using vec2 = vector; + template + using vec3 = vector; + template + using vec4 = vector; + +} + +#endif diff --git a/include/mat.hpp b/include/math/mat.hpp similarity index 90% rename from include/mat.hpp rename to include/math/mat.hpp index d9c03e1..ef4117f 100644 --- a/include/mat.hpp +++ b/include/math/mat.hpp @@ -1,19 +1,19 @@ /** - This file is a part of the rexy/r0nk/atlas project + This file is a part of our_dick Copyright (C) 2020 rexy712 This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by + it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ #ifndef REXY_MAT_HPP @@ -22,7 +22,8 @@ #include //size_t #include //integer_sequence #include //decay_t, is_same, integral_constant -#include "detail/math.hpp" +#include "math_common.hpp" +#include "fwd_declare.hpp" namespace math{ @@ -228,11 +229,11 @@ namespace math{ template constexpr auto operator*(const matrix& left, const matrix& right); - template::value,int> = 0> + template>,int> = 0> constexpr auto operator*(const matrix& left, U&& right); - template::value,int> = 0> + template>,int> = 0> constexpr auto operator*(U&& left, const matrix& right); - template::value,int> = 0> + template>,int> = 0> constexpr auto operator/(const matrix& left, U&& right); template constexpr auto operator+(const matrix& left, const matrix& right); @@ -243,15 +244,23 @@ namespace math{ template constexpr decltype(auto) operator*=(matrix& left, const matrix& right); - template::value,int> = 0> + template>,int> = 0> constexpr decltype(auto) operator*=(matrix& left, U&& right); - template::value,int> = 0> + template>,int> = 0> 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 + using mat2 = matrix; + template + using mat3 = matrix; + template + using mat4 = matrix; + } #include "mat.tpp" diff --git a/include/mat.tpp b/include/math/mat.tpp similarity index 96% rename from include/mat.tpp rename to include/math/mat.tpp index 733e409..60a74e5 100644 --- a/include/mat.tpp +++ b/include/math/mat.tpp @@ -1,19 +1,19 @@ /** - This file is a part of the rexy/r0nk/atlas project + This file is a part of our_dick Copyright (C) 2020 rexy712 This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by + it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ #ifndef REXY_MAT_TPP @@ -23,6 +23,7 @@ #include //sin, cos #include //decay_t, declval #include "detail/matrix.hpp" +#include "quat.hpp" namespace math{ @@ -202,8 +203,8 @@ namespace math{ } template matrix rotation2d(T x, T y, T z){ - //TODO - return {}; + quaternion q(x, y, z); + return q.to_mat3(); } template @@ -242,8 +243,8 @@ namespace math{ } template constexpr matrix rotation3d(T angle_x, T angle_y, T angle_z){ - //TODO - return {}; + quaternion q(angle_x, angle_y, angle_z); + return q.to_mat4(); } template constexpr matrix translation3d(T x, T y, T z){ diff --git a/include/math/math.hpp b/include/math/math.hpp new file mode 100644 index 0000000..2277b3e --- /dev/null +++ b/include/math/math.hpp @@ -0,0 +1,27 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef REXY_MATH_HPP +#define REXY_MATH_HPP + +#include "math_common.hpp" +#include "vec.hpp" +#include "mat.hpp" +#include "quat.hpp" + +#endif diff --git a/include/math/math_common.hpp b/include/math/math_common.hpp new file mode 100644 index 0000000..2d6bd6e --- /dev/null +++ b/include/math/math_common.hpp @@ -0,0 +1,58 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef REXY_DETAIL_MATH_HPP +#define REXY_DETAIL_MATH_HPP + +namespace math{ + + namespace detail{ + struct zero_initialize_t{}; + struct no_initialize_t{}; + struct id_initialize_t{}; + struct manual_initialize_t{}; + } + + static inline constexpr detail::zero_initialize_t zero_initialize; + static inline constexpr detail::no_initialize_t no_initialize; + static inline constexpr detail::id_initialize_t id_initialize; + static inline constexpr detail::manual_initialize_t manual_initialize; + + template + static constexpr T pi(){ + return static_cast(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821); + } + template + static constexpr T to_degrees(T t){ + return (t * 180.0) / pi(); + } + template + static constexpr T to_radians(T t){ + return (t * pi()) / 180.0; + } + + constexpr long double operator"" _rad(long double f){ + return f; + } + constexpr long double operator"" _deg(long double f){ + return to_radians(f); + } + +} + +#endif diff --git a/include/math/quat.hpp b/include/math/quat.hpp new file mode 100644 index 0000000..28e9259 --- /dev/null +++ b/include/math/quat.hpp @@ -0,0 +1,160 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef REXY_QUAT_HPP +#define REXY_QUAT_HPP + +#include //size_t +#include //pair +#include //is_same, is_arithmetic, integral_constant + +#include "math_common.hpp" +#include "fwd_declare.hpp" + +namespace math{ + + template + class quaternion + { + 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&; + + private: + value_type m_data[4]; + + public: + constexpr quaternion(); + //Construct from Euler angles + constexpr quaternion(detail::zero_initialize_t); + constexpr quaternion(detail::id_initialize_t); + constexpr quaternion(detail::no_initialize_t); + constexpr quaternion(detail::manual_initialize_t, + value_type w, value_type x, + value_type y, value_type z); + quaternion(value_type bank, value_type heading, value_type attitude); + quaternion(const vec3& angles); + //Construct from axis-angle + quaternion(value_type angle, const vec3& axis); + quaternion(value_type angle, value_type x, value_type y, value_type z); + //Copy ctor + constexpr quaternion(const quaternion&) = default; + constexpr quaternion(quaternion&&) = default; + ~quaternion() = default; + + //Assignment + constexpr quaternion& operator=(const quaternion&) = default; + constexpr quaternion& operator=(quaternion&&) = default; + + //Direct array access + constexpr operator pointer(); + constexpr operator const_pointer()const; + constexpr reference operator[](size_type i); + constexpr const_reference operator[](size_type i)const; + constexpr reference get(size_type i); + constexpr const_reference get(size_type i)const; + + constexpr reference w(); + constexpr const_reference w()const; + constexpr reference x(); + constexpr const_reference x()const; + constexpr reference y(); + constexpr const_reference y()const; + constexpr reference z(); + constexpr const_reference z()const; + + //Assign axis from angle-axis + void set_axis(value_type x, value_type y, value_type z); + void set_axis(const vec3& axis); + vec3 get_axis()const; + + void set_angle(value_type a); + value_type get_angle()const; + value_type norm()const; + quaternion conjugate()const; + quaternion inverse()const; + value_type magnitude()const; + quaternion normalize()const; + + vec3 get_right()const; + vec3 get_up()const; + vec3 get_forward()const; + + //Explicit Conversion1 + vec3 to_vec3()const; + vec4 to_vec4()const; + mat3 to_mat3()const; + mat4 to_mat4()const; + vec3 to_euler_angles()const; + std::pair> to_axis_angle()const; + }; + + namespace detail{ + + template + struct is_quat_helper { + template + static std::true_type test(quaternion*); + static std::false_type test(void*); + static constexpr bool value = std::is_same*>(nullptr)))>::value; + }; + } + template + struct is_quaternion { + static constexpr bool value = (detail::is_quat_helper::value && ...); + }; + + template + bool operator==(const quaternion& left, const quaternion& right); + template + bool operator!=(const quaternion& left, const quaternion& right); + template + auto operator-(const quaternion& left); + template + auto operator-(const quaternion& left, const quaternion& right); + template + auto operator+(const quaternion& left, const quaternion& right); + template + auto operator*(const quaternion& left, const quaternion& right); + template + auto operator*(const quaternion& left, const vec3& right); + template>,int> = 0> + auto operator*(const quaternion& left, U&& right); + template>,int> = 0> + auto operator/(const quaternion& left, U&& right); + + template + decltype(auto) operator+=(quaternion& left, const quaternion& right); + template + decltype(auto) operator-=(quaternion& left, const quaternion& right); + template + decltype(auto) operator*=(quaternion& left, const quaternion& right); + template>,int> = 0> + decltype(auto) operator*=(quaternion& left, U&& right); + template>,int> = 0> + decltype(auto) operator/=(quaternion& left, U&& right); + +} + +#include "quat.tpp" + +#endif diff --git a/include/math/quat.tpp b/include/math/quat.tpp new file mode 100644 index 0000000..f2913c7 --- /dev/null +++ b/include/math/quat.tpp @@ -0,0 +1,403 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +#ifndef REXY_QUAT_TPP +#define REXY_QUAT_TPP + +#include //sin, cos, tan, sqrt, etc +#include "mat.hpp" +#include "vec.hpp" + +namespace math{ + + template + constexpr quaternion::quaternion(): + quaternion(id_initialize){} + template + constexpr quaternion::quaternion(detail::zero_initialize_t): + m_data{0, 0, 0, 0}{} + template + constexpr quaternion::quaternion(detail::id_initialize_t): + m_data{1, 0, 0, 0}{} + template + constexpr quaternion::quaternion(detail::no_initialize_t){} + + template + constexpr quaternion::quaternion(detail::manual_initialize_t, + value_type w, value_type x, + value_type y, value_type z): + m_data{w, x, y, z}{} + + template + quaternion::quaternion(value_type bank, value_type heading, value_type attitude){ + bank /= value_type{2}; + heading /= value_type{2}; + attitude /= value_type{2}; + value_type cos_heading = std::cos(heading); + value_type sin_heading = std::sin(heading); + value_type cos_attitude = std::cos(attitude); + value_type sin_attitude = std::sin(attitude); + value_type cos_bank = std::cos(bank); + value_type sin_bank = std::sin(bank); + + m_data[0] = (cos_heading * cos_attitude * cos_bank) - (sin_heading * sin_attitude * sin_bank); + m_data[1] = (sin_heading * sin_attitude * cos_bank) + (cos_heading * cos_attitude * sin_bank); + m_data[2] = (sin_heading * cos_attitude * cos_bank) + (cos_heading * sin_attitude * sin_bank); + m_data[3] = (cos_heading * sin_attitude * cos_bank) - (sin_heading * cos_attitude * sin_bank); + } + template + quaternion::quaternion(const vec3& angles): + quaternion(angles.x(), angles.y(), angles.z()){} + template + quaternion::quaternion(value_type angle, const vec3& axis): + quaternion(angle, axis.get_x(), axis.get_y(), axis.get_z()){} + template + quaternion::quaternion(value_type angle, value_type x, value_type y, value_type z){ + angle /= value_type{2.0}; + value_type sin_angle = std::sin(angle); + m_data[0] = std::cos(angle); + m_data[1] = sin_angle * x; + m_data[2] = sin_angle * y; + m_data[3] = sin_angle * z; + } + + template + constexpr quaternion::operator pointer(void){ + return m_data; + } + template + constexpr quaternion::operator const_pointer(void)const{ + return m_data; + } + template + constexpr auto quaternion::operator[](size_type i) -> reference{ + return m_data[i]; + } + template + constexpr auto quaternion::operator[](size_type i)const -> const_reference{ + return m_data[i]; + } + template + constexpr auto quaternion::get(size_type i) -> reference{ + return m_data[i]; + } + template + constexpr auto quaternion::get(size_type i)const -> const_reference{ + return m_data[i]; + } + template + constexpr auto quaternion::w() -> reference{ + return m_data[0]; + } + template + constexpr auto quaternion::w()const -> const_reference{ + return m_data[0]; + } + template + constexpr auto quaternion::x() -> reference{ + return m_data[1]; + } + template + constexpr auto quaternion::x()const -> const_reference{ + return m_data[1]; + } + template + constexpr auto quaternion::y() -> reference{ + return m_data[2]; + } + template + constexpr auto quaternion::y()const -> const_reference{ + return m_data[2]; + } + template + constexpr auto quaternion::z() -> reference{ + return m_data[3]; + } + template + constexpr auto quaternion::z()const -> const_reference{ + return m_data[3]; + } + template + void quaternion::set_axis(value_type x, value_type y, value_type z){ + value_type sin_angle = std::sin(std::acos(m_data[0])); + m_data[1] = sin_angle * x; + m_data[2] = sin_angle * y; + m_data[3] = sin_angle * z; + } + template + void quaternion::set_axis(const vec3& v){ + set_axis(v.x(), v.y(), v.z()); + } + template + auto quaternion::get_axis()const -> vec3{ + quaternion tmp(*this); + if(m_data[0] > value_type{1.0}) + tmp.set_normalized(); + value_type s = std::sqrt(1 - tmp.m_data[0] * tmp.m_data[0]); + if(s <= value_type{0.001}) + return vec3(1, 0, 0); + return vec3(tmp.data[1] / s, tmp.data[2] / s, tmp.data[3] / s); + } + template + void quaternion::set_angle(value_type t){ + t /= value_type{2.0}; + value_type old_sin_angle = std::sin(std::acos(m_data[0])); + value_type sin_angle = std::sin(t); + m_data[0] = std::cos(t); + m_data[1] = (m_data[1] / old_sin_angle) * sin_angle; + m_data[2] = (m_data[2] / old_sin_angle) * sin_angle; + m_data[3] = (m_data[3] / old_sin_angle) * sin_angle; + } + template + auto quaternion::get_angle(void)const -> value_type{ + return 2.0 * std::acos(m_data[0]); + } + template + auto quaternion::norm(void)const -> value_type{ + return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2] + m_data[3] * m_data[3]; + } + template + quaternion quaternion::conjugate(void)const{ + return quaternion(manual_initialize, m_data[0], -m_data[1], -m_data[2], -m_data[3]); + } + template + quaternion quaternion::inverse(void)const{ + return conjugate() / norm(); + } + template + auto quaternion::magnitude(void)const -> value_type{ + return std::sqrt(norm()); + } + template + quaternion quaternion::normalize(void)const{ + value_type mag = magnitude(); + return quaternion(manual_initialize, m_data[0] / mag, m_data[1] / mag, m_data[2] / mag, m_data[3] / mag); + } + template + auto quaternion::get_right(void)const -> vec3{ + return vec3(1 - 2 * ((m_data[2] * m_data[2]) + (m_data[3] * m_data[3])), + 2 * ((m_data[1] * m_data[2]) - (m_data[3] * m_data[0])), + 2 * ((m_data[1] * m_data[3]) + (m_data[2] * m_data[0]))); + } + template + auto quaternion::get_up(void)const -> vec3{ + return vec3( 2 * ((m_data[1] * m_data[2]) + (m_data[3] * m_data[0])), + 1 - 2 * ((m_data[1] * m_data[1]) + (m_data[3] * m_data[3])), + 2 * ((m_data[2] * m_data[3]) - (m_data[1] * m_data[0]))); + } + template + auto quaternion::get_forward(void)const -> vec3{ + return vec3( 2 * ((m_data[1] * m_data[3]) - (m_data[2] * m_data[0])), + 2 * ((m_data[2] * m_data[3]) + (m_data[1] * m_data[0])), + 1 - 2 * ((m_data[1] * m_data[1]) + (m_data[2] * m_data[2]))); + } + template + auto quaternion::to_vec3(void)const -> vec3{ + return vec3(m_data[1], m_data[2], m_data[3]); + } + template + auto quaternion::to_vec4(void)const -> vec4{ + return vec4(m_data[1], m_data[2], m_data[3]); + } + template + auto quaternion::to_mat3(void)const -> mat3{ + mat3 m; + + value_type xx = m_data[1] * m_data[1]; + value_type yy = m_data[2] * m_data[2]; + value_type zz = m_data[3] * m_data[3]; + + value_type xy = m_data[1] * m_data[2]; + value_type xz = m_data[1] * m_data[3]; + value_type xw = m_data[1] * m_data[0]; + value_type yz = m_data[2] * m_data[3]; + value_type yw = m_data[2] * m_data[0]; + value_type zw = m_data[3] * m_data[0]; + + m[0] = 1 - 2 * (yy + zz); + m[1] = 2 * (xy + zw); + m[2] = 2 * (xz - yw); + m[3] = 2 * (xy - zw); + m[4] = 1 - 2 * (xx + zz); + m[5] = 2 * (yz + xw); + m[6] = 2 * (xz + yw); + m[7] = 2 * (yz - xw); + m[8] = 1 - 2 * (xx + yy); + return m; + } + template + auto quaternion::to_mat4(void)const -> mat4{ + mat4 m; + + value_type xx = m_data[1] * m_data[1]; + value_type yy = m_data[2] * m_data[2]; + value_type zz = m_data[3] * m_data[3]; + + value_type xy = m_data[1] * m_data[2]; + value_type xz = m_data[1] * m_data[3]; + value_type xw = m_data[1] * m_data[0]; + value_type yz = m_data[2] * m_data[3]; + value_type yw = m_data[2] * m_data[0]; + value_type zw = m_data[3] * m_data[0]; + + m[0] = 1 - 2 * (yy + zz); + m[1] = 2 * (xy + zw); + m[2] = 2 * (xz - yw); + m[3] = 0; + m[4] = 2 * (xy - zw); + m[5] = 1 - 2 * (xx + zz); + m[6] = 2 * (yz + xw); + m[7] = 0; + m[8] = 2 * (xz + yw); + m[9] = 2 * (yz - xw); + m[10] = 1 - 2 * (xx + yy); + m[11] = 0; + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + return m; + } + template + auto quaternion::to_euler_angles(void)const -> vec3{ + value_type ww = m_data[0] * m_data[0]; + value_type xx = m_data[1] * m_data[1]; + value_type yy = m_data[2] * m_data[2]; + value_type zz = m_data[3] * m_data[3]; + + value_type correction = ww + xx + yy + zz; + value_type test = m_data[1] * m_data[2] + m_data[3] * m_data[0]; + if(test > 0.499 * correction){ + return vec3(0, 2 * std::atan2(m_data[1], m_data[0]), pi() / 2.0); + }else if(test < -0.499 * correction){ + return vec3(0, -2 * std::atan2(m_data[1], m_data[0]), -pi() / 2.0); + } + return vec3(std::atan2((2 * m_data[1] * m_data[0]) - (2 * m_data[2] * m_data[3]), ww - xx + yy - zz), + std::atan2((2 * m_data[2] * m_data[0]) - (2 * m_data[1] * m_data[3]), xx - yy - zz + ww), + std::asin(2 * test / correction)); + } + template + auto quaternion::to_axis_angle()const -> std::pair>{ + quaternion q(*this); + if(m_data[0] > 1.0) + q = q.normalize(); + + value_type s = std::sqrt(1 - q.m_data[0] * q.m_data[0]); + if(s <= value_type{0.001}){ + return {2 * std::acos(q.m_data[0]), {1, 0, 0}}; + } + return {2 * std::acos(q.m_data[0]), {q.m_data[1] / s, q.m_data[2] / s, q.m_data[3] / s}}; + } + + template + bool operator==(const quaternion& left, const quaternion& right){ + return left.w() == right.w() && + left.x() == right.x() && + left.y() == right.y() && + left.z() == right.z(); + } + template + bool operator!=(const quaternion& left, const quaternion& right){ + return !(left == right); + } + template + auto operator-(const quaternion& left){ + using res_t = T; + return quaternion(manual_initialize, -left.w(), -left.x(), -left.y(), -left.z()); + } + template + auto operator-(const quaternion& left, const quaternion& right){ + using res_t = decltype(std::declval() - std::declval()); + return quaternion(manual_initialize, left.w() - right.w(), left.x() - right.x(), + left.y() - right.y(), left.z() - right.z()); + } + template + auto operator+(const quaternion& left, const quaternion& right){ + using res_t = decltype(std::declval() + std::declval()); + return quaternion(manual_initialize, left.w() + right.w(), left.x() + right.x(), + left.y() + right.y(), left.z() + right.z()); + } + template + auto operator*(const quaternion& left, const quaternion& right){ + using res_t = decltype(std::declval() * std::declval()); + return quaternion(manual_initialize, + (right.w() * left.w()) - (right.x() * left.x()) - + (right.y() * left.y()) - (right.z() * left.z()), + (right.w() * left.x()) + (right.x() * left.w()) + + (right.y() * left.z()) - (right.z() * left.y()), + (right.w() * left.y()) - (right.x() * left.z()) + + (right.y() * left.w()) + (right.z() * left.x()), + (right.w() * left.z()) + (right.x() * left.y()) - + (right.y() * left.x()) + (right.z() * left.w())); + } + template + auto operator*(const quaternion& left, const vec3& right){ + return left.to_mat3() * right; + } + template>,int>> + auto operator*(const quaternion& left, U&& right){ + using res_t = decltype(std::declval() * std::declval()); + return quaternion(manual_initialize, left.w() * right, left.x() * right, left.y() * right, left.z() * right); + } + template>,int>> + auto operator/(const quaternion& left, U&& right){ + using res_t = decltype(std::declval() / std::declval()); + return quaternion(manual_initialize, left.w() / right, left.x() / right, left.y() / right, left.z() / right); + } + template + decltype(auto) operator+=(quaternion& left, const quaternion& right){ + left.w() += right.w(); + left.x() += right.x(); + left.y() += right.y(); + left.z() += right.z(); + return left; + } + template + decltype(auto) operator-=(quaternion& left, const quaternion& right){ + left.w() -= right.w(); + left.x() -= right.x(); + left.y() -= right.y(); + left.z() -= right.z(); + return left; + } + template + decltype(auto) operator*=(quaternion& left, const quaternion& right){ + left = left * right; + return left; + } + + template>,int>> + decltype(auto) operator*=(quaternion& left, U&& right){ + left.w() *= right; + left.x() *= right; + left.y() *= right; + left.z() *= right; + return left; + } + template>,int>> + decltype(auto) operator/=(quaternion& left, U&& right){ + left.w() /= right; + left.x() /= right; + left.y() /= right; + left.z() /= right; + return left; + } + +} + +#endif diff --git a/include/vec.hpp b/include/math/vec.hpp similarity index 66% rename from include/vec.hpp rename to include/math/vec.hpp index 023327a..519636e 100644 --- a/include/vec.hpp +++ b/include/math/vec.hpp @@ -1,3 +1,21 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + #ifndef REXY_VEC_HPP #define REXY_VEC_HPP @@ -5,7 +23,7 @@ namespace math{ - template + template class vector : public matrix_base { private: @@ -33,6 +51,21 @@ namespace math{ constexpr reference operator[](size_type i); constexpr const_reference operator[](size_type i)const; + + constexpr reference x(); + constexpr const_reference x()const; + template + constexpr reference y(); + template + constexpr const_reference y()const; + template + constexpr reference z(); + template + constexpr const_reference z()const; + template + constexpr reference w(); + template + constexpr const_reference w()const; }; @@ -61,6 +94,14 @@ namespace math{ constexpr decltype(auto) operator+=(vector& left, const vector& right); template constexpr decltype(auto) operator-=(vector& left, const vector& right); + + + template + using vec2 = vector; + template + using vec3 = vector; + template + using vec4 = vector; } #include "vec.tpp" diff --git a/include/vec.tpp b/include/math/vec.tpp similarity index 65% rename from include/vec.tpp rename to include/math/vec.tpp index 7e0b907..056f3be 100644 --- a/include/vec.tpp +++ b/include/math/vec.tpp @@ -1,3 +1,21 @@ +/** + This file is a part of our_dick + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + #ifndef REXY_VEC_TPP #define REXY_VEC_TPP @@ -18,6 +36,51 @@ namespace math{ return this->m_data[i]; } + template + constexpr auto vector::x() -> reference{ + return this->m_data[0]; + } + template + constexpr auto vector::x()const -> const_reference{ + return this->m_data[0]; + } + template + template + constexpr auto vector::y() -> reference{ + static_assert(R > 1, "Vector does not contain a 2nd element"); + return this->m_data[1]; + } + template + template + constexpr auto vector::y()const -> const_reference{ + static_assert(R > 1, "Vector does not contain a 2nd element"); + return this->m_data[1]; + } + template + template + constexpr auto vector::z() -> reference{ + static_assert(R > 2, "Vector does not contain a 3rd element"); + return this->m_data[2]; + } + template + template + constexpr auto vector::z()const -> const_reference{ + static_assert(R > 2, "Vector does not contain a 3rd element"); + return this->m_data[2]; + } + template + template + constexpr auto vector::w() -> reference{ + static_assert(R > 3, "Vector does not contain a 4th element"); + return this->m_data[3]; + } + template + template + constexpr auto vector::w()const -> const_reference{ + static_assert(R > 3, "Vector does not contain a 4th element"); + return this->m_data[3]; + } + template constexpr auto operator*(const matrix& left, const vector& right){ using res_t = decltype(std::declval() * std::declval()); diff --git a/src/main.cpp b/src/main.cpp index 4cf1f47..c685293 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,7 +4,7 @@ #include "render.hpp" #include "game_state.hpp" -#include "mat.hpp" +#include "math/math.hpp" // 0 | 1 | 2 // ---------