156 lines
4.2 KiB
C
156 lines
4.2 KiB
C
/*
|
|
* 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 */
|