Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
use std::marker::PhantomData;
use crate::{
SpatialAccess,
point::{SpatialPoint, VecFromGlobalTransform, VecFromTransform},
spatial_access::UpdateSpatialAccess,
};
use bevy::{
ecs::schedule::{ScheduleLabel, SystemSet},
prelude::*,
};
/// Select which Transform to use when automatically updating the Spatial Datastructure.
#[derive(Clone, Default, Copy)]
pub enum TransformMode {
/// Uses the normal [`Transform`] for updating the Spatial Datastructure.
#[default]
Transform,
/// Uses the [`GlobalTransform`] for updating the Spatial Datastructure.
GlobalTransform,
}
// long term todo: add support for CustomCoordinate mode which uses a user-defined type implementing a trait like VecFromTransform
type GlamVec<S> = <<S as SpatialAccess>::Point as SpatialPoint>::Vec;
pub(crate) struct AutoT<SpatialDS>(PhantomData<SpatialDS>);
impl<SpatialDS> AutoT<SpatialDS>
where
GlamVec<SpatialDS>: VecFromTransform,
SpatialDS: UpdateSpatialAccess + Resource,
<SpatialDS as SpatialAccess>::Point: From<(Entity, GlamVec<SpatialDS>)>,
SpatialDS::Comp: Component,
{
#[allow(clippy::needless_pass_by_value)]
fn update_ds(
mut tree: ResMut<SpatialDS>,
changed: Query<(Entity, Ref<Transform>), With<SpatialDS::Comp>>,
mut removed: RemovedComponents<SpatialDS::Comp>,
) {
tree.update(
changed.iter().map(|(e, ch)| {
let changed = ch.is_changed();
(
(e, GlamVec::<SpatialDS>::from_transform(ch.into_inner())).into(),
changed,
)
}),
removed.read(),
);
}
pub fn build(app: &mut App, schedule: impl ScheduleLabel, set: impl SystemSet) {
app.add_systems(schedule, Self::update_ds.in_set(set));
}
}
pub(crate) struct AutoGT<SpatialDS>(PhantomData<SpatialDS>);
impl<SpatialDS> AutoGT<SpatialDS>
where
GlamVec<SpatialDS>: VecFromGlobalTransform,
SpatialDS: UpdateSpatialAccess + Resource,
<SpatialDS as SpatialAccess>::Point: From<(Entity, GlamVec<SpatialDS>)>,
SpatialDS::Comp: Component,
{
#[allow(clippy::needless_pass_by_value)]
fn update_ds(
mut tree: ResMut<SpatialDS>,
changed: Query<(Entity, Ref<GlobalTransform>), With<SpatialDS::Comp>>,
mut removed: RemovedComponents<SpatialDS::Comp>,
) {
tree.update(
changed.iter().map(|(e, ch)| {
let changed = ch.is_changed();
(
(e, GlamVec::<SpatialDS>::from_transform(ch.into_inner())).into(),
changed,
)
}),
removed.read(),
);
}
pub fn build(app: &mut App, schedule: impl ScheduleLabel, set: impl SystemSet) {
app.add_systems(schedule, Self::update_ds.in_set(set));
}
}

139
vendor/bevy_spatial/src/kdtree.rs vendored Normal file
View File

