• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /// @ref gtx_simd_vec4
2 /// @file glm/gtx/simd_vec4.hpp
3 ///
4 /// @see core (dependence)
5 ///
6 /// @defgroup gtx_simd_vec4 GLM_GTX_simd_vec4
7 /// @ingroup gtx
8 ///
9 /// @brief SIMD implementation of vec4 type.
10 ///
11 /// <glm/gtx/simd_vec4.hpp> need to be included to use these functionalities.
12 
13 #pragma once
14 
15 // Dependency:
16 #include "../glm.hpp"
17 
18 #if(GLM_ARCH != GLM_ARCH_PURE)
19 
20 #if(GLM_ARCH & GLM_ARCH_SSE2_BIT)
21 #	include "../detail/intrinsic_common.hpp"
22 #	include "../detail/intrinsic_geometric.hpp"
23 #	include "../detail/intrinsic_integer.hpp"
24 #else
25 #	error "GLM: GLM_GTX_simd_vec4 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_vec4 extension included")
30 #	pragma message("GLM: GLM_GTX_simd_vec4 extension is deprecated and will be removed in GLM 0.9.9. Use *vec4 types instead and use compiler SIMD arguments.")
31 #endif
32 
33 
34 // Warning silencer for nameless struct/union.
35 #if (GLM_COMPILER & GLM_COMPILER_VC)
36 #	pragma warning(push)
37 #	pragma warning(disable:4201)   // warning C4201: nonstandard extension used : nameless struct/union
38 #endif
39 
40 namespace glm
41 {
42 	enum comp
43 	{
44 		X = 0,
45 		R = 0,
46 		S = 0,
47 		Y = 1,
48 		G = 1,
49 		T = 1,
50 		Z = 2,
51 		B = 2,
52 		P = 2,
53 		W = 3,
54 		A = 3,
55 		Q = 3
56 	};
57 
58 }//namespace glm
59 
60 namespace glm{
61 namespace detail
62 {
63 	/// 4-dimensional vector implemented using SIMD SEE intrinsics.
64 	/// \ingroup gtx_simd_vec4
65 	GLM_ALIGNED_STRUCT(16) fvec4SIMD
66 	{
67 		typedef float value_type;
68 		typedef std::size_t size_type;
69 
70 		typedef fvec4SIMD type;
71 		typedef tvec4<float, defaultp> pure_type;
72 		typedef tvec4<bool, highp> bool_type;
73 
74 #ifdef GLM_SIMD_ENABLE_XYZW_UNION
75 		union
76 		{
77 			__m128 Data;
78 			struct {float x, y, z, w;};
79 		};
80 #else
81 		__m128 Data;
82 #endif
83 
84 		//////////////////////////////////////
85 		// Implicit basic constructors
86 
87 		fvec4SIMD() GLM_DEFAULT_CTOR;
88 		fvec4SIMD(fvec4SIMD const & v) GLM_DEFAULT;
89 		fvec4SIMD(__m128 const & Data);
90 
91 		//////////////////////////////////////
92 		// Explicit basic constructors
93 
94 		explicit fvec4SIMD(
95 			ctor);
96 		explicit fvec4SIMD(
97 			float const & s);
98 		explicit fvec4SIMD(
99 			float const & x,
100 			float const & y,
101 			float const & z,
102 			float const & w);
103 		explicit fvec4SIMD(
104 			vec4 const & v);
105 
106 		////////////////////////////////////////
107 		//// Conversion vector constructors
108 
109 		fvec4SIMD(vec2 const & v, float const & s1, float const & s2);
110 		fvec4SIMD(float const & s1, vec2 const & v, float const & s2);
111 		fvec4SIMD(float const & s1, float const & s2, vec2 const & v);
112 		fvec4SIMD(vec3 const & v, float const & s);
113 		fvec4SIMD(float const & s, vec3 const & v);
114 		fvec4SIMD(vec2 const & v1, vec2 const & v2);
115 		//fvec4SIMD(ivec4SIMD const & v);
116 
117 		//////////////////////////////////////
118 		// Unary arithmetic operators
119 
120 		fvec4SIMD& operator= (fvec4SIMD const & v) GLM_DEFAULT;
121 		fvec4SIMD& operator+=(fvec4SIMD const & v);
122 		fvec4SIMD& operator-=(fvec4SIMD const & v);
123 		fvec4SIMD& operator*=(fvec4SIMD const & v);
124 		fvec4SIMD& operator/=(fvec4SIMD const & v);
125 
126 		fvec4SIMD& operator+=(float const & s);
127 		fvec4SIMD& operator-=(float const & s);
128 		fvec4SIMD& operator*=(float const & s);
129 		fvec4SIMD& operator/=(float const & s);
130 
131 		fvec4SIMD& operator++();
132 		fvec4SIMD& operator--();
133 
134 		//////////////////////////////////////
135 		// Swizzle operators
136 
137 		template <comp X_, comp Y_, comp Z_, comp W_>
138 		fvec4SIMD& swizzle();
139 		template <comp X_, comp Y_, comp Z_, comp W_>
140 		fvec4SIMD swizzle() const;
141 		template <comp X_, comp Y_, comp Z_>
142 		fvec4SIMD swizzle() const;
143 		template <comp X_, comp Y_>
144 		fvec4SIMD swizzle() const;
145 		template <comp X_>
146 		fvec4SIMD swizzle() const;
147 	};
148 }//namespace detail
149 
150 	typedef glm::detail::fvec4SIMD simdVec4;
151 
152 	/// @addtogroup gtx_simd_vec4
153 	/// @{
154 
155 	//! Convert a simdVec4 to a vec4.
156 	/// @see gtx_simd_vec4
157 	vec4 vec4_cast(
158 		detail::fvec4SIMD const & x);
159 
160 	//! Returns x if x >= 0; otherwise, it returns -x.
161 	/// @see gtx_simd_vec4
162 	detail::fvec4SIMD abs(detail::fvec4SIMD const & x);
163 
164 	//! Returns 1.0 if x > 0, 0.0 if x = 0, or -1.0 if x < 0.
165 	/// @see gtx_simd_vec4
166 	detail::fvec4SIMD sign(detail::fvec4SIMD const & x);
167 
168 	//! Returns a value equal to the nearest integer that is less then or equal to x.
169 	/// @see gtx_simd_vec4
170 	detail::fvec4SIMD floor(detail::fvec4SIMD const & x);
171 
172 	//! Returns a value equal to the nearest integer to x
173 	//! whose absolute value is not larger than the absolute value of x.
174 	/// @see gtx_simd_vec4
175 	detail::fvec4SIMD trunc(detail::fvec4SIMD const & x);
176 
177 	//! Returns a value equal to the nearest integer to x.
178 	//! The fraction 0.5 will round in a direction chosen by the
179 	//! implementation, presumably the direction that is fastest.
180 	//! This includes the possibility that round(x) returns the
181 	//! same value as roundEven(x) for all values of x.
182 	///
183 	/// @see gtx_simd_vec4
184 	detail::fvec4SIMD round(detail::fvec4SIMD const & x);
185 
186 	//! Returns a value equal to the nearest integer to x.
187 	//! A fractional part of 0.5 will round toward the nearest even
188 	//! integer. (Both 3.5 and 4.5 for x will return 4.0.)
189 	///
190 	/// @see gtx_simd_vec4
191 	//detail::fvec4SIMD roundEven(detail::fvec4SIMD const & x);
192 
193 	//! Returns a value equal to the nearest integer
194 	//! that is greater than or equal to x.
195 	/// @see gtx_simd_vec4
196 	detail::fvec4SIMD ceil(detail::fvec4SIMD const & x);
197 
198 	//! Return x - floor(x).
199 	///
200 	/// @see gtx_simd_vec4
201 	detail::fvec4SIMD fract(detail::fvec4SIMD const & x);
202 
203 	//! Modulus. Returns x - y * floor(x / y)
204 	//! for each component in x using the floating point value y.
205 	///
206 	/// @see gtx_simd_vec4
207 	detail::fvec4SIMD mod(
208 		detail::fvec4SIMD const & x,
209 		detail::fvec4SIMD const & y);
210 
211 	//! Modulus. Returns x - y * floor(x / y)
212 	//! for each component in x using the floating point value y.
213 	///
214 	/// @see gtx_simd_vec4
215 	detail::fvec4SIMD mod(
216 		detail::fvec4SIMD const & x,
217 		float const & y);
218 
219 	//! Returns the fractional part of x and sets i to the integer
220 	//! part (as a whole number floating point value). Both the
221 	//! return value and the output parameter will have the same
222 	//! sign as x.
223 	//! (From GLM_GTX_simd_vec4 extension, common function)
224 	//detail::fvec4SIMD modf(
225 	//	detail::fvec4SIMD const & x,
226 	//	detail::fvec4SIMD & i);
227 
228 	//! Returns y if y < x; otherwise, it returns x.
229 	///
230 	/// @see gtx_simd_vec4
231 	detail::fvec4SIMD min(
232 		detail::fvec4SIMD const & x,
233 		detail::fvec4SIMD const & y);
234 
235 	detail::fvec4SIMD min(
236 		detail::fvec4SIMD const & x,
237 		float const & y);
238 
239 	//! Returns y if x < y; otherwise, it returns x.
240 	///
241 	/// @see gtx_simd_vec4
242 	detail::fvec4SIMD max(
243 		detail::fvec4SIMD const & x,
244 		detail::fvec4SIMD const & y);
245 
246 	detail::fvec4SIMD max(
247 		detail::fvec4SIMD const & x,
248 		float const & y);
249 
250 	//! Returns min(max(x, minVal), maxVal) for each component in x
251 	//! using the floating-point values minVal and maxVal.
252 	///
253 	/// @see gtx_simd_vec4
254 	detail::fvec4SIMD clamp(
255 		detail::fvec4SIMD const & x,
256 		detail::fvec4SIMD const & minVal,
257 		detail::fvec4SIMD const & maxVal);
258 
259 	detail::fvec4SIMD clamp(
260 		detail::fvec4SIMD const & x,
261 		float const & minVal,
262 		float const & maxVal);
263 
264 	//! \return If genTypeU is a floating scalar or vector:
265 	//! Returns x * (1.0 - a) + y * a, i.e., the linear blend of
266 	//! x and y using the floating-point value a.
267 	//! The value for a is not restricted to the range [0, 1].
268 	//!
269 	//! \return If genTypeU is a boolean scalar or vector:
270 	//! Selects which vector each returned component comes
271 	//! from. For a component of a that is false, the
272 	//! corresponding component of x is returned. For a
273 	//! component of a that is true, the corresponding
274 	//! component of y is returned. Components of x and y that
275 	//! are not selected are allowed to be invalid floating point
276 	//! values and will have no effect on the results. Thus, this
277 	//! provides different functionality than
278 	//! genType mix(genType x, genType y, genType(a))
279 	//! where a is a Boolean vector.
280 	//!
281 	//! From GLSL 1.30.08 specification, section 8.3
282 	//!
283 	//! \param[in]  x Floating point scalar or vector.
284 	//! \param[in]  y Floating point scalar or vector.
285 	//! \param[in]  a Floating point or boolean scalar or vector.
286 	//!
287 	/// \todo Test when 'a' is a boolean.
288 	///
289 	/// @see gtx_simd_vec4
290 	detail::fvec4SIMD mix(
291 		detail::fvec4SIMD const & x,
292 		detail::fvec4SIMD const & y,
293 		detail::fvec4SIMD const & a);
294 
295 	//! Returns 0.0 if x < edge, otherwise it returns 1.0.
296 	///
297 	/// @see gtx_simd_vec4
298 	detail::fvec4SIMD step(
299 		detail::fvec4SIMD const & edge,
300 		detail::fvec4SIMD const & x);
301 
302 	detail::fvec4SIMD step(
303 		float const & edge,
304 		detail::fvec4SIMD const & x);
305 
306 	//! Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
307 	//! performs smooth Hermite interpolation between 0 and 1
308 	//! when edge0 < x < edge1. This is useful in cases where
309 	//! you would want a threshold function with a smooth
310 	//! transition. This is equivalent to:
311 	//! genType t;
312 	//! t = clamp ((x - edge0) / (edge1 - edge0), 0, 1);
313 	//! return t * t * (3 - 2 * t);
314 	//! Results are undefined if edge0 >= edge1.
315 	///
316 	/// @see gtx_simd_vec4
317 	detail::fvec4SIMD smoothstep(
318 		detail::fvec4SIMD const & edge0,
319 		detail::fvec4SIMD const & edge1,
320 		detail::fvec4SIMD const & x);
321 
322 	detail::fvec4SIMD smoothstep(
323 		float const & edge0,
324 		float const & edge1,
325 		detail::fvec4SIMD const & x);
326 
327 	//! Returns true if x holds a NaN (not a number)
328 	//! representation in the underlying implementation's set of
329 	//! floating point representations. Returns false otherwise,
330 	//! including for implementations with no NaN
331 	//! representations.
332 	///
333 	/// @see gtx_simd_vec4
334 	//bvec4 isnan(detail::fvec4SIMD const & x);
335 
336 	//! Returns true if x holds a positive infinity or negative
337 	//! infinity representation in the underlying implementation's
338 	//! set of floating point representations. Returns false
339 	//! otherwise, including for implementations with no infinity
340 	//! representations.
341 	///
342 	/// @see gtx_simd_vec4
343 	//bvec4 isinf(detail::fvec4SIMD const & x);
344 
345 	//! Returns a signed or unsigned integer value representing
346 	//! the encoding of a floating-point value. The floatingpoint
347 	//! value's bit-level representation is preserved.
348 	///
349 	/// @see gtx_simd_vec4
350 	//detail::ivec4SIMD floatBitsToInt(detail::fvec4SIMD const & value);
351 
352 	//! Returns a floating-point value corresponding to a signed
353 	//! or unsigned integer encoding of a floating-point value.
354 	//! If an inf or NaN is passed in, it will not signal, and the
355 	//! resulting floating point value is unspecified. Otherwise,
356 	//! the bit-level representation is preserved.
357 	///
358 	/// @see gtx_simd_vec4
359 	//detail::fvec4SIMD intBitsToFloat(detail::ivec4SIMD const & value);
360 
361 	//! Computes and returns a * b + c.
362 	///
363 	/// @see gtx_simd_vec4
364 	detail::fvec4SIMD fma(
365 		detail::fvec4SIMD const & a,
366 		detail::fvec4SIMD const & b,
367 		detail::fvec4SIMD const & c);
368 
369 	//! Splits x into a floating-point significand in the range
370 	//! [0.5, 1.0) and an integral exponent of two, such that:
371 	//! x = significand * exp(2, exponent)
372 	//! The significand is returned by the function and the
373 	//! exponent is returned in the parameter exp. For a
374 	//! floating-point value of zero, the significant and exponent
375 	//! are both zero. For a floating-point value that is an
376 	//! infinity or is not a number, the results are undefined.
377 	///
378 	/// @see gtx_simd_vec4
379 	//detail::fvec4SIMD frexp(detail::fvec4SIMD const & x, detail::ivec4SIMD & exp);
380 
381 	//! Builds a floating-point number from x and the
382 	//! corresponding integral exponent of two in exp, returning:
383 	//! significand * exp(2, exponent)
384 	//! If this product is too large to be represented in the
385 	//! floating-point type, the result is undefined.
386 	///
387 	/// @see gtx_simd_vec4
388 	//detail::fvec4SIMD ldexp(detail::fvec4SIMD const & x, detail::ivec4SIMD const & exp);
389 
390 	//! Returns the length of x, i.e., sqrt(x * x).
391 	///
392 	/// @see gtx_simd_vec4
393 	float length(
394 		detail::fvec4SIMD const & x);
395 
396 	//! Returns the length of x, i.e., sqrt(x * x).
397 	//! Less accurate but much faster than simdLength.
398 	///
399 	/// @see gtx_simd_vec4
400 	float fastLength(
401 		detail::fvec4SIMD const & x);
402 
403 	//! Returns the length of x, i.e., sqrt(x * x).
404 	//! Slightly more accurate but much slower than simdLength.
405 	///
406 	/// @see gtx_simd_vec4
407 	float niceLength(
408 		detail::fvec4SIMD const & x);
409 
410 	//! Returns the length of x, i.e., sqrt(x * x).
411 	///
412 	/// @see gtx_simd_vec4
413 	detail::fvec4SIMD length4(
414 		detail::fvec4SIMD const & x);
415 
416 	//! Returns the length of x, i.e., sqrt(x * x).
417 	//! Less accurate but much faster than simdLength4.
418 	///
419 	/// @see gtx_simd_vec4
420 	detail::fvec4SIMD fastLength4(
421 		detail::fvec4SIMD const & x);
422 
423 	//! Returns the length of x, i.e., sqrt(x * x).
424 	//! Slightly more accurate but much slower than simdLength4.
425 	///
426 	/// @see gtx_simd_vec4
427 	detail::fvec4SIMD niceLength4(
428 		detail::fvec4SIMD const & x);
429 
430 	//! Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
431 	///
432 	/// @see gtx_simd_vec4
433 	float distance(
434 		detail::fvec4SIMD const & p0,
435 		detail::fvec4SIMD const & p1);
436 
437 	//! Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
438 	///
439 	/// @see gtx_simd_vec4
440 	detail::fvec4SIMD distance4(
441 		detail::fvec4SIMD const & p0,
442 		detail::fvec4SIMD const & p1);
443 
444 	//! Returns the dot product of x and y, i.e., result = x * y.
445 	///
446 	/// @see gtx_simd_vec4
447 	float simdDot(
448 		detail::fvec4SIMD const & x,
449 		detail::fvec4SIMD const & y);
450 
451 	//! Returns the dot product of x and y, i.e., result = x * y.
452 	///
453 	/// @see gtx_simd_vec4
454 	detail::fvec4SIMD dot4(
455 		detail::fvec4SIMD const & x,
456 		detail::fvec4SIMD const & y);
457 
458 	//! Returns the cross product of x and y.
459 	///
460 	/// @see gtx_simd_vec4
461 	detail::fvec4SIMD cross(
462 		detail::fvec4SIMD const & x,
463 		detail::fvec4SIMD const & y);
464 
465 	//! Returns a vector in the same direction as x but with length of 1.
466 	///
467 	/// @see gtx_simd_vec4
468 	detail::fvec4SIMD normalize(
469 		detail::fvec4SIMD const & x);
470 
471 	//! Returns a vector in the same direction as x but with length of 1.
472 	//! Less accurate but much faster than simdNormalize.
473 	///
474 	/// @see gtx_simd_vec4
475 	detail::fvec4SIMD fastNormalize(
476 		detail::fvec4SIMD const & x);
477 
478 	//! If dot(Nref, I) < 0.0, return N, otherwise, return -N.
479 	///
480 	/// @see gtx_simd_vec4
481 	detail::fvec4SIMD simdFaceforward(
482 		detail::fvec4SIMD const & N,
483 		detail::fvec4SIMD const & I,
484 		detail::fvec4SIMD const & Nref);
485 
486 	//! For the incident vector I and surface orientation N,
487 	//! returns the reflection direction : result = I - 2.0 * dot(N, I) * N.
488 	///
489 	/// @see gtx_simd_vec4
490 	detail::fvec4SIMD reflect(
491 		detail::fvec4SIMD const & I,
492 		detail::fvec4SIMD const & N);
493 
494 	//! For the incident vector I and surface normal N,
495 	//! and the ratio of indices of refraction eta,
496 	//! return the refraction vector.
497 	///
498 	/// @see gtx_simd_vec4
499 	detail::fvec4SIMD refract(
500 		detail::fvec4SIMD const & I,
501 		detail::fvec4SIMD const & N,
502 		float const & eta);
503 
504 	//! Returns the positive square root of x.
505 	///
506 	/// @see gtx_simd_vec4
507 	detail::fvec4SIMD sqrt(
508 		detail::fvec4SIMD const & x);
509 
510 	//! Returns the positive square root of x with the nicest quality but very slow.
511 	//! Slightly more accurate but much slower than simdSqrt.
512 	///
513 	/// @see gtx_simd_vec4
514 	detail::fvec4SIMD niceSqrt(
515 		detail::fvec4SIMD const & x);
516 
517 	//! Returns the positive square root of x
518 	//! Less accurate but much faster than sqrt.
519 	///
520 	/// @see gtx_simd_vec4
521 	detail::fvec4SIMD fastSqrt(
522 		detail::fvec4SIMD const & x);
523 
524 	//! Returns the reciprocal of the positive square root of x.
525 	///
526 	/// @see gtx_simd_vec4
527 	detail::fvec4SIMD inversesqrt(
528 		detail::fvec4SIMD const & x);
529 
530 	//! Returns the reciprocal of the positive square root of x.
531 	//! Faster than inversesqrt but less accurate.
532 	///
533 	/// @see gtx_simd_vec4
534 	detail::fvec4SIMD fastInversesqrt(
535 		detail::fvec4SIMD const & x);
536 
537 	/// @}
538 }//namespace glm
539 
540 #include "simd_vec4.inl"
541 
542 #if (GLM_COMPILER & GLM_COMPILER_VC)
543 #	pragma warning(pop)
544 #endif
545 
546 #endif//(GLM_ARCH != GLM_ARCH_PURE)
547