Skip to content

Commit 90cfd88

Browse files
committed
Merge pull request #108051 from RoyBerardo/listener_doppler_fix
Fix `AudioListener3D` not tracking velocity for doppler
2 parents 65b6368 + 769795f commit 90cfd88

File tree

6 files changed

+87
-13
lines changed

6 files changed

+87
-13
lines changed

doc/classes/AudioListener3D.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,21 @@
3535
</description>
3636
</method>
3737
</methods>
38+
<members>
39+
<member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" enum="AudioListener3D.DopplerTracking" default="0">
40+
If not [constant DOPPLER_TRACKING_DISABLED], this listener will simulate the [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] for objects changed in particular [code]_process[/code] methods.
41+
[b]Note:[/b] The Doppler effect will only be heard on [AudioStreamPlayer3D]s if [member AudioStreamPlayer3D.doppler_tracking] is not set to [constant AudioStreamPlayer3D.DOPPLER_TRACKING_DISABLED].
42+
</member>
43+
</members>
44+
<constants>
45+
<constant name="DOPPLER_TRACKING_DISABLED" value="0" enum="DopplerTracking">
46+
Disables [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] simulation (default).
47+
</constant>
48+
<constant name="DOPPLER_TRACKING_IDLE_STEP" value="1" enum="DopplerTracking">
49+
Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_process[/code]. Changes in the relative velocity of this listener compared to those objects affect how audio is perceived (changing the audio's [member AudioStreamPlayer3D.pitch_scale]).
50+
</constant>
51+
<constant name="DOPPLER_TRACKING_PHYSICS_STEP" value="2" enum="DopplerTracking">
52+
Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_physics_process[/code]. Changes in the relative velocity of this listener compared to those objects affect how audio is perceived (changing the audio's [member AudioStreamPlayer3D.pitch_scale]).
53+
</constant>
54+
</constants>
3855
</class>

doc/classes/AudioStreamPlayer3D.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
</member>
7575
<member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" enum="AudioStreamPlayer3D.DopplerTracking" default="0">
7676
Decides in which step the Doppler effect should be calculated.
77+
[b]Note:[/b] If [member doppler_tracking] is not [constant DOPPLER_TRACKING_DISABLED] but the current [Camera3D]/[AudioListener3D] has doppler tracking disabled, the Doppler effect will be heard but will not take the movement of the current listener into account. If accurate Doppler effect is desired, doppler tracking should be enabled on both the [AudioStreamPlayer3D] and the current [Camera3D]/[AudioListener3D].
7778
</member>
7879
<member name="emission_angle_degrees" type="float" setter="set_emission_angle" getter="get_emission_angle" default="45.0">
7980
The angle in which the audio reaches a listener unattenuated.

doc/classes/Camera3D.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@
175175
</member>
176176
<member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" enum="Camera3D.DopplerTracking" default="0">
177177
If not [constant DOPPLER_TRACKING_DISABLED], this camera will simulate the [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] for objects changed in particular [code]_process[/code] methods.
178+
[b]Note:[/b] The Doppler effect will only be heard on [AudioStreamPlayer3D]s if [member AudioStreamPlayer3D.doppler_tracking] is not set to [constant AudioStreamPlayer3D.DOPPLER_TRACKING_DISABLED].
178179
</member>
179180
<member name="environment" type="Environment" setter="set_environment" getter="get_environment">
180181
The [Environment] to use for this camera.

scene/3d/audio_listener_3d.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ void AudioListener3D::_notification(int p_what) {
8888

8989
case NOTIFICATION_TRANSFORM_CHANGED: {
9090
_request_listener_update();
91+
if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
92+
velocity_tracker->update_position(get_global_transform().origin);
93+
}
9194
} break;
9295

9396
case NOTIFICATION_EXIT_WORLD: {
@@ -140,15 +143,50 @@ bool AudioListener3D::is_current() const {
140143
}
141144
}
142145

146+
void AudioListener3D::set_doppler_tracking(DopplerTracking p_tracking) {
147+
if (doppler_tracking == p_tracking) {
148+
return;
149+
}
150+
151+
doppler_tracking = p_tracking;
152+
if (p_tracking != DOPPLER_TRACKING_DISABLED) {
153+
velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP);
154+
if (is_inside_tree()) {
155+
velocity_tracker->reset(get_global_transform().origin);
156+
}
157+
}
158+
}
159+
160+
AudioListener3D::DopplerTracking AudioListener3D::get_doppler_tracking() const {
161+
return doppler_tracking;
162+
}
163+
143164
void AudioListener3D::_bind_methods() {
144165
ClassDB::bind_method(D_METHOD("make_current"), &AudioListener3D::make_current);
145166
ClassDB::bind_method(D_METHOD("clear_current"), &AudioListener3D::clear_current);
146167
ClassDB::bind_method(D_METHOD("is_current"), &AudioListener3D::is_current);
147168
ClassDB::bind_method(D_METHOD("get_listener_transform"), &AudioListener3D::get_listener_transform);
169+
ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &AudioListener3D::set_doppler_tracking);
170+
ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &AudioListener3D::get_doppler_tracking);
171+
172+
ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking");
173+
174+
BIND_ENUM_CONSTANT(DOPPLER_TRACKING_DISABLED);
175+
BIND_ENUM_CONSTANT(DOPPLER_TRACKING_IDLE_STEP);
176+
BIND_ENUM_CONSTANT(DOPPLER_TRACKING_PHYSICS_STEP);
177+
}
178+
179+
Vector3 AudioListener3D::get_doppler_tracked_velocity() const {
180+
if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
181+
return velocity_tracker->get_tracked_linear_velocity();
182+
} else {
183+
return Vector3();
184+
}
148185
}
149186