@@ -0,0 +1,139 @@
//! implementations to use [`kd_tree`] trees as a spatial datastructure in ``bevy_spatial``.
use bevy::prelude::*;
use kd_tree::{KdPoint, KdTree as BaseKdTree, KdTreeN};
use crate::{
TComp,
point::SpatialPoint,
spatial_access::{SpatialAccess, UpdateSpatialAccess},
};
use std::marker::PhantomData;
use bevy::prelude::Resource;
#[cfg(all(feature = "kdtree_rayon", target_arch = "wasm32"))]
compile_error!(
"bevy-spatial feature \"kdtree_rayon\" is incompatible with target_arch = \"wasm32\" builds. Disable default-features and enable kdtree"
);
macro_rules! kdtree_impl {
($pt:ty, $treename:ident) => {
impl KdPoint for $pt {
type Scalar = <$pt as SpatialPoint>::Scalar;
type Dim = <$pt as SpatialPoint>::Dimension;
fn at(&self, i: usize) -> Self::Scalar {
<Self as SpatialPoint>::at(self, i)
}
}
/// Resource for storing a ``KdTree``
#[derive(Resource)]
pub struct $treename<Comp> {
/// The ``KdTree``
pub tree: BaseKdTree<$pt>,
component_type: PhantomData<Comp>,
}
impl<Comp> Default for $treename<Comp> {
fn default() -> Self {
Self {
tree: default(),
component_type: PhantomData,
}
}
}
impl<Comp> SpatialAccess for $treename<Comp>
where
Comp: TComp,
{
type Point = $pt;
type Comp = Comp;
type ResultT = (<$pt as SpatialPoint>::Vec, Option<Entity>);
/// Get the nearest neighbour to a position.
fn nearest_neighbour(&self, loc: <$pt as SpatialPoint>::Vec) -> Option<Self::ResultT> {
let p: $pt = loc.into();
let res = self.tree.nearest(&p);
res.map(|point| (point.item.vec(), point.item.entity()))
}
/// Get the `k` neighbours to `loc`
///
/// If `loc` is the location of a tracked entity, you might want to skip the first.
fn k_nearest_neighbour(
&self,
loc: <$pt as SpatialPoint>::Vec,
k: usize,
) -> Vec<Self::ResultT> {
let p: $pt = loc.into();
self.tree
.nearests(&p, k)
.iter()
.map(|e| (e.item.vec(), e.item.entity()))
.collect()
}
/// Get all entities within a certain distance (radius) of `loc`
fn within_distance(
&self,
loc: <$pt as SpatialPoint>::Vec,
distance: <$pt as SpatialPoint>::Scalar,
) -> Vec<Self::ResultT> {
let distance: <$pt as KdPoint>::Scalar = distance.into();
if self.tree.len() == 0 {
vec![]
} else {
let p: $pt = loc.into();
self.tree
.within_radius(&p, distance)
.iter()
.map(|e| (e.vec(), e.entity()))
.collect()
}
}
}
impl<Comp: TComp> UpdateSpatialAccess for $treename<Comp> {
fn update(
&mut self,
data: impl Iterator<Item = (Self::Point, bool)>,
_: impl Iterator<Item = Entity>,
) {
#[cfg(all(feature = "kdtree_rayon", not(target_arch = "wasm32")))]
let tree =
KdTreeN::par_build_by_ordered_float(data.map(|(p, _)| p).collect::<Vec<_>>());
#[cfg(any(not(feature = "kdtree_rayon"), target_arch = "wasm32"))]
let tree =
KdTreeN::build_by_ordered_float(data.map(|(p, _)| p).collect::<Vec<_>>());
self.tree = tree;
}
fn add(&mut self, _: Self::Point) {}
fn remove_point(&mut self, _: Self::Point) -> bool {
false
}
fn remove_entity(&mut self, _: Entity) -> bool {
false
}
fn clear(&mut self) {
self.tree = KdTreeN::default();
}
}
};
}
kdtree_impl!(crate::point::Point2, KDTree2);
kdtree_impl!(crate::point::Point3, KDTree3);
kdtree_impl!(crate::point::Point3A, KDTree3A);
kdtree_impl!(crate::point::PointD2, KDTreeD2);
kdtree_impl!(crate::point::PointD3, KDTreeD3);

