mirror of
https://github.com/g-truc/glm.git
synced 2024-11-22 08:54:35 +00:00
Added EXT_scalar_common, EXT_vector_common and EXT_quaternion_exponential extensions
This commit is contained in:
parent
f905aecd23
commit
c4ed4ed0c7
69
glm/ext/quaternion_exponential.hpp
Normal file
69
glm/ext/quaternion_exponential.hpp
Normal file
@ -0,0 +1,69 @@
|
||||
/// @ref ext_quaternion_exponential
|
||||
/// @file glm/ext/quaternion_exponential.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup ext_quaternion_exponential GLM_EXT_quaternion_exponential
|
||||
/// @ingroup ext
|
||||
///
|
||||
/// Include <glm/ext/quaternion_exponential.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Defines a templated quaternion type and several quaternion operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../common.hpp"
|
||||
#include "../trigonometric.hpp"
|
||||
#include "../geometric.hpp"
|
||||
#include "../ext/scalar_constants.hpp"
|
||||
|
||||
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_EXT_quaternion_exponential extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup ext_quaternion_transform
|
||||
/// @{
|
||||
|
||||
/// Returns a exponential of a quaternion.
|
||||
///
|
||||
/// @tparam T A floating-point scalar type
|
||||
/// @tparam Q A value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_exponential
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> exp(qua<T, Q> const& q);
|
||||
|
||||
/// Returns a logarithm of a quaternion
|
||||
///
|
||||
/// @tparam T A floating-point scalar type
|
||||
/// @tparam Q A value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_exponential
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> log(qua<T, Q> const& q);
|
||||
|
||||
/// Returns a quaternion raised to a power.
|
||||
///
|
||||
/// @tparam T A floating-point scalar type
|
||||
/// @tparam Q A value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_exponential
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> pow(qua<T, Q> const& q, T y);
|
||||
|
||||
/// Returns the square root of a quaternion
|
||||
///
|
||||
/// @tparam T A floating-point scalar type
|
||||
/// @tparam Q A value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_exponential
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> sqrt(qua<T, Q> const& q);
|
||||
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
#include "quaternion_exponential.inl"
|
72
glm/ext/quaternion_exponential.inl
Normal file
72
glm/ext/quaternion_exponential.inl
Normal file
@ -0,0 +1,72 @@
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier 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 qua<T, Q>();
|
||||
|
||||
vec<3, T, Q> const v(u / Angle);
|
||||
return qua<T, Q>(cos(Angle), sin(Angle) * v);
|
||||
}
|
||||
|
||||
template<typename T, qualifier 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);
|
||||
|
||||
if (Vec3Len < epsilon<T>())
|
||||
{
|
||||
if(q.w > 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 qua<T, Q>(log(-q.w), pi<T>(), static_cast<T>(0), static_cast<T>(0));
|
||||
else
|
||||
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 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 qua<T, Q> pow(qua<T, Q> const& x, T 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 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);
|
||||
|
||||
//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 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 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 qua<T, Q> sqrt(qua<T, Q> const& x)
|
||||
{
|
||||
return pow(x, static_cast<T>(0.5));
|
||||
}
|
||||
}//namespace glm
|
||||
|
||||
#if GLM_CONFIG_SIMD == GLM_ENABLE
|
||||
# include "quaternion_exponential_simd.inl"
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@ namespace glm
|
||||
/// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ...
|
||||
///
|
||||
/// @tparam T Floating-point scalar types.
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_geometric
|
||||
template<typename T, qualifier Q>
|
||||
|
@ -39,6 +39,32 @@ namespace glm
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> rotate(qua<T, Q> const& q, T const& angle, vec<3, T, Q> const& axis);
|
||||
|
||||
/// Build a look at quaternion based on the default handedness.
|
||||
///
|
||||
/// @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 qua<T, Q> quatLookAt(
|
||||
vec<3, T, Q> const& direction,
|
||||
vec<3, T, Q> const& up);
|
||||
|
||||
/// Build a right-handed look at quaternion.
|
||||
///
|
||||
/// @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 qua<T, Q> quatLookAtRH(
|
||||
vec<3, T, Q> const& direction,
|
||||
vec<3, T, Q> const& up);
|
||||
|
||||
/// Build a left-handed look at quaternion.
|
||||
///
|
||||
/// @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 qua<T, Q> quatLookAtLH(
|
||||
vec<3, T, Q> const& direction,
|
||||
vec<3, T, Q> const& up);
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
|
@ -20,6 +20,40 @@ namespace glm
|
||||
|
||||
return q * qua<T, Q>(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
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);
|
||||
# else
|
||||
return quatLookAtRH(direction, up);
|
||||
# endif
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
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;
|
||||
|
||||
Result[2] = -direction;
|
||||
Result[0] = normalize(cross(up, Result[2]));
|
||||
Result[1] = cross(Result[2], Result[0]);
|
||||
|
||||
return quat_cast(Result);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
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;
|
||||
|
||||
Result[2] = direction;
|
||||
Result[0] = normalize(cross(up, Result[2]));
|
||||
Result[1] = cross(Result[2], Result[0]);
|
||||
|
||||
return quat_cast(Result);
|
||||
}
|
||||
}//namespace glm
|
||||
|
||||
#if GLM_CONFIG_SIMD == GLM_ENABLE
|
||||
|
110
glm/ext/scalar_common.hpp
Normal file
110
glm/ext/scalar_common.hpp
Normal file
@ -0,0 +1,110 @@
|
||||
/// @ref ext_scalar_common
|
||||
/// @file glm/ext/scalar_common.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup ext_scalar_common GLM_EXT_scalar_common
|
||||
/// @ingroup ext
|
||||
///
|
||||
/// Include <glm/ext/scalar_common.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Min and max functions for 3 to 4 parameters.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../common.hpp"
|
||||
|
||||
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_EXT_scalar_common extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup ext_scalar_common
|
||||
/// @{
|
||||
|
||||
/// Returns the minimum component-wise values of 3 inputs
|
||||
///
|
||||
/// @tparam T A floating-point scalar type.
|
||||
///
|
||||
/// @see ext_scalar_common
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T min(T a, T b, T c);
|
||||
|
||||
/// Returns the minimum component-wise values of 4 inputs
|
||||
/// @see ext_scalar_common
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T min(T a, T b, T c, T d);
|
||||
|
||||
/// Returns the maximum component-wise values of 3 inputs
|
||||
///
|
||||
/// @tparam T A floating-point scalar type.
|
||||
///
|
||||
/// @see ext_scalar_common
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T max(T a, T b, T c);
|
||||
|
||||
/// Returns the maximum component-wise values of 4 inputs
|
||||
/// @see ext_scalar_common
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T max(T a, T b, T c, T d);
|
||||
|
||||
/// Returns the minimum component-wise values of 2 inputs. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam T A floating-point scalar type.
|
||||
///
|
||||
/// @see ext_scalar_common
|
||||
/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmin">std::fmin documentation</a>
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fmin(T a, T b);
|
||||
|
||||
/// Returns the minimum component-wise values of 3 inputs. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam T A floating-point scalar type.
|
||||
///
|
||||
/// @see ext_scalar_common
|
||||
/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmin">std::fmin documentation</a>
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fmin(T a, T b, T c);
|
||||
|
||||
/// Returns the minimum component-wise values of 4 inputs. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam T A floating-point scalar type.
|
||||
///
|
||||
/// @see ext_scalar_common
|
||||
/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmin">std::fmin documentation</a>
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fmin(T a, T b, T c, T d);
|
||||
|
||||
/// Returns the maximum component-wise values of 2 inputs. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam T A floating-point scalar type.
|
||||
///
|
||||
/// @see ext_scalar_common
|
||||
/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fmax(T a, T b);
|
||||
|
||||
/// Returns the maximum component-wise values of 3 inputs. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam T A floating-point scalar type.
|
||||
///
|
||||
/// @see ext_scalar_common
|
||||
/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fmax(T a, T b, T C);
|
||||
|
||||
/// Returns the maximum component-wise values of 4 inputs. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam T A floating-point scalar type.
|
||||
///
|
||||
/// @see ext_scalar_common
|
||||
/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
|
||||
template<typename T>
|
||||
GLM_FUNC_DECL T fmax(T a, T b, T C, T D);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "scalar_common.inl"
|
115
glm/ext/scalar_common.inl
Normal file
115
glm/ext/scalar_common.inl
Normal file
@ -0,0 +1,115 @@
|
||||
namespace glm
|
||||
{
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T min(T a, T b, T c)
|
||||
{
|
||||
return glm::min(glm::min(a, b), c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T min(T a, T b, T c, T d)
|
||||
{
|
||||
return glm::min(glm::min(a, b), glm::min(c, d));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T max(T a, T b, T c)
|
||||
{
|
||||
return glm::max(glm::max(a, b), c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T max(T a, T b, T c, T d)
|
||||
{
|
||||
return glm::max(glm::max(a, b), glm::max(c, d));
|
||||
}
|
||||
|
||||
# if GLM_HAS_CXX11_STL
|
||||
using std::fmin;
|
||||
# else
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fmin(T a, T b)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point input");
|
||||
|
||||
if (isnan(a))
|
||||
return b;
|
||||
return min(a, b);
|
||||
}
|
||||
# endif
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fmin(T a, T b, T c)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point input");
|
||||
|
||||
if (isnan(a))
|
||||
return fmin(b, c);
|
||||
if (isnan(b))
|
||||
return fmin(a, c);
|
||||
if (isnan(c))
|
||||
return min(a, b);
|
||||
return min(a, b, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fmin(T a, T b, T c, T d)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point input");
|
||||
|
||||
if (isnan(a))
|
||||
return fmin(b, c, d);
|
||||
if (isnan(b))
|
||||
return min(a, fmin(c, d));
|
||||
if (isnan(c))
|
||||
return fmin(min(a, b), d);
|
||||
if (isnan(d))
|
||||
return min(a, b, c);
|
||||
return min(a, b, c, d);
|
||||
}
|
||||
|
||||
|
||||
# if GLM_HAS_CXX11_STL
|
||||
using std::fmax;
|
||||
# else
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fmax(T a, T b)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point input");
|
||||
|
||||
if (isnan(a))
|
||||
return b;
|
||||
return max(a, b);
|
||||
}
|
||||
# endif
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fmax(T a, T b, T c)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point input");
|
||||
|
||||
if (isnan(a))
|
||||
return fmax(b, c);
|
||||
if (isnan(b))
|
||||
return fmax(a, c);
|
||||
if (isnan(c))
|
||||
return max(a, b);
|
||||
return max(a, b, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GLM_FUNC_QUALIFIER T fmax(T a, T b, T c, T d)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point input");
|
||||
|
||||
if (isnan(a))
|
||||
return fmax(b, c, d);
|
||||
if (isnan(b))
|
||||
return max(a, fmax(c, d));
|
||||
if (isnan(c))
|
||||
return fmax(max(a, b), d);
|
||||
if (isnan(d))
|
||||
return max(a, b, c);
|
||||
return max(a, b, c, d);
|
||||
}
|
||||
}//namespace glm
|
134
glm/ext/vector_common.hpp
Normal file
134
glm/ext/vector_common.hpp
Normal file
@ -0,0 +1,134 @@
|
||||
/// @ref ext_vector_common
|
||||
/// @file glm/ext/vector_common.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup ext_vector_common GLM_EXT_vector_common
|
||||
/// @ingroup ext
|
||||
///
|
||||
/// Include <glm/ext/vector_common.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Min and max functions for 3 to 4 parameters.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../glm.hpp"
|
||||
|
||||
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_EXT_vector_common extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup ext_vector_common
|
||||
/// @{
|
||||
|
||||
/// Return the minimum component-wise values of 3 inputs
|
||||
///
|
||||
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
|
||||
/// @tparam T Floating-point or integer scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_vector_common
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> min(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c);
|
||||
|
||||
/// Return the minimum component-wise values of 4 inputs
|
||||
///
|
||||
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
|
||||
/// @tparam T Floating-point or integer scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_vector_common
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> min(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c, vec<L, T, Q> const& d);
|
||||
|
||||
/// Return the maximum component-wise values of 3 inputs
|
||||
///
|
||||
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
|
||||
/// @tparam T Floating-point or integer scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_vector_common
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> max(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& z);
|
||||
|
||||
/// Return the maximum component-wise values of 4 inputs
|
||||
///
|
||||
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
|
||||
/// @tparam T Floating-point or integer scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_vector_common
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> max( vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& z, vec<L, T, Q> const& w);
|
||||
|
||||
/// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_vector_common
|
||||
/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmin">std::fmin documentation</a>
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fmin(vec<L, T, Q> const& x, T y);
|
||||
|
||||
/// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_vector_common
|
||||
/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmin">std::fmin documentation</a>
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fmin(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
|
||||
|
||||
/// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_vector_common
|
||||
/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fmax(vec<L, T, Q> const& x, T y);
|
||||
|
||||
/// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_vector_common
|
||||
/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fmax(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
|
||||
|
||||
/// Returns min(max(x, minVal), maxVal) for each component in x. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_vector_common
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fclamp(vec<L, T, Q> const& x, T minVal, T maxVal);
|
||||
|
||||
/// Returns min(max(x, minVal), maxVal) for each component in x. If one of the two arguments is NaN, the value of the other argument is returned.
|
||||
///
|
||||
/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_vector_common
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<L, T, Q> fclamp(vec<L, T, Q> const& x, vec<L, T, Q> const& minVal, vec<L, T, Q> const& maxVal);
|
||||
|
||||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "vector_common.inl"
|
72
glm/ext/vector_common.inl
Normal file
72
glm/ext/vector_common.inl
Normal file
@ -0,0 +1,72 @@
|
||||
namespace glm
|
||||
{
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> min(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& z)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'min' only accept floating-point or integer inputs");
|
||||
return glm::min(glm::min(x, y), z);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> min(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& z, vec<L, T, Q> const& w)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'min' only accept floating-point or integer inputs");
|
||||
return glm::min(glm::min(x, y), glm::min(z, w));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> max(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& z)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'max' only accept floating-point or integer inputs");
|
||||
return glm::max(glm::max(x, y), z);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> max(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& z, vec<L, T, Q> const& w)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'max' only accept floating-point or integer inputs");
|
||||
return glm::max(glm::max(x, y), glm::max(z, w));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fmin(vec<L, T, Q> const& a, T b)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point inputs");
|
||||
return detail::functor2<vec, L, T, Q>::call(fmin, a, vec<L, T, Q>(b));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fmin(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point inputs");
|
||||
return detail::functor2<vec, L, T, Q>::call(fmin, a, b);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fmax(vec<L, T, Q> const& a, T b)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point inputs");
|
||||
return detail::functor2<vec, L, T, Q>::call(fmax, a, vec<L, T, Q>(b));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fmax(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point inputs");
|
||||
return detail::functor2<vec, L, T, Q>::call(fmax, a, b);
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fclamp(vec<L, T, Q> const& x, T minVal, T maxVal)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fclamp' only accept floating-point inputs");
|
||||
return fmin(fmax(x, vec<L, T, Q>(minVal)), vec<L, T, Q>(maxVal));
|
||||
}
|
||||
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> fclamp(vec<L, T, Q> const& x, vec<L, T, Q> const& minVal, vec<L, T, Q> const& maxVal)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fclamp' only accept floating-point inputs");
|
||||
return fmin(fmax(x, minVal), maxVal);
|
||||
}
|
||||
}//namespace glm
|
@ -24,6 +24,7 @@
|
||||
#include "../ext/quaternion_double_precision.hpp"
|
||||
#include "../ext/quaternion_relational.hpp"
|
||||
#include "../ext/quaternion_geometric.hpp"
|
||||
#include "../ext/quaternion_transform.hpp"
|
||||
#include "../detail/type_mat3x3.hpp"
|
||||
#include "../detail/type_mat4x4.hpp"
|
||||
#include "../detail/type_vec3.hpp"
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../glm.hpp"
|
||||
#include "../gtc/constants.hpp"
|
||||
#include "../gtc/quaternion.hpp"
|
||||
#include "../ext/quaternion_exponential.hpp"
|
||||
#include "../gtx/norm.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
@ -75,28 +76,6 @@ namespace glm
|
||||
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 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 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 qua<T, Q> pow(
|
||||
qua<T, Q> const& x,
|
||||
T const& y);
|
||||
|
||||
//! Returns quarternion square root.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
@ -183,33 +162,6 @@ namespace glm
|
||||
vec<3, T, Q> const& orig,
|
||||
vec<3, T, Q> const& dest);
|
||||
|
||||
/// Build a look at quaternion based on the default handedness.
|
||||
///
|
||||
/// @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 qua<T, Q> quatLookAt(
|
||||
vec<3, T, Q> const& direction,
|
||||
vec<3, T, Q> const& up);
|
||||
|
||||
/// Build a right-handed look at quaternion.
|
||||
///
|
||||
/// @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 qua<T, Q> quatLookAtRH(
|
||||
vec<3, T, Q> const& direction,
|
||||
vec<3, T, Q> const& up);
|
||||
|
||||
/// Build a left-handed look at quaternion.
|
||||
///
|
||||
/// @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 qua<T, Q> quatLookAtLH(
|
||||
vec<3, T, Q> const& direction,
|
||||
vec<3, T, Q> const& up);
|
||||
|
||||
/// Returns the squared length of x.
|
||||
///
|
||||
/// @see gtx_quaternion
|
||||
|
@ -47,65 +47,6 @@ namespace glm
|
||||
return exp((log(next * invQuat) + log(prev * invQuat)) / static_cast<T>(-4)) * curr;
|
||||
}
|
||||
|
||||
template<typename T, qualifier 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 qua<T, Q>();
|
||||
|
||||
vec<3, T, Q> const v(u / Angle);
|
||||
return qua<T, Q>(cos(Angle), sin(Angle) * v);
|
||||
}
|
||||
|
||||
template<typename T, qualifier 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);
|
||||
|
||||
if (Vec3Len < epsilon<T>())
|
||||
{
|
||||
if(q.w > 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 qua<T, Q>(log(-q.w), pi<T>(), static_cast<T>(0), static_cast<T>(0));
|
||||
else
|
||||
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 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 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 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);
|
||||
|
||||
//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 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 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(qua<T, Q> const& q, vec<3, T, Q> const& v)
|
||||
{
|
||||
@ -215,39 +156,4 @@ namespace glm
|
||||
rotationAxis.y * invs,
|
||||
rotationAxis.z * invs);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
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);
|
||||
# else
|
||||
return quatLookAtRH(direction, up);
|
||||
# endif
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
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;
|
||||
|
||||
Result[2] = -direction;
|
||||
Result[0] = normalize(cross(up, Result[2]));
|
||||
Result[1] = cross(Result[2], Result[0]);
|
||||
|
||||
return quat_cast(Result);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
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;
|
||||
|
||||
Result[2] = direction;
|
||||
Result[0] = normalize(cross(up, Result[2]));
|
||||
Result[1] = cross(Result[2], Result[0]);
|
||||
|
||||
return quat_cast(Result);
|
||||
}
|
||||
|
||||
}//namespace glm
|
||||
|
@ -1,11 +1,13 @@
|
||||
glmCreateTestGTC(ext_matrix_relational)
|
||||
glmCreateTestGTC(ext_matrix_transform)
|
||||
glmCreateTestGTC(ext_quaternion_common)
|
||||
glmCreateTestGTC(ext_quaternion_exponential)
|
||||
glmCreateTestGTC(ext_quaternion_geometric)
|
||||
glmCreateTestGTC(ext_quaternion_relational)
|
||||
glmCreateTestGTC(ext_quaternion_transform)
|
||||
glmCreateTestGTC(ext_quaternion_trigonometric)
|
||||
glmCreateTestGTC(ext_quaternion_type)
|
||||
glmCreateTestGTC(ext_scalar_common)
|
||||
glmCreateTestGTC(ext_scalar_constants)
|
||||
glmCreateTestGTC(ext_scalar_float_sized)
|
||||
glmCreateTestGTC(ext_scalar_int_sized)
|
||||
@ -13,6 +15,7 @@ glmCreateTestGTC(ext_scalar_uint_sized)
|
||||
glmCreateTestGTC(ext_scalar_relational)
|
||||
glmCreateTestGTC(ext_vec1)
|
||||
glmCreateTestGTC(ext_vector_bool1)
|
||||
glmCreateTestGTC(ext_vector_common)
|
||||
glmCreateTestGTC(ext_vector_iec559)
|
||||
glmCreateTestGTC(ext_vector_integer)
|
||||
glmCreateTestGTC(ext_vector_relational)
|
||||
|
87
test/ext/ext_quaternion_exponential.cpp
Normal file
87
test/ext/ext_quaternion_exponential.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include <glm/ext/quaternion_exponential.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/quaternion_relational.hpp>
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
#include <glm/ext/vector_float3_precision.hpp>
|
||||
#include <glm/ext/vector_double3.hpp>
|
||||
#include <glm/ext/vector_double3_precision.hpp>
|
||||
#include <glm/ext/scalar_constants.hpp>
|
||||
|
||||
template <typename quaType, typename vecType>
|
||||
int test_log()
|
||||
{
|
||||
typedef typename quaType::value_type T;
|
||||
|
||||
T const Epsilon = static_cast<T>(0.001f);
|
||||
|
||||
int Error = 0;
|
||||
|
||||
quaType const Q(vecType(1, 0, 0), vecType(0, 1, 0));
|
||||
quaType const P = glm::log(Q);
|
||||
Error += glm::any(glm::notEqual(Q, P, Epsilon)) ? 0 : 1;
|
||||
|
||||
quaType const R = glm::exp(P);
|
||||
Error += glm::all(glm::equal(Q, R, Epsilon)) ? 0 : 1;
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
template <typename quaType, typename vecType>
|
||||
int test_pow()
|
||||
{
|
||||
typedef typename quaType::value_type T;
|
||||
|
||||
T const Epsilon = static_cast<T>(0.001f);
|
||||
|
||||
int Error = 0;
|
||||
|
||||
quaType const Q(vecType(1, 0, 0), vecType(0, 1, 0));
|
||||
|
||||
{
|
||||
T const One = static_cast<T>(1.0f);
|
||||
quaType const P = glm::pow(Q, One);
|
||||
Error += glm::all(glm::equal(Q, P, Epsilon)) ? 0 : 1;
|
||||
}
|
||||
|
||||
{
|
||||
T const Two = static_cast<T>(2.0f);
|
||||
quaType const P = glm::pow(Q, Two);
|
||||
quaType const R = Q * Q;
|
||||
Error += glm::all(glm::equal(P, R, Epsilon)) ? 0 : 1;
|
||||
|
||||
quaType const U = glm::sqrt(P);
|
||||
Error += glm::all(glm::equal(Q, U, Epsilon)) ? 0 : 1;
|
||||
}
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
Error += test_log<glm::quat, glm::vec3>();
|
||||
Error += test_log<glm::lowp_quat, glm::lowp_vec3>();
|
||||
Error += test_log<glm::mediump_quat, glm::mediump_vec3>();
|
||||
Error += test_log<glm::highp_quat, glm::highp_vec3>();
|
||||
|
||||
Error += test_log<glm::dquat, glm::dvec3>();
|
||||
Error += test_log<glm::lowp_dquat, glm::lowp_dvec3>();
|
||||
Error += test_log<glm::mediump_dquat, glm::mediump_dvec3>();
|
||||
Error += test_log<glm::highp_dquat, glm::highp_dvec3>();
|
||||
|
||||
Error += test_pow<glm::quat, glm::vec3>();
|
||||
Error += test_pow<glm::lowp_quat, glm::lowp_vec3>();
|
||||
Error += test_pow<glm::mediump_quat, glm::mediump_vec3>();
|
||||
Error += test_pow<glm::highp_quat, glm::highp_vec3>();
|
||||
|
||||
Error += test_pow<glm::dquat, glm::dvec3>();
|
||||
Error += test_pow<glm::lowp_dquat, glm::lowp_dvec3>();
|
||||
Error += test_pow<glm::mediump_dquat, glm::mediump_dvec3>();
|
||||
Error += test_pow<glm::highp_dquat, glm::highp_dvec3>();
|
||||
|
||||
return Error;
|
||||
}
|
@ -3,9 +3,43 @@
|
||||
#include <glm/ext/vector_relational.hpp>
|
||||
#include <glm/ext/scalar_constants.hpp>
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
static int test_lookAt()
|
||||
{
|
||||
int Error(0);
|
||||
|
||||
glm::vec3 eye(0.0f);
|
||||
glm::vec3 center(1.1f, -2.0f, 3.1416f);
|
||||
glm::vec3 up(-0.17f, 7.23f, -1.744f);
|
||||
|
||||
glm::quat test_quat = glm::quatLookAt(glm::normalize(center - eye), up);
|
||||
glm::quat test_mat = glm::conjugate(glm::quat_cast(glm::lookAt(eye, center, up)));
|
||||
|
||||
Error += static_cast<int>(glm::abs(glm::length(test_quat) - 1.0f) > glm::epsilon<float>());
|
||||
Error += static_cast<int>(glm::min(glm::length(test_quat + (-test_mat)), glm::length(test_quat + test_mat)) > glm::epsilon<float>());
|
||||
|
||||
// Test left-handed implementation
|
||||
glm::quat test_quatLH = glm::quatLookAtLH(glm::normalize(center - eye), up);
|
||||
glm::quat test_matLH = glm::conjugate(glm::quat_cast(glm::lookAtLH(eye, center, up)));
|
||||
Error += static_cast<int>(glm::abs(glm::length(test_quatLH) - 1.0f) > glm::epsilon<float>());
|
||||
Error += static_cast<int>(glm::min(glm::length(test_quatLH - test_matLH), glm::length(test_quatLH + test_matLH)) > glm::epsilon<float>());
|
||||
|
||||
// Test right-handed implementation
|
||||
glm::quat test_quatRH = glm::quatLookAtRH(glm::normalize(center - eye), up);
|
||||
glm::quat test_matRH = glm::conjugate(glm::quat_cast(glm::lookAtRH(eye, center, up)));
|
||||
Error += static_cast<int>(glm::abs(glm::length(test_quatRH) - 1.0f) > glm::epsilon<float>());
|
||||
Error += static_cast<int>(glm::min(glm::length(test_quatRH - test_matRH), glm::length(test_quatRH + test_matRH)) > glm::epsilon<float>());
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
Error += test_lookAt();
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
204
test/ext/ext_scalar_common.cpp
Normal file
204
test/ext/ext_scalar_common.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
#include <glm/ext/scalar_common.hpp>
|
||||
#include <glm/ext/scalar_constants.hpp>
|
||||
#include <glm/ext/scalar_relational.hpp>
|
||||
#include <glm/common.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
template <typename T>
|
||||
static int test_min()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
T const N = static_cast<T>(0);
|
||||
T const B = static_cast<T>(1);
|
||||
Error += glm::equal(glm::min(N, B), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(B, N), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
T const C = static_cast<T>(2);
|
||||
Error += glm::equal(glm::min(N, B, C), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(B, N, C), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(C, N, B), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(C, B, N), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(B, C, N), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(N, C, B), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
T const D = static_cast<T>(3);
|
||||
Error += glm::equal(glm::min(D, N, B, C), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(B, D, N, C), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(C, N, D, B), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(C, B, D, N), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(B, C, N, D), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::min(N, C, B, D), N, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static int test_min_nan()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
T const A = static_cast<T>(0);
|
||||
T const B = static_cast<T>(1);
|
||||
T const N = A / A;
|
||||
Error += glm::isnan(glm::min(N, B)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::min(B, N)) ? 0 : 1;
|
||||
|
||||
T const C = static_cast<T>(2);
|
||||
Error += glm::isnan(glm::min(N, B, C)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::min(B, N, C)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::min(C, N, B)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::min(C, B, N)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::min(B, C, N)) ? 0 : 1;
|
||||
Error += glm::isnan(glm::min(N, C, B)) ? 0 : 1;
|
||||
|
||||
T const D = static_cast<T>(3);
|
||||
Error += !glm::isnan(glm::min(D, N, B, C)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::min(B, D, N, C)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::min(C, N, D, B)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::min(C, B, D, N)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::min(B, C, N, D)) ? 0 : 1;
|
||||
Error += glm::isnan(glm::min(N, C, B, D)) ? 0 : 1;
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static int test_max()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
T const N = static_cast<T>(0);
|
||||
T const B = static_cast<T>(1);
|
||||
Error += glm::equal(glm::max(N, B), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(B, N), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
T const C = static_cast<T>(2);
|
||||
Error += glm::equal(glm::max(N, B, C), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(B, N, C), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(C, N, B), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(C, B, N), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(B, C, N), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(N, C, B), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
T const D = static_cast<T>(3);
|
||||
Error += glm::equal(glm::max(D, N, B, C), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(B, D, N, C), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(C, N, D, B), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(C, B, D, N), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(B, C, N, D), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::max(N, C, B, D), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static int test_max_nan()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
T const A = static_cast<T>(0);
|
||||
T const B = static_cast<T>(1);
|
||||
T const N = A / A;
|
||||
Error += glm::isnan(glm::max(N, B)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::max(B, N)) ? 0 : 1;
|
||||
|
||||
T const C = static_cast<T>(2);
|
||||
Error += glm::isnan(glm::max(N, B, C)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::max(B, N, C)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::max(C, N, B)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::max(C, B, N)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::max(B, C, N)) ? 0 : 1;
|
||||
Error += glm::isnan(glm::max(N, C, B)) ? 0 : 1;
|
||||
|
||||
T const D = static_cast<T>(3);
|
||||
Error += !glm::isnan(glm::max(D, N, B, C)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::max(B, D, N, C)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::max(C, N, D, B)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::max(C, B, D, N)) ? 0 : 1;
|
||||
Error += !glm::isnan(glm::max(B, C, N, D)) ? 0 : 1;
|
||||
Error += glm::isnan(glm::max(N, C, B, D)) ? 0 : 1;
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static int test_fmin()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
T const A = static_cast<T>(0);
|
||||
T const B = static_cast<T>(1);
|
||||
Error += glm::equal(glm::fmin(A / A, B), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(B, A / A), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
T const C = static_cast<T>(2);
|
||||
Error += glm::equal(glm::fmin(A / A, B, C), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(B, A / A, C), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(C, A / A, B), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(C, B, A / A), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(B, C, A / A), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(A / A, C, B), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
T const D = static_cast<T>(3);
|
||||
Error += glm::equal(glm::fmin(D, A / A, B, C), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(B, D, A / A, C), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(C, A / A, D, B), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(C, B, D, A / A), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(B, C, A / A, D), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmin(A / A, C, B, D), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static int test_fmax()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
T const A = static_cast<T>(0);
|
||||
T const B = static_cast<T>(1);
|
||||
Error += glm::equal(glm::fmax(A / A, B), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(B, A / A), B, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
T const C = static_cast<T>(2);
|
||||
Error += glm::equal(glm::fmax(A / A, B, C), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(B, A / A, C), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(C, A / A, B), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(C, B, A / A), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(B, C, A / A), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(A / A, C, B), C, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
T const D = static_cast<T>(3);
|
||||
Error += glm::equal(glm::fmax(D, A / A, B, C), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(B, D, A / A, C), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(C, A / A, D, B), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(C, B, D, A / A), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(B, C, A / A, D), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
Error += glm::equal(glm::fmax(A / A, C, B, D), D, glm::epsilon<T>()) ? 0 : 1;
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
Error += test_min<float>();
|
||||
Error += test_min<double>();
|
||||
Error += test_min_nan<float>();
|
||||
Error += test_min_nan<double>();
|
||||
|
||||
Error += test_max<float>();
|
||||
Error += test_max<double>();
|
||||
Error += test_max_nan<float>();
|
||||
Error += test_max_nan<double>();
|
||||
|
||||
Error += test_fmin<float>();
|
||||
Error += test_fmin<double>();
|
||||
|
||||
Error += test_fmax<float>();
|
||||
Error += test_fmax<double>();
|
||||
|
||||
return Error;
|
||||
}
|
24
test/ext/ext_vector_common.cpp
Normal file
24
test/ext/ext_vector_common.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include <glm/ext/vector_common.hpp>
|
||||
#include <glm/ext/vector_float1.hpp>
|
||||
#include <glm/ext/vector_float1_precision.hpp>
|
||||
#include <glm/ext/vector_float2.hpp>
|
||||
#include <glm/ext/vector_float2_precision.hpp>
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
#include <glm/ext/vector_float3_precision.hpp>
|
||||
#include <glm/ext/vector_float4.hpp>
|
||||
#include <glm/ext/vector_float4_precision.hpp>
|
||||
#include <glm/ext/vector_double1.hpp>
|
||||
#include <glm/ext/vector_double1_precision.hpp>
|
||||
#include <glm/ext/vector_double2.hpp>
|
||||
#include <glm/ext/vector_double2_precision.hpp>
|
||||
#include <glm/ext/vector_double3.hpp>
|
||||
#include <glm/ext/vector_double3_precision.hpp>
|
||||
#include <glm/ext/vector_double4.hpp>
|
||||
#include <glm/ext/vector_double4_precision.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
return Error;
|
||||
}
|
@ -93,35 +93,6 @@ int test_log()
|
||||
return Error;
|
||||
}
|
||||
|
||||
int test_quat_lookAt()
|
||||
{
|
||||
int Error(0);
|
||||
|
||||
glm::vec3 eye(0.0f);
|
||||
glm::vec3 center(1.1f, -2.0f, 3.1416f);
|
||||
glm::vec3 up(-0.17f, 7.23f, -1.744f);
|
||||
|
||||
glm::quat test_quat = glm::quatLookAt(glm::normalize(center - eye), up);
|
||||
glm::quat test_mat = glm::conjugate(glm::quat_cast(glm::lookAt(eye, center, up)));
|
||||
|
||||
Error += static_cast<int>(glm::abs(glm::length(test_quat) - 1.0f) > glm::epsilon<float>());
|
||||
Error += static_cast<int>(glm::min(glm::length(test_quat + (-test_mat)), glm::length(test_quat + test_mat)) > glm::epsilon<float>());
|
||||
|
||||
// Test left-handed implementation
|
||||
glm::quat test_quatLH = glm::quatLookAtLH(glm::normalize(center - eye), up);
|
||||
glm::quat test_matLH = glm::conjugate(glm::quat_cast(glm::lookAtLH(eye, center, up)));
|
||||
Error += static_cast<int>(glm::abs(glm::length(test_quatLH) - 1.0f) > glm::epsilon<float>());
|
||||
Error += static_cast<int>(glm::min(glm::length(test_quatLH - test_matLH), glm::length(test_quatLH + test_matLH)) > glm::epsilon<float>());
|
||||
|
||||
// Test right-handed implementation
|
||||
glm::quat test_quatRH = glm::quatLookAtRH(glm::normalize(center - eye), up);
|
||||
glm::quat test_matRH = glm::conjugate(glm::quat_cast(glm::lookAtRH(eye, center, up)));
|
||||
Error += static_cast<int>(glm::abs(glm::length(test_quatRH) - 1.0f) > glm::epsilon<float>());
|
||||
Error += static_cast<int>(glm::min(glm::length(test_quatRH - test_matRH), glm::length(test_quatRH + test_matRH)) > glm::epsilon<float>());
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int Error = 0;
|
||||
@ -131,7 +102,6 @@ int main()
|
||||
Error += test_orientation();
|
||||
Error += test_quat_fastMix();
|
||||
Error += test_quat_shortMix();
|
||||
Error += test_quat_lookAt();
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user