150187
AudioListener3D::AudioListener3D() {
151188
set_notify_transform(true);
189+
velocity_tracker.instantiate();
152190
}
153191

154192
AudioListener3D::~AudioListener3D() {

scene/3d/audio_listener_3d.h

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,32 @@
3131
#pragma once
3232

3333
#include "scene/3d/node_3d.h"
34+
#include "scene/3d/velocity_tracker_3d.h"
3435

3536
class AudioListener3D : public Node3D {
3637
GDCLASS(AudioListener3D, Node3D);
3738

39+
public:
40+
enum DopplerTracking {
41+
DOPPLER_TRACKING_DISABLED,
42+
DOPPLER_TRACKING_IDLE_STEP,
43+
DOPPLER_TRACKING_PHYSICS_STEP,
44+
};
45+
46+
void make_current();
47+
void clear_current();
48+
bool is_current() const;
49+
50+
virtual Transform3D get_listener_transform() const;
51+
52+
void set_doppler_tracking(DopplerTracking p_tracking);
53+
DopplerTracking get_doppler_tracking() const;
54+
55+
Vector3 get_doppler_tracked_velocity() const;
56+
57+
AudioListener3D();
58+
~AudioListener3D();
59+
3860
private:
3961
bool force_change = false;
4062
bool current = false;
@@ -44,6 +66,9 @@ class AudioListener3D : public Node3D {
4466
friend class Viewport;
4567
void _update_audio_listener_state();
4668

69+
DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED;
70+
Ref<VelocityTracker3D> velocity_tracker;
71+
4772
protected:
4873
void _update_listener();
4974
virtual void _request_listener_update();
@@ -54,14 +79,6 @@ class AudioListener3D : public Node3D {
5479
void _notification(int p_what);
5580

5681
static void _bind_methods();
57-
58-
public:
59-
void make_current();
60-
void clear_current();
61-
bool is_current() const;
62-
63-
virtual Transform3D get_listener_transform() const;
64-
65-
AudioListener3D();
66-
~AudioListener3D();
6782
};
83+
84+
VARIANT_ENUM_CAST(AudioListener3D::DopplerTracking);

scene/3d/audio_stream_player_3d.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,13 +397,11 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() {
397397
continue;
398398
}
399399

400-
bool listener_is_camera = true;
401400
Node3D *listener_node = camera;
402401

403402
AudioListener3D *listener = vp->get_audio_listener_3d();
404403
if (listener) {
405404
listener_node = listener;
406-
listener_is_camera = false;
407405
}
408406

409407
Vector3 local_pos = listener_node->get_global_transform().orthonormalized().affine_inverse().xform(global_pos);
@@ -507,7 +505,9 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() {
507505
if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
508506
Vector3 listener_velocity;
509507

510-
if (listener_is_camera) {
508+
if (listener) {
509+
listener_velocity = listener->get_doppler_tracked_velocity();
510+
} else {
511511
listener_velocity = camera->get_doppler_tracked_velocity();
512512
}
513513

0 commit comments

Comments
 (0)