Compare commits
No commits in common. "23d616eead83b6ea094f7f4290837833ebfb8c51" and "85e24b5b45bf687163a35b7aad9b29c31c5e04cf" have entirely different histories.
23d616eead
...
85e24b5b45
|
@ -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,31 +55,92 @@ 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()
|
||||||
if let Some(last) = last_step_distance.get(&entity) {
|
{
|
||||||
let distance = last.0 + (last.1.distance(transform));
|
let coordinates = transforms_storage.get(**parent).unwrap();
|
||||||
if distance >= footstep.step_length {
|
if let Some(last) = last_step_distance.get(&entity) {
|
||||||
last_step_distance.insert(entity, (0., *transform));
|
let distance = last.0 + (last.1.distance(coordinates));
|
||||||
sound.gain = footstep.gain;
|
if distance >= footstep.step_length {
|
||||||
sound.pitch = footstep.pitch.unwrap_or(1.);
|
last_step_distance.insert(entity, (0., *coordinates));
|
||||||
if let Some(pitch_variation) = footstep.pitch_variation {
|
sound.gain = footstep.gain;
|
||||||
let mut pitch = sound.pitch - pitch_variation / 2.;
|
if let Some(v) = footstep.reference_distance {
|
||||||
pitch += random::<f64>() * pitch_variation;
|
let insert = if let Some(v2) = reference_distance {
|
||||||
sound.pitch = pitch;
|
v != **v2
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
if insert {
|
||||||
|
commands.run_if_exists(entity, move |mut entity| {
|
||||||
|
entity.insert(DistanceRef(v));
|
||||||
|
})
|
||||||
}
|
}
|
||||||
sound.paused = false;
|
} else if reference_distance.is_some() {
|
||||||
sound.restart = true;
|
commands.run_if_exists(entity, |mut entity| {
|
||||||
} else if last.1 != *transform {
|
entity.remove::<DistanceRef>();
|
||||||
last_step_distance.insert(entity, (distance, *transform));
|
});
|
||||||
}
|
}
|
||||||
} else {
|
if let Some(v) = footstep.max_distance {
|
||||||
last_step_distance.insert(entity, (0., *transform));
|
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.);
|
||||||
|
if let Some(pitch_variation) = footstep.pitch_variation {
|
||||||
|
let mut pitch = sound.pitch - pitch_variation / 2.;
|
||||||
|
pitch += random::<f64>() * pitch_variation;
|
||||||
|
sound.pitch = pitch;
|
||||||
|
}
|
||||||
|
sound.paused = false;
|
||||||
|
sound.restart = true;
|
||||||
|
} else if last.1 != *coordinates {
|
||||||
|
last_step_distance.insert(entity, (distance, *coordinates));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
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),
|
||||||
|
|
|
@ -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>),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user