mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-29 02:08:48 -06:00
frustum culling impl
This commit is contained in:
parent
a29f6c65fd
commit
1f1b337988
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue