Fixed frustum culling

This commit is contained in:
2018-07-19 14:24:54 +02:00
parent 3172a0c58e
commit 674b49430f
6 changed files with 179 additions and 85 deletions
+27
View File
@@ -95,6 +95,16 @@ macro_rules! make_bounding_box {
ret
}
/// Returns true if the point is inside the bounding box.
pub fn contains_point(&self, point: $vector<T>) -> bool {
for i in 0 .. $size {
if self.min()[i] > point[i] || point[i] > self.max()[i] {
return false;
}
}
true
}
}
}
@@ -183,4 +193,21 @@ mod tests {
let bb2 = b2.intersection(&b1);
assert_eq!(bb1, bb2);
}
#[test]
fn contains_point() {
let b1 = BoundingBox3::new(
Vector3::new(0.0, 0.0, 0.0),
Vector3::new(2.0, 2.0, 2.0),
);
assert_eq!(b1.contains_point(Vector3::new(1.0, 1.0, 1.0)), true);
assert_eq!(b1.contains_point(Vector3::new(1.5, 0.5, 1.0)), true);
assert_eq!(b1.contains_point(Vector3::new(1.5, -0.5, 1.0)), false);
assert_eq!(b1.contains_point(Vector3::new(1.5, 0.5, -1.0)), false);
assert_eq!(b1.contains_point(Vector3::new(-0.5, 0.5, 1.0)), false);
assert_eq!(b1.contains_point(Vector3::new(2.5, 0.5, 1.0)), false);
assert_eq!(b1.contains_point(Vector3::new(0.5, 2.5, 1.0)), false);
}
}
+24 -19
View File
@@ -17,15 +17,27 @@ pub struct Frustum {
}
impl Frustum {
/// Creates a frustum from the matrix of a camera.
///
/// This is *ahem...* slightly inspired from THREE.js Frustum
/// Creates a frustum from its four planes.
pub fn new(planes: [Plane; 6]) -> Frustum {
Frustum {
planes: planes,
}
}
/// Creates a frustum for a camera matrix.
pub fn from_matrix(m: &Matrix4<f32>) -> Frustum {
let m0 = m[(0, 0)]; let m1 = m[(0, 1)]; let m2 = m[(0, 2)]; let m3 = m[(0, 3)];
let m4 = m[(1, 0)]; let m5 = m[(1, 1)]; let m6 = m[(1, 2)]; let m7 = m[(1, 3)];
let m8 = m[(2, 0)]; let m9 = m[(2, 1)]; let m10 = m[(2, 2)]; let m11 = m[(2, 3)];
let m12 = m[(3, 0)]; let m13 = m[(3, 1)]; let m14 = m[(3, 2)]; let m15 = m[(3, 3)];
// let m0 = m[(0, 0)]; let m1 = m[(0, 1)]; let m2 = m[(0, 2)]; let m3 = m[(0, 3)];
// let m4 = m[(1, 0)]; let m5 = m[(1, 1)]; let m6 = m[(1, 2)]; let m7 = m[(1, 3)];
// let m8 = m[(2, 0)]; let m9 = m[(2, 1)]; let m10 = m[(2, 2)]; let m11 = m[(2, 3)];
// let m12 = m[(3, 0)]; let m13 = m[(3, 1)]; let m14 = m[(3, 2)]; let m15 = m[(3, 3)];
// Swapped version...
let m0 = m[(0, 0)]; let m1 = m[(1, 0)]; let m2 = m[(2, 0)]; let m3 = m[(3, 0)];
let m4 = m[(0, 1)]; let m5 = m[(1, 1)]; let m6 = m[(2, 1)]; let m7 = m[(3, 1)];
let m8 = m[(0, 2)]; let m9 = m[(1, 2)]; let m10 = m[(2, 2)]; let m11 = m[(3, 2)];
let m12 = m[(0, 3)]; let m13 = m[(1, 3)]; let m14 = m[(2, 3)]; let m15 = m[(3, 3)];
Frustum {
planes: [
@@ -44,22 +56,15 @@ impl Frustum {
use num::Zero;
let mut p1 = Vector3::<f32>::zero();
let mut p2 = Vector3::<f32>::zero();
let mut p = Vector3::<f32>::zero();
for plane in &self.planes {
p1[0] = if plane.normal().x() > 0.0 { bbox.min().x() } else { bbox.max().x() };
p2[0] = if plane.normal().x() > 0.0 { bbox.max().x() } else { bbox.min().x() };
p1[1] = if plane.normal().y() > 0.0 { bbox.min().y() } else { bbox.max().y() };
p2[1] = if plane.normal().y() > 0.0 { bbox.max().y() } else { bbox.min().y() };
p1[2] = if plane.normal().z() > 0.0 { bbox.min().z() } else { bbox.max().z() };
p2[2] = if plane.normal().z() > 0.0 { bbox.max().z() } else { bbox.min().z() };
p[0] = if plane.normal().x() > 0.0 { bbox.max().x() } else { bbox.min().x() };
p[1] = if plane.normal().y() > 0.0 { bbox.max().y() } else { bbox.min().y() };
p[2] = if plane.normal().z() > 0.0 { bbox.max().z() } else { bbox.min().z() };
let d1 = plane.distance_to_point(p1);
let d2 = plane.distance_to_point(p2);
if d1 < 0.0 && d2 < 2.0 {
if plane.distance_to_point(p) < 0.0 {
return false;
}
}
+8
View File
@@ -39,6 +39,14 @@ macro_rules! make_vector {
}
}
impl<T> From<[T; $number]> for $name<T> {
fn from(data: [T; $number]) -> $name<T> {
$name {
data: data,
}
}
}
impl<T: Copy + Clone> Into<($( $t ) ,* )> for $name<T> {
fn into(self) -> ($( $t ) ,* ) {
( $( self.data[$y] ), *)