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