par_iter for update_vel
This commit is contained in:
parent
3d7663e032
commit
1d6d1ccf10
1 changed files with 65 additions and 65 deletions
130
src/systems.rs
130
src/systems.rs
|
|
@ -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(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue