From b51c75ddb821c6faf1c7e1b70b38382c96e9e21e Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Sat, 25 Nov 2023 14:46:43 -0800 Subject: [PATCH] swarms, but doesn't flock --- src/lib.rs | 34 +++++++++++++++++++++++++--------- src/main.rs | 4 ++-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b583547..2195abd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,11 +2,14 @@ use argh::FromArgs; use bevy::prelude::*; // toid -const SPEED: f32 = 1.0; +const SPEED: f32 = 10.0; const SPEED_DIFF_RANGE: f32 = 0.08; // +/- 8% // how far from origin before really wanting to come back -const RADIUS: f32 = 100.0; +const RADIUS: f32 = 800.0; + +// how close to try to stay to your buddies +const BUDDY_RADIUS: f32 = 15.0; const MIN_ALTITUDE: f32 = 1.5; @@ -45,8 +48,12 @@ pub fn turkey_time( let speed = SPEED + (SPEED * speed_diff); let vel = unit_vec(r) * speed; let buddies = r.gen_range(6..=8); + let spatial_bundle = SpatialBundle { + transform: Transform::from_xyz(0.0, MIN_ALTITUDE + 0.1, 0.0), + ..Default::default() + }; commands - .spawn(SpatialBundle::default()) + .spawn(spatial_bundle) .insert((Velocity(vel), Buddies::default(), Toid { speed, buddies })) .with_children(|t| { t.spawn(SceneBundle { @@ -96,21 +103,30 @@ pub fn update_vel( let dt = time.delta_seconds(); for (xform, mut vel, toid) in toids.iter_mut() { let speed = toid.speed; - let mut dir = xform.forward(); + let mut dir = vel.normalize(); let pos = xform.translation; // nudge up if too low if pos.y < MIN_ALTITUDE { let dh = MIN_ALTITUDE - pos.y; - let pct = (dh / MIN_ALTITUDE).min(1.0); - let up = Quat::from_rotation_arc(dir, Vec3::Y); - let rot = xform.rotation.slerp(up, pct); + let pct = (dh / MIN_ALTITUDE).min(1.0).powi(2); + let rot = Quat::from_rotation_arc(dir, Vec3::Y); + let (axis, ang) = rot.to_axis_angle(); + let rot = Quat::from_axis_angle(axis, ang * pct).normalize(); dir = rot.mul_vec3(dir); } // nudge toward origin if too far - let dist = pos.length(); - + { + let dist = pos.length(); + let toward_origin = -pos.normalize(); + let forward = dir.normalize(); + let rot = Quat::from_rotation_arc(forward, toward_origin); + let pct = (dist / RADIUS).min(1.0); + let (axis, ang) = rot.to_axis_angle(); + let rot = Quat::from_axis_angle(axis, ang * pct).normalize(); + dir = rot.mul_vec3(dir); + } // find buddies and orient: point more towards further-away buddies **vel = dir * speed; diff --git a/src/main.rs b/src/main.rs index a30fe70..0e72a20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ fn main() { Update, ( update_vel, - add_gizmos, + //add_gizmos, update_pos, update_buddies, rotate_camera, @@ -37,7 +37,7 @@ fn setup( let rand = &mut rand::thread_rng(); commands.spawn(Camera3dBundle { - transform: Transform::from_xyz(0., 3.5, 10.).looking_at(Vec3::ZERO, Vec3::Y), + transform: Transform::from_xyz(0., 3.5, 40.).looking_at(Vec3::new(0.0, 10.0, 0.0), Vec3::Y), ..default() }); // plane