mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-25 08:18:43 -06:00
frustum culling impl
This commit is contained in:
parent
a29f6c65fd
commit
1f1b337988
|
@ -6,11 +6,13 @@ mod matrices;
|
|||
mod frustum;
|
||||
|
||||
use matrices::update_matrices;
|
||||
use frustum::{Frustum, update_frustum};
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Camera {
|
||||
pub view_matrix: Mat4,
|
||||
pub perspective_matrix: Mat4,
|
||||
pub frustum: Frustum,
|
||||
pub up: Vec3,
|
||||
pub fov: 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 {
|
||||
Self {
|
||||
fov, z_near, z_far, up,
|
||||
//TODO maybe separate this?
|
||||
perspective_matrix: Mat4::default(),
|
||||
view_matrix: Mat4::default(),
|
||||
frustum: Frustum::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,5 +38,6 @@ impl Default for Camera {
|
|||
pub fn compute_cameras() -> Workload {
|
||||
(
|
||||
update_matrices,
|
||||
update_frustum,
|
||||
).into_workload()
|
||||
}
|
||||
|
|
|
@ -7,11 +7,10 @@
|
|||
// [ http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm ]
|
||||
// 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;
|
||||
|
||||
|
||||
#[repr(usize)]
|
||||
enum FrustumPlane {
|
||||
Left,
|
||||
|
@ -26,7 +25,8 @@ const PLANE_COUNT: usize = 6;
|
|||
const PLANE_COMBINATIONS: usize = PLANE_COUNT * (PLANE_COUNT - 1) / 2;
|
||||
const POINT_COUNT: usize = 8;
|
||||
|
||||
struct Frustum {
|
||||
#[derive(Default)]
|
||||
pub struct Frustum {
|
||||
planes: [Vec4; PLANE_COUNT],
|
||||
points: [Vec3A; POINT_COUNT]
|
||||
}
|
||||
|
@ -77,8 +77,59 @@ impl Frustum {
|
|||
|
||||
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 {
|
||||
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);
|
||||
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