Final fixes
This commit is contained in:
70
src/boids.rs
70
src/boids.rs
@@ -11,39 +11,47 @@ impl Plugin for Boids {
|
|||||||
.add_systems(Update, (simulate_boids, update_boid_vel).chain());
|
.add_systems(Update, (simulate_boids, update_boid_vel).chain());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const PROTECTED_RANGE: f32 = 40.;
|
||||||
|
const AVOID_RANGE: f32 = 20.;
|
||||||
|
const ALIGN_RANGE: f32 = 300.;
|
||||||
|
const CO_RANGE: f32 = 200.;
|
||||||
|
|
||||||
|
const ALIGN_FACTOR: f32 = 0.125;
|
||||||
|
const CO_FACTOR: f32 = 0.05;
|
||||||
|
|
||||||
|
const MAX_RANGE: f32 = 500.;
|
||||||
|
const MAX_SPEED: f32 = 200.;
|
||||||
|
|
||||||
|
const GRID_SIZE: i32 = 30;
|
||||||
|
|
||||||
fn simulate_boids(time: Res<Time>, mut boids: Query<(&Transform, &mut Vel), With<Boid>>) {
|
fn simulate_boids(time: Res<Time>, mut boids: Query<(&Transform, &mut Vel), With<Boid>>) {
|
||||||
let mut combos = boids.iter_combinations_mut();
|
let mut combos = boids.iter_combinations_mut();
|
||||||
while let Some([mut a, mut b]) = combos.fetch_next() {
|
while let Some([mut a, mut b]) = combos.fetch_next() {
|
||||||
let mut a_total_vel = a.1.value;
|
let mut a_total_vel = a.1.value;
|
||||||
let mut b_total_vel = b.1.value;
|
let mut b_total_vel = b.1.value;
|
||||||
//Match Speed
|
//Align
|
||||||
let dist = a.0.translation - b.0.translation;
|
let dist = a.0.translation - b.0.translation;
|
||||||
let d = dist.length();
|
let d = dist.length();
|
||||||
if d <= 200. {
|
if d <= ALIGN_RANGE && d > PROTECTED_RANGE {
|
||||||
let avg_vel = (a.1.value + b.1.value) / 2.;
|
let avg_vel = (a.1.value + b.1.value) / 2.;
|
||||||
a_total_vel += ((avg_vel - a_total_vel) / 8.) * time.delta_seconds();
|
a_total_vel -= (avg_vel - a_total_vel) * ALIGN_FACTOR * time.delta_seconds();
|
||||||
b_total_vel -= ((avg_vel - b_total_vel) / 8.) * time.delta_seconds();
|
b_total_vel -= (avg_vel - b_total_vel) * ALIGN_FACTOR * time.delta_seconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Collision Avoidance
|
//Collision Avoidance
|
||||||
if d < 10. {
|
if d < AVOID_RANGE {
|
||||||
a_total_vel += dist * time.elapsed_seconds();
|
a_total_vel += dist * time.delta_seconds();
|
||||||
b_total_vel += -dist * time.elapsed_seconds();
|
b_total_vel += -dist * time.delta_seconds();
|
||||||
}
|
}
|
||||||
if d < 200. {
|
if d < CO_RANGE && d > PROTECTED_RANGE {
|
||||||
//Flocking
|
//Choesian
|
||||||
let avg_pos = (a.0.translation + b.0.translation) / 2.;
|
let avg_pos = ((b.0.translation - a.0.translation) / 2.) + a.0.translation;
|
||||||
a_total_vel += tend_to_point(a.0.translation, avg_pos) * 0.008 * time.elapsed_seconds();
|
a_total_vel +=
|
||||||
b_total_vel += tend_to_point(b.0.translation, avg_pos) * 0.008 * time.elapsed_seconds();
|
tend_to_point(a.0.translation, avg_pos) * CO_FACTOR * time.delta_seconds();
|
||||||
|
b_total_vel +=
|
||||||
|
tend_to_point(b.0.translation, avg_pos) * CO_FACTOR * time.delta_seconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
// println!("{}", a_total_vel.length());
|
|
||||||
//Forward Vel
|
|
||||||
// let speed = 20.;
|
|
||||||
// a_total_vel += a.0.up() * speed * time.delta_seconds();
|
|
||||||
// b_total_vel += b.0.up() * speed * time.delta_seconds();
|
|
||||||
|
|
||||||
a.1.value = a_total_vel;
|
a.1.value = a_total_vel;
|
||||||
b.1.value = b_total_vel;
|
b.1.value = b_total_vel;
|
||||||
}
|
}
|
||||||
@@ -51,13 +59,12 @@ fn simulate_boids(time: Res<Time>, mut boids: Query<(&Transform, &mut Vel), With
|
|||||||
for (t, mut v) in &mut boids {
|
for (t, mut v) in &mut boids {
|
||||||
//Tend to Center
|
//Tend to Center
|
||||||
let mut d = t.translation.length();
|
let mut d = t.translation.length();
|
||||||
let max_d = 500.;
|
if d > MAX_RANGE {
|
||||||
if d > max_d {
|
d -= MAX_RANGE;
|
||||||
d -= max_d;
|
d /= MAX_RANGE;
|
||||||
d /= max_d;
|
|
||||||
v.value += tend_to_point(t.translation, Vec3::ZERO)
|
v.value += tend_to_point(t.translation, Vec3::ZERO)
|
||||||
* time.elapsed_seconds()
|
* time.elapsed_seconds()
|
||||||
* d.remap(0., 1., 0., 0.1);
|
* d.remap(0., 1., 0., 0.5);
|
||||||
}
|
}
|
||||||
//Limit Velocity
|
//Limit Velocity
|
||||||
if v.value == Vec3::ZERO {
|
if v.value == Vec3::ZERO {
|
||||||
@@ -73,9 +80,8 @@ fn tend_to_point(from: Vec3, to: Vec3) -> Vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn limit_velocity(v: &Vel) -> Vec3 {
|
fn limit_velocity(v: &Vel) -> Vec3 {
|
||||||
let max_speed = 200.;
|
if v.value.length() > MAX_SPEED {
|
||||||
if v.value.length() > max_speed {
|
return v.value.normalize() * MAX_SPEED;
|
||||||
return v.value.normalize() * max_speed;
|
|
||||||
}
|
}
|
||||||
return v.value;
|
return v.value;
|
||||||
}
|
}
|
||||||
@@ -97,20 +103,14 @@ fn init(
|
|||||||
) {
|
) {
|
||||||
commands.spawn(Camera2dBundle::default());
|
commands.spawn(Camera2dBundle::default());
|
||||||
|
|
||||||
let size = 25;
|
for x in 0..GRID_SIZE {
|
||||||
|
for y in 0..GRID_SIZE {
|
||||||
for x in 0..size {
|
|
||||||
for y in 0..size {
|
|
||||||
let shape = Mesh2dHandle(meshes.add(Triangle2d::new(
|
let shape = Mesh2dHandle(meshes.add(Triangle2d::new(
|
||||||
Vec2::Y * 5.0,
|
Vec2::Y * 5.0,
|
||||||
Vec2::new(-5.0, -5.0),
|
Vec2::new(-5.0, -5.0),
|
||||||
Vec2::new(5.0, -5.0),
|
Vec2::new(5.0, -5.0),
|
||||||
)));
|
)));
|
||||||
let color = Color::hsl(
|
let color = Color::hsl(360.0 * (x as f32 / GRID_SIZE as f32), 1., 0.7);
|
||||||
360.0 * (x as f32 / size as f32),
|
|
||||||
y as f32 / size as f32,
|
|
||||||
0.7,
|
|
||||||
);
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Boid,
|
Boid,
|
||||||
Vel { value: Vec3::ZERO },
|
Vel { value: Vec3::ZERO },
|
||||||
|
|||||||
Reference in New Issue
Block a user