frustum culling impl

This commit is contained in:
griffi-gh 2023-01-27 21:50:33 +01:00
parent a29f6c65fd
commit 1f1b337988
2 changed files with 69 additions and 5 deletions

View file

@ -6,11 +6,13 @@ mod matrices;
mod frustum; mod frustum;
use matrices::update_matrices; use matrices::update_matrices;
use frustum::{Frustum, update_frustum};
#[derive(Component)] #[derive(Component)]
pub struct Camera { pub struct Camera {
pub view_matrix: Mat4, pub view_matrix: Mat4,
pub perspective_matrix: Mat4, pub perspective_matrix: Mat4,
pub frustum: Frustum,
pub up: Vec3, pub up: Vec3,
pub fov: f32, pub fov: f32,
pub z_near: f32, pub z_near: f32,
@ -20,8 +22,10 @@ impl Camera {
pub fn new(fov: f32, z_near: f32, z_far: f32, up: Vec3) -> Self { pub fn new(fov: f32, z_near: f32, z_far: f32, up: Vec3) -> Self {
Self { Self {
fov, z_near, z_far, up, fov, z_near, z_far, up,
//TODO maybe separate this?
perspective_matrix: Mat4::default(), perspective_matrix: Mat4::default(),
view_matrix: Mat4::default(), view_matrix: Mat4::default(),
frustum: Frustum::default(),
} }
} }
} }
@ -34,5 +38,6 @@ impl Default for Camera {
pub fn compute_cameras() -> Workload { pub fn compute_cameras() -> Workload {
( (
update_matrices, update_matrices,
update_frustum,
).into_workload() ).into_workload()
} }

View file

@ -7,11 +7,10 @@
// [ http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm ] // [ http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm ]
// three layers of stolen code, yay! // three layers of stolen code, yay!
use glam::{Vec3A, Vec4, Mat3A, vec3a}; use glam::{Vec3A, Vec4, Mat3A, vec3a, Vec3, vec4};
use shipyard::{ViewMut, IntoIter};
use super::Camera; use super::Camera;
#[repr(usize)] #[repr(usize)]
enum FrustumPlane { enum FrustumPlane {
Left, Left,
@ -26,7 +25,8 @@ const PLANE_COUNT: usize = 6;
const PLANE_COMBINATIONS: usize = PLANE_COUNT * (PLANE_COUNT - 1) / 2; const PLANE_COMBINATIONS: usize = PLANE_COUNT * (PLANE_COUNT - 1) / 2;
const POINT_COUNT: usize = 8; const POINT_COUNT: usize = 8;
struct Frustum { #[derive(Default)]
pub struct Frustum {
planes: [Vec4; PLANE_COUNT], planes: [Vec4; PLANE_COUNT],
points: [Vec3A; POINT_COUNT] points: [Vec3A; POINT_COUNT]
} }
@ -77,8 +77,59 @@ impl Frustum {
Self { planes, points } Self { planes, points }
} }
//this may be broken
pub fn intersect_box(&self, minp: Vec3, maxp: Vec3) -> bool {
// check box outside/inside of frustum
for i in 0..PLANE_COUNT {
if self.planes[i].dot(vec4(minp.x, minp.y, minp.z, 1.)) < 0. &&
self.planes[i].dot(vec4(maxp.x, minp.y, minp.z, 1.)) < 0. &&
self.planes[i].dot(vec4(minp.x, maxp.y, minp.z, 1.)) < 0. &&
self.planes[i].dot(vec4(maxp.x, maxp.y, minp.z, 1.)) < 0. &&
self.planes[i].dot(vec4(minp.x, minp.y, maxp.z, 1.)) < 0. &&
self.planes[i].dot(vec4(maxp.x, minp.y, maxp.z, 1.)) < 0. &&
self.planes[i].dot(vec4(minp.x, maxp.y, maxp.z, 1.)) < 0. &&
self.planes[i].dot(vec4(maxp.x, maxp.y, maxp.z, 1.)) < 0.
{
return false
}
} }
// check frustum outside/inside box
let mut out: u8 = 0;
for i in 0..POINT_COUNT {
out += (self.points[i].x > maxp.x) as u8;
if out == 8 { return false }
}
let mut out: u8 = 0;
for i in 0..POINT_COUNT {
out += (self.points[i].x < minp.x) as u8;
if out == 8 { return false }
}
let mut out: u8 = 0;
for i in 0..POINT_COUNT {
out += (self.points[i].y > maxp.y) as u8;
if out == 8 { return false }
}
let mut out: u8 = 0;
for i in 0..POINT_COUNT {
out += (self.points[i].y < minp.y) as u8;
if out == 8 { return false }
}
let mut out: u8 = 0;
for i in 0..POINT_COUNT {
out += (self.points[i].z > maxp.z) as u8;
if out == 8 { return false }
}
let mut out: u8 = 0;
for i in 0..POINT_COUNT {
out += (self.points[i].z < minp.z) as u8;
if out == 8 { return false }
}
true
}
}
const fn ij2k<const I: usize, const J: usize>() -> usize { const fn ij2k<const I: usize, const J: usize>() -> usize {
I * (9 - I) / 2 + J - 1 I * (9 - I) / 2 + J - 1
@ -92,3 +143,11 @@ fn intersection<const A: usize, const B: usize, const C: usize>(planes: &[Vec4;
) * vec3a(planes[A].w, planes[B].w, planes[C].w); ) * vec3a(planes[A].w, planes[B].w, planes[C].w);
res * (-1. / d) res * (-1. / d)
} }
pub fn update_frustum(
mut cameras: ViewMut<Camera>,
) {
for camera in (&mut cameras).iter() {
camera.frustum = Frustum::compute(camera);
}
}