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?