• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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