From 336992573e9a490e97781a5e5b05980b1bfda618 Mon Sep 17 00:00:00 2001 From: Robert Garrett Date: Thu, 11 Jul 2024 14:46:36 -0500 Subject: [PATCH] Completed velocity pointer gizmo Right-clicking toggles velocity sensing mode and the cursor gets a line that indicates the average velocity of the targeted points. There is a coefficient of 50.0 on the pointer magnitude. The boids move so slowly that the line is very short without this magnification. There is also something wrong with the math. The boids expand and slow down, but the velocity vector does not reflect this. It *grows* slightly and then stays at that size as the boids slowly approach a stop. When writing the average velocity function, I realized that it is **exactly** the same as the center of mass function. They're both just averaging a bunch of points. Both functions are implemented as pass- through calls to a general purpose Vec2 averaging function. The `impl Iterator<...>...` *is* actually necessary because of the use of `map()`s to filter out the boids parts from the spatial tree. --- src/birdoids_plugin.rs | 8 ++++++++ src/debug_plugin.rs | 19 +++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/birdoids_plugin.rs b/src/birdoids_plugin.rs index b694ee85..3d5ee311 100644 --- a/src/birdoids_plugin.rs +++ b/src/birdoids_plugin.rs @@ -208,6 +208,14 @@ fn cohesion( } pub(crate) fn center_of_boids(points: impl Iterator) -> Option { + average_of_vec2s(points) +} + +pub(crate) fn velocity_of_boids(points: impl Iterator) -> Option { + average_of_vec2s(points) +} + +fn average_of_vec2s(points: impl Iterator) -> Option { // Average the points by summing them all together, and dividing by // the total count. // Passing the points as an iterator means we lose the length of the diff --git a/src/debug_plugin.rs b/src/debug_plugin.rs index 71a4ee66..f7692c24 100644 --- a/src/debug_plugin.rs +++ b/src/debug_plugin.rs @@ -5,7 +5,7 @@ use bevy_spatial::{ }; use crate::birdoids_plugin::{ - center_of_boids, Acceleration, Boid, TrackedByKdTree, Velocity + center_of_boids, velocity_of_boids, Acceleration, Boid, TrackedByKdTree, Velocity }; const SCANRADIUS: f32 = 50.0; @@ -154,7 +154,22 @@ fn do_scan( ); } }, - ScannerMode::Velocity => todo!(), + ScannerMode::Velocity => { + if let Some(avg_velocity) = velocity_of_boids( + boids.iter().map(|item| { + let entity_id = item.1.unwrap_or_else(|| panic!("Entity has no ID!")); + let (_, vel, _) = boids_query.get(entity_id).unwrap_or_else(|_| panic!("Boid has no Velocity component!")); + (*vel).xy() * 50.0 + }) + ) { + // cursor_pos.translation is already in world space, so I can skip the window -> world transform like in update_cursor() + gizmos.line_2d( + cursor_pos.translation.xy(), + cursor_pos.translation.xy() + avg_velocity, + bevy::color::palettes::css::RED + ); + } + }, } }, }