54
vendor/bevy_spatial/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,54 @@
#![warn(missing_docs)]
#![deny(clippy::pedantic)]
//! A bevy plugin to track your entities in spatial indices and query them.
//!
//! Quickstart using the `kdtree` feature:
//! ```
//! use bevy_spatial::{AutomaticUpdate, KDTree3, TransformMode, SpatialAccess};
//!
//! #[derive(Component, Default)]
//! struct TrackedByKDTree;
//!
//! fn main() {
//! App::new()
//! .add_plugin(AutomaticUpdate::<TrackedByKDTree>::new()
//! .with_frequency(Duration::from_secs_f32(0.3))
//! .with_transform(TransformMode::GlobalTransform))
//! .add_system(use_neighbour);
//! // ...
//! }
//!
//! type NNTree = KDTree3<TrackedByKDTree>; // type alias for later
//!
//! // spawn some entities with the TrackedByKDTree component
//!
//! fn use_neighbour(tree: Res<NNTree>){
//! if let Some((pos, entity)) = tree.nearest_neighbour(Vec3::ZERO) {
//! // pos: Vec3
//! // do something with the nearest entity here
//! }
//! }
//! ```
//!
//! For more details see [Examples](https://github.com/laundmo/bevy-spatial/tree/main/examples)
pub mod point;
mod spatial_access;
pub use self::spatial_access::SpatialAccess;
use bevy::prelude::Component;
mod timestep;
pub use self::timestep::TimestepLength;
pub mod kdtree;
mod plugin;
pub use plugin::{SpatialStructure, *};
mod automatic_systems;
pub use automatic_systems::TransformMode;
/// automatically implemented trait for all components which can be used as markers for automatic updates?
pub trait TComp: Component + Send + Sync + 'static {}
impl<T> TComp for T where T: Component + Send + Sync + 'static {}

185
vendor/bevy_spatial/src/plugin.rs vendored Normal file
View File

