Addressed comments and fixed pipeline

This commit is contained in:
jiminycrick 2020-11-16 16:38:48 -08:00
parent 3b47add55a
commit 2d2f267907
12 changed files with 110 additions and 113 deletions

View File

@ -2,7 +2,7 @@
tracks: [ tracks: [
( (
path: "voxygen.audio.ambient.wind", path: "voxygen.audio.ambient.wind",
length: 4.5, length: 14.5,
tag: Wind, tag: Wind,
), ),
] ]

BIN
assets/voxygen/audio/ambient/wind.ogg (Stored with Git LFS)

Binary file not shown.

View File

@ -102,32 +102,32 @@
], ],
threshold: 0.12, threshold: 0.12,
), ),
ExperienceGained: ( //ExperienceGained: (
files: [ // files: [
// "voxygen.audio.sfx.character.experience_gained_1", // "voxygen.audio.sfx.character.experience_gained_1",
// "voxygen.audio.sfx.character.experience_gained_2", // "voxygen.audio.sfx.character.experience_gained_2",
// "voxygen.audio.sfx.character.experience_gained_3", // "voxygen.audio.sfx.character.experience_gained_3",
], // ],
threshold: 0.5, // threshold: 0.5,
), //),
LevelUp:( LevelUp:(
files: [ files: [
"voxygen.audio.sfx.character.level_up_sound_-_shorter_wind_up", "voxygen.audio.sfx.character.level_up_sound_-_shorter_wind_up",
], ],
threshold: 0.5, threshold: 0.5,
), ),
Jump: ( //Jump: (
files: [ // files: [
// Event not implemented? // // Event not implemented?
], // ],
threshold: 0.25, // threshold: 0.25,
), //),
Fall: ( //Fall: (
files: [ // files: [
// Event not implemented? // // Event not implemented?
], // ],
threshold: 0.25, // threshold: 0.25,
), //),
Roll: ( Roll: (
files: [ files: [
"voxygen.audio.sfx.character.dive_roll_1", "voxygen.audio.sfx.character.dive_roll_1",
@ -135,18 +135,18 @@
], ],
threshold: 0.25, threshold: 0.25,
), ),
Climb: ( //Climb: (
files: [ // files: [
// TODO: sync with animation // TODO: sync with animation
//"voxygen.audio.sfx.footsteps.stepgrass_1", // "voxygen.audio.sfx.footsteps.stepgrass_1",
//"voxygen.audio.sfx.footsteps.stepgrass_2", // "voxygen.audio.sfx.footsteps.stepgrass_2",
//"voxygen.audio.sfx.footsteps.stepgrass_3", // "voxygen.audio.sfx.footsteps.stepgrass_3",
//"voxygen.audio.sfx.footsteps.stepgrass_4", // "voxygen.audio.sfx.footsteps.stepgrass_4",
//"voxygen.audio.sfx.footsteps.stepgrass_5", // "voxygen.audio.sfx.footsteps.stepgrass_5",
//"voxygen.audio.sfx.footsteps.stepgrass_6", // "voxygen.audio.sfx.footsteps.stepgrass_6",
], // ],
threshold: 0.25, // threshold: 0.25,
), //),
GliderOpen: ( GliderOpen: (
files: [ files: [
"voxygen.audio.sfx.glider_open", "voxygen.audio.sfx.glider_open",
@ -325,12 +325,12 @@
], ],
threshold: 0.2, threshold: 0.2,
), ),
Attack(BasicRanged, Staff): ( //Attack(BasicRanged, Staff): (
files: [ // files: [
// "voxygen.audio.sfx.abilities.staff_channeling", // "voxygen.audio.sfx.abilities.staff_channeling",
], // ],
threshold: 0.8, // threshold: 0.8,
), //),
Inventory(CollectedTool(Staff)): ( Inventory(CollectedTool(Staff)): (
files: [ files: [
"voxygen.audio.sfx.inventory.pickup_staff", "voxygen.audio.sfx.inventory.pickup_staff",
@ -577,17 +577,17 @@
], ],
threshold: 0.3, threshold: 0.3,
), ),
Explosion: ( //Explosion: (
files: [ // files: [
// in code // // in code
], // ],
threshold: 0.2, // threshold: 0.2,
), //),
ProjectileShot: ( //ProjectileShot: (
files: [ // files: [
// in code // // in code
], // ],
threshold: 0.5, // threshold: 0.5,
), //),
} }
) )

