bevy_spatial/
spatial_access.rs

1use bevy::prelude::*;
2
3use crate::{TComp, point::SpatialPoint};
4
5// todo: change Point to impl IntoPoint?
6#[allow(clippy::module_name_repetitions)]
7pub trait UpdateSpatialAccess: SpatialAccess {
8    /// Updates the underlying datastructure
9    ///
10    /// The boolean indicates if the point needs to be updated or is a existing point.
11    /// data should always include all points, even if they are not updated.
12    /// This is for datastructures like ``KDTree``, which need to be fully rebuilt.
13    fn update(
14        &mut self,
15        data: impl Iterator<Item = (Self::Point, bool)>,
16        removed: impl Iterator<Item = Entity>,
17    ) {
18        for (p, changed) in data {
19            if changed {
20                self.remove_point(p);
21                self.add(p);
22            }
23        }
24        for e in removed {
25            self.remove_entity(e);
26        }
27    }
28    /// Adds the point to the underlying datastructure.
29    fn add(&mut self, point: Self::Point);
30    /// Remove the point by coordinate + entity from the underlying datastructure.
31    fn remove_point(&mut self, point: Self::Point) -> bool;
32    /// Remove the point by entity from the underlying datastructure.
33    fn remove_entity(&mut self, entity: Entity) -> bool;
34    /// Clear the underlying datastructure, removing all points it contains.
35    fn clear(&mut self);
36}
37
38/// Trait for accessing point-based spatial datastructures.
39pub trait SpatialAccess: Send + Sync + 'static {
40    /// The point type, can be anything implementing [`SpatialPoint`].
41    type Point: SpatialPoint;
42    /// The marker component type marking the entities whos points are stored, used for accessing the component in trait bounds.
43    type Comp: TComp;
44    /// The type of a single query result.
45    type ResultT;
46
47    /// Get the nearest neighbour to `loc`.
48    /// Be aware that that distance to the returned point will be zero if `loc` is part of the datastructure.
49    fn nearest_neighbour(&self, loc: <Self::Point as SpatialPoint>::Vec) -> Option<Self::ResultT>;
50
51    /// Return the k nearest neighbours to `loc`.
52    fn k_nearest_neighbour(
53        &self,
54        loc: <Self::Point as SpatialPoint>::Vec,
55        k: usize,
56    ) -> Vec<Self::ResultT>;
57
58    /// Return all points which are within the specified distance.
59    fn within_distance(
60        &self,
61        loc: <Self::Point as SpatialPoint>::Vec,
62        distance: <Self::Point as SpatialPoint>::Scalar,
63    ) -> Vec<Self::ResultT>;
64}
65
66// TODO: SpatialAABBAccess trait definition - should it be separate from SpatialAccess or depend on it?