| /////////////////////////////////////////////////////////////////////////////////// |
| /// OpenGL Mathematics (glm.g-truc.net) |
| /// |
| /// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) |
| /// Permission is hereby granted, free of charge, to any person obtaining a copy |
| /// of this software and associated documentation files (the "Software"), to deal |
| /// in the Software without restriction, including without limitation the rights |
| /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| /// copies of the Software, and to permit persons to whom the Software is |
| /// furnished to do so, subject to the following conditions: |
| /// |
| /// The above copyright notice and this permission notice shall be included in |
| /// all copies or substantial portions of the Software. |
| /// |
| /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| /// THE SOFTWARE. |
| /// |
| /// @ref gtx_simd_quat |
| /// @file glm/gtx/simd_quat.hpp |
| /// @date 2009-05-07 / 2011-06-07 |
| /// @author Christophe Riccio |
| /// |
| /// @see core (dependence) |
| /// |
| /// @defgroup gtx_simd_vec4 GLM_GTX_simd_quat |
| /// @ingroup gtx |
| /// |
| /// @brief SIMD implementation of quat type. |
| /// |
| /// <glm/gtx/simd_quat.hpp> need to be included to use these functionalities. |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| #ifndef GLM_GTX_simd_quat |
| #define GLM_GTX_simd_quat |
| |
| // Dependency: |
| #include "../glm.hpp" |
| #include "../gtc/quaternion.hpp" |
| #include "../gtx/fast_trigonometry.hpp" |
| |
| #if(GLM_ARCH != GLM_ARCH_PURE) |
| |
| #if(GLM_ARCH & GLM_ARCH_SSE2) |
| # include "../gtx/simd_mat4.hpp" |
| #else |
| # error "GLM: GLM_GTX_simd_quat requires compiler support of SSE2 through intrinsics" |
| #endif |
| |
| #if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED)) |
| # pragma message("GLM: GLM_GTX_simd_quat extension included") |
| #endif |
| |
| |
| // Warning silencer for nameless struct/union. |
| #if (GLM_COMPILER & GLM_COMPILER_VC) |
| # pragma warning(push) |
| # pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union |
| #endif |
| |
| |
| namespace glm{ |
| namespace detail |
| { |
| /// Quaternion implemented using SIMD SEE intrinsics. |
| /// \ingroup gtx_simd_vec4 |
| GLM_ALIGNED_STRUCT(16) fquatSIMD |
| { |
| enum ctor{null}; |
| typedef __m128 value_type; |
| typedef std::size_t size_type; |
| static size_type value_size(); |
| |
| typedef fquatSIMD type; |
| typedef tquat<bool, defaultp> bool_type; |
| |
| #ifdef GLM_SIMD_ENABLE_XYZW_UNION |
| union |
| { |
| __m128 Data; |
| struct {float x, y, z, w;}; |
| }; |
| #else |
| __m128 Data; |
| #endif |
| |
| ////////////////////////////////////// |
| // Implicit basic constructors |
| |
| fquatSIMD(); |
| fquatSIMD(__m128 const & Data); |
| fquatSIMD(fquatSIMD const & q); |
| |
| ////////////////////////////////////// |
| // Explicit basic constructors |
| |
| explicit fquatSIMD( |
| ctor); |
| explicit fquatSIMD( |
| float const & w, |
| float const & x, |
| float const & y, |
| float const & z); |
| explicit fquatSIMD( |
| quat const & v); |
| explicit fquatSIMD( |
| vec3 const & eulerAngles); |
| |
| |
| ////////////////////////////////////// |
| // Unary arithmetic operators |
| |
| fquatSIMD& operator =(fquatSIMD const & q); |
| fquatSIMD& operator*=(float const & s); |
| fquatSIMD& operator/=(float const & s); |
| }; |
| |
| |
| ////////////////////////////////////// |
| // Arithmetic operators |
| |
| detail::fquatSIMD operator- ( |
| detail::fquatSIMD const & q); |
| |
| detail::fquatSIMD operator+ ( |
| detail::fquatSIMD const & q, |
| detail::fquatSIMD const & p); |
| |
| detail::fquatSIMD operator* ( |
| detail::fquatSIMD const & q, |
| detail::fquatSIMD const & p); |
| |
| detail::fvec4SIMD operator* ( |
| detail::fquatSIMD const & q, |
| detail::fvec4SIMD const & v); |
| |
| detail::fvec4SIMD operator* ( |
| detail::fvec4SIMD const & v, |
| detail::fquatSIMD const & q); |
| |
| detail::fquatSIMD operator* ( |
| detail::fquatSIMD const & q, |
| float s); |
| |
| detail::fquatSIMD operator* ( |
| float s, |
| detail::fquatSIMD const & q); |
| |
| detail::fquatSIMD operator/ ( |
| detail::fquatSIMD const & q, |
| float s); |
| |
| }//namespace detail |
| |
| typedef glm::detail::fquatSIMD simdQuat; |
| |
| /// @addtogroup gtx_simd_quat |
| /// @{ |
| |
| //! Convert a simdQuat to a quat. |
| //! (From GLM_GTX_simd_quat extension) |
| quat quat_cast( |
| detail::fquatSIMD const & x); |
| |
| //! Convert a simdMat4 to a simdQuat. |
| //! (From GLM_GTX_simd_quat extension) |
| detail::fquatSIMD quatSIMD_cast( |
| detail::fmat4x4SIMD const & m); |
| |
| //! Converts a mat4 to a simdQuat. |
| //! (From GLM_GTX_simd_quat extension) |
| template <typename T, precision P> |
| detail::fquatSIMD quatSIMD_cast( |
| detail::tmat4x4<T, P> const & m); |
| |
| //! Converts a mat3 to a simdQuat. |
| //! (From GLM_GTX_simd_quat extension) |
| template <typename T, precision P> |
| detail::fquatSIMD quatSIMD_cast( |
| detail::tmat3x3<T, P> const & m); |
| |
| //! Convert a simdQuat to a simdMat4 |
| //! (From GLM_GTX_simd_quat extension) |
| detail::fmat4x4SIMD mat4SIMD_cast( |
| detail::fquatSIMD const & q); |
| |
| //! Converts a simdQuat to a standard mat4. |
| //! (From GLM_GTX_simd_quat extension) |
| mat4 mat4_cast( |
| detail::fquatSIMD const & q); |
| |
| |
| /// Returns the length of the quaternion. |
| /// |
| /// @see gtc_quaternion |
| float length( |
| detail::fquatSIMD const & x); |
| |
| /// Returns the normalized quaternion. |
| /// |
| /// @see gtc_quaternion |
| detail::fquatSIMD normalize( |
| detail::fquatSIMD const & x); |
| |
| /// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ... |
| /// |
| /// @see gtc_quaternion |
| float dot( |
| detail::fquatSIMD const & q1, |
| detail::fquatSIMD const & q2); |
| |
| /// Spherical linear interpolation of two quaternions. |
| /// The interpolation is oriented and the rotation is performed at constant speed. |
| /// For short path spherical linear interpolation, use the slerp function. |
| /// |
| /// @param x A quaternion |
| /// @param y A quaternion |
| /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. |
| /// @tparam T Value type used to build the quaternion. Supported: half, float or double. |
| /// @see gtc_quaternion |
| /// @see - slerp(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a) |
| detail::fquatSIMD mix( |
| detail::fquatSIMD const & x, |
| detail::fquatSIMD const & y, |
| float const & a); |
| |
| /// Linear interpolation of two quaternions. |
| /// The interpolation is oriented. |
| /// |
| /// @param x A quaternion |
| /// @param y A quaternion |
| /// @param a Interpolation factor. The interpolation is defined in the range [0, 1]. |
| /// @tparam T Value type used to build the quaternion. Supported: half, float or double. |
| /// @see gtc_quaternion |
| detail::fquatSIMD lerp( |
| detail::fquatSIMD const & x, |
| detail::fquatSIMD const & y, |
| float const & a); |
| |
| /// Spherical linear interpolation of two quaternions. |
| /// The interpolation always take the short path and the rotation is performed at constant speed. |
| /// |
| /// @param x A quaternion |
| /// @param y A quaternion |
| /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. |
| /// @tparam T Value type used to build the quaternion. Supported: half, float or double. |
| /// @see gtc_quaternion |
| detail::fquatSIMD slerp( |
| detail::fquatSIMD const & x, |
| detail::fquatSIMD const & y, |
| float const & a); |
| |
| |
| /// Faster spherical linear interpolation of two unit length quaternions. |
| /// |
| /// This is the same as mix(), except for two rules: |
| /// 1) The two quaternions must be unit length. |
| /// 2) The interpolation factor (a) must be in the range [0, 1]. |
| /// |
| /// This will use the equivalent to fastAcos() and fastSin(). |
| /// |
| /// @see gtc_quaternion |
| /// @see - mix(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a) |
| detail::fquatSIMD fastMix( |
| detail::fquatSIMD const & x, |
| detail::fquatSIMD const & y, |
| float const & a); |
| |
| /// Identical to fastMix() except takes the shortest path. |
| /// |
| /// The same rules apply here as those in fastMix(). Both quaternions must be unit length and 'a' must be |
| /// in the range [0, 1]. |
| /// |
| /// @see - fastMix(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a) |
| /// @see - slerp(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a) |
| detail::fquatSIMD fastSlerp( |
| detail::fquatSIMD const & x, |
| detail::fquatSIMD const & y, |
| float const & a); |
| |
| |
| /// Returns the q conjugate. |
| /// |
| /// @see gtc_quaternion |
| detail::fquatSIMD conjugate( |
| detail::fquatSIMD const & q); |
| |
| /// Returns the q inverse. |
| /// |
| /// @see gtc_quaternion |
| detail::fquatSIMD inverse( |
| detail::fquatSIMD const & q); |
| |
| /// Build a quaternion from an angle and a normalized axis. |
| /// |
| /// @param angle Angle expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise. |
| /// @param axis Axis of the quaternion, must be normalized. |
| /// |
| /// @see gtc_quaternion |
| detail::fquatSIMD angleAxisSIMD( |
| float const & angle, |
| vec3 const & axis); |
| |
| /// Build a quaternion from an angle and a normalized axis. |
| /// |
| /// @param angle Angle expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise. |
| /// @param x x component of the x-axis, x, y, z must be a normalized axis |
| /// @param y y component of the y-axis, x, y, z must be a normalized axis |
| /// @param z z component of the z-axis, x, y, z must be a normalized axis |
| /// |
| /// @see gtc_quaternion |
| detail::fquatSIMD angleAxisSIMD( |
| float const & angle, |
| float const & x, |
| float const & y, |
| float const & z); |
| |
| |
| // TODO: Move this to somewhere more appropriate. Used with fastMix() and fastSlerp(). |
| /// Performs the equivalent of glm::fastSin() on each component of the given __m128. |
| __m128 fastSin(__m128 x); |
| |
| |
| /// @} |
| }//namespace glm |
| |
| #include "simd_quat.inl" |
| |
| |
| #if (GLM_COMPILER & GLM_COMPILER_VC) |
| # pragma warning(pop) |
| #endif |
| |
| |
| #endif//(GLM_ARCH != GLM_ARCH_PURE) |
| |
| #endif//GLM_GTX_simd_quat |