1 /*************************************************************************/
2 /*  animation_tree.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 "animation_tree.h"
32 
33 #include "animation_blend_tree.h"
34 #include "core/engine.h"
35 #include "core/method_bind_ext.gen.inc"
36 #include "scene/scene_string_names.h"
37 #include "servers/audio/audio_stream.h"
38 
get_parameter_list(List<PropertyInfo> * r_list) const39 void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
40 	if (get_script_instance()) {
41 		Array parameters = get_script_instance()->call("get_parameter_list");
42 		for (int i = 0; i < parameters.size(); i++) {
43 			Dictionary d = parameters[i];
44 			ERR_CONTINUE(d.empty());
45 			r_list->push_back(PropertyInfo::from_dict(d));
46 		}
47 	}
48 }
49 
get_parameter_default_value(const StringName & p_parameter) const50 Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter) const {
51 	if (get_script_instance()) {
52 		return get_script_instance()->call("get_parameter_default_value", p_parameter);
53 	}
54 	return Variant();
55 }
56 
set_parameter(const StringName & p_name,const Variant & p_value)57 void AnimationNode::set_parameter(const StringName &p_name, const Variant &p_value) {
58 	ERR_FAIL_COND(!state);
59 	ERR_FAIL_COND(!state->tree->property_parent_map.has(base_path));
60 	ERR_FAIL_COND(!state->tree->property_parent_map[base_path].has(p_name));
61 	StringName path = state->tree->property_parent_map[base_path][p_name];
62 
63 	state->tree->property_map[path] = p_value;
64 }
65 
get_parameter(const StringName & p_name) const66 Variant AnimationNode::get_parameter(const StringName &p_name) const {
67 	ERR_FAIL_COND_V(!state, Variant());
68 	ERR_FAIL_COND_V(!state->tree->property_parent_map.has(base_path), Variant());
69 	ERR_FAIL_COND_V(!state->tree->property_parent_map[base_path].has(p_name), Variant());
70 
71 	StringName path = state->tree->property_parent_map[base_path][p_name];
72 	return state->tree->property_map[path];
73 }
74 
get_child_nodes(List<ChildNode> * r_child_nodes)75 void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
76 
77 	if (get_script_instance()) {
78 		Dictionary cn = get_script_instance()->call("get_child_nodes");
79 		List<Variant> keys;
80 		cn.get_key_list(&keys);
81 		for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
82 			ChildNode child;
83 			child.name = E->get();
84 			child.node = cn[E->get()];
85 			r_child_nodes->push_back(child);
86 		}
87 	}
88 }
89 
blend_animation(const StringName & p_animation,float p_time,float p_delta,bool p_seeked,float p_blend)90 void AnimationNode::blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend) {
91 
92 	ERR_FAIL_COND(!state);
93 	ERR_FAIL_COND(!state->player->has_animation(p_animation));
94 
95 	Ref<Animation> animation = state->player->get_animation(p_animation);
96 
97 	if (animation.is_null()) {
98 
99 		AnimationNodeBlendTree *btree = Object::cast_to<AnimationNodeBlendTree>(parent);
100 		if (btree) {
101 			String name = btree->get_node_name(Ref<AnimationNodeAnimation>(this));
102 			make_invalid(vformat(RTR("In node '%s', invalid animation: '%s'."), name, p_animation));
103 		} else {
104 			make_invalid(vformat(RTR("Invalid animation: '%s'."), p_animation));
105 		}
106 		return;
107 	}
108 
109 	ERR_FAIL_COND(!animation.is_valid());
110 
111 	AnimationState anim_state;
112 	anim_state.blend = p_blend;
113 	anim_state.track_blends = &blends;
114 	anim_state.delta = p_delta;
115 	anim_state.time = p_time;
116 	anim_state.animation = animation;
117 	anim_state.seeked = p_seeked;
118 
119 	state->animation_states.push_back(anim_state);
120 }
121 
_pre_process(const StringName & p_base_path,AnimationNode * p_parent,State * p_state,float p_time,bool p_seek,const Vector<StringName> & p_connections)122 float AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections) {
123 
124 	base_path = p_base_path;
125 	parent = p_parent;
126 	connections = p_connections;
127 	state = p_state;
128 
129 	float t = process(p_time, p_seek);
130 
131 	state = NULL;
132 	parent = NULL;
133 	base_path = StringName();
134 	connections.clear();
135 
136 	return t;
137 }
138 
make_invalid(const String & p_reason)139 void AnimationNode::make_invalid(const String &p_reason) {
140 	ERR_FAIL_COND(!state);
141 	state->valid = false;
142 	if (state->invalid_reasons != String()) {
143 		state->invalid_reasons += "\n";
144 	}
145 	state->invalid_reasons += "- " + p_reason;
146 }
147 
blend_input(int p_input,float p_time,bool p_seek,float p_blend,FilterAction p_filter,bool p_optimize)148 float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) {
149 	ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
150 	ERR_FAIL_COND_V(!state, 0);
151 
152 	AnimationNodeBlendTree *blend_tree = Object::cast_to<AnimationNodeBlendTree>(parent);
153 	ERR_FAIL_COND_V(!blend_tree, 0);
154 
155 	StringName node_name = connections[p_input];
156 
157 	if (!blend_tree->has_node(node_name)) {
158 		String name = blend_tree->get_node_name(Ref<AnimationNode>(this));
159 		make_invalid(vformat(RTR("Nothing connected to input '%s' of node '%s'."), get_input_name(p_input), name));
160 		return 0;
161 	}
162 
163 	Ref<AnimationNode> node = blend_tree->get_node(node_name);
164 
165 	//inputs.write[p_input].last_pass = state->last_pass;
166 	float activity = 0;
167 	float ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), NULL, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity);
168 
169 	Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
170 
171 	if (activity_ptr && p_input < activity_ptr->size()) {
172 		activity_ptr->write[p_input].last_pass = state->last_pass;
173 		activity_ptr->write[p_input].activity = activity;
174 	}
175 	return ret;
176 }
177 
blend_node(const StringName & p_sub_path,Ref<AnimationNode> p_node,float p_time,bool p_seek,float p_blend,FilterAction p_filter,bool p_optimize)178 float AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) {
179 
180 	return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_blend, p_filter, p_optimize);
181 }
182 
_blend_node(const StringName & p_subpath,const Vector<StringName> & p_connections,AnimationNode * p_new_parent,Ref<AnimationNode> p_node,float p_time,bool p_seek,float p_blend,FilterAction p_filter,bool p_optimize,float * r_max)183 float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize, float *r_max) {
184 
185 	ERR_FAIL_COND_V(!p_node.is_valid(), 0);
186 	ERR_FAIL_COND_V(!state, 0);
187 
188 	int blend_count = blends.size();
189 
190 	if (p_node->blends.size() != blend_count) {
191 		p_node->blends.resize(blend_count);
192 	}
193 
194 	float *blendw = p_node->blends.ptrw();
195 	const float *blendr = blends.ptr();
196 
197 	bool any_valid = false;
198 
199 	if (has_filter() && is_filter_enabled() && p_filter != FILTER_IGNORE) {
200 
201 		for (int i = 0; i < blend_count; i++) {
202 			blendw[i] = 0.0; //all to zero by default
203 		}
204 
205 		const NodePath *K = NULL;
206 		while ((K = filter.next(K))) {
207 			if (!state->track_map.has(*K)) {
208 				continue;
209 			}
210 			int idx = state->track_map[*K];
211 			blendw[idx] = 1.0; //filtered goes to one
212 		}
213 
214 		switch (p_filter) {
215 			case FILTER_IGNORE:
216 				break; //will not happen anyway
217 			case FILTER_PASS: {
218 				//values filtered pass, the rest don't
219 				for (int i = 0; i < blend_count; i++) {
220 					if (blendw[i] == 0) //not filtered, does not pass
221 						continue;
222 
223 					blendw[i] = blendr[i] * p_blend;
224 					if (blendw[i] > CMP_EPSILON) {
225 						any_valid = true;
226 					}
227 				}
228 
229 			} break;
230 			case FILTER_STOP: {
231 
232 				//values filtered don't pass, the rest are blended
233 
234 				for (int i = 0; i < blend_count; i++) {
235 					if (blendw[i] > 0) //filtered, does not pass
236 						continue;
237 
238 					blendw[i] = blendr[i] * p_blend;
239 					if (blendw[i] > CMP_EPSILON) {
240 						any_valid = true;
241 					}
242 				}
243 
244 			} break;
245 			case FILTER_BLEND: {
246 
247 				//filtered values are blended, the rest are passed without blending
248 
249 				for (int i = 0; i < blend_count; i++) {
250 					if (blendw[i] == 1.0) {
251 						blendw[i] = blendr[i] * p_blend; //filtered, blend
252 					} else {
253 						blendw[i] = blendr[i]; //not filtered, do not blend
254 					}
255 
256 					if (blendw[i] > CMP_EPSILON) {
257 						any_valid = true;
258 					}
259 				}
260 
261 			} break;
262 		}
263 	} else {
264 		for (int i = 0; i < blend_count; i++) {
265 
266 			//regular blend
267 			blendw[i] = blendr[i] * p_blend;
268 			if (blendw[i] > CMP_EPSILON) {
269 				any_valid = true;
270 			}
271 		}
272 	}
273 
274 	if (r_max) {
275 		*r_max = 0;
276 		for (int i = 0; i < blend_count; i++) {
277 			*r_max = MAX(*r_max, blendw[i]);
278 		}
279 	}
280 
281 	if (!p_seek && p_optimize && !any_valid) //pointless to go on, all are zero
282 		return 0;
283 
284 	String new_path;
285 	AnimationNode *new_parent;
286 
287 	//this is the slowest part of processing, but as strings process in powers of 2, and the paths always exist, it will not result in that many allocations
288 	if (p_new_parent) {
289 		new_parent = p_new_parent;
290 		new_path = String(base_path) + String(p_subpath) + "/";
291 	} else {
292 		ERR_FAIL_COND_V(!parent, 0);
293 		new_parent = parent;
294 		new_path = String(parent->base_path) + String(p_subpath) + "/";
295 	}
296 	return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_connections);
297 }
298 
get_input_count() const299 int AnimationNode::get_input_count() const {
300 
301 	return inputs.size();
302 }
get_input_name(int p_input)303 String AnimationNode::get_input_name(int p_input) {
304 	ERR_FAIL_INDEX_V(p_input, inputs.size(), String());
305 	return inputs[p_input].name;
306 }
307 
get_caption() const308 String AnimationNode::get_caption() const {
309 
310 	if (get_script_instance()) {
311 		return get_script_instance()->call("get_caption");
312 	}
313 
314 	return "Node";
315 }
316 
add_input(const String & p_name)317 void AnimationNode::add_input(const String &p_name) {
318 	//root nodes can't add inputs
319 	ERR_FAIL_COND(Object::cast_to<AnimationRootNode>(this) != NULL);
320 	Input input;
321 	ERR_FAIL_COND(p_name.find(".") != -1 || p_name.find("/") != -1);
322 	input.name = p_name;
323 	inputs.push_back(input);
324 	emit_changed();
325 }
326 
set_input_name(int p_input,const String & p_name)327 void AnimationNode::set_input_name(int p_input, const String &p_name) {
328 	ERR_FAIL_INDEX(p_input, inputs.size());
329 	ERR_FAIL_COND(p_name.find(".") != -1 || p_name.find("/") != -1);
330 	inputs.write[p_input].name = p_name;
331 	emit_changed();
332 }
333 
remove_input(int p_index)334 void AnimationNode::remove_input(int p_index) {
335 	ERR_FAIL_INDEX(p_index, inputs.size());
336 	inputs.remove(p_index);
337 	emit_changed();
338 }
339 
process(float p_time,bool p_seek)340 float AnimationNode::process(float p_time, bool p_seek) {
341 
342 	if (get_script_instance()) {
343 		return get_script_instance()->call("process", p_time, p_seek);
344 	}
345 
346 	return 0;
347 }
348 
set_filter_path(const NodePath & p_path,bool p_enable)349 void AnimationNode::set_filter_path(const NodePath &p_path, bool p_enable) {
350 	if (p_enable) {
351 		filter[p_path] = true;
352 	} else {
353 		filter.erase(p_path);
354 	}
355 }
356 
set_filter_enabled(bool p_enable)357 void AnimationNode::set_filter_enabled(bool p_enable) {
358 	filter_enabled = p_enable;
359 }
360 
is_filter_enabled() const361 bool AnimationNode::is_filter_enabled() const {
362 	return filter_enabled;
363 }
364 
is_path_filtered(const NodePath & p_path) const365 bool AnimationNode::is_path_filtered(const NodePath &p_path) const {
366 	return filter.has(p_path);
367 }
368 
has_filter() const369 bool AnimationNode::has_filter() const {
370 	return false;
371 }
372 
_get_filters() const373 Array AnimationNode::_get_filters() const {
374 
375 	Array paths;
376 
377 	const NodePath *K = NULL;
378 	while ((K = filter.next(K))) {
379 		paths.push_back(String(*K)); //use strings, so sorting is possible
380 	}
381 	paths.sort(); //done so every time the scene is saved, it does not change
382 
383 	return paths;
384 }
_set_filters(const Array & p_filters)385 void AnimationNode::_set_filters(const Array &p_filters) {
386 	filter.clear();
387 	for (int i = 0; i < p_filters.size(); i++) {
388 		set_filter_path(p_filters[i], true);
389 	}
390 }
391 
_validate_property(PropertyInfo & property) const392 void AnimationNode::_validate_property(PropertyInfo &property) const {
393 	if (!has_filter() && (property.name == "filter_enabled" || property.name == "filters")) {
394 		property.usage = 0;
395 	}
396 }
397 
get_child_by_name(const StringName & p_name)398 Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) {
399 	if (get_script_instance()) {
400 		return get_script_instance()->call("get_child_by_name", p_name);
401 	}
402 	return Ref<AnimationNode>();
403 }
404 
_bind_methods()405 void AnimationNode::_bind_methods() {
406 
407 	ClassDB::bind_method(D_METHOD("get_input_count"), &AnimationNode::get_input_count);
408 	ClassDB::bind_method(D_METHOD("get_input_name", "input"), &AnimationNode::get_input_name);
409 
410 	ClassDB::bind_method(D_METHOD("add_input", "name"), &AnimationNode::add_input);
411 	ClassDB::bind_method(D_METHOD("remove_input", "index"), &AnimationNode::remove_input);
412 
413 	ClassDB::bind_method(D_METHOD("set_filter_path", "path", "enable"), &AnimationNode::set_filter_path);
414 	ClassDB::bind_method(D_METHOD("is_path_filtered", "path"), &AnimationNode::is_path_filtered);
415 
416 	ClassDB::bind_method(D_METHOD("set_filter_enabled", "enable"), &AnimationNode::set_filter_enabled);
417 	ClassDB::bind_method(D_METHOD("is_filter_enabled"), &AnimationNode::is_filter_enabled);
418 
419 	ClassDB::bind_method(D_METHOD("_set_filters", "filters"), &AnimationNode::_set_filters);
420 	ClassDB::bind_method(D_METHOD("_get_filters"), &AnimationNode::_get_filters);
421 
422 	ClassDB::bind_method(D_METHOD("blend_animation", "animation", "time", "delta", "seeked", "blend"), &AnimationNode::blend_animation);
423 	ClassDB::bind_method(D_METHOD("blend_node", "name", "node", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true));
424 	ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true));
425 
426 	ClassDB::bind_method(D_METHOD("set_parameter", "name", "value"), &AnimationNode::set_parameter);
427 	ClassDB::bind_method(D_METHOD("get_parameter", "name"), &AnimationNode::get_parameter);
428 
429 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_filter_enabled", "is_filter_enabled");
430 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "filters", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_filters", "_get_filters");
431 
432 	BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "get_child_nodes"));
433 	BIND_VMETHOD(MethodInfo(Variant::ARRAY, "get_parameter_list"));
434 	BIND_VMETHOD(MethodInfo(Variant::OBJECT, "get_child_by_name", PropertyInfo(Variant::STRING, "name")));
435 	{
436 		MethodInfo mi = MethodInfo(Variant::NIL, "get_parameter_default_value", PropertyInfo(Variant::STRING, "name"));
437 		mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT;
438 		BIND_VMETHOD(mi);
439 	}
440 	BIND_VMETHOD(MethodInfo("process", PropertyInfo(Variant::REAL, "time"), PropertyInfo(Variant::BOOL, "seek")));
441 	BIND_VMETHOD(MethodInfo(Variant::STRING, "get_caption"));
442 	BIND_VMETHOD(MethodInfo(Variant::STRING, "has_filter"));
443 
444 	ADD_SIGNAL(MethodInfo("removed_from_graph"));
445 
446 	ADD_SIGNAL(MethodInfo("tree_changed"));
447 
448 	BIND_ENUM_CONSTANT(FILTER_IGNORE);
449 	BIND_ENUM_CONSTANT(FILTER_PASS);
450 	BIND_ENUM_CONSTANT(FILTER_STOP);
451 	BIND_ENUM_CONSTANT(FILTER_BLEND);
452 }
453 
AnimationNode()454 AnimationNode::AnimationNode() {
455 
456 	state = NULL;
457 	parent = NULL;
458 	filter_enabled = false;
459 }
460 
461 ////////////////////
462 
set_tree_root(const Ref<AnimationNode> & p_root)463 void AnimationTree::set_tree_root(const Ref<AnimationNode> &p_root) {
464 
465 	if (root.is_valid()) {
466 		root->disconnect("tree_changed", this, "_tree_changed");
467 	}
468 
469 	root = p_root;
470 
471 	if (root.is_valid()) {
472 		root->connect("tree_changed", this, "_tree_changed");
473 	}
474 
475 	properties_dirty = true;
476 
477 	update_configuration_warning();
478 }
479 
get_tree_root() const480 Ref<AnimationNode> AnimationTree::get_tree_root() const {
481 	return root;
482 }
483 
set_active(bool p_active)484 void AnimationTree::set_active(bool p_active) {
485 
486 	if (active == p_active)
487 		return;
488 
489 	active = p_active;
490 	started = active;
491 
492 	if (process_mode == ANIMATION_PROCESS_IDLE) {
493 		set_process_internal(active);
494 	} else {
495 
496 		set_physics_process_internal(active);
497 	}
498 
499 	if (!active && is_inside_tree()) {
500 		for (Set<TrackCache *>::Element *E = playing_caches.front(); E; E = E->next()) {
501 
502 			if (ObjectDB::get_instance(E->get()->object_id)) {
503 				E->get()->object->call("stop");
504 			}
505 		}
506 
507 		playing_caches.clear();
508 	}
509 }
510 
is_active() const511 bool AnimationTree::is_active() const {
512 
513 	return active;
514 }
515 
set_process_mode(AnimationProcessMode p_mode)516 void AnimationTree::set_process_mode(AnimationProcessMode p_mode) {
517 
518 	if (process_mode == p_mode)
519 		return;
520 
521 	bool was_active = is_active();
522 	if (was_active) {
523 		set_active(false);
524 	}
525 
526 	process_mode = p_mode;
527 
528 	if (was_active) {
529 		set_active(true);
530 	}
531 }
532 
get_process_mode() const533 AnimationTree::AnimationProcessMode AnimationTree::get_process_mode() const {
534 	return process_mode;
535 }
536 
_node_removed(Node * p_node)537 void AnimationTree::_node_removed(Node *p_node) {
538 	cache_valid = false;
539 }
540 
_update_caches(AnimationPlayer * player)541 bool AnimationTree::_update_caches(AnimationPlayer *player) {
542 
543 	setup_pass++;
544 
545 	if (!player->has_node(player->get_root())) {
546 		ERR_PRINT("AnimationTree: AnimationPlayer root is invalid.");
547 		set_active(false);
548 		return false;
549 	}
550 	Node *parent = player->get_node(player->get_root());
551 
552 	List<StringName> sname;
553 	player->get_animation_list(&sname);
554 
555 	for (List<StringName>::Element *E = sname.front(); E; E = E->next()) {
556 		Ref<Animation> anim = player->get_animation(E->get());
557 		for (int i = 0; i < anim->get_track_count(); i++) {
558 			NodePath path = anim->track_get_path(i);
559 			Animation::TrackType track_type = anim->track_get_type(i);
560 
561 			TrackCache *track = NULL;
562 			if (track_cache.has(path)) {
563 				track = track_cache.get(path);
564 			}
565 
566 			//if not valid, delete track
567 			if (track && (track->type != track_type || ObjectDB::get_instance(track->object_id) == NULL)) {
568 				playing_caches.erase(track);
569 				memdelete(track);
570 				track_cache.erase(path);
571 				track = NULL;
572 			}
573 
574 			if (!track) {
575 
576 				RES resource;
577 				Vector<StringName> leftover_path;
578 				Node *child = parent->get_node_and_resource(path, resource, leftover_path);
579 
580 				if (!child) {
581 					ERR_PRINTS("AnimationTree: '" + String(E->get()) + "', couldn't resolve track:  '" + String(path) + "'");
582 					continue;
583 				}
584 
585 				if (!child->is_connected("tree_exited", this, "_node_removed")) {
586 					child->connect("tree_exited", this, "_node_removed", varray(child));
587 				}
588 
589 				switch (track_type) {
590 					case Animation::TYPE_VALUE: {
591 
592 						TrackCacheValue *track_value = memnew(TrackCacheValue);
593 
594 						if (resource.is_valid()) {
595 							track_value->object = resource.ptr();
596 						} else {
597 							track_value->object = child;
598 						}
599 
600 						track_value->subpath = leftover_path;
601 						track_value->object_id = track_value->object->get_instance_id();
602 
603 						track = track_value;
604 
605 					} break;
606 					case Animation::TYPE_TRANSFORM: {
607 
608 						Spatial *spatial = Object::cast_to<Spatial>(child);
609 
610 						if (!spatial) {
611 							ERR_PRINTS("AnimationTree: '" + String(E->get()) + "', transform track does not point to spatial:  '" + String(path) + "'");
612 							continue;
613 						}
614 
615 						TrackCacheTransform *track_xform = memnew(TrackCacheTransform);
616 
617 						track_xform->spatial = spatial;
618 						track_xform->skeleton = NULL;
619 						track_xform->bone_idx = -1;
620 
621 						if (path.get_subname_count() == 1 && Object::cast_to<Skeleton>(spatial)) {
622 
623 							Skeleton *sk = Object::cast_to<Skeleton>(spatial);
624 							int bone_idx = sk->find_bone(path.get_subname(0));
625 							if (bone_idx != -1) {
626 
627 								track_xform->skeleton = sk;
628 								track_xform->bone_idx = bone_idx;
629 							}
630 						}
631 
632 						track_xform->object = spatial;
633 						track_xform->object_id = track_xform->object->get_instance_id();
634 
635 						track = track_xform;
636 
637 					} break;
638 					case Animation::TYPE_METHOD: {
639 
640 						TrackCacheMethod *track_method = memnew(TrackCacheMethod);
641 
642 						if (resource.is_valid()) {
643 							track_method->object = resource.ptr();
644 						} else {
645 							track_method->object = child;
646 						}
647 
648 						track_method->object_id = track_method->object->get_instance_id();
649 
650 						track = track_method;
651 
652 					} break;
653 					case Animation::TYPE_BEZIER: {
654 
655 						TrackCacheBezier *track_bezier = memnew(TrackCacheBezier);
656 
657 						if (resource.is_valid()) {
658 							track_bezier->object = resource.ptr();
659 						} else {
660 							track_bezier->object = child;
661 						}
662 
663 						track_bezier->subpath = leftover_path;
664 						track_bezier->object_id = track_bezier->object->get_instance_id();
665 
666 						track = track_bezier;
667 					} break;
668 					case Animation::TYPE_AUDIO: {
669 
670 						TrackCacheAudio *track_audio = memnew(TrackCacheAudio);
671 
672 						track_audio->object = child;
673 						track_audio->object_id = track_audio->object->get_instance_id();
674 
675 						track = track_audio;
676 
677 					} break;
678 					case Animation::TYPE_ANIMATION: {
679 
680 						TrackCacheAnimation *track_animation = memnew(TrackCacheAnimation);
681 
682 						track_animation->object = child;
683 						track_animation->object_id = track_animation->object->get_instance_id();
684 
685 						track = track_animation;
686 
687 					} break;
688 					default: {
689 						ERR_PRINT("Animation corrupted (invalid track type)");
690 						continue;
691 					}
692 				}
693 
694 				track_cache[path] = track;
695 			}
696 
697 			track->setup_pass = setup_pass;
698 		}
699 	}
700 
701 	List<NodePath> to_delete;
702 
703 	const NodePath *K = NULL;
704 	while ((K = track_cache.next(K))) {
705 		TrackCache *tc = track_cache[*K];
706 		if (tc->setup_pass != setup_pass) {
707 			to_delete.push_back(*K);
708 		}
709 	}
710 
711 	while (to_delete.front()) {
712 		NodePath np = to_delete.front()->get();
713 		memdelete(track_cache[np]);
714 		track_cache.erase(np);
715 		to_delete.pop_front();
716 	}
717 
718 	state.track_map.clear();
719 
720 	K = NULL;
721 	int idx = 0;
722 	while ((K = track_cache.next(K))) {
723 		state.track_map[*K] = idx;
724 		idx++;
725 	}
726 
727 	state.track_count = idx;
728 
729 	cache_valid = true;
730 
731 	return true;
732 }
733 
_clear_caches()734 void AnimationTree::_clear_caches() {
735 
736 	const NodePath *K = NULL;
737 	while ((K = track_cache.next(K))) {
738 		memdelete(track_cache[*K]);
739 	}
740 	playing_caches.clear();
741 
742 	track_cache.clear();
743 	cache_valid = false;
744 }
745 
_process_graph(float p_delta)746 void AnimationTree::_process_graph(float p_delta) {
747 
748 	_update_properties(); //if properties need updating, update them
749 
750 	//check all tracks, see if they need modification
751 
752 	root_motion_transform = Transform();
753 
754 	if (!root.is_valid()) {
755 		ERR_PRINT("AnimationTree: root AnimationNode is not set, disabling playback.");
756 		set_active(false);
757 		cache_valid = false;
758 		return;
759 	}
760 
761 	if (!has_node(animation_player)) {
762 		ERR_PRINT("AnimationTree: no valid AnimationPlayer path set, disabling playback");
763 		set_active(false);
764 		cache_valid = false;
765 		return;
766 	}
767 
768 	AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
769 
770 	ObjectID current_animation_player = 0;
771 
772 	if (player) {
773 		current_animation_player = player->get_instance_id();
774 	}
775 
776 	if (last_animation_player != current_animation_player) {
777 
778 		if (last_animation_player) {
779 			Object *old_player = ObjectDB::get_instance(last_animation_player);
780 			if (old_player) {
781 				old_player->disconnect("caches_cleared", this, "_clear_caches");
782 			}
783 		}
784 
785 		if (player) {
786 			player->connect("caches_cleared", this, "_clear_caches");
787 		}
788 
789 		last_animation_player = current_animation_player;
790 	}
791 
792 	if (!player) {
793 		ERR_PRINT("AnimationTree: path points to a node not an AnimationPlayer, disabling playback");
794 		set_active(false);
795 		cache_valid = false;
796 		return;
797 	}
798 
799 	if (!cache_valid) {
800 		if (!_update_caches(player)) {
801 			return;
802 		}
803 	}
804 
805 	{ //setup
806 
807 		process_pass++;
808 
809 		state.valid = true;
810 		state.invalid_reasons = "";
811 		state.animation_states.clear(); //will need to be re-created
812 		state.valid = true;
813 		state.player = player;
814 		state.last_pass = process_pass;
815 		state.tree = this;
816 
817 		// root source blends
818 
819 		root->blends.resize(state.track_count);
820 		float *src_blendsw = root->blends.ptrw();
821 		for (int i = 0; i < state.track_count; i++) {
822 			src_blendsw[i] = 1.0; //by default all go to 1 for the root input
823 		}
824 	}
825 
826 	//process
827 
828 	{
829 
830 		if (started) {
831 			//if started, seek
832 			root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, NULL, &state, 0, true, Vector<StringName>());
833 			started = false;
834 		}
835 
836 		root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, NULL, &state, p_delta, false, Vector<StringName>());
837 	}
838 
839 	if (!state.valid) {
840 		return; //state is not valid. do nothing.
841 	}
842 	//apply value/transform/bezier blends to track caches and execute method/audio/animation tracks
843 
844 	{
845 
846 		bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint();
847 
848 		for (List<AnimationNode::AnimationState>::Element *E = state.animation_states.front(); E; E = E->next()) {
849 
850 			const AnimationNode::AnimationState &as = E->get();
851 
852 			Ref<Animation> a = as.animation;
853 			float time = as.time;
854 			float delta = as.delta;
855 			bool seeked = as.seeked;
856 
857 			for (int i = 0; i < a->get_track_count(); i++) {
858 
859 				NodePath path = a->track_get_path(i);
860 
861 				ERR_CONTINUE(!track_cache.has(path));
862 
863 				TrackCache *track = track_cache[path];
864 				if (track->type != a->track_get_type(i)) {
865 					continue; //may happen should not
866 				}
867 
868 				track->root_motion = root_motion_track == path;
869 
870 				ERR_CONTINUE(!state.track_map.has(path));
871 				int blend_idx = state.track_map[path];
872 
873 				ERR_CONTINUE(blend_idx < 0 || blend_idx >= state.track_count);
874 
875 				float blend = (*as.track_blends)[blend_idx];
876 
877 				if (blend < CMP_EPSILON)
878 					continue; //nothing to blend
879 
880 				switch (track->type) {
881 
882 					case Animation::TYPE_TRANSFORM: {
883 
884 						TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
885 
886 						if (track->root_motion) {
887 
888 							if (t->process_pass != process_pass) {
889 
890 								t->process_pass = process_pass;
891 								t->loc = Vector3();
892 								t->rot = Quat();
893 								t->rot_blend_accum = 0;
894 								t->scale = Vector3(1, 1, 1);
895 							}
896 
897 							float prev_time = time - delta;
898 							if (prev_time < 0) {
899 								if (!a->has_loop()) {
900 									prev_time = 0;
901 								} else {
902 									prev_time = a->get_length() + prev_time;
903 								}
904 							}
905 
906 							Vector3 loc[2];
907 							Quat rot[2];
908 							Vector3 scale[2];
909 
910 							if (prev_time > time) {
911 
912 								Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]);
913 								if (err != OK) {
914 									continue;
915 								}
916 
917 								a->transform_track_interpolate(i, a->get_length(), &loc[1], &rot[1], &scale[1]);
918 
919 								t->loc += (loc[1] - loc[0]) * blend;
920 								t->scale += (scale[1] - scale[0]) * blend;
921 								Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
922 								t->rot = (t->rot * q).normalized();
923 
924 								prev_time = 0;
925 							}
926 
927 							Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]);
928 							if (err != OK) {
929 								continue;
930 							}
931 
932 							a->transform_track_interpolate(i, time, &loc[1], &rot[1], &scale[1]);
933 
934 							t->loc += (loc[1] - loc[0]) * blend;
935 							t->scale += (scale[1] - scale[0]) * blend;
936 							Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
937 							t->rot = (t->rot * q).normalized();
938 
939 							prev_time = 0;
940 
941 						} else {
942 							Vector3 loc;
943 							Quat rot;
944 							Vector3 scale;
945 
946 							Error err = a->transform_track_interpolate(i, time, &loc, &rot, &scale);
947 							//ERR_CONTINUE(err!=OK); //used for testing, should be removed
948 
949 							if (t->process_pass != process_pass) {
950 
951 								t->process_pass = process_pass;
952 								t->loc = loc;
953 								t->rot = rot;
954 								t->rot_blend_accum = 0;
955 								t->scale = scale;
956 							}
957 
958 							if (err != OK)
959 								continue;
960 
961 							t->loc = t->loc.linear_interpolate(loc, blend);
962 							if (t->rot_blend_accum == 0) {
963 								t->rot = rot;
964 								t->rot_blend_accum = blend;
965 							} else {
966 								float rot_total = t->rot_blend_accum + blend;
967 								t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized();
968 								t->rot_blend_accum = rot_total;
969 							}
970 							t->scale = t->scale.linear_interpolate(scale, blend);
971 						}
972 
973 					} break;
974 					case Animation::TYPE_VALUE: {
975 
976 						TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
977 
978 						Animation::UpdateMode update_mode = a->value_track_get_update_mode(i);
979 
980 						if (update_mode == Animation::UPDATE_CONTINUOUS || update_mode == Animation::UPDATE_CAPTURE) { //delta == 0 means seek
981 
982 							Variant value = a->value_track_interpolate(i, time);
983 
984 							if (value == Variant())
985 								continue;
986 
987 							if (t->process_pass != process_pass) {
988 								t->value = value;
989 								t->process_pass = process_pass;
990 							}
991 
992 							Variant::interpolate(t->value, value, blend, t->value);
993 
994 						} else if (delta != 0) {
995 
996 							List<int> indices;
997 							a->value_track_get_key_indices(i, time, delta, &indices);
998 
999 							for (List<int>::Element *F = indices.front(); F; F = F->next()) {
1000 
1001 								Variant value = a->track_get_key_value(i, F->get());
1002 								t->object->set_indexed(t->subpath, value);
1003 							}
1004 						}
1005 
1006 					} break;
1007 					case Animation::TYPE_METHOD: {
1008 
1009 						if (delta == 0) {
1010 							continue;
1011 						}
1012 						TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track);
1013 
1014 						List<int> indices;
1015 
1016 						a->method_track_get_key_indices(i, time, delta, &indices);
1017 
1018 						for (List<int>::Element *F = indices.front(); F; F = F->next()) {
1019 
1020 							StringName method = a->method_track_get_name(i, F->get());
1021 							Vector<Variant> params = a->method_track_get_params(i, F->get());
1022 
1023 							int s = params.size();
1024 
1025 							ERR_CONTINUE(s > VARIANT_ARG_MAX);
1026 							if (can_call) {
1027 								t->object->call_deferred(
1028 										method,
1029 										s >= 1 ? params[0] : Variant(),
1030 										s >= 2 ? params[1] : Variant(),
1031 										s >= 3 ? params[2] : Variant(),
1032 										s >= 4 ? params[3] : Variant(),
1033 										s >= 5 ? params[4] : Variant());
1034 							}
1035 						}
1036 
1037 					} break;
1038 					case Animation::TYPE_BEZIER: {
1039 
1040 						TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
1041 
1042 						float bezier = a->bezier_track_interpolate(i, time);
1043 
1044 						if (t->process_pass != process_pass) {
1045 							t->value = bezier;
1046 							t->process_pass = process_pass;
1047 						}
1048 
1049 						t->value = Math::lerp(t->value, bezier, blend);
1050 
1051 					} break;
1052 					case Animation::TYPE_AUDIO: {
1053 
1054 						TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);
1055 
1056 						if (seeked) {
1057 							//find whathever should be playing
1058 							int idx = a->track_find_key(i, time);
1059 							if (idx < 0)
1060 								continue;
1061 
1062 							Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
1063 							if (!stream.is_valid()) {
1064 								t->object->call("stop");
1065 								t->playing = false;
1066 								playing_caches.erase(t);
1067 							} else {
1068 								float start_ofs = a->audio_track_get_key_start_offset(i, idx);
1069 								start_ofs += time - a->track_get_key_time(i, idx);
1070 								float end_ofs = a->audio_track_get_key_end_offset(i, idx);
1071 								float len = stream->get_length();
1072 
1073 								if (start_ofs > len - end_ofs) {
1074 									t->object->call("stop");
1075 									t->playing = false;
1076 									playing_caches.erase(t);
1077 									continue;
1078 								}
1079 
1080 								t->object->call("set_stream", stream);
1081 								t->object->call("play", start_ofs);
1082 
1083 								t->playing = true;
1084 								playing_caches.insert(t);
1085 								if (len && end_ofs > 0) { //force a end at a time
1086 									t->len = len - start_ofs - end_ofs;
1087 								} else {
1088 									t->len = 0;
1089 								}
1090 
1091 								t->start = time;
1092 							}
1093 
1094 						} else {
1095 							//find stuff to play
1096 							List<int> to_play;
1097 							a->track_get_key_indices_in_range(i, time, delta, &to_play);
1098 							if (to_play.size()) {
1099 								int idx = to_play.back()->get();
1100 
1101 								Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
1102 								if (!stream.is_valid()) {
1103 									t->object->call("stop");
1104 									t->playing = false;
1105 									playing_caches.erase(t);
1106 								} else {
1107 									float start_ofs = a->audio_track_get_key_start_offset(i, idx);
1108 									float end_ofs = a->audio_track_get_key_end_offset(i, idx);
1109 									float len = stream->get_length();
1110 
1111 									t->object->call("set_stream", stream);
1112 									t->object->call("play", start_ofs);
1113 
1114 									t->playing = true;
1115 									playing_caches.insert(t);
1116 									if (len && end_ofs > 0) { //force a end at a time
1117 										t->len = len - start_ofs - end_ofs;
1118 									} else {
1119 										t->len = 0;
1120 									}
1121 
1122 									t->start = time;
1123 								}
1124 							} else if (t->playing) {
1125 
1126 								bool loop = a->has_loop();
1127 
1128 								bool stop = false;
1129 
1130 								if (!loop && time < t->start) {
1131 									stop = true;
1132 								} else if (t->len > 0) {
1133 									float len = t->start > time ? (a->get_length() - t->start) + time : time - t->start;
1134 
1135 									if (len > t->len) {
1136 										stop = true;
1137 									}
1138 								}
1139 
1140 								if (stop) {
1141 									//time to stop
1142 									t->object->call("stop");
1143 									t->playing = false;
1144 									playing_caches.erase(t);
1145 								}
1146 							}
1147 						}
1148 
1149 						float db = Math::linear2db(MAX(blend, 0.00001));
1150 						if (t->object->has_method("set_unit_db")) {
1151 							t->object->call("set_unit_db", db);
1152 						} else {
1153 							t->object->call("set_volume_db", db);
1154 						}
1155 					} break;
1156 					case Animation::TYPE_ANIMATION: {
1157 
1158 						TrackCacheAnimation *t = static_cast<TrackCacheAnimation *>(track);
1159 
1160 						AnimationPlayer *player2 = Object::cast_to<AnimationPlayer>(t->object);
1161 
1162 						if (!player2)
1163 							continue;
1164 
1165 						if (delta == 0 || seeked) {
1166 							//seek
1167 							int idx = a->track_find_key(i, time);
1168 							if (idx < 0)
1169 								continue;
1170 
1171 							float pos = a->track_get_key_time(i, idx);
1172 
1173 							StringName anim_name = a->animation_track_get_key_animation(i, idx);
1174 							if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name))
1175 								continue;
1176 
1177 							Ref<Animation> anim = player2->get_animation(anim_name);
1178 
1179 							float at_anim_pos;
1180 
1181 							if (anim->has_loop()) {
1182 								at_anim_pos = Math::fposmod(time - pos, anim->get_length()); //seek to loop
1183 							} else {
1184 								at_anim_pos = MAX(anim->get_length(), time - pos); //seek to end
1185 							}
1186 
1187 							if (player2->is_playing() || seeked) {
1188 								player2->play(anim_name);
1189 								player2->seek(at_anim_pos);
1190 								t->playing = true;
1191 								playing_caches.insert(t);
1192 							} else {
1193 								player2->set_assigned_animation(anim_name);
1194 								player2->seek(at_anim_pos, true);
1195 							}
1196 						} else {
1197 							//find stuff to play
1198 							List<int> to_play;
1199 							a->track_get_key_indices_in_range(i, time, delta, &to_play);
1200 							if (to_play.size()) {
1201 								int idx = to_play.back()->get();
1202 
1203 								StringName anim_name = a->animation_track_get_key_animation(i, idx);
1204 								if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) {
1205 
1206 									if (playing_caches.has(t)) {
1207 										playing_caches.erase(t);
1208 										player2->stop();
1209 										t->playing = false;
1210 									}
1211 								} else {
1212 									player2->play(anim_name);
1213 									t->playing = true;
1214 									playing_caches.insert(t);
1215 								}
1216 							}
1217 						}
1218 
1219 					} break;
1220 				}
1221 			}
1222 		}
1223 	}
1224 
1225 	{
1226 		// finally, set the tracks
1227 		const NodePath *K = NULL;
1228 		while ((K = track_cache.next(K))) {
1229 			TrackCache *track = track_cache[*K];
1230 			if (track->process_pass != process_pass)
1231 				continue; //not processed, ignore
1232 
1233 			switch (track->type) {
1234 
1235 				case Animation::TYPE_TRANSFORM: {
1236 
1237 					TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
1238 
1239 					Transform xform;
1240 					xform.origin = t->loc;
1241 
1242 					xform.basis.set_quat_scale(t->rot, t->scale);
1243 
1244 					if (t->root_motion) {
1245 
1246 						root_motion_transform = xform;
1247 
1248 						if (t->skeleton && t->bone_idx >= 0) {
1249 							root_motion_transform = (t->skeleton->get_bone_rest(t->bone_idx) * root_motion_transform) * t->skeleton->get_bone_rest(t->bone_idx).affine_inverse();
1250 						}
1251 					} else if (t->skeleton && t->bone_idx >= 0) {
1252 
1253 						t->skeleton->set_bone_pose(t->bone_idx, xform);
1254 
1255 					} else {
1256 
1257 						t->spatial->set_transform(xform);
1258 					}
1259 
1260 				} break;
1261 				case Animation::TYPE_VALUE: {
1262 
1263 					TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
1264 
1265 					t->object->set_indexed(t->subpath, t->value);
1266 
1267 				} break;
1268 				case Animation::TYPE_BEZIER: {
1269 
1270 					TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
1271 
1272 					t->object->set_indexed(t->subpath, t->value);
1273 
1274 				} break;
1275 				default: {
1276 				} //the rest don't matter
1277 			}
1278 		}
1279 	}
1280 }
1281 
advance(float p_time)1282 void AnimationTree::advance(float p_time) {
1283 
1284 	_process_graph(p_time);
1285 }
1286 
_notification(int p_what)1287 void AnimationTree::_notification(int p_what) {
1288 
1289 	if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) {
1290 		_process_graph(get_physics_process_delta_time());
1291 	}
1292 
1293 	if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_mode == ANIMATION_PROCESS_IDLE) {
1294 		_process_graph(get_process_delta_time());
1295 	}
1296 
1297 	if (p_what == NOTIFICATION_EXIT_TREE) {
1298 		_clear_caches();
1299 		if (last_animation_player) {
1300 
1301 			Object *player = ObjectDB::get_instance(last_animation_player);
1302 			if (player) {
1303 				player->disconnect("caches_cleared", this, "_clear_caches");
1304 			}
1305 		}
1306 	} else if (p_what == NOTIFICATION_ENTER_TREE) {
1307 		if (last_animation_player) {
1308 
1309 			Object *player = ObjectDB::get_instance(last_animation_player);
1310 			if (player) {
1311 				player->connect("caches_cleared", this, "_clear_caches");
1312 			}
1313 		}
1314 	}
1315 }
1316 
set_animation_player(const NodePath & p_player)1317 void AnimationTree::set_animation_player(const NodePath &p_player) {
1318 	animation_player = p_player;
1319 	update_configuration_warning();
1320 }
1321 
get_animation_player() const1322 NodePath AnimationTree::get_animation_player() const {
1323 	return animation_player;
1324 }
1325 
is_state_invalid() const1326 bool AnimationTree::is_state_invalid() const {
1327 
1328 	return !state.valid;
1329 }
get_invalid_state_reason() const1330 String AnimationTree::get_invalid_state_reason() const {
1331 
1332 	return state.invalid_reasons;
1333 }
1334 
get_last_process_pass() const1335 uint64_t AnimationTree::get_last_process_pass() const {
1336 	return process_pass;
1337 }
1338 
get_configuration_warning() const1339 String AnimationTree::get_configuration_warning() const {
1340 
1341 	String warning = Node::get_configuration_warning();
1342 
1343 	if (!root.is_valid()) {
1344 		if (warning != String()) {
1345 			warning += "\n\n";
1346 		}
1347 		warning += TTR("No root AnimationNode for the graph is set.");
1348 	}
1349 
1350 	if (!has_node(animation_player)) {
1351 
1352 		if (warning != String()) {
1353 			warning += "\n\n";
1354 		}
1355 
1356 		warning += TTR("Path to an AnimationPlayer node containing animations is not set.");
1357 		return warning;
1358 	}
1359 
1360 	AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
1361 
1362 	if (!player) {
1363 		if (warning != String()) {
1364 			warning += "\n\n";
1365 		}
1366 
1367 		warning += TTR("Path set for AnimationPlayer does not lead to an AnimationPlayer node.");
1368 		return warning;
1369 	}
1370 
1371 	if (!player->has_node(player->get_root())) {
1372 		if (warning != String()) {
1373 			warning += "\n\n";
1374 		}
1375 
1376 		warning += TTR("The AnimationPlayer root node is not a valid node.");
1377 		return warning;
1378 	}
1379 
1380 	return warning;
1381 }
1382 
set_root_motion_track(const NodePath & p_track)1383 void AnimationTree::set_root_motion_track(const NodePath &p_track) {
1384 	root_motion_track = p_track;
1385 }
1386 
get_root_motion_track() const1387 NodePath AnimationTree::get_root_motion_track() const {
1388 	return root_motion_track;
1389 }
1390 
get_root_motion_transform() const1391 Transform AnimationTree::get_root_motion_transform() const {
1392 	return root_motion_transform;
1393 }
1394 
_tree_changed()1395 void AnimationTree::_tree_changed() {
1396 	if (properties_dirty) {
1397 		return;
1398 	}
1399 
1400 	call_deferred("_update_properties");
1401 	properties_dirty = true;
1402 }
1403 
_update_properties_for_node(const String & p_base_path,Ref<AnimationNode> node)1404 void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node) {
1405 
1406 	if (!property_parent_map.has(p_base_path)) {
1407 		property_parent_map[p_base_path] = HashMap<StringName, StringName>();
1408 	}
1409 
1410 	if (node->get_input_count() && !input_activity_map.has(p_base_path)) {
1411 
1412 		Vector<Activity> activity;
1413 		for (int i = 0; i < node->get_input_count(); i++) {
1414 			Activity a;
1415 			a.activity = 0;
1416 			a.last_pass = 0;
1417 			activity.push_back(a);
1418 		}
1419 		input_activity_map[p_base_path] = activity;
1420 		input_activity_map_get[String(p_base_path).substr(0, String(p_base_path).length() - 1)] = &input_activity_map[p_base_path];
1421 	}
1422 
1423 	List<PropertyInfo> plist;
1424 	node->get_parameter_list(&plist);
1425 	for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
1426 		PropertyInfo pinfo = E->get();
1427 
1428 		StringName key = pinfo.name;
1429 
1430 		if (!property_map.has(p_base_path + key)) {
1431 			property_map[p_base_path + key] = node->get_parameter_default_value(key);
1432 		}
1433 
1434 		property_parent_map[p_base_path][key] = p_base_path + key;
1435 
1436 		pinfo.name = p_base_path + key;
1437 		properties.push_back(pinfo);
1438 	}
1439 
1440 	List<AnimationNode::ChildNode> children;
1441 	node->get_child_nodes(&children);
1442 
1443 	for (List<AnimationNode::ChildNode>::Element *E = children.front(); E; E = E->next()) {
1444 		_update_properties_for_node(p_base_path + E->get().name + "/", E->get().node);
1445 	}
1446 }
1447 
_update_properties()1448 void AnimationTree::_update_properties() {
1449 	if (!properties_dirty) {
1450 		return;
1451 	}
1452 
1453 	properties.clear();
1454 	property_parent_map.clear();
1455 	input_activity_map.clear();
1456 	input_activity_map_get.clear();
1457 
1458 	if (root.is_valid()) {
1459 		_update_properties_for_node(SceneStringNames::get_singleton()->parameters_base_path, root);
1460 	}
1461 
1462 	properties_dirty = false;
1463 
1464 	_change_notify();
1465 }
1466 
_set(const StringName & p_name,const Variant & p_value)1467 bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) {
1468 	if (properties_dirty) {
1469 		_update_properties();
1470 	}
1471 
1472 	if (property_map.has(p_name)) {
1473 		property_map[p_name] = p_value;
1474 #ifdef TOOLS_ENABLED
1475 		_change_notify(p_name.operator String().utf8().get_data());
1476 #endif
1477 		return true;
1478 	}
1479 
1480 	return false;
1481 }
1482 
_get(const StringName & p_name,Variant & r_ret) const1483 bool AnimationTree::_get(const StringName &p_name, Variant &r_ret) const {
1484 	if (properties_dirty) {
1485 		const_cast<AnimationTree *>(this)->_update_properties();
1486 	}
1487 
1488 	if (property_map.has(p_name)) {
1489 		r_ret = property_map[p_name];
1490 		return true;
1491 	}
1492 
1493 	return false;
1494 }
_get_property_list(List<PropertyInfo> * p_list) const1495 void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const {
1496 	if (properties_dirty) {
1497 		const_cast<AnimationTree *>(this)->_update_properties();
1498 	}
1499 
1500 	for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
1501 		p_list->push_back(E->get());
1502 	}
1503 }
1504 
rename_parameter(const String & p_base,const String & p_new_base)1505 void AnimationTree::rename_parameter(const String &p_base, const String &p_new_base) {
1506 
1507 	//rename values first
1508 	for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
1509 		if (E->get().name.begins_with(p_base)) {
1510 			String new_name = E->get().name.replace_first(p_base, p_new_base);
1511 			property_map[new_name] = property_map[E->get().name];
1512 		}
1513 	}
1514 
1515 	//update tree second
1516 	properties_dirty = true;
1517 	_update_properties();
1518 }
1519 
get_connection_activity(const StringName & p_path,int p_connection) const1520 float AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const {
1521 
1522 	if (!input_activity_map_get.has(p_path)) {
1523 		return 0;
1524 	}
1525 	const Vector<Activity> *activity = input_activity_map_get[p_path];
1526 
1527 	if (!activity || p_connection < 0 || p_connection >= activity->size()) {
1528 		return 0;
1529 	}
1530 
1531 	if ((*activity)[p_connection].last_pass != process_pass) {
1532 		return 0;
1533 	}
1534 
1535 	return (*activity)[p_connection].activity;
1536 }
1537 
_bind_methods()1538 void AnimationTree::_bind_methods() {
1539 	ClassDB::bind_method(D_METHOD("set_active", "active"), &AnimationTree::set_active);
1540 	ClassDB::bind_method(D_METHOD("is_active"), &AnimationTree::is_active);
1541 
1542 	ClassDB::bind_method(D_METHOD("set_tree_root", "root"), &AnimationTree::set_tree_root);
1543 	ClassDB::bind_method(D_METHOD("get_tree_root"), &AnimationTree::get_tree_root);
1544 
1545 	ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &AnimationTree::set_process_mode);
1546 	ClassDB::bind_method(D_METHOD("get_process_mode"), &AnimationTree::get_process_mode);
1547 
1548 	ClassDB::bind_method(D_METHOD("set_animation_player", "root"), &AnimationTree::set_animation_player);
1549 	ClassDB::bind_method(D_METHOD("get_animation_player"), &AnimationTree::get_animation_player);
1550 
1551 	ClassDB::bind_method(D_METHOD("set_root_motion_track", "path"), &AnimationTree::set_root_motion_track);
1552 	ClassDB::bind_method(D_METHOD("get_root_motion_track"), &AnimationTree::get_root_motion_track);
1553 
1554 	ClassDB::bind_method(D_METHOD("get_root_motion_transform"), &AnimationTree::get_root_motion_transform);
1555 
1556 	ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationTree::_tree_changed);
1557 	ClassDB::bind_method(D_METHOD("_update_properties"), &AnimationTree::_update_properties);
1558 
1559 	ClassDB::bind_method(D_METHOD("rename_parameter", "old_name", "new_name"), &AnimationTree::rename_parameter);
1560 
1561 	ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTree::advance);
1562 
1563 	ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationTree::_node_removed);
1564 	ClassDB::bind_method(D_METHOD("_clear_caches"), &AnimationTree::_clear_caches);
1565 
1566 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root");
1567 	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player");
1568 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
1569 	ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_mode", "get_process_mode");
1570 	ADD_GROUP("Root Motion", "root_motion_");
1571 	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_motion_track"), "set_root_motion_track", "get_root_motion_track");
1572 
1573 	BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS);
1574 	BIND_ENUM_CONSTANT(ANIMATION_PROCESS_IDLE);
1575 	BIND_ENUM_CONSTANT(ANIMATION_PROCESS_MANUAL);
1576 }
1577 
AnimationTree()1578 AnimationTree::AnimationTree() {
1579 
1580 	process_mode = ANIMATION_PROCESS_IDLE;
1581 	active = false;
1582 	cache_valid = false;
1583 	setup_pass = 1;
1584 	process_pass = 1;
1585 	started = true;
1586 	properties_dirty = true;
1587 	last_animation_player = 0;
1588 }
1589 
~AnimationTree()1590 AnimationTree::~AnimationTree() {
1591 }
1592