@@ -0,0 +1,185 @@
use std::{marker::PhantomData, time::Duration};
use bevy::{
ecs::schedule::{ScheduleLabel, SystemSet},
prelude::*,
};
use crate::{
TComp,
automatic_systems::{AutoGT, AutoT, TransformMode},
kdtree::{KDTree2, KDTree3, KDTree3A},
timestep::{TimestepLength, on_timer_changeable},
};
/// Default set for spatial datastructure updates. Can be overridden using [`AutomaticUpdate::with_set()`](crate::AutomaticUpdate)
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub struct SpatialSet;
/// Enum containing the different types of spatial datastructure compatible with [`AutomaticUpdate`]
#[derive(Copy, Clone, Default)]
pub enum SpatialStructure {
/// Corresponds to [`kdtree::KdTree2`](crate::kdtree::KDTree2)
KDTree2,
/// Corresponds to [`kdtree::KdTree3`](crate::kdtree::KDTree3)
#[default]
KDTree3,
/// Corresponds to [`kdtree::KdTree3A`](crate::kdtree::KDTree3A)
KDTree3A,
// Linear/naive (linfa?)
// Grid
// RStar
}
/// Plugin struct for setting up a spatial datastructure with automatic updating.
///
///
/// ```
/// #[derive(Component, Default)]
/// struct EntityMarker;
///
/// App::new()
/// .add_plugins(DefaultPlugins)
/// .add_plugin(AutomaticUpdate::<EntityMarker>::new()
/// .with_frequency(Duration::from_secs_f32(0.3))
/// .with_spatial_ds(SpatialStructure::KDTree2)
/// .with_transform(TransformMode::GlobalTransform)
/// )
///
/// ```
pub struct AutomaticUpdate<Comp, Set = SpatialSet, Schedule = Update>
where
Set: SystemSet,
Schedule: ScheduleLabel + Clone,
{
pub(crate) comp: PhantomData<Comp>,
pub(crate) set: Set,
pub(crate) schedule: Schedule,
pub(crate) frequency: Duration,
pub(crate) transform: TransformMode,
pub(crate) spatial_ds: SpatialStructure,
}
impl<Comp, Set: SystemSet, Schedule: ScheduleLabel + Clone> AutomaticUpdate<Comp, Set, Schedule> {
/// Create a new [`AutomaticUpdate`] with defaults. Will add to the default [`ScheduleLabel`]: [`Update`].
#[must_use]
pub fn new() -> AutomaticUpdate<Comp> {
AutomaticUpdate {
comp: PhantomData,
set: SpatialSet,
schedule: Update,
frequency: Duration::from_millis(50),
transform: TransformMode::Transform,
spatial_ds: default(),
}
}
/// Change the Bevy [`ScheduleLabel`] in which this plugin will put its systems.
pub fn with_schedule<NewSchedule: ScheduleLabel + Clone>(
self,
schedule: NewSchedule,
) -> AutomaticUpdate<Comp, Set, NewSchedule> {
// Struct filling for differing types is experimental. Have to manually list each.
AutomaticUpdate {
set: self.set,
schedule,
comp: PhantomData,
frequency: self.frequency,
transform: self.transform,
spatial_ds: self.spatial_ds,
}
}
/// Change the Bevy [`SystemSet`] in which this plugin will put its systems.
pub fn with_set<NewSet: SystemSet + Copy>(
self,
set: NewSet,
) -> AutomaticUpdate<Comp, NewSet, Schedule> {
// Struct filling for differing types is experimental. Have to manually list each.
AutomaticUpdate::<Comp, NewSet, Schedule> {
set,
schedule: self.schedule,
comp: PhantomData,
frequency: self.frequency,
transform: self.transform,
spatial_ds: self.spatial_ds,
}
}
/// Change which spatial datastructure is used.
///
/// expects one of:
/// - [`SpatialStructure::KDTree2`]
/// - [`SpatialStructure::KDTree3`] (default)
/// - [`SpatialStructure::KDTree3A`]
#[must_use]
pub fn with_spatial_ds(self, spatial_ds: SpatialStructure) -> Self {
Self { spatial_ds, ..self }
}
/// Change the update rate.
///
/// Expects a [Duration] which is the delay between updates.
#[must_use]
pub fn with_frequency(self, frequency: Duration) -> Self {
Self { frequency, ..self }
}
/// Change which Transform is used to extrat coordinates from.
///
/// - [`TransformMode::Transform`] (default)
/// - [`TransformMode::GlobalTransform`]
///
/// Note: using [`TransformMode::GlobalTransform`] might cause double frame-delays
/// as Transform->GlobalTransform propagation happens in the
/// [`TransformPropagate`](bevy::transform::TransformSystem::TransformPropagate) [`SystemSet`] in [`PostUpdate`](bevy::app::PostUpdate).
/// You can order this plugins systems by modifying the default [`SpatialSet`]
/// or using your own [`SystemSet`] by calling [`AutomaticUpdate::with_set`](Self::with_set)
#[must_use]
pub fn with_transform(self, transform: TransformMode) -> Self {
Self { transform, ..self }
}
}
impl<Comp: TComp, Set: SystemSet + Copy, Schedule: ScheduleLabel + Clone> Plugin
for AutomaticUpdate<Comp, Set, Schedule>
{
fn build(&self, app: &mut App) {
app.insert_resource(TimestepLength(self.frequency, PhantomData::<Comp>))
.configure_sets(
self.schedule.clone(),
self.set.run_if(on_timer_changeable::<Comp>),
);
match self.spatial_ds {
SpatialStructure::KDTree2 => app.init_resource::<KDTree2<Comp>>(),
SpatialStructure::KDTree3 => app.init_resource::<KDTree3<Comp>>(),
SpatialStructure::KDTree3A => app.init_resource::<KDTree3A<Comp>>(),
};
match self.transform {
TransformMode::Transform => match self.spatial_ds {
SpatialStructure::KDTree2 => {
AutoT::<KDTree2<Comp>>::build(app, self.schedule.clone(), self.set);
}
SpatialStructure::KDTree3 => {
AutoT::<KDTree3<Comp>>::build(app, self.schedule.clone(), self.set);
}
SpatialStructure::KDTree3A => {
AutoT::<KDTree3A<Comp>>::build(app, self.schedule.clone(), self.set);
}
},
TransformMode::GlobalTransform => match self.spatial_ds {
SpatialStructure::KDTree2 => {
AutoGT::<KDTree2<Comp>>::build(app, self.schedule.clone(), self.set);
}
SpatialStructure::KDTree3 => {
AutoGT::<KDTree3<Comp>>::build(app, self.schedule.clone(), self.set);
}
SpatialStructure::KDTree3A => {
AutoGT::<KDTree3A<Comp>>::build(app, self.schedule.clone(), self.set);
}
},
}
}
}

206
vendor/bevy_spatial/src/point.rs vendored Normal file
View File

@@ -0,0 +1,206 @@
//! The different point Traits and Types used by ``bevy_spatial``
//!
//! - [`Scalar`] is a Trait based on [`num_traits`] which is implemented for all numeric types used in Points.
//! - [`SpatialPoint`] is a Trait that represents a point in space and the Entity it was created from.
//! It defines some, common methods needed while working with these points in different spatial datastructures.
//! - [`IntoSpatialPoint`] is a Trait which is implemented for vector coordinate types for which a corresponding Point type exists.
//! Needs a [`Entity`] to include in the Point type.
//! - [`VecFromTransform`] and [`VecFromGlobalTransform`] used to extract the translation from the corresponding Transform.
//! Used for automatically updating the spatial datastructure.
use bevy::{math::Vec3A, prelude::*};
use num_traits::{Bounded, Num, Signed};
use std::fmt::Debug;
use typenum::Unsigned;
/// Trait implemented for all numeric types used in Points.
pub trait Scalar: Bounded + Num + Clone + Copy + Signed + PartialOrd + Debug {}
impl<T> Scalar for T where T: Bounded + Num + Clone + Copy + Signed + PartialOrd + Debug {}
/// Represents a point in space and the Entity it was created from.
///
/// Implements a bunch of common methods needed while working with these points in different spatial datastructures.
#[allow(clippy::module_name_repetitions)]
pub trait SpatialPoint: Copy + Clone + PartialEq + Debug {
/// The Scalar type of a vector, example: [`f32`], [`f64`]
type Scalar: Scalar;
/// The vector type itself, for example [`Vec3`]
type Vec: Send + Sync + IntoSpatialPoint;
/// The dimension of this vector, like [`typenum::U2`] [`typenum::U3`]
type Dimension: Unsigned;
/// Get the value at this index.
/// Used for datastructure specific implementations.
///
/// `nth` is always smaller than [`Self::Dimension`].
fn at(&self, nth: usize) -> Self::Scalar;
/// Get the squared distance of this point to another point of the same type.
fn distance_squared(&self, other: &Self) -> Self::Scalar;
/// Get the elementwise minimum between this and another point
fn min_point(&self, other: &Self) -> Self::Vec;
/// Get the elementwise maximum between this and another point
fn max_point(&self, other: &Self) -> Self::Vec;
/// Get the Entity associated with this point.
fn entity(&self) -> Option<Entity>;
/// Get a this points vector.
fn vec(&self) -> Self::Vec;
}
/// Trait implemented for vector coordinate types for which a corresponding Point type exists.
/// Used to convert from the vector coordinate types to the corresponding Point type by providing a Entity
#[allow(clippy::module_name_repetitions)]
pub trait IntoSpatialPoint: Send + Sync + Sized + Copy {
/// The resulting point type, for example [`Point3`]
type Point: SpatialPoint + From<(Entity, Self)> + Copy;
/// Converts from the implementing type to the point type with its Entity filled.
fn into_spatial_point(self, e: Entity) -> Self::Point
where
Self::Point: From<(Entity, Self)>,
{
(e, self).into()
}
}
macro_rules! impl_spatial_point {
($pointname:ident, $bvec:ty, $unit:ty, $dim:ty, $diml:literal) => {
/// Newtype over bevy/glam vectors, needed to allow implementing foreign spatial datastructure traits.
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct $pointname {
/// The vector of this Point
pub vec: $bvec,
/// The Entity associated with this Point
pub entity: Option<Entity>,
}
impl $pointname {
fn new(vec: $bvec, entity: Entity) -> Self {
$pointname {
vec,
entity: Some(entity),
}
}
fn from_vec(vec: $bvec) -> Self {
$pointname { vec, entity: None }
}
}
impl SpatialPoint for $pointname {
type Scalar = $unit;
type Vec = $bvec;
type Dimension = $dim;
#[inline]
fn at(&self, nth: usize) -> Self::Scalar {
self.vec[nth]
}
#[inline]
fn distance_squared(&self, other: &Self) -> Self::Scalar {
self.vec.distance_squared(other.vec)
}
#[inline]
fn min_point(&self, other: &Self) -> Self::Vec {
self.vec.min(other.vec)
}
#[inline]
fn max_point(&self, other: &Self) -> Self::Vec {
self.vec.max(other.vec)
}
#[inline]
fn entity(&self) -> Option<Entity> {
self.entity
}
#[inline]
fn vec(&self) -> Self::Vec {
self.vec
}
}
impl From<(Entity, $bvec)> for $pointname {
fn from(value: (Entity, $bvec)) -> Self {
$pointname::new(value.1, value.0)
}
}
impl From<($bvec, Entity)> for $pointname {
fn from(value: ($bvec, Entity)) -> Self {
$pointname::new(value.0, value.1)
}
}
impl From<$bvec> for $pointname {
fn from(value: $bvec) -> Self {
$pointname::from_vec(value)
}
}
impl IntoSpatialPoint for $bvec {
type Point = $pointname;
}
};
}
impl_spatial_point!(Point2, bevy::math::Vec2, f32, typenum::consts::U2, 2);
impl_spatial_point!(Point3, bevy::math::Vec3, f32, typenum::consts::U3, 3);
impl_spatial_point!(Point3A, bevy::math::Vec3A, f32, typenum::consts::U3, 3);
impl_spatial_point!(PointD2, bevy::math::DVec2, f64, typenum::consts::U2, 2);
impl_spatial_point!(PointD3, bevy::math::DVec3, f64, typenum::consts::U3, 3);
/// Helper trait for extracting the translation of a [`Transform`] to a specific vector type
/// Used for automatically updating the spatial datastructure.
pub trait VecFromTransform: IntoSpatialPoint {
/// Create this vector type from a [`Transform`]
fn from_transform(t: &Transform) -> Self;
}
impl VecFromTransform for Vec2 {
fn from_transform(t: &Transform) -> Self {
t.translation.truncate()
}
}
impl VecFromTransform for Vec3 {
fn from_transform(t: &Transform) -> Self {
t.translation
}
}
impl VecFromTransform for Vec3A {
fn from_transform(t: &Transform) -> Self {
t.translation.into()
}
}
/// Helper trait for extracting the translation of a [`GlobalTransform`] to a specific vector type
/// Used for automatically updating the spatial datastructure.
pub trait VecFromGlobalTransform: IntoSpatialPoint {
/// Create this vector type from a [`GlobalTransform`]
fn from_transform(t: &GlobalTransform) -> Self;
}
impl VecFromGlobalTransform for Vec2 {
fn from_transform(t: &GlobalTransform) -> Self {
t.translation().truncate()
}
}
impl VecFromGlobalTransform for Vec3 {
fn from_transform(t: &GlobalTransform) -> Self {
t.translation()
}
}
impl VecFromGlobalTransform for Vec3A {
fn from_transform(t: &GlobalTransform) -> Self {
t.translation().into()
}
}

