You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

517 lines
18 KiB

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