-
Notifications
You must be signed in to change notification settings - Fork 31
/
frustum.rs
93 lines (77 loc) · 2.43 KB
/
frustum.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use crate::geometry::plane::Plane;
use crate::geometry::BoundingSphere;
use glam::Vec3;
#[derive(Clone, Debug)]
pub struct Frustum {
pub planes: Vec<Plane>,
is_invalid: bool,
}
impl Frustum {
pub fn new(num_planes: usize) -> Self {
Frustum {
planes: Vec::with_capacity(num_planes),
is_invalid: true,
}
}
pub fn update(&mut self) {
self.is_invalid = false;
}
pub fn invalidate(&mut self) {
self.is_invalid = true;
}
pub fn is_invalid(&self) -> bool {
self.is_invalid
}
pub fn contains_point(
&self,
point: Vec3,
) -> bool {
assert_ne!(self.is_invalid, true);
for plane in &self.planes {
if plane.distance(point) < 0. {
return false;
}
}
return true;
}
#[inline(never)]
pub fn contains_sphere_slow(
&self,
sphere: &BoundingSphere,
) -> bool {
assert_ne!(self.is_invalid, true);
let negative_radius = -sphere.radius;
for plane in &self.planes {
if plane.distance(sphere.position) <= negative_radius {
return false;
}
}
return true;
}
#[inline(never)]
pub fn contains_sphere_fast(
&self,
sphere: &BoundingSphere,
) -> bool {
assert_ne!(self.is_invalid, true);
assert_eq!(self.planes.len(), 6);
let radius = sphere.radius;
let spx = sphere.position.x;
let spy = sphere.position.y;
let spz = sphere.position.z;
let p1 = self.planes[0].normal;
let p2 = self.planes[1].normal;
let p3 = self.planes[2].normal;
let p4 = self.planes[3].normal;
let p5 = self.planes[4].normal;
let p6 = self.planes[5].normal;
let mut bitmask = 0;
bitmask |= ((p1.w + p1.x * spx + p1.y * spy + p1.z * spz + radius <= 0.) as i32) << 0;
bitmask |= ((p2.w + p2.x * spx + p2.y * spy + p2.z * spz + radius <= 0.) as i32) << 1;
bitmask |= ((p3.w + p3.x * spx + p3.y * spy + p3.z * spz + radius <= 0.) as i32) << 2;
bitmask |= ((p4.w + p4.x * spx + p4.y * spy + p4.z * spz + radius <= 0.) as i32) << 3;
bitmask |= ((p5.w + p5.x * spx + p5.y * spy + p5.z * spz + radius <= 0.) as i32) << 4;
bitmask |= ((p6.w + p6.x * spx + p6.y * spy + p6.z * spz + radius <= 0.) as i32) << 5;
return bitmask <= 0;
}
}