Filter-map the entities to avoid self-alignment

The boids shouldn't try to align with themselves. That doesn't really
make any sense.
This commit is contained in:
2025-09-02 16:25:10 -05:00
parent 8b61d38636
commit 7b380196a5

View File

@@ -189,7 +189,7 @@ fn separation(
fn alignment( fn alignment(
spatial_tree: Res<KDTree2<TrackedByKdTree>>, spatial_tree: Res<KDTree2<TrackedByKdTree>>,
mut boids: Query<(&Transform, &mut Force), With<Boid>>, mut boids: Query<(Entity, &Transform, &mut Force), With<Boid>>,
boid_velocities: Query<&Velocity, With<Boid>>, boid_velocities: Query<&Velocity, With<Boid>>,
) { ) {
// for each boid // for each boid
@@ -199,17 +199,21 @@ fn alignment(
// perpendicular so that magnitude is constant // perpendicular so that magnitude is constant
// apply steering force // apply steering force
for (transform, mut force) in &mut boids { for (this_entt, transform, mut force) in &mut boids {
let neighbors = spatial_tree.within_distance(transform.translation.xy(), BOID_VIEW_RANGE); let neighbors = spatial_tree.within_distance(transform.translation.xy(), BOID_VIEW_RANGE);
// averaging divides by length. Guard against an empty set of neighbors // averaging divides by length. Guard against an empty set of neighbors
let (len, sum) = neighbors let (len, sum) = neighbors
.iter() .iter()
// Extract the velocities by `get()`ing from another query param. // Extract the velocities by `get()`ing from another query param.
.map(|(_pos, maybe_entt)| { .filter_map(|(_pos, maybe_entt)| {
let entt = maybe_entt let entt = maybe_entt
.expect("Neighbor boid has no Entity ID. I don't know what this means"); .expect("Neighbor boid has no Entity ID. I don't know what this means");
if this_entt == entt {
None
} else {
let vel = boid_velocities.get(entt).expect("Boid has no velocity!"); let vel = boid_velocities.get(entt).expect("Boid has no velocity!");
vel.xy() Some(vel.xy())
}
}) })
.enumerate() .enumerate()
.fold((0, Vec2::ZERO), |(_len, vel_acc), (idx, vel)| { .fold((0, Vec2::ZERO), |(_len, vel_acc), (idx, vel)| {