Path: blob/master/scene/animation/animation_node_state_machine.h
21337 views
/**************************************************************************/1/* animation_node_state_machine.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/math/expression.h"33#include "scene/animation/animation_tree.h"34#include "scene/resources/curve.h"3536class AnimationNodeStateMachineTransition : public Resource {37GDCLASS(AnimationNodeStateMachineTransition, Resource);3839public:40enum SwitchMode {41SWITCH_MODE_IMMEDIATE,42SWITCH_MODE_SYNC,43SWITCH_MODE_AT_END,44};4546enum AdvanceMode {47ADVANCE_MODE_DISABLED,48ADVANCE_MODE_ENABLED,49ADVANCE_MODE_AUTO,50};5152private:53SwitchMode switch_mode = SWITCH_MODE_IMMEDIATE;54AdvanceMode advance_mode = ADVANCE_MODE_ENABLED;55StringName advance_condition;56StringName advance_condition_name;57float xfade_time = 0.0;58Ref<Curve> xfade_curve;59bool break_loop_at_end = false;60bool reset = true;61int priority = 1;62String advance_expression;6364friend class AnimationNodeStateMachinePlayback;65Ref<Expression> expression;6667protected:68static void _bind_methods();6970public:71void set_switch_mode(SwitchMode p_mode);72SwitchMode get_switch_mode() const;7374void set_advance_mode(AdvanceMode p_mode);75AdvanceMode get_advance_mode() const;7677void set_advance_condition(const StringName &p_condition);78StringName get_advance_condition() const;7980StringName get_advance_condition_name() const;8182void set_advance_expression(const String &p_expression);83String get_advance_expression() const;8485void set_xfade_time(float p_xfade);86float get_xfade_time() const;8788void set_break_loop_at_end(bool p_enable);89bool is_loop_broken_at_end() const;9091void set_reset(bool p_reset);92bool is_reset() const;9394void set_xfade_curve(const Ref<Curve> &p_curve);95Ref<Curve> get_xfade_curve() const;9697void set_priority(int p_priority);98int get_priority() const;99100AnimationNodeStateMachineTransition();101};102103VARIANT_ENUM_CAST(AnimationNodeStateMachineTransition::SwitchMode)104VARIANT_ENUM_CAST(AnimationNodeStateMachineTransition::AdvanceMode)105106class AnimationNodeStateMachinePlayback;107108class AnimationNodeStateMachine : public AnimationRootNode {109GDCLASS(AnimationNodeStateMachine, AnimationRootNode);110111public:112enum StateMachineType {113STATE_MACHINE_TYPE_ROOT,114STATE_MACHINE_TYPE_NESTED,115STATE_MACHINE_TYPE_GROUPED,116};117118private:119friend class AnimationNodeStateMachinePlayback;120121StateMachineType state_machine_type = STATE_MACHINE_TYPE_ROOT;122123struct State {124Ref<AnimationRootNode> node;125Vector2 position;126};127128HashMap<StringName, State> states;129bool allow_transition_to_self = false;130bool reset_ends = false;131132struct Transition {133StringName from;134StringName to;135Ref<AnimationNodeStateMachineTransition> transition;136};137138Vector<Transition> transitions;139140StringName playback = "playback";141bool updating_transitions = false;142143Vector2 graph_offset;144145void _remove_transition(const Ref<AnimationNodeStateMachineTransition> p_transition);146void _rename_transitions(const StringName &p_name, const StringName &p_new_name);147bool _can_connect(const StringName &p_name);148149protected:150static void _bind_methods();151152bool _set(const StringName &p_name, const Variant &p_value);153bool _get(const StringName &p_name, Variant &r_ret) const;154void _get_property_list(List<PropertyInfo> *p_list) const;155void _validate_property(PropertyInfo &p_property) const;156157bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;158159virtual void _tree_changed() override;160virtual void _animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) override;161virtual void _animation_node_removed(const ObjectID &p_oid, const StringName &p_node) override;162163virtual void reset_state() override;164165public:166virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;167virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;168virtual bool is_parameter_read_only(const StringName &p_parameter) const override;169170void add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position = Vector2());171void replace_node(const StringName &p_name, Ref<AnimationNode> p_node);172Ref<AnimationNode> get_node(const StringName &p_name) const;173void remove_node(const StringName &p_name);174void rename_node(const StringName &p_name, const StringName &p_new_name);175bool has_node(const StringName &p_name) const;176StringName get_node_name(const Ref<AnimationNode> &p_node) const;177LocalVector<StringName> get_node_list() const;178TypedArray<StringName> get_node_list_as_typed_array() const;179180void set_node_position(const StringName &p_name, const Vector2 &p_position);181Vector2 get_node_position(const StringName &p_name) const;182183virtual void get_child_nodes(List<ChildNode> *r_child_nodes) override;184185bool has_transition(const StringName &p_from, const StringName &p_to) const;186bool has_transition_from(const StringName &p_from) const;187bool has_transition_to(const StringName &p_to) const;188int find_transition(const StringName &p_from, const StringName &p_to) const;189Vector<int> find_transition_from(const StringName &p_from) const;190Vector<int> find_transition_to(const StringName &p_to) const;191void add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition);192Ref<AnimationNodeStateMachineTransition> get_transition(int p_transition) const;193StringName get_transition_from(int p_transition) const;194StringName get_transition_to(int p_transition) const;195int get_transition_count() const;196bool is_transition_across_group(int p_transition) const;197void remove_transition_by_index(const int p_transition);198void remove_transition(const StringName &p_from, const StringName &p_to);199200void set_state_machine_type(StateMachineType p_state_machine_type);201StateMachineType get_state_machine_type() const;202203void set_allow_transition_to_self(bool p_enable);204bool is_allow_transition_to_self() const;205206void set_reset_ends(bool p_enable);207bool are_ends_reset() const;208209bool can_edit_node(const StringName &p_name) const;210211void set_graph_offset(const Vector2 &p_offset);212Vector2 get_graph_offset() const;213214virtual NodeTimeInfo _process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only = false) override;215virtual String get_caption() const override;216217virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) const override;218219#ifdef TOOLS_ENABLED220virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;221#endif222223Vector<StringName> get_nodes_with_transitions_from(const StringName &p_node) const;224Vector<StringName> get_nodes_with_transitions_to(const StringName &p_node) const;225226AnimationNodeStateMachine();227};228229VARIANT_ENUM_CAST(AnimationNodeStateMachine::StateMachineType);230231class AnimationNodeStateMachinePlayback : public Resource {232GDCLASS(AnimationNodeStateMachinePlayback, Resource);233234friend class AnimationNodeStateMachine;235236struct AStarCost {237float distance = 0.0;238StringName prev;239};240241struct TransitionInfo {242StringName from;243StringName to;244StringName next;245};246247struct NextInfo {248StringName node;249double xfade;250Ref<Curve> curve;251AnimationNodeStateMachineTransition::SwitchMode switch_mode;252bool is_reset;253bool break_loop_at_end;254};255256struct ChildStateMachineInfo {257Ref<AnimationNodeStateMachinePlayback> playback;258Vector<StringName> path;259bool is_reset = false;260};261262Ref<AnimationNodeStateMachineTransition> default_transition;263String base_path;264265AnimationNode::NodeTimeInfo current_nti;266StringName current = SceneStringName(Start);267Ref<Curve> current_curve;268269Ref<AnimationNodeStateMachineTransition> group_start_transition;270Ref<AnimationNodeStateMachineTransition> group_end_transition;271272AnimationNode::NodeTimeInfo fadeing_from_nti;273StringName fading_from;274float fading_time = 0.0;275float fading_pos = 0.0;276277Vector<StringName> path;278bool playing = false;279280StringName start_request;281StringName travel_request;282bool reset_request = false;283bool reset_request_on_teleport = false;284bool _reset_request_for_fading_from = false;285bool next_request = false;286bool stop_request = false;287bool teleport_request = false;288289bool is_grouped = false;290291void _clear_fading(AnimationNodeStateMachine *p_state_machine, const StringName &p_state);292void _signal_state_change(AnimationTree *p_animation_tree, const StringName &p_state, bool p_started);293void _travel_main(const StringName &p_state, bool p_reset_on_teleport = true);294void _start_main(const StringName &p_state, bool p_reset = true);295void _next_main();296void _stop_main();297298bool _make_travel_path(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_is_allow_transition_to_self, Vector<StringName> &r_path, bool p_test_only);299String _validate_path(AnimationNodeStateMachine *p_state_machine, const String &p_path);300bool _travel(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_is_allow_transition_to_self, bool p_test_only);301void _start(AnimationNodeStateMachine *p_state_machine);302303void _clear_path_children(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_test_only);304bool _travel_children(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, const String &p_path, bool p_is_allow_transition_to_self, bool p_is_parent_same_state, bool p_test_only);305void _start_children(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, const String &p_path, bool p_test_only);306307AnimationNode::NodeTimeInfo process(AnimationNodeStateMachine *p_state_machine, const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only);308AnimationNode::NodeTimeInfo _process(AnimationNodeStateMachine *p_state_machine, const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only);309310bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;311bool _transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, double p_delta, bool p_test_only);312NextInfo _find_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine) const;313Ref<AnimationNodeStateMachineTransition> _check_group_transition(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, const AnimationNodeStateMachine::Transition &p_transition, Ref<AnimationNodeStateMachine> &r_state_machine, bool &r_bypass) const;314bool _can_transition_to_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, NextInfo p_next, bool p_test_only);315316void _set_current(AnimationNodeStateMachine *p_state_machine, const StringName &p_state);317void _set_grouped(bool p_is_grouped);318void _set_base_path(const String &p_base_path);319Ref<AnimationNodeStateMachinePlayback> _get_parent_playback(AnimationTree *p_tree) const;320Ref<AnimationNodeStateMachine> _get_parent_state_machine(AnimationTree *p_tree) const;321Ref<AnimationNodeStateMachineTransition> _get_group_start_transition() const;322Ref<AnimationNodeStateMachineTransition> _get_group_end_transition() const;323324TypedArray<StringName> _get_travel_path() const;325326protected:327static void _bind_methods();328329public:330void travel(const StringName &p_state, bool p_reset_on_teleport = true);331void start(const StringName &p_state, bool p_reset = true);332void next();333void stop();334bool is_playing() const;335bool is_end() const;336StringName get_current_node() const;337StringName get_fading_from_node() const;338Vector<StringName> get_travel_path() const;339float get_current_play_pos() const;340float get_current_length() const;341342float get_fading_from_play_pos() const;343float get_fading_from_length() const;344345float get_fading_time() const;346float get_fading_pos() const;347348void clear_path();349void push_path(const StringName &p_state);350351AnimationNodeStateMachinePlayback();352};353354355