#ifndef MATH_FRUSTUM_H #define MATH_FRUSTUM_H /* * View frustum: the six planes of a projection * view matrix. Lets the * renderer skip what can't be seen (behind you, off to the side, beyond * the far plane) before it is ever sent to the GPU. */ #include #include "math/linalg.h" typedef struct { float plane[6][4]; /* nx, ny, nz, d: inside where n . p + d >= 0 */ } Frustum; /* From a column-major projection * view matrix (Gribb / Hartmann). */ static inline Frustum frustum_from_matrix(Mat4 m) { Frustum f; for (int k = 0; k < 6; k++) { int row = k / 2; float sign = (k % 2) ? -1.0f : 1.0f; float p[4]; for (int c = 0; c < 4; c++) p[c] = m.m[3 + c * 4] + sign * m.m[row + c * 4]; float len = sqrtf(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]); if (len < 1e-8f) len = 1.0f; for (int c = 0; c < 4; c++) f.plane[k][c] = p[c] / len; } return f; } /* Does a sphere touch the frustum? (May say yes for some just outside a corner.) */ static inline bool frustum_sphere(const Frustum *f, Vec3 center, float radius) { for (int k = 0; k < 6; k++) { const float *p = f->plane[k]; if (p[0] * center.x + p[1] * center.y + p[2] * center.z + p[3] < -radius) return false; } return true; } #endif /* MATH_FRUSTUM_H */