/** 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(void); //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(const mat3& rotmat); quaternion(const mat4& rotmat); 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(void) = default; //Assignment constexpr quaternion& operator=(const quaternion&) = default; constexpr quaternion& operator=(quaternion&&) = default; //Direct array access constexpr operator pointer(void); constexpr operator const_pointer(void)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(void); constexpr const_reference w(void)const; constexpr reference x(void); constexpr const_reference x(void)const; constexpr reference y(void); constexpr const_reference y(void)const; constexpr reference z(void); constexpr const_reference z(void)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(void)const; void set_angle(value_type a); value_type get_angle(void)const; value_type norm(void)const; quaternion conjugate(void)const; quaternion inverse(void)const; value_type magnitude(void)const; quaternion normalize(void)const; vec3 get_right(void)const; vec3 get_up(void)const; vec3 get_forward(void)const; //Explicit Conversion1 vec3 to_vec3(void)const; vec4 to_vec4(void)const; mat3 to_mat3(void)const; mat4 to_mat4(void)const; vec3 to_euler_angles(void)const; std::pair> to_axis_angle(void)const; }; 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 auto operator*(const quaternion& left, U&& right); template 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 decltype(auto) operator*=(quaternion& left, U&& right); template decltype(auto) operator/=(quaternion& left, U&& right); } #include "quat.tpp" #endif