From 2349bbff315910a2909a9deb93f7bd94e651840f Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Fri, 12 Jan 2018 15:21:36 +0300 Subject: [PATCH 1/6] move frustum related stuff to frustum header * create helpers macro which defines corner index * func for get bounding box frustum * add missing source to make file * add more desc to glm_frustum_corners --- include/cglm/call.h | 1 + include/cglm/call/cam.h | 12 --- include/cglm/call/frustum.h | 35 +++++++ include/cglm/cam.h | 112 ----------------------- include/cglm/cglm.h | 1 + include/cglm/frustum.h | 176 ++++++++++++++++++++++++++++++++++++ makefile.am | 4 +- src/cam.c | 18 ---- src/frustum.c | 33 +++++++ 9 files changed, 249 insertions(+), 143 deletions(-) create mode 100644 include/cglm/call/frustum.h create mode 100644 include/cglm/frustum.h create mode 100644 src/frustum.c diff --git a/include/cglm/call.h b/include/cglm/call.h index c306ab9..00eb13c 100644 --- a/include/cglm/call.h +++ b/include/cglm/call.h @@ -21,6 +21,7 @@ extern "C" { #include "call/quat.h" #include "call/euler.h" #include "call/plane.h" +#include "call/frustum.h" #include "call/io.h" #ifdef __cplusplus diff --git a/include/cglm/call/cam.h b/include/cglm/call/cam.h index dc01f6f..35fb18d 100644 --- a/include/cglm/call/cam.h +++ b/include/cglm/call/cam.h @@ -53,18 +53,6 @@ CGLM_EXPORT void glmc_look_anyup(vec3 eye, vec3 dir, mat4 dest); -CGLM_EXPORT -void -glmc_frustum_planes(mat4 m, vec4 dest[6]); - -CGLM_EXPORT -void -glmc_frustum_corners(mat4 invMat, vec4 dest[8]); - -CGLM_EXPORT -void -glmc_frustum_center(vec4 corners[8], vec4 dest); - #ifdef __cplusplus } #endif diff --git a/include/cglm/call/frustum.h b/include/cglm/call/frustum.h new file mode 100644 index 0000000..066ed40 --- /dev/null +++ b/include/cglm/call/frustum.h @@ -0,0 +1,35 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglmc_frustum_h +#define cglmc_frustum_h +#ifdef __cplusplus +extern "C" { +#endif + +#include "../cglm.h" + +CGLM_EXPORT +void +glmc_frustum_planes(mat4 m, vec4 dest[6]); + +CGLM_EXPORT +void +glmc_frustum_corners(mat4 invMat, vec4 dest[8]); + +CGLM_EXPORT +void +glmc_frustum_center(vec4 corners[8], vec4 dest); + +CGLM_EXPORT +void +glmc_frustum_box(vec4 corners[8], mat4 m, vec3 box[2]); + +#ifdef __cplusplus +} +#endif +#endif /* cglmc_frustum_h */ diff --git a/include/cglm/cam.h b/include/cglm/cam.h index 23504cc..0d13a3d 100644 --- a/include/cglm/cam.h +++ b/include/cglm/cam.h @@ -541,116 +541,4 @@ glm_persp_sizes(mat4 proj, float fovy, vec4 dest) { dest[2] = a * dest[3]; } -/*! - * @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 exracted view frustum planes (see brief) - */ -CGLM_INLINE -void -glm_frustum_planes(mat4 m, vec4 dest[6]) { - mat4 t; - - glm_mat4_transpose_to(m, t); - - glm_vec4_add(t[3], t[0], dest[0]); /* left */ - glm_vec4_sub(t[3], t[0], dest[1]); /* right */ - glm_vec4_add(t[3], t[1], dest[2]); /* bottom */ - glm_vec4_sub(t[3], t[1], dest[3]); /* top */ - glm_vec4_add(t[3], t[2], dest[4]); /* near */ - glm_vec4_sub(t[3], t[2], dest[5]); /* far */ - - glm_plane_normalize(dest[0]); - glm_plane_normalize(dest[1]); - glm_plane_normalize(dest[2]); - glm_plane_normalize(dest[3]); - glm_plane_normalize(dest[4]); - glm_plane_normalize(dest[5]); -} - -/*! - * @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); - * - * @param[in] invMat matrix (see brief) - * @param[out] dest exracted view frustum corners (see brief) - */ -CGLM_INLINE -void -glm_frustum_corners(mat4 invMat, vec4 dest[8]) { - vec4 c[8]; - vec4 csCoords[8] = { - {-1.0f, -1.0f, -1.0f, 1.0f}, - {-1.0f, 1.0f, -1.0f, 1.0f}, - { 1.0f, -1.0f, -1.0f, 1.0f}, - { 1.0f, 1.0f, -1.0f, 1.0f}, - {-1.0f, -1.0f, 1.0f, 1.0f}, - {-1.0f, 1.0f, 1.0f, 1.0f}, - { 1.0f, -1.0f, 1.0f, 1.0f}, - { 1.0f, 1.0f, 1.0f, 1.0f} - }; - - glm_mat4_mulv(invMat, csCoords[0], c[0]); - glm_mat4_mulv(invMat, csCoords[1], c[1]); - glm_mat4_mulv(invMat, csCoords[2], c[2]); - glm_mat4_mulv(invMat, csCoords[3], c[3]); - glm_mat4_mulv(invMat, csCoords[4], c[4]); - glm_mat4_mulv(invMat, csCoords[5], c[5]); - glm_mat4_mulv(invMat, csCoords[6], c[6]); - glm_mat4_mulv(invMat, csCoords[7], c[7]); - - glm_vec4_scale(c[1], 1.0f / c[1][3], dest[1]); - glm_vec4_scale(c[2], 1.0f / c[2][3], dest[2]); - glm_vec4_scale(c[3], 1.0f / c[3][3], dest[3]); - glm_vec4_scale(c[4], 1.0f / c[4][3], dest[4]); - glm_vec4_scale(c[5], 1.0f / c[5][3], dest[5]); - glm_vec4_scale(c[6], 1.0f / c[6][3], dest[6]); - glm_vec4_scale(c[7], 1.0f / c[7][3], dest[7]); -} - -/*! - * @brief finds center of view frustum - * - * @param[in] corners view frustum corners - * @param[out] dest view frustum center - */ -CGLM_INLINE -void -glm_frustum_center(vec4 corners[8], vec4 dest) { - vec4 center; - - glm_vec4_copy(corners[0], center); - - glm_vec4_add(corners[1], center, center); - glm_vec4_add(corners[2], center, center); - glm_vec4_add(corners[3], center, center); - glm_vec4_add(corners[4], center, center); - glm_vec4_add(corners[5], center, center); - glm_vec4_add(corners[6], center, center); - glm_vec4_add(corners[7], center, center); - - glm_vec4_scale(center, 0.125f, dest); -} - #endif /* cglm_vcam_h */ diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h index 24544d1..e9fa774 100644 --- a/include/cglm/cglm.h +++ b/include/cglm/cglm.h @@ -15,6 +15,7 @@ #include "mat3.h" #include "affine.h" #include "cam.h" +#include "frustum.h" #include "quat.h" #include "euler.h" #include "plane.h" diff --git a/include/cglm/frustum.h b/include/cglm/frustum.h new file mode 100644 index 0000000..74a1769 --- /dev/null +++ b/include/cglm/frustum.h @@ -0,0 +1,176 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_frustum_h +#define cglm_frustum_h + +#include "common.h" +#include "plane.h" + +#define GLM_LBN 0 +#define GLM_LTN 1 +#define GLM_RTN 2 +#define GLM_RBN 3 + +#define GLM_LBF 4 +#define GLM_LTF 5 +#define GLM_RTF 6 +#define GLM_RBF 7 + +/*! + * @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 exracted view frustum planes (see brief) + */ +CGLM_INLINE +void +glm_frustum_planes(mat4 m, vec4 dest[6]) { + mat4 t; + + glm_mat4_transpose_to(m, t); + + glm_vec4_add(t[3], t[0], dest[0]); /* left */ + glm_vec4_sub(t[3], t[0], dest[1]); /* right */ + glm_vec4_add(t[3], t[1], dest[2]); /* bottom */ + glm_vec4_sub(t[3], t[1], dest[3]); /* top */ + glm_vec4_add(t[3], t[2], dest[4]); /* near */ + glm_vec4_sub(t[3], t[2], dest[5]); /* far */ + + glm_plane_normalize(dest[0]); + glm_plane_normalize(dest[1]); + glm_plane_normalize(dest[2]); + glm_plane_normalize(dest[3]); + glm_plane_normalize(dest[4]); + glm_plane_normalize(dest[5]); +} + +/*! + * @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_vec_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 +glm_frustum_corners(mat4 invMat, vec4 dest[8]) { + vec4 c[8]; + + /* indexOf(nearCoord) = indexOf(farCoord) + 4 */ + vec4 csCoords[8] = { + {-1.0f, -1.0f, -1.0f, 1.0f}, /* GLM_LBN */ + {-1.0f, 1.0f, -1.0f, 1.0f}, /* GLM_LTN */ + { 1.0f, 1.0f, -1.0f, 1.0f}, /* GLM_RTN */ + { 1.0f, -1.0f, -1.0f, 1.0f}, /* GLM_RBN */ + + {-1.0f, -1.0f, 1.0f, 1.0f}, /* GLM_LBF */ + {-1.0f, 1.0f, 1.0f, 1.0f}, /* GLM_LTF */ + { 1.0f, 1.0f, 1.0f, 1.0f}, /* GLM_RTF */ + { 1.0f, -1.0f, 1.0f, 1.0f} /* GLM_RBF */ + }; + + glm_mat4_mulv(invMat, csCoords[0], c[0]); + glm_mat4_mulv(invMat, csCoords[1], c[1]); + glm_mat4_mulv(invMat, csCoords[2], c[2]); + glm_mat4_mulv(invMat, csCoords[3], c[3]); + glm_mat4_mulv(invMat, csCoords[4], c[4]); + glm_mat4_mulv(invMat, csCoords[5], c[5]); + glm_mat4_mulv(invMat, csCoords[6], c[6]); + glm_mat4_mulv(invMat, csCoords[7], c[7]); + + glm_vec4_scale(c[0], 1.0f / c[1][3], dest[0]); + glm_vec4_scale(c[1], 1.0f / c[1][3], dest[1]); + glm_vec4_scale(c[2], 1.0f / c[2][3], dest[2]); + glm_vec4_scale(c[3], 1.0f / c[3][3], dest[3]); + glm_vec4_scale(c[4], 1.0f / c[4][3], dest[4]); + glm_vec4_scale(c[5], 1.0f / c[5][3], dest[5]); + glm_vec4_scale(c[6], 1.0f / c[6][3], dest[6]); + glm_vec4_scale(c[7], 1.0f / c[7][3], dest[7]); +} + +/*! + * @brief finds center of view frustum + * + * @param[in] corners view frustum corners + * @param[out] dest view frustum center + */ +CGLM_INLINE +void +glm_frustum_center(vec4 corners[8], vec4 dest) { + vec4 center; + + glm_vec4_copy(corners[0], center); + + glm_vec4_add(corners[1], center, center); + glm_vec4_add(corners[2], center, center); + glm_vec4_add(corners[3], center, center); + glm_vec4_add(corners[4], center, center); + glm_vec4_add(corners[5], center, center); + glm_vec4_add(corners[6], center, center); + glm_vec4_add(corners[7], center, center); + + glm_vec4_scale(center, 0.125f, dest); +} + +/*! + * @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 +glm_frustum_box(vec4 corners[8], mat4 m, vec3 box[2]) { + vec4 v; + int i; + + glm_vec_broadcast(0.0f, box[0]); + glm_vec_broadcast(0.0f, box[1]); + + for (i = 0; i < 8; i++) { + glm_mat4_mulv(m, corners[i], v); + + box[0][0] = glm_min(box[0][0], v[0]); + box[0][1] = glm_min(box[0][1], v[1]); + box[0][2] = glm_min(box[0][2], v[2]); + + box[1][0] = glm_max(box[1][0], v[0]); + box[1][1] = glm_max(box[1][1], v[1]); + box[1][2] = glm_max(box[1][2], v[2]); + } +} + +#endif /* cglm_frustum_h */ diff --git a/makefile.am b/makefile.am index 5830700..2350b9c 100644 --- a/makefile.am +++ b/makefile.am @@ -88,7 +88,9 @@ libcglm_la_SOURCES=\ src/vec3.c \ src/vec4.c \ src/mat3.c \ - src/mat4.c + src/mat4.c \ + src/plane.c \ + src/frustum.c test_tests_SOURCES=\ test/src/test_common.c \ diff --git a/src/cam.c b/src/cam.c index 3def839..aeac3c7 100644 --- a/src/cam.c +++ b/src/cam.c @@ -78,21 +78,3 @@ void glmc_look_anyup(vec3 eye, vec3 dir, mat4 dest) { glm_look_anyup(eye, dir, dest); } - -CGLM_EXPORT -void -glmc_frustum_planes(mat4 m, vec4 dest[6]) { - glm_frustum_planes(m, dest); -} - -CGLM_EXPORT -void -glmc_frustum_corners(mat4 invMat, vec4 dest[8]) { - glm_frustum_corners(invMat, dest); -} - -CGLM_EXPORT -void -glmc_frustum_center(vec4 corners[8], vec4 dest) { - glm_frustum_center(corners, dest); -} diff --git a/src/frustum.c b/src/frustum.c new file mode 100644 index 0000000..b175421 --- /dev/null +++ b/src/frustum.c @@ -0,0 +1,33 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#include "../include/cglm/cglm.h" +#include "../include/cglm/call.h" + +CGLM_EXPORT +void +glmc_frustum_planes(mat4 m, vec4 dest[6]) { + glm_frustum_planes(m, dest); +} + +CGLM_EXPORT +void +glmc_frustum_corners(mat4 invMat, vec4 dest[8]) { + glm_frustum_corners(invMat, dest); +} + +CGLM_EXPORT +void +glmc_frustum_center(vec4 corners[8], vec4 dest) { + glm_frustum_center(corners, dest); +} + +CGLM_EXPORT +void +glmc_frustum_box(vec4 corners[8], mat4 m, vec3 box[2]) { + glm_frustum_box(corners, m, box); +} From b6dc5029ddae064ad2f9afd493c9a0597b2cdb3e Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Fri, 12 Jan 2018 16:41:34 +0300 Subject: [PATCH 2/6] build, win: update windows solution and proejct files --- win/cglm.vcxproj | 8 +++++++- win/cglm.vcxproj.filters | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj index 91e8fa5..93d9e9b 100644 --- a/win/cglm.vcxproj +++ b/win/cglm.vcxproj @@ -23,9 +23,11 @@ + + @@ -37,9 +39,11 @@ + + @@ -47,9 +51,11 @@ + + @@ -73,7 +79,7 @@ {CA8BCAF9-CD25-4133-8F62-3D1449B5D2FC} Win32Proj cglm - 10.0.14393.0 + 10.0.16299.0 diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters index bed473d..5ea5810 100644 --- a/win/cglm.vcxproj.filters +++ b/win/cglm.vcxproj.filters @@ -66,6 +66,12 @@ src + + src + + + src + @@ -176,5 +182,17 @@ include\cglm + + include\cglm\call + + + include\cglm\call + + + include\cglm + + + include\cglm + \ No newline at end of file From 40458be41bac44424dd0dc0d9f7fca58decb7cbd Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Sat, 13 Jan 2018 17:27:06 +0300 Subject: [PATCH 3/6] frustum: fix array index --- include/cglm/frustum.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cglm/frustum.h b/include/cglm/frustum.h index 74a1769..7ab761b 100644 --- a/include/cglm/frustum.h +++ b/include/cglm/frustum.h @@ -110,7 +110,7 @@ glm_frustum_corners(mat4 invMat, vec4 dest[8]) { glm_mat4_mulv(invMat, csCoords[6], c[6]); glm_mat4_mulv(invMat, csCoords[7], c[7]); - glm_vec4_scale(c[0], 1.0f / c[1][3], dest[0]); + glm_vec4_scale(c[0], 1.0f / c[0][3], dest[0]); glm_vec4_scale(c[1], 1.0f / c[1][3], dest[1]); glm_vec4_scale(c[2], 1.0f / c[2][3], dest[2]); glm_vec4_scale(c[3], 1.0f / c[3][3], dest[3]); From a56da8cc4ab9b37c9ca893e80bed8eeaabf47957 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Sat, 13 Jan 2018 21:37:15 +0300 Subject: [PATCH 4/6] frustum: new macros for frustum --- include/cglm/frustum.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/cglm/frustum.h b/include/cglm/frustum.h index 7ab761b..f22fc0f 100644 --- a/include/cglm/frustum.h +++ b/include/cglm/frustum.h @@ -21,6 +21,13 @@ #define GLM_RTF 6 #define GLM_RBF 7 +#define GLM_LEFT 0 +#define GLM_RIGHT 1 +#define GLM_BOTTOM 2 +#define GLM_TOP 3 +#define GLM_NEAR 4 +#define GLM_FAR 5 + /*! * @brief extracts view frustum planes * From 944d285e14b8f469e2b487cc9186a4522a69a280 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Sat, 13 Jan 2018 21:40:34 +0300 Subject: [PATCH 5/6] frustum: new util for getting a plane's corners between near and far planes * optimize frustum box func --- include/cglm/frustum.h | 65 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/include/cglm/frustum.h b/include/cglm/frustum.h index f22fc0f..4e5a10c 100644 --- a/include/cglm/frustum.h +++ b/include/cglm/frustum.h @@ -162,22 +162,71 @@ CGLM_INLINE void glm_frustum_box(vec4 corners[8], mat4 m, vec3 box[2]) { vec4 v; + vec3 min, max; int i; - glm_vec_broadcast(0.0f, box[0]); - glm_vec_broadcast(0.0f, box[1]); + glm_vec_broadcast(0.0f, min); + glm_vec_broadcast(0.0f, max); for (i = 0; i < 8; i++) { glm_mat4_mulv(m, corners[i], v); - box[0][0] = glm_min(box[0][0], v[0]); - box[0][1] = glm_min(box[0][1], v[1]); - box[0][2] = glm_min(box[0][2], v[2]); + min[0] = glm_min(min[0], v[0]); + min[1] = glm_min(min[1], v[1]); + min[2] = glm_min(min[2], v[2]); - box[1][0] = glm_max(box[1][0], v[0]); - box[1][1] = glm_max(box[1][1], v[1]); - box[1][2] = glm_max(box[1][2], v[2]); + max[0] = glm_max(max[0], v[0]); + max[1] = glm_max(max[1], v[1]); + max[2] = glm_max(max[2], v[2]); } + + glm_vec_copy(min, box[0]); + glm_vec_copy(max, box[1]); +} + +/*! + * @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 +glm_frustum_corners_at(vec4 corners[8], + float splitDist, + float farDist, + vec4 planeCorners[4]) { + vec4 corner; + float dist, sc; + + dist = glm_vec_distance(corners[4], corners[0]); + sc = dist * (splitDist / farDist); + + /* left bottom */ + glm_vec4_sub(corners[4], corners[0], corner); + glm_vec4_scale_as(corner, sc, corner); + glm_vec4_add(corners[0], corner, planeCorners[0]); + + /* left top */ + glm_vec4_sub(corners[5], corners[1], corner); + glm_vec4_scale_as(corner, sc, corner); + glm_vec4_add(corners[1], corner, planeCorners[1]); + + /* right top */ + glm_vec4_sub(corners[6], corners[2], corner); + glm_vec4_scale_as(corner, sc, corner); + glm_vec4_add(corners[2], corner, planeCorners[2]); + + /* right bottom */ + glm_vec4_sub(corners[7], corners[3], corner); + glm_vec4_scale_as(corner, sc, corner); + glm_vec4_add(corners[3], corner, planeCorners[3]); } #endif /* cglm_frustum_h */ From 8bcd6bd077fb680d6135d75eae1ec8072cfb4ddf Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Sun, 14 Jan 2018 11:03:03 +0300 Subject: [PATCH 6/6] frustum: make clipspace coords configurable * now users can override clip space coords * add more desc to header * add call version for _corners_at --- include/cglm/call/frustum.h | 6 ++++ include/cglm/frustum.h | 70 ++++++++++++++++++++++++------------- src/frustum.c | 9 +++++ 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/include/cglm/call/frustum.h b/include/cglm/call/frustum.h index 066ed40..6b4facb 100644 --- a/include/cglm/call/frustum.h +++ b/include/cglm/call/frustum.h @@ -29,6 +29,12 @@ CGLM_EXPORT void glmc_frustum_box(vec4 corners[8], mat4 m, vec3 box[2]); +CGLM_EXPORT +void +glmc_frustum_corners_at(vec4 corners[8], + float splitDist, + float farDist, + vec4 planeCorners[4]); #ifdef __cplusplus } #endif diff --git a/include/cglm/frustum.h b/include/cglm/frustum.h index 4e5a10c..b526c34 100644 --- a/include/cglm/frustum.h +++ b/include/cglm/frustum.h @@ -11,15 +11,15 @@ #include "common.h" #include "plane.h" -#define GLM_LBN 0 -#define GLM_LTN 1 -#define GLM_RTN 2 -#define GLM_RBN 3 +#define GLM_LBN 0 /* left bottom near */ +#define GLM_LTN 1 /* left top near */ +#define GLM_RTN 2 /* right top near */ +#define GLM_RBN 3 /* right bottom near */ -#define GLM_LBF 4 -#define GLM_LTF 5 -#define GLM_RTF 6 -#define GLM_RBF 7 +#define GLM_LBF 4 /* left bottom far */ +#define GLM_LTF 5 /* left top far */ +#define GLM_RTF 6 /* right top far */ +#define GLM_RBF 7 /* right bottom far */ #define GLM_LEFT 0 #define GLM_RIGHT 1 @@ -28,6 +28,25 @@ #define GLM_NEAR 4 #define GLM_FAR 5 +/* 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 GLM_CSCOORD_LBN {-1.0f, -1.0f, -1.0f, 1.0f} +#define GLM_CSCOORD_LTN {-1.0f, 1.0f, -1.0f, 1.0f} +#define GLM_CSCOORD_RTN { 1.0f, 1.0f, -1.0f, 1.0f} +#define GLM_CSCOORD_RBN { 1.0f, -1.0f, -1.0f, 1.0f} + +/* far */ +#define GLM_CSCOORD_LBF {-1.0f, -1.0f, 1.0f, 1.0f} +#define GLM_CSCOORD_LTF {-1.0f, 1.0f, 1.0f, 1.0f} +#define GLM_CSCOORD_RTF { 1.0f, 1.0f, 1.0f, 1.0f} +#define GLM_CSCOORD_RBF { 1.0f, -1.0f, 1.0f, 1.0f} + +#endif + /*! * @brief extracts view frustum planes * @@ -97,15 +116,15 @@ glm_frustum_corners(mat4 invMat, vec4 dest[8]) { /* indexOf(nearCoord) = indexOf(farCoord) + 4 */ vec4 csCoords[8] = { - {-1.0f, -1.0f, -1.0f, 1.0f}, /* GLM_LBN */ - {-1.0f, 1.0f, -1.0f, 1.0f}, /* GLM_LTN */ - { 1.0f, 1.0f, -1.0f, 1.0f}, /* GLM_RTN */ - { 1.0f, -1.0f, -1.0f, 1.0f}, /* GLM_RBN */ + GLM_CSCOORD_LBN, + GLM_CSCOORD_LTN, + GLM_CSCOORD_RTN, + GLM_CSCOORD_RBN, - {-1.0f, -1.0f, 1.0f, 1.0f}, /* GLM_LBF */ - {-1.0f, 1.0f, 1.0f, 1.0f}, /* GLM_LTF */ - { 1.0f, 1.0f, 1.0f, 1.0f}, /* GLM_RTF */ - { 1.0f, -1.0f, 1.0f, 1.0f} /* GLM_RBF */ + GLM_CSCOORD_LBF, + GLM_CSCOORD_LTF, + GLM_CSCOORD_RTF, + GLM_CSCOORD_RBF }; glm_mat4_mulv(invMat, csCoords[0], c[0]); @@ -205,28 +224,29 @@ glm_frustum_corners_at(vec4 corners[8], vec4 corner; float dist, sc; - dist = glm_vec_distance(corners[4], corners[0]); + /* because distance and scale is same for all */ + dist = glm_vec_distance(corners[GLM_RTF], corners[GLM_RTN]); sc = dist * (splitDist / farDist); /* left bottom */ - glm_vec4_sub(corners[4], corners[0], corner); + glm_vec4_sub(corners[GLM_LBF], corners[GLM_LBN], corner); glm_vec4_scale_as(corner, sc, corner); - glm_vec4_add(corners[0], corner, planeCorners[0]); + glm_vec4_add(corners[GLM_LBN], corner, planeCorners[0]); /* left top */ - glm_vec4_sub(corners[5], corners[1], corner); + glm_vec4_sub(corners[GLM_LTF], corners[GLM_LTN], corner); glm_vec4_scale_as(corner, sc, corner); - glm_vec4_add(corners[1], corner, planeCorners[1]); + glm_vec4_add(corners[GLM_LTN], corner, planeCorners[1]); /* right top */ - glm_vec4_sub(corners[6], corners[2], corner); + glm_vec4_sub(corners[GLM_RTF], corners[GLM_RTN], corner); glm_vec4_scale_as(corner, sc, corner); - glm_vec4_add(corners[2], corner, planeCorners[2]); + glm_vec4_add(corners[GLM_RTN], corner, planeCorners[2]); /* right bottom */ - glm_vec4_sub(corners[7], corners[3], corner); + glm_vec4_sub(corners[GLM_RBF], corners[GLM_RBN], corner); glm_vec4_scale_as(corner, sc, corner); - glm_vec4_add(corners[3], corner, planeCorners[3]); + glm_vec4_add(corners[GLM_RBN], corner, planeCorners[3]); } #endif /* cglm_frustum_h */ diff --git a/src/frustum.c b/src/frustum.c index b175421..312c3d3 100644 --- a/src/frustum.c +++ b/src/frustum.c @@ -31,3 +31,12 @@ void glmc_frustum_box(vec4 corners[8], mat4 m, vec3 box[2]) { glm_frustum_box(corners, m, box); } + +CGLM_EXPORT +void +glmc_frustum_corners_at(vec4 corners[8], + float splitDist, + float farDist, + vec4 planeCorners[4]) { + glm_frustum_corners_at(corners, splitDist, farDist, planeCorners); +}