Added quaternion EXT extensions

This commit is contained in:
Christophe Riccio 2018-08-07 13:55:13 +02:00
parent c191e6cfe9
commit 8c9d16d868
32 changed files with 1174 additions and 825 deletions

View File

@ -237,14 +237,14 @@ template struct mat<4, 4, float32, highp>;
template struct mat<4, 4, float64, highp>;
// tquat type explicit instantiation
template struct tquat<float32, lowp>;
template struct tquat<float64, lowp>;
template struct qua<float32, lowp>;
template struct qua<float64, lowp>;
template struct tquat<float32, mediump>;
template struct tquat<float64, mediump>;
template struct qua<float32, mediump>;
template struct qua<float64, mediump>;
template struct tquat<float32, highp>;
template struct tquat<float64, highp>;
template struct qua<float32, highp>;
template struct qua<float64, highp>;
//tdualquat type explicit instantiation
template struct tdualquat<float32, lowp>;

View File

@ -38,6 +38,7 @@ namespace glm
template<length_t L, typename T, qualifier Q = defaultp> struct vec;
template<length_t C, length_t R, typename T, qualifier Q = defaultp> struct mat;
template<typename T, qualifier Q = defaultp> struct qua;
namespace detail
{

165
glm/detail/type_quat.hpp Normal file
View File

@ -0,0 +1,165 @@
/// @ref gtc_quaternion
/// @file glm/gtc/quaternion.hpp
///
/// @see core (dependence)
/// @see gtc_constants (dependence)
///
/// @defgroup gtc_quaternion GLM_GTC_quaternion
/// @ingroup gtc
///
/// Include <glm/gtc/quaternion.hpp> to use the features of this extension.
///
/// Defines a templated quaternion type and several quaternion operations.
#pragma once
// Dependency:
#include "../detail/type_mat3x3.hpp"
#include "../detail/type_mat4x4.hpp"
#include "../detail/type_vec3.hpp"
#include "../detail/type_vec4.hpp"
#include "../ext/vector_relational.hpp"
#include "../gtc/constants.hpp"
#include "../gtc/matrix_transform.hpp"
namespace glm
{
/// @addtogroup gtc_quaternion
/// @{
template<typename T, qualifier Q>
struct qua
{
// -- Implementation detail --
typedef qua<T, Q> type;
typedef T value_type;
// -- Data --
# if GLM_LANG & GLM_LANG_CXXMS_FLAG
union
{
struct { T x, y, z, w;};
typename detail::storage<4, T, detail::is_aligned<Q>::value>::type data;
};
# else
T x, y, z, w;
# endif
// -- Component accesses --
typedef length_t length_type;
/// Return the count of components of a quaternion
GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;}
GLM_FUNC_DECL GLM_CONSTEXPR T & operator[](length_type i);
GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const;
// -- Implicit basic constructors --
GLM_FUNC_DECL GLM_CONSTEXPR qua() GLM_DEFAULT;
GLM_FUNC_DECL GLM_CONSTEXPR qua(qua<T, Q> const& q) GLM_DEFAULT;
template<qualifier P>
GLM_FUNC_DECL GLM_CONSTEXPR qua(qua<T, P> const& q);
// -- Explicit basic constructors --
GLM_FUNC_DECL GLM_CONSTEXPR qua(T s, vec<3, T, Q> const& v);
GLM_FUNC_DECL GLM_CONSTEXPR qua(T w, T x, T y, T z);
// -- Conversion constructors --
template<typename U, qualifier P>
GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT qua(qua<U, P> const& q);
/// Explicit conversion operators
# if GLM_HAS_EXPLICIT_CONVERSION_OPERATORS
GLM_FUNC_DECL explicit operator mat<3, 3, T, Q>();
GLM_FUNC_DECL explicit operator mat<4, 4, T, Q>();
# endif
/// Create a quaternion from two normalized axis
///
/// @param u A first normalized axis
/// @param v A second normalized axis
/// @see gtc_quaternion
/// @see http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors
GLM_FUNC_DECL qua(vec<3, T, Q> const& u, vec<3, T, Q> const& v);
/// Build a quaternion from euler angles (pitch, yaw, roll), in radians.
GLM_FUNC_DECL GLM_EXPLICIT qua(vec<3, T, Q> const& eulerAngles);
GLM_FUNC_DECL GLM_EXPLICIT qua(mat<3, 3, T, Q> const& q);
GLM_FUNC_DECL GLM_EXPLICIT qua(mat<4, 4, T, Q> const& q);
// -- Unary arithmetic operators --
GLM_FUNC_DECL qua<T, Q>& operator=(qua<T, Q> const& q) GLM_DEFAULT;
template<typename U>
GLM_FUNC_DECL qua<T, Q>& operator=(qua<U, Q> const& q);
template<typename U>
GLM_FUNC_DECL qua<T, Q>& operator+=(qua<U, Q> const& q);
template<typename U>
GLM_FUNC_DECL qua<T, Q>& operator-=(qua<U, Q> const& q);
template<typename U>
GLM_FUNC_DECL qua<T, Q>& operator*=(qua<U, Q> const& q);
template<typename U>
GLM_FUNC_DECL qua<T, Q>& operator*=(U s);
template<typename U>
GLM_FUNC_DECL qua<T, Q>& operator/=(U s);
};
// -- Unary bit operators --
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> operator+(qua<T, Q> const& q);
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> operator-(qua<T, Q> const& q);
// -- Binary operators --
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> operator+(qua<T, Q> const& q, qua<T, Q> const& p);
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> operator-(qua<T, Q> const& q, qua<T, Q> const& p);
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> operator*(qua<T, Q> const& q, qua<T, Q> const& p);
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> operator*(qua<T, Q> const& q, vec<3, T, Q> const& v);
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua<T, Q> const& q);
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> operator*(qua<T, Q> const& q, vec<4, T, Q> const& v);
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua<T, Q> const& q);
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> operator*(qua<T, Q> const& q, T const& s);
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> operator*(T const& s, qua<T, Q> const& q);
template<typename T, qualifier Q>
GLM_FUNC_DECL qua<T, Q> operator/(qua<T, Q> const& q, T const& s);
// -- Boolean operators --
template<typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(qua<T, Q> const& q1, qua<T, Q> const& q2);
template<typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(qua<T, Q> const& q1, qua<T, Q> const& q2);
/// @}
} //namespace glm
#include "type_quat.inl"

393
glm/detail/type_quat.inl Normal file
View File

@ -0,0 +1,393 @@
/// @ref gtc_quaternion
#include "../trigonometric.hpp"
#include "../geometric.hpp"
#include "../exponential.hpp"
#include <limits>
namespace glm{
namespace detail
{
template <typename T>
struct genTypeTrait<qua<T> >
{
static const genTypeEnum GENTYPE = GENTYPE_QUAT;
};
template<typename T, qualifier Q, bool Aligned>
struct compute_dot<qua<T, Q>, T, Aligned>
{
static GLM_FUNC_QUALIFIER T call(qua<T, Q> const& a, qua<T, Q> const& b)
{
vec<4, T, Q> tmp(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
return (tmp.x + tmp.y) + (tmp.z + tmp.w);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_quat_add
{
static qua<T, Q> call(qua<T, Q> const& q, qua<T, Q> const& p)
{
return qua<T, Q>(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_quat_sub
{
static qua<T, Q> call(qua<T, Q> const& q, qua<T, Q> const& p)
{
return qua<T, Q>(q.w - p.w, q.x - p.x, q.y - p.y, q.z - p.z);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_quat_mul_scalar
{
static qua<T, Q> call(qua<T, Q> const& q, T s)
{
return qua<T, Q>(q.w * s, q.x * s, q.y * s, q.z * s);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_quat_div_scalar
{
static qua<T, Q> call(qua<T, Q> const& q, T s)
{
return qua<T, Q>(q.w / s, q.x / s, q.y / s, q.z / s);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_quat_mul_vec4
{
static vec<4, T, Q> call(qua<T, Q> const& q, vec<4, T, Q> const& v)
{
return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w);
}
};
}//namespace detail
// -- Component accesses --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & qua<T, Q>::operator[](typename qua<T, Q>::length_type i)
{
assert(i >= 0 && i < this->length());
return (&x)[i];
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& qua<T, Q>::operator[](typename qua<T, Q>::length_type i) const
{
assert(i >= 0 && i < this->length());
return (&x)[i];
}
// -- Implicit basic constructors --
# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua()
# if GLM_CONFIG_DEFAULTED_FUNCTIONS != GLM_DISABLE
: x(0), y(0), z(0), w(1)
# endif
{}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(qua<T, Q> const& q)
: x(q.x), y(q.y), z(q.z), w(q.w)
{}
# endif
template<typename T, qualifier Q>
template<qualifier P>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(qua<T, P> const& q)
: x(q.x), y(q.y), z(q.z), w(q.w)
{}
// -- Explicit basic constructors --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(T s, vec<3, T, Q> const& v)
: x(v.x), y(v.y), z(v.z), w(s)
{}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(T _w, T _x, T _y, T _z)
: x(_x), y(_y), z(_z), w(_w)
{}
// -- Conversion constructors --
template<typename T, qualifier Q>
template<typename U, qualifier P>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(qua<U, P> const& q)
: x(static_cast<T>(q.x))
, y(static_cast<T>(q.y))
, z(static_cast<T>(q.z))
, w(static_cast<T>(q.w))
{}
//template<typename valType>
//GLM_FUNC_QUALIFIER qua<valType>::qua
//(
// valType const& pitch,
// valType const& yaw,
// valType const& roll
//)
//{
// vec<3, valType> eulerAngle(pitch * valType(0.5), yaw * valType(0.5), roll * valType(0.5));
// vec<3, valType> c = glm::cos(eulerAngle * valType(0.5));
// vec<3, valType> s = glm::sin(eulerAngle * valType(0.5));
//
// this->w = c.x * c.y * c.z + s.x * s.y * s.z;
// this->x = s.x * c.y * c.z - c.x * s.y * s.z;
// this->y = c.x * s.y * c.z + s.x * c.y * s.z;
// this->z = c.x * c.y * s.z - s.x * s.y * c.z;
//}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q>::qua(vec<3, T, Q> const& u, vec<3, T, Q> const& v)
{
T norm_u_norm_v = sqrt(dot(u, u) * dot(v, v));
T real_part = norm_u_norm_v + dot(u, v);
vec<3, T, Q> t;
if(real_part < static_cast<T>(1.e-6f) * norm_u_norm_v)
{
// If u and v are exactly opposite, rotate 180 degrees
// around an arbitrary orthogonal axis. Axis normalisation
// can happen later, when we normalise the quaternion.
real_part = static_cast<T>(0);
t = abs(u.x) > abs(u.z) ? vec<3, T, Q>(-u.y, u.x, static_cast<T>(0)) : vec<3, T, Q>(static_cast<T>(0), -u.z, u.y);
}
else
{
// Otherwise, build quaternion the standard way.
t = cross(u, v);
}
*this = normalize(qua<T, Q>(real_part, t.x, t.y, t.z));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q>::qua(vec<3, T, Q> const& eulerAngle)
{
vec<3, T, Q> c = glm::cos(eulerAngle * T(0.5));
vec<3, T, Q> s = glm::sin(eulerAngle * T(0.5));
this->w = c.x * c.y * c.z + s.x * s.y * s.z;
this->x = s.x * c.y * c.z - c.x * s.y * s.z;
this->y = c.x * s.y * c.z + s.x * c.y * s.z;
this->z = c.x * c.y * s.z - s.x * s.y * c.z;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q>::qua(mat<3, 3, T, Q> const& m)
{
*this = quat_cast(m);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q>::qua(mat<4, 4, T, Q> const& m)
{
*this = quat_cast(m);
}
# if GLM_HAS_EXPLICIT_CONVERSION_OPERATORS
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q>::operator mat<3, 3, T, Q>()
{
return mat3_cast(*this);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q>::operator mat<4, 4, T, Q>()
{
return mat4_cast(*this);
}
# endif//GLM_HAS_EXPLICIT_CONVERSION_OPERATORS
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> conjugate(qua<T, Q> const& q)
{
return qua<T, Q>(q.w, -q.x, -q.y, -q.z);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> inverse(qua<T, Q> const& q)
{
return conjugate(q) / dot(q, q);
}
// -- Unary arithmetic operators --
# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator=(qua<T, Q> const& q)
{
this->w = q.w;
this->x = q.x;
this->y = q.y;
this->z = q.z;
return *this;
}
# endif
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator=(qua<U, Q> const& q)
{
this->w = static_cast<T>(q.w);
this->x = static_cast<T>(q.x);
this->y = static_cast<T>(q.y);
this->z = static_cast<T>(q.z);
return *this;
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator+=(qua<U, Q> const& q)
{
return (*this = detail::compute_quat_add<T, Q, detail::is_aligned<Q>::value>::call(*this, qua<T, Q>(q)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator-=(qua<U, Q> const& q)
{
return (*this = detail::compute_quat_sub<T, Q, detail::is_aligned<Q>::value>::call(*this, qua<T, Q>(q)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator*=(qua<U, Q> const& r)
{
qua<T, Q> const p(*this);
qua<T, Q> const q(r);
this->w = p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z;
this->x = p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y;
this->y = p.w * q.y + p.y * q.w + p.z * q.x - p.x * q.z;
this->z = p.w * q.z + p.z * q.w + p.x * q.y - p.y * q.x;
return *this;
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator*=(U s)
{
return (*this = detail::compute_quat_mul_scalar<T, Q, detail::is_aligned<Q>::value>::call(*this, static_cast<U>(s)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator/=(U s)
{
return (*this = detail::compute_quat_div_scalar<T, Q, detail::is_aligned<Q>::value>::call(*this, static_cast<U>(s)));
}
// -- Unary bit operators --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> operator+(qua<T, Q> const& q)
{
return q;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> operator-(qua<T, Q> const& q)
{
return qua<T, Q>(-q.w, -q.x, -q.y, -q.z);
}
// -- Binary operators --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> operator+(qua<T, Q> const& q, qua<T, Q> const& p)
{
return qua<T, Q>(q) += p;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> operator-(qua<T, Q> const& q, qua<T, Q> const& p)
{
return qua<T, Q>(q) -= p;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> operator*(qua<T, Q> const& q, qua<T, Q> const& p)
{
return qua<T, Q>(q) *= p;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(qua<T, Q> const& q, vec<3, T, Q> const& v)
{
vec<3, T, Q> const QuatVector(q.x, q.y, q.z);
vec<3, T, Q> const uv(glm::cross(QuatVector, v));
vec<3, T, Q> const uuv(glm::cross(QuatVector, uv));
return v + ((uv * q.w) + uuv) * static_cast<T>(2);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua<T, Q> const& q)
{
return glm::inverse(q) * v;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(qua<T, Q> const& q, vec<4, T, Q> const& v)
{
return detail::compute_quat_mul_vec4<T, Q, detail::is_aligned<Q>::value>::call(q, v);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua<T, Q> const& q)
{
return glm::inverse(q) * v;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> operator*(qua<T, Q> const& q, T const& s)
{
return qua<T, Q>(
q.w * s, q.x * s, q.y * s, q.z * s);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> operator*(T const& s, qua<T, Q> const& q)
{
return q * s;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> operator/(qua<T, Q> const& q, T const& s)
{
return qua<T, Q>(
q.w / s, q.x / s, q.y / s, q.z / s);
}
// -- Boolean operators --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(qua<T, Q> const& q1, qua<T, Q> const& q2)
{
return q1.x == q2.x && q1.y == q2.y && q1.z == q2.z && q1.w == q2.w;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(qua<T, Q> const& q1, qua<T, Q> const& q2)
{
return q1.x != q2.x || q1.y != q2.y || q1.z != q2.z || q1.w != q2.w;
}
}//namespace glm
#if GLM_CONFIG_SIMD == GLM_ENABLE
# include "quaternion_simd.inl"
#endif

View File

@ -0,0 +1,197 @@
/// @ref core
#if GLM_ARCH & GLM_ARCH_SSE2_BIT
namespace glm{
namespace detail
{
/*
template<qualifier Q>
struct compute_quat_mul<float, Q, true>
{
static qua<float, Q> call(qua<float, Q> const& q1, qua<float, Q> const& q2)
{
// SSE2 STATS: 11 shuffle, 8 mul, 8 add
// SSE4 STATS: 3 shuffle, 4 mul, 4 dpps
__m128 const mul0 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(0, 1, 2, 3)));
__m128 const mul1 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(1, 0, 3, 2)));
__m128 const mul2 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(2, 3, 0, 1)));
__m128 const mul3 = _mm_mul_ps(q1.Data, q2.Data);
# if GLM_ARCH & GLM_ARCH_SSE41_BIT
__m128 const add0 = _mm_dp_ps(mul0, _mm_set_ps(1.0f, -1.0f, 1.0f, 1.0f), 0xff);
__m128 const add1 = _mm_dp_ps(mul1, _mm_set_ps(1.0f, 1.0f, 1.0f, -1.0f), 0xff);
__m128 const add2 = _mm_dp_ps(mul2, _mm_set_ps(1.0f, 1.0f, -1.0f, 1.0f), 0xff);
__m128 const add3 = _mm_dp_ps(mul3, _mm_set_ps(1.0f, -1.0f, -1.0f, -1.0f), 0xff);
# else
__m128 const mul4 = _mm_mul_ps(mul0, _mm_set_ps(1.0f, -1.0f, 1.0f, 1.0f));
__m128 const add0 = _mm_add_ps(mul0, _mm_movehl_ps(mul4, mul4));
__m128 const add4 = _mm_add_ss(add0, _mm_shuffle_ps(add0, add0, 1));
__m128 const mul5 = _mm_mul_ps(mul1, _mm_set_ps(1.0f, 1.0f, 1.0f, -1.0f));
__m128 const add1 = _mm_add_ps(mul1, _mm_movehl_ps(mul5, mul5));
__m128 const add5 = _mm_add_ss(add1, _mm_shuffle_ps(add1, add1, 1));
__m128 const mul6 = _mm_mul_ps(mul2, _mm_set_ps(1.0f, 1.0f, -1.0f, 1.0f));
__m128 const add2 = _mm_add_ps(mul6, _mm_movehl_ps(mul6, mul6));
__m128 const add6 = _mm_add_ss(add2, _mm_shuffle_ps(add2, add2, 1));
__m128 const mul7 = _mm_mul_ps(mul3, _mm_set_ps(1.0f, -1.0f, -1.0f, -1.0f));
__m128 const add3 = _mm_add_ps(mul3, _mm_movehl_ps(mul7, mul7));
__m128 const add7 = _mm_add_ss(add3, _mm_shuffle_ps(add3, add3, 1));
#endif
// This SIMD code is a politically correct way of doing this, but in every test I've tried it has been slower than
// the final code below. I'll keep this here for reference - maybe somebody else can do something better...
//
//__m128 xxyy = _mm_shuffle_ps(add4, add5, _MM_SHUFFLE(0, 0, 0, 0));
//__m128 zzww = _mm_shuffle_ps(add6, add7, _MM_SHUFFLE(0, 0, 0, 0));
//
//return _mm_shuffle_ps(xxyy, zzww, _MM_SHUFFLE(2, 0, 2, 0));
qua<float, Q> Result;
_mm_store_ss(&Result.x, add4);
_mm_store_ss(&Result.y, add5);
_mm_store_ss(&Result.z, add6);
_mm_store_ss(&Result.w, add7);
return Result;
}
};
*/
template<qualifier Q>
struct compute_dot<qua<float, Q>, float, true>
{
static GLM_FUNC_QUALIFIER float call(qua<float, Q> const& x, qua<float, Q> const& y)
{
return _mm_cvtss_f32(glm_vec1_dot(x.data, y.data));
}
};
template<qualifier Q>
struct compute_quat_add<float, Q, true>
{
static qua<float, Q> call(qua<float, Q> const& q, qua<float, Q> const& p)
{
qua<float, Q> Result;
Result.data = _mm_add_ps(q.data, p.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX_BIT
template<qualifier Q>
struct compute_quat_add<double, Q, true>
{
static qua<double, Q> call(qua<double, Q> const& a, qua<double, Q> const& b)
{
qua<double, Q> Result;
Result.data = _mm256_add_pd(a.data, b.data);
return Result;
}
};
# endif
template<qualifier Q>
struct compute_quat_sub<float, Q, true>
{
static qua<float, Q> call(qua<float, Q> const& q, qua<float, Q> const& p)
{
vec<4, float, Q> Result;
Result.data = _mm_sub_ps(q.data, p.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX_BIT
template<qualifier Q>
struct compute_quat_sub<double, Q, true>
{
static qua<double, Q> call(qua<double, Q> const& a, qua<double, Q> const& b)
{
qua<double, Q> Result;
Result.data = _mm256_sub_pd(a.data, b.data);
return Result;
}
};
# endif
template<qualifier Q>
struct compute_quat_mul_scalar<float, Q, true>
{
static qua<float, Q> call(qua<float, Q> const& q, float s)
{
vec<4, float, Q> Result;
Result.data = _mm_mul_ps(q.data, _mm_set_ps1(s));
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX_BIT
template<qualifier Q>
struct compute_quat_mul_scalar<double, Q, true>
{
static qua<double, Q> call(qua<double, Q> const& q, double s)
{
qua<double, Q> Result;
Result.data = _mm256_mul_pd(q.data, _mm_set_ps1(s));
return Result;
}
};
# endif
template<qualifier Q>
struct compute_quat_div_scalar<float, Q, true>
{
static qua<float, Q> call(qua<float, Q> const& q, float s)
{
vec<4, float, Q> Result;
Result.data = _mm_div_ps(q.data, _mm_set_ps1(s));
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX_BIT
template<qualifier Q>
struct compute_quat_div_scalar<double, Q, true>
{
static qua<double, Q> call(qua<double, Q> const& q, double s)
{
qua<double, Q> Result;
Result.data = _mm256_div_pd(q.data, _mm_set_ps1(s));
return Result;
}
};
# endif
template<qualifier Q>
struct compute_quat_mul_vec4<float, Q, true>
{
static vec<4, float, Q> call(qua<float, Q> const& q, vec<4, float, Q> const& v)
{
__m128 const q_wwww = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 3, 3, 3));
__m128 const q_swp0 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 0, 2, 1));
__m128 const q_swp1 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 1, 0, 2));
__m128 const v_swp0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 0, 2, 1));
__m128 const v_swp1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 1, 0, 2));
__m128 uv = _mm_sub_ps(_mm_mul_ps(q_swp0, v_swp1), _mm_mul_ps(q_swp1, v_swp0));
__m128 uv_swp0 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 0, 2, 1));
__m128 uv_swp1 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 1, 0, 2));
__m128 uuv = _mm_sub_ps(_mm_mul_ps(q_swp0, uv_swp1), _mm_mul_ps(q_swp1, uv_swp0));
__m128 const two = _mm_set1_ps(2.0f);
uv = _mm_mul_ps(uv, _mm_mul_ps(q_wwww, two));
uuv = _mm_mul_ps(uuv, two);
vec<4, float, Q> Result;
Result.data = _mm_add_ps(v.Data, _mm_add_ps(uv, uuv));
return Result;
}
};
}//namespace detail
}//namespace glm
#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT

View File

@ -0,0 +1,37 @@
/// @ref ext_quaternion_double
/// @file glm/ext/quaternion_double.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_quaternion_double GLM_EXT_quaternion_double
/// @ingroup ext
///
/// Include <glm/ext/quaternion_double.hpp> to use the features of this extension.
///
/// Defines a templated quaternion type and several quaternion operations.
#pragma once
// Dependency:
#include "../detail/type_quat.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_quaternion_double extension included")
#endif
namespace glm
{
/// @addtogroup ext_quaternion_double
/// @{
#if GLM_CONFIG_PRECISION_FLOAT == GLM_HIGHP
typedef qua<double, highp> dquat;
#elif GLM_CONFIG_PRECISION_FLOAT == GLM_MEDIUMP
typedef qua<double, mediump> dquat;
#else
typedef qua<double, lowp> dquat;
#endif
/// @}
} //namespace glm

View File

@ -0,0 +1,44 @@
/// @ref ext_quaternion_double_precision
/// @file glm/ext/quaternion_double_precision.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_quaternion_double_precision GLM_EXT_quaternion_double_precision
/// @ingroup ext
///
/// Include <glm/ext/quaternion_double_precision.hpp> to use the features of this extension.
///
/// Defines a templated quaternion type and several quaternion operations.
#pragma once
// Dependency:
#include "../detail/type_quat.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_quaternion_double_precision extension included")
#endif
namespace glm
{
/// @addtogroup ext_quaternion_double_precision
/// @{
/// Quaternion of double-precision floating-point numbers using high precision arithmetic in term of ULPs.
///
/// @see ext_quaternion_double_precision
typedef qua<double, lowp> lowp_dquat;
/// Quaternion of medium double-qualifier floating-point numbers using high precision arithmetic in term of ULPs.
///
/// @see ext_quaternion_double_precision
typedef qua<double, mediump> mediump_dquat;
/// Quaternion of high double-qualifier floating-point numbers using high precision arithmetic in term of ULPs.
///
/// @see ext_quaternion_double_precision
typedef qua<double, highp> highp_dquat;
/// @}
} //namespace glm

View File

@ -0,0 +1,37 @@
/// @ref quaternion_float
/// @file glm/ext/quaternion_float.hpp
///
/// @see core (dependence)
///
/// @defgroup gtc_quaternion GLM_EXT_quaternion_float
/// @ingroup gtc
///
/// Include <glm/ext/quaternion_float.hpp> to use the features of this extension.
///
/// Defines a templated quaternion type and several quaternion operations.
#pragma once
// Dependency:
#include "../detail/type_quat.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_quaternion_float extension included")
#endif
namespace glm
{
/// @addtogroup ext_quaternion_float
/// @{
#if GLM_CONFIG_PRECISION_FLOAT == GLM_HIGHP
typedef qua<float, highp> quat;
#elif GLM_CONFIG_PRECISION_FLOAT == GLM_MEDIUMP
typedef qua<float, mediump> quat;
#else
typedef qua<float, lowp> quat;
#endif
/// @}
} //namespace glm

View File

@ -0,0 +1,44 @@
/// @ref ext_quaternion_float
/// @file glm/ext/quaternion_float.hpp
///
/// @see core (dependence)
///
/// @defgroup ext_quaternion_float GLM_EXT_quaternion_float
/// @ingroup ext
///
/// Include <glm/ext/quaternion_float.hpp> to use the features of this extension.
///
/// Defines a templated quaternion type and several quaternion operations.
#pragma once
// Dependency:
#include "../detail/type_quat.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_EXT_quaternion_float extension included")
#endif
namespace glm
{
/// @addtogroup ext_quaternion_float
/// @{
/// Quaternion of single-precision floating-point numbers using high precision arithmetic in term of ULPs.
///
/// @see ext_quaternion_float
typedef qua<float, lowp> lowp_quat;
/// Quaternion of single-precision floating-point numbers using high precision arithmetic in term of ULPs.
///
/// @see ext_quaternion_float
typedef qua<float, mediump> mediump_quat;
/// Quaternion of single-precision floating-point numbers using high precision arithmetic in term of ULPs.
///
/// @see ext_quaternion_float
typedef qua<float, highp> highp_quat;
/// @}
} //namespace glm

View File

@ -1,7 +1,6 @@
/// @ref gtc_epsilon
// Dependency:
#include "quaternion.hpp"
#include "../vector_relational.hpp"
#include "../common.hpp"
@ -66,14 +65,14 @@ namespace glm
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> epsilonEqual(tquat<T, Q> const& x, tquat<T, Q> const& y, T const& epsilon)
GLM_FUNC_QUALIFIER vec<4, bool, Q> epsilonEqual(qua<T, Q> const& x, qua<T, Q> const& y, T const& epsilon)
{
vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w);
return lessThan(abs(v), vec<4, T, Q>(epsilon));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> epsilonNotEqual(tquat<T, Q> const& x, tquat<T, Q> const& y, T const& epsilon)
GLM_FUNC_QUALIFIER vec<4, bool, Q> epsilonNotEqual(qua<T, Q> const& x, qua<T, Q> const& y, T const& epsilon)
{
vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w);
return greaterThanEqual(abs(v), vec<4, T, Q>(epsilon));

View File

@ -14,13 +14,17 @@
#pragma once
// Dependency:
#include "../gtc/constants.hpp"
#include "../gtc/matrix_transform.hpp"
#include "../ext/vector_relational.hpp"
#include "../ext/quaternion_float.hpp"
#include "../ext/quaternion_float_precision.hpp"
#include "../ext/quaternion_double.hpp"
#include "../ext/quaternion_double_precision.hpp"
#include "../detail/type_mat3x3.hpp"
#include "../detail/type_mat4x4.hpp"
#include "../detail/type_vec3.hpp"
#include "../detail/type_vec4.hpp"
#include "../ext/vector_relational.hpp"
#include "../gtc/constants.hpp"
#include "../gtc/matrix_transform.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTC_quaternion extension included")
@ -31,137 +35,13 @@ namespace glm
/// @addtogroup gtc_quaternion
/// @{
template<typename T, qualifier Q = defaultp>
struct tquat
{
// -- Implementation detail --
typedef tquat<T, Q> type;
typedef T value_type;
// -- Data --
# if GLM_LANG & GLM_LANG_CXXMS_FLAG
union
{
struct { T x, y, z, w;};
typename detail::storage<4, T, detail::is_aligned<Q>::value>::type data;
};
# else
T x, y, z, w;
# endif
// -- Component accesses --
typedef length_t length_type;
/// Return the count of components of a quaternion
GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;}
GLM_FUNC_DECL GLM_CONSTEXPR T & operator[](length_type i);
GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const;
// -- Implicit basic constructors --
GLM_FUNC_DECL GLM_CONSTEXPR tquat() GLM_DEFAULT;
GLM_FUNC_DECL GLM_CONSTEXPR tquat(tquat<T, Q> const& q) GLM_DEFAULT;
template<qualifier P>
GLM_FUNC_DECL GLM_CONSTEXPR tquat(tquat<T, P> const& q);
// -- Explicit basic constructors --
GLM_FUNC_DECL GLM_CONSTEXPR tquat(T s, vec<3, T, Q> const& v);
GLM_FUNC_DECL GLM_CONSTEXPR tquat(T w, T x, T y, T z);
// -- Conversion constructors --
template<typename U, qualifier P>
GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT tquat(tquat<U, P> const& q);
/// Explicit conversion operators
# if GLM_HAS_EXPLICIT_CONVERSION_OPERATORS
GLM_FUNC_DECL explicit operator mat<3, 3, T, Q>();
GLM_FUNC_DECL explicit operator mat<4, 4, T, Q>();
# endif
/// Create a quaternion from two normalized axis
///
/// @param u A first normalized axis
/// @param v A second normalized axis
/// @see gtc_quaternion
/// @see http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors
GLM_FUNC_DECL tquat(vec<3, T, Q> const& u, vec<3, T, Q> const& v);
/// Build a quaternion from euler angles (pitch, yaw, roll), in radians.
GLM_FUNC_DECL GLM_EXPLICIT tquat(vec<3, T, Q> const& eulerAngles);
GLM_FUNC_DECL GLM_EXPLICIT tquat(mat<3, 3, T, Q> const& q);
GLM_FUNC_DECL GLM_EXPLICIT tquat(mat<4, 4, T, Q> const& q);
// -- Unary arithmetic operators --
GLM_FUNC_DECL tquat<T, Q> & operator=(tquat<T, Q> const& q) GLM_DEFAULT;
template<typename U>
GLM_FUNC_DECL tquat<T, Q> & operator=(tquat<U, Q> const& q);
template<typename U>
GLM_FUNC_DECL tquat<T, Q> & operator+=(tquat<U, Q> const& q);
template<typename U>
GLM_FUNC_DECL tquat<T, Q> & operator-=(tquat<U, Q> const& q);
template<typename U>
GLM_FUNC_DECL tquat<T, Q> & operator*=(tquat<U, Q> const& q);
template<typename U>
GLM_FUNC_DECL tquat<T, Q> & operator*=(U s);
template<typename U>
GLM_FUNC_DECL tquat<T, Q> & operator/=(U s);
};
// -- Unary bit operators --
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> operator+(tquat<T, Q> const& q);
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> operator-(tquat<T, Q> const& q);
// -- Binary operators --
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> operator+(tquat<T, Q> const& q, tquat<T, Q> const& p);
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> operator-(tquat<T, Q> const& q, tquat<T, Q> const& p);
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> operator*(tquat<T, Q> const& q, tquat<T, Q> const& p);
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> operator*(tquat<T, Q> const& q, vec<3, T, Q> const& v);
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> operator*(vec<3, T, Q> const& v, tquat<T, Q> const& q);
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> operator*(tquat<T, Q> const& q, vec<4, T, Q> const& v);
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> operator*(vec<4, T, Q> const& v, tquat<T, Q> const& q);
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> operator*(tquat<T, Q> const& q, T const& s);
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> operator*(T const& s, tquat<T, Q> const& q);
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> operator/(tquat<T, Q> const& q, T const& s);
// -- Boolean operators --
template<typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(tquat<T, Q> const& q1, tquat<T, Q> const& q2);
GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(qua<T, Q> const& q1, qua<T, Q> const& q2);
template<typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(tquat<T, Q> const& q1, tquat<T, Q> const& q2);
GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(qua<T, Q> const& q1, qua<T, Q> const& q2);
/// Builds an identity quaternion.
template<typename genType>
@ -173,7 +53,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T length(tquat<T, Q> const& q);
GLM_FUNC_DECL T length(qua<T, Q> const& q);
/// Returns the normalized quaternion.
///
@ -181,7 +61,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> normalize(tquat<T, Q> const& q);
GLM_FUNC_DECL qua<T, Q> normalize(qua<T, Q> const& q);
/// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ...
///
@ -189,7 +69,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T dot(tquat<T, Q> const& x, tquat<T, Q> const& y);
GLM_FUNC_DECL T dot(qua<T, Q> const& x, qua<T, Q> const& y);
/// Spherical linear interpolation of two quaternions.
/// The interpolation is oriented and the rotation is performed at constant speed.
@ -200,10 +80,10 @@ namespace glm
/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
/// @tparam T Floating-point scalar types.
///
/// @see - slerp(tquat<T, Q> const& x, tquat<T, Q> const& y, T const& a)
/// @see - slerp(qua<T, Q> const& x, qua<T, Q> const& y, T const& a)
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> mix(tquat<T, Q> const& x, tquat<T, Q> const& y, T a);
GLM_FUNC_DECL qua<T, Q> mix(qua<T, Q> const& x, qua<T, Q> const& y, T a);
/// Linear interpolation of two quaternions.
/// The interpolation is oriented.
@ -215,7 +95,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> lerp(tquat<T, Q> const& x, tquat<T, Q> const& y, T a);
GLM_FUNC_DECL qua<T, Q> lerp(qua<T, Q> const& x, qua<T, Q> const& y, T a);
/// Spherical linear interpolation of two quaternions.
/// The interpolation always take the short path and the rotation is performed at constant speed.
@ -227,7 +107,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> slerp(tquat<T, Q> const& x, tquat<T, Q> const& y, T a);
GLM_FUNC_DECL qua<T, Q> slerp(qua<T, Q> const& x, qua<T, Q> const& y, T a);
/// Returns the q conjugate.
///
@ -235,7 +115,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> conjugate(tquat<T, Q> const& q);
GLM_FUNC_DECL qua<T, Q> conjugate(qua<T, Q> const& q);
/// Returns the q inverse.
///
@ -243,7 +123,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> inverse(tquat<T, Q> const& q);
GLM_FUNC_DECL qua<T, Q> inverse(qua<T, Q> const& q);
/// Rotates a quaternion from a vector of 3 components axis and an angle.
///
@ -254,7 +134,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> rotate(tquat<T, Q> const& q, T const& angle, vec<3, T, Q> const& axis);
GLM_FUNC_DECL qua<T, Q> rotate(qua<T, Q> const& q, T const& angle, vec<3, T, Q> const& axis);
/// Returns euler angles, pitch as x, yaw as y, roll as z.
/// The result is expressed in radians.
@ -263,7 +143,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> eulerAngles(tquat<T, Q> const& x);
GLM_FUNC_DECL vec<3, T, Q> eulerAngles(qua<T, Q> const& x);
/// Returns roll value of euler angles expressed in radians.
///
@ -271,7 +151,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T roll(tquat<T, Q> const& x);
GLM_FUNC_DECL T roll(qua<T, Q> const& x);
/// Returns pitch value of euler angles expressed in radians.
///
@ -279,7 +159,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T pitch(tquat<T, Q> const& x);
GLM_FUNC_DECL T pitch(qua<T, Q> const& x);
/// Returns yaw value of euler angles expressed in radians.
///
@ -287,7 +167,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T yaw(tquat<T, Q> const& x);
GLM_FUNC_DECL T yaw(qua<T, Q> const& x);
/// Converts a quaternion to a 3 * 3 matrix.
///
@ -295,7 +175,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL mat<3, 3, T, Q> mat3_cast(tquat<T, Q> const& x);
GLM_FUNC_DECL mat<3, 3, T, Q> mat3_cast(qua<T, Q> const& x);
/// Converts a quaternion to a 4 * 4 matrix.
///
@ -303,7 +183,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL mat<4, 4, T, Q> mat4_cast(tquat<T, Q> const& x);
GLM_FUNC_DECL mat<4, 4, T, Q> mat4_cast(qua<T, Q> const& x);
/// Converts a pure rotation 3 * 3 matrix to a quaternion.
///
@ -311,7 +191,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> quat_cast(mat<3, 3, T, Q> const& x);
GLM_FUNC_DECL qua<T, Q> quat_cast(mat<3, 3, T, Q> const& x);
/// Converts a pure rotation 4 * 4 matrix to a quaternion.
///
@ -319,7 +199,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> quat_cast(mat<4, 4, T, Q> const& x);
GLM_FUNC_DECL qua<T, Q> quat_cast(mat<4, 4, T, Q> const& x);
/// Returns the quaternion rotation angle.
///
@ -327,7 +207,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T angle(tquat<T, Q> const& x);
GLM_FUNC_DECL T angle(qua<T, Q> const& x);
/// Returns the q rotation axis.
///
@ -335,7 +215,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> axis(tquat<T, Q> const& x);
GLM_FUNC_DECL vec<3, T, Q> axis(qua<T, Q> const& x);
/// Build a quaternion from an angle and a normalized axis.
///
@ -345,7 +225,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> angleAxis(T const& angle, vec<3, T, Q> const& axis);
GLM_FUNC_DECL qua<T, Q> angleAxis(T const& angle, vec<3, T, Q> const& axis);
/// Returns the component-wise comparison result of x < y.
///
@ -353,7 +233,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, bool, Q> lessThan(tquat<T, Q> const& x, tquat<T, Q> const& y);
GLM_FUNC_DECL vec<4, bool, Q> lessThan(qua<T, Q> const& x, qua<T, Q> const& y);
/// Returns the component-wise comparison of result x <= y.
///
@ -361,7 +241,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, bool, Q> lessThanEqual(tquat<T, Q> const& x, tquat<T, Q> const& y);
GLM_FUNC_DECL vec<4, bool, Q> lessThanEqual(qua<T, Q> const& x, qua<T, Q> const& y);
/// Returns the component-wise comparison of result x > y.
///
@ -369,7 +249,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, bool, Q> greaterThan(tquat<T, Q> const& x, tquat<T, Q> const& y);
GLM_FUNC_DECL vec<4, bool, Q> greaterThan(qua<T, Q> const& x, qua<T, Q> const& y);
/// Returns the component-wise comparison of result x >= y.
///
@ -377,7 +257,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, bool, Q> greaterThanEqual(tquat<T, Q> const& x, tquat<T, Q> const& y);
GLM_FUNC_DECL vec<4, bool, Q> greaterThanEqual(qua<T, Q> const& x, qua<T, Q> const& y);
/// Returns the component-wise comparison of result x == y.
///
@ -385,7 +265,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, bool, Q> equal(tquat<T, Q> const& x, tquat<T, Q> const& y);
GLM_FUNC_DECL vec<4, bool, Q> equal(qua<T, Q> const& x, qua<T, Q> const& y);
/// Returns the component-wise comparison of |x - y| < epsilon.
///
@ -393,7 +273,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, bool, Q> equal(tquat<T, Q> const& x, tquat<T, Q> const& y, T epsilon);
GLM_FUNC_DECL vec<4, bool, Q> equal(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon);
/// Returns the component-wise comparison of result x != y.
///
@ -401,7 +281,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, bool, Q> notEqual(tquat<T, Q> const& x, tquat<T, Q> const& y);
GLM_FUNC_DECL vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y);
/// Returns the component-wise comparison of |x - y| >= epsilon.
///
@ -409,7 +289,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, bool, Q> notEqual(tquat<T, Q> const& x, tquat<T, Q> const& y, T epsilon);
GLM_FUNC_DECL vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon);
/// Returns true if x holds a NaN (not a number)
@ -424,7 +304,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, bool, Q> isnan(tquat<T, Q> const& x);
GLM_FUNC_DECL vec<4, bool, Q> isnan(qua<T, Q> const& x);
/// Returns true if x holds a positive infinity or negative
/// infinity representation in the underlying implementation's
@ -436,81 +316,7 @@ namespace glm
///
/// @see gtc_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, bool, Q> isinf(tquat<T, Q> const& x);
/// Quaternion of low single-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef tquat<float, lowp> lowp_quat;
/// Quaternion of medium single-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef tquat<float, mediump> mediump_quat;
/// Quaternion of high single-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef tquat<float, highp> highp_quat;
#if(defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
typedef highp_quat quat;
#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
typedef mediump_quat quat;
#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && defined(GLM_PRECISION_LOWP_FLOAT))
typedef lowp_quat quat;
#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
/// Quaternion of default single-qualifier floating-point numbers.
typedef highp_quat quat;
#endif
/// Quaternion of low single-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef lowp_quat lowp_fquat;
/// Quaternion of medium single-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef mediump_quat mediump_fquat;
/// Quaternion of high single-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef highp_quat highp_fquat;
/// Quaternion of default single-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef quat fquat;
/// Quaternion of low double-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef tquat<double, lowp> lowp_dquat;
/// Quaternion of medium double-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef tquat<double, mediump> mediump_dquat;
/// Quaternion of high double-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef tquat<double, highp> highp_dquat;
#if(defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
typedef highp_dquat dquat;
#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
typedef mediump_dquat dquat;
#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && defined(GLM_PRECISION_LOWP_DOUBLE))
typedef lowp_dquat dquat;
#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
/// Quaternion of default double-qualifier floating-point numbers.
///
/// @see gtc_quaternion
typedef highp_dquat dquat;
#endif
GLM_FUNC_DECL vec<4, bool, Q> isinf(qua<T, Q> const& x);
/// @}
} //namespace glm

View File

@ -6,416 +6,37 @@
#include "epsilon.hpp"
#include <limits>
namespace glm{
namespace detail
namespace glm
{
template <typename T>
struct genTypeTrait<tquat<T> >
{
static const genTypeEnum GENTYPE = GENTYPE_QUAT;
};
template<typename T, qualifier Q, bool Aligned>
struct compute_dot<tquat<T, Q>, T, Aligned>
{
static GLM_FUNC_QUALIFIER T call(tquat<T, Q> const& a, tquat<T, Q> const& b)
{
vec<4, T, Q> tmp(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
return (tmp.x + tmp.y) + (tmp.z + tmp.w);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_quat_add
{
static tquat<T, Q> call(tquat<T, Q> const& q, tquat<T, Q> const& p)
{
return tquat<T, Q>(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_quat_sub
{
static tquat<T, Q> call(tquat<T, Q> const& q, tquat<T, Q> const& p)
{
return tquat<T, Q>(q.w - p.w, q.x - p.x, q.y - p.y, q.z - p.z);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_quat_mul_scalar
{
static tquat<T, Q> call(tquat<T, Q> const& q, T s)
{
return tquat<T, Q>(q.w * s, q.x * s, q.y * s, q.z * s);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_quat_div_scalar
{
static tquat<T, Q> call(tquat<T, Q> const& q, T s)
{
return tquat<T, Q>(q.w / s, q.x / s, q.y / s, q.z / s);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_quat_mul_vec4
{
static vec<4, T, Q> call(tquat<T, Q> const& q, vec<4, T, Q> const& v)
{
return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w);
}
};
}//namespace detail
// -- Component accesses --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & tquat<T, Q>::operator[](typename tquat<T, Q>::length_type i)
{
assert(i >= 0 && i < this->length());
return (&x)[i];
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& tquat<T, Q>::operator[](typename tquat<T, Q>::length_type i) const
{
assert(i >= 0 && i < this->length());
return (&x)[i];
}
// -- Implicit basic constructors --
# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tquat<T, Q>::tquat()
# if GLM_CONFIG_DEFAULTED_FUNCTIONS != GLM_DISABLE
: x(0), y(0), z(0), w(1)
# endif
{}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tquat<T, Q>::tquat(tquat<T, Q> const& q)
: x(q.x), y(q.y), z(q.z), w(q.w)
{}
# endif
template<typename T, qualifier Q>
template<qualifier P>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tquat<T, Q>::tquat(tquat<T, P> const& q)
: x(q.x), y(q.y), z(q.z), w(q.w)
{}
// -- Explicit basic constructors --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tquat<T, Q>::tquat(T s, vec<3, T, Q> const& v)
: x(v.x), y(v.y), z(v.z), w(s)
{}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tquat<T, Q>::tquat(T _w, T _x, T _y, T _z)
: x(_x), y(_y), z(_z), w(_w)
{}
// -- Conversion constructors --
template<typename T, qualifier Q>
template<typename U, qualifier P>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tquat<T, Q>::tquat(tquat<U, P> const& q)
: x(static_cast<T>(q.x))
, y(static_cast<T>(q.y))
, z(static_cast<T>(q.z))
, w(static_cast<T>(q.w))
{}
//template<typename valType>
//GLM_FUNC_QUALIFIER tquat<valType>::tquat
//(
// valType const& pitch,
// valType const& yaw,
// valType const& roll
//)
//{
// vec<3, valType> eulerAngle(pitch * valType(0.5), yaw * valType(0.5), roll * valType(0.5));
// vec<3, valType> c = glm::cos(eulerAngle * valType(0.5));
// vec<3, valType> s = glm::sin(eulerAngle * valType(0.5));
//
// this->w = c.x * c.y * c.z + s.x * s.y * s.z;
// this->x = s.x * c.y * c.z - c.x * s.y * s.z;
// this->y = c.x * s.y * c.z + s.x * c.y * s.z;
// this->z = c.x * c.y * s.z - s.x * s.y * c.z;
//}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q>::tquat(vec<3, T, Q> const& u, vec<3, T, Q> const& v)
{
T norm_u_norm_v = sqrt(dot(u, u) * dot(v, v));
T real_part = norm_u_norm_v + dot(u, v);
vec<3, T, Q> t;
if(real_part < static_cast<T>(1.e-6f) * norm_u_norm_v)
{
// If u and v are exactly opposite, rotate 180 degrees
// around an arbitrary orthogonal axis. Axis normalisation
// can happen later, when we normalise the quaternion.
real_part = static_cast<T>(0);
t = abs(u.x) > abs(u.z) ? vec<3, T, Q>(-u.y, u.x, static_cast<T>(0)) : vec<3, T, Q>(static_cast<T>(0), -u.z, u.y);
}
else
{
// Otherwise, build quaternion the standard way.
t = cross(u, v);
}
*this = normalize(tquat<T, Q>(real_part, t.x, t.y, t.z));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q>::tquat(vec<3, T, Q> const& eulerAngle)
{
vec<3, T, Q> c = glm::cos(eulerAngle * T(0.5));
vec<3, T, Q> s = glm::sin(eulerAngle * T(0.5));
this->w = c.x * c.y * c.z + s.x * s.y * s.z;
this->x = s.x * c.y * c.z - c.x * s.y * s.z;
this->y = c.x * s.y * c.z + s.x * c.y * s.z;
this->z = c.x * c.y * s.z - s.x * s.y * c.z;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q>::tquat(mat<3, 3, T, Q> const& m)
{
*this = quat_cast(m);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q>::tquat(mat<4, 4, T, Q> const& m)
{
*this = quat_cast(m);
}
# if GLM_HAS_EXPLICIT_CONVERSION_OPERATORS
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q>::operator mat<3, 3, T, Q>()
{
return mat3_cast(*this);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q>::operator mat<4, 4, T, Q>()
{
return mat4_cast(*this);
}
# endif//GLM_HAS_EXPLICIT_CONVERSION_OPERATORS
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> conjugate(tquat<T, Q> const& q)
{
return tquat<T, Q>(q.w, -q.x, -q.y, -q.z);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> inverse(tquat<T, Q> const& q)
{
return conjugate(q) / dot(q, q);
}
// -- Unary arithmetic operators --
# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> & tquat<T, Q>::operator=(tquat<T, Q> const& q)
{
this->w = q.w;
this->x = q.x;
this->y = q.y;
this->z = q.z;
return *this;
}
# endif
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER tquat<T, Q> & tquat<T, Q>::operator=(tquat<U, Q> const& q)
{
this->w = static_cast<T>(q.w);
this->x = static_cast<T>(q.x);
this->y = static_cast<T>(q.y);
this->z = static_cast<T>(q.z);
return *this;
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER tquat<T, Q> & tquat<T, Q>::operator+=(tquat<U, Q> const& q)
{
return (*this = detail::compute_quat_add<T, Q, detail::is_aligned<Q>::value>::call(*this, tquat<T, Q>(q)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER tquat<T, Q> & tquat<T, Q>::operator-=(tquat<U, Q> const& q)
{
return (*this = detail::compute_quat_sub<T, Q, detail::is_aligned<Q>::value>::call(*this, tquat<T, Q>(q)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER tquat<T, Q> & tquat<T, Q>::operator*=(tquat<U, Q> const& r)
{
tquat<T, Q> const p(*this);
tquat<T, Q> const q(r);
this->w = p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z;
this->x = p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y;
this->y = p.w * q.y + p.y * q.w + p.z * q.x - p.x * q.z;
this->z = p.w * q.z + p.z * q.w + p.x * q.y - p.y * q.x;
return *this;
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER tquat<T, Q> & tquat<T, Q>::operator*=(U s)
{
return (*this = detail::compute_quat_mul_scalar<T, Q, detail::is_aligned<Q>::value>::call(*this, static_cast<U>(s)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER tquat<T, Q> & tquat<T, Q>::operator/=(U s)
{
return (*this = detail::compute_quat_div_scalar<T, Q, detail::is_aligned<Q>::value>::call(*this, static_cast<U>(s)));
}
// -- Unary bit operators --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> operator+(tquat<T, Q> const& q)
{
return q;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> operator-(tquat<T, Q> const& q)
{
return tquat<T, Q>(-q.w, -q.x, -q.y, -q.z);
}
// -- Binary operators --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> operator+(tquat<T, Q> const& q, tquat<T, Q> const& p)
{
return tquat<T, Q>(q) += p;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> operator-(tquat<T, Q> const& q, tquat<T, Q> const& p)
{
return tquat<T, Q>(q) -= p;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> operator*(tquat<T, Q> const& q, tquat<T, Q> const& p)
{
return tquat<T, Q>(q) *= p;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(tquat<T, Q> const& q, vec<3, T, Q> const& v)
{
vec<3, T, Q> const QuatVector(q.x, q.y, q.z);
vec<3, T, Q> const uv(glm::cross(QuatVector, v));
vec<3, T, Q> const uuv(glm::cross(QuatVector, uv));
return v + ((uv * q.w) + uuv) * static_cast<T>(2);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(vec<3, T, Q> const& v, tquat<T, Q> const& q)
{
return glm::inverse(q) * v;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(tquat<T, Q> const& q, vec<4, T, Q> const& v)
{
return detail::compute_quat_mul_vec4<T, Q, detail::is_aligned<Q>::value>::call(q, v);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(vec<4, T, Q> const& v, tquat<T, Q> const& q)
{
return glm::inverse(q) * v;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> operator*(tquat<T, Q> const& q, T const& s)
{
return tquat<T, Q>(
q.w * s, q.x * s, q.y * s, q.z * s);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> operator*(T const& s, tquat<T, Q> const& q)
{
return q * s;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> operator/(tquat<T, Q> const& q, T const& s)
{
return tquat<T, Q>(
q.w / s, q.x / s, q.y / s, q.z / s);
}
// -- Boolean operators --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(tquat<T, Q> const& q1, tquat<T, Q> const& q2)
{
return q1.x == q2.x && q1.y == q2.y && q1.z == q2.z && q1.w == q2.w;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(tquat<T, Q> const& q1, tquat<T, Q> const& q2)
{
return q1.x != q2.x || q1.y != q2.y || q1.z != q2.z || q1.w != q2.w;
}
// -- Operations --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T dot(tquat<T, Q> const& x, tquat<T, Q> const& y)
GLM_FUNC_QUALIFIER T dot(qua<T, Q> const& x, qua<T, Q> const& y)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'dot' accepts only floating-point inputs");
return detail::compute_dot<tquat<T, Q>, T, detail::is_aligned<Q>::value>::call(x, y);
return detail::compute_dot<qua<T, Q>, T, detail::is_aligned<Q>::value>::call(x, y);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T length(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER T length(qua<T, Q> const& q)
{
return glm::sqrt(dot(q, q));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> normalize(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER qua<T, Q> normalize(qua<T, Q> const& q)
{
T len = length(q);
if(len <= T(0)) // Problem
return tquat<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
return qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
T oneOverLen = T(1) / len;
return tquat<T, Q>(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen);
return qua<T, Q>(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> cross(tquat<T, Q> const& q1, tquat<T, Q> const& q2)
GLM_FUNC_QUALIFIER qua<T, Q> cross(qua<T, Q> const& q1, qua<T, Q> const& q2)
{
return tquat<T, Q>(
return qua<T, Q>(
q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z,
q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,
q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z,
@ -424,13 +45,13 @@ namespace detail
/*
// (x * sin(1 - a) * angle / sin(angle)) + (y * sin(a) * angle / sin(angle))
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> mix(tquat<T, Q> const& x, tquat<T, Q> const& y, T const& a)
GLM_FUNC_QUALIFIER qua<T, Q> mix(qua<T, Q> const& x, qua<T, Q> const& y, T const& a)
{
if(a <= T(0)) return x;
if(a >= T(1)) return y;
float fCos = dot(x, y);
tquat<T, Q> y2(y); //BUG!!! tquat<T, Q> y2;
qua<T, Q> y2(y); //BUG!!! qua<T, Q> y2;
if(fCos < T(0))
{
y2 = -y;
@ -453,7 +74,7 @@ namespace detail
k1 = sin((T(0) + a) * fAngle) * fOneOverSin;
}
return tquat<T, Q>(
return qua<T, Q>(
k0 * x.w + k1 * y2.w,
k0 * x.x + k1 * y2.x,
k0 * x.y + k1 * y2.y,
@ -461,10 +82,10 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> mix2
GLM_FUNC_QUALIFIER qua<T, Q> mix2
(
tquat<T, Q> const& x,
tquat<T, Q> const& y,
qua<T, Q> const& x,
qua<T, Q> const& y,
T const& a
)
{
@ -499,7 +120,7 @@ namespace detail
*/
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> mix(tquat<T, Q> const& x, tquat<T, Q> const& y, T a)
GLM_FUNC_QUALIFIER qua<T, Q> mix(qua<T, Q> const& x, qua<T, Q> const& y, T a)
{
T cosTheta = dot(x, y);
@ -507,7 +128,7 @@ namespace detail
if(cosTheta > T(1) - epsilon<T>())
{
// Linear interpolation
return tquat<T, Q>(
return qua<T, Q>(
mix(x.w, y.w, a),
mix(x.x, y.x, a),
mix(x.y, y.y, a),
@ -522,7 +143,7 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> lerp(tquat<T, Q> const& x, tquat<T, Q> const& y, T a)
GLM_FUNC_QUALIFIER qua<T, Q> lerp(qua<T, Q> const& x, qua<T, Q> const& y, T a)
{
// Lerp is only defined in [0, 1]
assert(a >= static_cast<T>(0));
@ -532,9 +153,9 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> slerp(tquat<T, Q> const& x, tquat<T, Q> const& y, T a)
GLM_FUNC_QUALIFIER qua<T, Q> slerp(qua<T, Q> const& x, qua<T, Q> const& y, T a)
{
tquat<T, Q> z = y;
qua<T, Q> z = y;
T cosTheta = dot(x, y);
@ -550,7 +171,7 @@ namespace detail
if(cosTheta > T(1) - epsilon<T>())
{
// Linear interpolation
return tquat<T, Q>(
return qua<T, Q>(
mix(x.w, z.w, a),
mix(x.x, z.x, a),
mix(x.y, z.y, a),
@ -565,7 +186,7 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> rotate(tquat<T, Q> const& q, T const& angle, vec<3, T, Q> const& v)
GLM_FUNC_QUALIFIER qua<T, Q> rotate(qua<T, Q> const& q, T const& angle, vec<3, T, Q> const& v)
{
vec<3, T, Q> Tmp = v;
@ -582,24 +203,24 @@ namespace detail
T const AngleRad(angle);
T const Sin = sin(AngleRad * T(0.5));
return q * tquat<T, Q>(cos(AngleRad * T(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
//return gtc::quaternion::cross(q, tquat<T, Q>(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin));
return q * qua<T, Q>(cos(AngleRad * T(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
//return gtc::quaternion::cross(q, qua<T, Q>(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> eulerAngles(tquat<T, Q> const& x)
GLM_FUNC_QUALIFIER vec<3, T, Q> eulerAngles(qua<T, Q> const& x)
{
return vec<3, T, Q>(pitch(x), yaw(x), roll(x));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T roll(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER T roll(qua<T, Q> const& q)
{
return static_cast<T>(atan(static_cast<T>(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T pitch(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER T pitch(qua<T, Q> const& q)
{
//return T(atan(T(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z));
T const y = static_cast<T>(2) * (q.y * q.z + q.w * q.x);
@ -612,13 +233,13 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T yaw(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER T yaw(qua<T, Q> const& q)
{
return asin(clamp(static_cast<T>(-2) * (q.x * q.z - q.w * q.y), static_cast<T>(-1), static_cast<T>(1)));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> mat3_cast(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> mat3_cast(qua<T, Q> const& q)
{
mat<3, 3, T, Q> Result(T(1));
T qxx(q.x * q.x);
@ -646,13 +267,13 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> mat4_cast(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> mat4_cast(qua<T, Q> const& q)
{
return mat<4, 4, T, Q>(mat3_cast(q));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> quat_cast(mat<3, 3, T, Q> const& m)
GLM_FUNC_QUALIFIER qua<T, Q> quat_cast(mat<3, 3, T, Q> const& m)
{
T fourXSquaredMinus1 = m[0][0] - m[1][1] - m[2][2];
T fourYSquaredMinus1 = m[1][1] - m[0][0] - m[2][2];
@ -683,33 +304,33 @@ namespace detail
switch(biggestIndex)
{
case 0:
return tquat<T, Q>(biggestVal, (m[1][2] - m[2][1]) * mult, (m[2][0] - m[0][2]) * mult, (m[0][1] - m[1][0]) * mult);
return qua<T, Q>(biggestVal, (m[1][2] - m[2][1]) * mult, (m[2][0] - m[0][2]) * mult, (m[0][1] - m[1][0]) * mult);
case 1:
return tquat<T, Q>((m[1][2] - m[2][1]) * mult, biggestVal, (m[0][1] + m[1][0]) * mult, (m[2][0] + m[0][2]) * mult);
return qua<T, Q>((m[1][2] - m[2][1]) * mult, biggestVal, (m[0][1] + m[1][0]) * mult, (m[2][0] + m[0][2]) * mult);
case 2:
return tquat<T, Q>((m[2][0] - m[0][2]) * mult, (m[0][1] + m[1][0]) * mult, biggestVal, (m[1][2] + m[2][1]) * mult);
return qua<T, Q>((m[2][0] - m[0][2]) * mult, (m[0][1] + m[1][0]) * mult, biggestVal, (m[1][2] + m[2][1]) * mult);
case 3:
return tquat<T, Q>((m[0][1] - m[1][0]) * mult, (m[2][0] + m[0][2]) * mult, (m[1][2] + m[2][1]) * mult, biggestVal);
return qua<T, Q>((m[0][1] - m[1][0]) * mult, (m[2][0] + m[0][2]) * mult, (m[1][2] + m[2][1]) * mult, biggestVal);
default: // Silence a -Wswitch-default warning in GCC. Should never actually get here. Assert is just for sanity.
assert(false);
return tquat<T, Q>(1, 0, 0, 0);
return qua<T, Q>(1, 0, 0, 0);
}
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> quat_cast(mat<4, 4, T, Q> const& m4)
GLM_FUNC_QUALIFIER qua<T, Q> quat_cast(mat<4, 4, T, Q> const& m4)
{
return quat_cast(mat<3, 3, T, Q>(m4));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T angle(tquat<T, Q> const& x)
GLM_FUNC_QUALIFIER T angle(qua<T, Q> const& x)
{
return acos(x.w) * static_cast<T>(2);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> axis(tquat<T, Q> const& x)
GLM_FUNC_QUALIFIER vec<3, T, Q> axis(qua<T, Q> const& x)
{
T tmp1 = static_cast<T>(1) - x.w * x.w;
if(tmp1 <= static_cast<T>(0))
@ -719,9 +340,9 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> angleAxis(T const& angle, vec<3, T, Q> const& v)
GLM_FUNC_QUALIFIER qua<T, Q> angleAxis(T const& angle, vec<3, T, Q> const& v)
{
tquat<T, Q> Result;
qua<T, Q> Result;
T const a(angle);
T const s = glm::sin(a * static_cast<T>(0.5));
@ -734,7 +355,7 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThan(tquat<T, Q> const& x, tquat<T, Q> const& y)
GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThan(qua<T, Q> const& x, qua<T, Q> const& y)
{
vec<4, bool, Q> Result;
for(length_t i = 0; i < x.length(); ++i)
@ -743,7 +364,7 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThanEqual(tquat<T, Q> const& x, tquat<T, Q> const& y)
GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThanEqual(qua<T, Q> const& x, qua<T, Q> const& y)
{
vec<4, bool, Q> Result;
for(length_t i = 0; i < x.length(); ++i)
@ -752,7 +373,7 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThan(tquat<T, Q> const& x, tquat<T, Q> const& y)
GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThan(qua<T, Q> const& x, qua<T, Q> const& y)
{
vec<4, bool, Q> Result;
for(length_t i = 0; i < x.length(); ++i)
@ -761,7 +382,7 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThanEqual(tquat<T, Q> const& x, tquat<T, Q> const& y)
GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThanEqual(qua<T, Q> const& x, qua<T, Q> const& y)
{
vec<4, bool, Q> Result;
for(length_t i = 0; i < x.length(); ++i)
@ -770,7 +391,7 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(tquat<T, Q> const& x, tquat<T, Q> const& y)
GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(qua<T, Q> const& x, qua<T, Q> const& y)
{
vec<4, bool, Q> Result;
for(length_t i = 0; i < x.length(); ++i)
@ -779,14 +400,14 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(tquat<T, Q> const& x, tquat<T, Q> const& y, T epsilon)
GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon)
{
vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w);
return lessThan(abs(v), vec<4, T, Q>(epsilon));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(tquat<T, Q> const& x, tquat<T, Q> const& y)
GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y)
{
vec<4, bool, Q> Result;
for(length_t i = 0; i < x.length(); ++i)
@ -795,14 +416,14 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(tquat<T, Q> const& x, tquat<T, Q> const& y, T epsilon)
GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon)
{
vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w);
return greaterThanEqual(abs(v), vec<4, T, Q>(epsilon));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> isnan(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER vec<4, bool, Q> isnan(qua<T, Q> const& q)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isnan' only accept floating-point inputs");
@ -810,7 +431,7 @@ namespace detail
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, bool, Q> isinf(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER vec<4, bool, Q> isinf(qua<T, Q> const& q)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isinf' only accept floating-point inputs");

View File

@ -9,7 +9,7 @@ namespace detail
template<qualifier Q>
struct compute_quat_mul<float, Q, true>
{
static tquat<float, Q> call(tquat<float, Q> const& q1, tquat<float, Q> const& q2)
static qua<float, Q> call(qua<float, Q> const& q1, qua<float, Q> const& q2)
{
// SSE2 STATS: 11 shuffle, 8 mul, 8 add
// SSE4 STATS: 3 shuffle, 4 mul, 4 dpps
@ -50,7 +50,7 @@ namespace detail
//
//return _mm_shuffle_ps(xxyy, zzww, _MM_SHUFFLE(2, 0, 2, 0));
tquat<float, Q> Result;
qua<float, Q> Result;
_mm_store_ss(&Result.x, add4);
_mm_store_ss(&Result.y, add5);
_mm_store_ss(&Result.z, add6);
@ -61,9 +61,9 @@ namespace detail
*/
template<qualifier Q>
struct compute_dot<tquat<float, Q>, float, true>
struct compute_dot<qua<float, Q>, float, true>
{
static GLM_FUNC_QUALIFIER float call(tquat<float, Q> const& x, tquat<float, Q> const& y)
static GLM_FUNC_QUALIFIER float call(qua<float, Q> const& x, qua<float, Q> const& y)
{
return _mm_cvtss_f32(glm_vec1_dot(x.data, y.data));
}
@ -72,9 +72,9 @@ namespace detail
template<qualifier Q>
struct compute_quat_add<float, Q, true>
{
static tquat<float, Q> call(tquat<float, Q> const& q, tquat<float, Q> const& p)
static qua<float, Q> call(qua<float, Q> const& q, qua<float, Q> const& p)
{
tquat<float, Q> Result;
qua<float, Q> Result;
Result.data = _mm_add_ps(q.data, p.data);
return Result;
}
@ -84,9 +84,9 @@ namespace detail
template<qualifier Q>
struct compute_quat_add<double, Q, true>
{
static tquat<double, Q> call(tquat<double, Q> const& a, tquat<double, Q> const& b)
static qua<double, Q> call(qua<double, Q> const& a, qua<double, Q> const& b)
{
tquat<double, Q> Result;
qua<double, Q> Result;
Result.data = _mm256_add_pd(a.data, b.data);
return Result;
}
@ -96,7 +96,7 @@ namespace detail
template<qualifier Q>
struct compute_quat_sub<float, Q, true>
{
static tquat<float, Q> call(tquat<float, Q> const& q, tquat<float, Q> const& p)
static qua<float, Q> call(qua<float, Q> const& q, qua<float, Q> const& p)
{
vec<4, float, Q> Result;
Result.data = _mm_sub_ps(q.data, p.data);
@ -108,9 +108,9 @@ namespace detail
template<qualifier Q>
struct compute_quat_sub<double, Q, true>
{
static tquat<double, Q> call(tquat<double, Q> const& a, tquat<double, Q> const& b)
static qua<double, Q> call(qua<double, Q> const& a, qua<double, Q> const& b)
{
tquat<double, Q> Result;
qua<double, Q> Result;
Result.data = _mm256_sub_pd(a.data, b.data);
return Result;
}
@ -120,7 +120,7 @@ namespace detail
template<qualifier Q>
struct compute_quat_mul_scalar<float, Q, true>
{
static tquat<float, Q> call(tquat<float, Q> const& q, float s)
static qua<float, Q> call(qua<float, Q> const& q, float s)
{
vec<4, float, Q> Result;
Result.data = _mm_mul_ps(q.data, _mm_set_ps1(s));
@ -132,9 +132,9 @@ namespace detail
template<qualifier Q>
struct compute_quat_mul_scalar<double, Q, true>
{
static tquat<double, Q> call(tquat<double, Q> const& q, double s)
static qua<double, Q> call(qua<double, Q> const& q, double s)
{
tquat<double, Q> Result;
qua<double, Q> Result;
Result.data = _mm256_mul_pd(q.data, _mm_set_ps1(s));
return Result;
}
@ -144,7 +144,7 @@ namespace detail
template<qualifier Q>
struct compute_quat_div_scalar<float, Q, true>
{
static tquat<float, Q> call(tquat<float, Q> const& q, float s)
static qua<float, Q> call(qua<float, Q> const& q, float s)
{
vec<4, float, Q> Result;
Result.data = _mm_div_ps(q.data, _mm_set_ps1(s));
@ -156,9 +156,9 @@ namespace detail
template<qualifier Q>
struct compute_quat_div_scalar<double, Q, true>
{
static tquat<double, Q> call(tquat<double, Q> const& q, double s)
static qua<double, Q> call(qua<double, Q> const& q, double s)
{
tquat<double, Q> Result;
qua<double, Q> Result;
Result.data = _mm256_div_pd(q.data, _mm_set_ps1(s));
return Result;
}
@ -168,7 +168,7 @@ namespace detail
template<qualifier Q>
struct compute_quat_mul_vec4<float, Q, true>
{
static vec<4, float, Q> call(tquat<float, Q> const& q, vec<4, float, Q> const& v)
static vec<4, float, Q> call(qua<float, Q> const& q, vec<4, float, Q> const& v)
{
__m128 const q_wwww = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 3, 3, 3));
__m128 const q_swp0 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 0, 2, 1));

View File

@ -2204,37 +2204,37 @@ namespace glm
/// Single-qualifier floating-point quaternion.
/// @see gtc_type_precision
typedef tquat<f32, defaultp> f32quat;
typedef qua<f32, defaultp> f32quat;
/// Low single-qualifier floating-point quaternion.
/// @see gtc_type_precision
typedef tquat<f32, lowp> lowp_f32quat;
typedef qua<f32, lowp> lowp_f32quat;
/// Low double-qualifier floating-point quaternion.
/// @see gtc_type_precision
typedef tquat<f64, lowp> lowp_f64quat;
typedef qua<f64, lowp> lowp_f64quat;
/// Medium single-qualifier floating-point quaternion.
/// @see gtc_type_precision
typedef tquat<f32, mediump> mediump_f32quat;
typedef qua<f32, mediump> mediump_f32quat;
# ifndef GLM_FORCE_SINGLE_ONLY
/// Medium double-qualifier floating-point quaternion.
/// @see gtc_type_precision
typedef tquat<f64, mediump> mediump_f64quat;
typedef qua<f64, mediump> mediump_f64quat;
/// High single-qualifier floating-point quaternion.
/// @see gtc_type_precision
typedef tquat<f32, highp> highp_f32quat;
typedef qua<f32, highp> highp_f32quat;
/// High double-qualifier floating-point quaternion.
/// @see gtc_type_precision
typedef tquat<f64, highp> highp_f64quat;
typedef qua<f64, highp> highp_f64quat;
/// Double-qualifier floating-point quaternion.
/// @see gtc_type_precision
typedef tquat<f64, defaultp> f64quat;
typedef qua<f64, defaultp> f64quat;
# endif//GLM_FORCE_SINGLE_ONLY

View File

@ -223,7 +223,7 @@ namespace glm
/// Build a quaternion from a pointer.
/// @see gtc_type_ptr
template<typename T>
GLM_FUNC_DECL tquat<T, defaultp> make_quat(T const * const ptr);
GLM_FUNC_DECL qua<T, defaultp> make_quat(T const * const ptr);
/// @}
}//namespace glm

View File

@ -152,13 +152,13 @@ namespace glm
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const * value_ptr(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER T const * value_ptr(qua<T, Q> const& q)
{
return &(q[0]);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(tquat<T, Q>& q)
GLM_FUNC_QUALIFIER T* value_ptr(qua<T, Q>& q)
{
return &(q[0]);
}
@ -374,10 +374,10 @@ namespace glm
}
template<typename T>
GLM_FUNC_QUALIFIER tquat<T, defaultp> make_quat(T const *const ptr)
GLM_FUNC_QUALIFIER qua<T, defaultp> make_quat(T const *const ptr)
{
tquat<T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(tquat<T, defaultp>));
qua<T, defaultp> Result;
memcpy(value_ptr(Result), ptr, sizeof(qua<T, defaultp>));
return Result;
}

View File

@ -18,6 +18,7 @@
#include "../detail/setup.hpp"
#include "../detail/qualifier.hpp"
#include "../detail/type_int.hpp"
#include "../gtc/constants.hpp"
#include "../ext/vector_relational.hpp"
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)

View File

@ -39,11 +39,11 @@ namespace glm
// -- Implementation detail --
typedef T value_type;
typedef glm::tquat<T, Q> part_type;
typedef qua<T, Q> part_type;
// -- Data --
glm::tquat<T, Q> real, dual;
qua<T, Q> real, dual;
// -- Component accesses --
@ -63,9 +63,9 @@ namespace glm
// -- Explicit basic constructors --
GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(tquat<T, Q> const& real);
GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(tquat<T, Q> const& orientation, vec<3, T, Q> const& translation);
GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(tquat<T, Q> const& real, tquat<T, Q> const& dual);
GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(qua<T, Q> const& real);
GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(qua<T, Q> const& orientation, vec<3, T, Q> const& translation);
GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(qua<T, Q> const& real, qua<T, Q> const& dual);
// -- Conversion constructors --

View File

@ -27,8 +27,8 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat()
# if GLM_CONFIG_DEFAULTED_FUNCTIONS != GLM_DISABLE
: real(tquat<T, Q>())
, dual(tquat<T, Q>(0, 0, 0, 0))
: real(qua<T, Q>())
, dual(qua<T, Q>(0, 0, 0, 0))
# endif
{}
@ -49,12 +49,12 @@ namespace glm
// -- Explicit basic constructors --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(tquat<T, Q> const& r)
: real(r), dual(tquat<T, Q>(0, 0, 0, 0))
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& r)
: real(r), dual(qua<T, Q>(0, 0, 0, 0))
{}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(tquat<T, Q> const& q, vec<3, T, Q> const& p)
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& q, vec<3, T, Q> const& p)
: real(q), dual(
T(-0.5) * ( p.x*q.x + p.y*q.y + p.z*q.z),
T(+0.5) * ( p.x*q.w + p.y*q.z - p.z*q.y),
@ -63,7 +63,7 @@ namespace glm
{}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(tquat<T, Q> const& r, tquat<T, Q> const& d)
GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& r, qua<T, Q> const& d)
: real(r), dual(d)
{}
@ -219,8 +219,8 @@ namespace glm
GLM_FUNC_QUALIFIER tdualquat<T, Q> dual_quat_identity()
{
return tdualquat<T, Q>(
tquat<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)),
tquat<T, Q>(static_cast<T>(0), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)));
qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)),
qua<T, Q>(static_cast<T>(0), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)));
}
template<typename T, qualifier Q>
@ -244,8 +244,8 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tdualquat<T, Q> inverse(tdualquat<T, Q> const& q)
{
const glm::tquat<T, Q> real = conjugate(q.real);
const glm::tquat<T, Q> dual = conjugate(q.dual);
const glm::qua<T, Q> real = conjugate(q.real);
const glm::qua<T, Q> dual = conjugate(q.dual);
return tdualquat<T, Q>(real, dual + (real * (-2.0f * dot(real,dual))));
}
@ -258,9 +258,9 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<3, 4, T, Q> mat3x4_cast(tdualquat<T, Q> const& x)
{
tquat<T, Q> r = x.real / length2(x.real);
qua<T, Q> r = x.real / length2(x.real);
tquat<T, Q> const rr(r.w * x.real.w, r.x * x.real.x, r.y * x.real.y, r.z * x.real.z);
qua<T, Q> const rr(r.w * x.real.w, r.x * x.real.x, r.y * x.real.y, r.z * x.real.z);
r *= static_cast<T>(2);
T const xy = r.x * x.real.y;
@ -295,14 +295,14 @@ namespace glm
GLM_FUNC_QUALIFIER tdualquat<T, Q> dualquat_cast(mat<2, 4, T, Q> const& x)
{
return tdualquat<T, Q>(
tquat<T, Q>( x[0].w, x[0].x, x[0].y, x[0].z ),
tquat<T, Q>( x[1].w, x[1].x, x[1].y, x[1].z ));
qua<T, Q>( x[0].w, x[0].x, x[0].y, x[0].z ),
qua<T, Q>( x[1].w, x[1].x, x[1].y, x[1].z ));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tdualquat<T, Q> dualquat_cast(mat<3, 4, T, Q> const& x)
{
tquat<T, Q> real;
qua<T, Q> real;
T const trace = x[0].x + x[1].y + x[2].z;
if(trace > static_cast<T>(0))
@ -342,7 +342,7 @@ namespace glm
real.w = (x[1].x - x[0].y) * invr;
}
tquat<T, Q> dual;
qua<T, Q> dual;
dual.x = static_cast<T>(0.5) * ( x[0].w * real.w + x[1].w * real.z - x[2].w * real.y);
dual.y = static_cast<T>(0.5) * (-x[0].w * real.z + x[1].w * real.w + x[2].w * real.x);
dual.z = static_cast<T>(0.5) * ( x[0].w * real.y - x[1].w * real.x + x[2].w * real.w);

View File

@ -38,7 +38,7 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_DECL bool decompose(
mat<4, 4, T, Q> const& modelMatrix,
vec<3, T, Q> & scale, tquat<T, Q> & orientation, vec<3, T, Q> & translation, vec<3, T, Q> & skew, vec<4, T, Q> & perspective);
vec<3, T, Q> & scale, qua<T, Q> & orientation, vec<3, T, Q> & translation, vec<3, T, Q> & skew, vec<4, T, Q> & perspective);
/// @}
}//namespace glm

View File

@ -29,7 +29,7 @@ namespace detail
// Decomposes the mode matrix to translations,rotation scale components
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER bool decompose(mat<4, 4, T, Q> const& ModelMatrix, vec<3, T, Q> & Scale, tquat<T, Q> & Orientation, vec<3, T, Q> & Translation, vec<3, T, Q> & Skew, vec<4, T, Q> & Perspective)
GLM_FUNC_QUALIFIER bool decompose(mat<4, 4, T, Q> const& ModelMatrix, vec<3, T, Q> & Scale, qua<T, Q> & Orientation, vec<3, T, Q> & Translation, vec<3, T, Q> & Skew, vec<4, T, Q> & Perspective)
{
mat<4, 4, T, Q> LocalMatrix(ModelMatrix);

View File

@ -36,14 +36,14 @@ namespace glm
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> quat_identity();
GLM_FUNC_DECL qua<T, Q> quat_identity();
/// Compute a cross product between a quaternion and a vector.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> cross(
tquat<T, Q> const& q,
qua<T, Q> const& q,
vec<3, T, Q> const& v);
//! Compute a cross product between a vector and a quaternion.
@ -52,64 +52,64 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> cross(
vec<3, T, Q> const& v,
tquat<T, Q> const& q);
qua<T, Q> const& q);
//! Compute a point on a path according squad equation.
//! q1 and q2 are control points; s1 and s2 are intermediate control points.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> squad(
tquat<T, Q> const& q1,
tquat<T, Q> const& q2,
tquat<T, Q> const& s1,
tquat<T, Q> const& s2,
GLM_FUNC_DECL qua<T, Q> squad(
qua<T, Q> const& q1,
qua<T, Q> const& q2,
qua<T, Q> const& s1,
qua<T, Q> const& s2,
T const& h);
//! Returns an intermediate control point for squad interpolation.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> intermediate(
tquat<T, Q> const& prev,
tquat<T, Q> const& curr,
tquat<T, Q> const& next);
GLM_FUNC_DECL qua<T, Q> intermediate(
qua<T, Q> const& prev,
qua<T, Q> const& curr,
qua<T, Q> const& next);
//! Returns a exp of a quaternion.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> exp(
tquat<T, Q> const& q);
GLM_FUNC_DECL qua<T, Q> exp(
qua<T, Q> const& q);
//! Returns a log of a quaternion.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> log(
tquat<T, Q> const& q);
GLM_FUNC_DECL qua<T, Q> log(
qua<T, Q> const& q);
/// Returns x raised to the y power.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> pow(
tquat<T, Q> const& x,
GLM_FUNC_DECL qua<T, Q> pow(
qua<T, Q> const& x,
T const& y);
//! Returns quarternion square root.
///
/// @see gtx_quaternion
//template<typename T, qualifier Q>
//tquat<T, Q> sqrt(
// tquat<T, Q> const& q);
//qua<T, Q> sqrt(
// qua<T, Q> const& q);
//! Rotates a 3 components vector by a quaternion.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<3, T, Q> rotate(
tquat<T, Q> const& q,
qua<T, Q> const& q,
vec<3, T, Q> const& v);
/// Rotates a 4 components vector by a quaternion.
@ -117,7 +117,7 @@ namespace glm
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL vec<4, T, Q> rotate(
tquat<T, Q> const& q,
qua<T, Q> const& q,
vec<4, T, Q> const& v);
/// Extract the real component of a quaternion.
@ -125,52 +125,52 @@ namespace glm
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T extractRealComponent(
tquat<T, Q> const& q);
qua<T, Q> const& q);
/// Converts a quaternion to a 3 * 3 matrix.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL mat<3, 3, T, Q> toMat3(
tquat<T, Q> const& x){return mat3_cast(x);}
qua<T, Q> const& x){return mat3_cast(x);}
/// Converts a quaternion to a 4 * 4 matrix.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL mat<4, 4, T, Q> toMat4(
tquat<T, Q> const& x){return mat4_cast(x);}
qua<T, Q> const& x){return mat4_cast(x);}
/// Converts a 3 * 3 matrix to a quaternion.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> toQuat(
GLM_FUNC_DECL qua<T, Q> toQuat(
mat<3, 3, T, Q> const& x){return quat_cast(x);}
/// Converts a 4 * 4 matrix to a quaternion.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> toQuat(
GLM_FUNC_DECL qua<T, Q> toQuat(
mat<4, 4, T, Q> const& x){return quat_cast(x);}
/// Quaternion interpolation using the rotation short path.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> shortMix(
tquat<T, Q> const& x,
tquat<T, Q> const& y,
GLM_FUNC_DECL qua<T, Q> shortMix(
qua<T, Q> const& x,
qua<T, Q> const& y,
T const& a);
/// Quaternion normalized linear interpolation.
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> fastMix(
tquat<T, Q> const& x,
tquat<T, Q> const& y,
GLM_FUNC_DECL qua<T, Q> fastMix(
qua<T, Q> const& x,
qua<T, Q> const& y,
T const& a);
/// Compute the rotation between two vectors.
@ -179,7 +179,7 @@ namespace glm
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> rotation(
GLM_FUNC_DECL qua<T, Q> rotation(
vec<3, T, Q> const& orig,
vec<3, T, Q> const& dest);
@ -188,7 +188,7 @@ namespace glm
/// @param direction Desired forward direction. Needs to be normalized.
/// @param up Up vector, how the camera is oriented. Typically (0, 1, 0).
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> quatLookAt(
GLM_FUNC_DECL qua<T, Q> quatLookAt(
vec<3, T, Q> const& direction,
vec<3, T, Q> const& up);
@ -197,7 +197,7 @@ namespace glm
/// @param direction Desired forward direction onto which the -z-axis gets mapped. Needs to be normalized.
/// @param up Up vector, how the camera is oriented. Typically (0, 1, 0).
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> quatLookAtRH(
GLM_FUNC_DECL qua<T, Q> quatLookAtRH(
vec<3, T, Q> const& direction,
vec<3, T, Q> const& up);
@ -206,7 +206,7 @@ namespace glm
/// @param direction Desired forward direction onto which the +z-axis gets mapped. Needs to be normalized.
/// @param up Up vector, how the camera is oriented. Typically (0, 1, 0).
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> quatLookAtLH(
GLM_FUNC_DECL qua<T, Q> quatLookAtLH(
vec<3, T, Q> const& direction,
vec<3, T, Q> const& up);
@ -214,7 +214,7 @@ namespace glm
///
/// @see gtx_quaternion
template<typename T, qualifier Q>
GLM_FUNC_DECL T length2(tquat<T, Q> const& q);
GLM_FUNC_DECL T length2(qua<T, Q> const& q);
/// @}
}//namespace glm

View File

@ -6,61 +6,61 @@
namespace glm
{
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> quat_identity()
GLM_FUNC_QUALIFIER qua<T, Q> quat_identity()
{
return tquat<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
return qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> cross(vec<3, T, Q> const& v, tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER vec<3, T, Q> cross(vec<3, T, Q> const& v, qua<T, Q> const& q)
{
return inverse(q) * v;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> cross(tquat<T, Q> const& q, vec<3, T, Q> const& v)
GLM_FUNC_QUALIFIER vec<3, T, Q> cross(qua<T, Q> const& q, vec<3, T, Q> const& v)
{
return q * v;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> squad
GLM_FUNC_QUALIFIER qua<T, Q> squad
(
tquat<T, Q> const& q1,
tquat<T, Q> const& q2,
tquat<T, Q> const& s1,
tquat<T, Q> const& s2,
qua<T, Q> const& q1,
qua<T, Q> const& q2,
qua<T, Q> const& s1,
qua<T, Q> const& s2,
T const& h)
{
return mix(mix(q1, q2, h), mix(s1, s2, h), static_cast<T>(2) * (static_cast<T>(1) - h) * h);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> intermediate
GLM_FUNC_QUALIFIER qua<T, Q> intermediate
(
tquat<T, Q> const& prev,
tquat<T, Q> const& curr,
tquat<T, Q> const& next
qua<T, Q> const& prev,
qua<T, Q> const& curr,
qua<T, Q> const& next
)
{
tquat<T, Q> invQuat = inverse(curr);
qua<T, Q> invQuat = inverse(curr);
return exp((log(next * invQuat) + log(prev * invQuat)) / static_cast<T>(-4)) * curr;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> exp(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER qua<T, Q> exp(qua<T, Q> const& q)
{
vec<3, T, Q> u(q.x, q.y, q.z);
T const Angle = glm::length(u);
if (Angle < epsilon<T>())
return tquat<T, Q>();
return qua<T, Q>();
vec<3, T, Q> const v(u / Angle);
return tquat<T, Q>(cos(Angle), sin(Angle) * v);
return qua<T, Q>(cos(Angle), sin(Angle) * v);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> log(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER qua<T, Q> log(qua<T, Q> const& q)
{
vec<3, T, Q> u(q.x, q.y, q.z);
T Vec3Len = length(u);
@ -68,27 +68,27 @@ namespace glm
if (Vec3Len < epsilon<T>())
{
if(q.w > static_cast<T>(0))
return tquat<T, Q>(log(q.w), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
return qua<T, Q>(log(q.w), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
else if(q.w < static_cast<T>(0))
return tquat<T, Q>(log(-q.w), pi<T>(), static_cast<T>(0), static_cast<T>(0));
return qua<T, Q>(log(-q.w), pi<T>(), static_cast<T>(0), static_cast<T>(0));
else
return tquat<T, Q>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
return qua<T, Q>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
}
else
{
T t = atan(Vec3Len, T(q.w)) / Vec3Len;
T QuatLen2 = Vec3Len * Vec3Len + q.w * q.w;
return tquat<T, Q>(static_cast<T>(0.5) * log(QuatLen2), t * q.x, t * q.y, t * q.z);
return qua<T, Q>(static_cast<T>(0.5) * log(QuatLen2), t * q.x, t * q.y, t * q.z);
}
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> pow(tquat<T, Q> const& x, T const& y)
GLM_FUNC_QUALIFIER qua<T, Q> pow(qua<T, Q> const& x, T const& y)
{
//Raising to the power of 0 should yield 1
//Needed to prevent a division by 0 error later on
if(y > -epsilon<T>() && y < epsilon<T>())
return tquat<T, Q>(1,0,0,0);
return qua<T, Q>(1,0,0,0);
//To deal with non-unit quaternions
T magnitude = sqrt(x.x * x.x + x.y * x.y + x.z * x.z + x.w *x.w);
@ -96,30 +96,30 @@ namespace glm
//Equivalent to raising a real number to a power
//Needed to prevent a division by 0 error later on
if(abs(x.w / magnitude) > static_cast<T>(1) - epsilon<T>() && abs(x.w / magnitude) < static_cast<T>(1) + epsilon<T>())
return tquat<T, Q>(pow(x.w, y),0,0,0);
return qua<T, Q>(pow(x.w, y),0,0,0);
T Angle = acos(x.w / magnitude);
T NewAngle = Angle * y;
T Div = sin(NewAngle) / sin(Angle);
T Mag = pow(magnitude, y - static_cast<T>(1));
return tquat<T, Q>(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag);
return qua<T, Q>(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> rotate(tquat<T, Q> const& q, vec<3, T, Q> const& v)
GLM_FUNC_QUALIFIER vec<3, T, Q> rotate(qua<T, Q> const& q, vec<3, T, Q> const& v)
{
return q * v;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, T, Q> rotate(tquat<T, Q> const& q, vec<4, T, Q> const& v)
GLM_FUNC_QUALIFIER vec<4, T, Q> rotate(qua<T, Q> const& q, vec<4, T, Q> const& v)
{
return q * v;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T extractRealComponent(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER T extractRealComponent(qua<T, Q> const& q)
{
T w = static_cast<T>(1) - q.x * q.x - q.y * q.y - q.z * q.z;
if(w < T(0))
@ -129,19 +129,19 @@ namespace glm
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T length2(tquat<T, Q> const& q)
GLM_FUNC_QUALIFIER T length2(qua<T, Q> const& q)
{
return q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w;
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> shortMix(tquat<T, Q> const& x, tquat<T, Q> const& y, T const& a)
GLM_FUNC_QUALIFIER qua<T, Q> shortMix(qua<T, Q> const& x, qua<T, Q> const& y, T const& a)
{
if(a <= static_cast<T>(0)) return x;
if(a >= static_cast<T>(1)) return y;
T fCos = dot(x, y);
tquat<T, Q> y2(y); //BUG!!! tquat<T> y2;
qua<T, Q> y2(y); //BUG!!! qua<T> y2;
if(fCos < static_cast<T>(0))
{
y2 = -y;
@ -164,7 +164,7 @@ namespace glm
k1 = sin((static_cast<T>(0) + a) * fAngle) * fOneOverSin;
}
return tquat<T, Q>(
return qua<T, Q>(
k0 * x.w + k1 * y2.w,
k0 * x.x + k1 * y2.x,
k0 * x.y + k1 * y2.y,
@ -172,13 +172,13 @@ namespace glm
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> fastMix(tquat<T, Q> const& x, tquat<T, Q> const& y, T const& a)
GLM_FUNC_QUALIFIER qua<T, Q> fastMix(qua<T, Q> const& x, qua<T, Q> const& y, T const& a)
{
return glm::normalize(x * (static_cast<T>(1) - a) + (y * a));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> rotation(vec<3, T, Q> const& orig, vec<3, T, Q> const& dest)
GLM_FUNC_QUALIFIER qua<T, Q> rotation(vec<3, T, Q> const& orig, vec<3, T, Q> const& dest)
{
T cosTheta = dot(orig, dest);
vec<3, T, Q> rotationAxis;
@ -209,7 +209,7 @@ namespace glm
T s = sqrt((T(1) + cosTheta) * static_cast<T>(2));
T invs = static_cast<T>(1) / s;
return tquat<T, Q>(
return qua<T, Q>(
s * static_cast<T>(0.5f),
rotationAxis.x * invs,
rotationAxis.y * invs,
@ -217,7 +217,7 @@ namespace glm
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> quatLookAt(vec<3, T, Q> const& direction, vec<3, T, Q> const& up)
GLM_FUNC_QUALIFIER qua<T, Q> quatLookAt(vec<3, T, Q> const& direction, vec<3, T, Q> const& up)
{
# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
return quatLookAtLH(direction, up);
@ -227,7 +227,7 @@ namespace glm
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> quatLookAtRH(vec<3, T, Q> const& direction, vec<3, T, Q> const& up)
GLM_FUNC_QUALIFIER qua<T, Q> quatLookAtRH(vec<3, T, Q> const& direction, vec<3, T, Q> const& up)
{
mat<3, 3, T, Q> Result;
@ -239,7 +239,7 @@ namespace glm
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> quatLookAtLH(vec<3, T, Q> const& direction, vec<3, T, Q> const& up)
GLM_FUNC_QUALIFIER qua<T, Q> quatLookAtLH(vec<3, T, Q> const& direction, vec<3, T, Q> const& up)
{
mat<3, 3, T, Q> Result;

View File

@ -57,8 +57,8 @@ namespace glm
///
/// @see gtx_rotate_normalized_axis
template<typename T, qualifier Q>
GLM_FUNC_DECL tquat<T, Q> rotateNormalizedAxis(
tquat<T, Q> const& q,
GLM_FUNC_DECL qua<T, Q> rotateNormalizedAxis(
qua<T, Q> const& q,
T const& angle,
vec<3, T, Q> const& axis);

View File

@ -40,9 +40,9 @@ namespace glm
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER tquat<T, Q> rotateNormalizedAxis
GLM_FUNC_QUALIFIER qua<T, Q> rotateNormalizedAxis
(
tquat<T, Q> const& q,
qua<T, Q> const& q,
T const& angle,
vec<3, T, Q> const& v
)
@ -52,7 +52,7 @@ namespace glm
T const AngleRad(angle);
T const Sin = sin(AngleRad * T(0.5));
return q * tquat<T, Q>(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
return q * qua<T, Q>(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
//return gtc::quaternion::cross(q, tquat<T, Q>(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin));
}
}//namespace glm

View File

@ -439,9 +439,9 @@ namespace detail
template<typename T, qualifier Q>
struct compute_to_string<tquat<T, Q> >
struct compute_to_string<qua<T, Q> >
{
GLM_FUNC_QUALIFIER static std::string call(tquat<T, Q> const& x)
GLM_FUNC_QUALIFIER static std::string call(qua<T, Q> const& x)
{
char const * PrefixStr = prefix<T>::value();
char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();

View File

@ -960,7 +960,7 @@ namespace glm
/// Single-qualifier floating-point aligned quaternion.
/// @see gtx_type_aligned
GLM_ALIGNED_TYPEDEF(fquat, aligned_fquat, 16);
GLM_ALIGNED_TYPEDEF(quat, aligned_fquat, 16);
/// Double-qualifier floating-point aligned quaternion.
/// @see gtx_type_aligned

View File

@ -62,7 +62,7 @@ namespace glm
};
template<typename T, qualifier Q>
struct type<tquat<T, Q> >
struct type<qua<T, Q> >
{
static bool const is_vec = false;
static bool const is_mat = false;

View File

@ -41,13 +41,13 @@ namespace glm
// tquat
template<typename T, qualifier Q>
bool const type<tquat<T, Q> >::is_vec;
bool const type<qua<T, Q> >::is_vec;
template<typename T, qualifier Q>
bool const type<tquat<T, Q> >::is_mat;
bool const type<qua<T, Q> >::is_mat;
template<typename T, qualifier Q>
bool const type<tquat<T, Q> >::is_quat;
bool const type<qua<T, Q> >::is_quat;
template<typename T, qualifier Q>
length_t const type<tquat<T, Q> >::components;
length_t const type<qua<T, Q> >::components;
// tdualquat
template<typename T, qualifier Q>

View File

@ -3,7 +3,10 @@
#include <glm/gtc/epsilon.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/gtc/ulp.hpp>
#include <glm/gtc/vec1.hpp>
#include <glm/ext/vector_vec1.hpp>
#include <glm/ext/vector_vec2.hpp>
#include <glm/ext/vector_vec3.hpp>
#include <glm/ext/vector_vec4.hpp>
static int test_pow()
{

View File

@ -1,7 +1,8 @@
#define GLM_FORCE_ALIGNED
#define GLM_FORCE_SWIZZLE
#include <glm/gtc/epsilon.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/ext/vec1.hpp>
#include <glm/ext/scalar_relational.hpp>
#include <glm/ext/vector_relational.hpp>
#include <glm/vector_relational.hpp>
#include <glm/vec2.hpp>
@ -740,10 +741,10 @@ static int test_inheritance()
my_vec4 v;
Error += v.member == 82 ? 0 : 1;
Error += glm::epsilonEqual(v.x, 76.f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::epsilonEqual(v.y, 75.f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::epsilonEqual(v.z, 74.f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::epsilonEqual(v.w, 73.f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.x, 76.f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, 75.f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, 74.f, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.w, 73.f, glm::epsilon<float>()) ? 0 : 1;
return Error;
}

View File

@ -26,7 +26,7 @@ int test_axisAngle()
std::cout << "dltAxis: (" << dltAxis.x << ", " << dltAxis.y << ", " << dltAxis.z << "), dltAngle: " << dltAngle << std::endl;
glm::fquat q = glm::quat_cast(dltRotation);
glm::quat q = glm::quat_cast(dltRotation);
std::cout << "q: (" << q.x << ", " << q.y << ", " << q.z << ", " << q.w << ")" << std::endl;
float yaw = glm::yaw(q);
std::cout << "Yaw: " << yaw << std::endl;