update camera to follow center of flock
This commit is contained in:
parent
2872643acc
commit
7a97abdeb1
5 changed files with 70 additions and 52 deletions
4
.rustfmt.toml
Normal file
4
.rustfmt.toml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
imports_granularity = "Crate"
|
||||||
|
group_imports = "StdExternalCrate"
|
||||||
|
wrap_comments = true
|
||||||
|
edition = "2021"
|
BIN
assets/models/toid.glb
Normal file
BIN
assets/models/toid.glb
Normal file
Binary file not shown.
72
src/lib.rs
72
src/lib.rs
|
@ -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
|
||||||
//-************************************************************************
|
//-************************************************************************
|
||||||
|
|
46
src/main.rs
46
src/main.rs
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue