jagua_rs/collision_detection/quadtree/
qt_partial_hazard.rs1use crate::collision_detection::quadtree::qt_traits::QTQueryable;
2use crate::geometry::geo_traits::CollidesWith;
3use crate::geometry::primitives::{Edge, Rect, SPolygon};
4
5#[derive(Clone, Debug)]
7pub struct QTHazPartial {
8 pub edges: Vec<Edge>,
10 pub ff_bbox: Rect,
12}
13
14impl QTHazPartial {
15 pub fn from_entire_shape(shape: &SPolygon) -> Self {
16 let edges = shape.edge_iter().collect();
17 let ff_bbox = shape.bbox;
18 Self { edges, ff_bbox }
19 }
20 pub fn from_parent(parent: &QTHazPartial, restricted_edges: Vec<Edge>) -> Self {
21 debug_assert!(!restricted_edges.is_empty());
22 debug_assert!(restricted_edges.iter().all(|e| parent.edges.contains(e)));
23 let ff_bbox = {
24 if parent.edges.len() == restricted_edges.len() {
26 parent.ff_bbox
28 } else {
29 let (mut x_min, mut y_min, mut x_max, mut y_max) = (
31 f32::INFINITY,
32 f32::INFINITY,
33 f32::NEG_INFINITY,
34 f32::NEG_INFINITY,
35 );
36 for edge in &restricted_edges {
37 x_min = x_min.min(edge.start.x()).min(edge.end.x());
38 y_min = y_min.min(edge.start.y()).min(edge.end.y());
39 x_max = x_max.max(edge.start.x()).max(edge.end.x());
40 y_max = y_max.max(edge.start.y()).max(edge.end.y());
41 }
42 if x_min < x_max && y_min < y_max {
43 Rect {
44 x_min,
45 y_min,
46 x_max,
47 y_max,
48 }
49 } else {
50 parent.ff_bbox
52 }
53 }
54 };
55
56 Self {
57 edges: restricted_edges,
58 ff_bbox,
59 }
60 }
61
62 pub fn n_edges(&self) -> usize {
63 self.edges.len()
64 }
65}
66
67impl<T: QTQueryable> CollidesWith<T> for QTHazPartial {
68 fn collides_with(&self, entity: &T) -> bool {
69 entity.collides_with(&self.ff_bbox) && self.edges.iter().any(|e| entity.collides_with(e))
71 }
72}