154 lines
5.1 KiB
C++
154 lines
5.1 KiB
C++
/**
|
|
This file is a part of rexy's math library
|
|
Copyright (C) 2020-2022 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 RML_QUAT_HPP
|
|
#define RML_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 rml{
|
|
|
|
//( ͡° ͜ʖ ͡°)
|
|
template<Scalar 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(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<T>& rotmat);
|
|
quaternion(const mat4<T>& rotmat);
|
|
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(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<value_type>& axis);
|
|
vec3<value_type> 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<value_type> get_right(void)const;
|
|
vec3<value_type> get_up(void)const;
|
|
vec3<value_type> get_forward(void)const;
|
|
|
|
//Explicit Conversion1
|
|
vec3<value_type> to_vec3(void)const;
|
|
vec4<value_type> to_vec4(void)const;
|
|
mat3<value_type> to_mat3(void)const;
|
|
mat4<value_type> to_mat4(void)const;
|
|
vec3<value_type> to_euler_angles(void)const;
|
|
std::pair<value_type,vec3<value_type>> to_axis_angle(void)const;
|
|
};
|
|
|
|
template<Scalar T, Scalar U>
|
|
bool operator==(const quaternion<T>& left, const quaternion<U>& right);
|
|
template<Scalar T, Scalar U>
|
|
bool operator!=(const quaternion<T>& left, const quaternion<U>& right);
|
|
template<Scalar T>
|
|
auto operator-(const quaternion<T>& left);
|
|
template<Scalar T, Scalar U>
|
|
auto operator-(const quaternion<T>& left, const quaternion<U>& right);
|
|
template<Scalar T, Scalar U>
|
|
auto operator+(const quaternion<T>& left, const quaternion<U>& right);
|
|
template<Scalar T, Scalar U>
|
|
auto operator*(const quaternion<T>& left, const quaternion<U>& right);
|
|
template<Scalar T, Scalar U>
|
|
auto operator*(const quaternion<T>& left, const vec3<U>& right);
|
|
template<Scalar T, Scalar U>
|
|
auto operator*(const quaternion<T>& left, U&& right);
|
|
template<Scalar T, Scalar U>
|
|
auto operator/(const quaternion<T>& left, U&& right);
|
|
|
|
template<Scalar T, Scalar U>
|
|
decltype(auto) operator+=(quaternion<T>& left, const quaternion<U>& right);
|
|
template<Scalar T, Scalar U>
|
|
decltype(auto) operator-=(quaternion<T>& left, const quaternion<U>& right);
|
|
template<Scalar T, Scalar U>
|
|
decltype(auto) operator*=(quaternion<T>& left, const quaternion<U>& right);
|
|
template<Scalar T, Scalar U>
|
|
decltype(auto) operator*=(quaternion<T>& left, U&& right);
|
|
template<Scalar T, Scalar U>
|
|
decltype(auto) operator/=(quaternion<T>& left, U&& right);
|
|
|
|
#if RML_INSTANTIATIONS_ENABLED
|
|
extern template class quaternion<float>;
|
|
extern template class quaternion<int>;
|
|
extern template class quaternion<double>;
|
|
#endif
|
|
}
|
|
|
|
#include "quat.tpp"
|
|
|
|
#endif
|