From 942bf08fe30598d415a6d0bb1620e81b9fff6523 Mon Sep 17 00:00:00 2001 From: Dave Reid Date: Wed, 24 Apr 2013 09:39:22 +1000 Subject: [PATCH] Add the ability to convert standard mat4s and mat3s to SIMD quats. --- glm/gtx/simd_quat.hpp | 14 +++++- glm/gtx/simd_quat.inl | 99 ++++++++++++++++++++++++++----------------- 2 files changed, 73 insertions(+), 40 deletions(-) diff --git a/glm/gtx/simd_quat.hpp b/glm/gtx/simd_quat.hpp index 962b9413..cce5ee61 100644 --- a/glm/gtx/simd_quat.hpp +++ b/glm/gtx/simd_quat.hpp @@ -77,7 +77,7 @@ namespace detail static size_type value_size(); typedef fquatSIMD type; - typedef tquat bool_type; + typedef tquat bool_type; #ifdef GLM_SIMD_ENABLE_XYZW_UNION union @@ -172,6 +172,18 @@ namespace detail detail::fquatSIMD quatSIMD_cast( detail::fmat4x4SIMD const & m); + //! Converts a mat4 to a simdQuat. + //! (From GLM_GTX_simd_quat extension) + template + detail::fquatSIMD quatSIMD_cast( + detail::tmat4x4 const & m); + + //! Converts a mat3 to a simdQuat. + //! (From GLM_GTX_simd_quat extension) + template + detail::fquatSIMD quatSIMD_cast( + detail::tmat3x3 const & m); + //! Convert a simdQuat to a simdMat4 //! (From GLM_GTX_simd_quat extension) detail::fmat4x4SIMD mat4SIMD_cast( diff --git a/glm/gtx/simd_quat.inl b/glm/gtx/simd_quat.inl index 9502a6ab..90b9a730 100644 --- a/glm/gtx/simd_quat.inl +++ b/glm/gtx/simd_quat.inl @@ -214,37 +214,23 @@ GLM_FUNC_QUALIFIER quat quat_cast { GLM_ALIGN(16) quat Result; _mm_store_ps(&Result[0], x.Data); + return Result; } -GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast -( - detail::fmat4x4SIMD const & m -) +template +GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast_impl(const T m0[], const T m1[], const T m2[]) { - // Scalar implementation for now. - - GLM_ALIGN(16) float m0[4]; - GLM_ALIGN(16) float m1[4]; - GLM_ALIGN(16) float m2[4]; - GLM_ALIGN(16) float m3[4]; - - _mm_store_ps(m0, m[0].Data); - _mm_store_ps(m1, m[1].Data); - _mm_store_ps(m2, m[2].Data); - _mm_store_ps(m3, m[3].Data); - - - float trace = m0[0] + m1[1] + m2[2] + 1.0f; - if (trace > 0) + T trace = m0[0] + m1[1] + m2[2] + T(1.0); + if (trace > T(0)) { - float s = 0.5f / sqrt(trace); + T s = T(0.5) / sqrt(trace); return _mm_set_ps( - 0.25f / s, - (m0[1] - m1[0]) * s, - (m2[0] - m0[2]) * s, - (m1[2] - m2[1]) * s); + static_cast(T(0.25) / s), + static_cast((m0[1] - m1[0]) * s), + static_cast((m2[0] - m0[2]) * s), + static_cast((m1[2] - m2[1]) * s)); } else { @@ -253,13 +239,13 @@ GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast if (m0[0] > m2[2]) { // X is biggest. - float s = sqrt(m0[0] - m1[1] - m2[2] + 1.0f) * 0.5f; + T s = sqrt(m0[0] - m1[1] - m2[2] + T(1.0)) * T(0.5); return _mm_set_ps( - (m1[2] - m2[1]) * s, - (m2[0] + m0[2]) * s, - (m0[1] + m1[0]) * s, - 0.5f * s); + static_cast((m1[2] - m2[1]) * s), + static_cast((m2[0] + m0[2]) * s), + static_cast((m0[1] + m1[0]) * s), + static_cast(T(0.5) * s)); } } else @@ -267,27 +253,62 @@ GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast if (m1[1] > m2[2]) { // Y is biggest. - float s = sqrt(m1[1] - m0[0] - m2[2] + 1.0f) * 0.5f; + T s = sqrt(m1[1] - m0[0] - m2[2] + T(1.0)) * T(0.5); return _mm_set_ps( - (m2[0] - m0[2]) * s, - (m1[2] + m2[1]) * s, - 0.5f * s, - (m0[1] + m1[0]) * s); + static_cast((m2[0] - m0[2]) * s), + static_cast((m1[2] + m2[1]) * s), + static_cast(T(0.5) * s), + static_cast((m0[1] + m1[0]) * s)); } } // Z is biggest. - float s = sqrt(m2[2] - m0[0] - m1[1] + 1.0f) * 0.5f; + T s = sqrt(m2[2] - m0[0] - m1[1] + T(1.0)) * T(0.5); return _mm_set_ps( - (m0[1] - m1[0]) * s, - 0.5f * s, - (m1[2] + m2[1]) * s, - (m2[0] + m0[2]) * s); + static_cast((m0[1] - m1[0]) * s), + static_cast(T(0.5) * s), + static_cast((m1[2] + m2[1]) * s), + static_cast((m2[0] + m0[2]) * s)); } } +GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast +( + detail::fmat4x4SIMD const & m +) +{ + // Scalar implementation for now. + GLM_ALIGN(16) float m0[4]; + GLM_ALIGN(16) float m1[4]; + GLM_ALIGN(16) float m2[4]; + + _mm_store_ps(m0, m[0].Data); + _mm_store_ps(m1, m[1].Data); + _mm_store_ps(m2, m[2].Data); + + return quatSIMD_cast_impl(m0, m1, m2); +} + +template +GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast +( + detail::tmat4x4 const & m +) +{ + return quatSIMD_cast_impl(&m[0][0], &m[1][0], &m[2][0]); +} + +template +GLM_FUNC_QUALIFIER detail::fquatSIMD quatSIMD_cast +( + detail::tmat3x3 const & m +) +{ + return quatSIMD_cast_impl(&m[0][0], &m[1][0], &m[2][0]); +} + GLM_FUNC_QUALIFIER detail::fmat4x4SIMD mat4SIMD_cast (