audubon/src/main.rs
2026-09-26 12:25:47 -07:00

116 lines
3.7 KiB
Rust

use bevy::{
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
input::keyboard::Key,
prelude::{
children, default, px, App, AssetServer, Assets, ButtonInput, Camera3d, ClearColor, Color,
Commands, DefaultPlugins, Entity, FontSize, GlobalAmbientLight, IntoScheduleConfigs, Mesh,
Mesh3d, MeshMaterial3d, Node, Plane3d, PositionType, Query, Res, ResMut, StandardMaterial,
Startup, Text, TextFont, Transform, Update, Vec2, Vec3, Visibility, Window,
},
};
use rstar::RTree;
use toids::{
init_naybs, rotate_camera, setup_channels, spawn_background, turkey_time, update_buddies,
update_naybs, update_pos, update_vel, BackgroundHandle, Config, LookAt, Naybs, Positions,
};
fn main() {
let config: toids::Config = argh::from_env();
App::new()
.add_plugins(DefaultPlugins)
.add_plugins((
FrameTimeDiagnosticsPlugin::default(),
LogDiagnosticsPlugin::default(),
))
.insert_resource(config)
.insert_resource(Positions::default())
.insert_resource(ClearColor(Color::srgb(0.64, 0.745, 0.937))) // a nice light blue
.insert_resource(GlobalAmbientLight {
color: Color::WHITE,
brightness: 150.0,
affects_lightmapped_meshes: true,
..Default::default()
})
.insert_resource(Naybs {
index: RTree::new(),
positions: None,
})
.insert_resource(BackgroundHandle::default())
.insert_resource(LookAt::default())
.add_systems(
Startup,
(setup_channels, setup, init_naybs, spawn_background).chain(),
)
.add_systems(Update, (update_pos, update_buddies, update_vel).chain())
.add_systems(
Update,
(rotate_camera, close_on_esc, update_naybs.after(update_pos)),
)
//.add_systems(Update, update_gizmos)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut positions: ResMut<Positions>,
config: Res<Config>,
models: Res<AssetServer>,
) {
let rand = &mut rand::rng();
commands.spawn((
Transform::from_xyz(0., 5.0, 25.).looking_at(Vec3::new(0.0, 5.0, 0.0), Vec3::Y),
Camera3d::default(),
));
// plane
commands.spawn((
Mesh3d(meshes.add(Mesh::from(Plane3d::new(Vec3::Y, Vec2::splat(500.0))))),
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.9, 0.3))),
Visibility::Visible,
Transform::default(),
));
// let toid_model = models.load("models/boid.glb#Scene0");
for _ in 0..config.toids {
turkey_time(&mut commands, rand, &models, &mut positions.0);
}
// instructions
commands.spawn((
Visibility::Visible,
Node {
position_type: PositionType::Absolute,
top: px(12.0),
left: px(12.0),
..default()
},
children![(
Text::new("Up and down for camera forward and back; hold shift to change height.\nLeft or right to move left or right.\nPress 'ESC' to quit."),
TextFont {
font_size: FontSize::Px(20.0),
..default()
},
)],
));
}
fn close_on_esc(
mut commands: Commands,
focused_windows: Query<(Entity, &Window)>,
input: Res<ButtonInput<Key>>,
mut handle: ResMut<BackgroundHandle>,
) {
for (window, focus) in focused_windows.iter() {
if !focus.focused {
continue;
}
if input.just_pressed(Key::Escape) {
drop((*handle).take());
commands.entity(window).despawn();
}
}
}