1 /*************************************************************************/
2 /* listener.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
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 "listener.h"
32
33 #include "scene/resources/mesh.h"
34
_update_audio_listener_state()35 void Listener::_update_audio_listener_state() {
36 }
37
_request_listener_update()38 void Listener::_request_listener_update() {
39
40 _update_listener();
41 }
42
_set(const StringName & p_name,const Variant & p_value)43 bool Listener::_set(const StringName &p_name, const Variant &p_value) {
44
45 if (p_name == "current") {
46 if (p_value.operator bool()) {
47 make_current();
48 } else {
49 clear_current();
50 }
51 } else
52 return false;
53
54 return true;
55 }
_get(const StringName & p_name,Variant & r_ret) const56 bool Listener::_get(const StringName &p_name, Variant &r_ret) const {
57
58 if (p_name == "current") {
59 if (is_inside_tree() && get_tree()->is_node_being_edited(this)) {
60 r_ret = current;
61 } else {
62 r_ret = is_current();
63 }
64 } else
65 return false;
66
67 return true;
68 }
69
_get_property_list(List<PropertyInfo> * p_list) const70 void Listener::_get_property_list(List<PropertyInfo> *p_list) const {
71
72 p_list->push_back(PropertyInfo(Variant::BOOL, "current"));
73 }
74
_update_listener()75 void Listener::_update_listener() {
76
77 if (is_inside_tree() && is_current()) {
78 get_viewport()->_listener_transform_changed_notify();
79 }
80 }
81
_notification(int p_what)82 void Listener::_notification(int p_what) {
83
84 switch (p_what) {
85
86 case NOTIFICATION_ENTER_WORLD: {
87 bool first_listener = get_viewport()->_listener_add(this);
88 if (!get_tree()->is_node_being_edited(this) && (current || first_listener))
89 make_current();
90 } break;
91 case NOTIFICATION_TRANSFORM_CHANGED: {
92 _request_listener_update();
93 } break;
94 case NOTIFICATION_EXIT_WORLD: {
95
96 if (!get_tree()->is_node_being_edited(this)) {
97 if (is_current()) {
98 clear_current();
99 current = true; //keep it true
100
101 } else {
102 current = false;
103 }
104 }
105
106 get_viewport()->_listener_remove(this);
107
108 } break;
109 }
110 }
111
get_listener_transform() const112 Transform Listener::get_listener_transform() const {
113
114 return get_global_transform().orthonormalized();
115 }
116
make_current()117 void Listener::make_current() {
118
119 current = true;
120
121 if (!is_inside_tree())
122 return;
123
124 get_viewport()->_listener_set(this);
125 }
126
clear_current()127 void Listener::clear_current() {
128
129 current = false;
130 if (!is_inside_tree())
131 return;
132
133 if (get_viewport()->get_listener() == this) {
134 get_viewport()->_listener_set(NULL);
135 get_viewport()->_listener_make_next_current(this);
136 }
137 }
138
is_current() const139 bool Listener::is_current() const {
140
141 if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) {
142
143 return get_viewport()->get_listener() == this;
144 } else
145 return current;
146
147 return false;
148 }
149
_can_gizmo_scale() const150 bool Listener::_can_gizmo_scale() const {
151
152 return false;
153 }
154
_get_gizmo_geometry() const155 RES Listener::_get_gizmo_geometry() const {
156 Ref<ArrayMesh> mesh = memnew(ArrayMesh);
157
158 return mesh;
159 }
160
_bind_methods()161 void Listener::_bind_methods() {
162
163 ClassDB::bind_method(D_METHOD("make_current"), &Listener::make_current);
164 ClassDB::bind_method(D_METHOD("clear_current"), &Listener::clear_current);
165 ClassDB::bind_method(D_METHOD("is_current"), &Listener::is_current);
166 ClassDB::bind_method(D_METHOD("get_listener_transform"), &Listener::get_listener_transform);
167 }
168
Listener()169 Listener::Listener() {
170
171 current = false;
172 force_change = false;
173 set_notify_transform(true);
174 //active=false;
175 }
176
~Listener()177 Listener::~Listener() {
178 }
179