From 8920ab0fbfd31098b97894d27db5704072c5cd2b Mon Sep 17 00:00:00 2001 From: Josh Grams Date: Sun, 27 Mar 2016 07:19:05 -0400 Subject: * AnimationTreePlayer (_process_node): remove `switched` argument. The _process_node function (which recurses through the blend tree generating blend values and the active animation list) had an argument named `switched` which would loop an animation back to the beginning if it had reached the end (regardless of whether or not it was supposed to be a looping animation). This argument was only used in four places: two of them were overridden by a seek-to-zero, and I believe the other two are bugs. In OneShot, it was used to reset the oneshot animation to the beginning when fired. But this would fail if the oneshot node was fired before it had completed its previous run. While this *could* be a valid way for oneshot to work (firing does nothing if it's already running), the code currently resets the fade-in, so I believe that it is intended to reset. I replaced this usage with seek-to-0. In Transition, it was used on the previous (fading out) animation when seeking the Transition node, which I believe is incorrect: why would you want to loop a non-looping animation instead of simply fading out from the end? Also it will never happen unless you seek the Transition node twice during one cross-fade. The other two uses are in Transition and _process_animation, where it is used along with a seek-to-zero which overrides it. --- scene/animation/animation_tree_player.cpp | 82 +++++++++++++++---------------- scene/animation/animation_tree_player.h | 2 +- 2 files changed, 41 insertions(+), 43 deletions(-) diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 9dcad8a533..050d6070a5 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -432,7 +432,7 @@ void AnimationTreePlayer::_notification(int p_what) { } -float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode **r_prev_anim,float p_weight, float p_time, bool switched, bool p_seek,const HashMap *p_filter, float p_reverse_weight) { +float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode **r_prev_anim,float p_weight, float p_time, bool p_seek,const HashMap *p_filter, float p_reverse_weight) { ERR_FAIL_COND_V(!node_map.has(p_node), 0); NodeBase *nb=node_map[p_node]; @@ -445,7 +445,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode case NODE_OUTPUT: { NodeOut *on = static_cast(nb); - return _process_node(on->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek); + return _process_node(on->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek); } break; case NODE_ANIMATION: { @@ -479,9 +479,6 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode an->time=anim_size; } - if (switched && an->time >= anim_size) { - an->time = 0.0; - } an->skip=true; for (List::Element *E=an->tref.front();E;E=E->next()) { @@ -523,13 +520,17 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode 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_weight,p_time,switched,p_seek,p_filter,p_reverse_weight); + return _process_node(osn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight); } + float os_seek = p_seek; + if (p_seek) osn->time=p_time; - if (osn->start) + if (osn->start) { osn->time=0; + os_seek = true; + } float blend; @@ -554,13 +555,13 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode 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,switched,p_seek,&osn->filter,p_weight); - os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,osn->start,p_seek,&osn->filter,-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,&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,switched,p_seek); - os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,osn->start,p_seek); + 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); } if (osn->start) { @@ -581,8 +582,8 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode MixNode *mn = static_cast(nb); - float rem = _process_node(mn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight); - _process_node(mn->inputs[1].node,r_prev_anim,p_weight*mn->amount,p_time,switched,p_seek,p_filter,p_reverse_weight); + float rem = _process_node(mn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight); + _process_node(mn->inputs[1].node,r_prev_anim,p_weight*mn->amount,p_time,p_seek,p_filter,p_reverse_weight); return rem; } break; @@ -593,12 +594,12 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode float rem; if (!bn->filter.empty()) { - rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,switched,p_seek,&bn->filter,p_weight); - _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,switched,p_seek,&bn->filter,-1); + rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,p_seek,&bn->filter,p_weight); + _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,p_seek,&bn->filter,-1); } else { - rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value)); - _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value); + rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value)); + _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,p_seek,p_filter,p_reverse_weight*bn->value); } return rem; @@ -618,19 +619,19 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode upper_blend = bn->value; } - rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,switched,p_seek,p_filter,p_reverse_weight*blend); - _process_node(bn->inputs[2].node,r_prev_anim,p_weight*upper_blend,p_time,switched,p_seek,p_filter,p_reverse_weight*upper_blend); - _process_node(bn->inputs[0].node,r_prev_anim,p_weight*lower_blend,p_time,switched,p_seek,p_filter,p_reverse_weight*lower_blend); + rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,p_seek,p_filter,p_reverse_weight*blend); + _process_node(bn->inputs[2].node,r_prev_anim,p_weight*upper_blend,p_time,p_seek,p_filter,p_reverse_weight*upper_blend); + _process_node(bn->inputs[0].node,r_prev_anim,p_weight*lower_blend,p_time,p_seek,p_filter,p_reverse_weight*lower_blend); return rem; } break; case NODE_BLEND4: { Blend4Node *bn = static_cast(nb); - float rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value.x),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.x)); - _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value.x,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value.x); - float rem2 = _process_node(bn->inputs[2].node,r_prev_anim,p_weight*(1.0-bn->value.y),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.y)); - _process_node(bn->inputs[3].node,r_prev_anim,p_weight*bn->value.y,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value.y); + float rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value.x),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.x)); + _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value.x,p_time,p_seek,p_filter,p_reverse_weight*bn->value.x); + float rem2 = _process_node(bn->inputs[2].node,r_prev_anim,p_weight*(1.0-bn->value.y),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.y)); + _process_node(bn->inputs[3].node,r_prev_anim,p_weight*bn->value.y,p_time,p_seek,p_filter,p_reverse_weight*bn->value.y); return MAX(rem,rem2); @@ -639,9 +640,9 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode TimeScaleNode *tsn = static_cast(nb); float rem; if (p_seek) - rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,true,p_filter,p_reverse_weight); + rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,true,p_filter,p_reverse_weight); else - rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,switched,false,p_filter,p_reverse_weight); + rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,false,p_filter,p_reverse_weight); if (tsn->scale == 0) return INFINITY; else @@ -653,21 +654,21 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode TimeSeekNode *tsn = static_cast(nb); if (tsn->seek_pos>=0) { - float res = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,tsn->seek_pos,switched,true,p_filter,p_reverse_weight); + float res = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,tsn->seek_pos,true,p_filter,p_reverse_weight); tsn->seek_pos=-1; return res; } else - return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek); + return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek); } break; case NODE_TRANSITION: { TransitionNode *tn = static_cast(nb); - if (tn->prev<0) { + if (tn->prev<0) { // process current animation, check for transition - float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight); + float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight); if (p_seek) tn->time=p_time; else @@ -687,32 +688,29 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode return rem; - } else { + } else { // cross-fading from tn->prev to tn->current float blend = tn->xfade? (tn->prev_xfading/tn->xfade) : 1; float rem; - if (!p_seek && tn->switched) { //just switched + if (!p_seek && tn->switched) { //just switched, seek to start of current - rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),0,true,true,p_filter,p_reverse_weight*(1.0-blend)); + rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),0,true,p_filter,p_reverse_weight*(1.0-blend)); } else { - rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-blend)); + rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),p_time,p_seek,p_filter,p_reverse_weight*(1.0-blend)); } tn->switched=false; - //if (!p_seek) - - - if (p_seek) { - _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,0,true,false,p_filter,p_reverse_weight*blend); + if (p_seek) { // don't seek prev animation + _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,0,false,p_filter,p_reverse_weight*blend); tn->time=p_time; } else { - _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,p_time,switched,false,p_filter,p_reverse_weight*blend); + _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,p_time,false,p_filter,p_reverse_weight*blend); tn->time+=p_time; tn->prev_xfading-=p_time; if (tn->prev_xfading<0) { @@ -749,10 +747,10 @@ void AnimationTreePlayer::_process_animation(float p_delta) { AnimationNode *prev=NULL; if (reset_request) { - _process_node(out_name,&prev, 1.0, 0, true, true ); + _process_node(out_name,&prev, 1.0, 0, true); reset_request=false; } else - _process_node(out_name,&prev, 1.0, p_delta, false, false ); + _process_node(out_name,&prev, 1.0, p_delta); if (dirty_caches) { //some animation changed.. ignore this pass diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h index 0fec9a9551..2e8ddc34d8 100644 --- a/scene/animation/animation_tree_player.h +++ b/scene/animation/animation_tree_player.h @@ -267,7 +267,7 @@ private: Map node_map; // return time left to finish animation - float _process_node(const StringName& p_node,AnimationNode **r_prev_anim, float p_weight,float p_step, bool switched, bool p_seek=false,const HashMap *p_filter=NULL, float p_reverse_weight=0); + float _process_node(const StringName& p_node,AnimationNode **r_prev_anim, float p_weight,float p_step, bool p_seek=false,const HashMap *p_filter=NULL, float p_reverse_weight=0); void _process_animation(float p_delta); bool reset_request; -- cgit v1.2.3 From 7fe28d4168aa52a79cbc41c42112c1d1ec2680f4 Mon Sep 17 00:00:00 2001 From: Josh Grams Date: Thu, 31 Mar 2016 10:06:38 -0400 Subject: AnimationTreePlayer (_process_node:TIMESEEK): give p_seek precedence over tsn->seek_pos. --- scene/animation/animation_tree_player.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 050d6070a5..1a3fbe3ef1 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -652,14 +652,14 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode case NODE_TIMESEEK: { TimeSeekNode *tsn = static_cast(nb); - if (tsn->seek_pos>=0) { + if (tsn->seek_pos>=0 && !p_seek) { - float res = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,tsn->seek_pos,true,p_filter,p_reverse_weight); - tsn->seek_pos=-1; - return res; + p_time = tsn->seek_pos; + p_seek = true; + } + tsn->seek_pos=-1; - } else - return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek); + return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek); } break; case NODE_TRANSITION: { -- cgit v1.2.3 From 0a9c8a9f36dbcba2e416b7ab29c949b70bd72c0e Mon Sep 17 00:00:00 2001 From: Josh Grams Date: Thu, 31 Mar 2016 12:12:05 -0400 Subject: AnimationTreePlayer (_process_node:TIMESEEK): allow auto-advance with 0 xfade. --- scene/animation/animation_tree_player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 1a3fbe3ef1..d36960c963 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -674,7 +674,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode else tn->time+=p_time; - if (tn->input_data[tn->current].auto_advance && rem < tn->xfade) { + if (tn->input_data[tn->current].auto_advance && rem <= tn->xfade) { tn->prev=tn->current; tn->current++; -- cgit v1.2.3 From 5d6b58fea69ab78cb04f1f52eed3b2aee0ec9207 Mon Sep 17 00:00:00 2001 From: Josh Grams Date: Wed, 6 Apr 2016 15:06:42 -0400 Subject: AnimationTreePlayer (_process_node): more robust oneshot termination condition. --- scene/animation/animation_tree_player.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index d36960c963..9c2235de78 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -571,8 +571,8 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode if (!p_seek) { osn->time+=p_time; - osn->remaining-=p_time; - if (osn->remaining<0) + osn->remaining=os_rem; + if (osn->remaining<=0) osn->active=false; } -- cgit v1.2.3 From 1b95dca6bd8113503f4da21c148f7eb98e7722e6 Mon Sep 17 00:00:00 2001 From: Josh Grams Date: Wed, 6 Apr 2016 15:07:58 -0400 Subject: AnimationTreePlayer (set_active, reset, constructor): seek all animations to start. --- scene/animation/animation_tree_player.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 9c2235de78..0f8599706e 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -1604,6 +1604,7 @@ void AnimationTreePlayer::set_active(bool p_active) { active = p_active; processing = active; + reset_request = p_active; _set_process(processing, true); } @@ -1621,7 +1622,7 @@ AnimationTreePlayer::ConnectError AnimationTreePlayer::get_last_error() const { void AnimationTreePlayer::reset() { - reset_request=false; + reset_request=true; } @@ -1863,7 +1864,7 @@ AnimationTreePlayer::AnimationTreePlayer() { processing = false; active=false; dirty_caches=true; - reset_request=false; + reset_request=true; last_error=CONNECT_INCOMPLETE; base_path=String(".."); } -- cgit v1.2.3 From 4f6b2152e2e12a6c9157ea3190830b627cbae3b7 Mon Sep 17 00:00:00 2001 From: Josh Grams Date: Wed, 6 Apr 2016 15:09:00 -0400 Subject: AnimationTreePlayer (transition_node_set_current): fix by removing copy-paste duplication. --- scene/animation/animation_tree_player.cpp | 34 ++++++++++++++----------------- scene/animation/animation_tree_player.h | 1 + 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 0f8599706e..ce341e2b09 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -676,14 +676,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode if (tn->input_data[tn->current].auto_advance && rem <= tn->xfade) { - tn->prev=tn->current; - tn->current++; - if (tn->current>=tn->inputs.size()) - tn->current=0; - tn->prev_xfading=tn->xfade; - tn->prev_time=tn->time; - tn->time=0; - tn->switched=true; + tn->set_current((tn->current+1) % tn->inputs.size()); } @@ -1156,21 +1149,24 @@ void AnimationTreePlayer::transition_node_set_xfade_time(const StringName& p_nod n->xfade=p_time; } +void AnimationTreePlayer::TransitionNode::set_current(int p_current) { + ERR_FAIL_INDEX(p_current,inputs.size()); -void AnimationTreePlayer::transition_node_set_current(const StringName& p_node, int p_current) { - - GET_NODE( NODE_TRANSITION, TransitionNode ); - ERR_FAIL_INDEX(p_current,n->inputs.size()); - - if (n->current==p_current) + if (current==p_current) return; - n->prev=n->current; - n->prev_xfading=n->xfade; - n->prev_time=n->time; - n->time=0; - n->current=p_current; + 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); } diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h index 2e8ddc34d8..7cc96fc1e3 100644 --- a/scene/animation/animation_tree_player.h +++ b/scene/animation/animation_tree_player.h @@ -246,6 +246,7 @@ private: 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); }; -- cgit v1.2.3