Fixed frustum culling
This commit is contained in:
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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] ), *)
|
||||
|
||||
Reference in New Issue
Block a user