Fixed bug #15, added missing roll, pitch and yaw functions; Fixed half implicit conversions

This commit is contained in:
Christophe Riccio 2012-12-13 22:48:20 +01:00
parent 931b7bcdd6
commit 841f91e830
11 changed files with 244 additions and 171 deletions

View File

@ -38,7 +38,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'pow' only accept floating-point input");
return ::std::pow(x, y);
return genType(::std::pow(x, y));
}
VECTORIZE_VEC_VEC(pow)
@ -52,7 +52,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'exp' only accept floating-point input");
return ::std::exp(x);
return genType(::std::exp(x));
}
VECTORIZE_VEC(exp)
@ -66,7 +66,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'log' only accept floating-point input");
return ::std::log(x);
return genType(::std::log(x));
}
VECTORIZE_VEC(log)
@ -80,7 +80,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'exp2' only accept floating-point input");
return ::std::exp(genType(0.69314718055994530941723212145818) * x);
return genType(::std::exp(genType(0.69314718055994530941723212145818) * x));
}
VECTORIZE_VEC(exp2)

View File

@ -67,7 +67,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sin' only accept floating-point input");
return ::std::sin(angle);
return genType(::std::sin(angle));
}
VECTORIZE_VEC(sin)
@ -78,7 +78,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cos' only accept floating-point input");
return ::std::cos(angle);
return genType(::std::cos(angle));
}
VECTORIZE_VEC(cos)
@ -92,7 +92,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'tan' only accept floating-point input");
return ::std::tan(angle);
return genType(::std::tan(angle));
}
VECTORIZE_VEC(tan)
@ -106,7 +106,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asin' only accept floating-point input");
return ::std::asin(x);
return genType(::std::asin(x));
}
VECTORIZE_VEC(asin)
@ -120,7 +120,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acos' only accept floating-point input");
return ::std::acos(x);
return genType(::std::acos(x));
}
VECTORIZE_VEC(acos)
@ -135,7 +135,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atan' only accept floating-point input");
return ::std::atan2(y, x);
return genType(::std::atan2(y, x));
}
VECTORIZE_VEC_VEC(atan)
@ -148,7 +148,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atan' only accept floating-point input");
return ::std::atan(x);
return genType(::std::atan(x));
}
VECTORIZE_VEC(atan)
@ -162,7 +162,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sinh' only accept floating-point input");
return std::sinh(angle);
return genType(std::sinh(angle));
}
VECTORIZE_VEC(sinh)
@ -176,7 +176,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cosh' only accept floating-point input");
return std::cosh(angle);
return genType(std::cosh(angle));
}
VECTORIZE_VEC(cosh)
@ -190,7 +190,7 @@ namespace glm
{
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'tanh' only accept floating-point input");
return std::tanh(angle);
return genType(std::tanh(angle));
}
VECTORIZE_VEC(tanh)

View File

@ -50,8 +50,9 @@ namespace detail
GLM_FUNC_DECL explicit half(U const & s);
// Cast
template <typename U>
GLM_FUNC_DECL operator U() const;
//template <typename U>
//GLM_FUNC_DECL operator U() const;
GLM_FUNC_DECL operator float() const;
// Unary updatable operators
GLM_FUNC_DECL half& operator= (half const & s);

View File

@ -266,12 +266,18 @@ namespace detail
GLM_FUNC_QUALIFIER half::half(U const & s) :
data(toFloat16(float(s)))
{}
/*
template <typename U>
GLM_FUNC_QUALIFIER half::operator U() const
{
return static_cast<U>(toFloat32(this->data));
}
*/
GLM_FUNC_QUALIFIER half::operator float() const
{
return toFloat32(this->data);
}
// Unary updatable operators
GLM_FUNC_QUALIFIER half& half::operator= (half const & s)

View File

