mirror of
https://github.com/recp/cglm.git
synced 2025-12-25 12:55:04 +00:00
Merge pull request #14 from recp/dev
feature: extract view frustum planes and corners
This commit is contained in:
6
LICENSE
6
LICENSE
@@ -52,3 +52,9 @@ LICENSE:
|
||||
|
||||
Computing Euler angles from a rotation matrix (euler.pdf)
|
||||
Gregory G. Slabaugh
|
||||
|
||||
4. Extracting Planes
|
||||
Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
|
||||
Authors:
|
||||
Gil Gribb (ggribb@ravensoft.com)
|
||||
Klaus Hartmann (k_hartmann@osnabrueck.netsurf.de)
|
||||
|
||||
@@ -50,6 +50,7 @@ https://github.com/g-truc/glm
|
||||
- euler angles / yaw-pitch-roll to matrix
|
||||
- extract euler angles
|
||||
- inline or pre-compiled function call
|
||||
- extract view frustum planes
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ extern "C" {
|
||||
#include "call/cam.h"
|
||||
#include "call/quat.h"
|
||||
#include "call/euler.h"
|
||||
#include "call/plane.h"
|
||||
#include "call/io.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -48,6 +48,18 @@ glmc_lookat(vec3 eye,
|
||||
vec3 up,
|
||||
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
|
||||
|
||||
23
include/cglm/call/plane.h
Normal file
23
include/cglm/call/plane.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglmc_plane_h
|
||||
#define cglmc_plane_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../cglm.h"
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_plane_normalize(vec4 plane);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* cglmc_plane_h */
|
||||
@@ -50,12 +50,15 @@
|
||||
float * __restrict farVal);
|
||||
CGLM_INLINE void glm_persp_decomp_far(mat4 proj, float * __restrict farVal);
|
||||
CGLM_INLINE void glm_persp_decomp_near(mat4 proj, float *__restrict nearVal);
|
||||
CGLM_INLINE void glm_frustum_planes(mat4 m, vec4 dest[6]);
|
||||
CGLM_INLINE void glm_frustum_corners(mat4 invMat, vec4 dest[8]);
|
||||
*/
|
||||
|
||||
#ifndef cglm_vcam_h
|
||||
#define cglm_vcam_h
|
||||
|
||||
#include "common.h"
|
||||
#include "plane.h"
|
||||
|
||||
/*!
|
||||
* @brief set up perspective peprojection matrix
|
||||
@@ -422,4 +425,117 @@ void
|
||||
glm_persp_decomp_near(mat4 proj, float * __restrict nearVal) {
|
||||
*nearVal = proj[3][2] / (proj[2][2] - 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @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 ndcCorners[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, ndcCorners[0], c[0]);
|
||||
glm_mat4_mulv(invMat, ndcCorners[1], c[1]);
|
||||
glm_mat4_mulv(invMat, ndcCorners[2], c[2]);
|
||||
glm_mat4_mulv(invMat, ndcCorners[3], c[3]);
|
||||
glm_mat4_mulv(invMat, ndcCorners[4], c[4]);
|
||||
glm_mat4_mulv(invMat, ndcCorners[5], c[5]);
|
||||
glm_mat4_mulv(invMat, ndcCorners[6], c[6]);
|
||||
glm_mat4_mulv(invMat, ndcCorners[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 */
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "cam.h"
|
||||
#include "quat.h"
|
||||
#include "euler.h"
|
||||
#include "plane.h"
|
||||
#include "util.h"
|
||||
#include "io.h"
|
||||
|
||||
|
||||
38
include/cglm/plane.h
Normal file
38
include/cglm/plane.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
#ifndef cglm_plane_h
|
||||
#define cglm_plane_h
|
||||
|
||||
#include "common.h"
|
||||
#include "mat4.h"
|
||||
#include "vec4.h"
|
||||
#include "vec3.h"
|
||||
|
||||
/*
|
||||
Plane equation: Ax + By + Cz + D = 0;
|
||||
|
||||
It stored in vec4 as [A, B, C, D]. (A, B, C) is normal and D is distance
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions:
|
||||
CGLM_INLINE void glm_plane_normalize(vec4 plane);
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief normalizes a plane
|
||||
*
|
||||
* @param[in, out] plane pnale to normalize
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_plane_normalize(vec4 plane) {
|
||||
glm_vec4_scale(plane, 1.0f / glm_vec_norm(plane), plane);
|
||||
}
|
||||
|
||||
#endif /* cglm_plane_h */
|
||||
@@ -61,4 +61,20 @@ glm_pow2(float x) {
|
||||
return x * x;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_min(float a, float b) {
|
||||
if (a < b)
|
||||
return a;
|
||||
return b;
|
||||
}
|
||||
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_max(float a, float b) {
|
||||
if (a > b)
|
||||
return a;
|
||||
return b;
|
||||
}
|
||||
|
||||
#endif /* cglm_util_h */
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
CGLM_INLINE bool glm_vec4_eq_eps(vec4 v, float val);
|
||||
CGLM_INLINE bool glm_vec4_eq_all(vec4 v);
|
||||
CGLM_INLINE bool glm_vec4_eqv(vec4 v1, vec4 v2);
|
||||
CGLM_INLINE bool glm_vec4_eqv_eps(vec3 v1, vec3 v2);
|
||||
CGLM_INLINE bool glm_vec4_eqv_eps(vec4 v1, vec4 v2);
|
||||
CGLM_INLINE float glm_vec4_max(vec4 v);
|
||||
CGLM_INLINE float glm_vec4_min(vec4 v);
|
||||
*/
|
||||
@@ -133,7 +133,7 @@ glm_vec4_eqv(vec4 v1, vec4 v2) {
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_vec4_eqv_eps(vec3 v1, vec3 v2) {
|
||||
glm_vec4_eqv_eps(vec4 v1, vec4 v2) {
|
||||
return fabsf(v1[0] - v2[0]) <= FLT_EPSILON
|
||||
&& fabsf(v1[1] - v2[1]) <= FLT_EPSILON
|
||||
&& fabsf(v1[2] - v2[2]) <= FLT_EPSILON
|
||||
|
||||
18
src/cam.c
18
src/cam.c
@@ -66,3 +66,21 @@ glmc_lookat(vec3 eye,
|
||||
mat4 dest) {
|
||||
glm_lookat(eye, center, up, 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);
|
||||
}
|
||||
|
||||
15
src/plane.c
Normal file
15
src/plane.c
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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_plane_normalize(vec4 plane) {
|
||||
glm_plane_normalize(plane);
|
||||
}
|
||||
Reference in New Issue
Block a user