diff options
Diffstat (limited to 'scene/animation/animation_tree.h')
-rw-r--r-- | scene/animation/animation_tree.h | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 87928e4d20..62a01b758f 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -63,6 +63,34 @@ public: HashMap<NodePath, bool> filter; bool filter_enabled = false; + // To propagate information from upstream for use in estimation of playback progress. + // These values must be taken from the result of blend_node() or blend_input() and must be essentially read-only. + // For example, if you want to change the position, you need to change the pi.time value of PlaybackInfo passed to blend_input(pi) and get the result. + struct NodeTimeInfo { + // Retain the previous frame values. These are stored into the AnimationTree's Map and exposing them as read-only values. + double length = 0.0; + double position = 0.0; + double delta = 0.0; + + // Needs internally to estimate remain time, the previous frame values are not retained. + Animation::LoopMode loop_mode = Animation::LOOP_NONE; + bool is_just_looped = false; // For breaking loop, it is true when just looped. + bool is_infinity = false; // For unpredictable state machine's end. + + bool is_looping() { + return loop_mode != Animation::LOOP_NONE; + } + double get_remain(bool p_break_loop = false) { + if ((is_looping() && !p_break_loop) || is_infinity) { + return HUGE_LENGTH; + } + if (p_break_loop && is_just_looped) { + return 0; + } + return length - position; + } + }; + // Temporary state for blending process which needs to be stored in each AnimationNodes. struct NodeState { StringName base_path; @@ -84,16 +112,23 @@ public: Array _get_filters() const; void _set_filters(const Array &p_filters); friend class AnimationNodeBlendTree; - double _blend_node(Ref<AnimationNode> p_node, const StringName &p_subpath, AnimationNode *p_new_parent, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, bool p_test_only = false, real_t *r_activity = nullptr); - double _pre_process(ProcessState *p_process_state, AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only = false); + + // The time information is passed from upstream to downstream by AnimationMixer::PlaybackInfo::p_playback_info until AnimationNodeAnimation processes it. + // Conversely, AnimationNodeAnimation returns the processed result as NodeTimeInfo from downstream to upstream. + NodeTimeInfo _blend_node(Ref<AnimationNode> p_node, const StringName &p_subpath, AnimationNode *p_new_parent, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, bool p_test_only = false, real_t *r_activity = nullptr); + NodeTimeInfo _pre_process(ProcessState *p_process_state, AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only = false); protected: - virtual double _process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only = false); - double process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only = false); + StringName current_length = "current_length"; + StringName current_position = "current_position"; + StringName current_delta = "current_delta"; + + virtual NodeTimeInfo process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only = false); // To organize time information. Virtualizing for especially AnimationNodeAnimation needs to take "backward" into account. + virtual NodeTimeInfo _process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only = false); // Main process. void blend_animation(const StringName &p_animation, AnimationMixer::PlaybackInfo p_playback_info); - double blend_node(Ref<AnimationNode> p_node, const StringName &p_subpath, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, bool p_test_only = false); - double blend_input(int p_input, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, bool p_test_only = false); + NodeTimeInfo blend_node(Ref<AnimationNode> p_node, const StringName &p_subpath, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, bool p_test_only = false); + NodeTimeInfo blend_input(int p_input, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, bool p_test_only = false); // Bind-able methods to expose for compatibility, moreover AnimationMixer::PlaybackInfo is not exposed. void blend_animation_ex(const StringName &p_animation, double p_time, double p_delta, bool p_seeked, bool p_is_external_seeking, real_t p_blend, Animation::LoopedFlag p_looped_flag = Animation::LOOPED_FLAG_NONE); @@ -124,6 +159,9 @@ public: void set_parameter(const StringName &p_name, const Variant &p_value); Variant get_parameter(const StringName &p_name) const; + void set_node_time_info(const NodeTimeInfo &p_node_time_info); // Wrapper of set_parameter(). + virtual NodeTimeInfo get_node_time_info() const; // Wrapper of get_parameter(). + struct ChildNode { StringName name; Ref<AnimationNode> node; @@ -146,11 +184,15 @@ public: void set_filter_enabled(bool p_enable); bool is_filter_enabled() const; - void set_closable(bool p_closable); - bool is_closable() const; + void set_deletable(bool p_closable); + bool is_deletable() const; virtual bool has_filter() const; +#ifdef TOOLS_ENABLED + virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override; +#endif + virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) const; Ref<AnimationNode> find_node_by_path(const String &p_name) const; |