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    #[must_use]
22    pub fn from_irrelevant_qzones(
23        required_quality: usize,
24        haz_map: &SlotMap<HazKey, Hazard>,
25    ) -> Self {
26        HazKeyFilter(
27            haz_map
28                .iter()
29                .filter_map(|(hkey, h)| {
30                    match h.entity {
31                        HazardEntity::InferiorQualityZone { quality, .. }
32                            if quality < required_quality =>
33                        {
34                            // Only consider inferior quality zones below the required quality
35                            Some((hkey, ()))
36                        }
37                        _ => None,
38                    }
39                })
40                .collect(),
41        )
42    }
43}
44
45impl HazardFilter for HazKeyFilter {
46    fn is_irrelevant(&self, haz_key: HazKey) -> bool {
47        self.0.contains_key(haz_key)
48    }
49}
50
51/// Deems hazards induced by itself as irrelevant.
52impl HazardFilter for HazKey {
53    fn is_irrelevant(&self, hk: HazKey) -> bool {
54        *self == hk
55    }
56}
57
58/// Deems no hazards as irrelevant.
59#[derive(Clone, Debug)]
60pub struct NoFilter;
61
62impl HazardFilter for NoFilter {
63    fn is_irrelevant(&self, _haz_key: HazKey) -> bool {
64        false
65    }
66}
67
68/// Implements [`HazardFilter`] for any type that implements [`HazardCollector`].
69/// Any [`HazardEntity`]s that are already in the collector are considered irrelevant.
70impl<T> HazardFilter for T
71where
72    T: HazardCollector,
73{
74    fn is_irrelevant(&self, hkey: HazKey) -> bool {
75        self.contains_key(hkey)
76    }
77}