audubon/src/lib.rs

123 lines
3.4 KiB
Rust
Raw Normal View History

2023-11-25 01:09:10 +00:00
use argh::FromArgs;
use bevy::prelude::*;
2023-11-25 19:24:43 +00:00
const SPEED: f32 = 1.0;
2023-11-25 06:40:47 +00:00
const SPEED_DIFF_RANGE: f32 = 0.08; // +/- 8%
2023-11-25 19:24:43 +00:00
const RADIUS: f32 = 1_000.0;
pub type Point = [f32; 3];
pub type Toint = rstar::primitives::GeomWithData<Point, Entity>;
2023-11-25 01:09:10 +00:00
#[derive(Debug, FromArgs, Resource)]
/// Toid Watching
pub struct Config {
/// how many Toids to spawn
#[argh(option, short = 't', default = "100")]
pub toids: usize,
}
2023-11-25 19:24:43 +00:00
#[derive(Resource, Deref, DerefMut, Default)]
2023-11-25 01:09:10 +00:00
pub struct Index(pub rstar::RTree<Toint>);
2023-11-25 19:24:43 +00:00
#[derive(Resource, Deref, DerefMut, Default)]
2023-11-25 06:40:47 +00:00
pub struct Positions(pub std::collections::HashMap<Entity, Vec3>);
2023-11-25 01:09:10 +00:00
#[derive(Component, Debug, Clone, Deref, DerefMut, Default)]
pub struct Buddies(Vec<Entity>);
#[derive(Component, Debug, Clone, Deref, DerefMut, Default)]
pub struct Velocity(Vec3);
#[derive(Component)]
2023-11-25 06:40:47 +00:00
pub struct Toid {
pub speed: f32,
2023-11-25 19:24:43 +00:00
pub buddies: usize,
2023-11-25 06:40:47 +00:00
}
2023-11-25 01:09:10 +00:00
2023-11-25 06:40:47 +00:00
pub fn turkey_time(
commands: &mut Commands,
scene: &Handle<Scene>,
r: &mut impl rand::prelude::Rng,
) -> Entity {
let speed_diff = r.gen_range(-SPEED_DIFF_RANGE..=SPEED_DIFF_RANGE);
let speed = SPEED + (SPEED * speed_diff);
let vel = unit_vec(r) * speed;
2023-11-25 19:24:43 +00:00
let buddies = r.gen_range(6..=8);
2023-11-25 01:09:10 +00:00
commands
.spawn(SpatialBundle::default())
2023-11-25 19:24:43 +00:00
.insert((Velocity(vel), Buddies::default(), Toid { speed, buddies }))
2023-11-25 01:09:10 +00:00
.with_children(|t| {
t.spawn(SceneBundle {
scene: scene.to_owned(),
..Default::default()
})
.insert(Transform::from_rotation(Quat::from_axis_angle(
Vec3::Y,
-std::f32::consts::FRAC_PI_2,
)));
})
.id()
}
pub fn add_gizmos(mut gizmos: Gizmos, toids: Query<(&Transform, Entity), With<Toid>>) {
let gizmos = &mut gizmos;
for (pos, _entity) in toids.iter() {
let nudge = pos.up() * 0.15;
let rpos = pos.translation + nudge;
gizmos.ray(rpos, pos.forward(), Color::RED);
}
}
2023-11-25 06:40:47 +00:00
pub fn update_pos(
mut toids: Query<(&mut Transform, &Velocity, Entity)>,
time: Res<Time>,
mut index: Res<Index>,
) {
let dt = time.delta_seconds();
for (mut xform, vel, _entity) in toids.iter_mut() {
2023-11-25 19:24:43 +00:00
xform.translation += vel.0 * dt;
let look_at = xform.translation + vel.0;
xform.look_at(look_at, Vec3::Y);
2023-11-25 06:40:47 +00:00
}
}
pub fn update_vel(
mut toids: Query<(&Transform, &mut Velocity, &Toid), With<Toid>>,
time: Res<Time>,
) {
let dt = time.delta_seconds();
for (xform, mut vel, toid) in toids.iter_mut() {
let speed = toid.speed;
let mut dir = xform.forward();
// nudge up if too low
// nudge toward origin if too far
// find buddies and orient: point more towards further-away buddies
}
}
pub fn update_buddies(mut toids: Query<(&Transform, Entity, &mut Buddies)>, index: Res<Index>) {}
//-************************************************************************
// util
//-************************************************************************
2023-11-25 19:24:43 +00:00
pub fn unit_vec(r: &mut impl rand::Rng) -> Vec3 {
2023-11-25 06:40:47 +00:00
let mut x1: f32 = 0.0;
let mut x2: f32 = 0.0;
let mut ssum = std::f32::MAX;
while ssum >= 1.0 {
x1 = r.gen_range(-1.0..=1.0);
x2 = r.gen_range(-1.0..=1.0);
ssum = x1.powi(2) + x2.powi(2);
}
let sqrt = (1.0 - ssum).sqrt();
let x = 2.0 * x1 * sqrt;
let y = 2.0 * x2 * sqrt;
let z = 1.0 - 2.0 * ssum;
Vec3::new(x, y, z).normalize()
}