frustum.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. #ifndef cglms_frustums_h
  8. #define cglms_frustums_h
  9. #include "../common.h"
  10. #include "../types-struct.h"
  11. #include "../frustum.h"
  12. #include "plane.h"
  13. #include "vec3.h"
  14. #include "vec4.h"
  15. #include "mat4.h"
  16. /* you can override clip space coords
  17. but you have to provide all with same name
  18. e.g.: define GLM_CSCOORD_LBN {0.0f, 0.0f, 1.0f, 1.0f} */
  19. #ifndef GLM_CUSTOM_CLIPSPACE
  20. /* near */
  21. #define GLMS_CSCOORD_LBN {-1.0f, -1.0f, -1.0f, 1.0f}
  22. #define GLMS_CSCOORD_LTN {-1.0f, 1.0f, -1.0f, 1.0f}
  23. #define GLMS_CSCOORD_RTN { 1.0f, 1.0f, -1.0f, 1.0f}
  24. #define GLMS_CSCOORD_RBN { 1.0f, -1.0f, -1.0f, 1.0f}
  25. /* far */
  26. #define GLMS_CSCOORD_LBF {-1.0f, -1.0f, 1.0f, 1.0f}
  27. #define GLMS_CSCOORD_LTF {-1.0f, 1.0f, 1.0f, 1.0f}
  28. #define GLMS_CSCOORD_RTF { 1.0f, 1.0f, 1.0f, 1.0f}
  29. #define GLMS_CSCOORD_RBF { 1.0f, -1.0f, 1.0f, 1.0f}
  30. #endif
  31. /*!
  32. * @brief extracts view frustum planes
  33. *
  34. * planes' space:
  35. * 1- if m = proj: View Space
  36. * 2- if m = viewProj: World Space
  37. * 3- if m = MVP: Object Space
  38. *
  39. * You probably want to extract planes in world space so use viewProj as m
  40. * Computing viewProj:
  41. * glm_mat4_mul(proj, view, viewProj);
  42. *
  43. * Exracted planes order: [left, right, bottom, top, near, far]
  44. *
  45. * @param[in] m matrix (see brief)
  46. * @param[out] dest extracted view frustum planes (see brief)
  47. */
  48. CGLM_INLINE
  49. void
  50. glms_frustum_planes(mat4s m, vec4s dest[6]) {
  51. vec4 rawDest[6];
  52. glm_frustum_planes(m.raw, rawDest);
  53. glms_vec4_(pack)(dest, rawDest, 6);
  54. }
  55. /*!
  56. * @brief extracts view frustum corners using clip-space coordinates
  57. *
  58. * corners' space:
  59. * 1- if m = invViewProj: World Space
  60. * 2- if m = invMVP: Object Space
  61. *
  62. * You probably want to extract corners in world space so use invViewProj
  63. * Computing invViewProj:
  64. * glm_mat4_mul(proj, view, viewProj);
  65. * ...
  66. * glm_mat4_inv(viewProj, invViewProj);
  67. *
  68. * if you have a near coord at i index, you can get it's far coord by i + 4
  69. *
  70. * Find center coordinates:
  71. * for (j = 0; j < 4; j++) {
  72. * glm_vec3_center(corners[i], corners[i + 4], centerCorners[i]);
  73. * }
  74. *
  75. * @param[in] invMat matrix (see brief)
  76. * @param[out] dest exracted view frustum corners (see brief)
  77. */
  78. CGLM_INLINE
  79. void
  80. glms_frustum_corners(mat4s invMat, vec4s dest[8]) {
  81. vec4 rawDest[8];
  82. glm_frustum_corners(invMat.raw, rawDest);
  83. glms_vec4_(pack)(dest, rawDest, 8);
  84. }
  85. /*!
  86. * @brief finds center of view frustum
  87. *
  88. * @param[in] corners view frustum corners
  89. * @returns view frustum center
  90. */
  91. CGLM_INLINE
  92. vec4s
  93. glms_frustum_center(vec4s corners[8]) {
  94. vec4 rawCorners[8];
  95. vec4s r;
  96. glms_vec4_(unpack)(rawCorners, corners, 8);
  97. glm_frustum_center(rawCorners, r.raw);
  98. return r;
  99. }
  100. /*!
  101. * @brief finds bounding box of frustum relative to given matrix e.g. view mat
  102. *
  103. * @param[in] corners view frustum corners
  104. * @param[in] m matrix to convert existing conners
  105. * @param[out] box bounding box as array [min, max]
  106. */
  107. CGLM_INLINE
  108. void
  109. glms_frustum_box(vec4s corners[8], mat4s m, vec3s box[2]) {
  110. vec4 rawCorners[8];
  111. vec3 rawBox[2];
  112. glms_vec4_(unpack)(rawCorners, corners, 8);
  113. glm_frustum_box(rawCorners, m.raw, rawBox);
  114. glms_vec3_(pack)(box, rawBox, 2);
  115. }
  116. /*!
  117. * @brief finds planes corners which is between near and far planes (parallel)
  118. *
  119. * this will be helpful if you want to split a frustum e.g. CSM/PSSM. This will
  120. * find planes' corners but you will need to one more plane.
  121. * Actually you have it, it is near, far or created previously with this func ;)
  122. *
  123. * @param[in] corners view frustum corners
  124. * @param[in] splitDist split distance
  125. * @param[in] farDist far distance (zFar)
  126. * @param[out] planeCorners plane corners [LB, LT, RT, RB]
  127. */
  128. CGLM_INLINE
  129. void
  130. glms_frustum_corners_at(vec4s corners[8],
  131. float splitDist,
  132. float farDist,
  133. vec4s planeCorners[4]) {
  134. vec4 rawCorners[8];
  135. vec4 rawPlaneCorners[4];
  136. glms_vec4_(unpack)(rawCorners, corners, 8);
  137. glm_frustum_corners_at(rawCorners, splitDist, farDist, rawPlaneCorners);
  138. glms_vec4_(pack)(planeCorners, rawPlaneCorners, 8);
  139. }
  140. #endif /* cglms_frustums_h */