persp_lh_no.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  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. Functions:
  9. CGLM_INLINE void glm_frustum_lh_no(float left, float right,
  10. float bottom, float top,
  11. float nearZ, float farZ,
  12. mat4 dest)
  13. CGLM_INLINE void glm_perspective_lh_no(float fovy,
  14. float aspect,
  15. float nearZ,
  16. float farZ,
  17. mat4 dest)
  18. CGLM_INLINE void glm_perspective_default_lh_no(float aspect, mat4 dest)
  19. CGLM_INLINE void glm_perspective_resize_lh_no(float aspect, mat4 proj)
  20. CGLM_INLINE void glm_persp_move_far_lh_no(mat4 proj,
  21. float deltaFar)
  22. CGLM_INLINE void glm_persp_decomp_lh_no(mat4 proj,
  23. float * __restrict nearZ,
  24. float * __restrict farZ,
  25. float * __restrict top,
  26. float * __restrict bottom,
  27. float * __restrict left,
  28. float * __restrict right)
  29. CGLM_INLINE void glm_persp_decompv_lh_no(mat4 proj,
  30. float dest[6])
  31. CGLM_INLINE void glm_persp_decomp_x_lh_no(mat4 proj,
  32. float * __restrict left,
  33. float * __restrict right)
  34. CGLM_INLINE void glm_persp_decomp_y_lh_no(mat4 proj,
  35. float * __restrict top,
  36. float * __restrict bottom)
  37. CGLM_INLINE void glm_persp_decomp_z_lh_no(mat4 proj,
  38. float * __restrict nearZ,
  39. float * __restrict farZ)
  40. CGLM_INLINE void glm_persp_decomp_far_lh_no(mat4 proj, float * __restrict farZ)
  41. CGLM_INLINE void glm_persp_decomp_near_lh_no(mat4 proj, float * __restrict nearZ)
  42. CGLM_INLINE void glm_persp_sizes_lh_no(mat4 proj, float fovy, vec4 dest)
  43. */
  44. #ifndef cglm_persp_lh_no_h
  45. #define cglm_persp_lh_no_h
  46. #include "../common.h"
  47. #include "persp.h"
  48. /*!
  49. * @brief set up perspective peprojection matrix
  50. * with a left-hand coordinate system and a
  51. * clip-space of [-1, 1].
  52. *
  53. * @param[in] left viewport.left
  54. * @param[in] right viewport.right
  55. * @param[in] bottom viewport.bottom
  56. * @param[in] top viewport.top
  57. * @param[in] nearZ near clipping plane
  58. * @param[in] farZ far clipping plane
  59. * @param[out] dest result matrix
  60. */
  61. CGLM_INLINE
  62. void
  63. glm_frustum_lh_no(float left, float right,
  64. float bottom, float top,
  65. float nearZ, float farZ,
  66. mat4 dest) {
  67. float rl, tb, fn, nv;
  68. glm_mat4_zero(dest);
  69. rl = 1.0f / (right - left);
  70. tb = 1.0f / (top - bottom);
  71. fn =-1.0f / (farZ - nearZ);
  72. nv = 2.0f * nearZ;
  73. dest[0][0] = nv * rl;
  74. dest[1][1] = nv * tb;
  75. dest[2][0] = (right + left) * rl;
  76. dest[2][1] = (top + bottom) * tb;
  77. dest[2][2] =-(farZ + nearZ) * fn;
  78. dest[2][3] = 1.0f;
  79. dest[3][2] = farZ * nv * fn;
  80. }
  81. /*!
  82. * @brief set up perspective projection matrix
  83. * with a left-hand coordinate system and a
  84. * clip-space of [-1, 1].
  85. *
  86. * @param[in] fovy field of view angle
  87. * @param[in] aspect aspect ratio ( width / height )
  88. * @param[in] nearZ near clipping plane
  89. * @param[in] farZ far clipping planes
  90. * @param[out] dest result matrix
  91. */
  92. CGLM_INLINE
  93. void
  94. glm_perspective_lh_no(float fovy,
  95. float aspect,
  96. float nearZ,
  97. float farZ,
  98. mat4 dest) {
  99. float f, fn;
  100. glm_mat4_zero(dest);
  101. f = 1.0f / tanf(fovy * 0.5f);
  102. fn = 1.0f / (nearZ - farZ);
  103. dest[0][0] = f / aspect;
  104. dest[1][1] = f;
  105. dest[2][2] =-(nearZ + farZ) * fn;
  106. dest[2][3] = 1.0f;
  107. dest[3][2] = 2.0f * nearZ * farZ * fn;
  108. }
  109. /*!
  110. * @brief set up perspective projection matrix with default near/far
  111. * and angle values with a left-hand coordinate system and a
  112. * clip-space of [-1, 1].
  113. *
  114. * @param[in] aspect aspect ratio ( width / height )
  115. * @param[out] dest result matrix
  116. */
  117. CGLM_INLINE
  118. void
  119. glm_perspective_default_lh_no(float aspect, mat4 dest) {
  120. glm_perspective_lh_no(GLM_PI_4f, aspect, 0.01f, 100.0f, dest);
  121. }
  122. /*!
  123. * @brief resize perspective matrix by aspect ratio ( width / height )
  124. * this makes very easy to resize proj matrix when window /viewport
  125. * resized with a left-hand coordinate system and a
  126. * clip-space of [-1, 1].
  127. *
  128. * @param[in] aspect aspect ratio ( width / height )
  129. * @param[in, out] proj perspective projection matrix
  130. */
  131. CGLM_INLINE
  132. void
  133. glm_perspective_resize_lh_no(float aspect, mat4 proj) {
  134. if (proj[0][0] == 0.0f)
  135. return;
  136. proj[0][0] = proj[1][1] / aspect;
  137. }
  138. /*!
  139. * @brief extend perspective projection matrix's far distance
  140. * with a left-hand coordinate system and a
  141. * clip-space of [-1, 1].
  142. *
  143. * this function does not guarantee far >= near, be aware of that!
  144. *
  145. * @param[in, out] proj projection matrix to extend
  146. * @param[in] deltaFar distance from existing far (negative to shink)
  147. */
  148. CGLM_INLINE
  149. void
  150. glm_persp_move_far_lh_no(mat4 proj, float deltaFar) {
  151. float fn, farZ, nearZ, p22, p32;
  152. p22 = -proj[2][2];
  153. p32 = proj[3][2];
  154. nearZ = p32 / (p22 - 1.0f);
  155. farZ = p32 / (p22 + 1.0f) + deltaFar;
  156. fn = 1.0f / (nearZ - farZ);
  157. proj[2][2] = -(farZ + nearZ) * fn;
  158. proj[3][2] = 2.0f * nearZ * farZ * fn;
  159. }
  160. /*!
  161. * @brief decomposes frustum values of perspective projection
  162. * with a left-hand coordinate system and a
  163. * clip-space of [-1, 1].
  164. *
  165. * @param[in] proj perspective projection matrix
  166. * @param[out] nearZ near
  167. * @param[out] farZ far
  168. * @param[out] top top
  169. * @param[out] bottom bottom
  170. * @param[out] left left
  171. * @param[out] right right
  172. */
  173. CGLM_INLINE
  174. void
  175. glm_persp_decomp_lh_no(mat4 proj,
  176. float * __restrict nearZ, float * __restrict farZ,
  177. float * __restrict top, float * __restrict bottom,
  178. float * __restrict left, float * __restrict right) {
  179. float m00, m11, m20, m21, m22, m32, n, f;
  180. float n_m11, n_m00;
  181. m00 = proj[0][0];
  182. m11 = proj[1][1];
  183. m20 = proj[2][0];
  184. m21 = proj[2][1];
  185. m22 =-proj[2][2];
  186. m32 = proj[3][2];
  187. n = m32 / (m22 - 1.0f);
  188. f = m32 / (m22 + 1.0f);
  189. n_m11 = n / m11;
  190. n_m00 = n / m00;
  191. *nearZ = n;
  192. *farZ = f;
  193. *bottom = n_m11 * (m21 - 1.0f);
  194. *top = n_m11 * (m21 + 1.0f);
  195. *left = n_m00 * (m20 - 1.0f);
  196. *right = n_m00 * (m20 + 1.0f);
  197. }
  198. /*!
  199. * @brief decomposes frustum values of perspective projection
  200. * with a left-hand coordinate system and a
  201. * clip-space of [-1, 1].
  202. * this makes easy to get all values at once
  203. *
  204. * @param[in] proj perspective projection matrix
  205. * @param[out] dest array
  206. */
  207. CGLM_INLINE
  208. void
  209. glm_persp_decompv_lh_no(mat4 proj, float dest[6]) {
  210. glm_persp_decomp_lh_no(proj, &dest[0], &dest[1], &dest[2],
  211. &dest[3], &dest[4], &dest[5]);
  212. }
  213. /*!
  214. * @brief decomposes left and right values of perspective projection
  215. * with a left-hand coordinate system and a
  216. * clip-space of [-1, 1].
  217. * x stands for x axis (left / right axis)
  218. *
  219. * @param[in] proj perspective projection matrix
  220. * @param[out] left left
  221. * @param[out] right right
  222. */
  223. CGLM_INLINE
  224. void
  225. glm_persp_decomp_x_lh_no(mat4 proj,
  226. float * __restrict left,
  227. float * __restrict right) {
  228. float nearZ, m20, m00, m22;
  229. m00 = proj[0][0];
  230. m20 = proj[2][0];
  231. m22 =-proj[2][2];
  232. nearZ = proj[3][2] / (m22 - 1.0f);
  233. *left = nearZ * (m20 - 1.0f) / m00;
  234. *right = nearZ * (m20 + 1.0f) / m00;
  235. }
  236. /*!
  237. * @brief decomposes top and bottom values of perspective projection
  238. * with a left-hand coordinate system and a
  239. * clip-space of [-1, 1].
  240. * y stands for y axis (top / bottom axis)
  241. *
  242. * @param[in] proj perspective projection matrix
  243. * @param[out] top top
  244. * @param[out] bottom bottom
  245. */
  246. CGLM_INLINE
  247. void
  248. glm_persp_decomp_y_lh_no(mat4 proj,
  249. float * __restrict top,
  250. float * __restrict bottom) {
  251. float nearZ, m21, m11, m22;
  252. m21 = proj[2][1];
  253. m11 = proj[1][1];
  254. m22 =-proj[2][2];
  255. nearZ = proj[3][2] / (m22 - 1.0f);
  256. *bottom = nearZ * (m21 - 1.0f) / m11;
  257. *top = nearZ * (m21 + 1.0f) / m11;
  258. }
  259. /*!
  260. * @brief decomposes near and far values of perspective projection
  261. * with a left-hand coordinate system and a
  262. * clip-space of [-1, 1].
  263. * z stands for z axis (near / far axis)
  264. *
  265. * @param[in] proj perspective projection matrix
  266. * @param[out] nearZ near
  267. * @param[out] farZ far
  268. */
  269. CGLM_INLINE
  270. void
  271. glm_persp_decomp_z_lh_no(mat4 proj,
  272. float * __restrict nearZ,
  273. float * __restrict farZ) {
  274. float m32, m22;
  275. m32 = proj[3][2];
  276. m22 =-proj[2][2];
  277. *nearZ = m32 / (m22 - 1.0f);
  278. *farZ = m32 / (m22 + 1.0f);
  279. }
  280. /*!
  281. * @brief decomposes far value of perspective projection
  282. * with a left-hand coordinate system and a
  283. * clip-space of [-1, 1].
  284. *
  285. * @param[in] proj perspective projection matrix
  286. * @param[out] farZ far
  287. */
  288. CGLM_INLINE
  289. void
  290. glm_persp_decomp_far_lh_no(mat4 proj, float * __restrict farZ) {
  291. *farZ = proj[3][2] / (-proj[2][2] + 1.0f);
  292. }
  293. /*!
  294. * @brief decomposes near value of perspective projection
  295. * with a left-hand coordinate system and a
  296. * clip-space of [-1, 1].
  297. *
  298. * @param[in] proj perspective projection matrix
  299. * @param[out] nearZ near
  300. */
  301. CGLM_INLINE
  302. void
  303. glm_persp_decomp_near_lh_no(mat4 proj, float * __restrict nearZ) {
  304. *nearZ = proj[3][2] / (-proj[2][2] - 1.0f);
  305. }
  306. /*!
  307. * @brief returns sizes of near and far planes of perspective projection
  308. * with a left-hand coordinate system and a
  309. * clip-space of [-1, 1].
  310. *
  311. * @param[in] proj perspective projection matrix
  312. * @param[in] fovy fovy (see brief)
  313. * @param[out] dest sizes order: [Wnear, Hnear, Wfar, Hfar]
  314. */
  315. CGLM_INLINE
  316. void
  317. glm_persp_sizes_lh_no(mat4 proj, float fovy, vec4 dest) {
  318. float t, a, nearZ, farZ;
  319. t = 2.0f * tanf(fovy * 0.5f);
  320. a = glm_persp_aspect(proj);
  321. glm_persp_decomp_z_lh_no(proj, &nearZ, &farZ);
  322. dest[1] = t * nearZ;
  323. dest[3] = t * farZ;
  324. dest[0] = a * dest[1];
  325. dest[2] = a * dest[3];
  326. }
  327. /*!
  328. * @brief returns field of view angle along the Y-axis (in radians)
  329. * with a left-hand coordinate system and a clip-space of [-1, 1].
  330. *
  331. * if you need to degrees, use glm_deg to convert it or use this:
  332. * fovy_deg = glm_deg(glm_persp_fovy(projMatrix))
  333. *
  334. * @param[in] proj perspective projection matrix
  335. */
  336. CGLM_INLINE
  337. float
  338. glm_persp_fovy_lh_no(mat4 proj) {
  339. return glm_persp_fovy(proj);
  340. }
  341. /*!
  342. * @brief returns aspect ratio of perspective projection
  343. * with a left-hand coordinate system and a clip-space of [-1, 1].
  344. *
  345. * @param[in] proj perspective projection matrix
  346. */
  347. CGLM_INLINE
  348. float
  349. glm_persp_aspect_lh_no(mat4 proj) {
  350. return glm_persp_aspect(proj);
  351. }
  352. #endif /*cglm_cam_lh_no_h*/