Преглед изворни кода

Merge pull request #2721 from SaracenOne/animation_tree_player_manual_control

Experimental retooling of AnimationTreePlayer to allow manual advancement
Juan Linietsky пре 9 година
родитељ
комит
6de941f21c
2 измењених фајлова са 105 додато и 10 уклоњено
  1. 88 8
      scene/animation/animation_tree_player.cpp
  2. 17 2
      scene/animation/animation_tree_player.h

+ 88 - 8
scene/animation/animation_tree_player.cpp

@@ -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,7 +413,19 @@ 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;
 	}
 
@@ -656,10 +727,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;
@@ -675,7 +743,7 @@ void AnimationTreePlayer::_process_animation() {
 		_process_node(out_name,&prev, 1.0, 0, 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 );
 
 	if (dirty_caches) {
 		//some animation changed.. ignore this pass
@@ -1520,8 +1588,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 +1815,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 +1847,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;

+ 17 - 2
scene/animation/animation_tree_player.h

@@ -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();
+	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