BIN
assets/voxygen/audio/sfx/ambient/fire.wav (Stored with Git LFS)

Binary file not shown.

View File

@ -8,6 +8,18 @@
( (
tracks: [ tracks: [
(
title: "Oceania",
path: "voxygen.audio.soundtrack.oceania",
length: 135.0,
timing: None,
biomes: [
(Lake, 2),
(Ocean, 3),
],
site: Some(Void),
artist: "Eden",
),
( (
title: "A Solemn Quest", title: "A Solemn Quest",
path: "voxygen.audio.soundtrack.a_solemn_quest", path: "voxygen.audio.soundtrack.a_solemn_quest",

BIN
assets/voxygen/audio/soundtrack/oceania.ogg (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -4,10 +4,11 @@ use crate::{
scene::Camera, scene::Camera,
}; };
use client::Client; use client::Client;
use common::{assets, state::State, terrain::BlockKind, vol::ReadVol}; use common::{assets, state::State, vol::ReadVol};
use serde::Deserialize; use serde::Deserialize;
use std::time::Instant; use std::time::Instant;
use tracing::warn; use tracing::warn;
use vek::*;
#[derive(Debug, Default, Deserialize)] #[derive(Debug, Default, Deserialize)]
struct AmbientCollection { struct AmbientCollection {
@ -20,6 +21,7 @@ pub struct AmbientItem {
path: String, path: String,
/// Length of the track in seconds /// Length of the track in seconds
length: f32, length: f32,
/// Specifies which ambient channel to play on
tag: AmbientChannelTag, tag: AmbientChannelTag,
} }
@ -57,31 +59,24 @@ impl AmbientMgr {
let focus_off = camera.get_focus_pos().map(f32::trunc); let focus_off = camera.get_focus_pos().map(f32::trunc);
let cam_pos = camera.dependents().cam_pos + focus_off; let cam_pos = camera.dependents().cam_pos + focus_off;
let cam_alt = cam_pos.z; let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() {
let terrain_alt = Self::get_current_terrain_alt(client); (chunk.meta().alt(), chunk.meta().tree_density())
} else {
(0.0, 0.0)
};
// The following code is specifically for wind, as it is the only // The following code is specifically for wind, as it is the only
// non-positional ambient sound in the game. Others can be added // non-positional ambient sound in the game. Others can be added
// as seen fit. // as seen fit.
let alt_multiplier = (cam_alt / 1200.0).abs(); // Wind volume increases with altitude
let alt_multiplier = (cam_pos.z / 1200.0).abs();
// Tree density factors into ambient volume. The more trees, // Tree density factors into wind volume. The more trees,
// the less ambient // the lower wind volume. The trees make more of an impact
let mut tree_multiplier = self.tree_multiplier; // the closer the camera is to the ground.
let new_tree_multiplier = if (cam_alt - terrain_alt) < 150.0 { self.tree_multiplier =
1.0 - Self::get_current_tree_density(client) ((1.0 - tree_density) + ((cam_pos.z - terrain_alt) / 150.0).powf(2.0)).min(1.0);
} else {
1.0
};
// Smooths tree_multiplier transitions between chunks
if tree_multiplier < new_tree_multiplier {
tree_multiplier += 0.001;
} else if tree_multiplier > new_tree_multiplier {
tree_multiplier -= 0.001;
}
self.tree_multiplier = tree_multiplier;
let mut volume_multiplier = alt_multiplier * self.tree_multiplier; let mut volume_multiplier = alt_multiplier * self.tree_multiplier;
@ -89,36 +84,30 @@ impl AmbientMgr {
if state if state
.terrain() .terrain()
.get((cam_pos).map(|e| e.floor() as i32)) .get((cam_pos).map(|e| e.floor() as i32))
.map(|b| b.kind()) .map(|b| b.is_liquid())
.unwrap_or(BlockKind::Air) .unwrap_or(false)
== BlockKind::Water
{ {
volume_multiplier *= 0.1; volume_multiplier *= 0.1;
} }
if cam_pos.z < Self::get_current_terrain_alt(client) - 10.0 { if cam_pos.z < terrain_alt - 10.0 {
volume_multiplier = 0.0; volume_multiplier = 0.0;
} }
let target_volume = volume_multiplier.max(0.0).min(1.0); let target_volume = volume_multiplier.clamped(0.0, 1.0);
// Transitions the ambient sounds (more) smoothly // Transitions the ambient sounds (more) smoothly
self.volume = audio.get_ambient_volume(); self.volume = audio.get_ambient_volume();
if self.volume < target_volume { audio.set_ambient_volume(Lerp::lerp(self.volume, target_volume, 0.01));
audio.set_ambient_volume(self.volume + 0.001);
} else if self.volume > target_volume {
audio.set_ambient_volume(self.volume - 0.001);
}
if self.began_playing.elapsed().as_secs_f32() > self.next_track_change { if self.began_playing.elapsed().as_secs_f32() > self.next_track_change {
//let game_time = (state.get_time_of_day() as u64 % 86400) as u32; // Right now there is only wind non-positional sfx so it is always
//let current_period_of_day = Self::get_current_day_period(game_time); // selected. Modify this variable assignment when adding other non-
// positional sfx
let track = &self let track = &self
.soundtrack .soundtrack
.tracks .tracks
.iter() .iter()
.filter(|track| track.tag == AmbientChannelTag::Wind) .find(|track| track.tag == AmbientChannelTag::Wind);
.next();
if let Some(track) = track { if let Some(track) = track {
self.began_playing = Instant::now(); self.began_playing = Instant::now();
@ -130,21 +119,6 @@ impl AmbientMgr {
} }
} }
fn get_current_terrain_alt(client: &Client) -> f32 {
if let Some(chunk) = client.current_chunk() {
chunk.meta().alt()
} else {
0.0
}
}
fn get_current_tree_density(client: &Client) -> f32 {
match client.current_chunk() {
Some(current_chunk) => current_chunk.meta().tree_density(),
None => 0.0,
}
}
fn load_soundtrack_items() -> AmbientCollection { fn load_soundtrack_items() -> AmbientCollection {
match assets::load_file("voxygen.audio.ambient", &["ron"]) { match assets::load_file("voxygen.audio.ambient", &["ron"]) {
Ok(file) => match ron::de::from_reader(file) { Ok(file) => match ron::de::from_reader(file) {

View File

@ -150,7 +150,7 @@ impl MusicMgr {
let mut rng = thread_rng(); let mut rng = thread_rng();
// Adds a bit of randomness between plays // Adds a bit of randomness between plays
let silence_between_tracks_seconds: f32 = rng.gen_range(15.0, 60.0); let silence_between_tracks_seconds: f32 = rng.gen_range(45.0, 120.0);
let game_time = (state.get_time_of_day() as u64 % 86400) as u32; let game_time = (state.get_time_of_day() as u64 % 86400) as u32;
let current_period_of_day = Self::get_current_day_period(game_time); let current_period_of_day = Self::get_current_day_period(game_time);

View File

@ -12,7 +12,7 @@ use common::{
comp::Pos, comp::Pos,
spiral::Spiral2d, spiral::Spiral2d,
state::State, state::State,
terrain::{BlockKind, TerrainChunk}, terrain::TerrainChunk,
vol::{ReadVol, RectRasterableVol}, vol::{ReadVol, RectRasterableVol},
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
@ -184,7 +184,7 @@ impl EventMapper for BlockEventMapper {
let underwater = state let underwater = state
.terrain() .terrain()
.get(cam_pos.map(|e| e.floor() as i32)) .get(cam_pos.map(|e| e.floor() as i32))
.map(|b| b.kind() == BlockKind::Water) .map(|b| b.is_liquid())
.unwrap_or(false); .unwrap_or(false);
let sfx_trigger_item = triggers.get_key_value(&sounds.sfx); let sfx_trigger_item = triggers.get_key_value(&sounds.sfx);
@ -212,6 +212,14 @@ impl BlockEventMapper {
} }
} }
/// Ensures that:
/// 1. An sfx.ron entry exists for an SFX event
/// 2. The sfx has not been played since it's timeout threshold has elapsed,
/// which prevents firing every tick
/// Note that with so many blocks to choose from and different blocks being
/// selected each time, this is not perfect, but does reduce the number of
/// plays from blocks that have already emitted sfx and are stored in the
/// BlockEventMapper history.
fn should_emit( fn should_emit(
previous_state: &PreviousBlockState, previous_state: &PreviousBlockState,
sfx_trigger_item: Option<(&SfxEvent, &SfxTriggerItem)>, sfx_trigger_item: Option<(&SfxEvent, &SfxTriggerItem)>,

View File

@ -11,7 +11,7 @@ use client::Client;
use common::{ use common::{
comp::{object, Body, Pos}, comp::{object, Body, Pos},
state::State, state::State,
terrain::{BlockKind, TerrainChunk}, terrain::TerrainChunk,
vol::ReadVol, vol::ReadVol,
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
@ -69,7 +69,7 @@ impl EventMapper for CampfireEventMapper {
let underwater = state let underwater = state
.terrain() .terrain()
.get(cam_pos.map(|e| e.floor() as i32)) .get(cam_pos.map(|e| e.floor() as i32))
.map(|b| b.kind() == BlockKind::Water) .map(|b| b.is_liquid())
.unwrap_or(false); .unwrap_or(false);
let sfx_trigger_item = triggers.get_key_value(&mapped_event); let sfx_trigger_item = triggers.get_key_value(&mapped_event);
audio.emit_sfx(sfx_trigger_item, pos.0, None, underwater); audio.emit_sfx(sfx_trigger_item, pos.0, None, underwater);

View File

@ -12,7 +12,7 @@ use client::Client;
use common::{ use common::{
comp::{item::ItemKind, CharacterAbilityType, CharacterState, Loadout, Pos}, comp::{item::ItemKind, CharacterAbilityType, CharacterState, Loadout, Pos},
state::State, state::State,
terrain::{BlockKind, TerrainChunk}, terrain::TerrainChunk,
vol::ReadVol, vol::ReadVol,
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
@ -75,7 +75,7 @@ impl EventMapper for CombatEventMapper {
let underwater = state let underwater = state
.terrain() .terrain()
.get(cam_pos.map(|e| e.floor() as i32)) .get(cam_pos.map(|e| e.floor() as i32))
.map(|b| b.kind() == BlockKind::Water) .map(|b| b.is_liquid())
.unwrap_or(false); .unwrap_or(false);
let sfx_trigger_item = triggers.get_key_value(&mapped_event); let sfx_trigger_item = triggers.get_key_value(&mapped_event);

View File

@ -101,7 +101,7 @@ impl EventMapper for MovementEventMapper {
let underwater = state let underwater = state
.terrain() .terrain()
.get(cam_pos.map(|e| e.floor() as i32)) .get(cam_pos.map(|e| e.floor() as i32))
.map(|b| b.kind() == BlockKind::Water) .map(|b| b.is_liquid())
.unwrap_or(false); .unwrap_or(false);
let sfx_trigger_item = triggers.get_key_value(&mapped_event); let sfx_trigger_item = triggers.get_key_value(&mapped_event);