From 3a680a4ea22f2e3af2873ebe6a4ce4a6fafa8631 Mon Sep 17 00:00:00 2001 From: Robert Garrett Date: Tue, 9 Jul 2024 11:56:52 -0500 Subject: [PATCH] Added bevy_spatial for boid interactions I'm finally starting on the actual Boids flocking algorithm parts. I don't want to iterate over all the things, and Bevy doesn't seem to have fast collision testing yet, so I've reached for bevy_spatial to track my Boids. --- Cargo.lock | 80 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/birdoids_plugin.rs | 41 ++++++++++++++++++++-- 3 files changed, 119 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 665fdcc6..2ca3d90d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -308,6 +308,7 @@ name = "bevy-testing" version = "0.1.0" dependencies = [ "bevy", + "bevy_spatial", ] [[package]] @@ -903,6 +904,18 @@ dependencies = [ "uuid", ] +[[package]] +name = "bevy_spatial" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0857f70fec5515c9ec93d23f5d4bf9fd9d9863198ce64c5878de5fab1a852d" +dependencies = [ + "bevy", + "kd-tree", + "num-traits", + "typenum", +] + [[package]] name = "bevy_sprite" version = "0.14.0" @@ -1521,6 +1534,25 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -2178,6 +2210,19 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kd-tree" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89ee4e60e82cf7024e5e94618c646fbf61ce7501dc5898b3d12786442d3682" +dependencies = [ + "num-traits", + "ordered-float", + "paste", + "rayon", + "typenum", +] + [[package]] name = "khronos-egl" version = "6.0.0" @@ -2808,6 +2853,15 @@ dependencies = [ "libredox", ] +[[package]] +name = "ordered-float" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ff2cf528c6c03d9ed653d6c4ce1dc0582dc4af309790ad92f07c1cd551b0be" +dependencies = [ + "num-traits", +] + [[package]] name = "overload" version = "0.1.1" @@ -3028,6 +3082,26 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "rectangle-pack" version = "0.4.2" @@ -3512,6 +3586,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf" +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-ident" version = "1.0.12" diff --git a/Cargo.toml b/Cargo.toml index c33213d6..43645bf9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] bevy = "0.14.0" +bevy_spatial = "0.9.0" [profile.dev] opt-level = 1 diff --git a/src/birdoids_plugin.rs b/src/birdoids_plugin.rs index ff7afeb4..b22633e4 100644 --- a/src/birdoids_plugin.rs +++ b/src/birdoids_plugin.rs @@ -1,16 +1,33 @@ +use std::time::Duration; + use bevy::{prelude::*, sprite::MaterialMesh2dBundle}; +use bevy_spatial::{ + AutomaticUpdate, + SpatialAccess, + TransformMode, + kdtree::KDTree2, +}; const BACKGROUND_COLOR: Color = Color::srgb(0.4, 0.4, 0.4); const PLAYERBOID_COLOR: Color = Color::srgb(1.0, 0.0, 0.0); const TURN_FACTOR: f32 = 1.; - +const BOID_VIEW_RANGE: f32 = 50.0; pub struct BoidsPlugin; impl Plugin for BoidsPlugin { fn build(&self, app: &mut App) { - app.insert_resource(ClearColor(BACKGROUND_COLOR)) + app + .add_plugins(AutomaticUpdate::::new() + .with_frequency(Duration::from_secs_f32(0.3)) + .with_transform(TransformMode::GlobalTransform)) + .insert_resource(ClearColor(BACKGROUND_COLOR)) .add_systems(Startup, (spawn_camera, spawn_boids)) - .add_systems(FixedUpdate, (apply_velocity, turn_if_edge, check_keyboard)); + .add_systems(FixedUpdate, ( + apply_velocity, + turn_if_edge, + check_keyboard, + cohesion, + )); } } @@ -25,10 +42,14 @@ struct PlayerBoid; #[derive(Component, Deref, DerefMut)] struct Velocity(Vec3); +#[derive(Component)] +struct TrackedByKdTree; + #[derive(Bundle)] struct BoidBundle { boid: Boid, velocity: Velocity, + spatial: TrackedByKdTree, } impl BoidBundle { @@ -36,6 +57,7 @@ impl BoidBundle { Self { boid: Boid, velocity: Velocity(vel), + spatial: TrackedByKdTree, } } } @@ -132,3 +154,16 @@ fn check_keyboard( **pvelocity = **pvelocity + dir.extend(0.0); } + +fn cohesion( + spatial_tree: Res>, + mut query: Query<&mut Boid, With>, + player: Query<&Transform, With>, +) { + let player_transform = player.get_single().unwrap(); + + let neighbors = spatial_tree.within_distance( + player_transform.translation.xy(), + BOID_VIEW_RANGE + ); +}