Path: blob/master/scene/animation/animation_node_state_machine.h
9902 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"3435class AnimationNodeStateMachineTransition : public Resource {36GDCLASS(AnimationNodeStateMachineTransition, Resource);3738public:39enum SwitchMode {40SWITCH_MODE_IMMEDIATE,41SWITCH_MODE_SYNC,42SWITCH_MODE_AT_END,43};4445enum AdvanceMode {46ADVANCE_MODE_DISABLED,47ADVANCE_MODE_ENABLED,48ADVANCE_MODE_AUTO,49};5051private:52SwitchMode switch_mode = SWITCH_MODE_IMMEDIATE;53AdvanceMode advance_mode = ADVANCE_MODE_ENABLED;54StringName advance_condition;55StringName advance_condition_name;56float xfade_time = 0.0;57Ref<Curve> xfade_curve;58bool break_loop_at_end = false;59bool reset = true;60int priority = 1;61String advance_expression;6263friend class AnimationNodeStateMachinePlayback;64Ref<Expression> expression;6566protected:67static void _bind_methods();6869public:70void set_switch_mode(SwitchMode p_mode);71SwitchMode get_switch_mode() const;7273void set_advance_mode(AdvanceMode p_mode);74AdvanceMode get_advance_mode() const;7576void set_advance_condition(const StringName &p_condition);77StringName get_advance_condition() const;7879StringName get_advance_condition_name() const;8081void set_advance_expression(const String &p_expression);82String get_advance_expression() const;8384void set_xfade_time(float p_xfade);85float get_xfade_time() const;8687void set_break_loop_at_end(bool p_enable);88bool is_loop_broken_at_end() const;8990void set_reset(bool p_reset);91bool is_reset() const;9293void set_xfade_curve(const Ref<Curve> &p_curve);94Ref<Curve> get_xfade_curve() const;9596void set_priority(int p_priority);97int get_priority() const;9899AnimationNodeStateMachineTransition();100};101102VARIANT_ENUM_CAST(AnimationNodeStateMachineTransition::SwitchMode)103VARIANT_ENUM_CAST(AnimationNodeStateMachineTransition::AdvanceMode)104105class AnimationNodeStateMachinePlayback;106107class AnimationNodeStateMachine : public AnimationRootNode {108GDCLASS(AnimationNodeStateMachine, AnimationRootNode);109110public:111enum StateMachineType {112STATE_MACHINE_TYPE_ROOT,113STATE_MACHINE_TYPE_NESTED,114STATE_MACHINE_TYPE_GROUPED,115};116117private:118friend class AnimationNodeStateMachinePlayback;119120StateMachineType state_machine_type = STATE_MACHINE_TYPE_ROOT;121122struct State {123Ref<AnimationRootNode> node;124Vector2 position;125};126127HashMap<StringName, State> states;128bool allow_transition_to_self = false;129bool reset_ends = false;130131struct Transition {132StringName from;133StringName to;134Ref<AnimationNodeStateMachineTransition> transition;135};136137Vector<Transition> transitions;138139StringName playback = "playback";140bool updating_transitions = false;141142Vector2 graph_offset;143144void _remove_transition(const Ref<AnimationNodeStateMachineTransition> p_transition);145void _rename_transitions(const StringName &p_name, const StringName &p_new_name);146bool _can_connect(const StringName &p_name);147148protected:149static void _bind_methods();150151bool _set(const StringName &p_name, const Variant &p_value);152bool _get(const StringName &p_name, Variant &r_ret) const;153void _get_property_list(List<PropertyInfo> *p_list) const;154void _validate_property(PropertyInfo &p_property) const;155156bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;157158virtual void _tree_changed() override;159virtual void _animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) override;160virtual void _animation_node_removed(const ObjectID &p_oid, const StringName &p_node) override;161162virtual void reset_state() override;163164public:165virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;166virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;167virtual bool is_parameter_read_only(const StringName &p_parameter) const override;168169void add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position = Vector2());170void replace_node(const StringName &p_name, Ref<AnimationNode> p_node);171Ref<AnimationNode> get_node(const StringName &p_name) const;172void remove_node(const StringName &p_name);173void rename_node(const StringName &p_name, const StringName &p_new_name);174bool has_node(const StringName &p_name) const;175StringName get_node_name(const Ref<AnimationNode> &p_node) const;176LocalVector<StringName> get_node_list() const;177TypedArray<StringName> get_node_list_as_typed_array() const;178179void set_node_position(const StringName &p_name, const Vector2 &p_position);180Vector2 get_node_position(const StringName &p_name) const;181182virtual void get_child_nodes(List<ChildNode> *r_child_nodes) override;183184bool has_transition(const StringName &p_from, const StringName &p_to) const;185bool has_transition_from(const StringName &p_from) const;186bool has_transition_to(const StringName &p_to) const;187int find_transition(const StringName &p_from, const StringName &p_to) const;188Vector<int> find_transition_from(const StringName &p_from) const;189Vector<int> find_transition_to(const StringName &p_to) const;190void add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition);191Ref<AnimationNodeStateMachineTransition> get_transition(int p_transition) const;192StringName get_transition_from(int p_transition) const;193StringName get_transition_to(int p_transition) const;194int get_transition_count() const;195bool is_transition_across_group(int p_transition) const;196void remove_transition_by_index(const int p_transition);197void remove_transition(const StringName &p_from, const StringName &p_to);198199void set_state_machine_type(StateMachineType p_state_machine_type);200StateMachineType get_state_machine_type() const;201202void set_allow_transition_to_self(bool p_enable);203bool is_allow_transition_to_self() const;204205void set_reset_ends(bool p_enable);206bool are_ends_reset() const;207208bool can_edit_node(const StringName &p_name) const;209210void set_graph_offset(const Vector2 &p_offset);211Vector2 get_graph_offset() const;212213virtual NodeTimeInfo _process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only = false) override;214virtual String get_caption() const override;215216virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) const override;217218#ifdef TOOLS_ENABLED219virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;220#endif221222Vector<StringName> get_nodes_with_transitions_from(const StringName &p_node) const;223Vector<StringName> get_nodes_with_transitions_to(const StringName &p_node) const;224225AnimationNodeStateMachine();226};227228VARIANT_ENUM_CAST(AnimationNodeStateMachine::StateMachineType);229230class AnimationNodeStateMachinePlayback : public Resource {231GDCLASS(AnimationNodeStateMachinePlayback, Resource);232233friend class AnimationNodeStateMachine;234235struct AStarCost {236float distance = 0.0;237StringName prev;238};239240struct TransitionInfo {241StringName from;242StringName to;243StringName next;244};245246struct NextInfo {247StringName node;248double xfade;249Ref<Curve> curve;250AnimationNodeStateMachineTransition::SwitchMode switch_mode;251bool is_reset;252bool break_loop_at_end;253};254255struct ChildStateMachineInfo {256Ref<AnimationNodeStateMachinePlayback> playback;257Vector<StringName> path;258bool is_reset = false;259};260261Ref<AnimationNodeStateMachineTransition> default_transition;262String base_path;263264AnimationNode::NodeTimeInfo current_nti;265StringName current;266Ref<Curve> current_curve;267268Ref<AnimationNodeStateMachineTransition> group_start_transition;269Ref<AnimationNodeStateMachineTransition> group_end_transition;270271AnimationNode::NodeTimeInfo fadeing_from_nti;272StringName fading_from;273float fading_time = 0.0;274float fading_pos = 0.0;275276Vector<StringName> path;277bool playing = false;278279StringName start_request;280StringName travel_request;281bool reset_request = false;282bool reset_request_on_teleport = false;283bool _reset_request_for_fading_from = false;284bool next_request = false;285bool stop_request = false;286bool teleport_request = false;287288bool is_grouped = false;289290void _clear_fading(AnimationNodeStateMachine *p_state_machine, const StringName &p_state);291void _signal_state_change(AnimationTree *p_animation_tree, const StringName &p_state, bool p_started);292void _travel_main(const StringName &p_state, bool p_reset_on_teleport = true);293void _start_main(const StringName &p_state, bool p_reset = true);294void _next_main();295void _stop_main();296297bool _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);298String _validate_path(AnimationNodeStateMachine *p_state_machine, const String &p_path);299bool _travel(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_is_allow_transition_to_self, bool p_test_only);300void _start(AnimationNodeStateMachine *p_state_machine);301302void _clear_path_children(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_test_only);303bool _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);304void _start_children(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, const String &p_path, bool p_test_only);305306AnimationNode::NodeTimeInfo process(AnimationNodeStateMachine *p_state_machine, const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only);307AnimationNode::NodeTimeInfo _process(AnimationNodeStateMachine *p_state_machine, const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only);308309bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;310bool _transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, double p_delta, bool p_test_only);311NextInfo _find_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine) const;312Ref<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;313bool _can_transition_to_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, NextInfo p_next, bool p_test_only);314315void _set_current(AnimationNodeStateMachine *p_state_machine, const StringName &p_state);316void _set_grouped(bool p_is_grouped);317void _set_base_path(const String &p_base_path);318Ref<AnimationNodeStateMachinePlayback> _get_parent_playback(AnimationTree *p_tree) const;319Ref<AnimationNodeStateMachine> _get_parent_state_machine(AnimationTree *p_tree) const;320Ref<AnimationNodeStateMachineTransition> _get_group_start_transition() const;321Ref<AnimationNodeStateMachineTransition> _get_group_end_transition() const;322323TypedArray<StringName> _get_travel_path() const;324325protected:326static void _bind_methods();327328public:329void travel(const StringName &p_state, bool p_reset_on_teleport = true);330void start(const StringName &p_state, bool p_reset = true);331void next();332void stop();333bool is_playing() const;334bool is_end() const;335StringName get_current_node() const;336StringName get_fading_from_node() const;337Vector<StringName> get_travel_path() const;338float get_current_play_pos() const;339float get_current_length() const;340341float get_fade_from_play_pos() const;342float get_fade_from_length() const;343344float get_fading_time() const;345float get_fading_pos() const;346347void clear_path();348void push_path(const StringName &p_state);349350AnimationNodeStateMachinePlayback();351};352353354