vec2.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. /*
  2. * Copyright (c), Recep Aslantas.
  3. *
  4. * MIT License (MIT), http://opensource.org/licenses/MIT
  5. * Full license can be found in the LICENSE file
  6. */
  7. /*
  8. Macros:
  9. GLM_VEC2_ONE_INIT
  10. GLM_VEC2_ZERO_INIT
  11. GLM_VEC2_ONE
  12. GLM_VEC2_ZERO
  13. Functions:
  14. CGLM_INLINE void glm_vec2(float * __restrict v, vec2 dest)
  15. CGLM_INLINE void glm_vec2_copy(vec2 a, vec2 dest)
  16. CGLM_INLINE void glm_vec2_zero(vec2 v)
  17. CGLM_INLINE void glm_vec2_one(vec2 v)
  18. CGLM_INLINE float glm_vec2_dot(vec2 a, vec2 b)
  19. CGLM_INLINE float glm_vec2_cross(vec2 a, vec2 b)
  20. CGLM_INLINE float glm_vec2_norm2(vec2 v)
  21. CGLM_INLINE float glm_vec2_norm(vec2 vec)
  22. CGLM_INLINE void glm_vec2_add(vec2 a, vec2 b, vec2 dest)
  23. CGLM_INLINE void glm_vec2_adds(vec2 v, float s, vec2 dest)
  24. CGLM_INLINE void glm_vec2_sub(vec2 a, vec2 b, vec2 dest)
  25. CGLM_INLINE void glm_vec2_subs(vec2 v, float s, vec2 dest)
  26. CGLM_INLINE void glm_vec2_mul(vec2 a, vec2 b, vec2 d)
  27. CGLM_INLINE void glm_vec2_scale(vec2 v, float s, vec2 dest)
  28. CGLM_INLINE void glm_vec2_scale_as(vec2 v, float s, vec2 dest)
  29. CGLM_INLINE void glm_vec2_div(vec2 a, vec2 b, vec2 dest)
  30. CGLM_INLINE void glm_vec2_divs(vec2 v, float s, vec2 dest)
  31. CGLM_INLINE void glm_vec2_addadd(vec2 a, vec2 b, vec2 dest)
  32. CGLM_INLINE void glm_vec2_subadd(vec2 a, vec2 b, vec2 dest)
  33. CGLM_INLINE void glm_vec2_muladd(vec2 a, vec2 b, vec2 dest)
  34. CGLM_INLINE void glm_vec2_muladds(vec2 a, float s, vec2 dest)
  35. CGLM_INLINE void glm_vec2_maxadd(vec2 a, vec2 b, vec2 dest)
  36. CGLM_INLINE void glm_vec2_minadd(vec2 a, vec2 b, vec2 dest)
  37. CGLM_INLINE void glm_vec2_subsub(vec2 a, vec2 b, vec2 dest)
  38. CGLM_INLINE void glm_vec2_addsub(vec2 a, vec2 b, vec2 dest)
  39. CGLM_INLINE void glm_vec2_mulsub(vec2 a, vec2 b, vec2 dest)
  40. CGLM_INLINE void glm_vec2_mulsubs(vec2 a, float s, vec2 dest)
  41. CGLM_INLINE void glm_vec2_maxsub(vec2 a, vec2 b, vec2 dest)
  42. CGLM_INLINE void glm_vec2_minsub(vec2 a, vec2 b, vec2 dest)
  43. CGLM_INLINE void glm_vec2_negate_to(vec2 v, vec2 dest)
  44. CGLM_INLINE void glm_vec2_negate(vec2 v)
  45. CGLM_INLINE void glm_vec2_normalize(vec2 v)
  46. CGLM_INLINE void glm_vec2_normalize_to(vec2 vec, vec2 dest)
  47. CGLM_INLINE void glm_vec2_rotate(vec2 v, float angle, vec2 dest)
  48. CGLM_INLINE void glm_vec2_center(vec2 a, vec2 b, vec2 dest)
  49. CGLM_INLINE float glm_vec2_distance2(vec2 a, vec2 b)
  50. CGLM_INLINE float glm_vec2_distance(vec2 a, vec2 b)
  51. CGLM_INLINE void glm_vec2_maxv(vec2 v1, vec2 v2, vec2 dest)
  52. CGLM_INLINE void glm_vec2_minv(vec2 v1, vec2 v2, vec2 dest)
  53. CGLM_INLINE void glm_vec2_clamp(vec2 v, float minVal, float maxVal)
  54. CGLM_INLINE void glm_vec2_swizzle(vec2 v, int mask, vec2 dest)
  55. CGLM_INLINE void glm_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest)
  56. CGLM_INLINE void glm_vec2_step(vec2 edge, vec2 x, vec2 dest)
  57. CGLM_INLINE void glm_vec2_make(float * restrict src, vec2 dest)
  58. CGLM_INLINE void glm_vec2_reflect(vec2 v, vec2 n, vec2 dest)
  59. CGLM_INLINE void glm_vec2_refract(vec2 v, vec2 n, float eta, vec2 dest)
  60. */
  61. #ifndef cglm_vec2_h
  62. #define cglm_vec2_h
  63. #include "common.h"
  64. #include "util.h"
  65. #include "vec2-ext.h"
  66. #define GLM_VEC2_ONE_INIT {1.0f, 1.0f}
  67. #define GLM_VEC2_ZERO_INIT {0.0f, 0.0f}
  68. #define GLM_VEC2_ONE ((vec2)GLM_VEC2_ONE_INIT)
  69. #define GLM_VEC2_ZERO ((vec2)GLM_VEC2_ZERO_INIT)
  70. /*!
  71. * @brief init vec2 using another vector
  72. *
  73. * @param[in] v a vector
  74. * @param[out] dest destination
  75. */
  76. CGLM_INLINE
  77. void
  78. glm_vec2(float * __restrict v, vec2 dest) {
  79. dest[0] = v[0];
  80. dest[1] = v[1];
  81. }
  82. /*!
  83. * @brief copy all members of [a] to [dest]
  84. *
  85. * @param[in] a source
  86. * @param[out] dest destination
  87. */
  88. CGLM_INLINE
  89. void
  90. glm_vec2_copy(vec2 a, vec2 dest) {
  91. dest[0] = a[0];
  92. dest[1] = a[1];
  93. }
  94. /*!
  95. * @brief make vector zero
  96. *
  97. * @param[in, out] v vector
  98. */
  99. CGLM_INLINE
  100. void
  101. glm_vec2_zero(vec2 v) {
  102. v[0] = v[1] = 0.0f;
  103. }
  104. /*!
  105. * @brief make vector one
  106. *
  107. * @param[in, out] v vector
  108. */
  109. CGLM_INLINE
  110. void
  111. glm_vec2_one(vec2 v) {
  112. v[0] = v[1] = 1.0f;
  113. }
  114. /*!
  115. * @brief vec2 dot product
  116. *
  117. * @param[in] a vector1
  118. * @param[in] b vector2
  119. *
  120. * @return dot product
  121. */
  122. CGLM_INLINE
  123. float
  124. glm_vec2_dot(vec2 a, vec2 b) {
  125. return a[0] * b[0] + a[1] * b[1];
  126. }
  127. /*!
  128. * @brief vec2 cross product
  129. *
  130. * REF: http://allenchou.net/2013/07/cross-product-of-2d-vectors/
  131. *
  132. * @param[in] a vector1
  133. * @param[in] b vector2
  134. *
  135. * @return Z component of cross product
  136. */
  137. CGLM_INLINE
  138. float
  139. glm_vec2_cross(vec2 a, vec2 b) {
  140. /* just calculate the z-component */
  141. return a[0] * b[1] - a[1] * b[0];
  142. }
  143. /*!
  144. * @brief norm * norm (magnitude) of vec
  145. *
  146. * we can use this func instead of calling norm * norm, because it would call
  147. * sqrtf function twice but with this func we can avoid func call, maybe this is
  148. * not good name for this func
  149. *
  150. * @param[in] v vector
  151. *
  152. * @return norm * norm
  153. */
  154. CGLM_INLINE
  155. float
  156. glm_vec2_norm2(vec2 v) {
  157. return glm_vec2_dot(v, v);
  158. }
  159. /*!
  160. * @brief norm (magnitude) of vec2
  161. *
  162. * @param[in] vec vector
  163. *
  164. * @return norm
  165. */
  166. CGLM_INLINE
  167. float
  168. glm_vec2_norm(vec2 vec) {
  169. return sqrtf(glm_vec2_norm2(vec));
  170. }
  171. /*!
  172. * @brief add a vector to b vector store result in dest
  173. *
  174. * @param[in] a vector1
  175. * @param[in] b vector2
  176. * @param[out] dest destination vector
  177. */
  178. CGLM_INLINE
  179. void
  180. glm_vec2_add(vec2 a, vec2 b, vec2 dest) {
  181. dest[0] = a[0] + b[0];
  182. dest[1] = a[1] + b[1];
  183. }
  184. /*!
  185. * @brief add scalar to v vector store result in dest (d = v + s)
  186. *
  187. * @param[in] v vector
  188. * @param[in] s scalar
  189. * @param[out] dest destination vector
  190. */
  191. CGLM_INLINE
  192. void
  193. glm_vec2_adds(vec2 v, float s, vec2 dest) {
  194. dest[0] = v[0] + s;
  195. dest[1] = v[1] + s;
  196. }
  197. /*!
  198. * @brief subtract b vector from a vector store result in dest
  199. *
  200. * @param[in] a vector1
  201. * @param[in] b vector2
  202. * @param[out] dest destination vector
  203. */
  204. CGLM_INLINE
  205. void
  206. glm_vec2_sub(vec2 a, vec2 b, vec2 dest) {
  207. dest[0] = a[0] - b[0];
  208. dest[1] = a[1] - b[1];
  209. }
  210. /*!
  211. * @brief subtract scalar from v vector store result in dest (d = v - s)
  212. *
  213. * @param[in] v vector
  214. * @param[in] s scalar
  215. * @param[out] dest destination vector
  216. */
  217. CGLM_INLINE
  218. void
  219. glm_vec2_subs(vec2 v, float s, vec2 dest) {
  220. dest[0] = v[0] - s;
  221. dest[1] = v[1] - s;
  222. }
  223. /*!
  224. * @brief multiply two vectors (component-wise multiplication)
  225. *
  226. * @param a v1
  227. * @param b v2
  228. * @param dest v3 = (a[0] * b[0], a[1] * b[1])
  229. */
  230. CGLM_INLINE
  231. void
  232. glm_vec2_mul(vec2 a, vec2 b, vec2 dest) {
  233. dest[0] = a[0] * b[0];
  234. dest[1] = a[1] * b[1];
  235. }
  236. /*!
  237. * @brief multiply/scale vector with scalar: result = v * s
  238. *
  239. * @param[in] v vector
  240. * @param[in] s scalar
  241. * @param[out] dest destination vector
  242. */
  243. CGLM_INLINE
  244. void
  245. glm_vec2_scale(vec2 v, float s, vec2 dest) {
  246. dest[0] = v[0] * s;
  247. dest[1] = v[1] * s;
  248. }
  249. /*!
  250. * @brief scale as vector specified: result = unit(v) * s
  251. *
  252. * @param[in] v vector
  253. * @param[in] s scalar
  254. * @param[out] dest destination vector
  255. */
  256. CGLM_INLINE
  257. void
  258. glm_vec2_scale_as(vec2 v, float s, vec2 dest) {
  259. float norm;
  260. norm = glm_vec2_norm(v);
  261. if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
  262. glm_vec2_zero(dest);
  263. return;
  264. }
  265. glm_vec2_scale(v, s / norm, dest);
  266. }
  267. /*!
  268. * @brief div vector with another component-wise division: d = a / b
  269. *
  270. * @param[in] a vector 1
  271. * @param[in] b vector 2
  272. * @param[out] dest result = (a[0]/b[0], a[1]/b[1])
  273. */
  274. CGLM_INLINE
  275. void
  276. glm_vec2_div(vec2 a, vec2 b, vec2 dest) {
  277. dest[0] = a[0] / b[0];
  278. dest[1] = a[1] / b[1];
  279. }
  280. /*!
  281. * @brief div vector with scalar: d = v / s
  282. *
  283. * @param[in] v vector
  284. * @param[in] s scalar
  285. * @param[out] dest result = (a[0]/s, a[1]/s)
  286. */
  287. CGLM_INLINE
  288. void
  289. glm_vec2_divs(vec2 v, float s, vec2 dest) {
  290. dest[0] = v[0] / s;
  291. dest[1] = v[1] / s;
  292. }
  293. /*!
  294. * @brief add two vectors and add result to sum
  295. *
  296. * it applies += operator so dest must be initialized
  297. *
  298. * @param[in] a vector 1
  299. * @param[in] b vector 2
  300. * @param[out] dest dest += (a + b)
  301. */
  302. CGLM_INLINE
  303. void
  304. glm_vec2_addadd(vec2 a, vec2 b, vec2 dest) {
  305. dest[0] += a[0] + b[0];
  306. dest[1] += a[1] + b[1];
  307. }
  308. /*!
  309. * @brief sub two vectors and add result to dest
  310. *
  311. * it applies += operator so dest must be initialized
  312. *
  313. * @param[in] a vector 1
  314. * @param[in] b vector 2
  315. * @param[out] dest dest += (a + b)
  316. */
  317. CGLM_INLINE
  318. void
  319. glm_vec2_subadd(vec2 a, vec2 b, vec2 dest) {
  320. dest[0] += a[0] - b[0];
  321. dest[1] += a[1] - b[1];
  322. }
  323. /*!
  324. * @brief mul two vectors and add result to dest
  325. *
  326. * it applies += operator so dest must be initialized
  327. *
  328. * @param[in] a vector 1
  329. * @param[in] b vector 2
  330. * @param[out] dest dest += (a * b)
  331. */
  332. CGLM_INLINE
  333. void
  334. glm_vec2_muladd(vec2 a, vec2 b, vec2 dest) {
  335. dest[0] += a[0] * b[0];
  336. dest[1] += a[1] * b[1];
  337. }
  338. /*!
  339. * @brief mul vector with scalar and add result to sum
  340. *
  341. * it applies += operator so dest must be initialized
  342. *
  343. * @param[in] a vector
  344. * @param[in] s scalar
  345. * @param[out] dest dest += (a * b)
  346. */
  347. CGLM_INLINE
  348. void
  349. glm_vec2_muladds(vec2 a, float s, vec2 dest) {
  350. dest[0] += a[0] * s;
  351. dest[1] += a[1] * s;
  352. }
  353. /*!
  354. * @brief add max of two vectors to result/dest
  355. *
  356. * it applies += operator so dest must be initialized
  357. *
  358. * @param[in] a vector 1
  359. * @param[in] b vector 2
  360. * @param[out] dest dest += max(a, b)
  361. */
  362. CGLM_INLINE
  363. void
  364. glm_vec2_maxadd(vec2 a, vec2 b, vec2 dest) {
  365. dest[0] += glm_max(a[0], b[0]);
  366. dest[1] += glm_max(a[1], b[1]);
  367. }
  368. /*!
  369. * @brief add min of two vectors to result/dest
  370. *
  371. * it applies += operator so dest must be initialized
  372. *
  373. * @param[in] a vector 1
  374. * @param[in] b vector 2
  375. * @param[out] dest dest += min(a, b)
  376. */
  377. CGLM_INLINE
  378. void
  379. glm_vec2_minadd(vec2 a, vec2 b, vec2 dest) {
  380. dest[0] += glm_min(a[0], b[0]);
  381. dest[1] += glm_min(a[1], b[1]);
  382. }
  383. /*!
  384. * @brief sub two vectors and sub result to dest
  385. *
  386. * it applies -= operator so dest must be initialized
  387. *
  388. * @param[in] a vector 1
  389. * @param[in] b vector 2
  390. * @param[out] dest dest -= (a - b)
  391. */
  392. CGLM_INLINE
  393. void
  394. glm_vec2_subsub(vec2 a, vec2 b, vec2 dest) {
  395. dest[0] -= a[0] - b[0];
  396. dest[1] -= a[1] - b[1];
  397. }
  398. /*!
  399. * @brief add two vectors and sub result to dest
  400. *
  401. * it applies -= operator so dest must be initialized
  402. *
  403. * @param[in] a vector 1
  404. * @param[in] b vector 2
  405. * @param[out] dest dest -= (a + b)
  406. */
  407. CGLM_INLINE
  408. void
  409. glm_vec2_addsub(vec2 a, vec2 b, vec2 dest) {
  410. dest[0] -= a[0] + b[0];
  411. dest[1] -= a[1] + b[1];
  412. }
  413. /*!
  414. * @brief mul two vectors and sub result to dest
  415. *
  416. * it applies -= operator so dest must be initialized
  417. *
  418. * @param[in] a vector 1
  419. * @param[in] b vector 2
  420. * @param[out] dest dest -= (a * b)
  421. */
  422. CGLM_INLINE
  423. void
  424. glm_vec2_mulsub(vec2 a, vec2 b, vec2 dest) {
  425. dest[0] -= a[0] * b[0];
  426. dest[1] -= a[1] * b[1];
  427. }
  428. /*!
  429. * @brief mul vector with scalar and sub result to sum
  430. *
  431. * it applies -= operator so dest must be initialized
  432. *
  433. * @param[in] a vector
  434. * @param[in] s scalar
  435. * @param[out] dest dest -= (a * b)
  436. */
  437. CGLM_INLINE
  438. void
  439. glm_vec2_mulsubs(vec2 a, float s, vec2 dest) {
  440. dest[0] -= a[0] * s;
  441. dest[1] -= a[1] * s;
  442. }
  443. /*!
  444. * @brief sub max of two vectors to result/dest
  445. *
  446. * it applies -= operator so dest must be initialized
  447. *
  448. * @param[in] a vector 1
  449. * @param[in] b vector 2
  450. * @param[out] dest dest -= max(a, b)
  451. */
  452. CGLM_INLINE
  453. void
  454. glm_vec2_maxsub(vec2 a, vec2 b, vec2 dest) {
  455. dest[0] -= glm_max(a[0], b[0]);
  456. dest[1] -= glm_max(a[1], b[1]);
  457. }
  458. /*!
  459. * @brief sub min of two vectors to result/dest
  460. *
  461. * it applies -= operator so dest must be initialized
  462. *
  463. * @param[in] a vector 1
  464. * @param[in] b vector 2
  465. * @param[out] dest dest -= min(a, b)
  466. */
  467. CGLM_INLINE
  468. void
  469. glm_vec2_minsub(vec2 a, vec2 b, vec2 dest) {
  470. dest[0] -= glm_min(a[0], b[0]);
  471. dest[1] -= glm_min(a[1], b[1]);
  472. }
  473. /*!
  474. * @brief negate vector components and store result in dest
  475. *
  476. * @param[in] v vector
  477. * @param[out] dest result vector
  478. */
  479. CGLM_INLINE
  480. void
  481. glm_vec2_negate_to(vec2 v, vec2 dest) {
  482. dest[0] = -v[0];
  483. dest[1] = -v[1];
  484. }
  485. /*!
  486. * @brief negate vector components
  487. *
  488. * @param[in, out] v vector
  489. */
  490. CGLM_INLINE
  491. void
  492. glm_vec2_negate(vec2 v) {
  493. glm_vec2_negate_to(v, v);
  494. }
  495. /*!
  496. * @brief normalize vector and store result in same vec
  497. *
  498. * @param[in, out] v vector
  499. */
  500. CGLM_INLINE
  501. void
  502. glm_vec2_normalize(vec2 v) {
  503. float norm;
  504. norm = glm_vec2_norm(v);
  505. if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
  506. v[0] = v[1] = 0.0f;
  507. return;
  508. }
  509. glm_vec2_scale(v, 1.0f / norm, v);
  510. }
  511. /*!
  512. * @brief normalize vector to dest
  513. *
  514. * @param[in] v source
  515. * @param[out] dest destination
  516. */
  517. CGLM_INLINE
  518. void
  519. glm_vec2_normalize_to(vec2 v, vec2 dest) {
  520. float norm;
  521. norm = glm_vec2_norm(v);
  522. if (CGLM_UNLIKELY(norm < FLT_EPSILON)) {
  523. glm_vec2_zero(dest);
  524. return;
  525. }
  526. glm_vec2_scale(v, 1.0f / norm, dest);
  527. }
  528. /*!
  529. * @brief rotate vec2 around origin by angle (CCW: counterclockwise)
  530. *
  531. * Formula:
  532. * 𝑥2 = cos(a)𝑥1 − sin(a)𝑦1
  533. * 𝑦2 = sin(a)𝑥1 + cos(a)𝑦1
  534. *
  535. * @param[in] v vector to rotate
  536. * @param[in] angle angle by radians
  537. * @param[out] dest destination vector
  538. */
  539. CGLM_INLINE
  540. void
  541. glm_vec2_rotate(vec2 v, float angle, vec2 dest) {
  542. float c, s, x1, y1;
  543. c = cosf(angle);
  544. s = sinf(angle);
  545. x1 = v[0];
  546. y1 = v[1];
  547. dest[0] = c * x1 - s * y1;
  548. dest[1] = s * x1 + c * y1;
  549. }
  550. /**
  551. * @brief find center point of two vector
  552. *
  553. * @param[in] a vector1
  554. * @param[in] b vector2
  555. * @param[out] dest center point
  556. */
  557. CGLM_INLINE
  558. void
  559. glm_vec2_center(vec2 a, vec2 b, vec2 dest) {
  560. glm_vec2_add(a, b, dest);
  561. glm_vec2_scale(dest, 0.5f, dest);
  562. }
  563. /**
  564. * @brief squared distance between two vectors
  565. *
  566. * @param[in] a vector1
  567. * @param[in] b vector2
  568. * @return returns squared distance (distance * distance)
  569. */
  570. CGLM_INLINE
  571. float
  572. glm_vec2_distance2(vec2 a, vec2 b) {
  573. return glm_pow2(b[0] - a[0]) + glm_pow2(b[1] - a[1]);
  574. }
  575. /**
  576. * @brief distance between two vectors
  577. *
  578. * @param[in] a vector1
  579. * @param[in] b vector2
  580. * @return returns distance
  581. */
  582. CGLM_INLINE
  583. float
  584. glm_vec2_distance(vec2 a, vec2 b) {
  585. return sqrtf(glm_vec2_distance2(a, b));
  586. }
  587. /*!
  588. * @brief max values of vectors
  589. *
  590. * @param[in] a vector1
  591. * @param[in] b vector2
  592. * @param[out] dest destination
  593. */
  594. CGLM_INLINE
  595. void
  596. glm_vec2_maxv(vec2 a, vec2 b, vec2 dest) {
  597. dest[0] = glm_max(a[0], b[0]);
  598. dest[1] = glm_max(a[1], b[1]);
  599. }
  600. /*!
  601. * @brief min values of vectors
  602. *
  603. * @param[in] a vector1
  604. * @param[in] b vector2
  605. * @param[out] dest destination
  606. */
  607. CGLM_INLINE
  608. void
  609. glm_vec2_minv(vec2 a, vec2 b, vec2 dest) {
  610. dest[0] = glm_min(a[0], b[0]);
  611. dest[1] = glm_min(a[1], b[1]);
  612. }
  613. /*!
  614. * @brief clamp vector's individual members between min and max values
  615. *
  616. * @param[in, out] v vector
  617. * @param[in] minval minimum value
  618. * @param[in] maxval maximum value
  619. */
  620. CGLM_INLINE
  621. void
  622. glm_vec2_clamp(vec2 v, float minval, float maxval) {
  623. v[0] = glm_clamp(v[0], minval, maxval);
  624. v[1] = glm_clamp(v[1], minval, maxval);
  625. }
  626. /*!
  627. * @brief swizzle vector components
  628. *
  629. * @param[in] v source
  630. * @param[in] mask mask
  631. * @param[out] dest destination
  632. */
  633. CGLM_INLINE
  634. void
  635. glm_vec2_swizzle(vec2 v, int mask, vec2 dest) {
  636. vec2 t;
  637. t[0] = v[(mask & (3 << 0))];
  638. t[1] = v[(mask & (3 << 2)) >> 2];
  639. glm_vec2_copy(t, dest);
  640. }
  641. /*!
  642. * @brief linear interpolation between two vector
  643. *
  644. * formula: from + s * (to - from)
  645. *
  646. * @param[in] from from value
  647. * @param[in] to to value
  648. * @param[in] t interpolant (amount) clamped between 0 and 1
  649. * @param[out] dest destination
  650. */
  651. CGLM_INLINE
  652. void
  653. glm_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest) {
  654. vec2 s, v;
  655. /* from + s * (to - from) */
  656. glm_vec2_fill(s, glm_clamp_zo(t));
  657. glm_vec2_sub(to, from, v);
  658. glm_vec2_mul(s, v, v);
  659. glm_vec2_add(from, v, dest);
  660. }
  661. /*!
  662. * @brief threshold function
  663. *
  664. * @param[in] edge threshold
  665. * @param[in] x value to test against threshold
  666. * @param[out] dest destination
  667. */
  668. CGLM_INLINE
  669. void
  670. glm_vec2_step(vec2 edge, vec2 x, vec2 dest) {
  671. dest[0] = glm_step(edge[0], x[0]);
  672. dest[1] = glm_step(edge[1], x[1]);
  673. }
  674. /*!
  675. * @brief Create two dimensional vector from pointer
  676. *
  677. * @param[in] src pointer to an array of floats
  678. * @param[out] dest destination vector
  679. */
  680. CGLM_INLINE
  681. void
  682. glm_vec2_make(const float * __restrict src, vec2 dest) {
  683. dest[0] = src[0]; dest[1] = src[1];
  684. }
  685. /*!
  686. * @brief reflection vector using an incident ray and a surface normal
  687. *
  688. * @param[in] v incident vector
  689. * @param[in] n normalized normal vector
  690. * @param[out] dest destination vector for the reflection result
  691. */
  692. CGLM_INLINE
  693. void
  694. glm_vec2_reflect(vec2 v, vec2 n, vec2 dest) {
  695. vec2 temp;
  696. glm_vec2_scale(n, 2.0f * glm_vec2_dot(v, n), temp);
  697. glm_vec2_sub(v, temp, dest);
  698. }
  699. /*!
  700. * @brief computes refraction vector for an incident vector and a surface normal.
  701. *
  702. * calculates the refraction vector based on Snell's law. If total internal reflection
  703. * occurs (angle too great given eta), dest is set to zero and returns false.
  704. * Otherwise, computes refraction vector, stores it in dest, and returns true.
  705. *
  706. * @param[in] v normalized incident vector
  707. * @param[in] n normalized normal vector
  708. * @param[in] eta ratio of indices of refraction (incident/transmitted)
  709. * @param[out] dest refraction vector if refraction occurs; zero vector otherwise
  710. *
  711. * @returns true if refraction occurs; false if total internal reflection occurs.
  712. */
  713. CGLM_INLINE
  714. bool
  715. glm_vec2_refract(vec2 v, vec2 n, float eta, vec2 dest) {
  716. float ndi, eni, k;
  717. ndi = glm_vec2_dot(n, v);
  718. eni = eta * ndi;
  719. k = 1.0f - eta * eta + eni * eni;
  720. if (k < 0.0f) {
  721. glm_vec2_zero(dest);
  722. return false;
  723. }
  724. glm_vec2_scale(v, eta, dest);
  725. glm_vec2_mulsubs(n, eni + sqrtf(k), dest);
  726. return true;
  727. }
  728. #endif /* cglm_vec2_h */