1/**************************************************************************/
2/* animation_tree.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 "animation_tree.h"
32
33#include "animation_blend_tree.h"
34#include "core/config/engine.h"
35#include "scene/resources/animation.h"
36#include "scene/scene_string_names.h"
37#include "servers/audio/audio_stream.h"
38
39void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
40 Array parameters;
41
42 if (GDVIRTUAL_CALL(_get_parameter_list, parameters)) {
43 for (int i = 0; i < parameters.size(); i++) {
44 Dictionary d = parameters[i];
45 ERR_CONTINUE(d.is_empty());
46 r_list->push_back(PropertyInfo::from_dict(d));
47 }
48 }
49}
50
51Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter) const {
52 Variant ret;
53 GDVIRTUAL_CALL(_get_parameter_default_value, p_parameter, ret);
54 return ret;
55}
56
57bool AnimationNode::is_parameter_read_only(const StringName &p_parameter) const {
58 bool ret = false;
59 GDVIRTUAL_CALL(_is_parameter_read_only, p_parameter, ret);
60 return ret;
61}
62
63void AnimationNode::set_parameter(const StringName &p_name, const Variant &p_value) {
64 if (is_testing) {
65 return;
66 }
67 ERR_FAIL_NULL(state);
68 ERR_FAIL_COND(!state->tree->property_parent_map.has(base_path));
69 ERR_FAIL_COND(!state->tree->property_parent_map[base_path].has(p_name));
70 StringName path = state->tree->property_parent_map[base_path][p_name];
71
72 state->tree->property_map[path].first = p_value;
73}
74
75Variant AnimationNode::get_parameter(const StringName &p_name) const {
76 ERR_FAIL_NULL_V(state, Variant());
77 ERR_FAIL_COND_V(!state->tree->property_parent_map.has(base_path), Variant());
78 ERR_FAIL_COND_V(!state->tree->property_parent_map[base_path].has(p_name), Variant());
79
80 StringName path = state->tree->property_parent_map[base_path][p_name];
81 return state->tree->property_map[path].first;
82}
83
84void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
85 Dictionary cn;
86 if (GDVIRTUAL_CALL(_get_child_nodes, cn)) {
87 List<Variant> keys;
88 cn.get_key_list(&keys);
89 for (const Variant &E : keys) {
90 ChildNode child;
91 child.name = E;
92 child.node = cn[E];
93 r_child_nodes->push_back(child);
94 }
95 }
96}
97
98void AnimationNode::blend_animation(const StringName &p_animation, double p_time, double p_delta, bool p_seeked, bool p_is_external_seeking, real_t p_blend, Animation::LoopedFlag p_looped_flag) {
99 ERR_FAIL_NULL(state);
100 ERR_FAIL_COND(!state->player->has_animation(p_animation));
101
102 Ref<Animation> animation = state->player->get_animation(p_animation);
103
104 if (animation.is_null()) {
105 AnimationNodeBlendTree *btree = Object::cast_to<AnimationNodeBlendTree>(parent);
106 if (btree) {
107 String node_name = btree->get_node_name(Ref<AnimationNodeAnimation>(this));
108 make_invalid(vformat(RTR("In node '%s', invalid animation: '%s'."), node_name, p_animation));
109 } else {
110 make_invalid(vformat(RTR("Invalid animation: '%s'."), p_animation));
111 }
112 return;
113 }
114
115 ERR_FAIL_COND(!animation.is_valid());
116
117 AnimationState anim_state;
118 anim_state.blend = p_blend;
119 anim_state.track_blends = blends;
120 anim_state.delta = p_delta;
121 anim_state.time = p_time;
122 anim_state.animation = animation;
123 anim_state.seeked = p_seeked;
124 anim_state.looped_flag = p_looped_flag;
125 anim_state.is_external_seeking = p_is_external_seeking;
126
127 state->animation_states.push_back(anim_state);
128}
129
130double AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, double p_time, bool p_seek, bool p_is_external_seeking, const Vector<StringName> &p_connections, bool p_test_only) {
131 base_path = p_base_path;
132 parent = p_parent;
133 connections = p_connections;
134 state = p_state;
135
136 double t = process(p_time, p_seek, p_is_external_seeking, p_test_only);
137
138 state = nullptr;
139 parent = nullptr;
140 base_path = StringName();
141 connections.clear();
142
143 return t;
144}
145
146AnimationTree *AnimationNode::get_animation_tree() const {
147 ERR_FAIL_NULL_V(state, nullptr);
148 return state->tree;
149}
150
151void AnimationNode::make_invalid(const String &p_reason) {
152 ERR_FAIL_NULL(state);
153 state->valid = false;
154 if (!state->invalid_reasons.is_empty()) {
155 state->invalid_reasons += "\n";
156 }
157 state->invalid_reasons += String::utf8("• ") + p_reason;
158}
159
160double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter, bool p_sync, bool p_test_only) {
161 ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
162 ERR_FAIL_NULL_V(state, 0);
163
164 AnimationNodeBlendTree *blend_tree = Object::cast_to<AnimationNodeBlendTree>(parent);
165 ERR_FAIL_NULL_V(blend_tree, 0);
166
167 StringName node_name = connections[p_input];
168
169 if (!blend_tree->has_node(node_name)) {
170 String node_name2 = blend_tree->get_node_name(Ref<AnimationNode>(this));
171 make_invalid(vformat(RTR("Nothing connected to input '%s' of node '%s'."), get_input_name(p_input), node_name2));
172 return 0;
173 }
174
175 Ref<AnimationNode> node = blend_tree->get_node(node_name);
176
177 //inputs.write[p_input].last_pass = state->last_pass;
178 real_t activity = 0.0;
179 double ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_is_external_seeking, p_blend, p_filter, p_sync, &activity, p_test_only);
180
181 Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
182
183 if (activity_ptr && p_input < activity_ptr->size()) {
184 activity_ptr->write[p_input].last_pass = state->last_pass;
185 activity_ptr->write[p_input].activity = activity;
186 }
187 return ret;
188}
189
190double AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter, bool p_sync, bool p_test_only) {
191 return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_is_external_seeking, p_blend, p_filter, p_sync, nullptr, p_test_only);
192}
193
194double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter, bool p_sync, real_t *r_max, bool p_test_only) {
195 ERR_FAIL_COND_V(!p_node.is_valid(), 0);
196 ERR_FAIL_NULL_V(state, 0);
197
198 int blend_count = blends.size();
199
200 if (p_node->blends.size() != blend_count) {
201 p_node->blends.resize(blend_count);
202 }
203
204 real_t *blendw = p_node->blends.ptrw();
205 const real_t *blendr = blends.ptr();
206
207 bool any_valid = false;
208
209 if (has_filter() && is_filter_enabled() && p_filter != FILTER_IGNORE) {
210 for (int i = 0; i < blend_count; i++) {
211 blendw[i] = 0.0; //all to zero by default
212 }
213
214 for (const KeyValue<NodePath, bool> &E : filter) {
215 if (!state->track_map.has(E.key)) {
216 continue;
217 }
218 int idx = state->track_map[E.key];
219 blendw[idx] = 1.0; //filtered goes to one
220 }
221
222 switch (p_filter) {
223 case FILTER_IGNORE:
224 break; //will not happen anyway
225 case FILTER_PASS: {
226 //values filtered pass, the rest don't
227 for (int i = 0; i < blend_count; i++) {
228 if (blendw[i] == 0) { //not filtered, does not pass
229 continue;
230 }
231
232 blendw[i] = blendr[i] * p_blend;
233 if (!Math::is_zero_approx(blendw[i])) {
234 any_valid = true;
235 }
236 }
237
238 } break;
239 case FILTER_STOP: {
240 //values filtered don't pass, the rest are blended
241
242 for (int i = 0; i < blend_count; i++) {
243 if (blendw[i] > 0) { //filtered, does not pass
244 continue;
245 }
246
247 blendw[i] = blendr[i] * p_blend;
248 if (!Math::is_zero_approx(blendw[i])) {
249 any_valid = true;
250 }
251 }
252
253 } break;
254 case FILTER_BLEND: {
255 //filtered values are blended, the rest are passed without blending
256
257 for (int i = 0; i < blend_count; i++) {
258 if (blendw[i] == 1.0) {
259 blendw[i] = blendr[i] * p_blend; //filtered, blend
260 } else {
261 blendw[i] = blendr[i]; //not filtered, do not blend
262 }
263
264 if (!Math::is_zero_approx(blendw[i])) {
265 any_valid = true;
266 }
267 }
268
269 } break;
270 }
271 } else {
272 for (int i = 0; i < blend_count; i++) {
273 //regular blend
274 blendw[i] = blendr[i] * p_blend;
275 if (!Math::is_zero_approx(blendw[i])) {
276 any_valid = true;
277 }
278 }
279 }
280
281 if (r_max) {
282 *r_max = 0;
283 for (int i = 0; i < blend_count; i++) {
284 *r_max = MAX(*r_max, Math::abs(blendw[i]));
285 }
286 }
287
288 String new_path;
289 AnimationNode *new_parent;
290
291 // 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.
292 if (p_new_parent) {
293 new_parent = p_new_parent;
294 new_path = String(base_path) + String(p_subpath) + "/";
295 } else {
296 ERR_FAIL_NULL_V(parent, 0);
297 new_parent = parent;
298 new_path = String(parent->base_path) + String(p_subpath) + "/";
299 }
300
301 // This process, which depends on p_sync is needed to process sync correctly in the case of
302 // that a synced AnimationNodeSync exists under the un-synced AnimationNodeSync.
303 if (!p_seek && !p_sync && !any_valid) {
304 return p_node->_pre_process(new_path, new_parent, state, 0, p_seek, p_is_external_seeking, p_connections, p_test_only);
305 }
306 return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_is_external_seeking, p_connections, p_test_only);
307}
308
309String AnimationNode::get_caption() const {
310 String ret = "Node";
311 GDVIRTUAL_CALL(_get_caption, ret);
312 return ret;
313}
314
315bool AnimationNode::add_input(const String &p_name) {
316 //root nodes can't add inputs
317 ERR_FAIL_COND_V(Object::cast_to<AnimationRootNode>(this) != nullptr, false);
318 Input input;
319 ERR_FAIL_COND_V(p_name.contains(".") || p_name.contains("/"), false);
320 input.name = p_name;
321 inputs.push_back(input);
322 emit_changed();
323 return true;
324}
325
326void AnimationNode::remove_input(int p_index) {
327 ERR_FAIL_INDEX(p_index, inputs.size());
328 inputs.remove_at(p_index);
329 emit_changed();
330}
331
332bool AnimationNode::set_input_name(int p_input, const String &p_name) {
333 ERR_FAIL_INDEX_V(p_input, inputs.size(), false);
334 ERR_FAIL_COND_V(p_name.contains(".") || p_name.contains("/"), false);
335 inputs.write[p_input].name = p_name;
336 emit_changed();
337 return true;
338}
339
340String AnimationNode::get_input_name(int p_input) const {
341 ERR_FAIL_INDEX_V(p_input, inputs.size(), String());
342 return inputs[p_input].name;
343}
344
345int AnimationNode::get_input_count() const {
346 return inputs.size();
347}
348
349int AnimationNode::find_input(const String &p_name) const {
350 int idx = -1;
351 for (int i = 0; i < inputs.size(); i++) {
352 if (inputs[i].name == p_name) {
353 idx = i;
354 break;
355 }
356 }
357 return idx;
358}
359
360double AnimationNode::process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
361 is_testing = p_test_only;
362 return _process(p_time, p_seek, p_is_external_seeking, p_test_only);
363}
364
365double AnimationNode::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
366 double ret = 0;
367 GDVIRTUAL_CALL(_process, p_time, p_seek, p_is_external_seeking, p_test_only, ret);
368 return ret;
369}
370
371void AnimationNode::set_filter_path(const NodePath &p_path, bool p_enable) {
372 if (p_enable) {
373 filter[p_path] = true;
374 } else {
375 filter.erase(p_path);
376 }
377}
378
379void AnimationNode::set_filter_enabled(bool p_enable) {
380 filter_enabled = p_enable;
381}
382
383bool AnimationNode::is_filter_enabled() const {
384 return filter_enabled;
385}
386
387void AnimationNode::set_closable(bool p_closable) {
388 closable = p_closable;
389}
390
391bool AnimationNode::is_closable() const {
392 return closable;
393}
394
395bool AnimationNode::is_path_filtered(const NodePath &p_path) const {
396 return filter.has(p_path);
397}
398
399bool AnimationNode::has_filter() const {
400 bool ret = false;
401 GDVIRTUAL_CALL(_has_filter, ret);
402 return ret;
403}
404
405Array AnimationNode::_get_filters() const {
406 Array paths;
407
408 for (const KeyValue<NodePath, bool> &E : filter) {
409 paths.push_back(String(E.key)); //use strings, so sorting is possible
410 }
411 paths.sort(); //done so every time the scene is saved, it does not change
412
413 return paths;
414}
415
416void AnimationNode::_set_filters(const Array &p_filters) {
417 filter.clear();
418 for (int i = 0; i < p_filters.size(); i++) {
419 set_filter_path(p_filters[i], true);
420 }
421}
422
423void AnimationNode::_validate_property(PropertyInfo &p_property) const {
424 if (!has_filter() && (p_property.name == "filter_enabled" || p_property.name == "filters")) {
425 p_property.usage = PROPERTY_USAGE_NONE;
426 }
427}
428
429Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) const {
430 Ref<AnimationNode> ret;
431 GDVIRTUAL_CALL(_get_child_by_name, p_name, ret);
432 return ret;
433}
434
435Ref<AnimationNode> AnimationNode::find_node_by_path(const String &p_name) const {
436 Vector<String> split = p_name.split("/");
437 Ref<AnimationNode> ret = const_cast<AnimationNode *>(this);
438 for (int i = 0; i < split.size(); i++) {
439 ret = ret->get_child_by_name(split[i]);
440 if (!ret.is_valid()) {
441 break;
442 }
443 }
444 return ret;
445}
446
447void AnimationNode::_bind_methods() {
448 ClassDB::bind_method(D_METHOD("add_input", "name"), &AnimationNode::add_input);
449 ClassDB::bind_method(D_METHOD("remove_input", "index"), &AnimationNode::remove_input);
450 ClassDB::bind_method(D_METHOD("set_input_name", "input", "name"), &AnimationNode::set_input_name);
451 ClassDB::bind_method(D_METHOD("get_input_name", "input"), &AnimationNode::get_input_name);
452 ClassDB::bind_method(D_METHOD("get_input_count"), &AnimationNode::get_input_count);
453 ClassDB::bind_method(D_METHOD("find_input", "name"), &AnimationNode::find_input);
454
455 ClassDB::bind_method(D_METHOD("set_filter_path", "path", "enable"), &AnimationNode::set_filter_path);
456 ClassDB::bind_method(D_METHOD("is_path_filtered", "path"), &AnimationNode::is_path_filtered);
457
458 ClassDB::bind_method(D_METHOD("set_filter_enabled", "enable"), &AnimationNode::set_filter_enabled);
459 ClassDB::bind_method(D_METHOD("is_filter_enabled"), &AnimationNode::is_filter_enabled);
460
461 ClassDB::bind_method(D_METHOD("_set_filters", "filters"), &AnimationNode::_set_filters);
462 ClassDB::bind_method(D_METHOD("_get_filters"), &AnimationNode::_get_filters);
463
464 ClassDB::bind_method(D_METHOD("blend_animation", "animation", "time", "delta", "seeked", "is_external_seeking", "blend", "looped_flag"), &AnimationNode::blend_animation, DEFVAL(Animation::LOOPED_FLAG_NONE));
465 ClassDB::bind_method(D_METHOD("blend_node", "name", "node", "time", "seek", "is_external_seeking", "blend", "filter", "sync", "test_only"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true), DEFVAL(false));
466 ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "is_external_seeking", "blend", "filter", "sync", "test_only"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true), DEFVAL(false));
467
468 ClassDB::bind_method(D_METHOD("set_parameter", "name", "value"), &AnimationNode::set_parameter);
469 ClassDB::bind_method(D_METHOD("get_parameter", "name"), &AnimationNode::get_parameter);
470
471 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_filter_enabled", "is_filter_enabled");
472 ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "filters", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_filters", "_get_filters");
473
474 GDVIRTUAL_BIND(_get_child_nodes);
475 GDVIRTUAL_BIND(_get_parameter_list);
476 GDVIRTUAL_BIND(_get_child_by_name, "name");
477 GDVIRTUAL_BIND(_get_parameter_default_value, "parameter");
478 GDVIRTUAL_BIND(_is_parameter_read_only, "parameter");
479 GDVIRTUAL_BIND(_process, "time", "seek", "is_external_seeking", "test_only");
480 GDVIRTUAL_BIND(_get_caption);
481 GDVIRTUAL_BIND(_has_filter);
482
483 ADD_SIGNAL(MethodInfo("tree_changed"));
484 ADD_SIGNAL(MethodInfo("animation_node_renamed", PropertyInfo(Variant::INT, "object_id"), PropertyInfo(Variant::STRING, "old_name"), PropertyInfo(Variant::STRING, "new_name")));
485 ADD_SIGNAL(MethodInfo("animation_node_removed", PropertyInfo(Variant::INT, "object_id"), PropertyInfo(Variant::STRING, "name")));
486
487 BIND_ENUM_CONSTANT(FILTER_IGNORE);
488 BIND_ENUM_CONSTANT(FILTER_PASS);
489 BIND_ENUM_CONSTANT(FILTER_STOP);
490 BIND_ENUM_CONSTANT(FILTER_BLEND);
491}
492
493AnimationNode::AnimationNode() {
494}
495
496////////////////////
497
498void AnimationRootNode::_tree_changed() {
499 emit_signal(SNAME("tree_changed"));
500}
501
502void AnimationRootNode::_animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) {
503 emit_signal(SNAME("animation_node_renamed"), p_oid, p_old_name, p_new_name);
504}
505
506void AnimationRootNode::_animation_node_removed(const ObjectID &p_oid, const StringName &p_node) {
507 emit_signal(SNAME("animation_node_removed"), p_oid, p_node);
508}
509
510////////////////////
511
512void AnimationTree::set_tree_root(const Ref<AnimationNode> &p_root) {
513 if (root.is_valid()) {
514 root->disconnect("tree_changed", callable_mp(this, &AnimationTree::_tree_changed));
515 root->disconnect("animation_node_renamed", callable_mp(this, &AnimationTree::_animation_node_renamed));
516 root->disconnect("animation_node_removed", callable_mp(this, &AnimationTree::_animation_node_removed));
517 }
518
519 root = p_root;
520
521 if (root.is_valid()) {
522 root->connect("tree_changed", callable_mp(this, &AnimationTree::_tree_changed));
523 root->connect("animation_node_renamed", callable_mp(this, &AnimationTree::_animation_node_renamed));
524 root->connect("animation_node_removed", callable_mp(this, &AnimationTree::_animation_node_removed));
525 }
526
527 properties_dirty = true;
528
529 update_configuration_warnings();
530}
531
532Ref<AnimationNode> AnimationTree::get_tree_root() const {
533 return root;
534}
535
536void AnimationTree::set_active(bool p_active) {
537 if (active == p_active) {
538 return;
539 }
540
541 active = p_active;
542 started = active;
543
544 if (process_callback == ANIMATION_PROCESS_IDLE) {
545 set_process_internal(active);
546 } else {
547 set_physics_process_internal(active);
548 }
549
550 if (!active && is_inside_tree()) {
551 _clear_caches();
552 }
553}
554
555bool AnimationTree::is_active() const {
556 return active;
557}
558
559void AnimationTree::set_process_callback(AnimationProcessCallback p_mode) {
560 if (process_callback == p_mode) {
561 return;
562 }
563
564 bool was_active = is_active();
565 if (was_active) {
566 set_active(false);
567 }
568
569 process_callback = p_mode;
570
571 if (was_active) {
572 set_active(true);
573 }
574}
575
576AnimationTree::AnimationProcessCallback AnimationTree::get_process_callback() const {
577 return process_callback;
578}
579
580void AnimationTree::_node_removed(Node *p_node) {
581 cache_valid = false;
582}
583
584bool AnimationTree::_update_caches(AnimationPlayer *player) {
585 setup_pass++;
586
587 if (!player->has_node(player->get_root())) {
588 ERR_PRINT("AnimationTree: AnimationPlayer root is invalid.");
589 set_active(false);
590 _clear_caches();
591 return false;
592 }
593 Node *parent = player->get_node(player->get_root());
594
595 List<StringName> sname;
596 player->get_animation_list(&sname);
597
598 root_motion_cache.loc = Vector3(0, 0, 0);
599 root_motion_cache.rot = Quaternion(0, 0, 0, 1);
600 root_motion_cache.scale = Vector3(1, 1, 1);
601
602 Ref<Animation> reset_anim;
603 bool has_reset_anim = player->has_animation(SceneStringNames::get_singleton()->RESET);
604 if (has_reset_anim) {
605 reset_anim = player->get_animation(SceneStringNames::get_singleton()->RESET);
606 }
607 for (const StringName &E : sname) {
608 Ref<Animation> anim = player->get_animation(E);
609 for (int i = 0; i < anim->get_track_count(); i++) {
610 NodePath path = anim->track_get_path(i);
611 Animation::TrackType track_type = anim->track_get_type(i);
612
613 Animation::TrackType track_cache_type = track_type;
614 if (track_cache_type == Animation::TYPE_POSITION_3D || track_cache_type == Animation::TYPE_ROTATION_3D || track_cache_type == Animation::TYPE_SCALE_3D) {
615 track_cache_type = Animation::TYPE_POSITION_3D; //reference them as position3D tracks, even if they modify rotation or scale
616 }
617
618 TrackCache *track = nullptr;
619 if (track_cache.has(path)) {
620 track = track_cache.get(path);
621 }
622
623 //if not valid, delete track
624 if (track && (track->type != track_cache_type || ObjectDB::get_instance(track->object_id) == nullptr)) {
625 playing_caches.erase(track);
626 memdelete(track);
627 track_cache.erase(path);
628 track = nullptr;
629 }
630
631 if (!track) {
632 Ref<Resource> resource;
633 Vector<StringName> leftover_path;
634 Node *child = parent->get_node_and_resource(path, resource, leftover_path);
635
636 if (!child) {
637 ERR_PRINT("AnimationTree: '" + String(E) + "', couldn't resolve track: '" + String(path) + "'");
638 continue;
639 }
640
641 if (!child->is_connected("tree_exited", callable_mp(this, &AnimationTree::_node_removed))) {
642 child->connect("tree_exited", callable_mp(this, &AnimationTree::_node_removed).bind(child));
643 }
644
645 switch (track_type) {
646 case Animation::TYPE_VALUE: {
647 TrackCacheValue *track_value = memnew(TrackCacheValue);
648
649 if (resource.is_valid()) {
650 track_value->object = resource.ptr();
651 } else {
652 track_value->object = child;
653 }
654
655 track_value->is_discrete = anim->value_track_get_update_mode(i) == Animation::UPDATE_DISCRETE;
656 track_value->is_using_angle = anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_LINEAR_ANGLE || anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_CUBIC_ANGLE;
657
658 track_value->subpath = leftover_path;
659 track_value->object_id = track_value->object->get_instance_id();
660
661 track = track_value;
662
663 // If a value track without a key is cached first, the initial value cannot be determined.
664 // It is a corner case, but which may cause problems with blending.
665 ERR_CONTINUE_MSG(anim->track_get_key_count(i) == 0, "AnimationTree: '" + String(E) + "', Value Track: '" + String(path) + "' must have at least one key to cache for blending.");
666 track_value->init_value = anim->track_get_key_value(i, 0);
667 track_value->init_value.zero();
668
669 // If there is a Reset Animation, it takes precedence by overwriting.
670 if (has_reset_anim) {
671 int rt = reset_anim->find_track(path, track_type);
672 if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
673 track_value->init_value = reset_anim->track_get_key_value(rt, 0);
674 }
675 }
676 } break;
677 case Animation::TYPE_POSITION_3D:
678 case Animation::TYPE_ROTATION_3D:
679 case Animation::TYPE_SCALE_3D: {
680#ifndef _3D_DISABLED
681 Node3D *node_3d = Object::cast_to<Node3D>(child);
682
683 if (!node_3d) {
684 ERR_PRINT("AnimationTree: '" + String(E) + "', transform track does not point to Node3D: '" + String(path) + "'");
685 continue;
686 }
687
688 TrackCacheTransform *track_xform = memnew(TrackCacheTransform);
689 track_xform->type = Animation::TYPE_POSITION_3D;
690
691 track_xform->node_3d = node_3d;
692 track_xform->skeleton = nullptr;
693 track_xform->bone_idx = -1;
694
695 bool has_rest = false;
696 if (path.get_subname_count() == 1 && Object::cast_to<Skeleton3D>(node_3d)) {
697 Skeleton3D *sk = Object::cast_to<Skeleton3D>(node_3d);
698 track_xform->skeleton = sk;
699 int bone_idx = sk->find_bone(path.get_subname(0));
700 if (bone_idx != -1) {
701 has_rest = true;
702 track_xform->bone_idx = bone_idx;
703 Transform3D rest = sk->get_bone_rest(bone_idx);
704 track_xform->init_loc = rest.origin;
705 track_xform->init_rot = rest.basis.get_rotation_quaternion();
706 track_xform->init_scale = rest.basis.get_scale();
707 }
708 }
709
710 track_xform->object = node_3d;
711 track_xform->object_id = track_xform->object->get_instance_id();
712
713 track = track_xform;
714
715 switch (track_type) {
716 case Animation::TYPE_POSITION_3D: {
717 track_xform->loc_used = true;
718 } break;
719 case Animation::TYPE_ROTATION_3D: {
720 track_xform->rot_used = true;
721 } break;
722 case Animation::TYPE_SCALE_3D: {
723 track_xform->scale_used = true;
724 } break;
725 default: {
726 }
727 }
728
729 // For non Skeleton3D bone animation.
730 if (has_reset_anim && !has_rest) {
731 int rt = reset_anim->find_track(path, track_type);
732 if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
733 switch (track_type) {
734 case Animation::TYPE_POSITION_3D: {
735 track_xform->init_loc = reset_anim->track_get_key_value(rt, 0);
736 } break;
737 case Animation::TYPE_ROTATION_3D: {
738 track_xform->init_rot = reset_anim->track_get_key_value(rt, 0);
739 } break;
740 case Animation::TYPE_SCALE_3D: {
741 track_xform->init_scale = reset_anim->track_get_key_value(rt, 0);
742 } break;
743 default: {
744 }
745 }
746 }
747 }
748#endif // _3D_DISABLED
749 } break;
750 case Animation::TYPE_BLEND_SHAPE: {
751#ifndef _3D_DISABLED
752 if (path.get_subname_count() != 1) {
753 ERR_PRINT("AnimationTree: '" + String(E) + "', blend shape track does not contain a blend shape subname: '" + String(path) + "'");
754 continue;
755 }
756 MeshInstance3D *mesh_3d = Object::cast_to<MeshInstance3D>(child);
757
758 if (!mesh_3d) {
759 ERR_PRINT("AnimationTree: '" + String(E) + "', blend shape track does not point to MeshInstance3D: '" + String(path) + "'");
760 continue;
761 }
762
763 StringName blend_shape_name = path.get_subname(0);
764 int blend_shape_idx = mesh_3d->find_blend_shape_by_name(blend_shape_name);
765 if (blend_shape_idx == -1) {
766 ERR_PRINT("AnimationTree: '" + String(E) + "', blend shape track points to a non-existing name: '" + String(blend_shape_name) + "'");
767 continue;
768 }
769
770 TrackCacheBlendShape *track_bshape = memnew(TrackCacheBlendShape);
771
772 track_bshape->mesh_3d = mesh_3d;
773 track_bshape->shape_index = blend_shape_idx;
774
775 track_bshape->object = mesh_3d;
776 track_bshape->object_id = mesh_3d->get_instance_id();
777 track = track_bshape;
778
779 if (has_reset_anim) {
780 int rt = reset_anim->find_track(path, track_type);
781 if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
782 track_bshape->init_value = reset_anim->track_get_key_value(rt, 0);
783 }
784 }
785#endif
786 } break;
787 case Animation::TYPE_METHOD: {
788 TrackCacheMethod *track_method = memnew(TrackCacheMethod);
789
790 if (resource.is_valid()) {
791 track_method->object = resource.ptr();
792 } else {
793 track_method->object = child;
794 }
795
796 track_method->object_id = track_method->object->get_instance_id();
797
798 track = track_method;
799
800 } break;
801 case Animation::TYPE_BEZIER: {
802 TrackCacheBezier *track_bezier = memnew(TrackCacheBezier);
803
804 if (resource.is_valid()) {
805 track_bezier->object = resource.ptr();
806 } else {
807 track_bezier->object = child;
808 }
809
810 track_bezier->subpath = leftover_path;
811 track_bezier->object_id = track_bezier->object->get_instance_id();
812
813 track = track_bezier;
814
815 if (has_reset_anim) {
816 int rt = reset_anim->find_track(path, track_type);
817 if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
818 track_bezier->init_value = (reset_anim->track_get_key_value(rt, 0).operator Array())[0];
819 }
820 }
821 } break;
822 case Animation::TYPE_AUDIO: {
823 TrackCacheAudio *track_audio = memnew(TrackCacheAudio);
824
825 track_audio->object = child;
826 track_audio->object_id = track_audio->object->get_instance_id();
827 track_audio->audio_stream.instantiate();
828 track_audio->audio_stream->set_polyphony(audio_max_polyphony);
829
830 track = track_audio;
831
832 } break;
833 case Animation::TYPE_ANIMATION: {
834 TrackCacheAnimation *track_animation = memnew(TrackCacheAnimation);
835
836 track_animation->object = child;
837 track_animation->object_id = track_animation->object->get_instance_id();
838
839 track = track_animation;
840
841 } break;
842 default: {
843 ERR_PRINT("Animation corrupted (invalid track type)");
844 continue;
845 }
846 }
847
848 track_cache[path] = track;
849 } else if (track_cache_type == Animation::TYPE_POSITION_3D) {
850 TrackCacheTransform *track_xform = static_cast<TrackCacheTransform *>(track);
851 if (track->setup_pass != setup_pass) {
852 track_xform->loc_used = false;
853 track_xform->rot_used = false;
854 track_xform->scale_used = false;
855 }
856 switch (track_type) {
857 case Animation::TYPE_POSITION_3D: {
858 track_xform->loc_used = true;
859 } break;
860 case Animation::TYPE_ROTATION_3D: {
861 track_xform->rot_used = true;
862 } break;
863 case Animation::TYPE_SCALE_3D: {
864 track_xform->scale_used = true;
865 } break;
866 default: {
867 }
868 }
869 } else if (track_cache_type == Animation::TYPE_VALUE) {
870 // If it has at least one angle interpolation, it also uses angle interpolation for blending.
871 TrackCacheValue *track_value = static_cast<TrackCacheValue *>(track);
872 bool was_discrete = track_value->is_discrete;
873 bool was_using_angle = track_value->is_using_angle;
874 track_value->is_discrete |= anim->value_track_get_update_mode(i) == Animation::UPDATE_DISCRETE;
875 track_value->is_using_angle |= anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_LINEAR_ANGLE || anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_CUBIC_ANGLE;
876
877 if (was_discrete != track_value->is_discrete) {
878 ERR_PRINT_ED("Value Track: " + String(path) + " with different update modes are blended. Blending prioritizes Discrete mode, so other update mode tracks will not be blended.");
879 }
880 if (was_using_angle != track_value->is_using_angle) {
881 WARN_PRINT_ED("Value Track: " + String(path) + " with different interpolation types for rotation are blended. Blending prioritizes angle interpolation, so the blending result uses the shortest path referenced to the initial (RESET animation) value.");
882 }
883 }
884
885 track->setup_pass = setup_pass;
886 }
887 }
888
889 List<NodePath> to_delete;
890
891 for (const KeyValue<NodePath, TrackCache *> &K : track_cache) {
892 TrackCache *tc = track_cache[K.key];
893 if (tc->setup_pass != setup_pass) {
894 to_delete.push_back(K.key);
895 }
896 }
897
898 while (to_delete.front()) {
899 NodePath np = to_delete.front()->get();
900 memdelete(track_cache[np]);
901 track_cache.erase(np);
902 to_delete.pop_front();
903 }
904
905 state.track_map.clear();
906
907 int idx = 0;
908 for (const KeyValue<NodePath, TrackCache *> &K : track_cache) {
909 state.track_map[K.key] = idx;
910 idx++;
911 }
912
913 state.track_count = idx;
914
915 cache_valid = true;
916
917 return true;
918}
919
920void AnimationTree::_animation_player_changed() {
921 emit_signal(SNAME("animation_player_changed"));
922 _clear_caches();
923}
924
925void AnimationTree::_clear_caches() {
926 _clear_audio_streams();
927 _clear_playing_caches();
928 for (KeyValue<NodePath, TrackCache *> &K : track_cache) {
929 memdelete(K.value);
930 }
931 track_cache.clear();
932 cache_valid = false;
933}
934
935void AnimationTree::_clear_audio_streams() {
936 for (int i = 0; i < playing_audio_stream_players.size(); i++) {
937 playing_audio_stream_players[i]->call(SNAME("stop"));
938 playing_audio_stream_players[i]->call(SNAME("set_stream"), Ref<AudioStream>());
939 }
940 playing_audio_stream_players.clear();
941}
942
943void AnimationTree::_clear_playing_caches() {
944 for (const TrackCache *E : playing_caches) {
945 if (ObjectDB::get_instance(E->object_id)) {
946 E->object->call(SNAME("stop"));
947 }
948 }
949 playing_caches.clear();
950}
951
952void AnimationTree::_call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
953 // Separate function to use alloca() more efficiently
954 const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * p_params.size());
955 const Variant *args = p_params.ptr();
956 uint32_t argcount = p_params.size();
957 for (uint32_t i = 0; i < argcount; i++) {
958 argptrs[i] = &args[i];
959 }
960 if (p_deferred) {
961 MessageQueue::get_singleton()->push_callp(p_object, p_method, argptrs, argcount);
962 } else {
963 Callable::CallError ce;
964 p_object->callp(p_method, argptrs, argcount, ce);
965 }
966}
967void AnimationTree::_process_graph(double p_delta) {
968 _update_properties(); //if properties need updating, update them
969
970 //check all tracks, see if they need modification
971 root_motion_position = Vector3(0, 0, 0);
972 root_motion_rotation = Quaternion(0, 0, 0, 1);
973 root_motion_scale = Vector3(0, 0, 0);
974
975 if (!root.is_valid()) {
976 ERR_PRINT("AnimationTree: root AnimationNode is not set, disabling playback.");
977 set_active(false);
978 cache_valid = false;
979 return;
980 }
981
982 if (!has_node(animation_player)) {
983 ERR_PRINT("AnimationTree: no valid AnimationPlayer path set, disabling playback");
984 set_active(false);
985 cache_valid = false;
986 return;
987 }
988
989 AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
990
991 ObjectID current_animation_player;
992
993 if (player) {
994 current_animation_player = player->get_instance_id();
995 }
996
997 if (last_animation_player != current_animation_player) {
998 if (last_animation_player.is_valid()) {
999 Object *old_player = ObjectDB::get_instance(last_animation_player);
1000 if (old_player) {
1001 old_player->disconnect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches));
1002 }
1003 }
1004
1005 if (player) {
1006 player->connect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches));
1007 }
1008
1009 last_animation_player = current_animation_player;
1010 }
1011
1012 if (!player) {
1013 ERR_PRINT("AnimationTree: path points to a node not an AnimationPlayer, disabling playback");
1014 set_active(false);
1015 cache_valid = false;
1016 return;
1017 }
1018
1019 if (!cache_valid) {
1020 if (!_update_caches(player)) {
1021 return;
1022 }
1023 }
1024
1025 { //setup
1026
1027 process_pass++;
1028
1029 state.valid = true;
1030 state.invalid_reasons = "";
1031 state.animation_states.clear(); //will need to be re-created
1032 state.player = player;
1033 state.last_pass = process_pass;
1034 state.tree = this;
1035
1036 // root source blends
1037
1038 root->blends.resize(state.track_count);
1039 real_t *src_blendsw = root->blends.ptrw();
1040 for (int i = 0; i < state.track_count; i++) {
1041 src_blendsw[i] = 1.0; //by default all go to 1 for the root input
1042 }
1043 }
1044
1045 //process
1046
1047 {
1048 if (started) {
1049 //if started, seek
1050 root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, nullptr, &state, 0, true, false, Vector<StringName>());
1051 started = false;
1052 }
1053
1054 root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, nullptr, &state, p_delta, false, false, Vector<StringName>());
1055 }
1056
1057 if (!state.valid) {
1058 return; //state is not valid. do nothing.
1059 }
1060
1061 // Init all value/transform/blend/bezier tracks that track_cache has.
1062 {
1063 for (const KeyValue<NodePath, TrackCache *> &K : track_cache) {
1064 TrackCache *track = K.value;
1065
1066 switch (track->type) {
1067 case Animation::TYPE_POSITION_3D: {
1068 TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
1069 if (track->root_motion) {
1070 root_motion_cache.loc = Vector3(0, 0, 0);
1071 root_motion_cache.rot = Quaternion(0, 0, 0, 1);
1072 root_motion_cache.scale = Vector3(1, 1, 1);
1073 }
1074 t->loc = t->init_loc;
1075 t->rot = t->init_rot;
1076 t->scale = t->init_scale;
1077 } break;
1078 case Animation::TYPE_BLEND_SHAPE: {
1079 TrackCacheBlendShape *t = static_cast<TrackCacheBlendShape *>(track);
1080 t->value = t->init_value;
1081 } break;
1082 case Animation::TYPE_VALUE: {
1083 TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
1084 t->value = t->init_value;
1085 } break;
1086 case Animation::TYPE_BEZIER: {
1087 TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
1088 t->value = t->init_value;
1089 } break;
1090 case Animation::TYPE_AUDIO: {
1091 TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);
1092 for (KeyValue<ObjectID, PlayingAudioTrackInfo> &L : t->playing_streams) {
1093 PlayingAudioTrackInfo &track_info = L.value;
1094 track_info.volume = 0.0;
1095 }
1096 } break;
1097 default: {
1098 } break;
1099 }
1100 }
1101 }
1102
1103 // Apply value/transform/blend/bezier blends to track caches and execute method/audio/animation tracks.
1104 {
1105#ifdef TOOLS_ENABLED
1106 bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint();
1107#endif // TOOLS_ENABLED
1108 for (const AnimationNode::AnimationState &as : state.animation_states) {
1109 Ref<Animation> a = as.animation;
1110 double time = as.time;
1111 double delta = as.delta;
1112 real_t weight = as.blend;
1113 bool seeked = as.seeked;
1114 Animation::LoopedFlag looped_flag = as.looped_flag;
1115 bool is_external_seeking = as.is_external_seeking;
1116 bool backward = signbit(delta); // This flag is used by the root motion calculates or detecting the end of audio stream.
1117#ifndef _3D_DISABLED
1118 bool calc_root = !seeked || is_external_seeking;
1119#endif // _3D_DISABLED
1120
1121 for (int i = 0; i < a->get_track_count(); i++) {
1122 if (!a->track_is_enabled(i)) {
1123 continue;
1124 }
1125
1126 NodePath path = a->track_get_path(i);
1127 if (!track_cache.has(path)) {
1128 continue; // No path, but avoid error spamming.
1129 }
1130 TrackCache *track = track_cache[path];
1131
1132 ERR_CONTINUE(!state.track_map.has(path));
1133 int blend_idx = state.track_map[path];
1134 ERR_CONTINUE(blend_idx < 0 || blend_idx >= state.track_count);
1135 real_t blend = (as.track_blends)[blend_idx] * weight;
1136
1137 Animation::TrackType ttype = a->track_get_type(i);
1138 if (ttype != Animation::TYPE_POSITION_3D && ttype != Animation::TYPE_ROTATION_3D && ttype != Animation::TYPE_SCALE_3D && track->type != ttype) {
1139 //broken animation, but avoid error spamming
1140 continue;
1141 }
1142 track->root_motion = root_motion_track == path;
1143
1144 switch (ttype) {
1145 case Animation::TYPE_POSITION_3D: {
1146#ifndef _3D_DISABLED
1147 if (Math::is_zero_approx(blend)) {
1148 continue; // Nothing to blend.
1149 }
1150 TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
1151
1152 if (track->root_motion && calc_root) {
1153 double prev_time = time - delta;
1154 if (!backward) {
1155 if (prev_time < 0) {
1156 switch (a->get_loop_mode()) {
1157 case Animation::LOOP_NONE: {
1158 prev_time = 0;
1159 } break;
1160 case Animation::LOOP_LINEAR: {
1161 prev_time = Math::fposmod(prev_time, (double)a->get_length());
1162 } break;
1163 case Animation::LOOP_PINGPONG: {
1164 prev_time = Math::pingpong(prev_time, (double)a->get_length());
1165 } break;
1166 default:
1167 break;
1168 }
1169 }
1170 } else {
1171 if (prev_time > a->get_length()) {
1172 switch (a->get_loop_mode()) {
1173 case Animation::LOOP_NONE: {
1174 prev_time = (double)a->get_length();
1175 } break;
1176 case Animation::LOOP_LINEAR: {
1177 prev_time = Math::fposmod(prev_time, (double)a->get_length());
1178 } break;
1179 case Animation::LOOP_PINGPONG: {
1180 prev_time = Math::pingpong(prev_time, (double)a->get_length());
1181 } break;
1182 default:
1183 break;
1184 }
1185 }
1186 }
1187
1188 Vector3 loc[2];
1189
1190 if (!backward) {
1191 if (prev_time > time) {
1192 Error err = a->try_position_track_interpolate(i, prev_time, &loc[0]);
1193 if (err != OK) {
1194 continue;
1195 }
1196 loc[0] = post_process_key_value(a, i, loc[0], t->object, t->bone_idx);
1197 a->try_position_track_interpolate(i, (double)a->get_length(), &loc[1]);
1198 loc[1] = post_process_key_value(a, i, loc[1], t->object, t->bone_idx);
1199 root_motion_cache.loc += (loc[1] - loc[0]) * blend;
1200 prev_time = 0;
1201 }
1202 } else {
1203 if (prev_time < time) {
1204 Error err = a->try_position_track_interpolate(i, prev_time, &loc[0]);
1205 if (err != OK) {
1206 continue;
1207 }
1208 loc[0] = post_process_key_value(a, i, loc[0], t->object, t->bone_idx);
1209 a->try_position_track_interpolate(i, 0, &loc[1]);
1210 loc[1] = post_process_key_value(a, i, loc[1], t->object, t->bone_idx);
1211 root_motion_cache.loc += (loc[1] - loc[0]) * blend;
1212 prev_time = (double)a->get_length();
1213 }
1214 }
1215
1216 Error err = a->try_position_track_interpolate(i, prev_time, &loc[0]);
1217 if (err != OK) {
1218 continue;
1219 }
1220 loc[0] = post_process_key_value(a, i, loc[0], t->object, t->bone_idx);
1221 a->try_position_track_interpolate(i, time, &loc[1]);
1222 loc[1] = post_process_key_value(a, i, loc[1], t->object, t->bone_idx);
1223 root_motion_cache.loc += (loc[1] - loc[0]) * blend;
1224 prev_time = !backward ? 0 : (double)a->get_length();
1225 }
1226
1227 {
1228 Vector3 loc;
1229
1230 Error err = a->try_position_track_interpolate(i, time, &loc);
1231 if (err != OK) {
1232 continue;
1233 }
1234 loc = post_process_key_value(a, i, loc, t->object, t->bone_idx);
1235
1236 t->loc += (loc - t->init_loc) * blend;
1237 }
1238#endif // _3D_DISABLED
1239 } break;
1240 case Animation::TYPE_ROTATION_3D: {
1241#ifndef _3D_DISABLED
1242 if (Math::is_zero_approx(blend)) {
1243 continue; // Nothing to blend.
1244 }
1245 TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
1246
1247 if (track->root_motion && calc_root) {
1248 double prev_time = time - delta;
1249 if (!backward) {
1250 if (prev_time < 0) {
1251 switch (a->get_loop_mode()) {
1252 case Animation::LOOP_NONE: {
1253 prev_time = 0;
1254 } break;
1255 case Animation::LOOP_LINEAR: {
1256 prev_time = Math::fposmod(prev_time, (double)a->get_length());
1257 } break;
1258 case Animation::LOOP_PINGPONG: {
1259 prev_time = Math::pingpong(prev_time, (double)a->get_length());
1260 } break;
1261 default:
1262 break;
1263 }
1264 }
1265 } else {
1266 if (prev_time > a->get_length()) {
1267 switch (a->get_loop_mode()) {
1268 case Animation::LOOP_NONE: {
1269 prev_time = (double)a->get_length();
1270 } break;
1271 case Animation::LOOP_LINEAR: {
1272 prev_time = Math::fposmod(prev_time, (double)a->get_length());
1273 } break;
1274 case Animation::LOOP_PINGPONG: {
1275 prev_time = Math::pingpong(prev_time, (double)a->get_length());
1276 } break;
1277 default:
1278 break;
1279 }
1280 }
1281 }
1282
1283 Quaternion rot[2];
1284
1285 if (!backward) {
1286 if (prev_time > time) {
1287 Error err = a->try_rotation_track_interpolate(i, prev_time, &rot[0]);
1288 if (err != OK) {
1289 continue;
1290 }
1291 rot[0] = post_process_key_value(a, i, rot[0], t->object, t->bone_idx);
1292 a->try_rotation_track_interpolate(i, (double)a->get_length(), &rot[1]);
1293 rot[1] = post_process_key_value(a, i, rot[1], t->object, t->bone_idx);
1294 root_motion_cache.rot = (root_motion_cache.rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized();
1295 prev_time = 0;
1296 }
1297 } else {
1298 if (prev_time < time) {
1299 Error err = a->try_rotation_track_interpolate(i, prev_time, &rot[0]);
1300 if (err != OK) {
1301 continue;
1302 }
1303 rot[0] = post_process_key_value(a, i, rot[0], t->object, t->bone_idx);
1304 a->try_rotation_track_interpolate(i, 0, &rot[1]);
1305 root_motion_cache.rot = (root_motion_cache.rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized();
1306 prev_time = (double)a->get_length();
1307 }
1308 }
1309
1310 Error err = a->try_rotation_track_interpolate(i, prev_time, &rot[0]);
1311 if (err != OK) {
1312 continue;
1313 }
1314 rot[0] = post_process_key_value(a, i, rot[0], t->object, t->bone_idx);
1315
1316 a->try_rotation_track_interpolate(i, time, &rot[1]);
1317 rot[1] = post_process_key_value(a, i, rot[1], t->object, t->bone_idx);
1318 root_motion_cache.rot = (root_motion_cache.rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized();
1319 prev_time = !backward ? 0 : (double)a->get_length();
1320 }
1321
1322 {
1323 Quaternion rot;
1324
1325 Error err = a->try_rotation_track_interpolate(i, time, &rot);
1326 if (err != OK) {
1327 continue;
1328 }
1329 rot = post_process_key_value(a, i, rot, t->object, t->bone_idx);
1330
1331 t->rot = (t->rot * Quaternion().slerp(t->init_rot.inverse() * rot, blend)).normalized();
1332 }
1333#endif // _3D_DISABLED
1334 } break;
1335 case Animation::TYPE_SCALE_3D: {
1336#ifndef _3D_DISABLED
1337 if (Math::is_zero_approx(blend)) {
1338 continue; // Nothing to blend.
1339 }
1340 TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
1341
1342 if (track->root_motion && calc_root) {
1343 double prev_time = time - delta;
1344 if (!backward) {
1345 if (prev_time < 0) {
1346 switch (a->get_loop_mode()) {
1347 case Animation::LOOP_NONE: {
1348 prev_time = 0;
1349 } break;
1350 case Animation::LOOP_LINEAR: {
1351 prev_time = Math::fposmod(prev_time, (double)a->get_length());
1352 } break;
1353 case Animation::LOOP_PINGPONG: {
1354 prev_time = Math::pingpong(prev_time, (double)a->get_length());
1355 } break;
1356 default:
1357 break;
1358 }
1359 }
1360 } else {
1361 if (prev_time > a->get_length()) {
1362 switch (a->get_loop_mode()) {
1363 case Animation::LOOP_NONE: {
1364 prev_time = (double)a->get_length();
1365 } break;
1366 case Animation::LOOP_LINEAR: {
1367 prev_time = Math::fposmod(prev_time, (double)a->get_length());
1368 } break;
1369 case Animation::LOOP_PINGPONG: {
1370 prev_time = Math::pingpong(prev_time, (double)a->get_length());
1371 } break;
1372 default:
1373 break;
1374 }
1375 }
1376 }
1377
1378 Vector3 scale[2];
1379
1380 if (!backward) {
1381 if (prev_time > time) {
1382 Error err = a->try_scale_track_interpolate(i, prev_time, &scale[0]);
1383 if (err != OK) {
1384 continue;
1385 }
1386 scale[0] = post_process_key_value(a, i, scale[0], t->object, t->bone_idx);
1387 a->try_scale_track_interpolate(i, (double)a->get_length(), &scale[1]);
1388 root_motion_cache.scale += (scale[1] - scale[0]) * blend;
1389 scale[1] = post_process_key_value(a, i, scale[1], t->object, t->bone_idx);
1390 prev_time = 0;
1391 }
1392 } else {
1393 if (prev_time < time) {
1394 Error err = a->try_scale_track_interpolate(i, prev_time, &scale[0]);
1395 if (err != OK) {
1396 continue;
1397 }
1398 scale[0] = post_process_key_value(a, i, scale[0], t->object, t->bone_idx);
1399 a->try_scale_track_interpolate(i, 0, &scale[1]);
1400 scale[1] = post_process_key_value(a, i, scale[1], t->object, t->bone_idx);
1401 root_motion_cache.scale += (scale[1] - scale[0]) * blend;
1402 prev_time = (double)a->get_length();
1403 }
1404 }
1405
1406 Error err = a->try_scale_track_interpolate(i, prev_time, &scale[0]);
1407 if (err != OK) {
1408 continue;
1409 }
1410 scale[0] = post_process_key_value(a, i, scale[0], t->object, t->bone_idx);
1411
1412 a->try_scale_track_interpolate(i, time, &scale[1]);
1413 scale[1] = post_process_key_value(a, i, scale[1], t->object, t->bone_idx);
1414 root_motion_cache.scale += (scale[1] - scale[0]) * blend;
1415 prev_time = !backward ? 0 : (double)a->get_length();
1416 }
1417
1418 {
1419 Vector3 scale;
1420
1421 Error err = a->try_scale_track_interpolate(i, time, &scale);
1422 if (err != OK) {
1423 continue;
1424 }
1425 scale = post_process_key_value(a, i, scale, t->object, t->bone_idx);
1426
1427 t->scale += (scale - t->init_scale) * blend;
1428 }
1429#endif // _3D_DISABLED
1430 } break;
1431 case Animation::TYPE_BLEND_SHAPE: {
1432#ifndef _3D_DISABLED
1433 if (Math::is_zero_approx(blend)) {
1434 continue; // Nothing to blend.
1435 }
1436 TrackCacheBlendShape *t = static_cast<TrackCacheBlendShape *>(track);
1437
1438 float value;
1439
1440 Error err = a->try_blend_shape_track_interpolate(i, time, &value);
1441 //ERR_CONTINUE(err!=OK); //used for testing, should be removed
1442
1443 if (err != OK) {
1444 continue;
1445 }
1446 value = post_process_key_value(a, i, value, t->object, t->shape_index);
1447
1448 t->value += (value - t->init_value) * blend;
1449#endif // _3D_DISABLED
1450 } break;
1451 case Animation::TYPE_VALUE: {
1452 if (Math::is_zero_approx(blend)) {
1453 continue; // Nothing to blend.
1454 }
1455 TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
1456
1457 Animation::UpdateMode update_mode = a->value_track_get_update_mode(i);
1458
1459 if (update_mode == Animation::UPDATE_CONTINUOUS || update_mode == Animation::UPDATE_CAPTURE) {
1460 Variant value = a->value_track_interpolate(i, time);
1461 value = post_process_key_value(a, i, value, t->object);
1462
1463 if (value == Variant()) {
1464 continue;
1465 }
1466
1467 // Special case for angle interpolation.
1468 if (t->is_using_angle) {
1469 // For blending consistency, it prevents rotation of more than 180 degrees from init_value.
1470 // This is the same as for Quaternion blends.
1471 float rot_a = t->value;
1472 float rot_b = value;
1473 float rot_init = t->init_value;
1474 rot_a = Math::fposmod(rot_a, (float)Math_TAU);
1475 rot_b = Math::fposmod(rot_b, (float)Math_TAU);
1476 rot_init = Math::fposmod(rot_init, (float)Math_TAU);
1477 if (rot_init < Math_PI) {
1478 rot_a = rot_a > rot_init + Math_PI ? rot_a - Math_TAU : rot_a;
1479 rot_b = rot_b > rot_init + Math_PI ? rot_b - Math_TAU : rot_b;
1480 } else {
1481 rot_a = rot_a < rot_init - Math_PI ? rot_a + Math_TAU : rot_a;
1482 rot_b = rot_b < rot_init - Math_PI ? rot_b + Math_TAU : rot_b;
1483 }
1484 t->value = Math::fposmod(rot_a + (rot_b - rot_init) * (float)blend, (float)Math_TAU);
1485 } else {
1486 if (t->init_value.get_type() == Variant::BOOL) {
1487 value = Animation::subtract_variant(value.operator real_t(), t->init_value.operator real_t());
1488 t->value = Animation::blend_variant(t->value.operator real_t(), value.operator real_t(), blend);
1489 } else {
1490 value = Animation::subtract_variant(value, t->init_value);
1491 t->value = Animation::blend_variant(t->value, value, blend);
1492 }
1493 }
1494 } else {
1495 if (seeked) {
1496 int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT);
1497 if (idx < 0) {
1498 continue;
1499 }
1500 Variant value = a->track_get_key_value(i, idx);
1501 value = post_process_key_value(a, i, value, t->object);
1502 t->object->set_indexed(t->subpath, value);
1503 } else {
1504 List<int> indices;
1505 a->track_get_key_indices_in_range(i, time, delta, &indices, looped_flag);
1506 for (int &F : indices) {
1507 Variant value = a->track_get_key_value(i, F);
1508 value = post_process_key_value(a, i, value, t->object);
1509 t->object->set_indexed(t->subpath, value);
1510 }
1511 }
1512 }
1513
1514 } break;
1515 case Animation::TYPE_METHOD: {
1516#ifdef TOOLS_ENABLED
1517 if (!can_call) {
1518 continue;
1519 }
1520#endif // TOOLS_ENABLED
1521 if (Math::is_zero_approx(blend)) {
1522 continue; // Nothing to blend.
1523 }
1524 TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track);
1525
1526 if (seeked) {
1527 int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT);
1528 if (idx < 0) {
1529 continue;
1530 }
1531 StringName method = a->method_track_get_name(i, idx);
1532 Vector<Variant> params = a->method_track_get_params(i, idx);
1533 _call_object(t->object, method, params, false);
1534 } else {
1535 List<int> indices;
1536 a->track_get_key_indices_in_range(i, time, delta, &indices, looped_flag);
1537 for (int &F : indices) {
1538 StringName method = a->method_track_get_name(i, F);
1539 Vector<Variant> params = a->method_track_get_params(i, F);
1540 _call_object(t->object, method, params, true);
1541 }
1542 }
1543 } break;
1544 case Animation::TYPE_BEZIER: {
1545 if (Math::is_zero_approx(blend)) {
1546 continue; // Nothing to blend.
1547 }
1548 TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
1549
1550 real_t bezier = a->bezier_track_interpolate(i, time);
1551 bezier = post_process_key_value(a, i, bezier, t->object);
1552
1553 t->value += (bezier - t->init_value) * blend;
1554 } break;
1555 case Animation::TYPE_AUDIO: {
1556 TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);
1557
1558 Node *asp = Object::cast_to<Node>(t->object);
1559 if (!asp) {
1560 t->playing_streams.clear();
1561 continue;
1562 }
1563
1564 ObjectID oid = a->get_instance_id();
1565 if (!t->playing_streams.has(oid)) {
1566 t->playing_streams[oid] = PlayingAudioTrackInfo();
1567 }
1568 // The end of audio should be observed even if the blend value is 0, build up the information and store to the cache for that.
1569 PlayingAudioTrackInfo &track_info = t->playing_streams[oid];
1570 track_info.length = a->get_length();
1571 track_info.time = time;
1572 track_info.volume += blend;
1573 track_info.loop = a->get_loop_mode() != Animation::LOOP_NONE;
1574 track_info.backward = backward;
1575 track_info.use_blend = a->audio_track_is_use_blend(i);
1576
1577 HashMap<int, PlayingAudioStreamInfo> &map = track_info.stream_info;
1578 // Find stream.
1579 int idx = -1;
1580 if (seeked) {
1581 idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT);
1582 // Discard previous stream when seeking.
1583 if (map.has(idx)) {
1584 t->audio_stream_playback->stop_stream(map[idx].index);
1585 map.erase(idx);
1586 }
1587 } else {
1588 List<int> to_play;
1589 a->track_get_key_indices_in_range(i, time, delta, &to_play, looped_flag);
1590 if (to_play.size()) {
1591 idx = to_play.back()->get();
1592 }
1593 }
1594 if (idx < 0) {
1595 continue;
1596 }
1597
1598 // Play stream.
1599 Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
1600 if (stream.is_valid()) {
1601 double start_ofs = a->audio_track_get_key_start_offset(i, idx);
1602 double end_ofs = a->audio_track_get_key_end_offset(i, idx);
1603 double len = stream->get_length();
1604
1605 if (seeked) {
1606 start_ofs += time - a->track_get_key_time(i, idx);
1607 }
1608
1609 if (t->object->call(SNAME("get_stream")) != t->audio_stream) {
1610 t->object->call(SNAME("set_stream"), t->audio_stream);
1611 t->audio_stream_playback.unref();
1612 if (!playing_audio_stream_players.has(asp)) {
1613 playing_audio_stream_players.push_back(asp);
1614 }
1615 }
1616 if (!t->object->call(SNAME("is_playing"))) {
1617 t->object->call(SNAME("play"));
1618 }
1619 if (!t->object->call(SNAME("has_stream_playback"))) {
1620 t->audio_stream_playback.unref();
1621 continue;
1622 }
1623 if (t->audio_stream_playback.is_null()) {
1624 t->audio_stream_playback = t->object->call(SNAME("get_stream_playback"));
1625 }
1626
1627 PlayingAudioStreamInfo pasi;
1628 pasi.index = t->audio_stream_playback->play_stream(stream, start_ofs);
1629 pasi.start = time;
1630 if (len && end_ofs > 0) { // Force an end at a time.
1631 pasi.len = len - start_ofs - end_ofs;
1632 } else {
1633 pasi.len = 0;
1634 }
1635 map[idx] = pasi;
1636 }
1637
1638 } break;
1639 case Animation::TYPE_ANIMATION: {
1640 if (Math::is_zero_approx(blend)) {
1641 continue; // Nothing to blend.
1642 }
1643 TrackCacheAnimation *t = static_cast<TrackCacheAnimation *>(track);
1644
1645 AnimationPlayer *player2 = Object::cast_to<AnimationPlayer>(t->object);
1646
1647 if (!player2) {
1648 continue;
1649 }
1650
1651 if (seeked) {
1652 //seek
1653 int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT);
1654 if (idx < 0) {
1655 continue;
1656 }
1657
1658 double pos = a->track_get_key_time(i, idx);
1659
1660 StringName anim_name = a->animation_track_get_key_animation(i, idx);
1661 if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) {
1662 continue;
1663 }
1664
1665 Ref<Animation> anim = player2->get_animation(anim_name);
1666
1667 double at_anim_pos = 0.0;
1668
1669 switch (anim->get_loop_mode()) {
1670 case Animation::LOOP_NONE: {
1671 at_anim_pos = MAX((double)anim->get_length(), time - pos); //seek to end
1672 } break;
1673 case Animation::LOOP_LINEAR: {
1674 at_anim_pos = Math::fposmod(time - pos, (double)anim->get_length()); //seek to loop
1675 } break;
1676 case Animation::LOOP_PINGPONG: {
1677 at_anim_pos = Math::pingpong(time - pos, (double)a->get_length());
1678 } break;
1679 default:
1680 break;
1681 }
1682
1683 if (player2->is_playing() || seeked) {
1684 player2->seek(at_anim_pos);
1685 player2->play(anim_name);
1686 t->playing = true;
1687 playing_caches.insert(t);
1688 } else {
1689 player2->set_assigned_animation(anim_name);
1690 player2->seek(at_anim_pos, true);
1691 }
1692 } else {
1693 //find stuff to play
1694 List<int> to_play;
1695 a->track_get_key_indices_in_range(i, time, delta, &to_play, looped_flag);
1696 if (to_play.size()) {
1697 int idx = to_play.back()->get();
1698
1699 StringName anim_name = a->animation_track_get_key_animation(i, idx);
1700 if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) {
1701 if (playing_caches.has(t)) {
1702 playing_caches.erase(t);
1703 player2->stop();
1704 t->playing = false;
1705 }
1706 } else {
1707 player2->play(anim_name);
1708 t->playing = true;
1709 playing_caches.insert(t);
1710 }
1711 }
1712 }
1713
1714 } break;
1715 }
1716 }
1717 }
1718 }
1719
1720 {
1721 // finally, set the tracks
1722 for (const KeyValue<NodePath, TrackCache *> &K : track_cache) {
1723 TrackCache *track = K.value;
1724
1725 switch (track->type) {
1726 case Animation::TYPE_POSITION_3D: {
1727#ifndef _3D_DISABLED
1728 TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
1729
1730 if (t->root_motion) {
1731 root_motion_position = root_motion_cache.loc;
1732 root_motion_rotation = root_motion_cache.rot;
1733 root_motion_scale = root_motion_cache.scale - Vector3(1, 1, 1);
1734 root_motion_position_accumulator = t->loc;
1735 root_motion_rotation_accumulator = t->rot;
1736 root_motion_scale_accumulator = t->scale;
1737 } else if (t->skeleton && t->bone_idx >= 0) {
1738 if (t->loc_used) {
1739 t->skeleton->set_bone_pose_position(t->bone_idx, t->loc);
1740 }
1741 if (t->rot_used) {
1742 t->skeleton->set_bone_pose_rotation(t->bone_idx, t->rot);
1743 }
1744 if (t->scale_used) {
1745 t->skeleton->set_bone_pose_scale(t->bone_idx, t->scale);
1746 }
1747
1748 } else if (!t->skeleton) {
1749 if (t->loc_used) {
1750 t->node_3d->set_position(t->loc);
1751 }
1752 if (t->rot_used) {
1753 t->node_3d->set_rotation(t->rot.get_euler());
1754 }
1755 if (t->scale_used) {
1756 t->node_3d->set_scale(t->scale);
1757 }
1758 }
1759#endif // _3D_DISABLED
1760 } break;
1761 case Animation::TYPE_BLEND_SHAPE: {
1762#ifndef _3D_DISABLED
1763 TrackCacheBlendShape *t = static_cast<TrackCacheBlendShape *>(track);
1764
1765 if (t->mesh_3d) {
1766 t->mesh_3d->set_blend_shape_value(t->shape_index, t->value);
1767 }
1768#endif // _3D_DISABLED
1769 } break;
1770 case Animation::TYPE_VALUE: {
1771 TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
1772
1773 if (t->is_discrete) {
1774 break; // Don't overwrite the value set by UPDATE_DISCRETE.
1775 }
1776
1777 if (t->init_value.get_type() == Variant::BOOL) {
1778 t->object->set_indexed(t->subpath, t->value.operator real_t() >= 0.5);
1779 } else {
1780 t->object->set_indexed(t->subpath, t->value);
1781 }
1782
1783 } break;
1784 case Animation::TYPE_BEZIER: {
1785 TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
1786
1787 t->object->set_indexed(t->subpath, t->value);
1788
1789 } break;
1790 case Animation::TYPE_AUDIO: {
1791 TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);
1792
1793 // Audio ending process.
1794 LocalVector<ObjectID> erase_maps;
1795 for (KeyValue<ObjectID, PlayingAudioTrackInfo> &L : t->playing_streams) {
1796 PlayingAudioTrackInfo &track_info = L.value;
1797 float db = Math::linear_to_db(track_info.use_blend ? track_info.volume : 1.0);
1798 LocalVector<int> erase_streams;
1799 HashMap<int, PlayingAudioStreamInfo> &map = track_info.stream_info;
1800 for (const KeyValue<int, PlayingAudioStreamInfo> &M : map) {
1801 PlayingAudioStreamInfo pasi = M.value;
1802
1803 bool stop = false;
1804 if (!t->audio_stream_playback->is_stream_playing(pasi.index)) {
1805 stop = true;
1806 }
1807 if (!track_info.loop) {
1808 if (!track_info.backward) {
1809 if (track_info.time < pasi.start) {
1810 stop = true;
1811 }
1812 } else if (track_info.backward) {
1813 if (track_info.time > pasi.start) {
1814 stop = true;
1815 }
1816 }
1817 }
1818 if (pasi.len > 0) {
1819 double len = 0.0;
1820 if (!track_info.backward) {
1821 len = pasi.start > track_info.time ? (track_info.length - pasi.start) + track_info.time : track_info.time - pasi.start;
1822 } else {
1823 len = pasi.start < track_info.time ? (track_info.length - track_info.time) + pasi.start : pasi.start - track_info.time;
1824 }
1825 if (len > pasi.len) {
1826 stop = true;
1827 }
1828 }
1829 if (stop) {
1830 // Time to stop.
1831 t->audio_stream_playback->stop_stream(pasi.index);
1832 erase_streams.push_back(M.key);
1833 } else {
1834 t->audio_stream_playback->set_stream_volume(pasi.index, db);
1835 }
1836 }
1837 for (uint32_t erase_idx = 0; erase_idx < erase_streams.size(); erase_idx++) {
1838 map.erase(erase_streams[erase_idx]);
1839 }
1840 if (map.size() == 0) {
1841 erase_maps.push_back(L.key);
1842 }
1843 }
1844 for (uint32_t erase_idx = 0; erase_idx < erase_maps.size(); erase_idx++) {
1845 t->playing_streams.erase(erase_maps[erase_idx]);
1846 }
1847 } break;
1848 default: {
1849 } //the rest don't matter
1850 }
1851 }
1852 }
1853}
1854
1855Variant AnimationTree::post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) {
1856 Variant res;
1857 if (GDVIRTUAL_CALL(_post_process_key_value, p_anim, p_track, p_value, const_cast<Object *>(p_object), p_object_idx, res)) {
1858 return res;
1859 }
1860
1861 return _post_process_key_value(p_anim, p_track, p_value, p_object, p_object_idx);
1862}
1863
1864Variant AnimationTree::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) {
1865 switch (p_anim->track_get_type(p_track)) {
1866#ifndef _3D_DISABLED
1867 case Animation::TYPE_POSITION_3D: {
1868 if (p_object_idx >= 0) {
1869 const Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_object);
1870 return Vector3(p_value) * skel->get_motion_scale();
1871 }
1872 return p_value;
1873 } break;
1874#endif // _3D_DISABLED
1875 default: {
1876 } break;
1877 }
1878 return p_value;
1879}
1880
1881void AnimationTree::advance(double p_time) {
1882 _process_graph(p_time);
1883}
1884
1885void AnimationTree::_notification(int p_what) {
1886 switch (p_what) {
1887 case NOTIFICATION_ENTER_TREE: {
1888 _setup_animation_player();
1889 if (last_animation_player.is_valid()) {
1890 Object *player = ObjectDB::get_instance(last_animation_player);
1891 if (player) {
1892 player->connect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches));
1893 }
1894 }
1895 } break;
1896
1897 case NOTIFICATION_EXIT_TREE: {
1898 _clear_caches();
1899 if (last_animation_player.is_valid()) {
1900 Object *player = ObjectDB::get_instance(last_animation_player);
1901 if (player) {
1902 player->disconnect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches));
1903 }
1904 }
1905 } break;
1906
1907 case NOTIFICATION_INTERNAL_PROCESS: {
1908 if (active && process_callback == ANIMATION_PROCESS_IDLE) {
1909 _process_graph(get_process_delta_time());
1910 }
1911 } break;
1912
1913 case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
1914 if (active && process_callback == ANIMATION_PROCESS_PHYSICS) {
1915 _process_graph(get_physics_process_delta_time());
1916 }
1917 } break;
1918 }
1919}
1920
1921void AnimationTree::_setup_animation_player() {
1922 if (!is_inside_tree()) {
1923 return;
1924 }
1925
1926 cache_valid = false;
1927
1928 AnimationPlayer *new_player = nullptr;
1929 if (!animation_player.is_empty()) {
1930 new_player = Object::cast_to<AnimationPlayer>(get_node_or_null(animation_player));
1931 if (new_player && !new_player->is_connected("animation_list_changed", callable_mp(this, &AnimationTree::_animation_player_changed))) {
1932 new_player->connect("animation_list_changed", callable_mp(this, &AnimationTree::_animation_player_changed));
1933 }
1934 }
1935
1936 if (new_player) {
1937 if (!last_animation_player.is_valid()) {
1938 // Animation player set newly.
1939 emit_signal(SNAME("animation_player_changed"));
1940 return;
1941 } else if (last_animation_player == new_player->get_instance_id()) {
1942 // Animation player isn't changed.
1943 return;
1944 }
1945 } else if (!last_animation_player.is_valid()) {
1946 // Animation player is being empty.
1947 return;
1948 }
1949
1950 AnimationPlayer *old_player = Object::cast_to<AnimationPlayer>(ObjectDB::get_instance(last_animation_player));
1951 if (old_player && old_player->is_connected("animation_list_changed", callable_mp(this, &AnimationTree::_animation_player_changed))) {
1952 old_player->disconnect("animation_list_changed", callable_mp(this, &AnimationTree::_animation_player_changed));
1953 }
1954 emit_signal(SNAME("animation_player_changed"));
1955}
1956
1957void AnimationTree::set_animation_player(const NodePath &p_player) {
1958 animation_player = p_player;
1959 _setup_animation_player();
1960 update_configuration_warnings();
1961}
1962
1963NodePath AnimationTree::get_animation_player() const {
1964 return animation_player;
1965}
1966
1967void AnimationTree::set_advance_expression_base_node(const NodePath &p_advance_expression_base_node) {
1968 advance_expression_base_node = p_advance_expression_base_node;
1969}
1970
1971NodePath AnimationTree::get_advance_expression_base_node() const {
1972 return advance_expression_base_node;
1973}
1974
1975void AnimationTree::set_audio_max_polyphony(int p_audio_max_polyphony) {
1976 ERR_FAIL_COND(p_audio_max_polyphony < 0 || p_audio_max_polyphony > 128);
1977 audio_max_polyphony = p_audio_max_polyphony;
1978}
1979
1980int AnimationTree::get_audio_max_polyphony() const {
1981 return audio_max_polyphony;
1982}
1983
1984bool AnimationTree::is_state_invalid() const {
1985 return !state.valid;
1986}
1987
1988String AnimationTree::get_invalid_state_reason() const {
1989 return state.invalid_reasons;
1990}
1991
1992uint64_t AnimationTree::get_last_process_pass() const {
1993 return process_pass;
1994}
1995
1996PackedStringArray AnimationTree::get_configuration_warnings() const {
1997 PackedStringArray warnings = Node::get_configuration_warnings();
1998
1999 if (!root.is_valid()) {
2000 warnings.push_back(RTR("No root AnimationNode for the graph is set."));
2001 }
2002
2003 if (!has_node(animation_player)) {
2004 warnings.push_back(RTR("Path to an AnimationPlayer node containing animations is not set."));
2005 } else {
2006 AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
2007
2008 if (!player) {
2009 warnings.push_back(RTR("Path set for AnimationPlayer does not lead to an AnimationPlayer node."));
2010 } else if (!player->has_node(player->get_root())) {
2011 warnings.push_back(RTR("The AnimationPlayer root node is not a valid node."));
2012 }
2013 }
2014
2015 return warnings;
2016}
2017
2018void AnimationTree::set_root_motion_track(const NodePath &p_track) {
2019 root_motion_track = p_track;
2020}
2021
2022NodePath AnimationTree::get_root_motion_track() const {
2023 return root_motion_track;
2024}
2025
2026Vector3 AnimationTree::get_root_motion_position() const {
2027 return root_motion_position;
2028}
2029
2030Quaternion AnimationTree::get_root_motion_rotation() const {
2031 return root_motion_rotation;
2032}
2033
2034Vector3 AnimationTree::get_root_motion_scale() const {
2035 return root_motion_scale;
2036}
2037
2038Vector3 AnimationTree::get_root_motion_position_accumulator() const {
2039 return root_motion_position_accumulator;
2040}
2041
2042Quaternion AnimationTree::get_root_motion_rotation_accumulator() const {
2043 return root_motion_rotation_accumulator;
2044}
2045
2046Vector3 AnimationTree::get_root_motion_scale_accumulator() const {
2047 return root_motion_scale_accumulator;
2048}
2049
2050void AnimationTree::_tree_changed() {
2051 if (properties_dirty) {
2052 return;
2053 }
2054
2055 call_deferred(SNAME("_update_properties"));
2056 properties_dirty = true;
2057}
2058
2059void AnimationTree::_animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) {
2060 ERR_FAIL_COND(!property_reference_map.has(p_oid));
2061 String base_path = property_reference_map[p_oid];
2062 String old_base = base_path + p_old_name;
2063 String new_base = base_path + p_new_name;
2064 for (const PropertyInfo &E : properties) {
2065 if (E.name.begins_with(old_base)) {
2066 String new_name = E.name.replace_first(old_base, new_base);
2067 property_map[new_name] = property_map[E.name];
2068 property_map.erase(E.name);
2069 }
2070 }
2071
2072 //update tree second
2073 properties_dirty = true;
2074 _update_properties();
2075}
2076
2077void AnimationTree::_animation_node_removed(const ObjectID &p_oid, const StringName &p_node) {
2078 ERR_FAIL_COND(!property_reference_map.has(p_oid));
2079 String base_path = String(property_reference_map[p_oid]) + String(p_node);
2080 for (const PropertyInfo &E : properties) {
2081 if (E.name.begins_with(base_path)) {
2082 property_map.erase(E.name);
2083 }
2084 }
2085
2086 //update tree second
2087 properties_dirty = true;
2088 _update_properties();
2089}
2090
2091void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node) {
2092 ERR_FAIL_COND(node.is_null());
2093 if (!property_parent_map.has(p_base_path)) {
2094 property_parent_map[p_base_path] = HashMap<StringName, StringName>();
2095 }
2096 if (!property_reference_map.has(node->get_instance_id())) {
2097 property_reference_map[node->get_instance_id()] = p_base_path;
2098 }
2099
2100 if (node->get_input_count() && !input_activity_map.has(p_base_path)) {
2101 Vector<Activity> activity;
2102 for (int i = 0; i < node->get_input_count(); i++) {
2103 Activity a;
2104 a.activity = 0;
2105 a.last_pass = 0;
2106 activity.push_back(a);
2107 }
2108 input_activity_map[p_base_path] = activity;
2109 input_activity_map_get[String(p_base_path).substr(0, String(p_base_path).length() - 1)] = &input_activity_map[p_base_path];
2110 }
2111
2112 List<PropertyInfo> plist;
2113 node->get_parameter_list(&plist);
2114 for (PropertyInfo &pinfo : plist) {
2115 StringName key = pinfo.name;
2116
2117 if (!property_map.has(p_base_path + key)) {
2118 Pair<Variant, bool> param;
2119 param.first = node->get_parameter_default_value(key);
2120 param.second = node->is_parameter_read_only(key);
2121 property_map[p_base_path + key] = param;
2122 }
2123
2124 property_parent_map[p_base_path][key] = p_base_path + key;
2125
2126 pinfo.name = p_base_path + key;
2127 properties.push_back(pinfo);
2128 }
2129
2130 List<AnimationNode::ChildNode> children;
2131 node->get_child_nodes(&children);
2132
2133 for (const AnimationNode::ChildNode &E : children) {
2134 _update_properties_for_node(p_base_path + E.name + "/", E.node);
2135 }
2136}
2137
2138void AnimationTree::_update_properties() {
2139 if (!properties_dirty) {
2140 return;
2141 }
2142
2143 properties.clear();
2144 property_reference_map.clear();
2145 property_parent_map.clear();
2146 input_activity_map.clear();
2147 input_activity_map_get.clear();
2148
2149 if (root.is_valid()) {
2150 _update_properties_for_node(SceneStringNames::get_singleton()->parameters_base_path, root);
2151 }
2152
2153 properties_dirty = false;
2154
2155 notify_property_list_changed();
2156}
2157
2158bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) {
2159 if (properties_dirty) {
2160 _update_properties();
2161 }
2162
2163 if (property_map.has(p_name)) {
2164 if (is_inside_tree() && property_map[p_name].second) {
2165 return false; // Prevent to set property by user.
2166 }
2167 property_map[p_name].first = p_value;
2168 return true;
2169 }
2170
2171 return false;
2172}
2173
2174bool AnimationTree::_get(const StringName &p_name, Variant &r_ret) const {
2175 if (properties_dirty) {
2176 const_cast<AnimationTree *>(this)->_update_properties();
2177 }
2178
2179 if (property_map.has(p_name)) {
2180 r_ret = property_map[p_name].first;
2181 return true;
2182 }
2183
2184 return false;
2185}
2186
2187void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const {
2188 if (properties_dirty) {
2189 const_cast<AnimationTree *>(this)->_update_properties();
2190 }
2191
2192 for (const PropertyInfo &E : properties) {
2193 p_list->push_back(E);
2194 }
2195}
2196
2197real_t AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const {
2198 if (!input_activity_map_get.has(p_path)) {
2199 return 0;
2200 }
2201 const Vector<Activity> *activity = input_activity_map_get[p_path];
2202
2203 if (!activity || p_connection < 0 || p_connection >= activity->size()) {
2204 return 0;
2205 }
2206
2207 if ((*activity)[p_connection].last_pass != process_pass) {
2208 return 0;
2209 }
2210
2211 return (*activity)[p_connection].activity;
2212}
2213
2214void AnimationTree::_bind_methods() {
2215 ClassDB::bind_method(D_METHOD("set_active", "active"), &AnimationTree::set_active);
2216 ClassDB::bind_method(D_METHOD("is_active"), &AnimationTree::is_active);
2217
2218 ClassDB::bind_method(D_METHOD("set_tree_root", "root"), &AnimationTree::set_tree_root);
2219 ClassDB::bind_method(D_METHOD("get_tree_root"), &AnimationTree::get_tree_root);
2220
2221 ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &AnimationTree::set_process_callback);
2222 ClassDB::bind_method(D_METHOD("get_process_callback"), &AnimationTree::get_process_callback);
2223
2224 ClassDB::bind_method(D_METHOD("set_animation_player", "root"), &AnimationTree::set_animation_player);
2225 ClassDB::bind_method(D_METHOD("get_animation_player"), &AnimationTree::get_animation_player);
2226
2227 ClassDB::bind_method(D_METHOD("set_advance_expression_base_node", "node"), &AnimationTree::set_advance_expression_base_node);
2228 ClassDB::bind_method(D_METHOD("get_advance_expression_base_node"), &AnimationTree::get_advance_expression_base_node);
2229
2230 ClassDB::bind_method(D_METHOD("set_root_motion_track", "path"), &AnimationTree::set_root_motion_track);
2231 ClassDB::bind_method(D_METHOD("get_root_motion_track"), &AnimationTree::get_root_motion_track);
2232
2233 ClassDB::bind_method(D_METHOD("set_audio_max_polyphony", "max_polyphony"), &AnimationTree::set_audio_max_polyphony);
2234 ClassDB::bind_method(D_METHOD("get_audio_max_polyphony"), &AnimationTree::get_audio_max_polyphony);
2235
2236 ClassDB::bind_method(D_METHOD("get_root_motion_position"), &AnimationTree::get_root_motion_position);
2237 ClassDB::bind_method(D_METHOD("get_root_motion_rotation"), &AnimationTree::get_root_motion_rotation);
2238 ClassDB::bind_method(D_METHOD("get_root_motion_scale"), &AnimationTree::get_root_motion_scale);
2239 ClassDB::bind_method(D_METHOD("get_root_motion_position_accumulator"), &AnimationTree::get_root_motion_position_accumulator);
2240 ClassDB::bind_method(D_METHOD("get_root_motion_rotation_accumulator"), &AnimationTree::get_root_motion_rotation_accumulator);
2241 ClassDB::bind_method(D_METHOD("get_root_motion_scale_accumulator"), &AnimationTree::get_root_motion_scale_accumulator);
2242
2243 ClassDB::bind_method(D_METHOD("_update_properties"), &AnimationTree::_update_properties);
2244
2245 ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTree::advance);
2246
2247 GDVIRTUAL_BIND(_post_process_key_value, "animation", "track", "value", "object", "object_idx");
2248
2249 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root");
2250 ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player");
2251 ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "advance_expression_base_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node"), "set_advance_expression_base_node", "get_advance_expression_base_node");
2252
2253 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
2254 ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_callback", "get_process_callback");
2255 ADD_GROUP("Audio", "audio_");
2256 ADD_PROPERTY(PropertyInfo(Variant::INT, "audio_max_polyphony", PROPERTY_HINT_RANGE, "1,127,1"), "set_audio_max_polyphony", "get_audio_max_polyphony");
2257 ADD_GROUP("Root Motion", "root_motion_");
2258 ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_motion_track"), "set_root_motion_track", "get_root_motion_track");
2259
2260 BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS);
2261 BIND_ENUM_CONSTANT(ANIMATION_PROCESS_IDLE);
2262 BIND_ENUM_CONSTANT(ANIMATION_PROCESS_MANUAL);
2263
2264 ADD_SIGNAL(MethodInfo("animation_player_changed"));
2265
2266 // Signals from AnimationNodes.
2267 ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING_NAME, "anim_name")));
2268 ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING_NAME, "anim_name")));
2269}
2270
2271AnimationTree::AnimationTree() {
2272}
2273
2274AnimationTree::~AnimationTree() {
2275}
2276