feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -34,12 +34,15 @@
|
|||
#include "core/config/project_settings.h"
|
||||
#include "scene/3d/audio_listener_3d.h"
|
||||
#include "scene/3d/camera_3d.h"
|
||||
#include "scene/3d/physics/area_3d.h"
|
||||
#include "scene/3d/velocity_tracker_3d.h"
|
||||
#include "scene/audio/audio_stream_player_internal.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "servers/audio/audio_stream.h"
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
#include "scene/3d/physics/area_3d.h"
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
// Based on "A Novel Multichannel Panning Method for Standard and Arbitrary Loudspeaker Configurations" by Ramy Sadek and Chris Kyriakakis (2004)
|
||||
// Speaker-Placement Correction Amplitude Panning (SPCAP)
|
||||
class Spcap {
|
||||
|
|
@ -60,6 +63,8 @@ public:
|
|||
w[speaker_num].direction = speaker_directions[speaker_num];
|
||||
w[speaker_num].squared_gain = 0.0;
|
||||
w[speaker_num].effective_number_of_speakers = 0.0;
|
||||
}
|
||||
for (unsigned int speaker_num = 0; speaker_num < speaker_count; speaker_num++) {
|
||||
for (unsigned int other_speaker_num = 0; other_speaker_num < speaker_count; other_speaker_num++) {
|
||||
w[speaker_num].effective_number_of_speakers += 0.5 * (1.0 + w[speaker_num].direction.dot(w[other_speaker_num].direction));
|
||||
}
|
||||
|
|
@ -141,6 +146,19 @@ void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tig
|
|||
}
|
||||
}
|
||||
|
||||
// Set the volume to cosine of half horizontal the angle from the source to the left/right speaker direction ignoring elevation.
|
||||
// Then scale `cosx` so that greatest ratio of the speaker volumes is `1-panning_strength`.
|
||||
// See https://github.com/godotengine/godot/issues/103989 for evidence that this is the most standard implementation.
|
||||
AudioFrame AudioStreamPlayer3D::_calc_output_vol_stereo(const Vector3 &source_dir, real_t panning_strength) {
|
||||
double flatrad = sqrt(source_dir.x * source_dir.x + source_dir.z * source_dir.z);
|
||||
double g = CLAMP((1.0 - panning_strength) * (1.0 - panning_strength), 0.0, 1.0);
|
||||
double f = (1.0 - g) / (1.0 + g);
|
||||
double cosx = CLAMP(source_dir.x / (flatrad == 0.0 ? 1.0 : flatrad), -1.0, 1.0);
|
||||
double fcosx = cosx * f;
|
||||
return AudioFrame(sqrt((-fcosx + 1.0) / 2.0), sqrt((fcosx + 1.0) / 2.0));
|
||||
}
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
void AudioStreamPlayer3D::_calc_reverb_vol(Area3D *area, Vector3 listener_area_pos, Vector<AudioFrame> direct_path_vol, Vector<AudioFrame> &reverb_vol) {
|
||||
reverb_vol.resize(4);
|
||||
reverb_vol.write[0] = AudioFrame(0, 0);
|
||||
|
|
@ -209,6 +227,7 @@ void AudioStreamPlayer3D::_calc_reverb_vol(Area3D *area, Vector3 listener_area_p
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const {
|
||||
float att = 0;
|
||||
|
|
@ -283,6 +302,7 @@ void AudioStreamPlayer3D::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
// Interacts with PhysicsServer3D, so can only be called during _physics_process
|
||||
Area3D *AudioStreamPlayer3D::_get_overriding_area() {
|
||||
//check if any area is diverting sound into a bus
|
||||
|
|
@ -321,13 +341,16 @@ Area3D *AudioStreamPlayer3D::_get_overriding_area() {
|
|||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
// Interacts with PhysicsServer3D, so can only be called during _physics_process.
|
||||
StringName AudioStreamPlayer3D::_get_actual_bus() {
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
Area3D *overriding_area = _get_overriding_area();
|
||||
if (overriding_area && overriding_area->is_overriding_audio_bus() && !overriding_area->is_using_reverb_bus()) {
|
||||
return overriding_area->get_audio_bus_name();
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
return internal->bus;
|
||||
}
|
||||
|
||||
|
|
@ -358,7 +381,9 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() {
|
|||
HashSet<Camera3D *> cameras = world_3d->get_cameras();
|
||||
cameras.insert(get_viewport()->get_camera_3d());
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
PhysicsDirectSpaceState3D *space_state = PhysicsServer3D::get_singleton()->space_get_direct_state(world_3d->get_space());
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
for (Camera3D *camera : cameras) {
|
||||
if (!camera) {
|
||||
|
|
@ -388,19 +413,22 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() {
|
|||
Vector3 area_sound_pos;
|
||||
Vector3 listener_area_pos;
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
Area3D *area = _get_overriding_area();
|
||||
|
||||
if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) {
|
||||
area_sound_pos = space_state->get_closest_point_to_object_volume(area->get_rid(), listener_node->get_global_transform().origin);
|
||||
listener_area_pos = listener_node->get_global_transform().affine_inverse().xform(area_sound_pos);
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
|
||||
if (max_distance > 0) {
|
||||
float total_max = max_distance;
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) {
|
||||
total_max = MAX(total_max, listener_area_pos.length());
|
||||
}
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
if (dist > total_max || total_max > max_distance) {
|
||||
if (!was_further_than_max_distance_last_frame) {
|
||||
HashMap<StringName, Vector<AudioFrame>> bus_volumes;
|
||||
|
|
@ -435,16 +463,25 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() {
|
|||
for (Ref<AudioStreamPlayback> &playback : internal->stream_playbacks) {
|
||||
AudioServer::get_singleton()->set_playback_highshelf_params(playback, linear_attenuation, attenuation_filter_cutoff_hz);
|
||||
}
|
||||
// Bake in a constant factor here to allow the project setting defaults for 2d and 3d to be normalized to 1.0.
|
||||
float tightness = cached_global_panning_strength * 2.0f;
|
||||
tightness *= panning_strength;
|
||||
_calc_output_vol(local_pos.normalized(), tightness, output_volume_vector);
|
||||
|
||||
if (AudioServer::get_singleton()->get_speaker_mode() == AudioServer::SPEAKER_MODE_STEREO) {
|
||||
output_volume_vector.write[0] = _calc_output_vol_stereo(local_pos, cached_global_panning_strength * panning_strength);
|
||||
output_volume_vector.write[1] = AudioFrame(0, 0);
|
||||
output_volume_vector.write[2] = AudioFrame(0, 0);
|
||||
output_volume_vector.write[3] = AudioFrame(0, 0);
|
||||
} else {
|
||||
// Bake in a constant factor here to allow the project setting defaults for 2d and 3d to be normalized to 1.0.
|
||||
float tightness = cached_global_panning_strength * 2.0f;
|
||||
tightness *= panning_strength;
|
||||
_calc_output_vol(local_pos.normalized(), tightness, output_volume_vector);
|
||||
}
|
||||
|
||||
for (unsigned int k = 0; k < 4; k++) {
|
||||
output_volume_vector.write[k] = multiplier * output_volume_vector[k];
|
||||
}
|
||||
|
||||
HashMap<StringName, Vector<AudioFrame>> bus_volumes;
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
if (area) {
|
||||
if (area->is_overriding_audio_bus()) {
|
||||
//override audio bus
|
||||
|
|
@ -457,7 +494,9 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() {
|
|||
_calc_reverb_vol(area, listener_area_pos, output_volume_vector, reverb_vol);
|
||||
bus_volumes[reverb_bus_name] = reverb_vol;
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
#endif // PHYSICS_3D_DISABLED
|
||||
{
|
||||
bus_volumes[internal->bus] = output_volume_vector;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue