Add quaternions. Move math to separate directory
This commit is contained in:
parent
f79a3cc9bd
commit
71278c460a
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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
|
||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_DETAIL_MATRIX_HPP
|
||||
#define REXY_DETAIL_MATRIX_HPP
|
||||
|
||||
#include <cstdlib> //size_t
|
||||
#include <utility> //integer_sequence
|
||||
|
||||
namespace math::detail{
|
||||
|
||||
template<size_t SW, size_t W = SW, size_t H = SW-1, size_t... Args>
|
||||
struct gen_id_tup {
|
||||
using tup = typename gen_id_tup<SW, W-1, H, Args..., 0>::tup;
|
||||
};
|
||||
template<size_t SW, size_t H, size_t... Args>
|
||||
struct gen_id_tup<SW,SW,H,Args...> {
|
||||
using tup = typename gen_id_tup<SW, SW-1, H, Args..., 1>::tup;
|
||||
};
|
||||
template<size_t SW, size_t H, size_t... Args>
|
||||
struct gen_id_tup<SW,0,H,Args...> {
|
||||
using tup = typename gen_id_tup<SW, SW, H-1, Args..., 0>::tup;
|
||||
};
|
||||
template<size_t SW, size_t... Args>
|
||||
struct gen_id_tup<SW,SW,0,Args...> {
|
||||
using tup = std::integer_sequence<size_t,Args...,1>;
|
||||
};
|
||||
|
||||
|
||||
template<size_t N, size_t... Args>
|
||||
struct gen_zero_tup {
|
||||
using tup = typename gen_zero_tup<N-1,Args...,0>::tup;
|
||||
};
|
||||
template<size_t... Args>
|
||||
struct gen_zero_tup<0,Args...> {
|
||||
using tup = std::integer_sequence<size_t,Args...>;
|
||||
};
|
||||
|
||||
template<size_t W>
|
||||
struct id_initialization_matrix {
|
||||
using tuple = typename gen_id_tup<W>::tup;
|
||||
};
|
||||
|
||||
|
||||
template<size_t W, size_t H>
|
||||
struct default_initialization_matrix {
|
||||
using tuple = typename gen_zero_tup<W>::tup;
|
||||
};
|
||||
template<size_t W>
|
||||
struct default_initialization_matrix<W,W> {
|
||||
using tuple = typename id_initialization_matrix<W>::tuple;
|
||||
};
|
||||
|
||||
template<typename T, size_t R>
|
||||
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<typename T, size_t R>
|
||||
struct determinate_helper {
|
||||
static constexpr T perform(const matrix<T,R,R>& m){
|
||||
T sum = 0;
|
||||
T op = 1;
|
||||
for(size_t i = 0;i < R;++i){
|
||||
T item = op * m[0][i];
|
||||
matrix<T,R-1,R-1> 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<T,R-1>::perform(mul);
|
||||
op = -op;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct determinate_helper<T,3> {
|
||||
static constexpr T perform(const matrix<T,3,3>& 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<typename T>
|
||||
struct determinate_helper<T,2> {
|
||||
static constexpr T perform(const matrix<T,2,2>& m){
|
||||
return m.get(0) * m.get(3) - m.get(1) * m.get(2);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, size_t R>
|
||||
struct inverse_helper {
|
||||
//TODO generalized inverse
|
||||
};
|
||||
template<typename T>
|
||||
struct inverse_helper<T,2> {
|
||||
static constexpr matrix<T,2,2> perform(const matrix<T,2,2>& m){
|
||||
T det = m.determinate();
|
||||
if(!det)
|
||||
return matrix<T,2,2>(zero_initialize);
|
||||
return matrix<T,2,2>(m.get(3) / det, -(m.get(1)) / det, -(m.get(2)) / det, m.get(0) / det);
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct inverse_helper<T,3> {
|
||||
static constexpr matrix<T,3,3> perform(const matrix<T,3,3>& m){
|
||||
T det = m.determinate();
|
||||
if(!det)
|
||||
return matrix<T,3,3>(zero_initialize);
|
||||
return matrix<T,3,3>(((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<typename T>
|
||||
struct inverse_helper<T,4> {
|
||||
static constexpr matrix<T,4,4> perform(const matrix<T,4,4>& m){
|
||||
T det = m.determinate();
|
||||
if(!det)
|
||||
return matrix<T,4,4>(zero_initialize);
|
||||
//Math is power
|
||||
return matrix<T,4,4>((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
|
||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_DETAIL_MATRIX_TPP
|
||||
#define REXY_DETAIL_MATRIX_TPP
|
||||
|
||||
#include <cstdlib> //size_t
|
||||
#include <utility> //integer_sequence
|
||||
|
||||
namespace math::detail{
|
||||
|
||||
template<typename T, size_t R>
|
||||
constexpr mat_ref_obj<T,R>::mat_ref_obj(T* d, size_type i):
|
||||
m_data(d+i){}
|
||||
|
||||
template<typename T, size_t R>
|
||||
constexpr T& mat_ref_obj<T,R>::operator[](size_type i){
|
||||
return m_data[i*R];
|
||||
}
|
||||
template<typename T, size_t R>
|
||||
constexpr const T& mat_ref_obj<T,R>::operator[](size_type i)const{
|
||||
return m_data[i*R];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
116
include/math/detail/matrix.hpp
Normal file
116
include/math/detail/matrix.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_DETAIL_MATRIX_HPP
|
||||
#define REXY_DETAIL_MATRIX_HPP
|
||||
|
||||
#include <cstdlib> //size_t
|
||||
#include <utility> //integer_sequence
|
||||
|
||||
namespace math::detail{
|
||||
|
||||
template<size_t SW, size_t W = SW, size_t H = SW-1, size_t... Args>
|
||||
struct gen_id_tup {
|
||||
using tup = typename gen_id_tup<SW, W-1, H, Args..., 0>::tup;
|
||||
};
|
||||
template<size_t SW, size_t H, size_t... Args>
|
||||
struct gen_id_tup<SW,SW,H,Args...> {
|
||||
using tup = typename gen_id_tup<SW, SW-1, H, Args..., 1>::tup;
|
||||
};
|
||||
template<size_t SW, size_t H, size_t... Args>
|
||||
struct gen_id_tup<SW,0,H,Args...> {
|
||||
using tup = typename gen_id_tup<SW, SW, H-1, Args..., 0>::tup;
|
||||
};
|
||||
template<size_t SW, size_t... Args>
|
||||
struct gen_id_tup<SW,SW,0,Args...> {
|
||||
using tup = std::integer_sequence<size_t,Args...,1>;
|
||||
};
|
||||
|
||||
|
||||
template<size_t N, size_t... Args>
|
||||
struct gen_zero_tup {
|
||||
using tup = typename gen_zero_tup<N-1,Args...,0>::tup;
|
||||
};
|
||||
template<size_t... Args>
|
||||
struct gen_zero_tup<0,Args...> {
|
||||
using tup = std::integer_sequence<size_t,Args...>;
|
||||
};
|
||||
|
||||
template<size_t W>
|
||||
struct id_initialization_matrix {
|
||||
using tuple = typename gen_id_tup<W>::tup;
|
||||
};
|
||||
|
||||
|
||||
template<size_t W, size_t H>
|
||||
struct default_initialization_matrix {
|
||||
using tuple = typename gen_zero_tup<W>::tup;
|
||||
};
|
||||
template<size_t W>
|
||||
struct default_initialization_matrix<W,W> {
|
||||
using tuple = typename id_initialization_matrix<W>::tuple;
|
||||
};
|
||||
|
||||
template<typename T, size_t R>
|
||||
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<typename T, size_t R>
|
||||
struct determinate_helper {
|
||||
static constexpr T perform(const matrix<T,R,R>& m);
|
||||
};
|
||||
template<typename T>
|
||||
struct determinate_helper<T,3> {
|
||||
static constexpr T perform(const matrix<T,3,3>& m);
|
||||
};
|
||||
template<typename T>
|
||||
struct determinate_helper<T,2> {
|
||||
static constexpr T perform(const matrix<T,2,2>& m);
|
||||
};
|
||||
|
||||
template<typename T, size_t R>
|
||||
struct inverse_helper {
|
||||
//TODO generalized inverse
|
||||
};
|
||||
template<typename T>
|
||||
struct inverse_helper<T,2> {
|
||||
static constexpr matrix<T,2,2> perform(const matrix<T,2,2>& m);
|
||||
};
|
||||
template<typename T>
|
||||
struct inverse_helper<T,3> {
|
||||
static constexpr matrix<T,3,3> perform(const matrix<T,3,3>& m);
|
||||
};
|
||||
template<typename T>
|
||||
struct inverse_helper<T,4> {
|
||||
static constexpr matrix<T,4,4> perform(const matrix<T,4,4>& m);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "matrix.tpp"
|
||||
|
||||
#endif
|
||||
166
include/math/detail/matrix.tpp
Normal file
166
include/math/detail/matrix.tpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_DETAIL_MATRIX_TPP
|
||||
#define REXY_DETAIL_MATRIX_TPP
|
||||
|
||||
#include <cstdlib> //size_t
|
||||
#include <utility> //integer_sequence
|
||||
|
||||
namespace math::detail{
|
||||
|
||||
template<typename T, size_t R>
|
||||
constexpr mat_ref_obj<T,R>::mat_ref_obj(T* d, size_type i):
|
||||
m_data(d+i){}
|
||||
|
||||
template<typename T, size_t R>
|
||||
constexpr T& mat_ref_obj<T,R>::operator[](size_type i){
|
||||
return m_data[i*R];
|
||||
}
|
||||
template<typename T, size_t R>
|
||||
constexpr const T& mat_ref_obj<T,R>::operator[](size_type i)const{
|
||||
return m_data[i*R];
|
||||
}
|
||||
template<typename T, size_t R>
|
||||
constexpr T determinate_helper<T,R>::perform(const matrix<T,R,R>& m){
|
||||
T sum = 0;
|
||||
T op = 1;
|
||||
for(size_t i = 0;i < R;++i){
|
||||
T item = op * m[0][i];
|
||||
matrix<T,R-1,R-1> 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<T,R-1>::perform(mul);
|
||||
op = -op;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
template<typename T>
|
||||
constexpr T determinate_helper<T,3>::perform(const matrix<T,3,3>& 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<typename T>
|
||||
constexpr T determinate_helper<T,2>::perform(const matrix<T,2,2>& m){
|
||||
return m.get(0) * m.get(3) - m.get(1) * m.get(2);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr matrix<T,2,2> inverse_helper<T,2>::perform(const matrix<T,2,2>& m){
|
||||
T det = m.determinate();
|
||||
if(!det)
|
||||
return matrix<T,2,2>(zero_initialize);
|
||||
return matrix<T,2,2>(m.get(3) / det, -(m.get(1)) / det, -(m.get(2)) / det, m.get(0) / det);
|
||||
}
|
||||
template<typename T>
|
||||
constexpr matrix<T,3,3> inverse_helper<T,3>::perform(const matrix<T,3,3>& m){
|
||||
T det = m.determinate();
|
||||
if(!det)
|
||||
return matrix<T,3,3>(zero_initialize);
|
||||
return matrix<T,3,3>(((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<typename T>
|
||||
constexpr matrix<T,4,4> inverse_helper<T,4>::perform(const matrix<T,4,4>& m){
|
||||
T det = m.determinate();
|
||||
if(!det)
|
||||
return matrix<T,4,4>(zero_initialize);
|
||||
//Math is power
|
||||
return matrix<T,4,4>((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
|
||||
49
include/math/fwd_declare.hpp
Normal file
49
include/math/fwd_declare.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_MATH_FWD_DECLARE_HPP
|
||||
#define REXY_MATH_FWD_DECLARE_HPP
|
||||
|
||||
#include <cstdlib> //size_t
|
||||
|
||||
namespace math{
|
||||
|
||||
template<typename T, size_t R, size_t C>
|
||||
class matrix;
|
||||
template<typename T, size_t R>
|
||||
class vector;
|
||||
template<typename T>
|
||||
class quaternion;
|
||||
|
||||
template<typename T>
|
||||
using mat2 = matrix<T,2,2>;
|
||||
template<typename T>
|
||||
using mat3 = matrix<T,3,3>;
|
||||
template<typename T>
|
||||
using mat4 = matrix<T,4,4>;
|
||||
|
||||
template<typename T>
|
||||
using vec2 = vector<T,2>;
|
||||
template<typename T>
|
||||
using vec3 = vector<T,3>;
|
||||
template<typename T>
|
||||
using vec4 = vector<T,4>;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_MAT_HPP
|
||||
@ -22,7 +22,8 @@
|
||||
#include <cstdlib> //size_t
|
||||
#include <utility> //integer_sequence
|
||||
#include <type_traits> //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<typename T, typename U, size_t R1, size_t C1, size_t R2>
|
||||
constexpr auto operator*(const matrix<T,R1,C1>& left, const matrix<U,C1,R2>& right);
|
||||
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
|
||||
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
|
||||
constexpr auto operator*(const matrix<T,R,C>& left, U&& right);
|
||||
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
|
||||
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
|
||||
constexpr auto operator*(U&& left, const matrix<T,R,C>& right);
|
||||
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
|
||||
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
|
||||
constexpr auto operator/(const matrix<T,R,C>& left, U&& right);
|
||||
template<typename T, typename U, size_t C, size_t R>
|
||||
constexpr auto operator+(const matrix<T,R,C>& left, const matrix<U,R,C>& right);
|
||||
@ -243,15 +244,23 @@ namespace math{
|
||||
|
||||
template<typename T, typename U, size_t R>
|
||||
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right);
|
||||
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
|
||||
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
|
||||
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right);
|
||||
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<!is_matrix<U>::value,int> = 0>
|
||||
template<typename T, typename U, size_t C, size_t R, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
|
||||
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right);
|
||||
template<typename T, typename U, size_t C, size_t R>
|
||||
constexpr decltype(auto) operator+=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
|
||||
template<typename T, typename U, size_t C, size_t R>
|
||||
constexpr decltype(auto) operator-=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
|
||||
|
||||
|
||||
template<typename T>
|
||||
using mat2 = matrix<T,2,2>;
|
||||
template<typename T>
|
||||
using mat3 = matrix<T,3,3>;
|
||||
template<typename T>
|
||||
using mat4 = matrix<T,4,4>;
|
||||
|
||||
}
|
||||
|
||||
#include "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 <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_MAT_TPP
|
||||
@ -23,6 +23,7 @@
|
||||
#include <cmath> //sin, cos
|
||||
#include <type_traits> //decay_t, declval
|
||||
#include "detail/matrix.hpp"
|
||||
#include "quat.hpp"
|
||||
|
||||
namespace math{
|
||||
|
||||
@ -202,8 +203,8 @@ namespace math{
|
||||
}
|
||||
template<typename T>
|
||||
matrix<T,3,3> rotation2d(T x, T y, T z){
|
||||
//TODO
|
||||
return {};
|
||||
quaternion<T> q(x, y, z);
|
||||
return q.to_mat3();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -242,8 +243,8 @@ namespace math{
|
||||
}
|
||||
template<typename T>
|
||||
constexpr matrix<T,4,4> rotation3d(T angle_x, T angle_y, T angle_z){
|
||||
//TODO
|
||||
return {};
|
||||
quaternion<T> q(angle_x, angle_y, angle_z);
|
||||
return q.to_mat4();
|
||||
}
|
||||
template<typename T>
|
||||
constexpr matrix<T,4,4> translation3d(T x, T y, T z){
|
||||
27
include/math/math.hpp
Normal file
27
include/math/math.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_MATH_HPP
|
||||
#define REXY_MATH_HPP
|
||||
|
||||
#include "math_common.hpp"
|
||||
#include "vec.hpp"
|
||||
#include "mat.hpp"
|
||||
#include "quat.hpp"
|
||||
|
||||
#endif
|
||||
58
include/math/math_common.hpp
Normal file
58
include/math/math_common.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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<typename T>
|
||||
static constexpr T pi(){
|
||||
return static_cast<T>(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821);
|
||||
}
|
||||
template<typename T>
|
||||
static constexpr T to_degrees(T t){
|
||||
return (t * 180.0) / pi<T>();
|
||||
}
|
||||
template<typename T>
|
||||
static constexpr T to_radians(T t){
|
||||
return (t * pi<T>()) / 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
|
||||
160
include/math/quat.hpp
Normal file
160
include/math/quat.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_QUAT_HPP
|
||||
#define REXY_QUAT_HPP
|
||||
|
||||
#include <cstdlib> //size_t
|
||||
#include <utility> //pair
|
||||
#include <type_traits> //is_same, is_arithmetic, integral_constant
|
||||
|
||||
#include "math_common.hpp"
|
||||
#include "fwd_declare.hpp"
|
||||
|
||||
namespace math{
|
||||
|
||||
template<typename T>
|
||||
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<value_type>& angles);
|
||||
//Construct from axis-angle
|
||||
quaternion(value_type angle, const vec3<value_type>& 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<value_type>& axis);
|
||||
vec3<value_type> 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<value_type> get_right()const;
|
||||
vec3<value_type> get_up()const;
|
||||
vec3<value_type> get_forward()const;
|
||||
|
||||
//Explicit Conversion1
|
||||
vec3<value_type> to_vec3()const;
|
||||
vec4<value_type> to_vec4()const;
|
||||
mat3<value_type> to_mat3()const;
|
||||
mat4<value_type> to_mat4()const;
|
||||
vec3<value_type> to_euler_angles()const;
|
||||
std::pair<value_type,vec3<value_type>> to_axis_angle()const;
|
||||
};
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename T>
|
||||
struct is_quat_helper {
|
||||
template<class U>
|
||||
static std::true_type test(quaternion<U>*);
|
||||
static std::false_type test(void*);
|
||||
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
|
||||
};
|
||||
}
|
||||
template<typename... Qs>
|
||||
struct is_quaternion {
|
||||
static constexpr bool value = (detail::is_quat_helper<Qs>::value && ...);
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
bool operator==(const quaternion<T>& left, const quaternion<U>& right);
|
||||
template<typename T, typename U>
|
||||
bool operator!=(const quaternion<T>& left, const quaternion<U>& right);
|
||||
template<typename T>
|
||||
auto operator-(const quaternion<T>& left);
|
||||
template<typename T, typename U>
|
||||
auto operator-(const quaternion<T>& left, const quaternion<U>& right);
|
||||
template<typename T, typename U>
|
||||
auto operator+(const quaternion<T>& left, const quaternion<U>& right);
|
||||
template<typename T, typename U>
|
||||
auto operator*(const quaternion<T>& left, const quaternion<U>& right);
|
||||
template<typename T, typename U>
|
||||
auto operator*(const quaternion<T>& left, const vec3<U>& right);
|
||||
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
|
||||
auto operator*(const quaternion<T>& left, U&& right);
|
||||
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
|
||||
auto operator/(const quaternion<T>& left, U&& right);
|
||||
|
||||
template<typename T, typename U>
|
||||
decltype(auto) operator+=(quaternion<T>& left, const quaternion<U>& right);
|
||||
template<typename T, typename U>
|
||||
decltype(auto) operator-=(quaternion<T>& left, const quaternion<U>& right);
|
||||
template<typename T, typename U>
|
||||
decltype(auto) operator*=(quaternion<T>& left, const quaternion<U>& right);
|
||||
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
|
||||
decltype(auto) operator*=(quaternion<T>& left, U&& right);
|
||||
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int> = 0>
|
||||
decltype(auto) operator/=(quaternion<T>& left, U&& right);
|
||||
|
||||
}
|
||||
|
||||
#include "quat.tpp"
|
||||
|
||||
#endif
|
||||
403
include/math/quat.tpp
Normal file
403
include/math/quat.tpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_QUAT_TPP
|
||||
#define REXY_QUAT_TPP
|
||||
|
||||
#include <cmath> //sin, cos, tan, sqrt, etc
|
||||
#include "mat.hpp"
|
||||
#include "vec.hpp"
|
||||
|
||||
namespace math{
|
||||
|
||||
template<typename T>
|
||||
constexpr quaternion<T>::quaternion():
|
||||
quaternion(id_initialize){}
|
||||
template<typename T>
|
||||
constexpr quaternion<T>::quaternion(detail::zero_initialize_t):
|
||||
m_data{0, 0, 0, 0}{}
|
||||
template<typename T>
|
||||
constexpr quaternion<T>::quaternion(detail::id_initialize_t):
|
||||
m_data{1, 0, 0, 0}{}
|
||||
template<typename T>
|
||||
constexpr quaternion<T>::quaternion(detail::no_initialize_t){}
|
||||
|
||||
template<typename T>
|
||||
constexpr quaternion<T>::quaternion(detail::manual_initialize_t,
|
||||
value_type w, value_type x,
|
||||
value_type y, value_type z):
|
||||
m_data{w, x, y, z}{}
|
||||
|
||||
template<typename T>
|
||||
quaternion<T>::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<typename T>
|
||||
quaternion<T>::quaternion(const vec3<T>& angles):
|
||||
quaternion(angles.x(), angles.y(), angles.z()){}
|
||||
template<typename T>
|
||||
quaternion<T>::quaternion(value_type angle, const vec3<value_type>& axis):
|
||||
quaternion(angle, axis.get_x(), axis.get_y(), axis.get_z()){}
|
||||
template<typename T>
|
||||
quaternion<T>::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<typename T>
|
||||
constexpr quaternion<T>::operator pointer(void){
|
||||
return m_data;
|
||||
}
|
||||
template<typename T>
|
||||
constexpr quaternion<T>::operator const_pointer(void)const{
|
||||
return m_data;
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::operator[](size_type i) -> reference{
|
||||
return m_data[i];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::operator[](size_type i)const -> const_reference{
|
||||
return m_data[i];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::get(size_type i) -> reference{
|
||||
return m_data[i];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::get(size_type i)const -> const_reference{
|
||||
return m_data[i];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::w() -> reference{
|
||||
return m_data[0];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::w()const -> const_reference{
|
||||
return m_data[0];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::x() -> reference{
|
||||
return m_data[1];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::x()const -> const_reference{
|
||||
return m_data[1];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::y() -> reference{
|
||||
return m_data[2];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::y()const -> const_reference{
|
||||
return m_data[2];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::z() -> reference{
|
||||
return m_data[3];
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto quaternion<T>::z()const -> const_reference{
|
||||
return m_data[3];
|
||||
}
|
||||
template<typename T>
|
||||
void quaternion<T>::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<typename T>
|
||||
void quaternion<T>::set_axis(const vec3<value_type>& v){
|
||||
set_axis(v.x(), v.y(), v.z());
|
||||
}
|
||||
template<typename T>
|
||||
auto quaternion<T>::get_axis()const -> vec3<value_type>{
|
||||
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<T>(1, 0, 0);
|
||||
return vec3<T>(tmp.data[1] / s, tmp.data[2] / s, tmp.data[3] / s);
|
||||
}
|
||||
template<typename T>
|
||||
void quaternion<T>::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<typename T>
|
||||
auto quaternion<T>::get_angle(void)const -> value_type{
|
||||
return 2.0 * std::acos(m_data[0]);
|
||||
}
|
||||
template<typename T>
|
||||
auto quaternion<T>::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<typename T>
|
||||
quaternion<T> quaternion<T>::conjugate(void)const{
|
||||
return quaternion(manual_initialize, m_data[0], -m_data[1], -m_data[2], -m_data[3]);
|
||||
}
|
||||
template<typename T>
|
||||
quaternion<T> quaternion<T>::inverse(void)const{
|
||||
return conjugate() / norm();
|
||||
}
|
||||
template<typename T>
|
||||
auto quaternion<T>::magnitude(void)const -> value_type{
|
||||
return std::sqrt(norm());
|
||||
}
|
||||
template<typename T>
|
||||
quaternion<T> quaternion<T>::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<typename T>
|
||||
auto quaternion<T>::get_right(void)const -> vec3<value_type>{
|
||||
return vec3<value_type>(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<typename T>
|
||||
auto quaternion<T>::get_up(void)const -> vec3<value_type>{
|
||||
return vec3<value_type>( 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<typename T>
|
||||
auto quaternion<T>::get_forward(void)const -> vec3<value_type>{
|
||||
return vec3<value_type>( 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<typename T>
|
||||
auto quaternion<T>::to_vec3(void)const -> vec3<value_type>{
|
||||
return vec3<value_type>(m_data[1], m_data[2], m_data[3]);
|
||||
}
|
||||
template<typename T>
|
||||
auto quaternion<T>::to_vec4(void)const -> vec4<value_type>{
|
||||
return vec4<value_type>(m_data[1], m_data[2], m_data[3]);
|
||||
}
|
||||
template<typename T>
|
||||
auto quaternion<T>::to_mat3(void)const -> mat3<value_type>{
|
||||
mat3<value_type> 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<typename T>
|
||||
auto quaternion<T>::to_mat4(void)const -> mat4<value_type>{
|
||||
mat4<value_type> 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<typename T>
|
||||
auto quaternion<T>::to_euler_angles(void)const -> vec3<value_type>{
|
||||
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<value_type>(0, 2 * std::atan2(m_data[1], m_data[0]), pi<value_type>() / 2.0);
|
||||
}else if(test < -0.499 * correction){
|
||||
return vec3<value_type>(0, -2 * std::atan2(m_data[1], m_data[0]), -pi<value_type>() / 2.0);
|
||||
}
|
||||
return vec3<value_type>(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<typename T>
|
||||
auto quaternion<T>::to_axis_angle()const -> std::pair<value_type,vec3<value_type>>{
|
||||
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<typename T, typename U>
|
||||
bool operator==(const quaternion<T>& left, const quaternion<U>& right){
|
||||
return left.w() == right.w() &&
|
||||
left.x() == right.x() &&
|
||||
left.y() == right.y() &&
|
||||
left.z() == right.z();
|
||||
}
|
||||
template<typename T, typename U>
|
||||
bool operator!=(const quaternion<T>& left, const quaternion<U>& right){
|
||||
return !(left == right);
|
||||
}
|
||||
template<typename T>
|
||||
auto operator-(const quaternion<T>& left){
|
||||
using res_t = T;
|
||||
return quaternion<res_t>(manual_initialize, -left.w(), -left.x(), -left.y(), -left.z());
|
||||
}
|
||||
template<typename T, typename U>
|
||||
auto operator-(const quaternion<T>& left, const quaternion<U>& right){
|
||||
using res_t = decltype(std::declval<T>() - std::declval<U>());
|
||||
return quaternion<res_t>(manual_initialize, left.w() - right.w(), left.x() - right.x(),
|
||||
left.y() - right.y(), left.z() - right.z());
|
||||
}
|
||||
template<typename T, typename U>
|
||||
auto operator+(const quaternion<T>& left, const quaternion<U>& right){
|
||||
using res_t = decltype(std::declval<T>() + std::declval<U>());
|
||||
return quaternion<res_t>(manual_initialize, left.w() + right.w(), left.x() + right.x(),
|
||||
left.y() + right.y(), left.z() + right.z());
|
||||
}
|
||||
template<typename T, typename U>
|
||||
auto operator*(const quaternion<T>& left, const quaternion<U>& right){
|
||||
using res_t = decltype(std::declval<T>() * std::declval<U>());
|
||||
return quaternion<res_t>(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<typename T, typename U>
|
||||
auto operator*(const quaternion<T>& left, const vec3<U>& right){
|
||||
return left.to_mat3() * right;
|
||||
}
|
||||
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
|
||||
auto operator*(const quaternion<T>& left, U&& right){
|
||||
using res_t = decltype(std::declval<T>() * std::declval<U>());
|
||||
return quaternion<res_t>(manual_initialize, left.w() * right, left.x() * right, left.y() * right, left.z() * right);
|
||||
}
|
||||
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
|
||||
auto operator/(const quaternion<T>& left, U&& right){
|
||||
using res_t = decltype(std::declval<T>() / std::declval<U>());
|
||||
return quaternion<res_t>(manual_initialize, left.w() / right, left.x() / right, left.y() / right, left.z() / right);
|
||||
}
|
||||
template<typename T, typename U>
|
||||
decltype(auto) operator+=(quaternion<T>& left, const quaternion<U>& right){
|
||||
left.w() += right.w();
|
||||
left.x() += right.x();
|
||||
left.y() += right.y();
|
||||
left.z() += right.z();
|
||||
return left;
|
||||
}
|
||||
template<typename T, typename U>
|
||||
decltype(auto) operator-=(quaternion<T>& left, const quaternion<U>& right){
|
||||
left.w() -= right.w();
|
||||
left.x() -= right.x();
|
||||
left.y() -= right.y();
|
||||
left.z() -= right.z();
|
||||
return left;
|
||||
}
|
||||
template<typename T, typename U>
|
||||
decltype(auto) operator*=(quaternion<T>& left, const quaternion<U>& right){
|
||||
left = left * right;
|
||||
return left;
|
||||
}
|
||||
|
||||
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
|
||||
decltype(auto) operator*=(quaternion<T>& left, U&& right){
|
||||
left.w() *= right;
|
||||
left.x() *= right;
|
||||
left.y() *= right;
|
||||
left.z() *= right;
|
||||
return left;
|
||||
}
|
||||
template<typename T, typename U, std::enable_if_t<std::is_arithmetic_v<std::decay_t<U>>,int>>
|
||||
decltype(auto) operator/=(quaternion<T>& left, U&& right){
|
||||
left.w() /= right;
|
||||
left.x() /= right;
|
||||
left.y() /= right;
|
||||
left.z() /= right;
|
||||
return left;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_VEC_HPP
|
||||
#define REXY_VEC_HPP
|
||||
|
||||
@ -5,7 +23,7 @@
|
||||
|
||||
namespace math{
|
||||
|
||||
template<class T, size_t R>
|
||||
template<typename T, size_t R>
|
||||
class vector : public matrix_base<T,R,1>
|
||||
{
|
||||
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<typename U = T>
|
||||
constexpr reference y();
|
||||
template<typename U = T>
|
||||
constexpr const_reference y()const;
|
||||
template<typename U = T>
|
||||
constexpr reference z();
|
||||
template<typename U = T>
|
||||
constexpr const_reference z()const;
|
||||
template<typename U = T>
|
||||
constexpr reference w();
|
||||
template<typename U = T>
|
||||
constexpr const_reference w()const;
|
||||
};
|
||||
|
||||
|
||||
@ -61,6 +94,14 @@ namespace math{
|
||||
constexpr decltype(auto) operator+=(vector<T,R>& left, const vector<U,R>& right);
|
||||
template<typename T, typename U, size_t R>
|
||||
constexpr decltype(auto) operator-=(vector<T,R>& left, const vector<U,R>& right);
|
||||
|
||||
|
||||
template<typename T>
|
||||
using vec2 = vector<T,2>;
|
||||
template<typename T>
|
||||
using vec3 = vector<T,3>;
|
||||
template<typename T>
|
||||
using vec4 = vector<T,4>;
|
||||
}
|
||||
|
||||
#include "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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_VEC_TPP
|
||||
#define REXY_VEC_TPP
|
||||
|
||||
@ -18,6 +36,51 @@ namespace math{
|
||||
return this->m_data[i];
|
||||
}
|
||||
|
||||
template<typename T, size_t R>
|
||||
constexpr auto vector<T,R>::x() -> reference{
|
||||
return this->m_data[0];
|
||||
}
|
||||
template<typename T, size_t R>
|
||||
constexpr auto vector<T,R>::x()const -> const_reference{
|
||||
return this->m_data[0];
|
||||
}
|
||||
template<typename T, size_t R>
|
||||
template<typename U>
|
||||
constexpr auto vector<T,R>::y() -> reference{
|
||||
static_assert(R > 1, "Vector does not contain a 2nd element");
|
||||
return this->m_data[1];
|
||||
}
|
||||
template<typename T, size_t R>
|
||||
template<typename U>
|
||||
constexpr auto vector<T,R>::y()const -> const_reference{
|
||||
static_assert(R > 1, "Vector does not contain a 2nd element");
|
||||
return this->m_data[1];
|
||||
}
|
||||
template<typename T, size_t R>
|
||||
template<typename U>
|
||||
constexpr auto vector<T,R>::z() -> reference{
|
||||
static_assert(R > 2, "Vector does not contain a 3rd element");
|
||||
return this->m_data[2];
|
||||
}
|
||||
template<typename T, size_t R>
|
||||
template<typename U>
|
||||
constexpr auto vector<T,R>::z()const -> const_reference{
|
||||
static_assert(R > 2, "Vector does not contain a 3rd element");
|
||||
return this->m_data[2];
|
||||
}
|
||||
template<typename T, size_t R>
|
||||
template<typename U>
|
||||
constexpr auto vector<T,R>::w() -> reference{
|
||||
static_assert(R > 3, "Vector does not contain a 4th element");
|
||||
return this->m_data[3];
|
||||
}
|
||||
template<typename T, size_t R>
|
||||
template<typename U>
|
||||
constexpr auto vector<T,R>::w()const -> const_reference{
|
||||
static_assert(R > 3, "Vector does not contain a 4th element");
|
||||
return this->m_data[3];
|
||||
}
|
||||
|
||||
template<typename T, typename U, size_t C, size_t R>
|
||||
constexpr auto operator*(const matrix<U,R,C>& left, const vector<T,C>& right){
|
||||
using res_t = decltype(std::declval<T>() * std::declval<U>());
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
#include "render.hpp"
|
||||
#include "game_state.hpp"
|
||||
#include "mat.hpp"
|
||||
#include "math/math.hpp"
|
||||
|
||||
// 0 | 1 | 2
|
||||
// ---------
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user