161 lines
5.5 KiB
C++
161 lines
5.5 KiB
C++
/**
|
|
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
|