jagua_rs/collision_detection/hazards/
filter.rs

1use crate::collision_detection::hazards::collector::HazardCollector;
2use crate::collision_detection::hazards::{HazKey, Hazard, HazardEntity};
3use slotmap::{SecondaryMap, SlotMap};
4
5/// Trait for filters to ignore all [`Hazard`]s induced by specific [`HazardEntity`]s.
6/// Enables collision queries to ignore specific hazards during the check.
7pub trait HazardFilter {
8    fn is_irrelevant(&self, haz_key: HazKey) -> bool;
9}
10
11/// Deems hazards with specific [`HazKey`]'s as irrelevant.
12#[derive(Clone, Debug)]
13pub struct HazKeyFilter(pub SecondaryMap<HazKey, ()>);
14
15impl HazKeyFilter {
16    pub fn from_keys(keys: impl IntoIterator<Item = HazKey>) -> Self {
17        HazKeyFilter(keys.into_iter().map(|k| (k, ())).collect())
18    }
19
20    /// Creates a filter that deems all inferior quality zones above or at a certain quality as irrelevant.
21    pub fn from_irrelevant_qzones(
22        required_quality: usize,
23        haz_map: &SlotMap<HazKey, Hazard>,
24    ) -> Self {
25        HazKeyFilter(
26            haz_map
27                .iter()
28                .filter_map(|(hkey, h)| {
29                    match h.entity {
30                        HazardEntity::InferiorQualityZone { quality, .. }
31                            if quality < required_quality =>
32                        {
33                            // Only consider inferior quality zones below the required quality
34                            Some((hkey, ()))
35                        }
36                        _ => None,
37                    }
38                })
39                .collect(),
40        )
41    }
42}
43
44impl HazardFilter for HazKeyFilter {
45    fn is_irrelevant(&self, haz_key: HazKey) -> bool {
46        self.0.contains_key(haz_key)
47    }
48}
49
50/// Deems hazards induced by itself as irrelevant.
51impl HazardFilter for HazKey {
52    fn is_irrelevant(&self, hk: HazKey) -> bool {
53        *self == hk
54    }
55}
56
57/// Deems no hazards as irrelevant.
58#[derive(Clone, Debug)]
59pub struct NoFilter;
60
61impl HazardFilter for NoFilter {
62    fn is_irrelevant(&self, _haz_key: HazKey) -> bool {
63        false
64    }
65}
66
67/// Implements [`HazardFilter`] for any type that implements [`HazardCollector`].
68/// Any [`HazardEntity`]s that are already in the collector are considered irrelevant.
69impl<T> HazardFilter for T
70where
71    T: HazardCollector,
72{
73    fn is_irrelevant(&self, hkey: HazKey) -> bool {
74        self.contains_key(hkey)
75    }
76}