diff options
Diffstat (limited to 'scene/animation/animation_tree.cpp')
-rw-r--r-- | scene/animation/animation_tree.cpp | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 1513010a8a..73bd00e456 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -109,8 +109,16 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p Ref<AnimationNode> node = blend_tree->get_node(node_name); //inputs.write[p_input].last_pass = state->last_pass; - float activity; - return _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); + float activity = 0; + 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); + + Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path); + + if (activity_ptr && p_input < activity_ptr->size()) { + activity_ptr->write[p_input].last_pass = state->last_pass; + activity_ptr->write[p_input].activity = activity; + } + return ret; } 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) { @@ -690,6 +698,28 @@ void AnimationTree::_process_graph(float p_delta) { AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player)); + ObjectID current_animation_player = 0; + + if (player) { + current_animation_player = player->get_instance_id(); + } + + if (last_animation_player != current_animation_player) { + + if (last_animation_player) { + Object *old_player = ObjectDB::get_instance(last_animation_player); + if (old_player) { + old_player->disconnect("caches_cleared", this, "_clear_caches"); + } + } + + if (player) { + player->connect("caches_cleared", this, "_clear_caches"); + } + + last_animation_player = current_animation_player; + } + if (!player) { ERR_PRINT("AnimationTree: path points to a node not an AnimationPlayer, disabling playback"); set_active(false); @@ -1189,6 +1219,13 @@ void AnimationTree::_notification(int p_what) { if (p_what == NOTIFICATION_EXIT_TREE) { _clear_caches(); + if (last_animation_player) { + + Object *old_player = ObjectDB::get_instance(last_animation_player); + if (old_player) { + old_player->disconnect("caches_cleared", this, "_clear_caches"); + } + } } } @@ -1285,6 +1322,18 @@ void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<A property_parent_map[p_base_path] = HashMap<StringName, StringName>(); } + if (node->get_input_count() && !input_activity_map.has(p_base_path)) { + + Vector<Activity> activity; + for (int i = 0; i < node->get_input_count(); i++) { + Activity a; + a.last_pass = 0; + activity.push_back(a); + } + input_activity_map[p_base_path] = activity; + input_activity_map_get[String(p_base_path).substr(0, String(p_base_path).length() - 1)] = &input_activity_map[p_base_path]; + } + List<PropertyInfo> plist; node->get_parameter_list(&plist); for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { @@ -1317,6 +1366,8 @@ void AnimationTree::_update_properties() { properties.clear(); property_parent_map.clear(); + input_activity_map.clear(); + input_activity_map_get.clear(); if (root.is_valid()) { _update_properties_for_node(SceneStringNames::get_singleton()->parameters_base_path, root); @@ -1380,6 +1431,24 @@ void AnimationTree::rename_parameter(const String &p_base, const String &p_new_b _update_properties(); } +float AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const { + + if (!input_activity_map_get.has(p_path)) { + return 0; + } + const Vector<Activity> *activity = input_activity_map_get[p_path]; + + if (!activity || p_connection < 0 || p_connection >= activity->size()) { + return 0; + } + + if ((*activity)[p_connection].last_pass != process_pass) { + return 0; + } + + return (*activity)[p_connection].activity; +} + void AnimationTree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_active", "active"), &AnimationTree::set_active); ClassDB::bind_method(D_METHOD("is_active"), &AnimationTree::is_active); @@ -1406,6 +1475,7 @@ void AnimationTree::_bind_methods() { ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTree::advance); ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationTree::_node_removed); + ClassDB::bind_method(D_METHOD("_clear_caches"), &AnimationTree::_clear_caches); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player"); @@ -1427,6 +1497,7 @@ AnimationTree::AnimationTree() { setup_pass = 1; started = true; properties_dirty = true; + last_animation_player = 0; } AnimationTree::~AnimationTree() { |