par_iter for update_vel

This commit is contained in:
Joe Ardent 2026-09-27 14:45:50 -07:00
parent 3d7663e032
commit 1d6d1ccf10

View file

@ -10,18 +10,16 @@ use super::{
}; };
// toid stuff // toid stuff
const SPEED: f32 = 6.0; const SPEED: f32 = 12.0;
const SPEED_DIFF_RANGE: f32 = 0.2; // +/- 10% const SPEED_DIFF_RANGE: f32 = 0.1;
const MAX_DELTA_V: f32 = std::f32::consts::PI * 1.5; // basically 360 const MAX_DELTA_V: f32 = std::f32::consts::PI * 2.0;
// degrees/sec
// how far from origin before really wanting to come back // how far from origin before really wanting to come back
const RADIUS: f32 = 40.0; const RADIUS: f32 = 30.0;
// how close to try to stay to your buddies // how close to try to stay to your buddies
const BUDDY_RADIUS: f32 = 10.0; const BUDDY_RADIUS: f32 = SPEED;
const MIN_ALTITUDE: f32 = 3.5; const MIN_ALTITUDE: f32 = 13.5;
pub fn setup_channels(mut commands: Commands) { pub fn setup_channels(mut commands: Commands) {
let (raw_tx, raw_rx) = bounded(1); let (raw_tx, raw_rx) = bounded(1);
@ -153,69 +151,71 @@ pub fn update_vel(
) { ) {
let dt = time.delta_secs(); let dt = time.delta_secs();
let max_delta = MAX_DELTA_V * dt; let max_delta = MAX_DELTA_V * dt;
for (xform, mut vel, toid, buddies, entity) in toids.iter_mut() { toids
let speed = toid.speed; .par_iter_mut()
let mut dir = vel.normalize(); .for_each(|(xform, mut vel, toid, buddies, entity)| {
let pos = xform.translation; let speed = toid.speed;
let original_dir = dir; let mut dir = vel.normalize();
let pos = xform.translation;
let original_dir = dir;
// find buddies and orient; point more towards further-away buddies // find buddies and orient; point more towards further-away buddies
for buddy in buddies.0.iter() { for buddy in buddies.0.iter() {
let bp = positions.get(buddy).unwrap(); let bp = positions.get(buddy).unwrap();
let bdir = *bp - pos; let bdir = *bp - pos;
let dist = bdir.length(); let dist = bdir.length();
let rot = Quat::from_rotation_arc(dir, bdir.normalize()); let rot = Quat::from_rotation_arc(dir, bdir.normalize());
let s = (dist / (BUDDY_RADIUS * 1.2)).min(1.0); let s = (dist / (BUDDY_RADIUS * 1.2)).min(1.0);
let rot = Quat::IDENTITY.slerp(rot, s); let rot = Quat::IDENTITY.slerp(rot, s);
dir = rot.mul_vec3(dir).normalize(); dir = rot.mul_vec3(dir).normalize();
} }
// avoid flying into neighbors // avoid flying into neighbors
let min_dist = speed; let min_dist = speed;
for neighbor in index for neighbor in index
.index .index
.locate_within_distance(pos.to_array(), min_dist) .locate_within_distance(pos.to_array(), min_dist * 10.0)
.filter(|n| n.data != entity) .filter(|n| n.data != entity)
{ {
let bp = Vec3::from_array(*neighbor.geom()); let bp = Vec3::from_array(*neighbor.geom());
let bdir = pos - bp; let bdir = pos - bp;
let dist = bdir.length(); let dist = bdir.length();
let s = 1.0 - (dist / min_dist).min(1.0); let s = 1.0 - (dist / min_dist).min(1.0);
let rot = Quat::from_rotation_arc(dir, bdir.normalize()); let rot = Quat::from_rotation_arc(dir, bdir.normalize());
let rot = Quat::IDENTITY.slerp(rot, s); let rot = Quat::IDENTITY.slerp(rot, s);
dir = rot.mul_vec3(dir).normalize(); dir = rot.mul_vec3(dir).normalize();
} }
// nudge toward origin if too far // nudge toward origin if too far
{ {
let dist = pos.length(); let dist = pos.length();
let toward_origin = -pos.normalize(); let toward_origin = -pos.normalize();
let s = (dist / RADIUS).min(1.0); let s = (dist / RADIUS).min(1.0);
let rot = Quat::from_rotation_arc(dir, toward_origin); let rot = Quat::from_rotation_arc(dir, toward_origin);
let rot = Quat::IDENTITY.slerp(rot, s); let rot = Quat::IDENTITY.slerp(rot, s);
dir = rot.mul_vec3(dir).normalize(); dir = rot.mul_vec3(dir).normalize();
} }
// nudge up if too low // nudge up if too low
if pos.y < MIN_ALTITUDE { if pos.y < MIN_ALTITUDE {
let dh = MIN_ALTITUDE - pos.y; let dh = MIN_ALTITUDE - pos.y;
let s = (dh / MIN_ALTITUDE).min(1.0); let s = (dh / MIN_ALTITUDE).min(1.0);
let rot = Quat::from_rotation_arc(dir, Vec3::Y); let rot = Quat::from_rotation_arc(dir, Vec3::Y);
let rot = Quat::IDENTITY.slerp(rot, s); let rot = Quat::IDENTITY.slerp(rot, s);
dir = rot.mul_vec3(dir).normalize(); dir = rot.mul_vec3(dir).normalize();
} }
// make sure velocity doesn't change too suddenly // make sure velocity doesn't change too suddenly
let delta = dir.dot(original_dir).acos(); let delta = dir.dot(original_dir).acos();
if delta > max_delta { if delta > max_delta {
let s = max_delta / delta; let s = max_delta / delta;
let rot = Quat::from_rotation_arc(original_dir, dir); let rot = Quat::from_rotation_arc(original_dir, dir);
let rot = Quat::IDENTITY.slerp(rot, s); let rot = Quat::IDENTITY.slerp(rot, s);
dir = rot.mul_vec3(original_dir).normalize(); dir = rot.mul_vec3(original_dir).normalize();
} }
**vel = dir * speed; **vel = dir * speed;
} });
} }
pub fn update_pos( pub fn update_pos(