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