View File

@@ -0,0 +1,66 @@
use bevy::prelude::*;
use crate::{TComp, point::SpatialPoint};
// todo: change Point to impl IntoPoint?
#[allow(clippy::module_name_repetitions)]
pub trait UpdateSpatialAccess: SpatialAccess {
/// Updates the underlying datastructure
///
/// The boolean indicates if the point needs to be updated or is a existing point.
/// data should always include all points, even if they are not updated.
/// This is for datastructures like ``KDTree``, which need to be fully rebuilt.
fn update(
&mut self,
data: impl Iterator<Item = (Self::Point, bool)>,
removed: impl Iterator<Item = Entity>,
) {
for (p, changed) in data {
if changed {
self.remove_point(p);
self.add(p);
}
}
for e in removed {
self.remove_entity(e);
}
}
/// Adds the point to the underlying datastructure.
fn add(&mut self, point: Self::Point);
/// Remove the point by coordinate + entity from the underlying datastructure.
fn remove_point(&mut self, point: Self::Point) -> bool;
/// Remove the point by entity from the underlying datastructure.
fn remove_entity(&mut self, entity: Entity) -> bool;
/// Clear the underlying datastructure, removing all points it contains.
fn clear(&mut self);
}
/// Trait for accessing point-based spatial datastructures.
pub trait SpatialAccess: Send + Sync + 'static {
/// The point type, can be anything implementing [`SpatialPoint`].
type Point: SpatialPoint;
/// The marker component type marking the entities whos points are stored, used for accessing the component in trait bounds.
type Comp: TComp;
/// The type of a single query result.
type ResultT;
/// Get the nearest neighbour to `loc`.
/// Be aware that that distance to the returned point will be zero if `loc` is part of the datastructure.
fn nearest_neighbour(&self, loc: <Self::Point as SpatialPoint>::Vec) -> Option<Self::ResultT>;
/// Return the k nearest neighbours to `loc`.
fn k_nearest_neighbour(
&self,
loc: <Self::Point as SpatialPoint>::Vec,
k: usize,
) -> Vec<Self::ResultT>;
/// Return all points which are within the specified distance.
fn within_distance(
&self,
loc: <Self::Point as SpatialPoint>::Vec,
distance: <Self::Point as SpatialPoint>::Scalar,
) -> Vec<Self::ResultT>;
}
// TODO: SpatialAABBAccess trait definition - should it be separate from SpatialAccess or depend on it?