@ -212,6 +212,27 @@ namespace detail
detail::tvec3<T> eulerAngles(
detail::tquat<T> const & x);
/// Returns roll value of euler angles expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
///
/// @see gtx_quaternion
template <typename valType>
valType roll(
detail::tquat<valType> const & x);
/// Returns pitch value of euler angles expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
///
/// @see gtx_quaternion
template <typename valType>
valType pitch(
detail::tquat<valType> const & x);
/// Returns yaw value of euler angles expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
///
/// @see gtx_quaternion
template <typename valType>
valType yaw(
detail::tquat<valType> const & x);
/// Converts a quaternion to a 3 * 3 matrix.
///
/// @see gtc_quaternion

View File

@ -512,7 +512,46 @@ namespace detail
{
return detail::tvec3<T>(pitch(x), yaw(x), roll(x));
}
template <typename valType>
GLM_FUNC_QUALIFIER valType roll
(
detail::tquat<valType> const & q
)
{
#ifdef GLM_FORCE_RADIANS
return valType(atan2(valType(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));
#else
return glm::degrees(atan(valType(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));
#endif
}
template <typename valType>
GLM_FUNC_QUALIFIER valType pitch
(
detail::tquat<valType> const & q
)
{
#ifdef GLM_FORCE_RADIANS
return valType(atan2(valType(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));
#else
return glm::degrees(atan(valType(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));
#endif
}
template <typename valType>
GLM_FUNC_QUALIFIER valType yaw
(
detail::tquat<valType> const & q
)
{
#ifdef GLM_FORCE_RADIANS
return asin(valType(-2) * (q.x * q.z - q.w * q.y));
#else
return glm::degrees(asin(valType(-2) * (q.x * q.z - q.w * q.y)));
#endif
}
template <typename T>
GLM_FUNC_QUALIFIER detail::tmat3x3<T> mat3_cast
(

View File

@ -127,7 +127,7 @@ namespace glm
detail::tquat<valType> const & q,
detail::tvec3<valType> const & v);
/// Rotates a 4 components vector by a quaternion.
/// Rotates a 4 components vector by a quaternion.
///
/// @see gtx_quaternion
template <typename valType>
@ -142,38 +142,10 @@ namespace glm
valType extractRealComponent(
detail::tquat<valType> const & q);
/// Returns roll value of euler angles expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
///
/// @see gtx_quaternion
template <typename valType>
valType roll(
detail::tquat<valType> const & x);
/// Returns pitch value of euler angles expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
///
/// @see gtx_quaternion
template <typename valType>
valType pitch(
detail::tquat<valType> const & x);
/// Returns yaw value of euler angles expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
///
/// @see gtx_quaternion
template <typename valType>
valType yaw(
detail::tquat<valType> const & x);
/// Returns euler angles, yitch as x, yaw as y, roll as z.
///
/// @see gtx_quaternion
template <typename valType>
detail::tvec3<valType> eulerAngles(
detail::tquat<valType> const & x);
/// Converts a quaternion to a 3 * 3 matrix.
///
/// @see gtx_quaternion
template <typename valType>
template <typename valType>
detail::tmat3x3<valType> toMat3(
detail::tquat<valType> const & x){return mat3_cast(x);}

View File

@ -154,45 +154,6 @@ namespace glm
return -sqrt(w);
}
template <typename valType>
GLM_FUNC_QUALIFIER valType roll
(
detail::tquat<valType> const & q
)
{
#ifdef GLM_FORCE_RADIANS
return atan2(valType(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);
#else
return glm::degrees(atan2(valType(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));
#endif
}
template <typename valType>
GLM_FUNC_QUALIFIER valType pitch
(
detail::tquat<valType> const & q
)
{
#ifdef GLM_FORCE_RADIANS
return atan2(valType(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);
#else
return glm::degrees(atan2(valType(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));
#endif
}
template <typename valType>
GLM_FUNC_QUALIFIER valType yaw
(
detail::tquat<valType> const & q
)
{
#ifdef GLM_FORCE_RADIANS
return asin(valType(-2) * (q.x * q.z - q.w * q.y));
#else
return glm::degrees(asin(valType(-2) * (q.x * q.z - q.w * q.y)));
#endif
}
template <typename T>
GLM_FUNC_QUALIFIER detail::tquat<T> shortMix
(

View File

@ -2,7 +2,7 @@
// OpenGL Mathematics Copyright (c) 2005 - 2012 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2012-09-19
// Updated : 2012-09-19
// Updated : 2012-12-13
// Licence : This source is under MIT licence
// File : test/gtc/constants.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -10,6 +10,25 @@
#include <glm/glm.hpp>
#include <glm/gtc/constants.hpp>
int test_epsilon()
{
int Error(0);
{
glm::half Test = glm::epsilon<glm::half>();
}
{
float Test = glm::epsilon<float>();
}
{
double Test = glm::epsilon<double>();
}
return Error;
}
int main()
{
int Error(0);

View File

@ -13,34 +13,34 @@
int test_quat_angle()
{
int Error = 0;
{
glm::quat Q = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.01f) ? 0 : 1;
float A = glm::angle(N);
Error += glm::epsilonEqual(A, 45.0f, 0.01f) ? 0 : 1;
}
{
glm::quat Q = glm::angleAxis(45.0f, glm::normalize(glm::vec3(0, 1, 1)));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.01f) ? 0 : 1;
float A = glm::angle(N);
Error += glm::epsilonEqual(A, 45.0f, 0.01f) ? 0 : 1;
}
{
glm::quat Q = glm::angleAxis(45.0f, glm::normalize(glm::vec3(1, 2, 3)));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.01f) ? 0 : 1;
float A = glm::angle(N);
Error += glm::epsilonEqual(A, 45.0f, 0.01f) ? 0 : 1;
}
return Error;
int Error = 0;
{
glm::quat Q = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.01f) ? 0 : 1;
float A = glm::angle(N);
Error += glm::epsilonEqual(A, 45.0f, 0.01f) ? 0 : 1;
}
{
glm::quat Q = glm::angleAxis(45.0f, glm::normalize(glm::vec3(0, 1, 1)));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.01f) ? 0 : 1;
float A = glm::angle(N);
Error += glm::epsilonEqual(A, 45.0f, 0.01f) ? 0 : 1;
}
{
glm::quat Q = glm::angleAxis(45.0f, glm::normalize(glm::vec3(1, 2, 3)));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.01f) ? 0 : 1;
float A = glm::angle(N);
Error += glm::epsilonEqual(A, 45.0f, 0.01f) ? 0 : 1;
}
return Error;
}
int test_quat_angleAxis()
@ -49,10 +49,10 @@ int test_quat_angleAxis()
glm::quat A = glm::angleAxis(0.0f, glm::vec3(0, 0, 1));
glm::quat B = glm::angleAxis(90.0f, glm::vec3(0, 0, 1));
glm::quat C = glm::mix(A, B, 0.5f);
glm::quat D = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
glm::quat C = glm::mix(A, B, 0.5f);
glm::quat D = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(C.x, D.x, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.x, D.x, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.y, D.y, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.z, D.z, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.w, D.w, 0.01f) ? 0 : 1;
@ -63,17 +63,17 @@ int test_quat_angleAxis()
int test_quat_mix()
{
int Error = 0;
glm::quat A = glm::angleAxis(0.0f, glm::vec3(0, 0, 1));
glm::quat B = glm::angleAxis(90.0f, glm::vec3(0, 0, 1));
glm::quat C = glm::mix(A, B, 0.5f);
glm::quat D = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(C.x, D.x, 0.01f) ? 0 : 1;
glm::quat C = glm::mix(A, B, 0.5f);
glm::quat D = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(C.x, D.x, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.y, D.y, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.z, D.z, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.w, D.w, 0.01f) ? 0 : 1;
return Error;
}
@ -83,54 +83,86 @@ int test_quat_precision()
Error += sizeof(glm::lowp_quat) <= sizeof(glm::mediump_quat) ? 0 : 1;
Error += sizeof(glm::mediump_quat) <= sizeof(glm::highp_quat) ? 0 : 1;
return Error;
return Error;
}
int test_quat_normalize()
{
int Error = 0;
{
glm::quat Q = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.000001f) ? 0 : 1;
}
{
glm::quat Q = glm::angleAxis(45.0f, glm::vec3(0, 0, 2));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.000001f) ? 0 : 1;
}
{
glm::quat Q = glm::angleAxis(45.0f, glm::vec3(1, 2, 3));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.000001f) ? 0 : 1;
}
int Error(0);
return Error;
{
glm::quat Q = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.000001f) ? 0 : 1;
}
{
glm::quat Q = glm::angleAxis(45.0f, glm::vec3(0, 0, 2));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.000001f) ? 0 : 1;
}
{
glm::quat Q = glm::angleAxis(45.0f, glm::vec3(1, 2, 3));
glm::quat N = glm::normalize(Q);
float L = glm::length(N);
Error += glm::epsilonEqual(L, 1.0f, 0.000001f) ? 0 : 1;
}
return Error;
}
int test_quat_euler()
{
int Error(0);
{
glm::quat q(1.0f, 0.0f, 0.0f, 1.0f);
float Roll = glm::roll(q);
float Pitch = glm::pitch(q);
float Yaw = glm::yaw(q);
glm::vec3 Angles = glm::eulerAngles(q);
}
{
glm::dquat q(1.0f, 0.0f, 0.0f, 1.0f);
double Roll = glm::roll(q);
double Pitch = glm::pitch(q);
double Yaw = glm::yaw(q);
glm::dvec3 Angles = glm::eulerAngles(q);
}
{
glm::hquat q(glm::half(1.0f), glm::half(0.0f), glm::half(0.0f), glm::half(1.0f));
glm::half Roll = glm::roll(q);
glm::half Pitch = glm::pitch(q);
glm::half Yaw = glm::yaw(q);
glm::hvec3 Angles = glm::eulerAngles(q);
}
return Error;
}
int test_quat_type()
{
glm::quat A;
glm::dquat B;
return 0;
glm::quat A;
glm::dquat B;
return 0;
}
int main()
{
int Error = 0;
int Error(0);
Error += test_quat_precision();
Error += test_quat_type();
Error += test_quat_angle();
Error += test_quat_type();
Error += test_quat_angle();
Error += test_quat_angleAxis();
Error += test_quat_mix();
Error += test_quat_normalize();
Error += test_quat_euler();
return Error;
}

View File

@ -14,43 +14,65 @@
int test_quat_fastMix()
{
int Error = 0;
glm::quat A = glm::angleAxis(0.0f, glm::vec3(0, 0, 1));
glm::quat B = glm::angleAxis(90.0f, glm::vec3(0, 0, 1));
glm::quat C = glm::fastMix(A, B, 0.5f);
glm::quat D = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(C.x, D.x, 0.01f) ? 0 : 1;
glm::quat C = glm::fastMix(A, B, 0.5f);
glm::quat D = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(C.x, D.x, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.y, D.y, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.z, D.z, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.w, D.w, 0.01f) ? 0 : 1;
return Error;
}
int test_quat_shortMix()
{
int Error = 0;
int Error(0);
glm::quat A = glm::angleAxis(0.0f, glm::vec3(0, 0, 1));
glm::quat B = glm::angleAxis(90.0f, glm::vec3(0, 0, 1));
glm::quat C = glm::shortMix(A, B, 0.5f);
glm::quat D = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(C.x, D.x, 0.01f) ? 0 : 1;
glm::quat C = glm::shortMix(A, B, 0.5f);
glm::quat D = glm::angleAxis(45.0f, glm::vec3(0, 0, 1));
Error += glm::epsilonEqual(C.x, D.x, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.y, D.y, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.z, D.z, 0.01f) ? 0 : 1;
Error += glm::epsilonEqual(C.w, D.w, 0.01f) ? 0 : 1;
return Error;
}
int test_orientation()
{
int Error(0);
{
glm::quat q(1.0f, 0.0f, 0.0f, 1.0f);
float p = glm::roll(q);
}
{
glm::quat q(1.0f, 0.0f, 0.0f, 1.0f);
float p = glm::pitch(q);
}
{
glm::quat q(1.0f, 0.0f, 0.0f, 1.0f);
float p = glm::yaw(q);
}
return Error;
}
int main()
{
int Error = 0;
Error += test_quat_fastMix();
Error += test_quat_shortMix();
Error += test_quat_shortMix();
return Error;
}