summaryrefslogtreecommitdiff
path: root/include/cglm/struct/frustum.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/cglm/struct/frustum.h')
-rw-r--r--include/cglm/struct/frustum.h155
1 files changed, 155 insertions, 0 deletions
diff --git a/include/cglm/struct/frustum.h b/include/cglm/struct/frustum.h
new file mode 100644
index 0000000..81b5b7b
--- /dev/null
+++ b/include/cglm/struct/frustum.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#ifndef cglms_frustums_h
+#define cglms_frustums_h
+
+#include "../common.h"
+#include "../types-struct.h"
+#include "../frustum.h"
+#include "plane.h"
+#include "vec3.h"
+#include "vec4.h"
+#include "mat4.h"
+
+/* you can override clip space coords
+ but you have to provide all with same name
+ e.g.: define GLM_CSCOORD_LBN {0.0f, 0.0f, 1.0f, 1.0f} */
+#ifndef GLM_CUSTOM_CLIPSPACE
+
+/* near */
+#define GLMS_CSCOORD_LBN {-1.0f, -1.0f, -1.0f, 1.0f}
+#define GLMS_CSCOORD_LTN {-1.0f, 1.0f, -1.0f, 1.0f}
+#define GLMS_CSCOORD_RTN { 1.0f, 1.0f, -1.0f, 1.0f}
+#define GLMS_CSCOORD_RBN { 1.0f, -1.0f, -1.0f, 1.0f}
+
+/* far */
+#define GLMS_CSCOORD_LBF {-1.0f, -1.0f, 1.0f, 1.0f}
+#define GLMS_CSCOORD_LTF {-1.0f, 1.0f, 1.0f, 1.0f}
+#define GLMS_CSCOORD_RTF { 1.0f, 1.0f, 1.0f, 1.0f}
+#define GLMS_CSCOORD_RBF { 1.0f, -1.0f, 1.0f, 1.0f}
+
+#endif
+
+/*!
+ * @brief extracts view frustum planes
+ *
+ * planes' space:
+ * 1- if m = proj: View Space
+ * 2- if m = viewProj: World Space
+ * 3- if m = MVP: Object Space
+ *
+ * You probably want to extract planes in world space so use viewProj as m
+ * Computing viewProj:
+ * glm_mat4_mul(proj, view, viewProj);
+ *
+ * Exracted planes order: [left, right, bottom, top, near, far]
+ *
+ * @param[in] m matrix (see brief)
+ * @param[out] dest extracted view frustum planes (see brief)
+ */
+CGLM_INLINE
+void
+glms_frustum_planes(mat4s m, vec4s dest[6]) {
+ vec4 rawDest[6];
+ glm_frustum_planes(m.raw, rawDest);
+ glms_vec4_(pack)(dest, rawDest, 6);
+}
+
+/*!
+ * @brief extracts view frustum corners using clip-space coordinates
+ *
+ * corners' space:
+ * 1- if m = invViewProj: World Space
+ * 2- if m = invMVP: Object Space
+ *
+ * You probably want to extract corners in world space so use invViewProj
+ * Computing invViewProj:
+ * glm_mat4_mul(proj, view, viewProj);
+ * ...
+ * glm_mat4_inv(viewProj, invViewProj);
+ *
+ * if you have a near coord at i index, you can get it's far coord by i + 4
+ *
+ * Find center coordinates:
+ * for (j = 0; j < 4; j++) {
+ * glm_vec3_center(corners[i], corners[i + 4], centerCorners[i]);
+ * }
+ *
+ * @param[in] invMat matrix (see brief)
+ * @param[out] dest exracted view frustum corners (see brief)
+ */
+CGLM_INLINE
+void
+glms_frustum_corners(mat4s invMat, vec4s dest[8]) {
+ vec4 rawDest[8];
+ glm_frustum_corners(invMat.raw, rawDest);
+ glms_vec4_(pack)(dest, rawDest, 8);
+}
+
+/*!
+ * @brief finds center of view frustum
+ *
+ * @param[in] corners view frustum corners
+ * @returns view frustum center
+ */
+CGLM_INLINE
+vec4s
+glms_frustum_center(vec4s corners[8]) {
+ vec4 rawCorners[8];
+ vec4s r;
+
+ glms_vec4_(unpack)(rawCorners, corners, 8);
+ glm_frustum_center(rawCorners, r.raw);
+ return r;
+}
+
+/*!
+ * @brief finds bounding box of frustum relative to given matrix e.g. view mat
+ *
+ * @param[in] corners view frustum corners
+ * @param[in] m matrix to convert existing conners
+ * @param[out] box bounding box as array [min, max]
+ */
+CGLM_INLINE
+void
+glms_frustum_box(vec4s corners[8], mat4s m, vec3s box[2]) {
+ vec4 rawCorners[8];
+ vec3 rawBox[2];
+
+ glms_vec4_(unpack)(rawCorners, corners, 8);
+ glm_frustum_box(rawCorners, m.raw, rawBox);
+ glms_vec3_(pack)(box, rawBox, 2);
+}
+
+/*!
+ * @brief finds planes corners which is between near and far planes (parallel)
+ *
+ * this will be helpful if you want to split a frustum e.g. CSM/PSSM. This will
+ * find planes' corners but you will need to one more plane.
+ * Actually you have it, it is near, far or created previously with this func ;)
+ *
+ * @param[in] corners view frustum corners
+ * @param[in] splitDist split distance
+ * @param[in] farDist far distance (zFar)
+ * @param[out] planeCorners plane corners [LB, LT, RT, RB]
+ */
+CGLM_INLINE
+void
+glms_frustum_corners_at(vec4s corners[8],
+ float splitDist,
+ float farDist,
+ vec4s planeCorners[4]) {
+ vec4 rawCorners[8];
+ vec4 rawPlaneCorners[4];
+
+ glms_vec4_(unpack)(rawCorners, corners, 8);
+ glm_frustum_corners_at(rawCorners, splitDist, farDist, rawPlaneCorners);
+ glms_vec4_(pack)(planeCorners, rawPlaneCorners, 8);
+}
+
+#endif /* cglms_frustums_h */