55
vendor/bevy_spatial/src/timestep.rs vendored Normal file
View File

@@ -0,0 +1,55 @@
use std::{marker::PhantomData, time::Duration};
use bevy::{
prelude::{Local, Res, Resource},
time::{Time, Timer, TimerMode},
};
use crate::TComp;
/// Resource used for fixed timestep without repeats in the same frame (builtin timestep may run the system multiple times per frame).
///
/// To modify the timestep at runtime, a system like this can be used:
/// ```rust
/// fn update_timestep(
/// mut step: ResMut<TimestepElapsed<NearestNeighbourMarker>>,
/// ) {
/// if some_condition {
/// step.set_duration(Duration::from_millis(15)); // only update spatial datastructure every 15ms.
/// }
/// }
/// ```
/// `NearestNeighbourMarker` in this case refers to the (marker) component you also passed to the Plugin.
#[allow(clippy::module_name_repetitions)]
#[derive(Resource, Default)]
pub struct TimestepLength<Comp>(pub Duration, pub(crate) PhantomData<Comp>);
impl<Comp> TimestepLength<Comp> {
/// Set the length of the timestep.
pub fn set_duration(&mut self, duration: Duration) {
self.0 = duration;
}
/// Get the length of the timestep.
#[must_use]
pub fn get_duration(&self) -> Duration {
self.0
}
}
#[allow(clippy::needless_pass_by_value)]
pub fn on_timer_changeable<Comp>(
length: Res<TimestepLength<Comp>>,
time: Res<Time>,
mut timer: Local<Timer>,
) -> bool
where
Comp: TComp,
{
if length.get_duration() != timer.duration() {
timer.set_mode(TimerMode::Repeating);
timer.set_duration(length.get_duration());
}
timer.tick(time.delta());
timer.just_finished()
}