1 /// @ref gtx_simd_quat 2 /// @file glm/gtx/simd_quat.hpp 3 /// 4 /// @see core (dependence) 5 /// 6 /// @defgroup gtx_simd_quat GLM_GTX_simd_quat 7 /// @ingroup gtx 8 /// 9 /// @brief SIMD implementation of quat type. 10 /// 11 /// <glm/gtx/simd_quat.hpp> need to be included to use these functionalities. 12 13 #pragma once 14 15 // Dependency: 16 #include "../glm.hpp" 17 #include "../gtc/quaternion.hpp" 18 #include "../gtx/fast_trigonometry.hpp" 19 20 #if GLM_ARCH != GLM_ARCH_PURE 21 22 #if GLM_ARCH & GLM_ARCH_SSE2_BIT 23 # include "../gtx/simd_mat4.hpp" 24 #else 25 # error "GLM: GLM_GTX_simd_quat requires compiler support of SSE2 through intrinsics" 26 #endif 27 28 #if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_EXT_INCLUDED) 29 # pragma message("GLM: GLM_GTX_simd_quat extension included") 30 # pragma message("GLM: GLM_GTX_simd_quat extension is deprecated and will be removed in GLM 0.9.9. Use GLM_GTC_quaternion instead and use compiler SIMD arguments.") 31 #endif 32 33 // Warning silencer for nameless struct/union. 34 #if (GLM_COMPILER & GLM_COMPILER_VC) 35 # pragma warning(push) 36 # pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union 37 #endif 38 39 namespace glm{ 40 namespace detail 41 { 42 GLM_ALIGNED_STRUCT(16) fquatSIMD 43 { 44 typedef float value_type; 45 typedef std::size_t size_type; 46 47 typedef fquatSIMD type; 48 typedef tquat<bool, defaultp> bool_type; 49 typedef tquat<float, defaultp> pure_type; 50 51 #ifdef GLM_SIMD_ENABLE_XYZW_UNION 52 union 53 { 54 __m128 Data; 55 struct {float x, y, z, w;}; 56 }; 57 #else 58 __m128 Data; 59 #endif 60 61 ////////////////////////////////////// 62 // Implicit basic constructors 63 64 fquatSIMD() GLM_DEFAULT_CTOR; 65 fquatSIMD(fquatSIMD const & q) GLM_DEFAULT; 66 fquatSIMD(__m128 const & Data); 67 68 ////////////////////////////////////// 69 // Explicit basic constructors 70 71 explicit fquatSIMD( 72 ctor); 73 explicit fquatSIMD( 74 float const & w, 75 float const & x, 76 float const & y, 77 float const & z); 78 explicit fquatSIMD( 79 quat const & v); 80 explicit fquatSIMD( 81 vec3 const & eulerAngles); 82 83 84 ////////////////////////////////////// 85 // Unary arithmetic operators 86 87 fquatSIMD& operator= (fquatSIMD const & q) GLM_DEFAULT; 88 fquatSIMD& operator*=(float const & s); 89 fquatSIMD& operator/=(float const & s); 90 }; 91 92 93 ////////////////////////////////////// 94 // Arithmetic operators 95 96 detail::fquatSIMD operator- ( 97 detail::fquatSIMD const & q); 98 99 detail::fquatSIMD operator+ ( 100 detail::fquatSIMD const & q, 101 detail::fquatSIMD const & p); 102 103 detail::fquatSIMD operator* ( 104 detail::fquatSIMD const & q, 105 detail::fquatSIMD const & p); 106 107 detail::fvec4SIMD operator* ( 108 detail::fquatSIMD const & q, 109 detail::fvec4SIMD const & v); 110 111 detail::fvec4SIMD operator* ( 112 detail::fvec4SIMD const & v, 113 detail::fquatSIMD const & q); 114 115 detail::fquatSIMD operator* ( 116 detail::fquatSIMD const & q, 117 float s); 118 119 detail::fquatSIMD operator* ( 120 float s, 121 detail::fquatSIMD const & q); 122 123 detail::fquatSIMD operator/ ( 124 detail::fquatSIMD const & q, 125 float s); 126 127 }//namespace detail 128 129 /// @addtogroup gtx_simd_quat 130 /// @{ 131 132 typedef glm::detail::fquatSIMD simdQuat; 133 134 //! Convert a simdQuat to a quat. 135 /// @see gtx_simd_quat 136 quat quat_cast( 137 detail::fquatSIMD const & x); 138 139 //! Convert a simdMat4 to a simdQuat. 140 /// @see gtx_simd_quat 141 detail::fquatSIMD quatSIMD_cast( 142 detail::fmat4x4SIMD const & m); 143 144 //! Converts a mat4 to a simdQuat. 145 /// @see gtx_simd_quat 146 template <typename T, precision P> 147 detail::fquatSIMD quatSIMD_cast( 148 tmat4x4<T, P> const & m); 149 150 //! Converts a mat3 to a simdQuat. 151 /// @see gtx_simd_quat 152 template <typename T, precision P> 153 detail::fquatSIMD quatSIMD_cast( 154 tmat3x3<T, P> const & m); 155 156 //! Convert a simdQuat to a simdMat4 157 /// @see gtx_simd_quat 158 detail::fmat4x4SIMD mat4SIMD_cast( 159 detail::fquatSIMD const & q); 160 161 //! Converts a simdQuat to a standard mat4. 162 /// @see gtx_simd_quat 163 mat4 mat4_cast( 164 detail::fquatSIMD const & q); 165 166 167 /// Returns the length of the quaternion. 168 /// 169 /// @see gtx_simd_quat 170 float length( 171 detail::fquatSIMD const & x); 172 173 /// Returns the normalized quaternion. 174 /// 175 /// @see gtx_simd_quat 176 detail::fquatSIMD normalize( 177 detail::fquatSIMD const & x); 178 179 /// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ... 180 /// 181 /// @see gtx_simd_quat 182 float dot( 183 detail::fquatSIMD const & q1, 184 detail::fquatSIMD const & q2); 185 186 /// Spherical linear interpolation of two quaternions. 187 /// The interpolation is oriented and the rotation is performed at constant speed. 188 /// For short path spherical linear interpolation, use the slerp function. 189 /// 190 /// @param x A quaternion 191 /// @param y A quaternion 192 /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. 193 /// @tparam T Value type used to build the quaternion. Supported: half, float or double. 194 /// @see gtx_simd_quat 195 /// @see - slerp(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a) 196 detail::fquatSIMD mix( 197 detail::fquatSIMD const & x, 198 detail::fquatSIMD const & y, 199 float const & a); 200 201 /// Linear interpolation of two quaternions. 202 /// The interpolation is oriented. 203 /// 204 /// @param x A quaternion 205 /// @param y A quaternion 206 /// @param a Interpolation factor. The interpolation is defined in the range [0, 1]. 207 /// @tparam T Value type used to build the quaternion. Supported: half, float or double. 208 /// @see gtx_simd_quat 209 detail::fquatSIMD lerp( 210 detail::fquatSIMD const & x, 211 detail::fquatSIMD const & y, 212 float const & a); 213 214 /// Spherical linear interpolation of two quaternions. 215 /// The interpolation always take the short path and the rotation is performed at constant speed. 216 /// 217 /// @param x A quaternion 218 /// @param y A quaternion 219 /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. 220 /// @tparam T Value type used to build the quaternion. Supported: half, float or double. 221 /// @see gtx_simd_quat 222 detail::fquatSIMD slerp( 223 detail::fquatSIMD const & x, 224 detail::fquatSIMD const & y, 225 float const & a); 226 227 228 /// Faster spherical linear interpolation of two unit length quaternions. 229 /// 230 /// This is the same as mix(), except for two rules: 231 /// 1) The two quaternions must be unit length. 232 /// 2) The interpolation factor (a) must be in the range [0, 1]. 233 /// 234 /// This will use the equivalent to fastAcos() and fastSin(). 235 /// 236 /// @see gtx_simd_quat 237 /// @see - mix(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a) 238 detail::fquatSIMD fastMix( 239 detail::fquatSIMD const & x, 240 detail::fquatSIMD const & y, 241 float const & a); 242 243 /// Identical to fastMix() except takes the shortest path. 244 /// 245 /// The same rules apply here as those in fastMix(). Both quaternions must be unit length and 'a' must be 246 /// in the range [0, 1]. 247 /// 248 /// @see - fastMix(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a) 249 /// @see - slerp(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a) 250 detail::fquatSIMD fastSlerp( 251 detail::fquatSIMD const & x, 252 detail::fquatSIMD const & y, 253 float const & a); 254 255 256 /// Returns the q conjugate. 257 /// 258 /// @see gtx_simd_quat 259 detail::fquatSIMD conjugate( 260 detail::fquatSIMD const & q); 261 262 /// Returns the q inverse. 263 /// 264 /// @see gtx_simd_quat 265 detail::fquatSIMD inverse( 266 detail::fquatSIMD const & q); 267 268 /// Build a quaternion from an angle and a normalized axis. 269 /// 270 /// @param angle Angle expressed in radians. 271 /// @param axis Axis of the quaternion, must be normalized. 272 /// 273 /// @see gtx_simd_quat 274 detail::fquatSIMD angleAxisSIMD( 275 float const & angle, 276 vec3 const & axis); 277 278 /// Build a quaternion from an angle and a normalized axis. 279 /// 280 /// @param angle Angle expressed in radians. 281 /// @param x x component of the x-axis, x, y, z must be a normalized axis 282 /// @param y y component of the y-axis, x, y, z must be a normalized axis 283 /// @param z z component of the z-axis, x, y, z must be a normalized axis 284 /// 285 /// @see gtx_simd_quat 286 detail::fquatSIMD angleAxisSIMD( 287 float const & angle, 288 float const & x, 289 float const & y, 290 float const & z); 291 292 // TODO: Move this to somewhere more appropriate. Used with fastMix() and fastSlerp(). 293 /// Performs the equivalent of glm::fastSin() on each component of the given __m128. 294 __m128 fastSin(__m128 x); 295 296 /// @} 297 }//namespace glm 298 299 #include "simd_quat.inl" 300 301 302 #if (GLM_COMPILER & GLM_COMPILER_VC) 303 # pragma warning(pop) 304 #endif 305 306 307 #endif//(GLM_ARCH != GLM_ARCH_PURE) 308