Explosion sound and event lights

This commit is contained in:
Joshua Barretto 2020-08-03 12:56:12 +01:00 committed by scott-c
parent 8547cdd681
commit a924f9694d
9 changed files with 70 additions and 12 deletions

View File

@ -109,9 +109,9 @@
),
Explosion: (
files: [
"voxygen.audio.sfx.glider_open",
"voxygen.audio.sfx.explosion",
],
threshold: 0.5,
threshold: 0.2,
),
ProjectileShot: (
files: [

BIN
assets/voxygen/audio/sfx/explosion.wav (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -31,6 +31,7 @@ float gold_noise(in vec2 xy, in float seed){
const int SMOKE = 0;
const int FIRE = 1;
const int GUN_POWDER_SPARK = 2;
const int SHRAPNEL = 3;
// meters per second
const float earth_gravity = 9.807;
@ -105,6 +106,15 @@ void main() {
1.0,
vec3(3.5, 3 + rand7, 0)
);
} else if (inst_mode == SHRAPNEL) {
attr = Attr(
linear_motion(
vec3(0),
vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity)
),
3.0 + rand0,
vec3(0.6 + rand7 * 0.4)
);
} else {
attr = Attr(
linear_motion(

View File

@ -199,7 +199,7 @@ impl<'a> TryFrom<&'a Outcome> for SfxEventItem {
Outcome::Explosion { pos, power } => Ok(Self::new(
SfxEvent::Explosion,
Some(*pos),
Some((*power / 10.0).min(1.0)),
Some((*power / 2.5).min(1.5)),
)),
Outcome::ProjectileShot { pos, .. } => {
Ok(Self::new(SfxEvent::ProjectileShot, Some(*pos), None))

View File

@ -117,6 +117,11 @@ impl Light {
}
pub fn get_pos(&self) -> Vec3<f32> { Vec3::new(self.pos[0], self.pos[1], self.pos[2]) }
pub fn with_strength(mut self, strength: f32) -> Self {
self.col = (Vec4::<f32>::from(self.col) * strength).into_array();
self
}
}
impl Default for Light {

View File

@ -83,9 +83,10 @@ impl Vertex {
}
pub enum ParticleMode {
CampfireSmoke,
CampfireFire,
GunPowderSpark,
CampfireSmoke = 0,
CampfireFire = 1,
GunPowderSpark = 2,
Shrapnel = 3,
}
impl ParticleMode {

View File

@ -21,9 +21,10 @@ use crate::{
use anim::character::SkeletonAttr;
use common::{
comp,
state::State,
state::{State, DeltaTime},
terrain::{BlockKind, TerrainChunk},
vol::ReadVol,
outcome::Outcome,
};
use specs::{Entity as EcsEntity, Join, WorldExt};
use vek::*;
@ -41,6 +42,12 @@ const SHADOW_MAX_DIST: f32 = 96.0; // The distance beyond which shadows may not
/// Used for first person camera effects
const RUNNING_THRESHOLD: f32 = 0.7;
struct EventLight {
light: Light,
timeout: f32,
fadeout: fn(f32) -> f32,
}
struct Skybox {
model: Model<SkyboxPipeline>,
locals: Consts<SkyboxLocals>,
@ -57,6 +64,7 @@ pub struct Scene {
shadows: Consts<Shadow>,
camera: Camera,
camera_input_state: Vec2<f32>,
event_lights: Vec<EventLight>,
skybox: Skybox,
postprocess: PostProcess,
@ -101,6 +109,7 @@ impl Scene {
.unwrap(),
camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson),
camera_input_state: Vec2::zero(),
event_lights: Vec::new(),
skybox: Skybox {
model: renderer.create_model(&create_skybox_mesh()).unwrap(),
@ -135,9 +144,6 @@ impl Scene {
/// Get a reference to the scene's particle manager.
pub fn particle_mgr(&self) -> &ParticleMgr { &self.particle_mgr }
/// Get a mutable reference to the scene's particle manager.
pub fn particle_mgr_mut(&mut self) -> &mut ParticleMgr { &mut self.particle_mgr }
/// Get a reference to the scene's figure manager.
pub fn figure_mgr(&self) -> &FigureMgr { &self.figure_mgr }
@ -187,6 +193,23 @@ impl Scene {
}
}
pub fn handle_outcome(&mut self, outcome: &Outcome, scene_data: &SceneData) {
match outcome {
Outcome::Explosion { pos, power, .. } => self.event_lights.push(EventLight {
light: Light::new(
*pos,
Rgb::new(1.0, 0.5, 0.0),
*power * 2.5,
),
timeout: 0.5,
fadeout: |timeout| timeout * 2.0,
}),
_ => {},
}
self.particle_mgr.handle_outcome(&outcome, &scene_data);
}
/// Maintain data such as GPU constant buffers, models, etc. To be called
/// once per tick.
pub fn maintain(
@ -319,6 +342,9 @@ impl Scene {
light_anim.strength,
)
})
.chain(self.event_lights
.iter()
.map(|el| el.light.with_strength((el.fadeout)(el.timeout))))
.collect::<Vec<_>>();
lights.sort_by_key(|light| light.get_pos().distance_squared(player_pos) as i32);
lights.truncate(MAX_LIGHT_COUNT);
@ -326,6 +352,13 @@ impl Scene {
.update_consts(&mut self.lights, &lights)
.expect("Failed to update light constants");
// Update event lights
let dt = ecs.fetch::<DeltaTime>().0;
self.event_lights.drain_filter(|el| {
el.timeout -= dt;
el.timeout <= 0.0
});
// Update shadow constants
let mut shadows = (
&scene_data.state.ecs().read_storage::<comp::Pos>(),

View File

@ -53,7 +53,13 @@ impl ParticleMgr {
match outcome {
Outcome::Explosion { pos, power } => {
for _ in 0..64 {
for _ in 0..150 {
self.particles.push(Particles {
alive_until: now + Duration::from_millis(250),
instance: ParticleInstance::new(time, rng.gen(), ParticleMode::Shrapnel, *pos),
});
}
for _ in 0..200 {
self.particles.push(Particles {
alive_until: now + Duration::from_secs(4),
instance: ParticleInstance::new(time, rng.gen(), ParticleMode::CampfireSmoke, *pos + Vec2::<f32>::zero().map(|_| rng.gen_range(-1.0, 1.0) * power)),

View File

@ -1033,7 +1033,7 @@ impl PlayState for SessionState {
.read_resource::<EventBus<SfxEventItem>>()
.emit_now(sfx_event_item);
}
self.scene.particle_mgr_mut().handle_outcome(&outcome, &scene_data);
self.scene.handle_outcome(&outcome, &scene_data);
}
}
}