diff --git a/glm/ext/quaternion_trigonometric.hpp b/glm/ext/quaternion_trigonometric.hpp index 6228f025..3192ede5 100644 --- a/glm/ext/quaternion_trigonometric.hpp +++ b/glm/ext/quaternion_trigonometric.hpp @@ -28,39 +28,6 @@ namespace glm /// @addtogroup ext_quaternion_trigonometric /// @{ - /// Returns euler angles, pitch as x, yaw as y, roll as z. - /// The result is expressed in radians. - /// - /// @tparam T Floating-point scalar types. - /// - /// @see ext_quaternion_trigonometric - template - GLM_FUNC_DECL vec<3, T, Q> eulerAngles(qua const& x); - - /// Returns roll value of euler angles expressed in radians. - /// - /// @tparam T Floating-point scalar types. - /// - /// @see ext_quaternion_trigonometric - template - GLM_FUNC_DECL T roll(qua const& x); - - /// Returns pitch value of euler angles expressed in radians. - /// - /// @tparam T Floating-point scalar types. - /// - /// @see ext_quaternion_trigonometric - template - GLM_FUNC_DECL T pitch(qua const& x); - - /// Returns yaw value of euler angles expressed in radians. - /// - /// @tparam T Floating-point scalar types. - /// - /// @see ext_quaternion_trigonometric - template - GLM_FUNC_DECL T yaw(qua const& x); - /// Returns the quaternion rotation angle. /// /// @tparam T Floating-point scalar types. diff --git a/glm/ext/quaternion_trigonometric.inl b/glm/ext/quaternion_trigonometric.inl index f8a068d0..ef58aac2 100644 --- a/glm/ext/quaternion_trigonometric.inl +++ b/glm/ext/quaternion_trigonometric.inl @@ -1,35 +1,5 @@ namespace glm { - template - GLM_FUNC_QUALIFIER vec<3, T, Q> eulerAngles(qua const& x) - { - return vec<3, T, Q>(pitch(x), yaw(x), roll(x)); - } - - template - GLM_FUNC_QUALIFIER T roll(qua const& q) - { - return static_cast(atan(static_cast(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 - GLM_FUNC_QUALIFIER T pitch(qua const& q) - { - T const y = static_cast(2) * (q.y * q.z + q.w * q.x); - T const x = q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z; - - if(all(equal(vec<2, T, Q>(x, y), vec<2, T, Q>(0), epsilon()))) //avoid atan2(0,0) - handle singularity - Matiis - return static_cast(static_cast(2) * atan(q.x, q.w)); - - return static_cast(atan(y, x)); - } - - template - GLM_FUNC_QUALIFIER T yaw(qua const& q) - { - return asin(clamp(static_cast(-2) * (q.x * q.z - q.w * q.y), static_cast(-1), static_cast(1))); - } - template GLM_FUNC_QUALIFIER T angle(qua const& x) { diff --git a/glm/gtc/quaternion.hpp b/glm/gtc/quaternion.hpp index f65e9886..dd59cd47 100644 --- a/glm/gtc/quaternion.hpp +++ b/glm/gtc/quaternion.hpp @@ -24,6 +24,7 @@ #include "../ext/quaternion_double_precision.hpp" #include "../ext/quaternion_relational.hpp" #include "../ext/quaternion_geometric.hpp" +#include "../ext/quaternion_trigonometric.hpp" #include "../ext/quaternion_transform.hpp" #include "../detail/type_mat3x3.hpp" #include "../detail/type_mat4x4.hpp" @@ -39,22 +40,6 @@ namespace glm /// @addtogroup gtc_quaternion /// @{ - /// Returns the q conjugate. - /// - /// @tparam T Floating-point scalar types. - /// - /// @see gtc_quaternion - template - GLM_FUNC_DECL qua conjugate(qua const& q); - - /// Returns the q inverse. - /// - /// @tparam T Floating-point scalar types. - /// - /// @see gtc_quaternion - template - GLM_FUNC_DECL qua inverse(qua const& q); - /// Rotates a quaternion from a vector of 3 components axis and an angle. /// /// @param q Source orientation @@ -131,32 +116,6 @@ namespace glm template GLM_FUNC_DECL qua quat_cast(mat<4, 4, T, Q> const& x); - /// Returns the quaternion rotation angle. - /// - /// @tparam T Floating-point scalar types. - /// - /// @see gtc_quaternion - template - GLM_FUNC_DECL T angle(qua const& x); - - /// Returns the q rotation axis. - /// - /// @tparam T Floating-point scalar types. - /// - /// @see gtc_quaternion - template - GLM_FUNC_DECL vec<3, T, Q> axis(qua const& x); - - /// Build a quaternion from an angle and a normalized axis. - /// - /// @param angle Angle expressed in radians. - /// @param axis Axis of the quaternion, must be normalized. - /// @tparam T Floating-point scalar types. - /// - /// @see gtc_quaternion - template - GLM_FUNC_DECL qua angleAxis(T const& angle, vec<3, T, Q> const& axis); - /// Returns the component-wise comparison result of x < y. /// /// @tparam T Floating-point scalar types diff --git a/glm/gtc/quaternion.inl b/glm/gtc/quaternion.inl index e1cafb6b..84891977 100644 --- a/glm/gtc/quaternion.inl +++ b/glm/gtc/quaternion.inl @@ -122,37 +122,6 @@ namespace glm return quat_cast(mat<3, 3, T, Q>(m4)); } - template - GLM_FUNC_QUALIFIER T angle(qua const& x) - { - return acos(x.w) * static_cast(2); - } - - template - GLM_FUNC_QUALIFIER vec<3, T, Q> axis(qua const& x) - { - T tmp1 = static_cast(1) - x.w * x.w; - if(tmp1 <= static_cast(0)) - return vec<3, T, Q>(0, 0, 1); - T tmp2 = static_cast(1) / sqrt(tmp1); - return vec<3, T, Q>(x.x * tmp2, x.y * tmp2, x.z * tmp2); - } - - template - GLM_FUNC_QUALIFIER qua angleAxis(T const& angle, vec<3, T, Q> const& v) - { - qua Result; - - T const a(angle); - T const s = glm::sin(a * static_cast(0.5)); - - Result.w = glm::cos(a * static_cast(0.5)); - Result.x = v.x * s; - Result.y = v.y * s; - Result.z = v.z * s; - return Result; - } - template GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThan(qua const& x, qua const& y) { diff --git a/test/ext/ext_quaternion_common.cpp b/test/ext/ext_quaternion_common.cpp index 0b9a6bca..861aa65f 100644 --- a/test/ext/ext_quaternion_common.cpp +++ b/test/ext/ext_quaternion_common.cpp @@ -2,7 +2,9 @@ #include #include #include +#include #include +#include static int test_conjugate() { @@ -18,11 +20,42 @@ static int test_conjugate() return Error; } +static int test_mix() +{ + int Error = 0; + + glm::quat const Q1(glm::vec3(1, 0, 0), glm::vec3(1, 0, 0)); + glm::quat const Q2(glm::vec3(1, 0, 0), glm::vec3(0, 1, 0)); + + { + glm::quat const Q3 = glm::mix(Q1, Q2, 0.5f); + float const F3 = glm::degrees(glm::angle(Q3)); + Error += glm::equal(F3, 45.0f, 0.001f) ? 0 : 1; + + glm::quat const Q4 = glm::mix(Q2, Q1, 0.5f); + float const F4 = glm::degrees(glm::angle(Q4)); + Error += glm::equal(F4, 45.0f, 0.001f) ? 0 : 1; + } + + { + glm::quat const Q3 = glm::slerp(Q1, Q2, 0.5f); + float const F3 = glm::degrees(glm::angle(Q3)); + Error += glm::equal(F3, 45.0f, 0.001f) ? 0 : 1; + + glm::quat const Q4 = glm::slerp(Q2, Q1, 0.5f); + float const F4 = glm::degrees(glm::angle(Q4)); + Error += glm::equal(F4, 45.0f, 0.001f) ? 0 : 1; + } + + return Error; +} + int main() { int Error = 0; Error += test_conjugate(); + Error += test_mix(); return Error; } diff --git a/test/ext/ext_scalar_common.cpp b/test/ext/ext_scalar_common.cpp index 1c35b5a6..1db28707 100644 --- a/test/ext/ext_scalar_common.cpp +++ b/test/ext/ext_scalar_common.cpp @@ -3,6 +3,12 @@ #include #include +#if ((GLM_LANG & GLM_LANG_CXX11_FLAG) || (GLM_COMPILER & GLM_COMPILER_VC)) +# define GLM_NAN NAN +#else +# define GLM_NAN (A / A) +#endif + template static int test_min() { @@ -39,7 +45,7 @@ static int test_min_nan() T const A = static_cast(0); T const B = static_cast(1); - T const N = A / A; + T const N = GLM_NAN; Error += glm::isnan(glm::min(N, B)) ? 0 : 1; Error += !glm::isnan(glm::min(B, N)) ? 0 : 1; @@ -98,7 +104,7 @@ static int test_max_nan() T const A = static_cast(0); T const B = static_cast(1); - T const N = A / A; + T const N = GLM_NAN; Error += glm::isnan(glm::max(N, B)) ? 0 : 1; Error += !glm::isnan(glm::max(B, N)) ? 0 : 1; @@ -128,24 +134,25 @@ static int test_fmin() T const A = static_cast(0); T const B = static_cast(1); - Error += glm::equal(glm::fmin(A / A, B), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(B, A / A), B, glm::epsilon()) ? 0 : 1; + T const N = GLM_NAN; + Error += glm::equal(glm::fmin(N, B), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(B, N), B, glm::epsilon()) ? 0 : 1; T const C = static_cast(2); - Error += glm::equal(glm::fmin(A / A, B, C), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(B, A / A, C), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(C, A / A, B), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(C, B, A / A), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(B, C, A / A), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(A / A, C, B), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(N, B, C), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(B, N, C), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(C, N, B), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(C, B, N), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(B, C, N), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(N, C, B), B, glm::epsilon()) ? 0 : 1; T const D = static_cast(3); - Error += glm::equal(glm::fmin(D, A / A, B, C), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(B, D, A / A, C), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(C, A / A, D, B), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(C, B, D, A / A), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(B, C, A / A, D), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmin(A / A, C, B, D), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(D, N, B, C), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(B, D, N, C), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(C, N, D, B), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(C, B, D, N), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(B, C, N, D), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmin(N, C, B, D), B, glm::epsilon()) ? 0 : 1; return Error; } @@ -157,24 +164,25 @@ static int test_fmax() T const A = static_cast(0); T const B = static_cast(1); - Error += glm::equal(glm::fmax(A / A, B), B, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(B, A / A), B, glm::epsilon()) ? 0 : 1; + T const N = GLM_NAN; + Error += glm::equal(glm::fmax(N, B), B, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(B, N), B, glm::epsilon()) ? 0 : 1; T const C = static_cast(2); - Error += glm::equal(glm::fmax(A / A, B, C), C, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(B, A / A, C), C, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(C, A / A, B), C, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(C, B, A / A), C, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(B, C, A / A), C, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(A / A, C, B), C, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(N, B, C), C, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(B, N, C), C, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(C, N, B), C, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(C, B, N), C, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(B, C, N), C, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(N, C, B), C, glm::epsilon()) ? 0 : 1; T const D = static_cast(3); - Error += glm::equal(glm::fmax(D, A / A, B, C), D, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(B, D, A / A, C), D, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(C, A / A, D, B), D, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(C, B, D, A / A), D, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(B, C, A / A, D), D, glm::epsilon()) ? 0 : 1; - Error += glm::equal(glm::fmax(A / A, C, B, D), D, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(D, N, B, C), D, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(B, D, N, C), D, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(C, N, D, B), D, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(C, B, D, N), D, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(B, C, N, D), D, glm::epsilon()) ? 0 : 1; + Error += glm::equal(glm::fmax(N, C, B, D), D, glm::epsilon()) ? 0 : 1; return Error; }