Compare commits

..

No commits in common. "23d616eead83b6ea094f7f4290837833ebfb8c51" and "85e24b5b45bf687163a35b7aad9b29c31c5e04cf" have entirely different histories.

4 changed files with 194 additions and 30 deletions

View File

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use bevy::{prelude::*, transform::TransformSystem}; use bevy::{prelude::*, transform::TransformSystem};
use bevy_synthizer::{Buffer, Sound}; use bevy_synthizer::{Buffer, DistanceMax, DistanceRef, Rolloff, Sound};
use rand::random; use rand::random;
use crate::{commands::RunIfExistsExt, core::PointLike}; use crate::{commands::RunIfExistsExt, core::PointLike};
@ -12,6 +12,9 @@ pub struct Footstep {
pub sound: Handle<Buffer>, pub sound: Handle<Buffer>,
pub step_length: f32, pub step_length: f32,
pub gain: f64, pub gain: f64,
pub reference_distance: Option<f64>,
pub max_distance: Option<f64>,
pub rolloff: Option<f64>,
pub pitch: Option<f64>, pub pitch: Option<f64>,
pub pitch_variation: Option<f64>, pub pitch_variation: Option<f64>,
} }
@ -22,12 +25,22 @@ impl Default for Footstep {
sound: default(), sound: default(),
step_length: 0.8, step_length: 0.8,
gain: 1., gain: 1.,
reference_distance: None,
max_distance: None,
rolloff: None,
pitch: None, pitch: None,
pitch_variation: Some(0.15), pitch_variation: Some(0.15),
} }
} }
} }
#[derive(Bundle, Default)]
pub struct FootstepBundle {
pub footstep: Footstep,
pub transform: Transform,
pub global_transform: GlobalTransform,
}
fn added(mut commands: Commands, footsteps: Query<(Entity, &Footstep), Added<Footstep>>) { fn added(mut commands: Commands, footsteps: Query<(Entity, &Footstep), Added<Footstep>>) {
for (entity, footstep) in footsteps.iter() { for (entity, footstep) in footsteps.iter() {
let buffer = footstep.sound.clone(); let buffer = footstep.sound.clone();
@ -42,17 +55,79 @@ fn added(mut commands: Commands, footsteps: Query<(Entity, &Footstep), Added<Foo
} }
fn update( fn update(
mut last_step_distance: Local<HashMap<Entity, (f32, GlobalTransform)>>, mut commands: Commands,
mut footsteps: Query<(Entity, &Footstep, &Parent, &mut Sound)>, mut last_step_distance: Local<HashMap<Entity, (f32, Transform)>>,
transforms_storage: Query<&GlobalTransform>, mut footsteps: Query<
(
Entity,
&Footstep,
&Parent,
&mut Sound,
Option<&DistanceRef>,
Option<&DistanceMax>,
Option<&Rolloff>,
),
Changed<GlobalTransform>,
>,
transforms_storage: Query<&Transform>,
) { ) {
for (entity, footstep, parent, mut sound) in footsteps.iter_mut() { for (entity, footstep, parent, mut sound, reference_distance, max_distance, rolloff) in
if let Ok(transform) = transforms_storage.get(**parent) { footsteps.iter_mut()
{
let coordinates = transforms_storage.get(**parent).unwrap();
if let Some(last) = last_step_distance.get(&entity) { if let Some(last) = last_step_distance.get(&entity) {
let distance = last.0 + (last.1.distance(transform)); let distance = last.0 + (last.1.distance(coordinates));
if distance >= footstep.step_length { if distance >= footstep.step_length {
last_step_distance.insert(entity, (0., *transform)); last_step_distance.insert(entity, (0., *coordinates));
sound.gain = footstep.gain; sound.gain = footstep.gain;
if let Some(v) = footstep.reference_distance {
let insert = if let Some(v2) = reference_distance {
v != **v2
} else {
true
};
if insert {
commands.run_if_exists(entity, move |mut entity| {
entity.insert(DistanceRef(v));
})
}
} else if reference_distance.is_some() {
commands.run_if_exists(entity, |mut entity| {
entity.remove::<DistanceRef>();
});
}
if let Some(v) = footstep.max_distance {
let insert = if let Some(v2) = max_distance {
v != **v2
} else {
true
};
if insert {
commands.run_if_exists(entity, move |mut entity| {
entity.insert(DistanceMax(v));
})
}
} else if max_distance.is_some() {
commands.run_if_exists(entity, |mut entity| {
entity.remove::<DistanceMax>();
});
}
if let Some(v) = footstep.rolloff {
let insert = if let Some(v2) = rolloff {
v != **v2
} else {
true
};
if insert {
commands.run_if_exists(entity, move |mut entity| {
entity.insert(Rolloff(v));
})
}
} else if rolloff.is_some() {
commands.run_if_exists(entity, |mut entity| {
entity.remove::<Rolloff>();
});
}
sound.pitch = footstep.pitch.unwrap_or(1.); sound.pitch = footstep.pitch.unwrap_or(1.);
if let Some(pitch_variation) = footstep.pitch_variation { if let Some(pitch_variation) = footstep.pitch_variation {
let mut pitch = sound.pitch - pitch_variation / 2.; let mut pitch = sound.pitch - pitch_variation / 2.;
@ -61,12 +136,11 @@ fn update(
} }
sound.paused = false; sound.paused = false;
sound.restart = true; sound.restart = true;
} else if last.1 != *transform { } else if last.1 != *coordinates {
last_step_distance.insert(entity, (distance, *transform)); last_step_distance.insert(entity, (distance, *coordinates));
} }
} else { } else {
last_step_distance.insert(entity, (0., *transform)); last_step_distance.insert(entity, (0., *coordinates));
}
} }
} }
} }
@ -76,7 +150,7 @@ pub struct FootstepPlugin;
impl Plugin for FootstepPlugin { impl Plugin for FootstepPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.register_type::<Footstep>() app.register_type::<Footstep>()
.add_system_to_stage(CoreStage::PreUpdate, added) .add_system(added)
.add_system_to_stage( .add_system_to_stage(
CoreStage::PostUpdate, CoreStage::PostUpdate,
update.after(TransformSystem::TransformPropagate), update.after(TransformSystem::TransformPropagate),

View File

@ -1,7 +1,7 @@
use std::{fmt::Debug, hash::Hash, time::Duration}; use std::{fmt::Debug, hash::Hash, time::Duration};
use bevy::prelude::*; use bevy::{prelude::*, transform::TransformSystem};
use bevy_synthizer::{Buffer, Sound}; use bevy_synthizer::{Buffer, DistanceMax, DistanceRef, Rolloff, Sound};
use rand::random; use rand::random;
@ -17,6 +17,9 @@ pub struct SoundIcon {
pub sound: Handle<Buffer>, pub sound: Handle<Buffer>,
pub gain: f64, pub gain: f64,
pub pitch: f64, pub pitch: f64,
pub reference_distance: Option<f64>,
pub max_distance: Option<f64>,
pub rolloff: Option<f64>,
pub interval: Option<Timer>, pub interval: Option<Timer>,
} }
@ -27,6 +30,9 @@ impl Default for SoundIcon {
sound: default(), sound: default(),
gain: 1., gain: 1.,
pitch: 1., pitch: 1.,
reference_distance: None,
max_distance: None,
rolloff: None,
interval: Some(Timer::from_seconds(seconds, true)), interval: Some(Timer::from_seconds(seconds, true)),
}; };
if let Some(ref mut interval) = icon.interval { if let Some(ref mut interval) = icon.interval {
@ -37,12 +43,22 @@ impl Default for SoundIcon {
} }
} }
#[derive(Bundle, Clone, Debug, Default)]
pub struct SoundIconBundle {
pub sound_icon: SoundIcon,
pub transform: Transform,
pub global_transform: GlobalTransform,
}
fn added(mut commands: Commands, icons: Query<(Entity, &SoundIcon), Added<SoundIcon>>) { fn added(mut commands: Commands, icons: Query<(Entity, &SoundIcon), Added<SoundIcon>>) {
for (entity, icon) in icons.iter() { for (entity, icon) in icons.iter() {
let buffer = icon.sound.clone(); let buffer = icon.sound.clone();
let gain = icon.gain; let gain = icon.gain;
let pitch = icon.pitch; let pitch = icon.pitch;
let looping = icon.interval.is_none(); let looping = icon.interval.is_none();
let reference_distance = icon.reference_distance;
let max_distance = icon.max_distance;
let rolloff = icon.rolloff;
commands.run_if_exists(entity, move |mut entity| { commands.run_if_exists(entity, move |mut entity| {
entity.insert(Sound { entity.insert(Sound {
buffer, buffer,
@ -52,11 +68,21 @@ fn added(mut commands: Commands, icons: Query<(Entity, &SoundIcon), Added<SoundI
paused: true, paused: true,
..default() ..default()
}); });
if let Some(v) = reference_distance {
entity.insert(DistanceRef(v));
}
if let Some(v) = max_distance {
entity.insert(DistanceMax(v));
}
if let Some(v) = rolloff {
entity.insert(Rolloff(v));
}
}); });
} }
} }
fn update<S>( fn update<S>(
mut commands: Commands,
config: Res<SoundIconConfig<S>>, config: Res<SoundIconConfig<S>>,
state: Res<State<S>>, state: Res<State<S>>,
time: Res<Time>, time: Res<Time>,
@ -67,6 +93,9 @@ fn update<S>(
Option<&Visible>, Option<&Visible>,
Option<&Parent>, Option<&Parent>,
&mut Sound, &mut Sound,
Option<&DistanceRef>,
Option<&DistanceMax>,
Option<&Rolloff>,
)>, )>,
) where ) where
S: 'static + Clone + Debug + Eq + Hash + Send + Sync, S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
@ -75,7 +104,17 @@ fn update<S>(
return; return;
} }
for visible in viewers.iter() { for visible in viewers.iter() {
for (icon_entity, mut icon, visibility, parent, mut sound) in icons.iter_mut() { for (
icon_entity,
mut icon,
visibility,
parent,
mut sound,
distance_ref,
distance_max,
rolloff,
) in icons.iter_mut()
{
let entity = if visibility.is_some() { let entity = if visibility.is_some() {
Some(icon_entity) Some(icon_entity)
} else if parent.is_some() { } else if parent.is_some() {
@ -102,6 +141,54 @@ fn update<S>(
sound.gain = icon.gain; sound.gain = icon.gain;
sound.pitch = icon.pitch; sound.pitch = icon.pitch;
sound.looping = icon.interval.is_none(); sound.looping = icon.interval.is_none();
if let Some(v) = icon.reference_distance {
let insert = if let Some(v2) = distance_ref {
v != **v2
} else {
true
};
if insert {
commands.run_if_exists(icon_entity, move |mut entity| {
entity.insert(DistanceRef(v));
})
}
} else if distance_ref.is_some() {
commands.run_if_exists(icon_entity, |mut entity| {
entity.remove::<DistanceRef>();
});
}
if let Some(v) = icon.max_distance {
let insert = if let Some(v2) = distance_max {
v != **v2
} else {
true
};
if insert {
commands.run_if_exists(icon_entity, move |mut entity| {
entity.insert(DistanceMax(v));
})
}
} else if distance_max.is_some() {
commands.run_if_exists(icon_entity, |mut entity| {
entity.remove::<DistanceMax>();
});
}
if let Some(v) = icon.rolloff {
let insert = if let Some(v2) = rolloff {
v != **v2
} else {
true
};
if insert {
commands.run_if_exists(icon_entity, move |mut entity| {
entity.insert(Rolloff(v));
})
}
} else if rolloff.is_some() {
commands.run_if_exists(icon_entity, |mut entity| {
entity.remove::<Rolloff>();
});
}
} else if !sound.paused { } else if !sound.paused {
sound.paused = true; sound.paused = true;
sound.restart = true; sound.restart = true;
@ -201,7 +288,10 @@ where
{ {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_system(added) app.add_system(added)
.add_system_to_stage(CoreStage::PostUpdate, update::<S>) .add_system_to_stage(
CoreStage::PostUpdate,
update::<S>.after(TransformSystem::TransformPropagate),
)
.add_system_to_stage( .add_system_to_stage(
CoreStage::PostUpdate, CoreStage::PostUpdate,
exploration_focus_changed.after(update::<S>), exploration_focus_changed.after(update::<S>),

View File

@ -7,8 +7,8 @@ use crate::core::CoreConfig;
pub mod footstep; pub mod footstep;
pub mod icon; pub mod icon;
pub use footstep::Footstep; pub use footstep::{Footstep, FootstepBundle};
pub use icon::SoundIcon; pub use icon::{SoundIcon, SoundIconBundle};
/*fn scale_sounds(config: Res<CoreConfig>, mut sounds: Query<&mut Sound>) { /*fn scale_sounds(config: Res<CoreConfig>, mut sounds: Query<&mut Sound>) {
let pixels_per_unit = config.pixels_per_unit as f32; let pixels_per_unit = config.pixels_per_unit as f32;

View File

@ -85,7 +85,7 @@ impl Viewshed {
); );
let mut context: Context<u8> = Context::default(); let mut context: Context<u8> = Context::default();
let vision_distance = vision_distance::Circle::new(self.range); let vision_distance = vision_distance::Circle::new(self.range);
let shape = Collider::cuboid(0.5 - f32::EPSILON, 0.5 - f32::EPSILON); let shape = Collider::cuboid(0.5, 0.5);
let mut new_visible_entities = HashSet::new(); let mut new_visible_entities = HashSet::new();
let size = ( let size = (
(start.translation().x.abs() + self.range as f32) as u32, (start.translation().x.abs() + self.range as f32) as u32,