simd_vec4.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. // OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. // Created : 2009-05-07
  5. // Updated : 2009-05-07
  6. // Licence : This source is under MIT License
  7. // File : glm/gtx/simd_vec4.hpp
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. // Dependency:
  10. // - GLM core
  11. // - intrinsic
  12. ///////////////////////////////////////////////////////////////////////////////////////////////////
  13. #ifndef glm_gtx_simd_vec4
  14. #define glm_gtx_simd_vec4
  15. // Dependency:
  16. #include "../glm.hpp"
  17. #if(GLM_ARCH & GLM_ARCH_SSE2)
  18. # include "../core/intrinsic_common.hpp"
  19. # include "../core/intrinsic_geometric.hpp"
  20. #else
  21. # error "GLM: GLM_GTX_simd_vec4 requires compiler support of SSE2 through intrinsics"
  22. #endif
  23. #if(defined(GLM_MESSAGES) && !defined(glm_ext))
  24. # pragma message("GLM: GLM_GTX_simd_vec4 extension included")
  25. #endif
  26. namespace glm{
  27. namespace detail
  28. {
  29. /// 4-dimensional vector implemented using SIMD SEE intrinsics.
  30. /// \ingroup gtx_simd_vec4
  31. GLM_ALIGNED_STRUCT(16) fvec4SIMD
  32. {
  33. enum ctor{null};
  34. typedef __m128 value_type;
  35. typedef std::size_t size_type;
  36. static size_type value_size();
  37. typedef fvec4SIMD type;
  38. typedef tvec4<bool> bool_type;
  39. __m128 Data;
  40. //////////////////////////////////////
  41. // Implicit basic constructors
  42. fvec4SIMD();
  43. fvec4SIMD(__m128 const & Data);
  44. fvec4SIMD(fvec4SIMD const & v);
  45. //////////////////////////////////////
  46. // Explicit basic constructors
  47. explicit fvec4SIMD(
  48. ctor);
  49. explicit fvec4SIMD(
  50. float const & s);
  51. explicit fvec4SIMD(
  52. float const & x,
  53. float const & y,
  54. float const & z,
  55. float const & w);
  56. explicit fvec4SIMD(
  57. tvec4<float> const & v);
  58. ////////////////////////////////////////
  59. //// Convertion vector constructors
  60. fvec4SIMD(vec2 const & v, float const & s1, float const & s2);
  61. fvec4SIMD(float const & s1, vec2 const & v, float const & s2);
  62. fvec4SIMD(float const & s1, float const & s2, vec2 const & v);
  63. fvec4SIMD(vec3 const & v, float const & s);
  64. fvec4SIMD(float const & s, vec3 const & v);
  65. fvec4SIMD(vec2 const & v1, vec2 const & v2);
  66. //fvec4SIMD(ivec4SIMD const & v);
  67. //////////////////////////////////////
  68. // Unary arithmetic operators
  69. fvec4SIMD& operator= (fvec4SIMD const & v);
  70. fvec4SIMD& operator+=(fvec4SIMD const & v);
  71. fvec4SIMD& operator-=(fvec4SIMD const & v);
  72. fvec4SIMD& operator*=(fvec4SIMD const & v);
  73. fvec4SIMD& operator/=(fvec4SIMD const & v);
  74. fvec4SIMD& operator+=(float const & s);
  75. fvec4SIMD& operator-=(float const & s);
  76. fvec4SIMD& operator*=(float const & s);
  77. fvec4SIMD& operator/=(float const & s);
  78. fvec4SIMD& operator++();
  79. fvec4SIMD& operator--();
  80. //////////////////////////////////////
  81. // Swizzle operators
  82. template <comp X, comp Y, comp Z, comp W>
  83. fvec4SIMD& swizzle();
  84. template <comp X, comp Y, comp Z, comp W>
  85. fvec4SIMD swizzle() const;
  86. template <comp X, comp Y, comp Z>
  87. fvec4SIMD swizzle() const;
  88. template <comp X, comp Y>
  89. fvec4SIMD swizzle() const;
  90. template <comp X>
  91. fvec4SIMD swizzle() const;
  92. };
  93. }//namespace detail
  94. namespace gtx{
  95. namespace simd_vec4 ///< GLM_GTX_simd_vec4 extension: SIMD implementation of vec4 type.
  96. {
  97. typedef glm::detail::fvec4SIMD simdVec4;
  98. /// \addtogroup gtx_simd_vec4
  99. ///@{
  100. //! Convert a simdVec4 to a vec4.
  101. //! (From GLM_GTX_simd_vec4 extension)
  102. detail::tvec4<float> vec4_cast(
  103. detail::fvec4SIMD const & x);
  104. //! Returns x if x >= 0; otherwise, it returns -x.
  105. //! (From GLM_GTX_simd_vec4 extension, common function)
  106. detail::fvec4SIMD abs(detail::fvec4SIMD const & x);
  107. //! Returns 1.0 if x > 0, 0.0 if x = 0, or -1.0 if x < 0.
  108. //! (From GLM_GTX_simd_vec4 extension, common function)
  109. detail::fvec4SIMD sign(detail::fvec4SIMD const & x);
  110. //! Returns a value equal to the nearest integer that is less then or equal to x.
  111. //! (From GLM_GTX_simd_vec4 extension, common function)
  112. detail::fvec4SIMD floor(detail::fvec4SIMD const & x);
  113. //! Returns a value equal to the nearest integer to x
  114. //! whose absolute value is not larger than the absolute value of x.
  115. //! (From GLM_GTX_simd_vec4 extension, common function)
  116. detail::fvec4SIMD trunc(detail::fvec4SIMD const & x);
  117. //! Returns a value equal to the nearest integer to x.
  118. //! The fraction 0.5 will round in a direction chosen by the
  119. //! implementation, presumably the direction that is fastest.
  120. //! This includes the possibility that round(x) returns the
  121. //! same value as roundEven(x) for all values of x.
  122. //! (From GLM_GTX_simd_vec4 extension, common function)
  123. detail::fvec4SIMD round(detail::fvec4SIMD const & x);
  124. //! Returns a value equal to the nearest integer to x.
  125. //! A fractional part of 0.5 will round toward the nearest even
  126. //! integer. (Both 3.5 and 4.5 for x will return 4.0.)
  127. //! (From GLM_GTX_simd_vec4 extension, common function)
  128. //detail::fvec4SIMD roundEven(detail::fvec4SIMD const & x);
  129. //! Returns a value equal to the nearest integer
  130. //! that is greater than or equal to x.
  131. //! (From GLM_GTX_simd_vec4 extension, common function)
  132. detail::fvec4SIMD ceil(detail::fvec4SIMD const & x);
  133. //! Return x - floor(x).
  134. //! (From GLM_GTX_simd_vec4 extension, common function)
  135. detail::fvec4SIMD fract(detail::fvec4SIMD const & x);
  136. //! Modulus. Returns x - y * floor(x / y)
  137. //! for each component in x using the floating point value y.
  138. //! (From GLM_GTX_simd_vec4 extension, common function)
  139. detail::fvec4SIMD mod(
  140. detail::fvec4SIMD const & x,
  141. detail::fvec4SIMD const & y);
  142. //! Modulus. Returns x - y * floor(x / y)
  143. //! for each component in x using the floating point value y.
  144. //! (From GLM_GTX_simd_vec4 extension, common function)
  145. detail::fvec4SIMD mod(
  146. detail::fvec4SIMD const & x,
  147. float const & y);
  148. //! Returns the fractional part of x and sets i to the integer
  149. //! part (as a whole number floating point value). Both the
  150. //! return value and the output parameter will have the same
  151. //! sign as x.
  152. //! (From GLM_GTX_simd_vec4 extension, common function)
  153. //detail::fvec4SIMD modf(
  154. // detail::fvec4SIMD const & x,
  155. // detail::fvec4SIMD & i);
  156. //! Returns y if y < x; otherwise, it returns x.
  157. //! (From GLM_GTX_simd_vec4 extension, common function)
  158. detail::fvec4SIMD min(
  159. detail::fvec4SIMD const & x,
  160. detail::fvec4SIMD const & y);
  161. detail::fvec4SIMD min(
  162. detail::fvec4SIMD const & x,
  163. float const & y);
  164. //! Returns y if x < y; otherwise, it returns x.
  165. //! (From GLM_GTX_simd_vec4 extension, common function)
  166. detail::fvec4SIMD max(
  167. detail::fvec4SIMD const & x,
  168. detail::fvec4SIMD const & y);
  169. detail::fvec4SIMD max(
  170. detail::fvec4SIMD const & x,
  171. float const & y);
  172. //! Returns min(max(x, minVal), maxVal) for each component in x
  173. //! using the floating-point values minVal and maxVal.
  174. //! (From GLM_GTX_simd_vec4 extension, common function)
  175. detail::fvec4SIMD clamp(
  176. detail::fvec4SIMD const & x,
  177. detail::fvec4SIMD const & minVal,
  178. detail::fvec4SIMD const & maxVal);
  179. detail::fvec4SIMD clamp(
  180. detail::fvec4SIMD const & x,
  181. float const & minVal,
  182. float const & maxVal);
  183. //! \return If genTypeU is a floating scalar or vector:
  184. //! Returns x * (1.0 - a) + y * a, i.e., the linear blend of
  185. //! x and y using the floating-point value a.
  186. //! The value for a is not restricted to the range [0, 1].
  187. //!
  188. //! \return If genTypeU is a boolean scalar or vector:
  189. //! Selects which vector each returned component comes
  190. //! from. For a component of a that is false, the
  191. //! corresponding component of x is returned. For a
  192. //! component of a that is true, the corresponding
  193. //! component of y is returned. Components of x and y that
  194. //! are not selected are allowed to be invalid floating point
  195. //! values and will have no effect on the results. Thus, this
  196. //! provides different functionality than
  197. //! genType mix(genType x, genType y, genType(a))
  198. //! where a is a Boolean vector.
  199. //!
  200. //! From GLSL 1.30.08 specification, section 8.3
  201. //!
  202. //! \param[in] x Floating point scalar or vector.
  203. //! \param[in] y Floating point scalar or vector.
  204. //! \param[in] a Floating point or boolean scalar or vector.
  205. //!
  206. // \todo Test when 'a' is a boolean.
  207. //! (From GLM_GTX_simd_vec4 extension, common function)
  208. detail::fvec4SIMD mix(
  209. detail::fvec4SIMD const & x,
  210. detail::fvec4SIMD const & y,
  211. detail::fvec4SIMD const & a);
  212. //! Returns 0.0 if x < edge, otherwise it returns 1.0.
  213. //! (From GLM_GTX_simd_vec4 extension, common function)
  214. detail::fvec4SIMD step(
  215. detail::fvec4SIMD const & edge,
  216. detail::fvec4SIMD const & x);
  217. detail::fvec4SIMD step(
  218. float const & edge,
  219. detail::fvec4SIMD const & x);
  220. //! Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
  221. //! performs smooth Hermite interpolation between 0 and 1
  222. //! when edge0 < x < edge1. This is useful in cases where
  223. //! you would want a threshold function with a smooth
  224. //! transition. This is equivalent to:
  225. //! genType t;
  226. //! t = clamp ((x – edge0) / (edge1 – edge0), 0, 1);
  227. //! return t * t * (3 – 2 * t);
  228. //! Results are undefined if edge0 >= edge1.
  229. //! (From GLM_GTX_simd_vec4 extension, common function)
  230. detail::fvec4SIMD smoothstep(
  231. detail::fvec4SIMD const & edge0,
  232. detail::fvec4SIMD const & edge1,
  233. detail::fvec4SIMD const & x);
  234. detail::fvec4SIMD smoothstep(
  235. float const & edge0,
  236. float const & edge1,
  237. detail::fvec4SIMD const & x);
  238. //! Returns true if x holds a NaN (not a number)
  239. //! representation in the underlying implementation's set of
  240. //! floating point representations. Returns false otherwise,
  241. //! including for implementations with no NaN
  242. //! representations.
  243. //! (From GLM_GTX_simd_vec4 extension, common function)
  244. //bvec4 isnan(detail::fvec4SIMD const & x);
  245. //! Returns true if x holds a positive infinity or negative
  246. //! infinity representation in the underlying implementation's
  247. //! set of floating point representations. Returns false
  248. //! otherwise, including for implementations with no infinity
  249. //! representations.
  250. //! (From GLM_GTX_simd_vec4 extension, common function)
  251. //bvec4 isinf(detail::fvec4SIMD const & x);
  252. //! Returns a signed or unsigned integer value representing
  253. //! the encoding of a floating-point value. The floatingpoint
  254. //! value's bit-level representation is preserved.
  255. //! (From GLM_GTX_simd_vec4 extension, common function)
  256. //detail::ivec4SIMD floatBitsToInt(detail::fvec4SIMD const & value);
  257. //! Returns a floating-point value corresponding to a signed
  258. //! or unsigned integer encoding of a floating-point value.
  259. //! If an inf or NaN is passed in, it will not signal, and the
  260. //! resulting floating point value is unspecified. Otherwise,
  261. //! the bit-level representation is preserved.
  262. //! (From GLM_GTX_simd_vec4 extension, common function)
  263. //detail::fvec4SIMD intBitsToFloat(detail::ivec4SIMD const & value);
  264. //! Computes and returns a * b + c.
  265. //! (From GLM_GTX_simd_vec4 extension, common function)
  266. detail::fvec4SIMD fma(
  267. detail::fvec4SIMD const & a,
  268. detail::fvec4SIMD const & b,
  269. detail::fvec4SIMD const & c);
  270. //! Splits x into a floating-point significand in the range
  271. //! [0.5, 1.0) and an integral exponent of two, such that:
  272. //! x = significand * exp(2, exponent)
  273. //! The significand is returned by the function and the
  274. //! exponent is returned in the parameter exp. For a
  275. //! floating-point value of zero, the significant and exponent
  276. //! are both zero. For a floating-point value that is an
  277. //! infinity or is not a number, the results are undefined.
  278. //! (From GLM_GTX_simd_vec4 extension, common function)
  279. //detail::fvec4SIMD frexp(detail::fvec4SIMD const & x, detail::ivec4SIMD & exp);
  280. //! Builds a floating-point number from x and the
  281. //! corresponding integral exponent of two in exp, returning:
  282. //! significand * exp(2, exponent)
  283. //! If this product is too large to be represented in the
  284. //! floating-point type, the result is undefined.
  285. //! (From GLM_GTX_simd_vec4 extension, common function)
  286. //detail::fvec4SIMD ldexp(detail::fvec4SIMD const & x, detail::ivec4SIMD const & exp);
  287. //! Returns the length of x, i.e., sqrt(x * x).
  288. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  289. float length(
  290. detail::fvec4SIMD const & x);
  291. //! Returns the length of x, i.e., sqrt(x * x).
  292. //! Less accurate but much faster than simdLength.
  293. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  294. float fastLength(
  295. detail::fvec4SIMD const & x);
  296. //! Returns the length of x, i.e., sqrt(x * x).
  297. //! Slightly more accurate but much slower than simdLength.
  298. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  299. float niceLength(
  300. detail::fvec4SIMD const & x);
  301. //! Returns the length of x, i.e., sqrt(x * x).
  302. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  303. detail::fvec4SIMD length4(
  304. detail::fvec4SIMD const & x);
  305. //! Returns the length of x, i.e., sqrt(x * x).
  306. //! Less accurate but much faster than simdLength4.
  307. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  308. detail::fvec4SIMD fastLength4(
  309. detail::fvec4SIMD const & x);
  310. //! Returns the length of x, i.e., sqrt(x * x).
  311. //! Slightly more accurate but much slower than simdLength4.
  312. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  313. detail::fvec4SIMD niceLength4(
  314. detail::fvec4SIMD const & x);
  315. //! Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
  316. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  317. float distance(
  318. detail::fvec4SIMD const & p0,
  319. detail::fvec4SIMD const & p1);
  320. //! Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
  321. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  322. detail::fvec4SIMD distance4(
  323. detail::fvec4SIMD const & p0,
  324. detail::fvec4SIMD const & p1);
  325. //! Returns the dot product of x and y, i.e., result = x * y.
  326. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  327. float simdDot(
  328. detail::fvec4SIMD const & x,
  329. detail::fvec4SIMD const & y);
  330. //! Returns the dot product of x and y, i.e., result = x * y.
  331. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  332. detail::fvec4SIMD dot4(
  333. detail::fvec4SIMD const & x,
  334. detail::fvec4SIMD const & y);
  335. //! Returns the cross product of x and y.
  336. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  337. detail::fvec4SIMD cross(
  338. detail::fvec4SIMD const & x,
  339. detail::fvec4SIMD const & y);
  340. //! Returns a vector in the same direction as x but with length of 1.
  341. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  342. detail::fvec4SIMD normalize(
  343. detail::fvec4SIMD const & x);
  344. //! Returns a vector in the same direction as x but with length of 1.
  345. //! Less accurate but much faster than simdNormalize.
  346. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  347. detail::fvec4SIMD fastNormalize(
  348. detail::fvec4SIMD const & x);
  349. //! If dot(Nref, I) < 0.0, return N, otherwise, return -N.
  350. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  351. detail::fvec4SIMD simdFaceforward(
  352. detail::fvec4SIMD const & N,
  353. detail::fvec4SIMD const & I,
  354. detail::fvec4SIMD const & Nref);
  355. //! For the incident vector I and surface orientation N,
  356. //! returns the reflection direction : result = I - 2.0 * dot(N, I) * N.
  357. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  358. detail::fvec4SIMD reflect(
  359. detail::fvec4SIMD const & I,
  360. detail::fvec4SIMD const & N);
  361. //! For the incident vector I and surface normal N,
  362. //! and the ratio of indices of refraction eta,
  363. //! return the refraction vector.
  364. //! (From GLM_GTX_simd_vec4 extension, geometry functions)
  365. detail::fvec4SIMD refract(
  366. detail::fvec4SIMD const & I,
  367. detail::fvec4SIMD const & N,
  368. float const & eta);
  369. //! Returns the positive square root of x.
  370. //! (From GLM_GTX_simd_vec4 extension, exponential function)
  371. detail::fvec4SIMD sqrt(
  372. detail::fvec4SIMD const & x);
  373. //! Returns the positive square root of x with the nicest quality but very slow.
  374. //! Slightly more accurate but much slower than simdSqrt.
  375. //! (From GLM_GTX_simd_vec4 extension, exponential function)
  376. detail::fvec4SIMD niceSqrt(
  377. detail::fvec4SIMD const & x);
  378. //! Returns the positive square root of x
  379. //! Less accurate but much faster than sqrt.
  380. //! (From GLM_GTX_simd_vec4 extension, exponential function)
  381. detail::fvec4SIMD fastSqrt(
  382. detail::fvec4SIMD const & x);
  383. //! Returns the reciprocal of the positive square root of x.
  384. //! (From GLM_GTX_simd_vec4 extension, exponential function)
  385. detail::fvec4SIMD inversesqrt(
  386. detail::fvec4SIMD const & x);
  387. //! Returns the reciprocal of the positive square root of x.
  388. //! Faster than inversesqrt but less accurate.
  389. //! (From GLM_GTX_simd_vec4 extension, exponential function)
  390. detail::fvec4SIMD fastInversesqrt(
  391. detail::fvec4SIMD const & x);
  392. /// @}
  393. }//namespace simd_vec4
  394. }//namespace gtx
  395. }//namespace glm
  396. #include "simd_vec4.inl"
  397. namespace glm{using namespace gtx::simd_vec4;}
  398. #endif//glm_gtx_simd_vec4