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.

1226 lines
27 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 core
  24. /// @file glm/core/func_common.inl
  25. /// @date 2008-08-03 / 2011-06-15
  26. /// @author Christophe Riccio
  27. ///////////////////////////////////////////////////////////////////////////////////
  28. namespace glm{
  29. namespace detail
  30. {
  31. template <typename genFIType, bool /*signed*/>
  32. struct Abs_
  33. {};
  34. template <typename genFIType>
  35. struct Abs_<genFIType, true>
  36. {
  37. GLM_FUNC_QUALIFIER static genFIType get(genFIType const & x)
  38. {
  39. GLM_STATIC_ASSERT(
  40. detail::type<genFIType>::is_float ||
  41. detail::type<genFIType>::is_int, "'abs' only accept floating-point and integer inputs");
  42. return x >= genFIType(0) ? x : -x;
  43. // TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff;
  44. }
  45. };
  46. template <typename genFIType>
  47. struct Abs_<genFIType, false>
  48. {
  49. GLM_FUNC_QUALIFIER static genFIType get(genFIType const & x)
  50. {
  51. GLM_STATIC_ASSERT(
  52. detail::type<genFIType>::is_uint, "'abs' only accept floating-point and integer inputs");
  53. return x;
  54. }
  55. };
  56. }//namespace detail
  57. // abs
  58. template <typename genFIType>
  59. GLM_FUNC_QUALIFIER genFIType abs
  60. (
  61. genFIType const & x
  62. )
  63. {
  64. return detail::Abs_<genFIType, std::numeric_limits<genFIType>::is_signed>::get(x);
  65. }
  66. VECTORIZE_VEC(abs)
  67. // sign
  68. //Try something like based on x >> 31 to get the sign bit
  69. template <typename genFIType>
  70. GLM_FUNC_QUALIFIER genFIType sign
  71. (
  72. genFIType const & x
  73. )
  74. {
  75. GLM_STATIC_ASSERT(
  76. detail::type<genFIType>::is_float ||
  77. detail::type<genFIType>::is_int, "'sign' only accept signed inputs");
  78. genFIType result;
  79. if(x > genFIType(0))
  80. result = genFIType(1);
  81. else if(x < genFIType(0))
  82. result = genFIType(-1);
  83. else
  84. result = genFIType(0);
  85. return result;
  86. }
  87. VECTORIZE_VEC(sign)
  88. // floor
  89. template <>
  90. GLM_FUNC_QUALIFIER detail::half floor<detail::half>(detail::half const & x)
  91. {
  92. return detail::half(::std::floor(float(x)));
  93. }
  94. template <typename genType>
  95. GLM_FUNC_QUALIFIER genType floor(genType const & x)
  96. {
  97. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'floor' only accept floating-point inputs");
  98. return ::std::floor(x);
  99. }
  100. VECTORIZE_VEC(floor)
  101. // trunc
  102. template <typename genType>
  103. GLM_FUNC_QUALIFIER genType trunc(genType const & x)
  104. {
  105. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'trunc' only accept floating-point inputs");
  106. return x < 0 ? -floor(-x) : floor(x);
  107. }
  108. VECTORIZE_VEC(trunc)
  109. // round
  110. template <typename genType>
  111. GLM_FUNC_QUALIFIER genType round(genType const& x)
  112. {
  113. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'round' only accept floating-point inputs");
  114. if(x < 0)
  115. return genType(int(x - genType(0.5)));
  116. return genType(int(x + genType(0.5)));
  117. }
  118. VECTORIZE_VEC(round)
  119. /*
  120. // roundEven
  121. template <typename genType>
  122. GLM_FUNC_QUALIFIER genType roundEven(genType const& x)
  123. {
  124. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'roundEven' only accept floating-point inputs");
  125. return genType(int(x + genType(int(x) % 2)));
  126. }
  127. */
  128. // roundEven
  129. template <typename genType>
  130. GLM_FUNC_QUALIFIER genType roundEven(genType const & x)
  131. {
  132. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'roundEven' only accept floating-point inputs");
  133. int Integer = int(x);
  134. genType IntegerPart = genType(Integer);
  135. genType FractionalPart = fract(x);
  136. if(FractionalPart > genType(0.5) || FractionalPart < genType(0.5))
  137. {
  138. return round(x);
  139. }
  140. else if((Integer % 2) == 0)
  141. {
  142. return IntegerPart;
  143. }
  144. else if(x <= genType(0)) // Work around...
  145. {
  146. return IntegerPart - 1;
  147. }
  148. else
  149. {
  150. return IntegerPart + 1;
  151. }
  152. //else // Bug on MinGW 4.5.2
  153. //{
  154. // return mix(IntegerPart + genType(-1), IntegerPart + genType(1), x <= genType(0));
  155. //}
  156. }
  157. VECTORIZE_VEC(roundEven)
  158. // ceil
  159. template <typename genType>
  160. GLM_FUNC_QUALIFIER genType ceil(genType const & x)
  161. {
  162. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'ceil' only accept floating-point inputs");
  163. return ::std::ceil(x);
  164. }
  165. VECTORIZE_VEC(ceil)
  166. // fract
  167. template <typename genType>
  168. GLM_FUNC_QUALIFIER genType fract
  169. (
  170. genType const & x
  171. )
  172. {
  173. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'fract' only accept floating-point inputs");
  174. return x - ::std::floor(x);
  175. }
  176. VECTORIZE_VEC(fract)
  177. // mod
  178. template <typename genType>
  179. GLM_FUNC_QUALIFIER genType mod
  180. (
  181. genType const & x,
  182. genType const & y
  183. )
  184. {
  185. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'mod' only accept floating-point inputs");
  186. return x - y * floor(x / y);
  187. }
  188. VECTORIZE_VEC_SCA(mod)
  189. VECTORIZE_VEC_VEC(mod)
  190. // modf
  191. template <typename genType>
  192. GLM_FUNC_QUALIFIER genType modf
  193. (
  194. genType const & x,
  195. genType & i
  196. )
  197. {
  198. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'modf' only accept floating-point inputs");
  199. return std::modf(x, &i);
  200. }
  201. template <typename valType>
  202. GLM_FUNC_QUALIFIER detail::tvec2<valType> modf
  203. (
  204. detail::tvec2<valType> const & x,
  205. detail::tvec2<valType> & i
  206. )
  207. {
  208. return detail::tvec2<valType>(
  209. modf(x.x, i.x),
  210. modf(x.y, i.y));
  211. }
  212. template <typename valType>
  213. GLM_FUNC_QUALIFIER detail::tvec3<valType> modf
  214. (
  215. detail::tvec3<valType> const & x,
  216. detail::tvec3<valType> & i
  217. )
  218. {
  219. return detail::tvec3<valType>(
  220. modf(x.x, i.x),
  221. modf(x.y, i.y),
  222. modf(x.z, i.z));
  223. }
  224. template <typename valType>
  225. GLM_FUNC_QUALIFIER detail::tvec4<valType> modf
  226. (
  227. detail::tvec4<valType> const & x,
  228. detail::tvec4<valType> & i
  229. )
  230. {
  231. return detail::tvec4<valType>(
  232. modf(x.x, i.x),
  233. modf(x.y, i.y),
  234. modf(x.z, i.z),
  235. modf(x.w, i.w));
  236. }
  237. //// Only valid if (INT_MIN <= x-y <= INT_MAX)
  238. //// min(x,y)
  239. //r = y + ((x - y) & ((x - y) >> (sizeof(int) *
  240. //CHAR_BIT - 1)));
  241. //// max(x,y)
  242. //r = x - ((x - y) & ((x - y) >> (sizeof(int) *
  243. //CHAR_BIT - 1)));
  244. // min
  245. template <typename genType>
  246. GLM_FUNC_QUALIFIER genType min
  247. (
  248. genType const & x,
  249. genType const & y
  250. )
  251. {
  252. GLM_STATIC_ASSERT(
  253. detail::type<genType>::is_float ||
  254. detail::type<genType>::is_int ||
  255. detail::type<genType>::is_uint, "'min' only accept numbers");
  256. return x < y ? x : y;
  257. }
  258. VECTORIZE_VEC_SCA(min)
  259. VECTORIZE_VEC_VEC(min)
  260. // max
  261. template <typename genType>
  262. GLM_FUNC_QUALIFIER genType max
  263. (
  264. genType const & x,
  265. genType const & y
  266. )
  267. {
  268. GLM_STATIC_ASSERT(
  269. detail::type<genType>::is_float ||
  270. detail::type<genType>::is_int ||
  271. detail::type<genType>::is_uint, "'max' only accept numbers");
  272. return x > y ? x : y;
  273. }
  274. VECTORIZE_VEC_SCA(max)
  275. VECTORIZE_VEC_VEC(max)
  276. // clamp
  277. template <typename valType>
  278. GLM_FUNC_QUALIFIER valType clamp
  279. (
  280. valType const & x,
  281. valType const & minVal,
  282. valType const & maxVal
  283. )
  284. {
  285. GLM_STATIC_ASSERT(
  286. detail::type<valType>::is_float ||
  287. detail::type<valType>::is_int ||
  288. detail::type<valType>::is_uint, "'clamp' only accept numbers");
  289. return min(maxVal, max(minVal, x));
  290. }
  291. template <typename T>
  292. GLM_FUNC_QUALIFIER detail::tvec2<T> clamp
  293. (
  294. detail::tvec2<T> const & x,
  295. typename detail::tvec2<T>::value_type const & minVal,
  296. typename detail::tvec2<T>::value_type const & maxVal
  297. )
  298. {
  299. return detail::tvec2<T>(
  300. clamp(x.x, minVal, maxVal),
  301. clamp(x.y, minVal, maxVal));
  302. }
  303. template <typename T>
  304. GLM_FUNC_QUALIFIER detail::tvec3<T> clamp
  305. (
  306. detail::tvec3<T> const & x,
  307. typename detail::tvec3<T>::value_type const & minVal,
  308. typename detail::tvec3<T>::value_type const & maxVal
  309. )
  310. {
  311. return detail::tvec3<T>(
  312. clamp(x.x, minVal, maxVal),
  313. clamp(x.y, minVal, maxVal),
  314. clamp(x.z, minVal, maxVal));
  315. }
  316. template <typename T>
  317. GLM_FUNC_QUALIFIER detail::tvec4<T> clamp
  318. (
  319. detail::tvec4<T> const & x,
  320. typename detail::tvec4<T>::value_type const & minVal,
  321. typename detail::tvec4<T>::value_type const & maxVal
  322. )
  323. {
  324. return detail::tvec4<T>(
  325. clamp(x.x, minVal, maxVal),
  326. clamp(x.y, minVal, maxVal),
  327. clamp(x.z, minVal, maxVal),
  328. clamp(x.w, minVal, maxVal));
  329. }
  330. template <typename T>
  331. GLM_FUNC_QUALIFIER detail::tvec2<T> clamp
  332. (
  333. detail::tvec2<T> const & x,
  334. detail::tvec2<T> const & minVal,
  335. detail::tvec2<T> const & maxVal
  336. )
  337. {
  338. return detail::tvec2<T>(
  339. clamp(x.x, minVal.x, maxVal.x),
  340. clamp(x.y, minVal.y, maxVal.y));
  341. }
  342. template <typename T>
  343. GLM_FUNC_QUALIFIER detail::tvec3<T> clamp
  344. (
  345. detail::tvec3<T> const & x,
  346. detail::tvec3<T> const & minVal,
  347. detail::tvec3<T> const & maxVal
  348. )
  349. {
  350. return detail::tvec3<T>(
  351. clamp(x.x, minVal.x, maxVal.x),
  352. clamp(x.y, minVal.y, maxVal.y),
  353. clamp(x.z, minVal.z, maxVal.z));
  354. }
  355. template <typename T>
  356. GLM_FUNC_QUALIFIER detail::tvec4<T> clamp
  357. (
  358. detail::tvec4<T> const & x,
  359. detail::tvec4<T> const & minVal,
  360. detail::tvec4<T> const & maxVal
  361. )
  362. {
  363. return detail::tvec4<T>(
  364. clamp(x.x, minVal.x, maxVal.x),
  365. clamp(x.y, minVal.y, maxVal.y),
  366. clamp(x.z, minVal.z, maxVal.z),
  367. clamp(x.w, minVal.w, maxVal.w));
  368. }
  369. // mix
  370. template <typename genType>
  371. GLM_FUNC_QUALIFIER genType mix
  372. (
  373. genType const & x,
  374. genType const & y,
  375. genType const & a
  376. )
  377. {
  378. GLM_STATIC_ASSERT(detail::type<genType>::is_float , "'genType' is not floating-point type");
  379. return x + a * (y - x);
  380. }
  381. template <typename valType>
  382. GLM_FUNC_QUALIFIER detail::tvec2<valType> mix
  383. (
  384. detail::tvec2<valType> const & x,
  385. detail::tvec2<valType> const & y,
  386. valType const & a
  387. )
  388. {
  389. GLM_STATIC_ASSERT(detail::type<valType>::is_float , "'genType' is not floating-point type");
  390. return x + a * (y - x);
  391. }
  392. template <typename valType>
  393. GLM_FUNC_QUALIFIER detail::tvec3<valType> mix
  394. (
  395. detail::tvec3<valType> const & x,
  396. detail::tvec3<valType> const & y,
  397. valType const & a
  398. )
  399. {
  400. return x + a * (y - x);
  401. }
  402. template <typename valType>
  403. GLM_FUNC_QUALIFIER detail::tvec4<valType> mix
  404. (
  405. detail::tvec4<valType> const & x,
  406. detail::tvec4<valType> const & y,
  407. valType const & a
  408. )
  409. {
  410. return x + a * (y - x);
  411. }
  412. template <typename valType>
  413. GLM_FUNC_QUALIFIER detail::tvec2<valType> mix
  414. (
  415. detail::tvec2<valType> const & x,
  416. detail::tvec2<valType> const & y,
  417. detail::tvec2<valType> const & a
  418. )
  419. {
  420. return x + a * (y - x);
  421. }
  422. template <typename valType>
  423. GLM_FUNC_QUALIFIER detail::tvec3<valType> mix
  424. (
  425. detail::tvec3<valType> const & x,
  426. detail::tvec3<valType> const & y,
  427. detail::tvec3<valType> const & a
  428. )
  429. {
  430. GLM_STATIC_ASSERT(detail::type<valType>::is_float , "'genType' is not floating-point type");
  431. return x + a * (y - x);
  432. }
  433. template <typename valType>
  434. GLM_FUNC_QUALIFIER detail::tvec4<valType> mix
  435. (
  436. detail::tvec4<valType> const & x,
  437. detail::tvec4<valType> const & y,
  438. detail::tvec4<valType> const & a
  439. )
  440. {
  441. return x + a * (y - x);
  442. }
  443. //template <typename genTypeT>
  444. //GLM_FUNC_QUALIFIER genTypeT mix
  445. //(
  446. // genTypeT const & x,
  447. // genTypeT const & y,
  448. // float const & a
  449. //)
  450. //{
  451. // // It could be a vector too
  452. // //GLM_STATIC_ASSERT(
  453. // // detail::type<genTypeT>::is_float &&
  454. // // detail::type<genTypeU>::is_float);
  455. // return x + a * (y - x);
  456. //}
  457. template <>
  458. GLM_FUNC_QUALIFIER float mix
  459. (
  460. float const & x,
  461. float const & y,
  462. bool const & a
  463. )
  464. {
  465. return a ? y : x;
  466. }
  467. template <>
  468. GLM_FUNC_QUALIFIER double mix
  469. (
  470. double const & x,
  471. double const & y,
  472. bool const & a
  473. )
  474. {
  475. return a ? y : x;
  476. }
  477. template <typename T>
  478. GLM_FUNC_QUALIFIER detail::tvec2<T> mix
  479. (
  480. detail::tvec2<T> const & x,
  481. detail::tvec2<T> const & y,
  482. bool a
  483. )
  484. {
  485. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'mix' only accept floating-point inputs");
  486. return a ? y : x;
  487. }
  488. template <typename T>
  489. GLM_FUNC_QUALIFIER detail::tvec3<T> mix
  490. (
  491. detail::tvec3<T> const & x,
  492. detail::tvec3<T> const & y,
  493. bool a
  494. )
  495. {
  496. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'mix' only accept floating-point inputs");
  497. return a ? y : x;
  498. }
  499. template <typename T>
  500. GLM_FUNC_QUALIFIER detail::tvec4<T> mix
  501. (
  502. detail::tvec4<T> const & x,
  503. detail::tvec4<T> const & y,
  504. bool a
  505. )
  506. {
  507. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'mix' only accept floating-point inputs");
  508. return a ? y : x;
  509. }
  510. template <typename T>
  511. GLM_FUNC_QUALIFIER detail::tvec2<T> mix
  512. (
  513. detail::tvec2<T> const & x,
  514. detail::tvec2<T> const & y,
  515. typename detail::tvec2<T>::bool_type a
  516. )
  517. {
  518. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'mix' only accept floating-point inputs");
  519. detail::tvec2<T> result;
  520. for
  521. (
  522. typename detail::tvec2<T>::size_type i = 0;
  523. i < x.length(); ++i
  524. )
  525. {
  526. result[i] = a[i] ? y[i] : x[i];
  527. }
  528. return result;
  529. }
  530. template <typename T>
  531. GLM_FUNC_QUALIFIER detail::tvec3<T> mix
  532. (
  533. detail::tvec3<T> const & x,
  534. detail::tvec3<T> const & y,
  535. typename detail::tvec3<T>::bool_type a
  536. )
  537. {
  538. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'mix' only accept floating-point inputs");
  539. detail::tvec3<T> result;
  540. for
  541. (
  542. typename detail::tvec3<T>::size_type i = 0;
  543. i < x.length(); ++i
  544. )
  545. {
  546. result[i] = a[i] ? y[i] : x[i];
  547. }
  548. return result;
  549. }
  550. template <typename T>
  551. GLM_FUNC_QUALIFIER detail::tvec4<T> mix
  552. (
  553. detail::tvec4<T> const & x,
  554. detail::tvec4<T> const & y,
  555. typename detail::tvec4<T>::bool_type a
  556. )
  557. {
  558. GLM_STATIC_ASSERT(detail::type<T>::is_float, "'mix' only accept floating-point inputs");
  559. detail::tvec4<T> result;
  560. for
  561. (
  562. typename detail::tvec4<T>::size_type i = 0;
  563. i < x.length(); ++i
  564. )
  565. {
  566. result[i] = a[i] ? y[i] : x[i];
  567. }
  568. return result;
  569. }
  570. // step
  571. template <typename genType>
  572. GLM_FUNC_QUALIFIER genType step
  573. (
  574. genType const & edge,
  575. genType const & x
  576. )
  577. {
  578. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'step' only accept floating-point inputs");
  579. return x < edge ? genType(0) : genType(1);
  580. }
  581. template <typename T>
  582. GLM_FUNC_QUALIFIER detail::tvec2<T> step
  583. (
  584. typename detail::tvec2<T>::value_type const & edge,
  585. detail::tvec2<T> const & x
  586. )
  587. {
  588. return detail::tvec2<T>(
  589. x.x < edge ? T(0) : T(1),
  590. x.y < edge ? T(0) : T(1));
  591. }
  592. template <typename T>
  593. GLM_FUNC_QUALIFIER detail::tvec3<T> step
  594. (
  595. typename detail::tvec3<T>::value_type const & edge,
  596. detail::tvec3<T> const & x
  597. )
  598. {
  599. return detail::tvec3<T>(
  600. x.x < edge ? T(0) : T(1),
  601. x.y < edge ? T(0) : T(1),
  602. x.z < edge ? T(0) : T(1));
  603. }
  604. template <typename T>
  605. GLM_FUNC_QUALIFIER detail::tvec4<T> step
  606. (
  607. typename detail::tvec4<T>::value_type const & edge,
  608. detail::tvec4<T> const & x
  609. )
  610. {
  611. return detail::tvec4<T>(
  612. x.x < edge ? T(0) : T(1),
  613. x.y < edge ? T(0) : T(1),
  614. x.z < edge ? T(0) : T(1),
  615. x.w < edge ? T(0) : T(1));
  616. }
  617. template <typename T>
  618. GLM_FUNC_QUALIFIER detail::tvec2<T> step
  619. (
  620. detail::tvec2<T> const & edge,
  621. detail::tvec2<T> const & x
  622. )
  623. {
  624. return detail::tvec2<T>(
  625. x.x < edge.x ? T(0) : T(1),
  626. x.y < edge.y ? T(0) : T(1));
  627. }
  628. template <typename T>
  629. GLM_FUNC_QUALIFIER detail::tvec3<T> step
  630. (
  631. detail::tvec3<T> const & edge,
  632. detail::tvec3<T> const & x
  633. )
  634. {
  635. return detail::tvec3<T>(
  636. x.x < edge.x ? T(0) : T(1),
  637. x.y < edge.y ? T(0) : T(1),
  638. x.z < edge.z ? T(0) : T(1));
  639. }
  640. template <typename T>
  641. GLM_FUNC_QUALIFIER detail::tvec4<T> step
  642. (
  643. detail::tvec4<T> const & edge,
  644. detail::tvec4<T> const & x
  645. )
  646. {
  647. return detail::tvec4<T>(
  648. x.x < edge.x ? T(0) : T(1),
  649. x.y < edge.y ? T(0) : T(1),
  650. x.z < edge.z ? T(0) : T(1),
  651. x.w < edge.w ? T(0) : T(1));
  652. }
  653. // smoothstep
  654. template <typename genType>
  655. GLM_FUNC_QUALIFIER genType smoothstep
  656. (
  657. genType const & edge0,
  658. genType const & edge1,
  659. genType const & x
  660. )
  661. {
  662. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'smoothstep' only accept floating-point inputs");
  663. genType tmp = clamp((x - edge0) / (edge1 - edge0), genType(0), genType(1));
  664. return tmp * tmp * (genType(3) - genType(2) * tmp);
  665. }
  666. template <typename T>
  667. GLM_FUNC_QUALIFIER detail::tvec2<T> smoothstep
  668. (
  669. typename detail::tvec2<T>::value_type const & edge0,
  670. typename detail::tvec2<T>::value_type const & edge1,
  671. detail::tvec2<T> const & x
  672. )
  673. {
  674. return detail::tvec2<T>(
  675. smoothstep(edge0, edge1, x.x),
  676. smoothstep(edge0, edge1, x.y));
  677. }
  678. template <typename T>
  679. GLM_FUNC_QUALIFIER detail::tvec3<T> smoothstep
  680. (
  681. typename detail::tvec3<T>::value_type const & edge0,
  682. typename detail::tvec3<T>::value_type const & edge1,
  683. detail::tvec3<T> const & x
  684. )
  685. {
  686. return detail::tvec3<T>(
  687. smoothstep(edge0, edge1, x.x),
  688. smoothstep(edge0, edge1, x.y),
  689. smoothstep(edge0, edge1, x.z));
  690. }
  691. template <typename T>
  692. GLM_FUNC_QUALIFIER detail::tvec4<T> smoothstep
  693. (
  694. typename detail::tvec4<T>::value_type const & edge0,
  695. typename detail::tvec4<T>::value_type const & edge1,
  696. detail::tvec4<T> const & x
  697. )
  698. {
  699. return detail::tvec4<T>(
  700. smoothstep(edge0, edge1, x.x),
  701. smoothstep(edge0, edge1, x.y),
  702. smoothstep(edge0, edge1, x.z),
  703. smoothstep(edge0, edge1, x.w));
  704. }
  705. template <typename T>
  706. GLM_FUNC_QUALIFIER detail::tvec2<T> smoothstep
  707. (
  708. detail::tvec2<T> const & edge0,
  709. detail::tvec2<T> const & edge1,
  710. detail::tvec2<T> const & x
  711. )
  712. {
  713. return detail::tvec2<T>(
  714. smoothstep(edge0.x, edge1.x, x.x),
  715. smoothstep(edge0.y, edge1.y, x.y));
  716. }
  717. template <typename T>
  718. GLM_FUNC_QUALIFIER detail::tvec3<T> smoothstep
  719. (
  720. detail::tvec3<T> const & edge0,
  721. detail::tvec3<T> const & edge1,
  722. detail::tvec3<T> const & x
  723. )
  724. {
  725. return detail::tvec3<T>(
  726. smoothstep(edge0.x, edge1.x, x.x),
  727. smoothstep(edge0.y, edge1.y, x.y),
  728. smoothstep(edge0.z, edge1.z, x.z));
  729. }
  730. template <typename T>
  731. GLM_FUNC_QUALIFIER detail::tvec4<T> smoothstep
  732. (
  733. detail::tvec4<T> const & edge0,
  734. detail::tvec4<T> const & edge1,
  735. detail::tvec4<T> const & x
  736. )
  737. {
  738. return detail::tvec4<T>(
  739. smoothstep(edge0.x, edge1.x, x.x),
  740. smoothstep(edge0.y, edge1.y, x.y),
  741. smoothstep(edge0.z, edge1.z, x.z),
  742. smoothstep(edge0.w, edge1.w, x.w));
  743. }
  744. // TODO: Not working on MinGW...
  745. template <typename genType>
  746. GLM_FUNC_QUALIFIER bool isnan(genType const & x)
  747. {
  748. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'isnan' only accept floating-point inputs");
  749. # if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_INTEL))
  750. return _isnan(x) != 0;
  751. # elif(GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG))
  752. # if(GLM_PLATFORM & GLM_PLATFORM_ANDROID)
  753. return _isnan(x) != 0;
  754. # else
  755. return std::isnan(x);
  756. # endif
  757. # elif(GLM_COMPILER & GLM_COMPILER_CUDA)
  758. return isnan(x) != 0;
  759. # else
  760. return std::isnan(x);
  761. # endif
  762. }
  763. template <typename T>
  764. GLM_FUNC_QUALIFIER typename detail::tvec2<T>::bool_type isnan
  765. (
  766. detail::tvec2<T> const & x
  767. )
  768. {
  769. return typename detail::tvec2<T>::bool_type(
  770. isnan(x.x),
  771. isnan(x.y));
  772. }
  773. template <typename T>
  774. GLM_FUNC_QUALIFIER typename detail::tvec3<T>::bool_type isnan
  775. (
  776. detail::tvec3<T> const & x
  777. )
  778. {
  779. return typename detail::tvec3<T>::bool_type(
  780. isnan(x.x),
  781. isnan(x.y),
  782. isnan(x.z));
  783. }
  784. template <typename T>
  785. GLM_FUNC_QUALIFIER typename detail::tvec4<T>::bool_type isnan
  786. (
  787. detail::tvec4<T> const & x
  788. )
  789. {
  790. return typename detail::tvec4<T>::bool_type(
  791. isnan(x.x),
  792. isnan(x.y),
  793. isnan(x.z),
  794. isnan(x.w));
  795. }
  796. template <typename genType>
  797. GLM_FUNC_QUALIFIER bool isinf(
  798. genType const & x)
  799. {
  800. GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'isinf' only accept floating-point inputs");
  801. # if(GLM_COMPILER & (GLM_COMPILER_INTEL | GLM_COMPILER_VC))
  802. return _fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF;
  803. # elif(GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG))
  804. # if(GLM_PLATFORM & GLM_PLATFORM_ANDROID)
  805. return _isinf(x) != 0;
  806. # else
  807. return std::isinf(x);
  808. # endif
  809. # elif(GLM_COMPILER & GLM_COMPILER_CUDA)
  810. // http://developer.download.nvidia.com/compute/cuda/4_2/rel/toolkit/docs/online/group__CUDA__MATH__DOUBLE_g13431dd2b40b51f9139cbb7f50c18fab.html#g13431dd2b40b51f9139cbb7f50c18fab
  811. return isinf(double(x)) != 0;
  812. # else
  813. return std::isinf(x);
  814. # endif
  815. }
  816. template <typename T>
  817. GLM_FUNC_QUALIFIER typename detail::tvec2<T>::bool_type isinf
  818. (
  819. detail::tvec2<T> const & x
  820. )
  821. {
  822. return typename detail::tvec2<T>::bool_type(
  823. isinf(x.x),
  824. isinf(x.y));
  825. }
  826. template <typename T>
  827. GLM_FUNC_QUALIFIER typename detail::tvec3<T>::bool_type isinf
  828. (
  829. detail::tvec3<T> const & x
  830. )
  831. {
  832. return typename detail::tvec3<T>::bool_type(
  833. isinf(x.x),
  834. isinf(x.y),
  835. isinf(x.z));
  836. }
  837. template <typename T>
  838. GLM_FUNC_QUALIFIER typename detail::tvec4<T>::bool_type isinf
  839. (
  840. detail::tvec4<T> const & x
  841. )
  842. {
  843. return typename detail::tvec4<T>::bool_type(
  844. isinf(x.x),
  845. isinf(x.y),
  846. isinf(x.z),
  847. isinf(x.w));
  848. }
  849. GLM_FUNC_QUALIFIER int floatBitsToInt(float const & value)
  850. {
  851. union
  852. {
  853. float f;
  854. int i;
  855. } fi;
  856. fi.f = value;
  857. return fi.i;
  858. }
  859. GLM_FUNC_QUALIFIER detail::tvec2<int> floatBitsToInt
  860. (
  861. detail::tvec2<float> const & value
  862. )
  863. {
  864. return detail::tvec2<int>(
  865. floatBitsToInt(value.x),
  866. floatBitsToInt(value.y));
  867. }
  868. GLM_FUNC_QUALIFIER detail::tvec3<int> floatBitsToInt
  869. (
  870. detail::tvec3<float> const & value
  871. )
  872. {
  873. return detail::tvec3<int>(
  874. floatBitsToInt(value.x),
  875. floatBitsToInt(value.y),
  876. floatBitsToInt(value.z));
  877. }
  878. GLM_FUNC_QUALIFIER detail::tvec4<int> floatBitsToInt
  879. (
  880. detail::tvec4<float> const & value
  881. )
  882. {
  883. return detail::tvec4<int>(
  884. floatBitsToInt(value.x),
  885. floatBitsToInt(value.y),
  886. floatBitsToInt(value.z),
  887. floatBitsToInt(value.w));
  888. }
  889. GLM_FUNC_QUALIFIER uint floatBitsToUint(float const & value)
  890. {
  891. union
  892. {
  893. float f;
  894. uint u;
  895. } fu;
  896. fu.f = value;
  897. return fu.u;
  898. }
  899. GLM_FUNC_QUALIFIER detail::tvec2<uint> floatBitsToUint
  900. (
  901. detail::tvec2<float> const & value
  902. )
  903. {
  904. return detail::tvec2<uint>(
  905. floatBitsToUint(value.x),
  906. floatBitsToUint(value.y));
  907. }
  908. GLM_FUNC_QUALIFIER detail::tvec3<uint> floatBitsToUint
  909. (
  910. detail::tvec3<float> const & value
  911. )
  912. {
  913. return detail::tvec3<uint>(
  914. floatBitsToUint(value.x),
  915. floatBitsToUint(value.y),
  916. floatBitsToUint(value.z));
  917. }
  918. GLM_FUNC_QUALIFIER detail::tvec4<uint> floatBitsToUint
  919. (
  920. detail::tvec4<float> const & value
  921. )
  922. {
  923. return detail::tvec4<uint>(
  924. floatBitsToUint(value.x),
  925. floatBitsToUint(value.y),
  926. floatBitsToUint(value.z),
  927. floatBitsToUint(value.w));
  928. }
  929. GLM_FUNC_QUALIFIER float intBitsToFloat(int const & value)
  930. {
  931. union
  932. {
  933. float f;
  934. int i;
  935. } fi;
  936. fi.i = value;
  937. return fi.f;
  938. }
  939. GLM_FUNC_QUALIFIER detail::tvec2<float> intBitsToFloat
  940. (
  941. detail::tvec2<int> const & value
  942. )
  943. {
  944. return detail::tvec2<float>(
  945. intBitsToFloat(value.x),
  946. intBitsToFloat(value.y));
  947. }
  948. GLM_FUNC_QUALIFIER detail::tvec3<float> intBitsToFloat
  949. (
  950. detail::tvec3<int> const & value
  951. )
  952. {
  953. return detail::tvec3<float>(
  954. intBitsToFloat(value.x),
  955. intBitsToFloat(value.y),
  956. intBitsToFloat(value.z));
  957. }
  958. GLM_FUNC_QUALIFIER detail::tvec4<float> intBitsToFloat
  959. (
  960. detail::tvec4<int> const & value
  961. )
  962. {
  963. return detail::tvec4<float>(
  964. intBitsToFloat(value.x),
  965. intBitsToFloat(value.y),
  966. intBitsToFloat(value.z),
  967. intBitsToFloat(value.w));
  968. }
  969. GLM_FUNC_QUALIFIER float uintBitsToFloat(uint const & value)
  970. {
  971. union
  972. {
  973. float f;
  974. uint u;
  975. } fu;
  976. fu.u = value;
  977. return fu.f;
  978. }
  979. GLM_FUNC_QUALIFIER detail::tvec2<float> uintBitsToFloat
  980. (
  981. detail::tvec2<uint> const & value
  982. )
  983. {
  984. return detail::tvec2<float>(
  985. uintBitsToFloat(value.x),
  986. uintBitsToFloat(value.y));
  987. }
  988. GLM_FUNC_QUALIFIER detail::tvec3<float> uintBitsToFloat
  989. (
  990. detail::tvec3<uint> const & value
  991. )
  992. {
  993. return detail::tvec3<float>(
  994. uintBitsToFloat(value.x),
  995. uintBitsToFloat(value.y),
  996. uintBitsToFloat(value.z));
  997. }
  998. GLM_FUNC_QUALIFIER detail::tvec4<float> uintBitsToFloat
  999. (
  1000. detail::tvec4<uint> const & value
  1001. )
  1002. {
  1003. return detail::tvec4<float>(
  1004. uintBitsToFloat(value.x),
  1005. uintBitsToFloat(value.y),
  1006. uintBitsToFloat(value.z),
  1007. uintBitsToFloat(value.w));
  1008. }
  1009. template <typename genType>
  1010. GLM_FUNC_QUALIFIER genType fma
  1011. (
  1012. genType const & a,
  1013. genType const & b,
  1014. genType const & c
  1015. )
  1016. {
  1017. return a * b + c;
  1018. }
  1019. template <typename genType>
  1020. GLM_FUNC_QUALIFIER genType frexp
  1021. (
  1022. genType const & x,
  1023. int & exp
  1024. )
  1025. {
  1026. return std::frexp(x, exp);
  1027. }
  1028. template <typename T>
  1029. GLM_FUNC_QUALIFIER detail::tvec2<T> frexp
  1030. (
  1031. detail::tvec2<T> const & x,
  1032. detail::tvec2<int> & exp
  1033. )
  1034. {
  1035. return std::frexp(x, exp);
  1036. }
  1037. template <typename T>
  1038. GLM_FUNC_QUALIFIER detail::tvec3<T> frexp
  1039. (
  1040. detail::tvec3<T> const & x,
  1041. detail::tvec3<int> & exp
  1042. )
  1043. {
  1044. return std::frexp(x, exp);
  1045. }
  1046. template <typename T>
  1047. GLM_FUNC_QUALIFIER detail::tvec4<T> frexp
  1048. (
  1049. detail::tvec4<T> const & x,
  1050. detail::tvec4<int> & exp
  1051. )
  1052. {
  1053. return std::frexp(x, exp);
  1054. }
  1055. template <typename genType>
  1056. GLM_FUNC_QUALIFIER genType ldexp
  1057. (
  1058. genType const & x,
  1059. int const & exp
  1060. )
  1061. {
  1062. return std::frexp(x, exp);
  1063. }
  1064. template <typename T>
  1065. GLM_FUNC_QUALIFIER detail::tvec2<T> ldexp
  1066. (
  1067. detail::tvec2<T> const & x,
  1068. detail::tvec2<int> const & exp
  1069. )
  1070. {
  1071. return std::frexp(x, exp);
  1072. }
  1073. template <typename T>
  1074. GLM_FUNC_QUALIFIER detail::tvec3<T> ldexp
  1075. (
  1076. detail::tvec3<T> const & x,
  1077. detail::tvec3<int> const & exp
  1078. )
  1079. {
  1080. return std::frexp(x, exp);
  1081. }
  1082. template <typename T>
  1083. GLM_FUNC_QUALIFIER detail::tvec4<T> ldexp
  1084. (
  1085. detail::tvec4<T> const & x,
  1086. detail::tvec4<int> const & exp
  1087. )
  1088. {
  1089. return std::frexp(x, exp);
  1090. }
  1091. }//namespace glm