summaryrefslogtreecommitdiff
path: root/scene/animation
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation')
-rw-r--r--scene/animation/SCsub2
-rw-r--r--scene/animation/animation_cache.cpp2
-rw-r--r--scene/animation/animation_cache.h2
-rw-r--r--scene/animation/animation_player.cpp89
-rw-r--r--scene/animation/animation_player.h4
-rw-r--r--scene/animation/animation_tree_player.cpp167
-rw-r--r--scene/animation/animation_tree_player.h23
-rw-r--r--scene/animation/transitioner.cpp2
-rw-r--r--scene/animation/transitioner.h2
-rw-r--r--scene/animation/tween.cpp2
-rw-r--r--scene/animation/tween.h2
-rw-r--r--scene/animation/tween_interpolaters.cpp2
12 files changed, 236 insertions, 63 deletions
diff --git a/scene/animation/SCsub b/scene/animation/SCsub
index 055d2f2474..bbe59b3054 100644
--- a/scene/animation/SCsub
+++ b/scene/animation/SCsub
@@ -3,5 +3,3 @@ Import('env')
env.add_source_files(env.scene_sources,"*.cpp")
Export('env')
-
-
diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp
index b1d6da7294..b1123897b2 100644
--- a/scene/animation/animation_cache.cpp
+++ b/scene/animation/animation_cache.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/animation/animation_cache.h b/scene/animation/animation_cache.h
index e94530d924..c9b4ff298c 100644
--- a/scene/animation/animation_cache.h
+++ b/scene/animation/animation_cache.h
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index c2ea1c8bb6..f6d058c2fd 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -268,6 +268,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
TrackNodeCacheKey key;
key.id=id;
key.bone_idx=bone_idx;
+
if (node_cache_map.has(key)) {
@@ -278,6 +279,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
node_cache_map[key]=TrackNodeCache();
p_anim->node_cache[i]=&node_cache_map[key];
+ p_anim->node_cache[i]->path=a->track_get_path(i);
p_anim->node_cache[i]->node=child;
p_anim->node_cache[i]->resource=resource;
p_anim->node_cache[i]->node_2d=child->cast_to<Node2D>();
@@ -320,6 +322,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
pa.prop=property;
pa.object=resource.is_valid()?(Object*)resource.ptr():(Object*)child;
pa.special=SP_NONE;
+ pa.owner=p_anim->node_cache[i];
if (false && p_anim->node_cache[i]->node_2d) {
if (pa.prop==SceneStringNames::get_singleton()->transform_pos)
@@ -410,7 +413,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
TrackNodeCache::PropertyAnim *pa = &E->get();
- if (a->value_track_is_continuous(i) || p_delta==0) {
+ if (a->value_track_is_continuous(i) || p_delta==0) { //delta == 0 means seek
Variant value=a->value_track_interpolate(i,p_time);
@@ -436,10 +439,42 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
Variant value=a->track_get_key_value(i,F->get());
switch(pa->special) {
- case SP_NONE: pa->object->set(pa->prop,value); break; //you are not speshul
- case SP_NODE2D_POS: static_cast<Node2D*>(pa->object)->set_pos(value); break;
- case SP_NODE2D_ROT: static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(value)); break;
- case SP_NODE2D_SCALE: static_cast<Node2D*>(pa->object)->set_scale(value); break;
+ case SP_NONE: {
+ bool valid;
+ pa->object->set(pa->prop,value,&valid); //you are not speshul
+#ifdef DEBUG_ENABLED
+ if (!valid) {
+ ERR_PRINTS("Failed setting track value '"+String(pa->owner->path)+"'. Check if property exists or the type of key is valid");
+ }
+#endif
+
+ } break;
+ case SP_NODE2D_POS: {
+#ifdef DEBUG_ENABLED
+ if (value.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Position key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+ static_cast<Node2D*>(pa->object)->set_pos(value);
+ } break;
+ case SP_NODE2D_ROT: {
+#ifdef DEBUG_ENABLED
+ if (value.is_num()) {
+ ERR_PRINTS("Rotation key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not numerical");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(value));
+ } break;
+ case SP_NODE2D_SCALE: {
+#ifdef DEBUG_ENABLED
+ if (value.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Scale key at time "+rtos(p_time)+" in Animation Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_scale(value);
+ } break;
}
}
@@ -607,13 +642,53 @@ void AnimationPlayer::_animation_update_transforms() {
ERR_CONTINUE( pa->accum_pass!=accum_pass );
#if 1
- switch(pa->special) {
+/* switch(pa->special) {
case SP_NONE: pa->object->set(pa->prop,pa->value_accum); break; //you are not speshul
case SP_NODE2D_POS: static_cast<Node2D*>(pa->object)->set_pos(pa->value_accum); break;
case SP_NODE2D_ROT: static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(pa->value_accum)); break;
case SP_NODE2D_SCALE: static_cast<Node2D*>(pa->object)->set_scale(pa->value_accum); break;
+ }*/
+
+ switch(pa->special) {
+
+ case SP_NONE: {
+ bool valid;
+ pa->object->set(pa->prop,pa->value_accum,&valid); //you are not speshul
+#ifdef DEBUG_ENABLED
+ if (!valid) {
+ ERR_PRINTS("Failed setting key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"'. Check if property exists or the type of key is right for the property");
+ }
+#endif
+
+ } break;
+ case SP_NODE2D_POS: {
+#ifdef DEBUG_ENABLED
+ if (pa->value_accum.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Position key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+ static_cast<Node2D*>(pa->object)->set_pos(pa->value_accum);
+ } break;
+ case SP_NODE2D_ROT: {
+#ifdef DEBUG_ENABLED
+ if (pa->value_accum.is_num()) {
+ ERR_PRINTS("Rotation key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not numerical");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_rot(Math::deg2rad(pa->value_accum));
+ } break;
+ case SP_NODE2D_SCALE: {
+#ifdef DEBUG_ENABLED
+ if (pa->value_accum.get_type()!=Variant::VECTOR2) {
+ ERR_PRINTS("Scale key at time "+rtos(playback.current.pos)+" in Animation '"+get_current_animation()+"', Track '"+String(pa->owner->path)+"' not of type Vector2()");
+ }
+#endif
+
+ static_cast<Node2D*>(pa->object)->set_scale(pa->value_accum);
+ } break;
}
#else
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 1e3c37c4d6..853526c80a 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -68,6 +68,7 @@ private:
struct TrackNodeCache {
+ NodePath path;
uint32_t id;
RES resource;
Node *node;
@@ -84,6 +85,7 @@ private:
struct PropertyAnim {
+ TrackNodeCache *owner;
SpecialProperty special; //small optimization
StringName prop;
Object *object;
diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp
index 14f2110915..77d9f77bb5 100644
--- a/scene/animation/animation_tree_player.cpp
+++ b/scene/animation/animation_tree_player.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,6 +29,42 @@
#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_FIXED: set_fixed_process(p_process && active); break;
+ case ANIMATION_PROCESS_IDLE: set_process(p_process && active); break;
+ }
+
+ processing = p_process;
+}
+
bool AnimationTreePlayer::_set(const StringName& p_name, const Variant& p_value) {
@@ -42,6 +78,11 @@ bool AnimationTreePlayer::_set(const StringName& p_name, const Variant& 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;
@@ -190,6 +231,11 @@ bool AnimationTreePlayer::_get(const StringName& p_name,Variant &r_ret) const {
return true;
}
+ if (String(p_name) == "playback/active") {
+ r_ret=is_active();
+ return true;
+ }
+
if (String(p_name)!="data")
return false;
@@ -342,11 +388,24 @@ 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: {
+
+ if (!processing) {
+ //make sure that a previous process state was not saved
+ //only process if "processing" is set
+ set_fixed_process(false);
+ set_process(false);
+ }
+ } break;
case NOTIFICATION_READY: {
dirty_caches=true;
if (master!=NodePath()) {
@@ -354,14 +413,26 @@ void AnimationTreePlayer::_notification(int p_what) {
}
} break;
case NOTIFICATION_PROCESS: {
- _process_animation();
+ if (animation_process_mode==ANIMATION_PROCESS_FIXED)
+ break;
+
+ if (processing)
+ _process_animation( get_process_delta_time() );
+ } break;
+ case NOTIFICATION_FIXED_PROCESS: {
+
+ if (animation_process_mode==ANIMATION_PROCESS_IDLE)
+ break;
+
+ if (processing)
+ _process_animation(get_fixed_process_delta_time());
} break;
}
}
-float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode **r_prev_anim,float p_weight, float p_time, bool p_seek,const HashMap<NodePath,bool> *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 switched, bool p_seek,const HashMap<NodePath,bool> *p_filter, float p_reverse_weight) {
ERR_FAIL_COND_V(!node_map.has(p_node), 0);
NodeBase *nb=node_map[p_node];
@@ -374,7 +445,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
case NODE_OUTPUT: {
NodeOut *on = static_cast<NodeOut*>(nb);
- return _process_node(on->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek);
+ return _process_node(on->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek);
} break;
case NODE_ANIMATION: {
@@ -408,6 +479,9 @@ 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<AnimationNode::TrackRef>::Element *E=an->tref.front();E;E=E->next()) {
@@ -449,7 +523,7 @@ 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,p_seek,p_filter,p_reverse_weight);
+ return _process_node(osn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight);
}
if (p_seek)
@@ -480,13 +554,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,p_seek,&osn->filter,p_weight);
- os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,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,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);
} 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,p_seek);
+ 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);
}
if (osn->start) {
@@ -507,8 +581,8 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
MixNode *mn = static_cast<MixNode*>(nb);
- 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);
+ 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);
return rem;
} break;
@@ -519,12 +593,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,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);
+ 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);
} else {
- 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);
+ 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);
}
return rem;
@@ -535,16 +609,16 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
float rem;
if (bn->value==0) {
- rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight);
+ rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight);
} else if (bn->value>0) {
- rem = _process_node(bn->inputs[1].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[2].node,r_prev_anim,p_weight*bn->value,p_time,p_seek,p_filter,p_reverse_weight*bn->value);
+ rem = _process_node(bn->inputs[1].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[2].node,r_prev_anim,p_weight*bn->value,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value);
} else {
- rem = _process_node(bn->inputs[1].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[0].node,r_prev_anim,p_weight*-bn->value,p_time,p_seek,p_filter,p_reverse_weight*-bn->value);
+ rem = _process_node(bn->inputs[1].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[0].node,r_prev_anim,p_weight*-bn->value,p_time,switched,p_seek,p_filter,p_reverse_weight*-bn->value);
}
return rem;
@@ -552,10 +626,10 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
case NODE_BLEND4: {
Blend4Node *bn = static_cast<Blend4Node*>(nb);
- 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);
+ 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);
return MAX(rem,rem2);
@@ -563,9 +637,9 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
case NODE_TIMESCALE: {
TimeScaleNode *tsn = static_cast<TimeScaleNode*>(nb);
if (p_seek)
- return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,true,p_filter,p_reverse_weight);
+ return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,true,p_filter,p_reverse_weight);
else
- return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,false,p_filter,p_reverse_weight);
+ return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,switched,false,p_filter,p_reverse_weight);
} break;
case NODE_TIMESEEK: {
@@ -573,12 +647,12 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
TimeSeekNode *tsn = static_cast<TimeSeekNode*>(nb);
if (tsn->seek_pos>=0) {
- float res = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,tsn->seek_pos,true,p_filter,p_reverse_weight);
+ float res = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,tsn->seek_pos,switched,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,p_seek);
+ return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek);
} break;
case NODE_TRANSITION: {
@@ -587,7 +661,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
if (tn->prev<0) {
- float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight);
+ float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight);
if (p_seek)
tn->time=p_time;
else
@@ -616,10 +690,10 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
if (!p_seek && tn->switched) { //just switched
- 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));
+ 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));
} else {
- 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));
+ 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));
}
@@ -629,10 +703,10 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
if (p_seek) {
- _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,0,false,p_filter,p_reverse_weight*blend);
+ _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,0,true,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,false,p_filter,p_reverse_weight*blend);
+ _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,p_time,switched,false,p_filter,p_reverse_weight*blend);
tn->time+=p_time;
tn->prev_xfading-=p_time;
if (tn->prev_xfading<0) {
@@ -656,10 +730,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
}
-void AnimationTreePlayer::_process_animation() {
-
- if (!active)
- return;
+void AnimationTreePlayer::_process_animation(float p_delta) {
if (last_error!=CONNECT_OK)
return;
@@ -672,10 +743,10 @@ void AnimationTreePlayer::_process_animation() {
AnimationNode *prev=NULL;
if (reset_request) {
- _process_node(out_name,&prev, 1.0, 0, true );
+ _process_node(out_name,&prev, 1.0, 0, true, true );
reset_request=false;
} else
- _process_node(out_name,&prev, 1.0, get_process_delta_time(), false );
+ _process_node(out_name,&prev, 1.0, p_delta, false, false );
if (dirty_caches) {
//some animation changed.. ignore this pass
@@ -766,7 +837,7 @@ void AnimationTreePlayer::_process_animation() {
StringName method = a->method_track_get_name(tr.local_track,E->get());
Vector<Variant> args=a->method_track_get_params(tr.local_track,E->get());
- ERR_CONTINUE(args.size()!=VARIANT_ARG_MAX);
+ args.resize(VARIANT_ARG_MAX);
tr.track->node->call(method,args[0],args[1],args[2],args[3],args[4]);
}
} break;
@@ -1520,8 +1591,12 @@ void AnimationTreePlayer::recompute_caches() {
void AnimationTreePlayer::set_active(bool p_active) {
- active=p_active;
- set_process(active);
+ if (active == p_active)
+ return;
+
+ active = p_active;
+ processing = active;
+ _set_process(processing, true);
}
bool AnimationTreePlayer::is_active() const {
@@ -1743,13 +1818,18 @@ void AnimationTreePlayer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_node_list"),&AnimationTreePlayer::_get_node_list);
+ ObjectTypeDB::bind_method(_MD("set_animation_process_mode","mode"),&AnimationTreePlayer::set_animation_process_mode);
+ ObjectTypeDB::bind_method(_MD("get_animation_process_mode"),&AnimationTreePlayer::get_animation_process_mode);
+ ObjectTypeDB::bind_method(_MD("advance", "delta"), &AnimationTreePlayer::advance);
ObjectTypeDB::bind_method(_MD("reset"),&AnimationTreePlayer::reset);
ObjectTypeDB::bind_method(_MD("recompute_caches"),&AnimationTreePlayer::recompute_caches);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "playback/process_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), _SCS("set_animation_process_mode"), _SCS("get_animation_process_mode"));
+
BIND_CONSTANT( NODE_OUTPUT );
BIND_CONSTANT( NODE_ANIMATION );
BIND_CONSTANT( NODE_ONESHOT );
@@ -1770,6 +1850,9 @@ AnimationTreePlayer::AnimationTreePlayer() {
out_name="out";
out->pos=Point2(40,40);
node_map.insert( out_name , out);
+ AnimationProcessMode animation_process_mode;
+ animation_process_mode = ANIMATION_PROCESS_IDLE;
+ processing = false;
active=false;
dirty_caches=true;
reset_request=false;
diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h
index 9e936304c6..0fec9a9551 100644
--- a/scene/animation/animation_tree_player.h
+++ b/scene/animation/animation_tree_player.h
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,6 +34,7 @@
#include "scene/3d/spatial.h"
#include "scene/3d/skeleton.h"
#include "scene/main/misc.h"
+#include "animation_player.h"
class AnimationTreePlayer : public Node {
@@ -42,7 +43,10 @@ class AnimationTreePlayer : public Node {
OBJ_CATEGORY("Animation Nodes");
public:
-
+ enum AnimationProcessMode {
+ ANIMATION_PROCESS_FIXED,
+ ANIMATION_PROCESS_IDLE,
+ };
enum NodeType {
@@ -256,13 +260,15 @@ private:
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_weight,float p_step, bool p_seek=false,const HashMap<NodePath,bool> *p_filter=NULL, float p_reverse_weight=0);
- void _process_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<NodePath,bool> *p_filter=NULL, float p_reverse_weight=0);
+ void _process_animation(float p_delta);
bool reset_request;
ConnectError _cycle_test(const StringName &p_at_node);
@@ -409,12 +415,21 @@ public:
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/animation/transitioner.cpp b/scene/animation/transitioner.cpp
index d210f29db0..adcf73d489 100644
--- a/scene/animation/transitioner.cpp
+++ b/scene/animation/transitioner.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/animation/transitioner.h b/scene/animation/transitioner.h
index dba83cddd8..8b7ec4f3fa 100644
--- a/scene/animation/transitioner.h
+++ b/scene/animation/transitioner.h
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 73d93e50ec..31f30dd1d9 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/animation/tween.h b/scene/animation/tween.h
index d504c63d8a..f06ca1e9e7 100644
--- a/scene/animation/tween.h
+++ b/scene/animation/tween.h
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/animation/tween_interpolaters.cpp b/scene/animation/tween_interpolaters.cpp
index 9128d220de..80588d643e 100644
--- a/scene/animation/tween_interpolaters.cpp
+++ b/scene/animation/tween_interpolaters.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */