1/**************************************************************************/
2/* audio_listener_3d.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "audio_listener_3d.h"
32
33#include "scene/main/viewport.h"
34
35void AudioListener3D::_update_audio_listener_state() {
36}
37
38void AudioListener3D::_request_listener_update() {
39 _update_listener();
40}
41
42bool AudioListener3D::_set(const StringName &p_name, const Variant &p_value) {
43 if (p_name == "current") {
44 if (p_value.operator bool()) {
45 make_current();
46 } else {
47 clear_current();
48 }
49 } else {
50 return false;
51 }
52
53 return true;
54}
55
56bool AudioListener3D::_get(const StringName &p_name, Variant &r_ret) const {
57 if (p_name == "current") {
58 if (is_inside_tree() && get_tree()->is_node_being_edited(this)) {
59 r_ret = current;
60 } else {
61 r_ret = is_current();
62 }
63 } else {
64 return false;
65 }
66
67 return true;
68}
69
70void AudioListener3D::_get_property_list(List<PropertyInfo> *p_list) const {
71 p_list->push_back(PropertyInfo(Variant::BOOL, PNAME("current")));
72}
73
74void AudioListener3D::_update_listener() {
75 if (is_inside_tree() && is_current()) {
76 get_viewport()->_listener_transform_3d_changed_notify();
77 }
78}
79
80void AudioListener3D::_notification(int p_what) {
81 switch (p_what) {
82 case NOTIFICATION_ENTER_WORLD: {
83 bool first_listener = get_viewport()->_audio_listener_3d_add(this);
84 if (!get_tree()->is_node_being_edited(this) && (current || first_listener)) {
85 make_current();
86 }
87 } break;
88
89 case NOTIFICATION_TRANSFORM_CHANGED: {
90 _request_listener_update();
91 } break;
92
93 case NOTIFICATION_EXIT_WORLD: {
94 if (!get_tree()->is_node_being_edited(this)) {
95 if (is_current()) {
96 clear_current();
97 current = true; //keep it true
98
99 } else {
100 current = false;
101 }
102 }
103
104 get_viewport()->_audio_listener_3d_remove(this);
105 } break;
106 }
107}
108
109Transform3D AudioListener3D::get_listener_transform() const {
110 return get_global_transform().orthonormalized();
111}
112
113void AudioListener3D::make_current() {
114 current = true;
115
116 if (!is_inside_tree()) {
117 return;
118 }
119
120 get_viewport()->_audio_listener_3d_set(this);
121}
122
123void AudioListener3D::clear_current() {
124 current = false;
125 if (!is_inside_tree()) {
126 return;
127 }
128
129 if (get_viewport()->get_audio_listener_3d() == this) {
130 get_viewport()->_audio_listener_3d_set(nullptr);
131 get_viewport()->_audio_listener_3d_make_next_current(this);
132 }
133}
134
135bool AudioListener3D::is_current() const {
136 if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) {
137 return get_viewport()->get_audio_listener_3d() == this;
138 } else {
139 return current;
140 }
141}
142
143void AudioListener3D::_bind_methods() {
144 ClassDB::bind_method(D_METHOD("make_current"), &AudioListener3D::make_current);
145 ClassDB::bind_method(D_METHOD("clear_current"), &AudioListener3D::clear_current);
146 ClassDB::bind_method(D_METHOD("is_current"), &AudioListener3D::is_current);
147 ClassDB::bind_method(D_METHOD("get_listener_transform"), &AudioListener3D::get_listener_transform);
148}
149
150AudioListener3D::AudioListener3D() {
151 set_notify_transform(true);
152}
153
154AudioListener3D::~AudioListener3D() {
155}
156