diff options
-rw-r--r-- | editor/editor_node.cpp | 2 | ||||
-rw-r--r-- | editor/icons/icon_animation_tree_player.svg | 1 | ||||
-rw-r--r-- | editor/plugins/animation_tree_player_editor_plugin.cpp | 1451 | ||||
-rw-r--r-- | editor/plugins/animation_tree_player_editor_plugin.h | 184 | ||||
-rw-r--r-- | scene/animation/animation_tree_player.cpp | 1866 | ||||
-rw-r--r-- | scene/animation/animation_tree_player.h | 487 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 4 |
7 files changed, 1 insertions, 3994 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index f7d8d2c7c4..d6dcbf7e84 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -112,7 +112,6 @@ #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/animation_state_machine_editor.h" #include "editor/plugins/animation_tree_editor_plugin.h" -#include "editor/plugins/animation_tree_player_editor_plugin.h" #include "editor/plugins/asset_library_editor_plugin.h" #include "editor/plugins/audio_stream_editor_plugin.h" #include "editor/plugins/baked_lightmap_editor_plugin.h" @@ -6650,7 +6649,6 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(MultiMeshEditorPlugin(this))); add_editor_plugin(memnew(MeshInstanceEditorPlugin(this))); add_editor_plugin(memnew(AnimationTreeEditorPlugin(this))); - add_editor_plugin(memnew(AnimationTreePlayerEditorPlugin(this))); add_editor_plugin(memnew(MeshLibraryEditorPlugin(this))); add_editor_plugin(memnew(StyleBoxEditorPlugin(this))); add_editor_plugin(memnew(SpriteEditorPlugin(this))); diff --git a/editor/icons/icon_animation_tree_player.svg b/editor/icons/icon_animation_tree_player.svg deleted file mode 100644 index 718eaac2d2..0000000000 --- a/editor/icons/icon_animation_tree_player.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h1.166v-2h1.834v2h8v-2h2v2h1v-14h-1v2h-2v-2h-8v2h-1.834v-2zm4 3h2v1 1h1 3v2h-2v1 1h1 1v2h-1-2a1.0001 1.0001 0 0 1 -1-1v-1-2h-1a1.0001 1.0001 0 0 1 -1-1v-1-1zm-2.834 1h1.834v2h-1.834zm9.834 0h2v2h-2zm-9.834 4h1.834v2h-1.834zm9.834 0h2v2h-2z" fill="#cea4f1"/></svg>
\ No newline at end of file diff --git a/editor/plugins/animation_tree_player_editor_plugin.cpp b/editor/plugins/animation_tree_player_editor_plugin.cpp deleted file mode 100644 index 2b365feec5..0000000000 --- a/editor/plugins/animation_tree_player_editor_plugin.cpp +++ /dev/null @@ -1,1451 +0,0 @@ -/*************************************************************************/ -/* animation_tree_player_editor_plugin.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "animation_tree_player_editor_plugin.h" - -#include "core/io/resource_loader.h" -#include "core/os/input.h" -#include "core/os/keyboard.h" -#include "core/project_settings.h" -#include "editor/editor_scale.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/panel.h" -#include "scene/main/viewport.h" - -void AnimationTreePlayerEditor::edit(AnimationTreePlayer *p_anim_tree) { - - anim_tree = p_anim_tree; - - if (!anim_tree) { - hide(); - } else { - order.clear(); - p_anim_tree->get_node_list(&order); - /* - for(List<StringName>::Element* E=order.front();E;E=E->next()) { - - if (E->get() >= (int)last_id) - last_id=E->get()+1; - }*/ - play_button->set_pressed(p_anim_tree->is_active()); - //read the orders - } -} - -Size2 AnimationTreePlayerEditor::_get_maximum_size() { - - Size2 max; - - for (List<StringName>::Element *E = order.front(); E; E = E->next()) { - - Point2 pos = anim_tree->node_get_position(E->get()); - - if (click_type == CLICK_NODE && click_node == E->get()) { - - pos += click_motion - click_pos; - } - pos += get_node_size(E->get()); - if (pos.x > max.x) - max.x = pos.x; - if (pos.y > max.y) - max.y = pos.y; - } - - return max; -} - -const char *AnimationTreePlayerEditor::_node_type_names[] = { "Output", "Animation", "OneShot", "Mix", "Blend2", "Blend3", "Blend4", "TimeScale", "TimeSeek", "Transition" }; - -Size2 AnimationTreePlayerEditor::get_node_size(const StringName &p_node) const { - - AnimationTreePlayer::NodeType type = anim_tree->node_get_type(p_node); - - Ref<StyleBox> style = get_stylebox("panel", "PopupMenu"); - Ref<Font> font = get_font("font", "PopupMenu"); - - Size2 size = style->get_minimum_size(); - - int count = 2; // title and name - int inputs = anim_tree->node_get_input_count(p_node); - count += inputs ? inputs : 1; - String name = p_node; - - float name_w = font->get_string_size(name).width; - float type_w = font->get_string_size(String(_node_type_names[type])).width; - float max_w = MAX(name_w, type_w); - - switch (type) { - case AnimationTreePlayer::NODE_TIMESEEK: - case AnimationTreePlayer::NODE_OUTPUT: { - } break; - case AnimationTreePlayer::NODE_ANIMATION: - case AnimationTreePlayer::NODE_ONESHOT: - case AnimationTreePlayer::NODE_MIX: - case AnimationTreePlayer::NODE_BLEND2: - case AnimationTreePlayer::NODE_BLEND3: - case AnimationTreePlayer::NODE_BLEND4: - case AnimationTreePlayer::NODE_TIMESCALE: - case AnimationTreePlayer::NODE_TRANSITION: { - - size.height += font->get_height(); - } break; - case AnimationTreePlayer::NODE_MAX: { - } - } - - size.x += max_w + 20; - size.y += count * (font->get_height() + get_constant("vseparation", "PopupMenu")); - - return size; -} - -void AnimationTreePlayerEditor::_edit_dialog_changede(String) { - - edit_dialog->hide(); -} - -void AnimationTreePlayerEditor::_edit_dialog_changeds(String s) { - - _edit_dialog_changed(); -} - -void AnimationTreePlayerEditor::_edit_dialog_changedf(float) { - - _edit_dialog_changed(); -} - -void AnimationTreePlayerEditor::_edit_dialog_changed() { - - if (updating_edit) - return; - - if (renaming_edit) { - - if (anim_tree->node_rename(edited_node, edit_line[0]->get_text()) == OK) { - for (List<StringName>::Element *E = order.front(); E; E = E->next()) { - - if (E->get() == edited_node) - E->get() = edit_line[0]->get_text(); - } - edited_node = edit_line[0]->get_text(); - } - update(); - return; - } - - AnimationTreePlayer::NodeType type = anim_tree->node_get_type(edited_node); - - switch (type) { - - case AnimationTreePlayer::NODE_TIMESCALE: - anim_tree->timescale_node_set_scale(edited_node, edit_line[0]->get_text().to_double()); - break; - case AnimationTreePlayer::NODE_ONESHOT: - anim_tree->oneshot_node_set_fadein_time(edited_node, edit_line[0]->get_text().to_double()); - anim_tree->oneshot_node_set_fadeout_time(edited_node, edit_line[1]->get_text().to_double()); - anim_tree->oneshot_node_set_autorestart_delay(edited_node, edit_line[2]->get_text().to_double()); - anim_tree->oneshot_node_set_autorestart_random_delay(edited_node, edit_line[3]->get_text().to_double()); - anim_tree->oneshot_node_set_autorestart(edited_node, edit_check->is_pressed()); - anim_tree->oneshot_node_set_mix_mode(edited_node, edit_option->get_selected()); - - break; - - case AnimationTreePlayer::NODE_MIX: - - anim_tree->mix_node_set_amount(edited_node, edit_scroll[0]->get_value()); - break; - case AnimationTreePlayer::NODE_BLEND2: - anim_tree->blend2_node_set_amount(edited_node, edit_scroll[0]->get_value()); - - break; - - case AnimationTreePlayer::NODE_BLEND3: - anim_tree->blend3_node_set_amount(edited_node, edit_scroll[0]->get_value()); - - break; - case AnimationTreePlayer::NODE_BLEND4: - - anim_tree->blend4_node_set_amount(edited_node, Point2(edit_scroll[0]->get_value(), edit_scroll[1]->get_value())); - - break; - - case AnimationTreePlayer::NODE_TRANSITION: { - anim_tree->transition_node_set_xfade_time(edited_node, edit_line[0]->get_text().to_double()); - if (anim_tree->transition_node_get_current(edited_node) != edit_option->get_selected()) - anim_tree->transition_node_set_current(edited_node, edit_option->get_selected()); - } break; - default: { - } - } -} - -void AnimationTreePlayerEditor::_edit_dialog_animation_changed() { - - Ref<Animation> anim = property_editor->get_variant().operator RefPtr(); - anim_tree->animation_node_set_animation(edited_node, anim); - update(); -} - -void AnimationTreePlayerEditor::_edit_dialog_edit_animation() { - - if (Engine::get_singleton()->is_editor_hint()) { - get_tree()->get_root()->get_child(0)->call("_resource_selected", property_editor->get_variant().operator RefPtr()); - }; -}; - -void AnimationTreePlayerEditor::_edit_oneshot_start() { - - anim_tree->oneshot_node_start(edited_node); -} - -void AnimationTreePlayerEditor::_play_toggled() { - - anim_tree->set_active(play_button->is_pressed()); -} - -void AnimationTreePlayerEditor::_master_anim_menu_item(int p_item) { - - if (p_item == 0) - _edit_filters(); - else { - - String str = master_anim_popup->get_item_text(p_item); - anim_tree->animation_node_set_master_animation(edited_node, str); - } - update(); -} - -void AnimationTreePlayerEditor::_popup_edit_dialog() { - - updating_edit = true; - - for (int i = 0; i < 2; i++) - edit_scroll[i]->hide(); - - for (int i = 0; i < 4; i++) { - - edit_line[i]->hide(); - edit_label[i]->hide(); - } - - edit_option->hide(); - edit_button->hide(); - filter_button->hide(); - edit_check->hide(); - - Point2 pos = anim_tree->node_get_position(edited_node) - Point2(h_scroll->get_value(), v_scroll->get_value()); - Ref<StyleBox> style = get_stylebox("panel", "PopupMenu"); - Size2 size = get_node_size(edited_node); - Point2 popup_pos(pos.x + style->get_margin(MARGIN_LEFT), pos.y + size.y - style->get_margin(MARGIN_BOTTOM)); - popup_pos += get_global_position(); - - if (renaming_edit) { - - edit_label[0]->set_text(TTR("New name:")); - edit_label[0]->set_position(Point2(5, 5)); - edit_label[0]->show(); - edit_line[0]->set_begin(Point2(15, 25)); - edit_line[0]->set_text(edited_node); - edit_line[0]->show(); - edit_dialog->set_size(Size2(150, 50)); - - } else { - - AnimationTreePlayer::NodeType type = anim_tree->node_get_type(edited_node); - - switch (type) { - - case AnimationTreePlayer::NODE_ANIMATION: - - if (anim_tree->get_master_player() != NodePath() && anim_tree->has_node(anim_tree->get_master_player()) && Object::cast_to<AnimationPlayer>(anim_tree->get_node(anim_tree->get_master_player()))) { - - AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(anim_tree->get_node(anim_tree->get_master_player())); - master_anim_popup->clear(); - master_anim_popup->add_item(TTR("Edit Filters")); - master_anim_popup->add_separator(); - List<StringName> sn; - ap->get_animation_list(&sn); - sn.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = sn.front(); E; E = E->next()) { - master_anim_popup->add_item(E->get()); - } - - master_anim_popup->set_position(popup_pos); - master_anim_popup->popup(); - } else { - property_editor->edit(this, "", Variant::OBJECT, anim_tree->animation_node_get_animation(edited_node), PROPERTY_HINT_RESOURCE_TYPE, "Animation"); - property_editor->set_position(popup_pos); - property_editor->popup(); - updating_edit = false; - } - return; - case AnimationTreePlayer::NODE_TIMESCALE: - edit_label[0]->set_text(TTR("Scale:")); - edit_label[0]->set_position(Point2(5, 5)); - edit_label[0]->show(); - edit_line[0]->set_begin(Point2(15, 25)); - edit_line[0]->set_text(rtos(anim_tree->timescale_node_get_scale(edited_node))); - edit_line[0]->show(); - edit_dialog->set_size(Size2(150, 50)); - break; - case AnimationTreePlayer::NODE_ONESHOT: - edit_label[0]->set_text(TTR("Fade In (s):")); - edit_label[0]->set_position(Point2(5, 5)); - edit_label[0]->show(); - edit_line[0]->set_begin(Point2(15, 25)); - edit_line[0]->set_text(rtos(anim_tree->oneshot_node_get_fadein_time(edited_node))); - edit_line[0]->show(); - edit_label[1]->set_text(TTR("Fade Out (s):")); - edit_label[1]->set_position(Point2(5, 55)); - edit_label[1]->show(); - edit_line[1]->set_begin(Point2(15, 75)); - edit_line[1]->set_text(rtos(anim_tree->oneshot_node_get_fadeout_time(edited_node))); - edit_line[1]->show(); - - edit_option->clear(); - edit_option->add_item(TTR("Blend"), 0); - edit_option->add_item(TTR("Mix"), 1); - edit_option->set_begin(Point2(15, 105)); - - edit_option->select(anim_tree->oneshot_node_get_mix_mode(edited_node)); - edit_option->show(); - - edit_check->set_text(TTR("Auto Restart:")); - edit_check->set_begin(Point2(15, 125)); - edit_check->set_pressed(anim_tree->oneshot_node_has_autorestart(edited_node)); - edit_check->show(); - - edit_label[2]->set_text(TTR("Restart (s):")); - edit_label[2]->set_position(Point2(5, 145)); - edit_label[2]->show(); - edit_line[2]->set_begin(Point2(15, 165)); - edit_line[2]->set_text(rtos(anim_tree->oneshot_node_get_autorestart_delay(edited_node))); - edit_line[2]->show(); - edit_label[3]->set_text(TTR("Random Restart (s):")); - edit_label[3]->set_position(Point2(5, 195)); - edit_label[3]->show(); - edit_line[3]->set_begin(Point2(15, 215)); - edit_line[3]->set_text(rtos(anim_tree->oneshot_node_get_autorestart_random_delay(edited_node))); - edit_line[3]->show(); - - filter_button->set_begin(Point2(10, 245)); - filter_button->show(); - - edit_button->set_begin(Point2(10, 268)); - edit_button->set_text(TTR("Start!")); - - edit_button->show(); - - edit_dialog->set_size(Size2(180, 293)); - - break; - - case AnimationTreePlayer::NODE_MIX: - - edit_label[0]->set_text(TTR("Amount:")); - edit_label[0]->set_position(Point2(5, 5)); - edit_label[0]->show(); - edit_scroll[0]->set_min(0); - edit_scroll[0]->set_max(1); - edit_scroll[0]->set_step(0.01); - edit_scroll[0]->set_value(anim_tree->mix_node_get_amount(edited_node)); - edit_scroll[0]->set_begin(Point2(15, 25)); - edit_scroll[0]->show(); - edit_dialog->set_size(Size2(150, 50)); - - break; - case AnimationTreePlayer::NODE_BLEND2: - edit_label[0]->set_text(TTR("Blend:")); - edit_label[0]->set_position(Point2(5, 5)); - edit_label[0]->show(); - edit_scroll[0]->set_min(0); - edit_scroll[0]->set_max(1); - edit_scroll[0]->set_step(0.01); - edit_scroll[0]->set_value(anim_tree->blend2_node_get_amount(edited_node)); - edit_scroll[0]->set_begin(Point2(15, 25)); - edit_scroll[0]->show(); - filter_button->set_begin(Point2(10, 47)); - filter_button->show(); - edit_dialog->set_size(Size2(150, 74)); - - break; - - case AnimationTreePlayer::NODE_BLEND3: - edit_label[0]->set_text(TTR("Blend:")); - edit_label[0]->set_position(Point2(5, 5)); - edit_label[0]->show(); - edit_scroll[0]->set_min(-1); - edit_scroll[0]->set_max(1); - edit_scroll[0]->set_step(0.01); - edit_scroll[0]->set_value(anim_tree->blend3_node_get_amount(edited_node)); - edit_scroll[0]->set_begin(Point2(15, 25)); - edit_scroll[0]->show(); - edit_dialog->set_size(Size2(150, 50)); - - break; - case AnimationTreePlayer::NODE_BLEND4: - - edit_label[0]->set_text(TTR("Blend 0:")); - edit_label[0]->set_position(Point2(5, 5)); - edit_label[0]->show(); - edit_scroll[0]->set_min(0); - edit_scroll[0]->set_max(1); - edit_scroll[0]->set_step(0.01); - edit_scroll[0]->set_value(anim_tree->blend4_node_get_amount(edited_node).x); - edit_scroll[0]->set_begin(Point2(15, 25)); - edit_scroll[0]->show(); - edit_label[1]->set_text(TTR("Blend 1:")); - edit_label[1]->set_position(Point2(5, 55)); - edit_label[1]->show(); - edit_scroll[1]->set_min(0); - edit_scroll[1]->set_max(1); - edit_scroll[1]->set_step(0.01); - edit_scroll[1]->set_value(anim_tree->blend4_node_get_amount(edited_node).y); - edit_scroll[1]->set_begin(Point2(15, 75)); - edit_scroll[1]->show(); - edit_dialog->set_size(Size2(150, 100)); - - break; - - case AnimationTreePlayer::NODE_TRANSITION: { - - edit_label[0]->set_text(TTR("X-Fade Time (s):")); - edit_label[0]->set_position(Point2(5, 5)); - edit_label[0]->show(); - edit_line[0]->set_begin(Point2(15, 25)); - edit_line[0]->set_text(rtos(anim_tree->transition_node_get_xfade_time(edited_node))); - edit_line[0]->show(); - - edit_label[1]->set_text(TTR("Current:")); - edit_label[1]->set_position(Point2(5, 55)); - edit_label[1]->show(); - edit_option->set_begin(Point2(15, 75)); - - edit_option->clear(); - - for (int i = 0; i < anim_tree->transition_node_get_input_count(edited_node); i++) { - edit_option->add_item(itos(i), i); - } - - edit_option->select(anim_tree->transition_node_get_current(edited_node)); - edit_option->show(); - edit_dialog->set_size(Size2(150, 100)); - - } break; - default: { - } - } - } - - edit_dialog->set_position(popup_pos); - edit_dialog->popup(); - - updating_edit = false; -} - -void AnimationTreePlayerEditor::_draw_node(const StringName &p_node) { - - RID ci = get_canvas_item(); - AnimationTreePlayer::NodeType type = anim_tree->node_get_type(p_node); - - Ref<StyleBox> style = get_stylebox("panel", "PopupMenu"); - Ref<Font> font = get_font("font", "PopupMenu"); - Color font_color = get_color("font_color", "PopupMenu"); - Color font_color_title = get_color("font_color_hover", "PopupMenu"); - font_color_title.a *= 0.8; - Ref<Texture> slot_icon = get_icon("VisualShaderPort", "EditorIcons"); - - Size2 size = get_node_size(p_node); - Point2 pos = anim_tree->node_get_position(p_node); - if (click_type == CLICK_NODE && click_node == p_node) { - - pos += click_motion - click_pos; - if (pos.x < 5) - pos.x = 5; - if (pos.y < 5) - pos.y = 5; - } - - pos -= Point2(h_scroll->get_value(), v_scroll->get_value()); - - style->draw(ci, Rect2(pos, size)); - - float w = size.width - style->get_minimum_size().width; - float h = font->get_height() + get_constant("vseparation", "PopupMenu"); - - Point2 ofs = style->get_offset() + pos; - Point2 ascofs(0, font->get_ascent()); - - Color bx = font_color_title; - bx.a *= 0.1; - draw_rect(Rect2(ofs, Size2(size.width - style->get_minimum_size().width, font->get_height())), bx); - font->draw_halign(ci, ofs + ascofs, HALIGN_CENTER, w, String(_node_type_names[type]), font_color_title); - - ofs.y += h; - font->draw_halign(ci, ofs + ascofs, HALIGN_CENTER, w, p_node, font_color); - ofs.y += h; - - int inputs = anim_tree->node_get_input_count(p_node); - - float icon_h_ofs = Math::floor((font->get_height() - slot_icon->get_height()) / 2.0) + 1; - - if (type != AnimationTreePlayer::NODE_OUTPUT) - slot_icon->draw(ci, ofs + Point2(w, icon_h_ofs)); //output - - if (inputs) { - for (int i = 0; i < inputs; i++) { - - slot_icon->draw(ci, ofs + Point2(-slot_icon->get_width(), icon_h_ofs)); - String text; - switch (type) { - - case AnimationTreePlayer::NODE_TIMESCALE: - case AnimationTreePlayer::NODE_TIMESEEK: text = "in"; break; - case AnimationTreePlayer::NODE_OUTPUT: text = "out"; break; - case AnimationTreePlayer::NODE_ANIMATION: break; - case AnimationTreePlayer::NODE_ONESHOT: text = (i == 0 ? "in" : "add"); break; - case AnimationTreePlayer::NODE_BLEND2: - case AnimationTreePlayer::NODE_MIX: text = (i == 0 ? "a" : "b"); break; - case AnimationTreePlayer::NODE_BLEND3: - switch (i) { - case 0: text = "b-"; break; - case 1: text = "a"; break; - case 2: text = "b+"; break; - } - break; - - case AnimationTreePlayer::NODE_BLEND4: - switch (i) { - case 0: text = "a0"; break; - case 1: text = "b0"; break; - case 2: text = "a1"; break; - case 3: text = "b1"; break; - } - break; - - case AnimationTreePlayer::NODE_TRANSITION: - text = itos(i); - if (anim_tree->transition_node_has_input_auto_advance(p_node, i)) - text += "->"; - - break; - default: { - } - } - font->draw(ci, ofs + ascofs + Point2(3, 0), text, font_color); - - ofs.y += h; - } - } else { - ofs.y += h; - } - - Ref<StyleBox> pg_bg = get_stylebox("bg", "ProgressBar"); - Ref<StyleBox> pg_fill = get_stylebox("fill", "ProgressBar"); - Rect2 pg_rect(ofs, Size2(w, h)); - - bool editable = true; - switch (type) { - case AnimationTreePlayer::NODE_ANIMATION: { - - Ref<Animation> anim = anim_tree->animation_node_get_animation(p_node); - String text; - if (anim_tree->animation_node_get_master_animation(p_node) != "") - text = anim_tree->animation_node_get_master_animation(p_node); - else if (anim.is_null()) - text = "load..."; - else - text = anim->get_name(); - - font->draw_halign(ci, ofs + ascofs, HALIGN_CENTER, w, text, font_color_title); - - } break; - case AnimationTreePlayer::NODE_ONESHOT: - case AnimationTreePlayer::NODE_MIX: - case AnimationTreePlayer::NODE_BLEND2: - case AnimationTreePlayer::NODE_BLEND3: - case AnimationTreePlayer::NODE_BLEND4: - case AnimationTreePlayer::NODE_TIMESCALE: - case AnimationTreePlayer::NODE_TRANSITION: { - - font->draw_halign(ci, ofs + ascofs, HALIGN_CENTER, w, "edit...", font_color_title); - } break; - default: editable = false; - } - - if (editable) { - - Ref<Texture> arrow = get_icon("GuiDropdown", "EditorIcons"); - Point2 arrow_ofs(w - arrow->get_width(), Math::floor((h - arrow->get_height()) / 2)); - arrow->draw(ci, ofs + arrow_ofs); - } -} - -AnimationTreePlayerEditor::ClickType AnimationTreePlayerEditor::_locate_click(const Point2 &p_click, StringName *p_node_id, int *p_slot_index) const { - - Ref<StyleBox> style = get_stylebox("panel", "PopupMenu"); - Ref<Font> font = get_font("font", "PopupMenu"); - - float h = (font->get_height() + get_constant("vseparation", "PopupMenu")); - - for (const List<StringName>::Element *E = order.back(); E; E = E->prev()) { - - const StringName &node = E->get(); - - AnimationTreePlayer::NodeType type = anim_tree->node_get_type(node); - - Point2 pos = anim_tree->node_get_position(node); - Size2 size = get_node_size(node); - - pos -= Point2(h_scroll->get_value(), v_scroll->get_value()); - - if (!Rect2(pos, size).has_point(p_click)) - continue; - - if (p_node_id) - *p_node_id = node; - - pos = p_click - pos; - - float y = pos.y - style->get_offset().height; - - if (y < 2 * h) - return CLICK_NODE; - y -= 2 * h; - - int inputs = anim_tree->node_get_input_count(node); - int count = MAX(inputs, 1); - - if (inputs == 0 || (pos.x > size.width / 2 && type != AnimationTreePlayer::NODE_OUTPUT)) { - - if (y < count * h) { - - if (p_slot_index) - *p_slot_index = 0; - return CLICK_OUTPUT_SLOT; - } - } - - for (int i = 0; i < count; i++) { - - if (y < h) { - if (p_slot_index) - *p_slot_index = i; - return CLICK_INPUT_SLOT; - } - y -= h; - } - - bool has_parameters = type != AnimationTreePlayer::NODE_OUTPUT && type != AnimationTreePlayer::NODE_TIMESEEK; - return has_parameters ? CLICK_PARAMETER : CLICK_NODE; - } - - return CLICK_NONE; -} - -Point2 AnimationTreePlayerEditor::_get_slot_pos(const StringName &p_node_id, bool p_input, int p_slot) { - - Ref<StyleBox> style = get_stylebox("panel", "PopupMenu"); - Ref<Font> font = get_font("font", "PopupMenu"); - Ref<Texture> slot_icon = get_icon("VisualShaderPort", "EditorIcons"); - - Size2 size = get_node_size(p_node_id); - Point2 pos = anim_tree->node_get_position(p_node_id); - - if (click_type == CLICK_NODE && click_node == p_node_id) { - - pos += click_motion - click_pos; - if (pos.x < 5) - pos.x = 5; - if (pos.y < 5) - pos.y = 5; - } - - pos -= Point2(h_scroll->get_value(), v_scroll->get_value()); - - float w = size.width - style->get_minimum_size().width; - float h = font->get_height() + get_constant("vseparation", "PopupMenu"); - - pos += style->get_offset(); - - pos.y += h * 2; - - pos.y += h * p_slot; - - pos += Point2(-slot_icon->get_width() / 2.0, h / 2.0).floor(); - - if (!p_input) { - pos.x += w + slot_icon->get_width(); - } - - return pos; -} - -void AnimationTreePlayerEditor::_gui_input(Ref<InputEvent> p_event) { - - Ref<InputEventMouseButton> mb = p_event; - - if (mb.is_valid()) { - - if (mb->is_pressed()) { - - if (mb->get_button_index() == 1) { - click_pos = Point2(mb->get_position().x, mb->get_position().y); - click_motion = click_pos; - click_type = _locate_click(click_pos, &click_node, &click_slot); - if (click_type != CLICK_NONE) { - - order.erase(click_node); - order.push_back(click_node); - update(); - } - - switch (click_type) { - case CLICK_INPUT_SLOT: { - click_pos = _get_slot_pos(click_node, true, click_slot); - } break; - case CLICK_OUTPUT_SLOT: { - click_pos = _get_slot_pos(click_node, false, click_slot); - } break; - case CLICK_PARAMETER: { - - edited_node = click_node; - renaming_edit = false; - _popup_edit_dialog(); - //open editor - //_node_edit_property(click_node); - } break; - default: { - } - } - } - if (mb->get_button_index() == 2) { - - if (click_type != CLICK_NONE) { - click_type = CLICK_NONE; - update(); - } else { - // try to disconnect/remove - - Point2 rclick_pos = Point2(mb->get_position().x, mb->get_position().y); - rclick_type = _locate_click(rclick_pos, &rclick_node, &rclick_slot); - if (rclick_type == CLICK_INPUT_SLOT || rclick_type == CLICK_OUTPUT_SLOT) { - - node_popup->clear(); - node_popup->set_size(Size2(1, 1)); - node_popup->add_item(TTR("Disconnect"), NODE_DISCONNECT); - if (anim_tree->node_get_type(rclick_node) == AnimationTreePlayer::NODE_TRANSITION) { - node_popup->add_item(TTR("Add Input"), NODE_ADD_INPUT); - if (rclick_type == CLICK_INPUT_SLOT) { - if (anim_tree->transition_node_has_input_auto_advance(rclick_node, rclick_slot)) - node_popup->add_item(TTR("Clear Auto-Advance"), NODE_CLEAR_AUTOADVANCE); - else - node_popup->add_item(TTR("Set Auto-Advance"), NODE_SET_AUTOADVANCE); - node_popup->add_item(TTR("Delete Input"), NODE_DELETE_INPUT); - } - } - - node_popup->set_position(rclick_pos + get_global_position()); - node_popup->popup(); - } - - if (rclick_type == CLICK_NODE) { - node_popup->clear(); - node_popup->set_size(Size2(1, 1)); - node_popup->add_item(TTR("Rename"), NODE_RENAME); - node_popup->add_item(TTR("Remove"), NODE_ERASE); - if (anim_tree->node_get_type(rclick_node) == AnimationTreePlayer::NODE_TRANSITION) - node_popup->add_item(TTR("Add Input"), NODE_ADD_INPUT); - node_popup->set_position(rclick_pos + get_global_position()); - node_popup->popup(); - } - } - } - } else { - - if (mb->get_button_index() == 1 && click_type != CLICK_NONE) { - - switch (click_type) { - case CLICK_INPUT_SLOT: - case CLICK_OUTPUT_SLOT: { - - Point2 dst_click_pos = Point2(mb->get_position().x, mb->get_position().y); - StringName id; - int slot; - ClickType dst_click_type = _locate_click(dst_click_pos, &id, &slot); - - if (dst_click_type == CLICK_INPUT_SLOT && click_type == CLICK_OUTPUT_SLOT) { - - anim_tree->connect_nodes(click_node, id, slot); - } - if (click_type == CLICK_INPUT_SLOT && dst_click_type == CLICK_OUTPUT_SLOT) { - - anim_tree->connect_nodes(id, click_node, click_slot); - } - - } break; - case CLICK_NODE: { - Point2 new_pos = anim_tree->node_get_position(click_node) + (click_motion - click_pos); - if (new_pos.x < 5) - new_pos.x = 5; - if (new_pos.y < 5) - new_pos.y = 5; - anim_tree->node_set_position(click_node, new_pos); - - } break; - default: { - } - } - - click_type = CLICK_NONE; - update(); - } - } - } - - Ref<InputEventMouseMotion> mm = p_event; - - if (mm.is_valid()) { - - if (mm->get_button_mask() & 1 && click_type != CLICK_NONE) { - - click_motion = Point2(mm->get_position().x, mm->get_position().y); - update(); - } - if (mm->get_button_mask() & 4 || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { - - h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); - v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); - update(); - } - } -} - -void AnimationTreePlayerEditor::_draw_cos_line(const Vector2 &p_from, const Vector2 &p_to, const Color &p_color) { - - static const int steps = 20; - - Rect2 r; - r.position = p_from; - r.expand_to(p_to); - Vector2 sign = Vector2((p_from.x < p_to.x) ? 1 : -1, (p_from.y < p_to.y) ? 1 : -1); - bool flip = sign.x * sign.y < 0; - - Vector2 prev; - for (int i = 0; i <= steps; i++) { - - float d = i / float(steps); - float c = -Math::cos(d * Math_PI) * 0.5 + 0.5; - if (flip) - c = 1.0 - c; - Vector2 p = r.position + Vector2(d * r.size.width, c * r.size.height); - - if (i > 0) { - - draw_line(prev, p, p_color, 2); - } - - prev = p; - } -} - -void AnimationTreePlayerEditor::_notification(int p_what) { - - switch (p_what) { - - case NOTIFICATION_ENTER_TREE: { - - play_button->set_icon(get_icon("Play", "EditorIcons")); - add_menu->set_icon(get_icon("Add", "EditorIcons")); - } break; - case NOTIFICATION_DRAW: { - - _update_scrollbars(); - //VisualServer::get_singleton()->canvas_item_add_rect(get_canvas_item(),Rect2(Point2(),get_size()),Color(0,0,0,1)); - get_stylebox("bg", "Tree")->draw(get_canvas_item(), Rect2(Point2(), get_size())); - - for (List<StringName>::Element *E = order.front(); E; E = E->next()) { - - _draw_node(E->get()); - } - - if (click_type == CLICK_INPUT_SLOT || click_type == CLICK_OUTPUT_SLOT) { - - _draw_cos_line(click_pos, click_motion, Color(0.5, 1, 0.5, 0.8)); - } - - List<AnimationTreePlayer::Connection> connections; - anim_tree->get_connection_list(&connections); - - for (List<AnimationTreePlayer::Connection>::Element *E = connections.front(); E; E = E->next()) { - - const AnimationTreePlayer::Connection &c = E->get(); - Point2 source = _get_slot_pos(c.src_node, false, 0); - Point2 dest = _get_slot_pos(c.dst_node, true, c.dst_input); - Color col = Color(1, 1, 0.5, 0.8); - /* - if (click_type==CLICK_NODE && click_node==c.src_node) { - - source+=click_motion-click_pos; - } - - if (click_type==CLICK_NODE && click_node==c.dst_node) { - - dest+=click_motion-click_pos; - }*/ - - _draw_cos_line(source, dest, col); - } - - const Ref<Font> f = get_font("font", "Label"); - const Point2 status_offset = Point2(5, 25) * EDSCALE + Point2(0, f->get_ascent()); - - switch (anim_tree->get_last_error()) { - - case AnimationTreePlayer::CONNECT_OK: { - - f->draw(get_canvas_item(), status_offset, TTR("Animation tree is valid."), Color(0, 1, 0.6, 0.8)); - } break; - default: { - - f->draw(get_canvas_item(), status_offset, TTR("Animation tree is invalid."), Color(1, 0.6, 0.0, 0.8)); - } break; - } - - } break; - } -} - -void AnimationTreePlayerEditor::_update_scrollbars() { - - Size2 size = get_size(); - Size2 hmin = h_scroll->get_combined_minimum_size(); - Size2 vmin = v_scroll->get_combined_minimum_size(); - - v_scroll->set_begin(Point2(size.width - vmin.width, 0)); - v_scroll->set_end(Point2(size.width, size.height)); - - h_scroll->set_begin(Point2(0, size.height - hmin.height)); - h_scroll->set_end(Point2(size.width - vmin.width, size.height)); - - Size2 min = _get_maximum_size(); - - if (min.height < size.height - hmin.height) { - - v_scroll->hide(); - offset.y = 0; - } else { - - v_scroll->show(); - v_scroll->set_max(min.height); - v_scroll->set_page(size.height - hmin.height); - offset.y = v_scroll->get_value(); - } - - if (min.width < size.width - vmin.width) { - - h_scroll->hide(); - offset.x = 0; - } else { - - h_scroll->show(); - h_scroll->set_max(min.width); - h_scroll->set_page(size.width - vmin.width); - offset.x = h_scroll->get_value(); - } -} - -void AnimationTreePlayerEditor::_scroll_moved(float) { - - offset.x = h_scroll->get_value(); - offset.y = v_scroll->get_value(); - update(); -} - -void AnimationTreePlayerEditor::_node_menu_item(int p_item) { - - switch (p_item) { - - case NODE_DISCONNECT: { - - if (rclick_type == CLICK_INPUT_SLOT) { - - anim_tree->disconnect_nodes(rclick_node, rclick_slot); - update(); - } - - if (rclick_type == CLICK_OUTPUT_SLOT) { - - List<AnimationTreePlayer::Connection> connections; - anim_tree->get_connection_list(&connections); - - for (List<AnimationTreePlayer::Connection>::Element *E = connections.front(); E; E = E->next()) { - - const AnimationTreePlayer::Connection &c = E->get(); - if (c.dst_node == rclick_node) { - - anim_tree->disconnect_nodes(c.dst_node, c.dst_input); - } - } - update(); - } - - } break; - case NODE_RENAME: { - - renaming_edit = true; - edited_node = rclick_node; - _popup_edit_dialog(); - - } break; - case NODE_ADD_INPUT: { - - anim_tree->transition_node_set_input_count(rclick_node, anim_tree->transition_node_get_input_count(rclick_node) + 1); - update(); - } break; - case NODE_DELETE_INPUT: { - - anim_tree->transition_node_delete_input(rclick_node, rclick_slot); - update(); - } break; - case NODE_SET_AUTOADVANCE: { - - anim_tree->transition_node_set_input_auto_advance(rclick_node, rclick_slot, true); - update(); - - } break; - case NODE_CLEAR_AUTOADVANCE: { - - anim_tree->transition_node_set_input_auto_advance(rclick_node, rclick_slot, false); - update(); - - } break; - - case NODE_ERASE: { - - if (rclick_node == "out") - break; - order.erase(rclick_node); - anim_tree->remove_node(rclick_node); - update(); - } break; - } -} - -StringName AnimationTreePlayerEditor::_add_node(int p_item) { - - static const char *bname[] = { - "out", - "anim", - "oneshot", - "mix", - "blend2", - "blend3", - "blend4", - "scale", - "seek", - "transition" - }; - - String name; - int idx = 1; - - while (true) { - - name = bname[p_item]; - if (idx > 1) - name += " " + itos(idx); - if (anim_tree->node_exists(name)) - idx++; - else - break; - } - - anim_tree->add_node((AnimationTreePlayer::NodeType)p_item, name); - anim_tree->node_set_position(name, Point2(last_x, last_y)); - order.push_back(name); - last_x += 10; - last_y += 10; - last_x = last_x % (int)get_size().width; - last_y = last_y % (int)get_size().height; - update(); - - return name; -}; - -void AnimationTreePlayerEditor::_file_dialog_selected(String p_path) { - - switch (file_op) { - - case MENU_IMPORT_ANIMATIONS: { - Vector<String> files = file_dialog->get_selected_files(); - - for (int i = 0; i < files.size(); i++) { - - StringName node = _add_node(AnimationTreePlayer::NODE_ANIMATION); - - RES anim = ResourceLoader::load(files[i]); - anim_tree->animation_node_set_animation(node, anim); - //anim_tree->node_set_name(node, files[i].get_file()); - }; - } break; - - default: - break; - }; -}; - -void AnimationTreePlayerEditor::_add_menu_item(int p_item) { - - if (p_item == MENU_GRAPH_CLEAR) { - - //clear - } else if (p_item == MENU_IMPORT_ANIMATIONS) { - - file_op = MENU_IMPORT_ANIMATIONS; - file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); - file_dialog->popup_centered_ratio(); - - } else { - - _add_node(p_item); - } -} - -Size2 AnimationTreePlayerEditor::get_minimum_size() const { - - return Size2(10, 200); -} - -void AnimationTreePlayerEditor::_find_paths_for_filter(const StringName &p_node, Set<String> &paths) { - - ERR_FAIL_COND(!anim_tree->node_exists(p_node)); - - for (int i = 0; i < anim_tree->node_get_input_count(p_node); i++) { - - StringName port = anim_tree->node_get_input_source(p_node, i); - if (port == StringName()) - continue; - _find_paths_for_filter(port, paths); - } - - if (anim_tree->node_get_type(p_node) == AnimationTreePlayer::NODE_ANIMATION) { - - Ref<Animation> anim = anim_tree->animation_node_get_animation(p_node); - if (anim.is_valid()) { - - for (int i = 0; i < anim->get_track_count(); i++) { - paths.insert(anim->track_get_path(i)); - } - } - } -} - -void AnimationTreePlayerEditor::_filter_edited() { - - TreeItem *ed = filter->get_edited(); - if (!ed) - return; - - if (anim_tree->node_get_type(edited_node) == AnimationTreePlayer::NODE_ONESHOT) { - anim_tree->oneshot_node_set_filter_path(edited_node, ed->get_metadata(0), ed->is_checked(0)); - } else if (anim_tree->node_get_type(edited_node) == AnimationTreePlayer::NODE_BLEND2) { - anim_tree->blend2_node_set_filter_path(edited_node, ed->get_metadata(0), ed->is_checked(0)); - } else if (anim_tree->node_get_type(edited_node) == AnimationTreePlayer::NODE_ANIMATION) { - anim_tree->animation_node_set_filter_path(edited_node, ed->get_metadata(0), ed->is_checked(0)); - } -} - -void AnimationTreePlayerEditor::_edit_filters() { - - filter_dialog->popup_centered_ratio(); - filter->clear(); - - Set<String> npb; - _find_paths_for_filter(edited_node, npb); - - TreeItem *root = filter->create_item(); - filter->set_hide_root(true); - Map<String, TreeItem *> pm; - - Node *base = anim_tree->get_node(anim_tree->get_base_path()); - - for (Set<String>::Element *E = npb.front(); E; E = E->next()) { - - TreeItem *parent = root; - String descr = E->get(); - if (base) { - NodePath np = E->get(); - - if (np.get_subname_count() == 1) { - Node *n = base->get_node(np); - Skeleton *s = Object::cast_to<Skeleton>(n); - if (s) { - - String skelbase = E->get().substr(0, E->get().find(":")); - - int bidx = s->find_bone(np.get_subname(0)); - - if (bidx != -1) { - int bparent = s->get_bone_parent(bidx); - // - if (bparent != -1) { - - String bpn = skelbase + ":" + s->get_bone_name(bparent); - if (pm.has(bpn)) { - parent = pm[bpn]; - descr = np.get_subname(0); - } - } else { - - if (pm.has(skelbase)) { - parent = pm[skelbase]; - } - } - } - } - } - } - - TreeItem *it = filter->create_item(parent); - it->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - it->set_text(0, descr); - it->set_metadata(0, NodePath(E->get())); - it->set_editable(0, true); - if (anim_tree->node_get_type(edited_node) == AnimationTreePlayer::NODE_ONESHOT) { - it->set_checked(0, anim_tree->oneshot_node_is_path_filtered(edited_node, E->get())); - } else if (anim_tree->node_get_type(edited_node) == AnimationTreePlayer::NODE_BLEND2) { - it->set_checked(0, anim_tree->blend2_node_is_path_filtered(edited_node, E->get())); - } else if (anim_tree->node_get_type(edited_node) == AnimationTreePlayer::NODE_ANIMATION) { - it->set_checked(0, anim_tree->animation_node_is_path_filtered(edited_node, E->get())); - } - pm[E->get()] = it; - } -} - -void AnimationTreePlayerEditor::_bind_methods() { - - ClassDB::bind_method("_add_menu_item", &AnimationTreePlayerEditor::_add_menu_item); - ClassDB::bind_method("_node_menu_item", &AnimationTreePlayerEditor::_node_menu_item); - ClassDB::bind_method("_gui_input", &AnimationTreePlayerEditor::_gui_input); - //ClassDB::bind_method( "_node_param_changed", &AnimationTreeEditor::_node_param_changed ); - ClassDB::bind_method("_scroll_moved", &AnimationTreePlayerEditor::_scroll_moved); - ClassDB::bind_method("_edit_dialog_changeds", &AnimationTreePlayerEditor::_edit_dialog_changeds); - ClassDB::bind_method("_edit_dialog_changede", &AnimationTreePlayerEditor::_edit_dialog_changede); - ClassDB::bind_method("_edit_dialog_changedf", &AnimationTreePlayerEditor::_edit_dialog_changedf); - ClassDB::bind_method("_edit_dialog_changed", &AnimationTreePlayerEditor::_edit_dialog_changed); - ClassDB::bind_method("_edit_dialog_animation_changed", &AnimationTreePlayerEditor::_edit_dialog_animation_changed); - ClassDB::bind_method("_edit_dialog_edit_animation", &AnimationTreePlayerEditor::_edit_dialog_edit_animation); - ClassDB::bind_method("_play_toggled", &AnimationTreePlayerEditor::_play_toggled); - ClassDB::bind_method("_edit_oneshot_start", &AnimationTreePlayerEditor::_edit_oneshot_start); - ClassDB::bind_method("_file_dialog_selected", &AnimationTreePlayerEditor::_file_dialog_selected); - ClassDB::bind_method("_master_anim_menu_item", &AnimationTreePlayerEditor::_master_anim_menu_item); - ClassDB::bind_method("_edit_filters", &AnimationTreePlayerEditor::_edit_filters); - ClassDB::bind_method("_filter_edited", &AnimationTreePlayerEditor::_filter_edited); -} - -AnimationTreePlayerEditor::AnimationTreePlayerEditor() { - - set_focus_mode(FOCUS_ALL); - - PopupMenu *p; - List<PropertyInfo> defaults; - - add_menu = memnew(MenuButton); - //add_menu->set_ - add_menu->set_position(Point2(0, 0)); - add_menu->set_size(Point2(25, 15)); - add_child(add_menu); - - p = add_menu->get_popup(); - p->add_item(TTR("Animation Node"), AnimationTreePlayer::NODE_ANIMATION); - p->add_item(TTR("OneShot Node"), AnimationTreePlayer::NODE_ONESHOT); - p->add_item(TTR("Mix Node"), AnimationTreePlayer::NODE_MIX); - p->add_item(TTR("Blend2 Node"), AnimationTreePlayer::NODE_BLEND2); - p->add_item(TTR("Blend3 Node"), AnimationTreePlayer::NODE_BLEND3); - p->add_item(TTR("Blend4 Node"), AnimationTreePlayer::NODE_BLEND4); - p->add_item(TTR("TimeScale Node"), AnimationTreePlayer::NODE_TIMESCALE); - p->add_item(TTR("TimeSeek Node"), AnimationTreePlayer::NODE_TIMESEEK); - p->add_item(TTR("Transition Node"), AnimationTreePlayer::NODE_TRANSITION); - p->add_separator(); - p->add_item(TTR("Import Animations..."), MENU_IMPORT_ANIMATIONS); // wtf - p->add_separator(); - p->add_item(TTR("Clear"), MENU_GRAPH_CLEAR); - - p->connect("id_pressed", this, "_add_menu_item"); - - play_button = memnew(Button); - play_button->set_position(Point2(25, 0) * EDSCALE); - play_button->set_size(Point2(25, 15)); - add_child(play_button); - play_button->set_toggle_mode(true); - play_button->connect("pressed", this, "_play_toggled"); - - last_x = 50; - last_y = 50; - - property_editor = memnew(CustomPropertyEditor); - add_child(property_editor); - property_editor->connect("variant_changed", this, "_edit_dialog_animation_changed"); - property_editor->connect("resource_edit_request", this, "_edit_dialog_edit_animation"); - - h_scroll = memnew(HScrollBar); - v_scroll = memnew(VScrollBar); - - add_child(h_scroll); - add_child(v_scroll); - - h_scroll->connect("value_changed", this, "_scroll_moved"); - v_scroll->connect("value_changed", this, "_scroll_moved"); - - node_popup = memnew(PopupMenu); - add_child(node_popup); - node_popup->set_as_toplevel(true); - - master_anim_popup = memnew(PopupMenu); - add_child(master_anim_popup); - master_anim_popup->connect("id_pressed", this, "_master_anim_menu_item"); - - node_popup->connect("id_pressed", this, "_node_menu_item"); - - updating_edit = false; - - edit_dialog = memnew(PopupPanel); - //edit_dialog->get_ok()->hide(); - //edit_dialog->get_cancel()->hide(); - add_child(edit_dialog); - - edit_option = memnew(OptionButton); - edit_option->set_anchor(MARGIN_RIGHT, ANCHOR_END); - edit_option->set_margin(MARGIN_RIGHT, -10); - edit_dialog->add_child(edit_option); - edit_option->connect("item_selected", this, "_edit_dialog_changedf"); - edit_option->hide(); - - for (int i = 0; i < 2; i++) { - edit_scroll[i] = memnew(HSlider); - edit_scroll[i]->set_anchor(MARGIN_RIGHT, ANCHOR_END); - edit_scroll[i]->set_margin(MARGIN_RIGHT, -10); - edit_dialog->add_child(edit_scroll[i]); - edit_scroll[i]->hide(); - edit_scroll[i]->connect("value_changed", this, "_edit_dialog_changedf"); - } - for (int i = 0; i < 4; i++) { - edit_line[i] = memnew(LineEdit); - edit_line[i]->set_anchor(MARGIN_RIGHT, ANCHOR_END); - edit_line[i]->set_margin(MARGIN_RIGHT, -10); - edit_dialog->add_child(edit_line[i]); - edit_line[i]->hide(); - edit_line[i]->connect("text_changed", this, "_edit_dialog_changeds"); - edit_line[i]->connect("text_entered", this, "_edit_dialog_changede"); - edit_label[i] = memnew(Label); - edit_dialog->add_child(edit_label[i]); - edit_label[i]->hide(); - } - - edit_button = memnew(Button); - edit_button->set_anchor(MARGIN_RIGHT, ANCHOR_END); - edit_button->set_margin(MARGIN_RIGHT, -10); - edit_dialog->add_child(edit_button); - edit_button->hide(); - edit_button->connect("pressed", this, "_edit_oneshot_start"); - - edit_check = memnew(CheckButton); - edit_check->set_anchor(MARGIN_RIGHT, ANCHOR_END); - edit_check->set_margin(MARGIN_RIGHT, -10); - edit_dialog->add_child(edit_check); - edit_check->hide(); - edit_check->connect("pressed", this, "_edit_dialog_changed"); - - file_dialog = memnew(EditorFileDialog); - file_dialog->set_enable_multiple_selection(true); - file_dialog->set_current_dir(ProjectSettings::get_singleton()->get_resource_path()); - add_child(file_dialog); - file_dialog->connect("file_selected", this, "_file_dialog_selected"); - - filter_dialog = memnew(AcceptDialog); - filter_dialog->set_title(TTR("Edit Node Filters")); - add_child(filter_dialog); - - filter = memnew(Tree); - filter_dialog->add_child(filter); - //filter_dialog->set_child_rect(filter); - filter->connect("item_edited", this, "_filter_edited"); - - filter_button = memnew(Button); - filter_button->set_anchor(MARGIN_RIGHT, ANCHOR_END); - filter_button->set_margin(MARGIN_RIGHT, -10); - edit_dialog->add_child(filter_button); - filter_button->hide(); - filter_button->set_text(TTR("Filters...")); - filter_button->connect("pressed", this, "_edit_filters"); - - set_clip_contents(true); -} - -void AnimationTreePlayerEditorPlugin::edit(Object *p_object) { - - anim_tree_editor->edit(Object::cast_to<AnimationTreePlayer>(p_object)); -} - -bool AnimationTreePlayerEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("AnimationTreePlayer"); -} - -void AnimationTreePlayerEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - //editor->hide_animation_player_editors(); - //editor->animation_panel_make_visible(true); - button->show(); - editor->make_bottom_panel_item_visible(anim_tree_editor); - anim_tree_editor->set_physics_process(true); - } else { - - if (anim_tree_editor->is_visible_in_tree()) - editor->hide_bottom_panel(); - button->hide(); - anim_tree_editor->set_physics_process(false); - } -} - -AnimationTreePlayerEditorPlugin::AnimationTreePlayerEditorPlugin(EditorNode *p_node) { - - editor = p_node; - anim_tree_editor = memnew(AnimationTreePlayerEditor); - anim_tree_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); - - button = editor->add_bottom_panel_item(TTR("AnimationTree"), anim_tree_editor); - button->hide(); -} - -AnimationTreePlayerEditorPlugin::~AnimationTreePlayerEditorPlugin() { -} diff --git a/editor/plugins/animation_tree_player_editor_plugin.h b/editor/plugins/animation_tree_player_editor_plugin.h deleted file mode 100644 index d3fd6ae362..0000000000 --- a/editor/plugins/animation_tree_player_editor_plugin.h +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************/ -/* animation_tree_player_editor_plugin.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef ANIMATION_TREE_PLAYER_EDITOR_PLUGIN_H -#define ANIMATION_TREE_PLAYER_EDITOR_PLUGIN_H - -#include "editor/editor_node.h" -#include "editor/editor_plugin.h" -#include "editor/property_editor.h" -#include "scene/animation/animation_tree_player.h" -#include "scene/gui/button.h" -#include "scene/gui/popup.h" -#include "scene/gui/tree.h" - -class AnimationTreePlayerEditor : public Control { - - GDCLASS(AnimationTreePlayerEditor, Control); - - static const char *_node_type_names[]; - - enum ClickType { - CLICK_NONE, - CLICK_NAME, - CLICK_NODE, - CLICK_INPUT_SLOT, - CLICK_OUTPUT_SLOT, - CLICK_PARAMETER - }; - - enum { - - MENU_GRAPH_CLEAR = 100, - MENU_IMPORT_ANIMATIONS = 101, - NODE_DISCONNECT, - NODE_RENAME, - NODE_ERASE, - NODE_ADD_INPUT, - NODE_DELETE_INPUT, - NODE_SET_AUTOADVANCE, - NODE_CLEAR_AUTOADVANCE - }; - - bool renaming_edit; - StringName edited_node; - bool updating_edit; - Popup *edit_dialog; - HSlider *edit_scroll[2]; - LineEdit *edit_line[4]; - OptionButton *edit_option; - Label *edit_label[4]; - Button *edit_button; - Button *filter_button; - CheckButton *edit_check; - EditorFileDialog *file_dialog; - int file_op; - - void _popup_edit_dialog(); - - void _setup_edit_dialog(const StringName &p_node); - PopupMenu *master_anim_popup; - PopupMenu *node_popup; - PopupMenu *add_popup; - HScrollBar *h_scroll; - VScrollBar *v_scroll; - MenuButton *add_menu; - - CustomPropertyEditor *property_editor; - - AnimationTreePlayer *anim_tree; - List<StringName> order; - Set<StringName> active_nodes; - - int last_x, last_y; - - Point2 offset; - ClickType click_type; - Point2 click_pos; - StringName click_node; - int click_slot; - Point2 click_motion; - ClickType rclick_type; - StringName rclick_node; - int rclick_slot; - - Button *play_button; - - Size2 _get_maximum_size(); - Size2 get_node_size(const StringName &p_node) const; - void _draw_node(const StringName &p_node); - - AcceptDialog *filter_dialog; - Tree *filter; - - void _draw_cos_line(const Vector2 &p_from, const Vector2 &p_to, const Color &p_color); - void _update_scrollbars(); - void _scroll_moved(float); - void _play_toggled(); - /* - void _node_param_changed(); - void _node_add_callback(); - void _node_add(VisualServer::AnimationTreeNodeType p_type); - void _node_edit_property(const StringName& p_node); -*/ - - void _master_anim_menu_item(int p_item); - void _node_menu_item(int p_item); - void _add_menu_item(int p_item); - - void _filter_edited(); - void _find_paths_for_filter(const StringName &p_node, Set<String> &paths); - void _edit_filters(); - - void _edit_oneshot_start(); - void _edit_dialog_animation_changed(); - void _edit_dialog_edit_animation(); - void _edit_dialog_changeds(String); - void _edit_dialog_changede(String); - void _edit_dialog_changedf(float); - void _edit_dialog_changed(); - void _dialog_changed() const; - ClickType _locate_click(const Point2 &p_click, StringName *p_node_id, int *p_slot_index) const; - Point2 _get_slot_pos(const StringName &p_node_id, bool p_input, int p_slot); - - StringName _add_node(int p_item); - void _file_dialog_selected(String p_path); - -protected: - void _notification(int p_what); - void _gui_input(Ref<InputEvent> p_event); - static void _bind_methods(); - -public: - virtual Size2 get_minimum_size() const; - void edit(AnimationTreePlayer *p_anim_tree); - AnimationTreePlayerEditor(); -}; - -class AnimationTreePlayerEditorPlugin : public EditorPlugin { - - GDCLASS(AnimationTreePlayerEditorPlugin, EditorPlugin); - - AnimationTreePlayerEditor *anim_tree_editor; - EditorNode *editor; - Button *button; - -public: - virtual String get_name() const { return "AnimTree"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_object); - virtual bool handles(Object *p_object) const; - virtual void make_visible(bool p_visible); - - AnimationTreePlayerEditorPlugin(EditorNode *p_node); - ~AnimationTreePlayerEditorPlugin(); -}; - -#endif // ANIMATION_TREE_EDITOR_PLUGIN_H diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp deleted file mode 100644 index c7362391dc..0000000000 --- a/scene/animation/animation_tree_player.cpp +++ /dev/null @@ -1,1866 +0,0 @@ -/*************************************************************************/ -/* animation_tree_player.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "animation_tree_player.h" -#include "animation_player.h" - -#include "scene/scene_string_names.h" - -void AnimationTreePlayer::set_animation_process_mode(AnimationProcessMode p_mode) { - - if (animation_process_mode == p_mode) - return; - - bool pr = processing; - if (pr) - _set_process(false); - animation_process_mode = p_mode; - if (pr) - _set_process(true); -} - -AnimationTreePlayer::AnimationProcessMode AnimationTreePlayer::get_animation_process_mode() const { - - return animation_process_mode; -} - -void AnimationTreePlayer::_set_process(bool p_process, bool p_force) { - if (processing == p_process && !p_force) - return; - - switch (animation_process_mode) { - - case ANIMATION_PROCESS_PHYSICS: set_physics_process_internal(p_process && active); break; - case ANIMATION_PROCESS_IDLE: set_process_internal(p_process && active); break; - } - - processing = p_process; -} - -bool AnimationTreePlayer::_set(const StringName &p_name, const Variant &p_value) { - - if (String(p_name) == "base_path") { - set_base_path(p_value); - return true; - } - - if (String(p_name) == "master_player") { - set_master_player(p_value); - return true; - } - - if (String(p_name) == SceneStringNames::get_singleton()->playback_active) { - set_active(p_value); - return true; - } - - if (String(p_name) != "data") - return false; - - Dictionary data = p_value; - - Array nodes = data.get_valid("nodes"); - - for (int i = 0; i < nodes.size(); i++) { - - Dictionary node = nodes[i]; - - StringName id = node.get_valid("id"); - Point2 pos = node.get_valid("position"); - - NodeType nt = NODE_MAX; - String type = node.get_valid("type"); - - if (type == "output") - nt = NODE_OUTPUT; - else if (type == "animation") - nt = NODE_ANIMATION; - else if (type == "oneshot") - nt = NODE_ONESHOT; - else if (type == "mix") - nt = NODE_MIX; - else if (type == "blend2") - nt = NODE_BLEND2; - else if (type == "blend3") - nt = NODE_BLEND3; - else if (type == "blend4") - nt = NODE_BLEND4; - else if (type == "timescale") - nt = NODE_TIMESCALE; - else if (type == "timeseek") - nt = NODE_TIMESEEK; - else if (type == "transition") - nt = NODE_TRANSITION; - - ERR_FAIL_COND_V(nt == NODE_MAX, false); - - if (nt != NODE_OUTPUT) - add_node(nt, id); - node_set_position(id, pos); - - switch (nt) { - case NODE_OUTPUT: { - - } break; - case NODE_ANIMATION: { - - if (node.has("from")) - animation_node_set_master_animation(id, node.get_valid("from")); - else - animation_node_set_animation(id, node.get_valid("animation")); - Array filters = node.get_valid("filter"); - for (int j = 0; j < filters.size(); j++) { - - animation_node_set_filter_path(id, filters[j], true); - } - } break; - case NODE_ONESHOT: { - - oneshot_node_set_fadein_time(id, node.get_valid("fade_in")); - oneshot_node_set_fadeout_time(id, node.get_valid("fade_out")); - oneshot_node_set_mix_mode(id, node.get_valid("mix")); - oneshot_node_set_autorestart(id, node.get_valid("autorestart")); - oneshot_node_set_autorestart_delay(id, node.get_valid("autorestart_delay")); - oneshot_node_set_autorestart_random_delay(id, node.get_valid("autorestart_random_delay")); - Array filters = node.get_valid("filter"); - for (int j = 0; j < filters.size(); j++) { - - oneshot_node_set_filter_path(id, filters[j], true); - } - - } break; - case NODE_MIX: { - mix_node_set_amount(id, node.get_valid("mix")); - } break; - case NODE_BLEND2: { - blend2_node_set_amount(id, node.get_valid("blend")); - Array filters = node.get_valid("filter"); - for (int j = 0; j < filters.size(); j++) { - - blend2_node_set_filter_path(id, filters[j], true); - } - } break; - case NODE_BLEND3: { - blend3_node_set_amount(id, node.get_valid("blend")); - } break; - case NODE_BLEND4: { - blend4_node_set_amount(id, node.get_valid("blend")); - } break; - case NODE_TIMESCALE: { - timescale_node_set_scale(id, node.get_valid("scale")); - } break; - case NODE_TIMESEEK: { - } break; - case NODE_TRANSITION: { - - transition_node_set_xfade_time(id, node.get_valid("xfade")); - - Array transitions = node.get_valid("transitions"); - transition_node_set_input_count(id, transitions.size()); - - for (int x = 0; x < transitions.size(); x++) { - - Dictionary d = transitions[x]; - bool aa = d.get_valid("auto_advance"); - transition_node_set_input_auto_advance(id, x, aa); - } - - } break; - default: { - }; - } - } - - Array connections = data.get_valid("connections"); - ERR_FAIL_COND_V(connections.size() % 3, false); - - int cc = connections.size() / 3; - - for (int i = 0; i < cc; i++) { - - StringName src = connections[i * 3 + 0]; - StringName dst = connections[i * 3 + 1]; - int dst_in = connections[i * 3 + 2]; - connect_nodes(src, dst, dst_in); - } - - set_active(data.get_valid("active")); - set_master_player(data.get_valid("master")); - - return true; -} - -bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const { - - if (String(p_name) == "base_path") { - r_ret = base_path; - return true; - } - - if (String(p_name) == "master_player") { - r_ret = master; - return true; - } - - if (String(p_name) == "playback/active") { - r_ret = is_active(); - return true; - } - - if (String(p_name) != "data") - return false; - - Dictionary data; - - Array nodes; - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - NodeBase *n = node_map[E->key()]; - - Dictionary node; - node["id"] = E->key(); - node["position"] = n->pos; - - switch (n->type) { - case NODE_OUTPUT: node["type"] = "output"; break; - case NODE_ANIMATION: node["type"] = "animation"; break; - case NODE_ONESHOT: node["type"] = "oneshot"; break; - case NODE_MIX: node["type"] = "mix"; break; - case NODE_BLEND2: node["type"] = "blend2"; break; - case NODE_BLEND3: node["type"] = "blend3"; break; - case NODE_BLEND4: node["type"] = "blend4"; break; - case NODE_TIMESCALE: node["type"] = "timescale"; break; - case NODE_TIMESEEK: node["type"] = "timeseek"; break; - case NODE_TRANSITION: node["type"] = "transition"; break; - default: node["type"] = ""; break; - } - - switch (n->type) { - case NODE_OUTPUT: { - - } break; - case NODE_ANIMATION: { - AnimationNode *an = static_cast<AnimationNode *>(n); - if (master != NodePath() && an->from != "") { - node["from"] = an->from; - } else { - node["animation"] = an->animation; - } - Array k; - List<NodePath> keys; - an->filter.get_key_list(&keys); - k.resize(keys.size()); - int i = 0; - for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { - k[i++] = F->get(); - } - node["filter"] = k; - } break; - case NODE_ONESHOT: { - OneShotNode *osn = static_cast<OneShotNode *>(n); - node["fade_in"] = osn->fade_in; - node["fade_out"] = osn->fade_out; - node["mix"] = osn->mix; - node["autorestart"] = osn->autorestart; - node["autorestart_delay"] = osn->autorestart_delay; - node["autorestart_random_delay"] = osn->autorestart_random_delay; - - Array k; - List<NodePath> keys; - osn->filter.get_key_list(&keys); - k.resize(keys.size()); - int i = 0; - for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { - k[i++] = F->get(); - } - node["filter"] = k; - - } break; - case NODE_MIX: { - MixNode *mn = static_cast<MixNode *>(n); - node["mix"] = mn->amount; - } break; - case NODE_BLEND2: { - Blend2Node *bn = static_cast<Blend2Node *>(n); - node["blend"] = bn->value; - Array k; - List<NodePath> keys; - bn->filter.get_key_list(&keys); - k.resize(keys.size()); - int i = 0; - for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { - k[i++] = F->get(); - } - node["filter"] = k; - - } break; - case NODE_BLEND3: { - Blend3Node *bn = static_cast<Blend3Node *>(n); - node["blend"] = bn->value; - } break; - case NODE_BLEND4: { - Blend4Node *bn = static_cast<Blend4Node *>(n); - node["blend"] = bn->value; - - } break; - case NODE_TIMESCALE: { - TimeScaleNode *tsn = static_cast<TimeScaleNode *>(n); - node["scale"] = tsn->scale; - } break; - case NODE_TIMESEEK: { - } break; - case NODE_TRANSITION: { - - TransitionNode *tn = static_cast<TransitionNode *>(n); - node["xfade"] = tn->xfade; - Array transitions; - - for (int i = 0; i < tn->input_data.size(); i++) { - - Dictionary d; - d["auto_advance"] = tn->input_data[i].auto_advance; - transitions.push_back(d); - } - - node["transitions"] = transitions; - - } break; - default: { - }; - } - - nodes.push_back(node); - } - - data["nodes"] = nodes; - //connectiosn - - List<Connection> connections; - get_connection_list(&connections); - Array connections_arr; - connections_arr.resize(connections.size() * 3); - - int idx = 0; - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { - - connections_arr.set(idx + 0, E->get().src_node); - connections_arr.set(idx + 1, E->get().dst_node); - connections_arr.set(idx + 2, E->get().dst_input); - - idx += 3; - } - - data["connections"] = connections_arr; - data["active"] = active; - data["master"] = master; - - r_ret = data; - - return true; -} - -void AnimationTreePlayer::_get_property_list(List<PropertyInfo> *p_list) const { - - p_list->push_back(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK)); -} - -void AnimationTreePlayer::advance(float p_time) { - - _process_animation(p_time); -} - -void AnimationTreePlayer::_notification(int p_what) { - - switch (p_what) { - - case NOTIFICATION_ENTER_TREE: { - - WARN_DEPRECATED_MSG("AnimationTreePlayer has been deprecated. Use AnimationTree instead."); - - if (!processing) { - //make sure that a previous process state was not saved - //only process if "processing" is set - set_physics_process_internal(false); - set_process_internal(false); - } - } break; - case NOTIFICATION_READY: { - - dirty_caches = true; - if (master != NodePath()) { - _update_sources(); - } - } break; - case NOTIFICATION_INTERNAL_PROCESS: { - - if (animation_process_mode == ANIMATION_PROCESS_PHYSICS) - break; - - if (processing) - _process_animation(get_process_delta_time()); - } break; - case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - - if (animation_process_mode == ANIMATION_PROCESS_IDLE) - break; - - if (processing) - _process_animation(get_physics_process_delta_time()); - } break; - } -} - -void AnimationTreePlayer::_compute_weights(float *p_fallback_weight, HashMap<NodePath, float> *p_weights, float p_coeff, const HashMap<NodePath, bool> *p_filter, float p_filtered_coeff) { - - if (p_filter != NULL) { - - List<NodePath> key_list; - p_filter->get_key_list(&key_list); - - for (List<NodePath>::Element *E = key_list.front(); E; E = E->next()) { - - if ((*p_filter)[E->get()]) { - - if (p_weights->has(E->get())) { - (*p_weights)[E->get()] *= p_filtered_coeff; - } else { - p_weights->set(E->get(), *p_fallback_weight * p_filtered_coeff); - } - - } else if (p_weights->has(E->get())) { - (*p_weights)[E->get()] *= p_coeff; - } - } - } - - List<NodePath> key_list; - p_weights->get_key_list(&key_list); - - for (List<NodePath>::Element *E = key_list.front(); E; E = E->next()) { - if (p_filter == NULL || !p_filter->has(E->get())) { - (*p_weights)[E->get()] *= p_coeff; - } - } - - *p_fallback_weight *= p_coeff; -} - -float AnimationTreePlayer::_process_node(const StringName &p_node, AnimationNode **r_prev_anim, float p_time, bool p_seek, float p_fallback_weight, HashMap<NodePath, float> *p_weights) { - - ERR_FAIL_COND_V(!node_map.has(p_node), 0); - NodeBase *nb = node_map[p_node]; - - //transform to seconds... - - switch (nb->type) { - - case NODE_OUTPUT: { - - NodeOut *on = static_cast<NodeOut *>(nb); - HashMap<NodePath, float> weights; - - return _process_node(on->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, &weights); - - } break; - case NODE_ANIMATION: { - - AnimationNode *an = static_cast<AnimationNode *>(nb); - - float rem = 0; - if (!an->animation.is_null()) { - - //float pos = an->time; - //float delta = p_time; - - //const Animation *a = an->animation.operator->(); - - if (p_seek) { - an->time = p_time; - an->step = 0; - } else { - an->time = MAX(0, an->time + p_time); - an->step = p_time; - } - - float anim_size = an->animation->get_length(); - - if (an->animation->has_loop()) { - - if (anim_size) - an->time = Math::fposmod(an->time, anim_size); - - } else if (an->time > anim_size) { - - an->time = anim_size; - } - - an->skip = true; - - for (List<AnimationNode::TrackRef>::Element *E = an->tref.front(); E; E = E->next()) { - NodePath track_path = an->animation->track_get_path(E->get().local_track); - if (an->filter.has(track_path) && an->filter[track_path]) { - E->get().weight = 0; - } else { - if (p_weights->has(track_path)) { - float weight = (*p_weights)[track_path]; - E->get().weight = weight; - } else { - E->get().weight = p_fallback_weight; - } - } - if (E->get().weight > CMP_EPSILON) - an->skip = false; - } - - rem = anim_size - an->time; - } - - if (!(*r_prev_anim)) - active_list = an; - else - (*r_prev_anim)->next = an; - - an->next = NULL; - *r_prev_anim = an; - - return rem; - - } break; - case NODE_ONESHOT: { - - OneShotNode *osn = static_cast<OneShotNode *>(nb); - - if (!osn->active) { - //make it as if this node doesn't exist, pass input 0 by. - return _process_node(osn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - } - - bool os_seek = p_seek; - - if (p_seek) - osn->time = p_time; - if (osn->start) { - osn->time = 0; - os_seek = true; - } - - float blend; - - if (osn->time < osn->fade_in) { - - if (osn->fade_in > 0) - blend = osn->time / osn->fade_in; - else - blend = 0; //wtf - - } else if (!osn->start && osn->remaining < osn->fade_out) { - - if (osn->fade_out) - blend = (osn->remaining / osn->fade_out); - else - blend = 1.0; - } else - blend = 1.0; - - float main_rem; - float os_rem; - - HashMap<NodePath, float> os_weights(*p_weights); - float os_fallback_weight = p_fallback_weight; - _compute_weights(&p_fallback_weight, p_weights, osn->mix ? 1.0 : 1.0 - blend, &osn->filter, 1.0); - _compute_weights(&os_fallback_weight, &os_weights, blend, &osn->filter, 0.0); - - main_rem = _process_node(osn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - os_rem = _process_node(osn->inputs[1].node, r_prev_anim, p_time, os_seek, os_fallback_weight, &os_weights); - - if (osn->start) { - osn->remaining = os_rem; - osn->start = false; - } - - if (!p_seek) { - osn->time += p_time; - osn->remaining = os_rem; - if (osn->remaining <= 0) - osn->active = false; - } - - return MAX(main_rem, osn->remaining); - } break; - case NODE_MIX: { - MixNode *mn = static_cast<MixNode *>(nb); - - HashMap<NodePath, float> mn_weights(*p_weights); - float mn_fallback_weight = p_fallback_weight; - _compute_weights(&mn_fallback_weight, &mn_weights, mn->amount); - float rem = _process_node(mn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - _process_node(mn->inputs[1].node, r_prev_anim, p_time, p_seek, mn_fallback_weight, &mn_weights); - return rem; - - } break; - case NODE_BLEND2: { - - Blend2Node *bn = static_cast<Blend2Node *>(nb); - - HashMap<NodePath, float> bn_weights(*p_weights); - float bn_fallback_weight = p_fallback_weight; - _compute_weights(&p_fallback_weight, p_weights, 1.0 - bn->value, &bn->filter, 1.0); - _compute_weights(&bn_fallback_weight, &bn_weights, bn->value, &bn->filter, 0.0); - float rem = _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, bn_fallback_weight, &bn_weights); - - return rem; - } break; - case NODE_BLEND3: { - Blend3Node *bn = static_cast<Blend3Node *>(nb); - - float rem; - float blend, lower_blend, upper_blend; - if (bn->value < 0) { - lower_blend = -bn->value; - blend = 1.0 - lower_blend; - upper_blend = 0; - } else { - lower_blend = 0; - blend = 1.0 - bn->value; - upper_blend = bn->value; - } - - HashMap<NodePath, float> upper_weights(*p_weights); - float upper_fallback_weight = p_fallback_weight; - HashMap<NodePath, float> lower_weights(*p_weights); - float lower_fallback_weight = p_fallback_weight; - _compute_weights(&upper_fallback_weight, &upper_weights, upper_blend); - _compute_weights(&p_fallback_weight, p_weights, blend); - _compute_weights(&lower_fallback_weight, &lower_weights, lower_blend); - - rem = _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, lower_fallback_weight, &lower_weights); - _process_node(bn->inputs[2].node, r_prev_anim, p_time, p_seek, upper_fallback_weight, &upper_weights); - - return rem; - } break; - case NODE_BLEND4: { - Blend4Node *bn = static_cast<Blend4Node *>(nb); - - HashMap<NodePath, float> weights1(*p_weights); - float fallback_weight1 = p_fallback_weight; - HashMap<NodePath, float> weights2(*p_weights); - float fallback_weight2 = p_fallback_weight; - HashMap<NodePath, float> weights3(*p_weights); - float fallback_weight3 = p_fallback_weight; - - _compute_weights(&p_fallback_weight, p_weights, 1.0 - bn->value.x); - _compute_weights(&fallback_weight1, &weights1, bn->value.x); - _compute_weights(&fallback_weight2, &weights2, 1.0 - bn->value.y); - _compute_weights(&fallback_weight3, &weights3, bn->value.y); - - float rem = _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, fallback_weight1, &weights1); - float rem2 = _process_node(bn->inputs[2].node, r_prev_anim, p_time, p_seek, fallback_weight2, &weights2); - _process_node(bn->inputs[3].node, r_prev_anim, p_time, p_seek, fallback_weight3, &weights3); - - return MAX(rem, rem2); - - } break; - case NODE_TIMESCALE: { - TimeScaleNode *tsn = static_cast<TimeScaleNode *>(nb); - float rem; - if (p_seek) - rem = _process_node(tsn->inputs[0].node, r_prev_anim, p_time, true, p_fallback_weight, p_weights); - else - rem = _process_node(tsn->inputs[0].node, r_prev_anim, p_time * tsn->scale, false, p_fallback_weight, p_weights); - if (tsn->scale == 0) - return Math_INF; - else - return rem / tsn->scale; - - } break; - case NODE_TIMESEEK: { - - TimeSeekNode *tsn = static_cast<TimeSeekNode *>(nb); - if (tsn->seek_pos >= 0 && !p_seek) { - - p_time = tsn->seek_pos; - p_seek = true; - } - tsn->seek_pos = -1; - - return _process_node(tsn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - - } break; - case NODE_TRANSITION: { - - TransitionNode *tn = static_cast<TransitionNode *>(nb); - HashMap<NodePath, float> prev_weights(*p_weights); - float prev_fallback_weight = p_fallback_weight; - - if (tn->prev < 0) { // process current animation, check for transition - - float rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - if (p_seek) - tn->time = p_time; - else - tn->time += p_time; - - if (tn->input_data[tn->current].auto_advance && rem <= tn->xfade) { - - tn->set_current((tn->current + 1) % tn->inputs.size()); - } - - return rem; - } else { // cross-fading from tn->prev to tn->current - - float blend = tn->xfade ? (tn->prev_xfading / tn->xfade) : 1; - - float rem; - - _compute_weights(&p_fallback_weight, p_weights, 1.0 - blend); - _compute_weights(&prev_fallback_weight, &prev_weights, blend); - - if (!p_seek && tn->switched) { //just switched, seek to start of current - - rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, 0, true, p_fallback_weight, p_weights); - } else { - - rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - } - - tn->switched = false; - - if (p_seek) { // don't seek prev animation - _process_node(tn->inputs[tn->prev].node, r_prev_anim, 0, false, prev_fallback_weight, &prev_weights); - tn->time = p_time; - } else { - _process_node(tn->inputs[tn->prev].node, r_prev_anim, p_time, false, prev_fallback_weight, &prev_weights); - tn->time += p_time; - tn->prev_xfading -= p_time; - if (tn->prev_xfading < 0) { - - tn->prev = -1; - } - } - - return rem; - } - - } break; - default: { - } - } - - return 0; -} - -void AnimationTreePlayer::_process_animation(float p_delta) { - - if (last_error != CONNECT_OK) - return; - - if (dirty_caches) - _recompute_caches(); - - active_list = NULL; - AnimationNode *prev = NULL; - - if (reset_request) { - - _process_node(out_name, &prev, 0, true); - reset_request = false; - } else - _process_node(out_name, &prev, p_delta); - - if (dirty_caches) { - //some animation changed.. ignore this pass - return; - } - - //update the tracks.. - - /* STEP 1 CLEAR TRACKS */ - - for (TrackMap::Element *E = track_map.front(); E; E = E->next()) { - - Track &t = E->get(); - - t.loc.zero(); - t.rot = Quat(); - t.scale.x = 0; - t.scale.y = 0; - t.scale.z = 0; - - t.value = t.object->get_indexed(t.subpath); - t.value.zero(); - - t.skip = false; - } - - /* STEP 2 PROCESS ANIMATIONS */ - - AnimationNode *anim_list = active_list; - Quat empty_rot; - - while (anim_list) { - - if (!anim_list->animation.is_null() && !anim_list->skip) { - //check if animation is meaningful - Animation *a = anim_list->animation.operator->(); - - for (List<AnimationNode::TrackRef>::Element *E = anim_list->tref.front(); E; E = E->next()) { - - AnimationNode::TrackRef &tr = E->get(); - if (tr.track == NULL || tr.local_track < 0 || tr.weight < CMP_EPSILON || !a->track_is_enabled(tr.local_track)) - continue; - - switch (a->track_get_type(tr.local_track)) { - case Animation::TYPE_TRANSFORM: { ///< Transform a node or a bone. - - Vector3 loc; - Quat rot; - Vector3 scale; - a->transform_track_interpolate(tr.local_track, anim_list->time, &loc, &rot, &scale); - - tr.track->loc += loc * tr.weight; - - scale.x -= 1.0; - scale.y -= 1.0; - scale.z -= 1.0; - tr.track->scale += scale * tr.weight; - - tr.track->rot = tr.track->rot * empty_rot.slerp(rot, tr.weight); - - } break; - case Animation::TYPE_VALUE: { ///< Set a value in a property, can be interpolated. - - if (a->value_track_get_update_mode(tr.local_track) == Animation::UPDATE_CONTINUOUS) { - Variant value = a->value_track_interpolate(tr.local_track, anim_list->time); - Variant::blend(tr.track->value, value, tr.weight, tr.track->value); - } else { - int index = a->track_find_key(tr.local_track, anim_list->time); - tr.track->value = a->track_get_key_value(tr.local_track, index); - } - } break; - case Animation::TYPE_METHOD: { ///< Call any method on a specific node. - - List<int> indices; - a->method_track_get_key_indices(tr.local_track, anim_list->time, anim_list->step, &indices); - for (List<int>::Element *F = indices.front(); F; F = F->next()) { - - StringName method = a->method_track_get_name(tr.local_track, F->get()); - Vector<Variant> args = a->method_track_get_params(tr.local_track, F->get()); - args.resize(VARIANT_ARG_MAX); - tr.track->object->call(method, args[0], args[1], args[2], args[3], args[4]); - } - } break; - default: { - } - } - } - } - - anim_list = anim_list->next; - } - - /* STEP 3 APPLY TRACKS */ - - for (TrackMap::Element *E = track_map.front(); E; E = E->next()) { - - Track &t = E->get(); - - if (t.skip || !t.object) - continue; - - if (t.subpath.size()) { // value track - t.object->set_indexed(t.subpath, t.value); - continue; - } - - Transform xform; - xform.origin = t.loc; - - t.scale.x += 1.0; - t.scale.y += 1.0; - t.scale.z += 1.0; - xform.basis.set_quat_scale(t.rot, t.scale); - - if (t.bone_idx >= 0) { - if (t.skeleton) - t.skeleton->set_bone_pose(t.bone_idx, xform); - - } else if (t.spatial) { - - t.spatial->set_transform(xform); - } - } -} - -void AnimationTreePlayer::add_node(NodeType p_type, const StringName &p_node) { - - ERR_FAIL_COND(p_type == NODE_OUTPUT); - ERR_FAIL_COND(node_map.has(p_node)); - - NodeBase *n = NULL; - - switch (p_type) { - - case NODE_ANIMATION: { - - n = memnew(AnimationNode); - } break; - case NODE_ONESHOT: { - - n = memnew(OneShotNode); - - } break; - case NODE_MIX: { - n = memnew(MixNode); - - } break; - case NODE_BLEND2: { - n = memnew(Blend2Node); - - } break; - case NODE_BLEND3: { - n = memnew(Blend3Node); - - } break; - case NODE_BLEND4: { - n = memnew(Blend4Node); - - } break; - case NODE_TIMESCALE: { - n = memnew(TimeScaleNode); - - } break; - case NODE_TIMESEEK: { - n = memnew(TimeSeekNode); - - } break; - case NODE_TRANSITION: { - n = memnew(TransitionNode); - - } break; - default: { - } - } - - //n->name+=" "+itos(p_node); - node_map[p_node] = n; -} - -StringName AnimationTreePlayer::node_get_input_source(const StringName &p_node, int p_input) const { - - ERR_FAIL_COND_V(!node_map.has(p_node), StringName()); - ERR_FAIL_INDEX_V(p_input, node_map[p_node]->inputs.size(), StringName()); - return node_map[p_node]->inputs[p_input].node; -} - -int AnimationTreePlayer::node_get_input_count(const StringName &p_node) const { - - ERR_FAIL_COND_V(!node_map.has(p_node), -1); - return node_map[p_node]->inputs.size(); -} -#define GET_NODE(m_type, m_cast) \ - ERR_FAIL_COND(!node_map.has(p_node)); \ - ERR_FAIL_COND_MSG(node_map[p_node]->type != m_type, "Invalid parameter for node type."); \ - m_cast *n = static_cast<m_cast *>(node_map[p_node]); - -void AnimationTreePlayer::animation_node_set_animation(const StringName &p_node, const Ref<Animation> &p_animation) { - - GET_NODE(NODE_ANIMATION, AnimationNode); - n->animation = p_animation; - dirty_caches = true; -} - -void AnimationTreePlayer::animation_node_set_master_animation(const StringName &p_node, const String &p_master_animation) { - - GET_NODE(NODE_ANIMATION, AnimationNode); - n->from = p_master_animation; - dirty_caches = true; - if (master != NodePath()) - _update_sources(); -} - -void AnimationTreePlayer::animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter) { - - GET_NODE(NODE_ANIMATION, AnimationNode); - - if (p_filter) - n->filter[p_track_path] = true; - else - n->filter.erase(p_track_path); -} - -void AnimationTreePlayer::animation_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const { - - GET_NODE(NODE_ANIMATION, AnimationNode); - - n->filter.get_key_list(r_paths); -} - -void AnimationTreePlayer::oneshot_node_set_fadein_time(const StringName &p_node, float p_time) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->fade_in = p_time; -} - -void AnimationTreePlayer::oneshot_node_set_fadeout_time(const StringName &p_node, float p_time) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->fade_out = p_time; -} - -void AnimationTreePlayer::oneshot_node_set_mix_mode(const StringName &p_node, bool p_mix) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->mix = p_mix; -} - -void AnimationTreePlayer::oneshot_node_set_autorestart(const StringName &p_node, bool p_active) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->autorestart = p_active; -} - -void AnimationTreePlayer::oneshot_node_set_autorestart_delay(const StringName &p_node, float p_time) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->autorestart_delay = p_time; -} -void AnimationTreePlayer::oneshot_node_set_autorestart_random_delay(const StringName &p_node, float p_time) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->autorestart_random_delay = p_time; -} - -void AnimationTreePlayer::oneshot_node_start(const StringName &p_node) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->active = true; - n->start = true; -} - -void AnimationTreePlayer::oneshot_node_stop(const StringName &p_node) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->active = false; -} - -void AnimationTreePlayer::oneshot_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - - if (p_enable) - n->filter[p_filter] = true; - else - n->filter.erase(p_filter); -} - -void AnimationTreePlayer::oneshot_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const { - - GET_NODE(NODE_ONESHOT, OneShotNode); - - n->filter.get_key_list(r_paths); -} - -void AnimationTreePlayer::mix_node_set_amount(const StringName &p_node, float p_amount) { - - GET_NODE(NODE_MIX, MixNode); - n->amount = p_amount; -} - -void AnimationTreePlayer::blend2_node_set_amount(const StringName &p_node, float p_amount) { - - GET_NODE(NODE_BLEND2, Blend2Node); - n->value = p_amount; -} - -void AnimationTreePlayer::blend2_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable) { - - GET_NODE(NODE_BLEND2, Blend2Node); - - if (p_enable) - n->filter[p_filter] = true; - else - n->filter.erase(p_filter); -} - -void AnimationTreePlayer::blend2_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const { - - GET_NODE(NODE_BLEND2, Blend2Node); - - n->filter.get_key_list(r_paths); -} - -void AnimationTreePlayer::blend3_node_set_amount(const StringName &p_node, float p_amount) { - - GET_NODE(NODE_BLEND3, Blend3Node); - n->value = p_amount; -} -void AnimationTreePlayer::blend4_node_set_amount(const StringName &p_node, const Vector2 &p_amount) { - - GET_NODE(NODE_BLEND4, Blend4Node); - n->value = p_amount; -} -void AnimationTreePlayer::timescale_node_set_scale(const StringName &p_node, float p_scale) { - - GET_NODE(NODE_TIMESCALE, TimeScaleNode); - n->scale = p_scale; -} -void AnimationTreePlayer::timeseek_node_seek(const StringName &p_node, float p_pos) { - - GET_NODE(NODE_TIMESEEK, TimeSeekNode); - n->seek_pos = p_pos; -} -void AnimationTreePlayer::transition_node_set_input_count(const StringName &p_node, int p_inputs) { - - GET_NODE(NODE_TRANSITION, TransitionNode); - ERR_FAIL_COND(p_inputs < 1); - - n->inputs.resize(p_inputs); - n->input_data.resize(p_inputs); - - _clear_cycle_test(); - - last_error = _cycle_test(out_name); -} -void AnimationTreePlayer::transition_node_set_input_auto_advance(const StringName &p_node, int p_input, bool p_auto_advance) { - - GET_NODE(NODE_TRANSITION, TransitionNode); - ERR_FAIL_INDEX(p_input, n->input_data.size()); - - n->input_data.write[p_input].auto_advance = p_auto_advance; -} -void AnimationTreePlayer::transition_node_set_xfade_time(const StringName &p_node, float p_time) { - - GET_NODE(NODE_TRANSITION, TransitionNode); - n->xfade = p_time; -} - -void AnimationTreePlayer::TransitionNode::set_current(int p_current) { - - ERR_FAIL_INDEX(p_current, inputs.size()); - - if (current == p_current) - return; - - prev = current; - prev_xfading = xfade; - prev_time = time; - time = 0; - current = p_current; - switched = true; -} - -void AnimationTreePlayer::transition_node_set_current(const StringName &p_node, int p_current) { - - GET_NODE(NODE_TRANSITION, TransitionNode); - n->set_current(p_current); -} - -void AnimationTreePlayer::node_set_position(const StringName &p_node, const Vector2 &p_pos) { - - ERR_FAIL_COND(!node_map.has(p_node)); - node_map[p_node]->pos = p_pos; -} - -AnimationTreePlayer::NodeType AnimationTreePlayer::node_get_type(const StringName &p_node) const { - - ERR_FAIL_COND_V(!node_map.has(p_node), NODE_OUTPUT); - return node_map[p_node]->type; -} -Point2 AnimationTreePlayer::node_get_position(const StringName &p_node) const { - - ERR_FAIL_COND_V(!node_map.has(p_node), Point2()); - return node_map[p_node]->pos; -} - -#define GET_NODE_V(m_type, m_cast, m_ret) \ - ERR_FAIL_COND_V(!node_map.has(p_node), m_ret); \ - ERR_FAIL_COND_V_MSG(node_map[p_node]->type != m_type, m_ret, "Invalid parameter for node type."); \ - m_cast *n = static_cast<m_cast *>(node_map[p_node]); - -Ref<Animation> AnimationTreePlayer::animation_node_get_animation(const StringName &p_node) const { - - GET_NODE_V(NODE_ANIMATION, AnimationNode, Ref<Animation>()); - return n->animation; -} - -String AnimationTreePlayer::animation_node_get_master_animation(const StringName &p_node) const { - - GET_NODE_V(NODE_ANIMATION, AnimationNode, String()); - return n->from; -} - -float AnimationTreePlayer::animation_node_get_position(const StringName &p_node) const { - - GET_NODE_V(NODE_ANIMATION, AnimationNode, 0); - return n->time; -} - -bool AnimationTreePlayer::animation_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const { - - GET_NODE_V(NODE_ANIMATION, AnimationNode, 0); - return n->filter.has(p_path); -} - -float AnimationTreePlayer::oneshot_node_get_fadein_time(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->fade_in; -} - -float AnimationTreePlayer::oneshot_node_get_fadeout_time(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->fade_out; -} - -bool AnimationTreePlayer::oneshot_node_get_mix_mode(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->mix; -} -bool AnimationTreePlayer::oneshot_node_has_autorestart(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->autorestart; -} -float AnimationTreePlayer::oneshot_node_get_autorestart_delay(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->autorestart_delay; -} -float AnimationTreePlayer::oneshot_node_get_autorestart_random_delay(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->autorestart_random_delay; -} - -bool AnimationTreePlayer::oneshot_node_is_active(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->active; -} - -bool AnimationTreePlayer::oneshot_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->filter.has(p_path); -} - -float AnimationTreePlayer::mix_node_get_amount(const StringName &p_node) const { - - GET_NODE_V(NODE_MIX, MixNode, 0); - return n->amount; -} -float AnimationTreePlayer::blend2_node_get_amount(const StringName &p_node) const { - - GET_NODE_V(NODE_BLEND2, Blend2Node, 0); - return n->value; -} - -bool AnimationTreePlayer::blend2_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const { - - GET_NODE_V(NODE_BLEND2, Blend2Node, 0); - return n->filter.has(p_path); -} - -float AnimationTreePlayer::blend3_node_get_amount(const StringName &p_node) const { - - GET_NODE_V(NODE_BLEND3, Blend3Node, 0); - return n->value; -} -Vector2 AnimationTreePlayer::blend4_node_get_amount(const StringName &p_node) const { - - GET_NODE_V(NODE_BLEND4, Blend4Node, Vector2()); - return n->value; -} - -float AnimationTreePlayer::timescale_node_get_scale(const StringName &p_node) const { - - GET_NODE_V(NODE_TIMESCALE, TimeScaleNode, 0); - return n->scale; -} - -void AnimationTreePlayer::transition_node_delete_input(const StringName &p_node, int p_input) { - - GET_NODE(NODE_TRANSITION, TransitionNode); - ERR_FAIL_INDEX(p_input, n->inputs.size()); - - if (n->inputs.size() <= 1) - return; - - n->inputs.remove(p_input); - n->input_data.remove(p_input); - last_error = _cycle_test(out_name); -} - -int AnimationTreePlayer::transition_node_get_input_count(const StringName &p_node) const { - - GET_NODE_V(NODE_TRANSITION, TransitionNode, 0); - return n->inputs.size(); -} - -bool AnimationTreePlayer::transition_node_has_input_auto_advance(const StringName &p_node, int p_input) const { - - GET_NODE_V(NODE_TRANSITION, TransitionNode, false); - ERR_FAIL_INDEX_V(p_input, n->inputs.size(), false); - return n->input_data[p_input].auto_advance; -} -float AnimationTreePlayer::transition_node_get_xfade_time(const StringName &p_node) const { - - GET_NODE_V(NODE_TRANSITION, TransitionNode, 0); - return n->xfade; -} - -int AnimationTreePlayer::transition_node_get_current(const StringName &p_node) const { - - GET_NODE_V(NODE_TRANSITION, TransitionNode, -1); - return n->current; -} - -/*misc */ -void AnimationTreePlayer::get_node_list(List<StringName> *p_node_list) const { - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - p_node_list->push_back(E->key()); - } -} - -void AnimationTreePlayer::remove_node(const StringName &p_node) { - - ERR_FAIL_COND(!node_map.has(p_node)); - ERR_FAIL_COND_MSG(p_node == out_name, "Node 0 (output) can't be removed."); - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - NodeBase *nb = E->get(); - for (int i = 0; i < nb->inputs.size(); i++) { - - if (nb->inputs[i].node == p_node) - nb->inputs.write[i].node = StringName(); - } - } - - node_map.erase(p_node); - - _clear_cycle_test(); - - // compute last error again, just in case - last_error = _cycle_test(out_name); - dirty_caches = true; -} - -AnimationTreePlayer::ConnectError AnimationTreePlayer::_cycle_test(const StringName &p_at_node) { - - ERR_FAIL_COND_V(!node_map.has(p_at_node), CONNECT_INCOMPLETE); - - NodeBase *nb = node_map[p_at_node]; - if (nb->cycletest) - return CONNECT_CYCLE; - - nb->cycletest = true; - - for (int i = 0; i < nb->inputs.size(); i++) { - if (nb->inputs[i].node == StringName()) - return CONNECT_INCOMPLETE; - - ConnectError _err = _cycle_test(nb->inputs[i].node); - if (_err) - return _err; - } - - return CONNECT_OK; -} - -// Use this function to not alter next complete _cycle_test(). -void AnimationTreePlayer::_clear_cycle_test() { - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - NodeBase *nb = E->get(); - nb->cycletest = false; - } -} - -Error AnimationTreePlayer::connect_nodes(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) { - - ERR_FAIL_COND_V(!node_map.has(p_src_node), ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(!node_map.has(p_dst_node), ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(p_src_node == p_dst_node, ERR_INVALID_PARAMETER); - - //NodeBase *src = node_map[p_src_node]; - NodeBase *dst = node_map[p_dst_node]; - ERR_FAIL_INDEX_V(p_dst_input, dst->inputs.size(), ERR_INVALID_PARAMETER); - - //int oldval = dst->inputs[p_dst_input].node; - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - NodeBase *nb = E->get(); - for (int i = 0; i < nb->inputs.size(); i++) { - - if (nb->inputs[i].node == p_src_node) - nb->inputs.write[i].node = StringName(); - } - } - - dst->inputs.write[p_dst_input].node = p_src_node; - - _clear_cycle_test(); - - last_error = _cycle_test(out_name); - if (last_error) { - - if (last_error == CONNECT_INCOMPLETE) - return ERR_UNCONFIGURED; - else if (last_error == CONNECT_CYCLE) - return ERR_CYCLIC_LINK; - } - dirty_caches = true; - return OK; -} - -bool AnimationTreePlayer::are_nodes_connected(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) const { - - ERR_FAIL_COND_V(!node_map.has(p_src_node), false); - ERR_FAIL_COND_V(!node_map.has(p_dst_node), false); - ERR_FAIL_COND_V(p_src_node == p_dst_node, false); - - NodeBase *dst = node_map[p_dst_node]; - - return dst->inputs[p_dst_input].node == p_src_node; -} - -void AnimationTreePlayer::disconnect_nodes(const StringName &p_node, int p_input) { - - ERR_FAIL_COND(!node_map.has(p_node)); - - NodeBase *dst = node_map[p_node]; - ERR_FAIL_INDEX(p_input, dst->inputs.size()); - dst->inputs.write[p_input].node = StringName(); - last_error = CONNECT_INCOMPLETE; - dirty_caches = true; -} - -void AnimationTreePlayer::get_connection_list(List<Connection> *p_connections) const { - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - NodeBase *nb = E->get(); - for (int i = 0; i < nb->inputs.size(); i++) { - - if (nb->inputs[i].node != StringName()) { - Connection c; - c.src_node = nb->inputs[i].node; - c.dst_node = E->key(); - c.dst_input = i; - p_connections->push_back(c); - } - } - } -} - -AnimationTreePlayer::Track *AnimationTreePlayer::_find_track(const NodePath &p_path) { - - Node *parent = get_node(base_path); - ERR_FAIL_COND_V(!parent, NULL); - - RES resource; - Vector<StringName> leftover_path; - Node *child = parent->get_node_and_resource(p_path, resource, leftover_path); - if (!child) { - String err = "Animation track references unknown Node: '" + String(p_path) + "'."; - WARN_PRINT(err.ascii().get_data()); - return NULL; - } - - ObjectID id = child->get_instance_id(); - int bone_idx = -1; - - if (p_path.get_subname_count()) { - - if (Object::cast_to<Skeleton>(child)) - bone_idx = Object::cast_to<Skeleton>(child)->find_bone(p_path.get_subname(0)); - } - - TrackKey key; - key.id = id; - key.bone_idx = bone_idx; - key.subpath_concatenated = p_path.get_concatenated_subnames(); - - if (!track_map.has(key)) { - - Track tr; - tr.id = id; - tr.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child; - tr.skeleton = Object::cast_to<Skeleton>(child); - tr.spatial = Object::cast_to<Spatial>(child); - tr.bone_idx = bone_idx; - if (bone_idx == -1) tr.subpath = leftover_path; - - track_map[key] = tr; - } - - return &track_map[key]; -} - -void AnimationTreePlayer::_recompute_caches() { - - track_map.clear(); - _recompute_caches(out_name); - dirty_caches = false; -} - -void AnimationTreePlayer::_recompute_caches(const StringName &p_node) { - - ERR_FAIL_COND(!node_map.has(p_node)); - - NodeBase *nb = node_map[p_node]; - - if (nb->type == NODE_ANIMATION) { - - AnimationNode *an = static_cast<AnimationNode *>(nb); - an->tref.clear(); - - if (!an->animation.is_null()) { - - Ref<Animation> a = an->animation; - - for (int i = 0; i < an->animation->get_track_count(); i++) { - - Track *tr = _find_track(a->track_get_path(i)); - if (!tr) - continue; - - AnimationNode::TrackRef tref; - tref.local_track = i; - tref.track = tr; - tref.weight = 0; - - an->tref.push_back(tref); - } - } - } - - for (int i = 0; i < nb->inputs.size(); i++) { - - _recompute_caches(nb->inputs[i].node); - } -} - -void AnimationTreePlayer::recompute_caches() { - - dirty_caches = true; -} - -/* playback */ - -void AnimationTreePlayer::set_active(bool p_active) { - - if (active == p_active) - return; - - active = p_active; - processing = active; - reset_request = p_active; - _set_process(processing, true); -} - -bool AnimationTreePlayer::is_active() const { - - return active; -} - -AnimationTreePlayer::ConnectError AnimationTreePlayer::get_last_error() const { - - return last_error; -} - -void AnimationTreePlayer::reset() { - - reset_request = true; -} - -void AnimationTreePlayer::set_base_path(const NodePath &p_path) { - - base_path = p_path; - recompute_caches(); -} - -NodePath AnimationTreePlayer::get_base_path() const { - - return base_path; -} - -void AnimationTreePlayer::set_master_player(const NodePath &p_path) { - - if (p_path == master) - return; - - master = p_path; - _update_sources(); - recompute_caches(); -} - -NodePath AnimationTreePlayer::get_master_player() const { - - return master; -} - -PoolVector<String> AnimationTreePlayer::_get_node_list() { - - List<StringName> nl; - get_node_list(&nl); - PoolVector<String> ret; - ret.resize(nl.size()); - int idx = 0; - for (List<StringName>::Element *E = nl.front(); E; E = E->next()) { - ret.set(idx++, E->get()); - } - - return ret; -} - -void AnimationTreePlayer::_update_sources() { - - if (master == NodePath()) - return; - if (!is_inside_tree()) - return; - - Node *m = get_node(master); - if (!m) { - master = NodePath(); - ERR_FAIL_COND(!m); - } - - AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(m); - - if (!ap) { - - master = NodePath(); - ERR_FAIL_COND(!ap); - } - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - if (E->get()->type == NODE_ANIMATION) { - - AnimationNode *an = static_cast<AnimationNode *>(E->get()); - - if (an->from != "") { - - an->animation = ap->get_animation(an->from); - } - } - } -} - -bool AnimationTreePlayer::node_exists(const StringName &p_name) const { - - return (node_map.has(p_name)); -} - -Error AnimationTreePlayer::node_rename(const StringName &p_node, const StringName &p_new_name) { - - if (p_new_name == p_node) - return OK; - ERR_FAIL_COND_V(!node_map.has(p_node), ERR_ALREADY_EXISTS); - ERR_FAIL_COND_V(node_map.has(p_new_name), ERR_ALREADY_EXISTS); - ERR_FAIL_COND_V(p_new_name == StringName(), ERR_INVALID_DATA); - ERR_FAIL_COND_V(p_node == out_name, ERR_INVALID_DATA); - ERR_FAIL_COND_V(p_new_name == out_name, ERR_INVALID_DATA); - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - NodeBase *nb = E->get(); - for (int i = 0; i < nb->inputs.size(); i++) { - - if (nb->inputs[i].node == p_node) { - nb->inputs.write[i].node = p_new_name; - } - } - } - - node_map[p_new_name] = node_map[p_node]; - node_map.erase(p_node); - - return OK; -} - -String AnimationTreePlayer::get_configuration_warning() const { - - return TTR("This node has been deprecated. Use AnimationTree instead."); -} - -void AnimationTreePlayer::_bind_methods() { - - ClassDB::bind_method(D_METHOD("add_node", "type", "id"), &AnimationTreePlayer::add_node); - - ClassDB::bind_method(D_METHOD("node_exists", "node"), &AnimationTreePlayer::node_exists); - ClassDB::bind_method(D_METHOD("node_rename", "node", "new_name"), &AnimationTreePlayer::node_rename); - - ClassDB::bind_method(D_METHOD("node_get_type", "id"), &AnimationTreePlayer::node_get_type); - ClassDB::bind_method(D_METHOD("node_get_input_count", "id"), &AnimationTreePlayer::node_get_input_count); - ClassDB::bind_method(D_METHOD("node_get_input_source", "id", "idx"), &AnimationTreePlayer::node_get_input_source); - - ClassDB::bind_method(D_METHOD("animation_node_set_animation", "id", "animation"), &AnimationTreePlayer::animation_node_set_animation); - ClassDB::bind_method(D_METHOD("animation_node_get_animation", "id"), &AnimationTreePlayer::animation_node_get_animation); - - ClassDB::bind_method(D_METHOD("animation_node_set_master_animation", "id", "source"), &AnimationTreePlayer::animation_node_set_master_animation); - ClassDB::bind_method(D_METHOD("animation_node_get_master_animation", "id"), &AnimationTreePlayer::animation_node_get_master_animation); - ClassDB::bind_method(D_METHOD("animation_node_get_position", "id"), &AnimationTreePlayer::animation_node_get_position); - ClassDB::bind_method(D_METHOD("animation_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::animation_node_set_filter_path); - - ClassDB::bind_method(D_METHOD("oneshot_node_set_fadein_time", "id", "time_sec"), &AnimationTreePlayer::oneshot_node_set_fadein_time); - ClassDB::bind_method(D_METHOD("oneshot_node_get_fadein_time", "id"), &AnimationTreePlayer::oneshot_node_get_fadein_time); - - ClassDB::bind_method(D_METHOD("oneshot_node_set_fadeout_time", "id", "time_sec"), &AnimationTreePlayer::oneshot_node_set_fadeout_time); - ClassDB::bind_method(D_METHOD("oneshot_node_get_fadeout_time", "id"), &AnimationTreePlayer::oneshot_node_get_fadeout_time); - - ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart", "id", "enable"), &AnimationTreePlayer::oneshot_node_set_autorestart); - ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart_delay", "id", "delay_sec"), &AnimationTreePlayer::oneshot_node_set_autorestart_delay); - ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart_random_delay", "id", "rand_sec"), &AnimationTreePlayer::oneshot_node_set_autorestart_random_delay); - - ClassDB::bind_method(D_METHOD("oneshot_node_has_autorestart", "id"), &AnimationTreePlayer::oneshot_node_has_autorestart); - ClassDB::bind_method(D_METHOD("oneshot_node_get_autorestart_delay", "id"), &AnimationTreePlayer::oneshot_node_get_autorestart_delay); - ClassDB::bind_method(D_METHOD("oneshot_node_get_autorestart_random_delay", "id"), &AnimationTreePlayer::oneshot_node_get_autorestart_random_delay); - - ClassDB::bind_method(D_METHOD("oneshot_node_start", "id"), &AnimationTreePlayer::oneshot_node_start); - ClassDB::bind_method(D_METHOD("oneshot_node_stop", "id"), &AnimationTreePlayer::oneshot_node_stop); - ClassDB::bind_method(D_METHOD("oneshot_node_is_active", "id"), &AnimationTreePlayer::oneshot_node_is_active); - ClassDB::bind_method(D_METHOD("oneshot_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::oneshot_node_set_filter_path); - - ClassDB::bind_method(D_METHOD("mix_node_set_amount", "id", "ratio"), &AnimationTreePlayer::mix_node_set_amount); - ClassDB::bind_method(D_METHOD("mix_node_get_amount", "id"), &AnimationTreePlayer::mix_node_get_amount); - - ClassDB::bind_method(D_METHOD("blend2_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend2_node_set_amount); - ClassDB::bind_method(D_METHOD("blend2_node_get_amount", "id"), &AnimationTreePlayer::blend2_node_get_amount); - ClassDB::bind_method(D_METHOD("blend2_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::blend2_node_set_filter_path); - - ClassDB::bind_method(D_METHOD("blend3_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend3_node_set_amount); - ClassDB::bind_method(D_METHOD("blend3_node_get_amount", "id"), &AnimationTreePlayer::blend3_node_get_amount); - - ClassDB::bind_method(D_METHOD("blend4_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend4_node_set_amount); - ClassDB::bind_method(D_METHOD("blend4_node_get_amount", "id"), &AnimationTreePlayer::blend4_node_get_amount); - - ClassDB::bind_method(D_METHOD("timescale_node_set_scale", "id", "scale"), &AnimationTreePlayer::timescale_node_set_scale); - ClassDB::bind_method(D_METHOD("timescale_node_get_scale", "id"), &AnimationTreePlayer::timescale_node_get_scale); - - ClassDB::bind_method(D_METHOD("timeseek_node_seek", "id", "seconds"), &AnimationTreePlayer::timeseek_node_seek); - - ClassDB::bind_method(D_METHOD("transition_node_set_input_count", "id", "count"), &AnimationTreePlayer::transition_node_set_input_count); - ClassDB::bind_method(D_METHOD("transition_node_get_input_count", "id"), &AnimationTreePlayer::transition_node_get_input_count); - ClassDB::bind_method(D_METHOD("transition_node_delete_input", "id", "input_idx"), &AnimationTreePlayer::transition_node_delete_input); - - ClassDB::bind_method(D_METHOD("transition_node_set_input_auto_advance", "id", "input_idx", "enable"), &AnimationTreePlayer::transition_node_set_input_auto_advance); - ClassDB::bind_method(D_METHOD("transition_node_has_input_auto_advance", "id", "input_idx"), &AnimationTreePlayer::transition_node_has_input_auto_advance); - - ClassDB::bind_method(D_METHOD("transition_node_set_xfade_time", "id", "time_sec"), &AnimationTreePlayer::transition_node_set_xfade_time); - ClassDB::bind_method(D_METHOD("transition_node_get_xfade_time", "id"), &AnimationTreePlayer::transition_node_get_xfade_time); - - ClassDB::bind_method(D_METHOD("transition_node_set_current", "id", "input_idx"), &AnimationTreePlayer::transition_node_set_current); - ClassDB::bind_method(D_METHOD("transition_node_get_current", "id"), &AnimationTreePlayer::transition_node_get_current); - - ClassDB::bind_method(D_METHOD("node_set_position", "id", "screen_position"), &AnimationTreePlayer::node_set_position); - ClassDB::bind_method(D_METHOD("node_get_position", "id"), &AnimationTreePlayer::node_get_position); - - ClassDB::bind_method(D_METHOD("remove_node", "id"), &AnimationTreePlayer::remove_node); - ClassDB::bind_method(D_METHOD("connect_nodes", "id", "dst_id", "dst_input_idx"), &AnimationTreePlayer::connect_nodes); - ClassDB::bind_method(D_METHOD("are_nodes_connected", "id", "dst_id", "dst_input_idx"), &AnimationTreePlayer::are_nodes_connected); - ClassDB::bind_method(D_METHOD("disconnect_nodes", "id", "dst_input_idx"), &AnimationTreePlayer::disconnect_nodes); - - ClassDB::bind_method(D_METHOD("set_active", "enabled"), &AnimationTreePlayer::set_active); - ClassDB::bind_method(D_METHOD("is_active"), &AnimationTreePlayer::is_active); - - ClassDB::bind_method(D_METHOD("set_base_path", "path"), &AnimationTreePlayer::set_base_path); - ClassDB::bind_method(D_METHOD("get_base_path"), &AnimationTreePlayer::get_base_path); - - ClassDB::bind_method(D_METHOD("set_master_player", "nodepath"), &AnimationTreePlayer::set_master_player); - ClassDB::bind_method(D_METHOD("get_master_player"), &AnimationTreePlayer::get_master_player); - - ClassDB::bind_method(D_METHOD("get_node_list"), &AnimationTreePlayer::_get_node_list); - - ClassDB::bind_method(D_METHOD("set_animation_process_mode", "mode"), &AnimationTreePlayer::set_animation_process_mode); - ClassDB::bind_method(D_METHOD("get_animation_process_mode"), &AnimationTreePlayer::get_animation_process_mode); - - ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTreePlayer::advance); - - ClassDB::bind_method(D_METHOD("reset"), &AnimationTreePlayer::reset); - - ClassDB::bind_method(D_METHOD("recompute_caches"), &AnimationTreePlayer::recompute_caches); - - ADD_GROUP("Playback", "playback_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode"); - - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "master_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_master_player", "get_master_player"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "base_path"), "set_base_path", "get_base_path"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active"); - - BIND_ENUM_CONSTANT(NODE_OUTPUT); - BIND_ENUM_CONSTANT(NODE_ANIMATION); - BIND_ENUM_CONSTANT(NODE_ONESHOT); - BIND_ENUM_CONSTANT(NODE_MIX); - BIND_ENUM_CONSTANT(NODE_BLEND2); - BIND_ENUM_CONSTANT(NODE_BLEND3); - BIND_ENUM_CONSTANT(NODE_BLEND4); - BIND_ENUM_CONSTANT(NODE_TIMESCALE); - BIND_ENUM_CONSTANT(NODE_TIMESEEK); - BIND_ENUM_CONSTANT(NODE_TRANSITION); - - BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS); - BIND_ENUM_CONSTANT(ANIMATION_PROCESS_IDLE); -} - -AnimationTreePlayer::AnimationTreePlayer() { - - active_list = NULL; - out = memnew(NodeOut); - out_name = "out"; - out->pos = Point2(40, 40); - node_map.insert(out_name, out); - animation_process_mode = ANIMATION_PROCESS_IDLE; - processing = false; - active = false; - dirty_caches = true; - reset_request = true; - last_error = CONNECT_INCOMPLETE; - base_path = String(".."); -} - -AnimationTreePlayer::~AnimationTreePlayer() { - - while (node_map.size()) { - memdelete(node_map.front()->get()); - node_map.erase(node_map.front()); - } -} diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h deleted file mode 100644 index e1f6ce7b9c..0000000000 --- a/scene/animation/animation_tree_player.h +++ /dev/null @@ -1,487 +0,0 @@ -/*************************************************************************/ -/* animation_tree_player.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef ANIMATION_TREE_PLAYER_H -#define ANIMATION_TREE_PLAYER_H - -#include "animation_player.h" -#include "scene/3d/skeleton.h" -#include "scene/3d/spatial.h" -#include "scene/resources/animation.h" - -class AnimationTreePlayer : public Node { - - GDCLASS(AnimationTreePlayer, Node); - OBJ_CATEGORY("Animation Nodes"); - -public: - enum AnimationProcessMode { - ANIMATION_PROCESS_PHYSICS, - ANIMATION_PROCESS_IDLE, - }; - - enum NodeType { - - NODE_OUTPUT, - NODE_ANIMATION, - NODE_ONESHOT, - NODE_MIX, - NODE_BLEND2, - NODE_BLEND3, - NODE_BLEND4, - NODE_TIMESCALE, - NODE_TIMESEEK, - NODE_TRANSITION, - - NODE_MAX, - }; - - enum ConnectError { - - CONNECT_OK, - CONNECT_INCOMPLETE, - CONNECT_CYCLE - }; - -private: - enum { - - DISCONNECTED = -1, - }; - - struct TrackKey { - - uint32_t id; - StringName subpath_concatenated; - int bone_idx; - - inline bool operator<(const TrackKey &p_right) const { - - if (id == p_right.id) { - if (bone_idx == p_right.bone_idx) { - return subpath_concatenated < p_right.subpath_concatenated; - } else - return bone_idx < p_right.bone_idx; - } else - return id < p_right.id; - } - }; - - struct Track { - uint32_t id; - Object *object; - Spatial *spatial; - Skeleton *skeleton; - int bone_idx; - Vector<StringName> subpath; - - Vector3 loc; - Quat rot; - Vector3 scale; - - Variant value; - - bool skip; - - Track() : - id(0), - object(NULL), - spatial(NULL), - skeleton(NULL), - bone_idx(-1), - skip(false) {} - }; - - typedef Map<TrackKey, Track> TrackMap; - - TrackMap track_map; - - struct Input { - - StringName node; - //Input() { node=-1; } - }; - - struct NodeBase { - - bool cycletest; - - NodeType type; - Point2 pos; - - Vector<Input> inputs; - - NodeBase() { cycletest = false; }; - virtual ~NodeBase() { cycletest = false; } - }; - - struct NodeOut : public NodeBase { - - NodeOut() { - type = NODE_OUTPUT; - inputs.resize(1); - } - }; - - struct AnimationNode : public NodeBase { - - Ref<Animation> animation; - - struct TrackRef { - int local_track; - Track *track; - float weight; - }; - - uint64_t last_version; - List<TrackRef> tref; - AnimationNode *next; - float time; - float step; - String from; - bool skip; - - HashMap<NodePath, bool> filter; - - AnimationNode() { - type = NODE_ANIMATION; - next = NULL; - last_version = 0; - skip = false; - } - }; - - struct OneShotNode : public NodeBase { - - bool active; - bool start; - float fade_in; - float fade_out; - - bool autorestart; - float autorestart_delay; - float autorestart_random_delay; - bool mix; - - float time; - float remaining; - float autorestart_remaining; - - HashMap<NodePath, bool> filter; - - OneShotNode() { - type = NODE_ONESHOT; - fade_in = 0; - fade_out = 0; - inputs.resize(2); - autorestart = false; - autorestart_delay = 1; - autorestart_remaining = 0; - mix = false; - active = false; - start = false; - } - }; - - struct MixNode : public NodeBase { - - float amount; - MixNode() { - type = NODE_MIX; - inputs.resize(2); - } - }; - - struct Blend2Node : public NodeBase { - - float value; - HashMap<NodePath, bool> filter; - Blend2Node() { - type = NODE_BLEND2; - value = 0; - inputs.resize(2); - } - }; - - struct Blend3Node : public NodeBase { - - float value; - Blend3Node() { - type = NODE_BLEND3; - value = 0; - inputs.resize(3); - } - }; - - struct Blend4Node : public NodeBase { - - Point2 value; - Blend4Node() { - type = NODE_BLEND4; - inputs.resize(4); - } - }; - - struct TimeScaleNode : public NodeBase { - - float scale; - TimeScaleNode() { - type = NODE_TIMESCALE; - scale = 1; - inputs.resize(1); - } - }; - - struct TimeSeekNode : public NodeBase { - - float seek_pos; - - TimeSeekNode() { - type = NODE_TIMESEEK; - inputs.resize(1); - seek_pos = -1; - } - }; - - struct TransitionNode : public NodeBase { - - struct InputData { - - bool auto_advance; - InputData() { auto_advance = false; } - }; - - Vector<InputData> input_data; - - float prev_time; - float prev_xfading; - int prev; - bool switched; - - float time; - int current; - - float xfade; - - TransitionNode() { - type = NODE_TRANSITION; - xfade = 0; - inputs.resize(1); - input_data.resize(1); - current = 0; - prev = -1; - prev_time = 0; - prev_xfading = 0; - switched = false; - } - void set_current(int p_current); - }; - - void _update_sources(); - - StringName out_name; - NodeOut *out; - - NodePath base_path; - NodePath master; - - ConnectError last_error; - AnimationNode *active_list; - AnimationProcessMode animation_process_mode; - bool processing; - bool active; - bool dirty_caches; - Map<StringName, NodeBase *> node_map; - - // return time left to finish animation - float _process_node(const StringName &p_node, AnimationNode **r_prev_anim, float p_time, bool p_seek = false, float p_fallback_weight = 1.0, HashMap<NodePath, float> *p_weights = NULL); - void _process_animation(float p_delta); - bool reset_request; - - ConnectError _cycle_test(const StringName &p_at_node); - void _clear_cycle_test(); - - Track *_find_track(const NodePath &p_path); - void _recompute_caches(); - void _recompute_caches(const StringName &p_node); - PoolVector<String> _get_node_list(); - - void _compute_weights(float *p_fallback_weight, HashMap<NodePath, float> *p_weights, float p_coeff, const HashMap<NodePath, bool> *p_filter = NULL, float p_filtered_coeff = 0); - -protected: - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; - void _notification(int p_what); - - static void _bind_methods(); - -public: - void add_node(NodeType p_type, const StringName &p_node); // nodes must be >0 node 0 is built-in (exit) - bool node_exists(const StringName &p_name) const; - - Error node_rename(const StringName &p_node, const StringName &p_new_name); - int node_get_input_count(const StringName &p_node) const; - StringName node_get_input_source(const StringName &p_node, int p_input) const; - - String get_configuration_warning() const; - - /* ANIMATION NODE */ - void animation_node_set_animation(const StringName &p_node, const Ref<Animation> &p_animation); - Ref<Animation> animation_node_get_animation(const StringName &p_node) const; - void animation_node_set_master_animation(const StringName &p_node, const String &p_master_animation); - String animation_node_get_master_animation(const StringName &p_node) const; - float animation_node_get_position(const StringName &p_node) const; - - void animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter); - void animation_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const; - bool animation_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const; - - /* ONE SHOT NODE */ - - void oneshot_node_set_fadein_time(const StringName &p_node, float p_time); - void oneshot_node_set_fadeout_time(const StringName &p_node, float p_time); - - float oneshot_node_get_fadein_time(const StringName &p_node) const; - float oneshot_node_get_fadeout_time(const StringName &p_node) const; - - void oneshot_node_set_autorestart(const StringName &p_node, bool p_active); - void oneshot_node_set_autorestart_delay(const StringName &p_node, float p_time); - void oneshot_node_set_autorestart_random_delay(const StringName &p_node, float p_time); - - bool oneshot_node_has_autorestart(const StringName &p_node) const; - float oneshot_node_get_autorestart_delay(const StringName &p_node) const; - float oneshot_node_get_autorestart_random_delay(const StringName &p_node) const; - - void oneshot_node_set_mix_mode(const StringName &p_node, bool p_mix); - bool oneshot_node_get_mix_mode(const StringName &p_node) const; - - void oneshot_node_start(const StringName &p_node); - void oneshot_node_stop(const StringName &p_node); - bool oneshot_node_is_active(const StringName &p_node) const; - - void oneshot_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable); - void oneshot_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const; - bool oneshot_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const; - - /* MIX/BLEND NODES */ - - void mix_node_set_amount(const StringName &p_node, float p_amount); - float mix_node_get_amount(const StringName &p_node) const; - - void blend2_node_set_amount(const StringName &p_node, float p_amount); - float blend2_node_get_amount(const StringName &p_node) const; - void blend2_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable); - void blend2_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const; - bool blend2_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const; - - void blend3_node_set_amount(const StringName &p_node, float p_amount); - float blend3_node_get_amount(const StringName &p_node) const; - - void blend4_node_set_amount(const StringName &p_node, const Point2 &p_amount); - Point2 blend4_node_get_amount(const StringName &p_node) const; - - /* TIMESCALE/TIMESEEK NODES */ - - void timescale_node_set_scale(const StringName &p_node, float p_scale); - float timescale_node_get_scale(const StringName &p_node) const; - - void timeseek_node_seek(const StringName &p_node, float p_pos); - - /* TRANSITION NODE */ - - void transition_node_set_input_count(const StringName &p_node, int p_inputs); // used for transition node - int transition_node_get_input_count(const StringName &p_node) const; - void transition_node_delete_input(const StringName &p_node, int p_input); // used for transition node - - void transition_node_set_input_auto_advance(const StringName &p_node, int p_input, bool p_auto_advance); // used for transition node - bool transition_node_has_input_auto_advance(const StringName &p_node, int p_input) const; - - void transition_node_set_xfade_time(const StringName &p_node, float p_time); // used for transition node - float transition_node_get_xfade_time(const StringName &p_node) const; - - void transition_node_set_current(const StringName &p_node, int p_current); - int transition_node_get_current(const StringName &p_node) const; - - void node_set_position(const StringName &p_node, const Vector2 &p_pos); //for display - - /* GETS */ - Point2 node_get_position(const StringName &p_node) const; //for display - - NodeType node_get_type(const StringName &p_node) const; - - void get_node_list(List<StringName> *p_node_list) const; - void remove_node(const StringName &p_node); - - Error connect_nodes(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input); - bool are_nodes_connected(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) const; - void disconnect_nodes(const StringName &p_node, int p_input); - - void set_base_path(const NodePath &p_path); - NodePath get_base_path() const; - - void set_master_player(const NodePath &p_path); - NodePath get_master_player() const; - - struct Connection { - - StringName src_node; - StringName dst_node; - int dst_input; - }; - - void get_connection_list(List<Connection> *p_connections) const; - - /* playback */ - - void set_active(bool p_active); - bool is_active() const; - - void reset(); - - void recompute_caches(); - - ConnectError get_last_error() const; - - void set_animation_process_mode(AnimationProcessMode p_mode); - AnimationProcessMode get_animation_process_mode() const; - - void _set_process(bool p_process, bool p_force = false); - - void advance(float p_time); - - AnimationTreePlayer(); - ~AnimationTreePlayer(); -}; - -VARIANT_ENUM_CAST(AnimationTreePlayer::NodeType); -VARIANT_ENUM_CAST(AnimationTreePlayer::AnimationProcessMode); - -#endif // ANIMATION_TREE_PLAYER_H diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 1cd4b54a5b..433c015a33 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -73,7 +73,6 @@ #include "scene/animation/animation_node_state_machine.h" #include "scene/animation/animation_player.h" #include "scene/animation/animation_tree.h" -#include "scene/animation/animation_tree_player.h" #include "scene/animation/root_motion_view.h" #include "scene/animation/tween.h" #include "scene/audio/audio_stream_player.h" @@ -374,7 +373,6 @@ void register_scene_types() { ClassDB::register_class<AnimationPlayer>(); ClassDB::register_class<Tween>(); - ClassDB::register_class<AnimationTreePlayer>(); ClassDB::register_class<AnimationTree>(); ClassDB::register_class<AnimationNode>(); ClassDB::register_class<AnimationRootNode>(); @@ -735,7 +733,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("ImageSkyBox", "PanoramaSky"); ClassDB::add_compatibility_class("FixedSpatialMaterial", "SpatialMaterial"); ClassDB::add_compatibility_class("Mesh", "ArrayMesh"); - + ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree"); #endif OS::get_singleton()->yield(); //may take time to init |