collision/algorithm/broad_phase/
brute_force.rs1use crate::prelude::*;
2
3#[derive(Debug, Default)]
7pub struct BruteForce;
8
9impl BruteForce {
10 pub fn find_collider_pairs<A>(&self, shapes: &[A]) -> Vec<(usize, usize)>
21 where
22 A: HasBound,
23 A::Bound: Discrete<A::Bound>,
24 {
25 let mut pairs = Vec::default();
26 if shapes.len() <= 1 {
27 return pairs;
28 }
29
30 for left_index in 0..(shapes.len() - 1) {
31 let left = &shapes[left_index];
32 for right_index in (left_index + 1)..shapes.len() {
33 if left.bound().intersects(shapes[right_index].bound()) {
34 pairs.push((left_index, right_index));
35 }
36 }
37 }
38 pairs
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use cgmath::Point2;
45
46 use super::*;
47 use crate::Aabb2;
48
49 #[derive(Debug, Clone, PartialEq)]
50 pub struct BroadCollisionInfo2 {
51 pub id: u32,
53
54 pub bound: Aabb2<f32>,
56 index: usize,
57 }
58
59 impl BroadCollisionInfo2 {
60 pub fn new(id: u32, bound: Aabb2<f32>) -> Self {
62 Self {
63 id,
64 bound,
65 index: 0,
66 }
67 }
68 }
69
70 impl HasBound for BroadCollisionInfo2 {
71 type Bound = Aabb2<f32>;
72
73 fn bound(&self) -> &Aabb2<f32> {
74 &self.bound
75 }
76 }
77
78 #[test]
79 fn no_intersection_for_miss() {
80 let left = coll(1, 8., 8., 10., 11.);
81
82 let right = coll(2, 12., 13., 18., 18.);
83
84 let brute = BruteForce::default();
85 let potentials = brute.find_collider_pairs(&vec![left, right]);
86 assert_eq!(0, potentials.len());
87 }
88
89 #[test]
90 fn no_intersection_for_miss_unsorted() {
91 let left = coll(1, 8., 8., 10., 11.);
92
93 let right = coll(2, 12., 13., 18., 18.);
94
95 let brute = BruteForce::default();
96 let potentials = brute.find_collider_pairs(&vec![right, left]);
97 assert_eq!(0, potentials.len());
98 }
99
100 #[test]
101 fn intersection_for_hit() {
102 let left = coll(1, 8., 8., 10., 11.);
103
104 let right = coll(2, 9., 10., 18., 18.);
105
106 let brute = BruteForce::default();
107 let potentials = brute.find_collider_pairs(&vec![left.clone(), right.clone()]);
108 assert_eq!(1, potentials.len());
109 assert_eq!((0, 1), potentials[0]);
110 }
111
112 #[test]
113 fn intersection_for_hit_unsorted() {
114 let left = coll(1, 8., 8., 10., 11.);
115
116 let right = coll(222, 9., 10., 18., 18.);
117
118 let brute = BruteForce::default();
119 let potentials = brute.find_collider_pairs(&vec![right.clone(), left.clone()]);
120 assert_eq!(1, potentials.len());
121 assert_eq!((0, 1), potentials[0]);
122 }
123
124 fn coll(id: u32, min_x: f32, min_y: f32, max_x: f32, max_y: f32) -> BroadCollisionInfo2 {
126 BroadCollisionInfo2::new(id, bound(min_x, min_y, max_x, max_y))
127 }
128
129 fn bound(min_x: f32, min_y: f32, max_x: f32, max_y: f32) -> Aabb2<f32> {
130 Aabb2::new(Point2::new(min_x, min_y), Point2::new(max_x, max_y))
131 }
132}