update camera to follow center of flock

This commit is contained in:
Joe Ardent 2023-12-03 12:49:30 -08:00
parent 2872643acc
commit 7a97abdeb1
5 changed files with 70 additions and 52 deletions

4
.rustfmt.toml Normal file
View file

@ -0,0 +1,4 @@
imports_granularity = "Crate"
group_imports = "StdExternalCrate"
wrap_comments = true
edition = "2021"

BIN
assets/models/toid.glb Normal file

Binary file not shown.

View file

@ -8,15 +8,15 @@ use bevy_spatial::{kdtree::KDTree3, SpatialAccess};
pub type NNTree = KDTree3<Toid>; pub type NNTree = KDTree3<Toid>;
// toid stuff // toid stuff
const SPEED: f32 = 5.0; const SPEED: f32 = 2.0;
const SPEED_DIFF_RANGE: f32 = 0.1; // +/- 10% const SPEED_DIFF_RANGE: f32 = 0.1; // +/- 10%
const MAX_DELTA_V: f32 = std::f32::consts::PI * 2.0; // basically 360 degrees/sec const MAX_DELTA_V: f32 = std::f32::consts::PI * 2.0; // basically 360 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 = 50.0; const RADIUS: f32 = 40.0;
// how close to try to stay to your buddies // how close to try to stay to your buddies
const BUDDY_RADIUS: f32 = 30.0; const BUDDY_RADIUS: f32 = 10.0;
const MIN_ALTITUDE: f32 = 3.5; const MIN_ALTITUDE: f32 = 3.5;
@ -43,6 +43,9 @@ pub struct Toid {
pub buddies: usize, pub buddies: usize,
} }
#[derive(Debug, Default, Clone, Copy, Deref, DerefMut, Resource)]
pub struct LookAt(Vec3);
pub fn turkey_time( pub fn turkey_time(
commands: &mut Commands, commands: &mut Commands,
scene: &Handle<Scene>, scene: &Handle<Scene>,
@ -67,10 +70,11 @@ pub fn turkey_time(
scene: scene.to_owned(), scene: scene.to_owned(),
..Default::default() ..Default::default()
}) })
.insert(Transform::from_rotation(Quat::from_axis_angle( .insert(Transform::default());
Vec3::Y, // .insert(Transform::from_rotation(Quat::from_axis_angle(
-std::f32::consts::FRAC_PI_2, // Vec3::Y,
))); // -std::f32::consts::FRAC_PI_2,
// )));
}) })
.id() .id()
} }
@ -101,7 +105,7 @@ pub fn update_vel(
} }
// avoid flying into neighbors // avoid flying into neighbors
let min_dist = speed / 2.0; let min_dist = speed;
for neighbor in index for neighbor in index
.within_distance(pos, min_dist) .within_distance(pos, min_dist)
.iter() .iter()
@ -151,15 +155,19 @@ pub fn update_vel(
pub fn update_pos( pub fn update_pos(
mut toids: Query<(&mut Transform, &Velocity, Entity), With<Toid>>, mut toids: Query<(&mut Transform, &Velocity, Entity), With<Toid>>,
mut positions: ResMut<Positions>, mut positions: ResMut<Positions>,
mut lookat: ResMut<LookAt>,
time: Res<Time>, time: Res<Time>,
) { ) {
let mut new_look = Vec3::ZERO;
let dt = time.delta_seconds(); let dt = time.delta_seconds();
for (mut xform, vel, entity) in toids.iter_mut() { for (mut xform, vel, entity) in toids.iter_mut() {
let look_at = xform.translation + vel.0; let look_at = xform.translation + vel.0;
xform.translation += vel.0 * dt; xform.translation += vel.0 * dt;
xform.look_at(look_at, Vec3::Y); xform.look_at(look_at, Vec3::Y);
*positions.entry(entity).or_insert(Vec3::ZERO) = xform.translation; *positions.entry(entity).or_insert(Vec3::ZERO) = xform.translation;
new_look += xform.translation;
} }
**lookat = new_look / positions.len() as f32;
} }
pub fn update_buddies( pub fn update_buddies(
@ -170,7 +178,6 @@ pub fn update_buddies(
let d2 = (BUDDY_RADIUS * 1.5).powi(2); let d2 = (BUDDY_RADIUS * 1.5).powi(2);
for (xform, entity, toid, mut buddies) in toids.iter_mut() { for (xform, entity, toid, mut buddies) in toids.iter_mut() {
let pos = xform.translation; let pos = xform.translation;
for buddy in buddies.clone().iter() { for buddy in buddies.clone().iter() {
let bp = positions.get(buddy).unwrap(); let bp = positions.get(buddy).unwrap();
let bd2 = (*bp - pos).length_squared(); let bd2 = (*bp - pos).length_squared();
@ -192,6 +199,53 @@ pub fn update_buddies(
} }
} }
pub fn update_gizmos(toids: Query<&Transform, With<Toid>>, mut gizmos: Gizmos) {
for toid in toids.iter() {
let pos = toid.translation;
let up = toid.up();
let forward = toid.forward();
let right = toid.right();
gizmos.ray(pos, pos + forward, Color::RED);
gizmos.ray(pos, pos + up, Color::BLUE);
gizmos.ray(pos, pos + right, Color::GREEN);
}
}
pub fn rotate_camera(
mut query: Query<&mut Transform, With<Camera>>,
keys: Res<Input<KeyCode>>,
lookat: Res<LookAt>,
) {
let mut xform = query.single_mut();
let forward = xform.forward() * 0.7;
let right = xform.right();
if keys.pressed(KeyCode::Right) {
xform.translation += right;
}
if keys.pressed(KeyCode::Left) {
xform.translation -= right;
}
if keys.pressed(KeyCode::Up) {
if keys.pressed(KeyCode::ShiftLeft) || keys.pressed(KeyCode::ShiftRight) {
xform.translation += Vec3::Y;
} else {
xform.translation += forward;
}
}
if keys.pressed(KeyCode::Down) {
if keys.pressed(KeyCode::ShiftLeft) || keys.pressed(KeyCode::ShiftRight) {
xform.translation -= Vec3::Y;
} else {
xform.translation -= forward;
}
}
xform.look_at(**lookat, Vec3::Y);
}
//-************************************************************************ //-************************************************************************
// util // util
//-************************************************************************ //-************************************************************************

View file

@ -25,9 +25,11 @@ fn main() {
color: Color::WHITE, color: Color::WHITE,
brightness: 1.0, brightness: 1.0,
}) })
.insert_resource(LookAt::default())
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (update_pos, update_buddies, update_vel).chain()) .add_systems(Update, (update_pos, update_buddies, update_vel).chain())
.add_systems(Update, (rotate_camera, bevy::window::close_on_esc)) .add_systems(Update, (rotate_camera, bevy::window::close_on_esc))
//.add_systems(Update, update_gizmos)
.run(); .run();
} }
@ -60,7 +62,7 @@ fn setup(
// instructions // instructions
commands.spawn( commands.spawn(
TextBundle::from_section( TextBundle::from_section(
"Up and down for camera forward and back; hold shift to change height.\nLeft and right to rotate camera; hold shift to translate.\nPress 'r' to look back at the origin. Press 'ESC' to quit.", "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.",
TextStyle { TextStyle {
font_size: 20., font_size: 20.,
..default() ..default()
@ -74,45 +76,3 @@ fn setup(
}), }),
); );
} }
fn rotate_camera(mut query: Query<&mut Transform, With<Camera>>, keys: Res<Input<KeyCode>>) {
let mut xform = query.single_mut();
let forward = xform.forward() * 0.7;
let right = xform.right();
if keys.pressed(KeyCode::Right) {
if keys.pressed(KeyCode::ShiftLeft) || keys.pressed(KeyCode::ShiftRight) {
xform.translation += right;
} else {
xform.rotate(Quat::from_rotation_y(-0.08));
}
}
if keys.pressed(KeyCode::Left) {
if keys.pressed(KeyCode::ShiftLeft) || keys.pressed(KeyCode::ShiftRight) {
xform.translation -= right;
} else {
xform.rotate(Quat::from_rotation_y(0.08));
}
}
if keys.pressed(KeyCode::Up) {
if keys.pressed(KeyCode::ShiftLeft) || keys.pressed(KeyCode::ShiftRight) {
xform.translation += Vec3::Y;
} else {
xform.translation += forward;
}
}
if keys.pressed(KeyCode::Down) {
if keys.pressed(KeyCode::ShiftLeft) || keys.pressed(KeyCode::ShiftRight) {
xform.translation -= Vec3::Y;
} else {
xform.translation -= forward;
}
}
if keys.just_pressed(KeyCode::R) {
let height = xform.translation.y;
xform.look_at(Vec3::new(0.0, height, 0.0), Vec3::Y);
}
}

View file