Fix 2D audio in multiple viewports

This commit is contained in:
kobewi 2023-05-03 22:57:15 +02:00
parent 8c729f0f34
commit 8a41eefb97
4 changed files with 22 additions and 7 deletions

View File

@ -157,7 +157,6 @@ void AudioStreamPlayer2D::_update_panning() {
Vector2 global_pos = get_global_position();
HashSet<Viewport *> viewports = world_2d->get_viewports();
viewports.insert(get_viewport()); // TODO: This is a mediocre workaround for #50958. Remove when that bug is fixed!
volume_vector.resize(4);
volume_vector.write[0] = AudioFrame(0, 0);
@ -188,11 +187,11 @@ void AudioStreamPlayer2D::_update_panning() {
float dist = global_pos.distance_to(listener_in_global); // Distance to listener, or screen if none.
if (dist > max_distance) {
continue; //can't hear this sound in this viewport
continue; // Can't hear this sound in this viewport.
}
float multiplier = Math::pow(1.0f - dist / max_distance, attenuation);
multiplier *= Math::db_to_linear(volume_db); //also apply player volume!
multiplier *= Math::db_to_linear(volume_db); // Also apply player volume!
float pan = relative_to_listener.x / screen_size.x;
// Don't let the panning effect extend (too far) beyond the screen.
@ -206,7 +205,9 @@ void AudioStreamPlayer2D::_update_panning() {
float l = 1.0 - pan;
float r = pan;
volume_vector.write[0] = AudioFrame(l, r) * multiplier;
const AudioFrame &prev_sample = volume_vector[0];
AudioFrame new_sample = AudioFrame(l, r) * multiplier;
volume_vector.write[0] = AudioFrame(MAX(prev_sample[0], new_sample[0]), MAX(prev_sample[1], new_sample[1]));
}
for (const Ref<AudioStreamPlayback> &playback : stream_playbacks) {

View File

@ -1090,6 +1090,10 @@ void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
}
if (world_2d.is_valid()) {
world_2d->remove_viewport(this);
}
if (p_world_2d.is_valid()) {
world_2d = p_world_2d;
} else {
@ -1097,6 +1101,7 @@ void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
world_2d = Ref<World2D>(memnew(World2D));
}
world_2d->register_viewport(this);
_update_audio_listener_2d();
if (is_inside_tree()) {
@ -4149,6 +4154,7 @@ void Viewport::_validate_property(PropertyInfo &p_property) const {
Viewport::Viewport() {
world_2d = Ref<World2D>(memnew(World2D));
world_2d->register_viewport(this);
viewport = RenderingServer::get_singleton()->viewport_create();
texture_rid = RenderingServer::get_singleton()->viewport_get_texture(viewport);

View File

@ -82,6 +82,14 @@ PhysicsDirectSpaceState2D *World2D::get_direct_space_state() {
return PhysicsServer2D::get_singleton()->space_get_direct_state(get_space());
}
void World2D::register_viewport(Viewport *p_viewport) {
viewports.insert(p_viewport);
}
void World2D::remove_viewport(Viewport *p_viewport) {
viewports.erase(p_viewport);
}
World2D::World2D() {
canvas = RenderingServer::get_singleton()->canvas_create();
}

View File

@ -52,9 +52,6 @@ protected:
static void _bind_methods();
friend class Viewport;
void _register_viewport(Viewport *p_viewport);
void _remove_viewport(Viewport *p_viewport);
public:
RID get_canvas() const;
RID get_space() const;
@ -62,6 +59,9 @@ public:
PhysicsDirectSpaceState2D *get_direct_space_state();
void register_viewport(Viewport *p_viewport);
void remove_viewport(Viewport *p_viewport);
_FORCE_INLINE_ const HashSet<Viewport *> &get_viewports() { return viewports; }
World2D();