parent
8288f17558
commit
ba8ee44b19
14 changed files with 547 additions and 227 deletions
@ -0,0 +1,71 @@ |
||||
/// @ref ext_quaternion_geometric
|
||||
/// @file glm/ext/quaternion_geometric.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup ext_quaternion_geometric GLM_EXT_quaternion_geometric
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/ext/quaternion_geometric.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Defines a templated quaternion type and several quaternion operations.
|
||||
|
||||
#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 "../ext/quaternion_relational.hpp" |
||||
#include "../detail/type_mat3x3.hpp" |
||||
#include "../detail/type_mat4x4.hpp" |
||||
#include "../detail/type_vec3.hpp" |
||||
#include "../detail/type_vec4.hpp" |
||||
|
||||
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) |
||||
# pragma message("GLM: GLM_GTC_quaternion extension included") |
||||
#endif |
||||
|
||||
namespace glm |
||||
{ |
||||
/// @addtogroup ext_quaternion_geometric
|
||||
/// @{
|
||||
|
||||
/// Returns the length of the quaternion.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types.
|
||||
///
|
||||
/// @see ext_quaternion_geometric
|
||||
template<typename T, qualifier Q> |
||||
GLM_FUNC_DECL T length(qua<T, Q> const& q); |
||||
|
||||
/// Returns the normalized quaternion.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types.
|
||||
///
|
||||
/// @see ext_quaternion_geometric
|
||||
template<typename T, qualifier 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] + ...
|
||||
///
|
||||
/// @tparam T Floating-point scalar types.
|
||||
///
|
||||
/// @see ext_quaternion_geometric
|
||||
template<typename T, qualifier Q> |
||||
GLM_FUNC_DECL T dot(qua<T, Q> const& x, qua<T, Q> const& y); |
||||
|
||||
/// Compute a cross product between a quaternion and a vector.
|
||||
///
|
||||
/// @see ext_quaternion_geometric
|
||||
template<typename T, qualifier Q> |
||||
GLM_FUNC_QUALIFIER qua<T, Q> cross(qua<T, Q> const& q1, qua<T, Q> const& q2); |
||||
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
#include "quaternion_geometric.inl" |
@ -0,0 +1,42 @@ |
||||
#include "../geometric.hpp" |
||||
#include "../exponential.hpp" |
||||
#include <limits> |
||||
|
||||
namespace glm |
||||
{ |
||||
// -- Operations -- |
||||
|
||||
template<typename T, qualifier Q> |
||||
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<qua<T, Q>, T, detail::is_aligned<Q>::value>::call(x, y); |
||||
} |
||||
|
||||
template<typename T, qualifier 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 qua<T, Q> normalize(qua<T, Q> const& q) |
||||
{ |
||||
T len = length(q); |
||||
if(len <= static_cast<T>(0)) // Problem |
||||
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 qua<T, Q>(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen); |
||||
} |
||||
|
||||
template<typename T, qualifier Q> |
||||
GLM_FUNC_QUALIFIER qua<T, Q> cross(qua<T, Q> const& q1, qua<T, Q> const& q2) |
||||
{ |
||||
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, |
||||
q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x); |
||||
} |
||||
}//namespace glm |
||||
|
@ -0,0 +1,100 @@ |
||||
/// @ref ext_quaternion_relational
|
||||
/// @file glm/ext/quaternion_relational.hpp
|
||||
///
|
||||
/// @defgroup ext_quaternion_relational GLM_EXT_quaternion_relational
|
||||
/// @ingroup gtc
|
||||
///
|
||||
/// Include <glm/ext/quaternion_relational.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Defines a templated quaternion type and several quaternion operations.
|
||||
|
||||
#pragma once |
||||
|
||||
// Dependency:
|
||||
#include "../detail/qualifier.hpp" |
||||
|
||||
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) |
||||
# pragma message("GLM: GLM_EXT_quaternion_relational extension included") |
||||
#endif |
||||
|
||||
namespace glm |
||||
{ |
||||
/// @addtogroup ext_quaternion_relational
|
||||
/// @{
|
||||
|
||||
/// Returns the component-wise comparison result of x < y.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q> |
||||
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.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q> |
||||
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.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q> |
||||
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.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q> |
||||
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.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q> |
||||
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.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q> |
||||
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.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q> |
||||
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.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q> |
||||
GLM_FUNC_DECL vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon); |
||||
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
#include "quaternion_relational.inl" |
@ -0,0 +1,71 @@ |
||||
namespace glm |
||||
{ |
||||
template<typename T, qualifier Q> |
||||
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) |
||||
Result[i] = x[i] < y[i]; |
||||
return Result; |
||||
} |
||||
|
||||
template<typename T, qualifier Q> |
||||
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) |
||||
Result[i] = x[i] <= y[i]; |
||||
return Result; |
||||
} |
||||
|
||||
template<typename T, qualifier Q> |
||||
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) |
||||
Result[i] = x[i] > y[i]; |
||||
return Result; |
||||
} |
||||
|
||||
template<typename T, qualifier Q> |
||||
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) |
||||
Result[i] = x[i] >= y[i]; |
||||
return Result; |
||||
} |
||||
|
||||
template<typename T, qualifier Q> |
||||
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) |
||||
Result[i] = detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(x[i], y[i]); |
||||
return Result; |
||||
} |
||||
|
||||
template<typename T, qualifier Q> |
||||
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(qua<T, Q> const& x, qua<T, Q> const& y) |
||||
{ |
||||
vec<4, bool, Q> Result; |
||||
for(length_t i = 0; i < x.length(); ++i) |
||||
Result[i] = !detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(x[i], y[i]); |
||||
return Result; |
||||
} |
||||
|
||||
template<typename T, qualifier Q> |
||||
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)); |
||||
} |
||||
}//namespace glm |
||||
|
@ -0,0 +1,127 @@ |
||||
#include <glm/gtc/constants.hpp> |
||||
#include <glm/ext/vector_relational.hpp> |
||||
#include <glm/ext/vector_float1.hpp> |
||||
#include <glm/ext/vector_float1_precision.hpp> |
||||
#include <glm/ext/vector_float2.hpp> |
||||
#include <glm/ext/vector_float3.hpp> |
||||
#include <glm/ext/vector_float4.hpp> |
||||
|
||||
template <typename genType> |
||||
static int test_operators() |
||||
{ |
||||
int Error = 0; |
||||
|
||||
{ |
||||
genType const A(1); |
||||
genType const B(1); |
||||
|
||||
genType const C = A + B; |
||||
Error += glm::all(glm::equal(C, genType(2), glm::epsilon<float>())) ? 0 : 1; |
||||
|
||||
genType const D = A - B; |
||||
Error += glm::all(glm::equal(D, genType(0), glm::epsilon<float>())) ? 0 : 1; |
||||
|
||||
genType const E = A * B; |
||||
Error += glm::all(glm::equal(E, genType(1), glm::epsilon<float>())) ? 0 : 1; |
||||
|
||||
genType const F = A / B; |
||||
Error += glm::all(glm::equal(F, genType(1), glm::epsilon<float>())) ? 0 : 1; |
||||
} |
||||
|
||||
return Error; |
||||
} |
||||
|
||||
template <typename genType> |
||||
static int test_ctor() |
||||
{ |
||||
int Error = 0; |
||||
|
||||
glm::vec1 const A = genType(1); |
||||
|
||||
glm::vec1 const E(genType(1)); |
||||
Error += glm::all(glm::equal(A, E, glm::epsilon<float>())) ? 0 : 1; |
||||
|
||||
glm::vec1 const F(E); |
||||
Error += glm::all(glm::equal(A, F, glm::epsilon<float>())) ? 0 : 1; |
||||
|
||||
genType const B = genType(1); |
||||
genType const G(glm::vec2(1)); |
||||
Error += glm::all(glm::equal(B, G, glm::epsilon<float>())) ? 0 : 1; |
||||
|
||||
genType const H(glm::vec3(1)); |
||||
Error += glm::all(glm::equal(B, H, glm::epsilon<float>())) ? 0 : 1; |
||||
|
||||
genType const I(glm::vec4(1)); |
||||
Error += glm::all(glm::equal(B, I, glm::epsilon<float>())) ? 0 : 1; |
||||
|
||||
return Error; |
||||
} |
||||
|
||||
template <typename genType> |
||||
static int test_size() |
||||
{ |
||||
int Error = 0; |
||||
|
||||
Error += sizeof(glm::vec1) == sizeof(genType) ? 0 : 1; |
||||
Error += genType().length() == 1 ? 0 : 1; |
||||
Error += genType::length() == 1 ? 0 : 1; |
||||
|
||||
return Error; |
||||
} |
||||
|
||||
template <typename genType> |
||||
static int test_relational() |
||||
{ |
||||
int Error = 0; |
||||
|
||||
genType const A(1); |
||||
genType const B(1); |
||||
genType const C(0); |
||||
|
||||
Error += all(equal(A, B, glm::epsilon<float>())) ? 0 : 1; |
||||
Error += any(notEqual(A, C, glm::epsilon<float>())) ? 0 : 1; |
||||
|
||||
return Error; |
||||
} |
||||
|
||||
template <typename genType> |
||||
static int test_constexpr() |
||||
{ |
||||
# if GLM_CONFIG_CONSTEXP == GLM_ENABLE |
||||
static_assert(genType::length() == 1, "GLM: Failed constexpr"); |
||||
# endif |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int main() |
||||
{ |
||||
int Error = 0; |
||||
|
||||
Error += test_operators<glm::vec1>(); |
||||
Error += test_operators<glm::lowp_vec1>(); |
||||
Error += test_operators<glm::mediump_vec1>(); |
||||
Error += test_operators<glm::highp_vec1>(); |
||||
|
||||
Error += test_ctor<glm::vec1>(); |
||||
Error += test_ctor<glm::lowp_vec1>(); |
||||
Error += test_ctor<glm::mediump_vec1>(); |
||||
Error += test_ctor<glm::highp_vec1>(); |
||||
|
||||
Error += test_size<glm::vec1>(); |
||||
Error += test_size<glm::lowp_vec1>(); |
||||
Error += test_size<glm::mediump_vec1>(); |
||||
Error += test_size<glm::highp_vec1>(); |
||||
|
||||
Error += test_relational<glm::vec1>(); |
||||
Error += test_relational<glm::lowp_vec1>(); |
||||
Error += test_relational<glm::mediump_vec1>(); |
||||
Error += test_relational<glm::highp_vec1>(); |
||||
|
||||
Error += test_constexpr<glm::vec1>(); |
||||
Error += test_constexpr<glm::lowp_vec1>(); |
||||
Error += test_constexpr<glm::mediump_vec1>(); |
||||
Error += test_constexpr<glm::highp_vec1>(); |
||||
|
||||
return Error; |
||||
} |
@ -0,0 +1,113 @@ |
||||
#include <glm/gtc/constants.hpp> |
||||
#include <glm/ext/quaternion_relational.hpp> |
||||
#include <glm/ext/quaternion_float.hpp> |
||||
#include <glm/ext/quaternion_float_precision.hpp> |
||||
#include <glm/ext/quaternion_double.hpp> |
||||
#include <glm/ext/quaternion_double_precision.hpp> |
||||
#include <glm/ext/vector_float3.hpp> |
||||
#include <vector> |
||||
|
||||
static int test_ctr() |
||||
{ |
||||
int Error(0); |
||||
|
||||
# if GLM_HAS_TRIVIAL_QUERIES |
||||
// Error += std::is_trivially_default_constructible<glm::quat>::value ? 0 : 1;
|
||||
// Error += std::is_trivially_default_constructible<glm::dquat>::value ? 0 : 1;
|
||||
// Error += std::is_trivially_copy_assignable<glm::quat>::value ? 0 : 1;
|
||||
// Error += std::is_trivially_copy_assignable<glm::dquat>::value ? 0 : 1;
|
||||
Error += std::is_trivially_copyable<glm::quat>::value ? 0 : 1; |
||||
Error += std::is_trivially_copyable<glm::dquat>::value ? 0 : 1; |
||||
|
||||
Error += std::is_copy_constructible<glm::quat>::value ? 0 : 1; |
||||
Error += std::is_copy_constructible<glm::dquat>::value ? 0 : 1; |
||||
# endif |
||||
|
||||
# if GLM_HAS_INITIALIZER_LISTS |
||||
{ |
||||
glm::quat A{0, 1, 2, 3}; |
||||
|
||||
std::vector<glm::quat> B{ |
||||
{0, 1, 2, 3}, |
||||
{0, 1, 2, 3}}; |
||||
} |
||||
# endif//GLM_HAS_INITIALIZER_LISTS
|
||||
|
||||
return Error; |
||||
} |
||||
|
||||
static int test_two_axis_ctr() |
||||
{ |
||||
int Error = 0; |
||||
|
||||
glm::quat const q1(glm::vec3(1, 0, 0), glm::vec3(0, 1, 0)); |
||||
glm::vec3 const v1 = q1 * glm::vec3(1, 0, 0); |
||||
Error += glm::all(glm::equal(v1, glm::vec3(0, 1, 0), 0.0001f)) ? 0 : 1; |
||||
|
||||
glm::quat const q2 = q1 * q1; |
||||
glm::vec3 const v2 = q2 * glm::vec3(1, 0, 0); |
||||
Error += glm::all(glm::equal(v2, glm::vec3(-1, 0, 0), 0.0001f)) ? 0 : 1; |
||||
|
||||
glm::quat const q3(glm::vec3(1, 0, 0), glm::vec3(-1, 0, 0)); |
||||
glm::vec3 const v3 = q3 * glm::vec3(1, 0, 0); |
||||
Error += glm::all(glm::equal(v3, glm::vec3(-1, 0, 0), 0.0001f)) ? 0 : 1; |
||||
|
||||
glm::quat const q4(glm::vec3(0, 1, 0), glm::vec3(0, -1, 0)); |
||||
glm::vec3 const v4 = q4 * glm::vec3(0, 1, 0); |
||||
Error += glm::all(glm::equal(v4, glm::vec3(0, -1, 0), 0.0001f)) ? 0 : 1; |
||||
|
||||
glm::quat const q5(glm::vec3(0, 0, 1), glm::vec3(0, 0, -1)); |
||||
glm::vec3 const v5 = q5 * glm::vec3(0, 0, 1); |
||||
Error += glm::all(glm::equal(v5, glm::vec3(0, 0, -1), 0.0001f)) ? 0 : 1; |
||||
|
||||
return Error; |
||||
} |
||||
|
||||
static int test_size() |
||||
{ |
||||
int Error = 0; |
||||
|
||||
std::size_t const A = sizeof(glm::quat); |
||||
Error += 16 == A ? 0 : 1; |
||||
std::size_t const B = sizeof(glm::dquat); |
||||
Error += 32 == B ? 0 : 1; |
||||
Error += glm::quat().length() == 4 ? 0 : 1; |
||||
Error += glm::dquat().length() == 4 ? 0 : 1; |
||||
Error += glm::quat::length() == 4 ? 0 : 1; |
||||
Error += glm::dquat::length() == 4 ? 0 : 1; |
||||
|
||||
return Error; |
||||
} |
||||
|
||||
static int test_precision() |
||||
{ |
||||
int Error = 0; |
||||
|
||||
Error += sizeof(glm::lowp_quat) <= sizeof(glm::mediump_quat) ? 0 : 1; |
||||
Error += sizeof(glm::mediump_quat) <= sizeof(glm::highp_quat) ? 0 : 1; |
||||
|
||||
return Error; |
||||
} |
||||
|
||||
static int test_constexpr() |
||||
{ |
||||
#if GLM_HAS_CONSTEXPR |
||||
static_assert(glm::quat::length() == 4, "GLM: Failed constexpr"); |
||||
static_assert(glm::quat(1.0f, glm::vec3(0.0f)).w > 0.0f, "GLM: Failed constexpr"); |
||||
#endif |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int main() |
||||
{ |
||||
int Error = 0; |
||||
|
||||
Error += test_ctr(); |
||||
Error += test_two_axis_ctr(); |
||||
Error += test_size(); |
||||
Error += test_precision(); |
||||
Error += test_constexpr(); |
||||
|
||||
return Error; |
||||
} |
Loading…
Reference in New Issue