From bd95e18ae48711e5c62f3f2254aaf3d9edc989e1 Mon Sep 17 00:00:00 2001 From: Josh Grams Date: Mon, 25 Apr 2016 05:41:23 -0400 Subject: [PATCH] AnimationTree: add filters to Animation nodes. --- doc/base/classes.xml | 60 +++++++++++++++ scene/animation/animation_tree_player.cpp | 77 ++++++++++++++----- scene/animation/animation_tree_player.h | 8 ++ .../plugins/animation_tree_editor_plugin.cpp | 54 +++++++------ 4 files changed, 155 insertions(+), 44 deletions(-) diff --git a/doc/base/classes.xml b/doc/base/classes.xml index b77a1c29a89..21e7177cc0b 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -2900,6 +2900,12 @@ + + + + + + @@ -3023,6 +3029,16 @@ + + + + + + + + + + @@ -13887,6 +13903,12 @@ Returns an empty String "" at the end of the list. + + + + + + @@ -19118,6 +19140,14 @@ Example: (content-length:12), (Content-Type:application/json; charset=UTF-8) Set the mesh of the item. + + + + + + + + @@ -19144,6 +19174,14 @@ Example: (content-length:12), (Content-Type:application/json; charset=UTF-8) Return the mesh of the item. + + + + + + + + @@ -36069,6 +36107,22 @@ This method controls whether the position between two cached points is interpola + + + + + + + + + + + + + + + + @@ -37311,6 +37365,12 @@ This method controls whether the position between two cached points is interpola + + + + + + diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 0117766f1a2..211c5961b02 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -139,6 +139,11 @@ bool AnimationTreePlayer::_set(const StringName& p_name, const Variant& p_value) 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 i=0;ianimation; } + Array k; + List keys; + an->filter.get_key_list(&keys); + k.resize(keys.size()); + int i=0; + for(List::Element *E=keys.front();E;E=E->next()) { + k[i++]=E->get(); + } + node["filter"]=k; } break; case NODE_ONESHOT: { OneShotNode *osn = static_cast(n); @@ -439,7 +453,6 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode //transform to seconds... - switch(nb->type) { case NODE_OUTPUT: { @@ -464,7 +477,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode an->time=p_time; an->step=0; } else { - an->time+=p_time; + an->time=MAX(0,an->time+p_time); an->step=p_time; } @@ -482,14 +495,12 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode an->skip=true; for (List::Element *E=an->tref.front();E;E=E->next()) { - - if (p_filter && p_filter->has(an->animation->track_get_path(E->get().local_track))) { - - if (p_reverse_weight<0) - E->get().weight=0; - else - E->get().weight=p_reverse_weight; - + NodePath track_path = an->animation->track_get_path(E->get().local_track); + if (p_filter && p_filter->has(track_path)) { + E->get().weight = MAX(0, p_reverse_weight); + } else if(an->filter.has(track_path)) { + E->get().weight = 0; + E->get().track->skip = true; } else { E->get().weight=p_weight; } @@ -552,18 +563,17 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode float main_rem; float os_rem; + float os_reverse_weight = p_reverse_weight; if (!osn->filter.empty()) { - - main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,p_seek,&osn->filter,p_weight); - os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,os_seek,&osn->filter,-1); - - } else { - - main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,p_seek); - os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,os_seek); + p_filter = &osn->filter; + p_reverse_weight = p_weight; + os_reverse_weight = -1; } + main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,p_seek,p_filter,p_reverse_weight); + os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,os_seek,p_filter,os_reverse_weight); + if (osn->start) { osn->remaining=os_rem; osn->start=false; @@ -768,6 +778,8 @@ void AnimationTreePlayer::_process_animation(float p_delta) { t.value = t.object->get(t.property); t.value.zero(); + + t.skip = false; } @@ -817,7 +829,7 @@ void AnimationTreePlayer::_process_animation(float p_delta) { Variant value = a->value_track_interpolate(tr.local_track,anim_list->time); Variant::blend(tr.track->value,value,blend,tr.track->value); } else { - int index = a->track_find_key(tr.local_track,anim_list->time+anim_list->step); + 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; @@ -847,7 +859,7 @@ void AnimationTreePlayer::_process_animation(float p_delta) { Track &t = E->get(); - if (!t.object) + if (t.skip || !t.object) continue; if(t.property) { // value track @@ -978,6 +990,24 @@ void AnimationTreePlayer::animation_node_set_master_animation(const StringName& } +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 *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 ); @@ -1205,6 +1235,12 @@ String AnimationTreePlayer::animation_node_get_master_animation(const StringName } +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 { @@ -1745,6 +1781,7 @@ void AnimationTreePlayer::_bind_methods() { ObjectTypeDB::bind_method(_MD("animation_node_set_master_animation","id","source"),&AnimationTreePlayer::animation_node_set_master_animation); ObjectTypeDB::bind_method(_MD("animation_node_get_master_animation","id"),&AnimationTreePlayer::animation_node_get_master_animation); + ObjectTypeDB::bind_method(_MD("animation_node_set_filter_path","id","path","enable"),&AnimationTreePlayer::animation_node_set_filter_path); ObjectTypeDB::bind_method(_MD("oneshot_node_set_fadein_time","id","time_sec"),&AnimationTreePlayer::oneshot_node_set_fadein_time); ObjectTypeDB::bind_method(_MD("oneshot_node_get_fadein_time","id"),&AnimationTreePlayer::oneshot_node_get_fadein_time); diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h index 2e44d69aa19..0e78281e4c1 100644 --- a/scene/animation/animation_tree_player.h +++ b/scene/animation/animation_tree_player.h @@ -111,6 +111,7 @@ private: Variant value; + bool skip; }; @@ -162,6 +163,9 @@ private: float step; String from; bool skip; + + HashMap filter; + AnimationNode() { type=NODE_ANIMATION; next=NULL; last_version=0; skip=false; } }; @@ -310,6 +314,10 @@ public: 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; + void animation_node_set_filter_path(const StringName& p_node,const NodePath& p_filter,bool p_enable); + void animation_node_set_get_filtered_paths(const StringName& p_node,List *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); diff --git a/tools/editor/plugins/animation_tree_editor_plugin.cpp b/tools/editor/plugins/animation_tree_editor_plugin.cpp index 08c2a1c3ae1..7e1214ec831 100644 --- a/tools/editor/plugins/animation_tree_editor_plugin.cpp +++ b/tools/editor/plugins/animation_tree_editor_plugin.cpp @@ -239,8 +239,12 @@ void AnimationTreeEditor::_play_toggled() { void AnimationTreeEditor::_master_anim_menu_item(int p_item) { - String str = master_anim_popup->get_item_text(p_item); - anim_tree->animation_node_set_master_animation(edited_node,str); + 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(); } @@ -291,6 +295,8 @@ void AnimationTreeEditor::_popup_edit_dialog() { AnimationPlayer *ap = anim_tree->get_node(anim_tree->get_master_player())->cast_to(); master_anim_popup->clear(); + master_anim_popup->add_item("Edit Filters"); + master_anim_popup->add_separator(); List sn; ap->get_animation_list(&sn); sn.sort_custom(); @@ -652,39 +658,35 @@ AnimationTreeEditor::ClickType AnimationTreeEditor::_locate_click(const Point2& float y = pos.y-style->get_offset().height; - if (ynode_get_input_count(node); - count += inputs?inputs:1; + int count = MAX(inputs,1); + + if (inputs==0 || (pos.x > size.width/2 && type != AnimationTreePlayer::NODE_OUTPUT)) { + + if (y size.width/2)) { - - if (p_slot_index) - *p_slot_index=0; - return CLICK_OUTPUT_SLOT; - } else { - - if (p_slot_index) - *p_slot_index=i; - return CLICK_INPUT_SLOT; - } + if (p_slot_index) + *p_slot_index=i; + return CLICK_INPUT_SLOT; } y-=h; } - return (type!=AnimationTreePlayer::NODE_OUTPUT && type!=AnimationTreePlayer::NODE_TIMESEEK)?CLICK_PARAMETER:CLICK_NODE; + bool has_parameters = type!=AnimationTreePlayer::NODE_OUTPUT && type!=AnimationTreePlayer::NODE_TIMESEEK; + return has_parameters ? CLICK_PARAMETER : CLICK_NODE; } return CLICK_NONE; @@ -1243,6 +1245,8 @@ void AnimationTreeEditor::_filter_edited() { 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)); } } @@ -1310,6 +1314,8 @@ void AnimationTreeEditor::_edit_filters() { 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; }