17 vec4 planes[PLANE_COUNT];
18 int cross_indices[PLANE_COUNT][PLANE_COUNT];
21 __attribute__((constructor)) static void init_frustum()
23 for (Plane a = 0; a < PLANE_COUNT; a++)
24 for (Plane b = 0; b < PLANE_COUNT; b++)
25 frustum.cross_indices[a][b] = a * (9 - a) / 2 + b - 1;
28 void frustum_update(mat4x4 view_proj)
32 mat4x4_transpose(m, view_proj);
34 vec4_add(frustum.planes[PLANE_LEFT], m[3], m[0]);
35 vec4_sub(frustum.planes[PLANE_RIGHT], m[3], m[0]);
36 vec4_add(frustum.planes[PLANE_BOTTOM], m[3], m[1]);
37 vec4_sub(frustum.planes[PLANE_TOP], m[3], m[1]);
38 vec4_add(frustum.planes[PLANE_NEAR], m[3], m[2]);
39 vec4_sub(frustum.planes[PLANE_FAR], m[3], m[2]);
42 vec3 crosses[PLANE_COUNT * (PLANE_COUNT - 1) / 2];
43 for (Plane a = 0; a < PLANE_COUNT; a++)
44 for (Plane b = a + 1; b < PLANE_COUNT; b++)
45 vec3_mul_cross(crosses[i++], frustum.planes[a], frustum.planes[b]);
48 for (Plane c = PLANE_NEAR; c <= PLANE_FAR; c++) {
49 for (Plane a = PLANE_LEFT; a <= PLANE_RIGHT; a++) {
50 for (Plane b = PLANE_BOTTOM; b <= PLANE_TOP; b++) {
51 float d = -1.0f / vec3_mul_inner(frustum.planes[a], crosses[frustum.cross_indices[b][c]]);
52 vec3 w = {frustum.planes[a][3], frustum.planes[b][3], frustum.planes[c][3]};
53 float *res = frustum.points[j++];
55 vec3 res_1_cross = {-crosses[frustum.cross_indices[a][c]][0], -crosses[frustum.cross_indices[a][c]][1], -crosses[frustum.cross_indices[a][c]][2]};
57 res[0] = vec3_mul_inner(crosses[frustum.cross_indices[b][c]], w) * d;
58 res[1] = vec3_mul_inner(res_1_cross, w) * d;
59 res[2] = vec3_mul_inner(crosses[frustum.cross_indices[a][b]], w) * d;
65 static bool outside_plane(Plane i, aabb3f32 box)
67 for (int x = 0; x <= 1; x++) {
68 for (int y = 0; y <= 1; y++) {
69 for (int z = 0; z <= 1; z++) {
71 x ? box.max.x : box.min.x,
72 y ? box.max.y : box.min.y,
73 z ? box.max.z : box.min.z,
77 if (vec4_mul_inner(frustum.planes[i], plane) > 0.0)
86 // http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm
87 bool frustum_is_visible(aabb3f32 box)
89 for (Plane i = 0; i < PLANE_COUNT; i++) {
90 if (outside_plane(i, box))
94 int box_outside[6] = {0};
96 for (Plane i = 0; i < PLANE_COUNT; i++) {
98 frustum.points[i][0] > box.max.x,
99 frustum.points[i][0] < box.min.x,
100 frustum.points[i][1] > box.max.y,
101 frustum.points[i][1] < box.min.y,
102 frustum.points[i][2] > box.max.z,
103 frustum.points[i][2] < box.min.z,
106 for (int i = 0; i < 6; i++)
107 box_outside[i] += outside[i];
110 for (int i = 0; i < 6; i++) {
111 if (box_outside[i] == 8)