summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/animation/animation_blend_space_1d.cpp20
-rw-r--r--scene/animation/animation_blend_space_1d.h7
-rw-r--r--scene/animation/animation_blend_space_2d.cpp26
-rw-r--r--scene/animation/animation_blend_space_2d.h7
-rw-r--r--scene/animation/animation_blend_tree.cpp53
-rw-r--r--scene/animation/animation_blend_tree.h8
-rw-r--r--scene/animation/animation_node_state_machine.cpp20
-rw-r--r--scene/animation/animation_node_state_machine.h5
-rw-r--r--scene/animation/animation_player.cpp15
-rw-r--r--scene/animation/animation_tree.cpp60
-rw-r--r--scene/animation/animation_tree.h8
-rw-r--r--scene/gui/control.cpp2
-rw-r--r--scene/gui/option_button.cpp8
-rw-r--r--scene/main/viewport.cpp11
-rw-r--r--scene/main/window.cpp1
15 files changed, 214 insertions, 37 deletions
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp
index d28a6fcc04..0e9e02f247 100644
--- a/scene/animation/animation_blend_space_1d.cpp
+++ b/scene/animation/animation_blend_space_1d.cpp
@@ -61,7 +61,15 @@ void AnimationNodeBlendSpace1D::_validate_property(PropertyInfo &p_property) con
}
void AnimationNodeBlendSpace1D::_tree_changed() {
- emit_signal(SNAME("tree_changed"));
+ AnimationRootNode::_tree_changed();
+}
+
+void AnimationNodeBlendSpace1D::_animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) {
+ AnimationRootNode::_animation_node_renamed(p_oid, p_old_name, p_new_name);
+}
+
+void AnimationNodeBlendSpace1D::_animation_node_removed(const ObjectID &p_oid, const StringName &p_node) {
+ AnimationRootNode::_animation_node_removed(p_oid, p_node);
}
void AnimationNodeBlendSpace1D::_bind_methods() {
@@ -137,6 +145,8 @@ void AnimationNodeBlendSpace1D::add_blend_point(const Ref<AnimationRootNode> &p_
blend_points[p_at_index].position = p_position;
blend_points[p_at_index].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_at_index].node->connect("animation_node_renamed", callable_mp(this, &AnimationNodeBlendSpace1D::_animation_node_renamed), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_at_index].node->connect("animation_node_removed", callable_mp(this, &AnimationNodeBlendSpace1D::_animation_node_removed), CONNECT_REFERENCE_COUNTED);
blend_points_used++;
emit_signal(SNAME("tree_changed"));
@@ -154,10 +164,14 @@ void AnimationNodeBlendSpace1D::set_blend_point_node(int p_point, const Ref<Anim
if (blend_points[p_point].node.is_valid()) {
blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed));
+ blend_points[p_point].node->disconnect("animation_node_renamed", callable_mp(this, &AnimationNodeBlendSpace1D::_animation_node_renamed));
+ blend_points[p_point].node->disconnect("animation_node_removed", callable_mp(this, &AnimationNodeBlendSpace1D::_animation_node_removed));
}
blend_points[p_point].node = p_node;
blend_points[p_point].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_point].node->connect("animation_node_renamed", callable_mp(this, &AnimationNodeBlendSpace1D::_animation_node_renamed), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_point].node->connect("animation_node_removed", callable_mp(this, &AnimationNodeBlendSpace1D::_animation_node_removed), CONNECT_REFERENCE_COUNTED);
emit_signal(SNAME("tree_changed"));
}
@@ -177,12 +191,16 @@ void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) {
ERR_FAIL_COND(blend_points[p_point].node.is_null());
blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed));
+ blend_points[p_point].node->disconnect("animation_node_renamed", callable_mp(this, &AnimationNodeBlendSpace1D::_animation_node_renamed));
+ blend_points[p_point].node->disconnect("animation_node_removed", callable_mp(this, &AnimationNodeBlendSpace1D::_animation_node_removed));
for (int i = p_point; i < blend_points_used - 1; i++) {
blend_points[i] = blend_points[i + 1];
}
blend_points_used--;
+
+ emit_signal(SNAME("animation_node_removed"), get_instance_id(), itos(p_point));
emit_signal(SNAME("tree_changed"));
}
diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h
index a1e9a7a764..4007df0ded 100644
--- a/scene/animation/animation_blend_space_1d.h
+++ b/scene/animation/animation_blend_space_1d.h
@@ -66,20 +66,21 @@ protected:
void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node);
- void _tree_changed();
-
StringName blend_position = "blend_position";
StringName closest = "closest";
StringName length_internal = "length_internal";
BlendMode blend_mode = BLEND_MODE_INTERPOLATED;
-protected:
bool sync = false;
void _validate_property(PropertyInfo &p_property) const;
static void _bind_methods();
+ virtual void _tree_changed() override;
+ virtual void _animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) override;
+ virtual void _animation_node_removed(const ObjectID &p_oid, const StringName &p_node) override;
+
public:
virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index c37d54961e..ae5b0d5779 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -81,6 +81,8 @@ void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_
blend_points[p_at_index].position = p_position;
blend_points[p_at_index].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_at_index].node->connect("animation_node_renamed", callable_mp(this, &AnimationNodeBlendSpace2D::_animation_node_renamed), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_at_index].node->connect("animation_node_removed", callable_mp(this, &AnimationNodeBlendSpace2D::_animation_node_removed), CONNECT_REFERENCE_COUNTED);
blend_points_used++;
_queue_auto_triangles();
@@ -100,9 +102,13 @@ void AnimationNodeBlendSpace2D::set_blend_point_node(int p_point, const Ref<Anim
if (blend_points[p_point].node.is_valid()) {
blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed));
+ blend_points[p_point].node->disconnect("animation_node_renamed", callable_mp(this, &AnimationNodeBlendSpace2D::_animation_node_renamed));
+ blend_points[p_point].node->disconnect("animation_node_removed", callable_mp(this, &AnimationNodeBlendSpace2D::_animation_node_removed));
}
blend_points[p_point].node = p_node;
blend_points[p_point].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_point].node->connect("animation_node_renamed", callable_mp(this, &AnimationNodeBlendSpace2D::_animation_node_renamed), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_point].node->connect("animation_node_removed", callable_mp(this, &AnimationNodeBlendSpace2D::_animation_node_removed), CONNECT_REFERENCE_COUNTED);
emit_signal(SNAME("tree_changed"));
}
@@ -122,6 +128,8 @@ void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
ERR_FAIL_COND(blend_points[p_point].node.is_null());
blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed));
+ blend_points[p_point].node->disconnect("animation_node_renamed", callable_mp(this, &AnimationNodeBlendSpace2D::_animation_node_renamed));
+ blend_points[p_point].node->disconnect("animation_node_removed", callable_mp(this, &AnimationNodeBlendSpace2D::_animation_node_removed));
for (int i = 0; i < triangles.size(); i++) {
bool erase = false;
@@ -144,6 +152,8 @@ void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
blend_points[i] = blend_points[i + 1];
}
blend_points_used--;
+
+ emit_signal(SNAME("animation_node_removed"), get_instance_id(), itos(p_point));
emit_signal(SNAME("tree_changed"));
}
@@ -598,10 +608,6 @@ Ref<AnimationNode> AnimationNodeBlendSpace2D::get_child_by_name(const StringName
return get_blend_point_node(p_name.operator String().to_int());
}
-void AnimationNodeBlendSpace2D::_tree_changed() {
- emit_signal(SNAME("tree_changed"));
-}
-
void AnimationNodeBlendSpace2D::set_blend_mode(BlendMode p_blend_mode) {
blend_mode = p_blend_mode;
}
@@ -618,6 +624,18 @@ bool AnimationNodeBlendSpace2D::is_using_sync() const {
return sync;
}
+void AnimationNodeBlendSpace2D::_tree_changed() {
+ AnimationRootNode::_tree_changed();
+}
+
+void AnimationNodeBlendSpace2D::_animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) {
+ AnimationRootNode::_animation_node_renamed(p_oid, p_old_name, p_new_name);
+}
+
+void AnimationNodeBlendSpace2D::_animation_node_removed(const ObjectID &p_oid, const StringName &p_node) {
+ AnimationRootNode::_animation_node_removed(p_oid, p_node);
+}
+
void AnimationNodeBlendSpace2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_blend_point", "node", "pos", "at_index"), &AnimationNodeBlendSpace2D::add_blend_point, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_blend_point_position", "point", "pos"), &AnimationNodeBlendSpace2D::set_blend_point_position);
diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h
index 044c93d9f6..a770bf01ee 100644
--- a/scene/animation/animation_blend_space_2d.h
+++ b/scene/animation/animation_blend_space_2d.h
@@ -85,14 +85,15 @@ protected:
void _update_triangles();
void _queue_auto_triangles();
- void _tree_changed();
-
-protected:
bool sync = false;
void _validate_property(PropertyInfo &p_property) const;
static void _bind_methods();
+ virtual void _tree_changed() override;
+ virtual void _animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) override;
+ virtual void _animation_node_removed(const ObjectID &p_oid, const StringName &p_node) override;
+
public:
virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 12a96c8679..3fe46b380f 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -721,12 +721,10 @@ void AnimationNodeTransition::get_parameter_list(List<PropertyInfo> *r_list) con
Variant AnimationNodeTransition::get_parameter_default_value(const StringName &p_parameter) const {
if (p_parameter == time || p_parameter == prev_xfading) {
return 0.0;
- } else if (p_parameter == prev_index) {
+ } else if (p_parameter == prev_index || p_parameter == current_index) {
return -1;
- } else if (p_parameter == transition_request || p_parameter == current_state) {
- return String();
} else {
- return 0;
+ return String();
}
}
@@ -748,6 +746,10 @@ void AnimationNodeTransition::set_input_count(int p_inputs) {
while (get_input_count() > p_inputs) {
remove_input(get_input_count() - 1);
}
+
+ pending_update = true;
+
+ emit_signal(SNAME("tree_changed")); // For updating connect activity map.
notify_property_list_changed();
}
@@ -764,6 +766,11 @@ void AnimationNodeTransition::remove_input(int p_index) {
AnimationNode::remove_input(p_index);
}
+bool AnimationNodeTransition::set_input_name(int p_input, const String &p_name) {
+ pending_update = true;
+ return AnimationNode::set_input_name(p_input, p_name);
+}
+
void AnimationNodeTransition::set_input_as_auto_advance(int p_input, bool p_enable) {
ERR_FAIL_INDEX(p_input, get_input_count());
input_data.write[p_input].auto_advance = p_enable;
@@ -819,6 +826,22 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
bool switched = false;
bool restart = false;
+ if (pending_update) {
+ if (cur_current_index < 0 || cur_current_index >= get_input_count()) {
+ set_parameter(prev_index, -1);
+ if (get_input_count() > 0) {
+ set_parameter(current_index, 0);
+ set_parameter(current_state, get_input_name(0));
+ } else {
+ set_parameter(current_index, -1);
+ set_parameter(current_state, StringName());
+ }
+ } else {
+ set_parameter(current_state, get_input_name(cur_current_index));
+ }
+ pending_update = false;
+ }
+
if (!cur_transition_request.is_empty()) {
int new_idx = find_input(cur_transition_request);
if (new_idx >= 0) {
@@ -985,6 +1008,8 @@ void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNod
emit_signal(SNAME("tree_changed"));
p_node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendTree::_tree_changed), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("animation_node_renamed", callable_mp(this, &AnimationNodeBlendTree::_animation_node_renamed), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("animation_node_removed", callable_mp(this, &AnimationNodeBlendTree::_animation_node_removed), CONNECT_REFERENCE_COUNTED);
p_node->connect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed).bind(p_name), CONNECT_REFERENCE_COUNTED);
}
@@ -1047,6 +1072,8 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
{
Ref<AnimationNode> node = nodes[p_name].node;
node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendTree::_tree_changed));
+ node->disconnect("animation_node_renamed", callable_mp(this, &AnimationNodeBlendTree::_animation_node_renamed));
+ node->disconnect("animation_node_removed", callable_mp(this, &AnimationNodeBlendTree::_animation_node_removed));
node->disconnect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed));
}
@@ -1061,6 +1088,7 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
}
}
+ emit_signal(SNAME("animation_node_removed"), get_instance_id(), p_name);
emit_changed();
emit_signal(SNAME("tree_changed"));
}
@@ -1087,6 +1115,7 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN
// Connection must be done with new name.
nodes[p_new_name].node->connect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed).bind(p_new_name), CONNECT_REFERENCE_COUNTED);
+ emit_signal(SNAME("animation_node_renamed"), get_instance_id(), p_name, p_new_name);
emit_signal(SNAME("tree_changed"));
}
@@ -1287,6 +1316,18 @@ void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) cons
p_list->push_back(PropertyInfo(Variant::ARRAY, "node_connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
}
+void AnimationNodeBlendTree::_tree_changed() {
+ AnimationRootNode::_tree_changed();
+}
+
+void AnimationNodeBlendTree::_animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) {
+ AnimationRootNode::_animation_node_renamed(p_oid, p_old_name, p_new_name);
+}
+
+void AnimationNodeBlendTree::_animation_node_removed(const ObjectID &p_oid, const StringName &p_node) {
+ AnimationRootNode::_animation_node_removed(p_oid, p_node);
+}
+
void AnimationNodeBlendTree::reset_state() {
graph_offset = Vector2();
nodes.clear();
@@ -1295,10 +1336,6 @@ void AnimationNodeBlendTree::reset_state() {
emit_signal(SNAME("tree_changed"));
}
-void AnimationNodeBlendTree::_tree_changed() {
- emit_signal(SNAME("tree_changed"));
-}
-
void AnimationNodeBlendTree::_node_changed(const StringName &p_node) {
ERR_FAIL_COND(!nodes.has(p_node));
nodes[p_node].connections.resize(nodes[p_node].node->get_input_count());
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 1e90952564..d4827180bb 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -296,6 +296,8 @@ class AnimationNodeTransition : public AnimationNodeSync {
Ref<Curve> xfade_curve;
bool allow_transition_to_self = false;
+ bool pending_update = false;
+
protected:
bool _get(const StringName &p_path, Variant &r_ret) const;
bool _set(const StringName &p_path, const Variant &p_value);
@@ -313,6 +315,7 @@ public:
virtual bool add_input(const String &p_name) override;
virtual void remove_input(int p_index) override;
+ virtual bool set_input_name(int p_input, const String &p_name) override;
void set_input_as_auto_advance(int p_input, bool p_enable);
bool is_input_set_as_auto_advance(int p_input) const;
@@ -358,7 +361,6 @@ class AnimationNodeBlendTree : public AnimationRootNode {
Vector2 graph_offset;
- void _tree_changed();
void _node_changed(const StringName &p_node);
void _initialize_node_tree();
@@ -369,6 +371,10 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void _tree_changed() override;
+ virtual void _animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) override;
+ virtual void _animation_node_removed(const ObjectID &p_oid, const StringName &p_node) override;
+
virtual void reset_state() override;
public:
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index ec28a5cca1..d19d3cc7a3 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -791,6 +791,8 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation
emit_signal(SNAME("tree_changed"));
p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("animation_node_renamed", callable_mp(this, &AnimationNodeStateMachine::_animation_node_renamed), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("animation_node_removed", callable_mp(this, &AnimationNodeStateMachine::_animation_node_removed), CONNECT_REFERENCE_COUNTED);
}
void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<AnimationNode> p_node) {
@@ -802,6 +804,8 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima
Ref<AnimationNode> node = states[p_name].node;
if (node.is_valid()) {
node->disconnect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed));
+ node->disconnect("animation_node_renamed", callable_mp(this, &AnimationNodeStateMachine::_animation_node_renamed));
+ node->disconnect("animation_node_removed", callable_mp(this, &AnimationNodeStateMachine::_animation_node_removed));
}
}
@@ -811,6 +815,8 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima
emit_signal(SNAME("tree_changed"));
p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("animation_node_renamed", callable_mp(this, &AnimationNodeStateMachine::_animation_node_renamed), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("animation_node_removed", callable_mp(this, &AnimationNodeStateMachine::_animation_node_removed), CONNECT_REFERENCE_COUNTED);
}
void AnimationNodeStateMachine::set_allow_transition_to_self(bool p_enable) {
@@ -884,10 +890,13 @@ void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
Ref<AnimationNode> node = states[p_name].node;
ERR_FAIL_COND(node.is_null());
node->disconnect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed));
+ node->disconnect("animation_node_renamed", callable_mp(this, &AnimationNodeStateMachine::_animation_node_renamed));
+ node->disconnect("animation_node_removed", callable_mp(this, &AnimationNodeStateMachine::_animation_node_removed));
}
states.erase(p_name);
+ emit_signal(SNAME("animation_node_removed"), get_instance_id(), p_name);
emit_changed();
emit_signal(SNAME("tree_changed"));
}
@@ -907,6 +916,7 @@ void AnimationNodeStateMachine::rename_node(const StringName &p_name, const Stri
_rename_transitions(p_name, p_new_name);
+ emit_signal(SNAME("animation_node_renamed"), get_instance_id(), p_name, p_new_name);
emit_changed();
emit_signal(SNAME("tree_changed"));
}
@@ -1365,7 +1375,15 @@ Vector2 AnimationNodeStateMachine::get_node_position(const StringName &p_name) c
void AnimationNodeStateMachine::_tree_changed() {
emit_changed();
- emit_signal(SNAME("tree_changed"));
+ AnimationRootNode::_tree_changed();
+}
+
+void AnimationNodeStateMachine::_animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) {
+ AnimationRootNode::_animation_node_renamed(p_oid, p_old_name, p_new_name);
+}
+
+void AnimationNodeStateMachine::_animation_node_removed(const ObjectID &p_oid, const StringName &p_node) {
+ AnimationRootNode::_animation_node_removed(p_oid, p_node);
}
void AnimationNodeStateMachine::_bind_methods() {
diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h
index 5c2a4d6264..5867b6c65a 100644
--- a/scene/animation/animation_node_state_machine.h
+++ b/scene/animation/animation_node_state_machine.h
@@ -207,7 +207,6 @@ private:
Vector2 graph_offset;
- void _tree_changed();
void _remove_transition(const Ref<AnimationNodeStateMachineTransition> p_transition);
void _rename_transitions(const StringName &p_name, const StringName &p_new_name);
bool _can_connect(const StringName &p_name, Vector<AnimationNodeStateMachine *> p_parents = Vector<AnimationNodeStateMachine *>());
@@ -221,6 +220,10 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const;
bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;
+ virtual void _tree_changed() override;
+ virtual void _animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) override;
+ virtual void _animation_node_removed(const ObjectID &p_oid, const StringName &p_node) override;
+
virtual void reset_state() override;
public:
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 2e25d685d6..8087ac6250 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -857,7 +857,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
HashMap<int, TrackNodeCache::PlayingAudioStreamInfo> &map = aa->playing_streams;
// Find stream.
int idx = -1;
- if (p_seeked) {
+ if (p_seeked || p_started) {
idx = a->track_find_key(i, p_time);
// Discard previous stream when seeking.
if (map.has(idx)) {
@@ -866,12 +866,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
}
} else {
List<int> to_play;
- if (p_started) {
- int first_key = a->track_find_key(i, p_prev_time, Animation::FIND_MODE_EXACT);
- if (first_key >= 0) {
- to_play.push_back(first_key);
- }
- }
+
a->track_get_key_indices_in_range(i, p_time, p_delta, &to_play, p_looped_flag);
if (to_play.size()) {
idx = to_play.back()->get();
@@ -888,6 +883,10 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
double end_ofs = a->audio_track_get_key_end_offset(i, idx);
double len = stream->get_length();
+ if (p_seeked || p_started) {
+ start_ofs += p_time - a->track_get_key_time(i, idx);
+ }
+
if (aa->object->call(SNAME("get_stream")) != aa->audio_stream) {
aa->object->call(SNAME("set_stream"), aa->audio_stream);
aa->audio_stream_playback.unref();
@@ -1286,6 +1285,8 @@ void AnimationPlayer::_animation_process(double p_delta) {
_animation_update_transforms();
if (end_reached) {
+ _clear_audio_streams();
+ _stop_playing_caches(false);
if (queued.size()) {
String old = playback.assigned;
play(queued.front()->get());
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index dd5bf31c66..7c2edef1de 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -453,6 +453,8 @@ void AnimationNode::_bind_methods() {
GDVIRTUAL_BIND(_has_filter);
ADD_SIGNAL(MethodInfo("tree_changed"));
+ ADD_SIGNAL(MethodInfo("animation_node_renamed", PropertyInfo(Variant::INT, "object_id"), PropertyInfo(Variant::STRING, "old_name"), PropertyInfo(Variant::STRING, "new_name")));
+ ADD_SIGNAL(MethodInfo("animation_node_removed", PropertyInfo(Variant::INT, "object_id"), PropertyInfo(Variant::STRING, "name")));
BIND_ENUM_CONSTANT(FILTER_IGNORE);
BIND_ENUM_CONSTANT(FILTER_PASS);
@@ -465,15 +467,33 @@ AnimationNode::AnimationNode() {
////////////////////
+void AnimationRootNode::_tree_changed() {
+ emit_signal(SNAME("tree_changed"));
+}
+
+void AnimationRootNode::_animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) {
+ emit_signal(SNAME("animation_node_renamed"), p_oid, p_old_name, p_new_name);
+}
+
+void AnimationRootNode::_animation_node_removed(const ObjectID &p_oid, const StringName &p_node) {
+ emit_signal(SNAME("animation_node_removed"), p_oid, p_node);
+}
+
+////////////////////
+
void AnimationTree::set_tree_root(const Ref<AnimationNode> &p_root) {
if (root.is_valid()) {
root->disconnect("tree_changed", callable_mp(this, &AnimationTree::_tree_changed));
+ root->disconnect("animation_node_renamed", callable_mp(this, &AnimationTree::_animation_node_renamed));
+ root->disconnect("animation_node_removed", callable_mp(this, &AnimationTree::_animation_node_removed));
}
root = p_root;
if (root.is_valid()) {
root->connect("tree_changed", callable_mp(this, &AnimationTree::_tree_changed));
+ root->connect("animation_node_renamed", callable_mp(this, &AnimationTree::_animation_node_renamed));
+ root->connect("animation_node_removed", callable_mp(this, &AnimationTree::_animation_node_removed));
}
properties_dirty = true;
@@ -1546,6 +1566,10 @@ void AnimationTree::_process_graph(double p_delta) {
double end_ofs = a->audio_track_get_key_end_offset(i, idx);
double len = stream->get_length();
+ if (seeked) {
+ start_ofs += time - a->track_get_key_time(i, idx);
+ }
+
if (t->object->call(SNAME("get_stream")) != t->audio_stream) {
t->object->call(SNAME("set_stream"), t->audio_stream);
t->audio_stream_playback.unref();
@@ -1982,11 +2006,46 @@ void AnimationTree::_tree_changed() {
properties_dirty = true;
}
+void AnimationTree::_animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name) {
+ ERR_FAIL_COND(!property_reference_map.has(p_oid));
+ String base_path = property_reference_map[p_oid];
+ String old_base = base_path + p_old_name;
+ String new_base = base_path + p_new_name;
+ for (const PropertyInfo &E : properties) {
+ if (E.name.begins_with(old_base)) {
+ String new_name = E.name.replace_first(old_base, new_base);
+ property_map[new_name] = property_map[E.name];
+ property_map.erase(E.name);
+ }
+ }
+
+ //update tree second
+ properties_dirty = true;
+ _update_properties();
+}
+
+void AnimationTree::_animation_node_removed(const ObjectID &p_oid, const StringName &p_node) {
+ ERR_FAIL_COND(!property_reference_map.has(p_oid));
+ String base_path = String(property_reference_map[p_oid]) + String(p_node);
+ for (const PropertyInfo &E : properties) {
+ if (E.name.begins_with(base_path)) {
+ property_map.erase(E.name);
+ }
+ }
+
+ //update tree second
+ properties_dirty = true;
+ _update_properties();
+}
+
void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node) {
ERR_FAIL_COND(node.is_null());
if (!property_parent_map.has(p_base_path)) {
property_parent_map[p_base_path] = HashMap<StringName, StringName>();
}
+ if (!property_reference_map.has(node->get_instance_id())) {
+ property_reference_map[node->get_instance_id()] = p_base_path;
+ }
if (node->get_input_count() && !input_activity_map.has(p_base_path)) {
Vector<Activity> activity;
@@ -2032,6 +2091,7 @@ void AnimationTree::_update_properties() {
}
properties.clear();
+ property_reference_map.clear();
property_parent_map.clear();
input_activity_map.clear();
input_activity_map_get.clear();
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index c5c2790fae..0540add85b 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -167,6 +167,11 @@ VARIANT_ENUM_CAST(AnimationNode::FilterAction)
class AnimationRootNode : public AnimationNode {
GDCLASS(AnimationRootNode, AnimationNode);
+protected:
+ virtual void _tree_changed();
+ virtual void _animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name);
+ virtual void _animation_node_removed(const ObjectID &p_oid, const StringName &p_node);
+
public:
AnimationRootNode() {}
};
@@ -326,9 +331,12 @@ private:
friend class AnimationNode;
bool properties_dirty = true;
void _tree_changed();
+ void _animation_node_renamed(const ObjectID &p_oid, const String &p_old_name, const String &p_new_name);
+ void _animation_node_removed(const ObjectID &p_oid, const StringName &p_node);
void _update_properties();
List<PropertyInfo> properties;
HashMap<StringName, HashMap<StringName, StringName>> property_parent_map;
+ HashMap<ObjectID, StringName> property_reference_map;
HashMap<StringName, Pair<Variant, bool>> property_map; // Property value and read-only flag.
struct Activity {
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index a930b8d972..ec75fcb665 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -3392,7 +3392,7 @@ void Control::_bind_methods() {
ADD_SIGNAL(MethodInfo("minimum_size_changed"));
ADD_SIGNAL(MethodInfo("theme_changed"));
- GDVIRTUAL_BIND(_has_point, "position");
+ GDVIRTUAL_BIND(_has_point, "point");
GDVIRTUAL_BIND(_structured_text_parser, "args", "text");
GDVIRTUAL_BIND(_get_minimum_size);
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 027c97b383..dc1d6cc73e 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -491,9 +491,11 @@ void OptionButton::show_popup() {
return;
}
- Size2 button_size = get_global_transform_with_canvas().get_scale() * get_size();
- popup->set_position(get_screen_position() + Size2(0, button_size.height));
- popup->set_size(Size2i(button_size.width, 0));
+ Rect2 rect = get_screen_rect();
+ rect.position.y += rect.size.height;
+ rect.size.height = 0;
+ popup->set_position(rect.position);
+ popup->set_size(rect.size);
// If not triggered by the mouse, start the popup with the checked item (or the first enabled one) focused.
if (current != NONE_SELECTED && !popup->is_item_disabled(current)) {
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 7091dd0388..cbb34a480b 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -614,7 +614,7 @@ void Viewport::_process_picking() {
physics_last_mouse_state.mouse_mask.clear_flag(mouse_button_to_mask(mb->get_button_index()));
// If touch mouse raised, assume we don't know last mouse pos until new events come
- if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) {
+ if (mb->get_device() == InputEvent::DEVICE_ID_EMULATION) {
physics_has_last_mousepos = false;
}
}
@@ -1348,7 +1348,7 @@ bool Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
Ref<InputEvent> ev = p_input;
// Returns true if an event should be impacted by a control's mouse filter.
- bool is_mouse_event = Ref<InputEventMouse>(p_input).is_valid();
+ bool is_pointer_event = Ref<InputEventMouse>(p_input).is_valid() || Ref<InputEventScreenDrag>(p_input).is_valid() || Ref<InputEventScreenTouch>(p_input).is_valid();
Ref<InputEventMouseButton> mb = p_input;
bool is_scroll_event = mb.is_valid() &&
@@ -1372,8 +1372,8 @@ bool Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
stopped = true;
break;
}
- if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP && is_mouse_event && !(is_scroll_event && control->data.force_pass_scroll_events)) {
- // Mouse events are stopped by default with MOUSE_FILTER_STOP, unless we have a scroll event and force_pass_scroll_events set to true
+ if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP && is_pointer_event && !(is_scroll_event && control->data.force_pass_scroll_events)) {
+ // Mouse, ScreenDrag and ScreenTouch events are stopped by default with MOUSE_FILTER_STOP, unless we have a scroll event and force_pass_scroll_events set to true
stopped = true;
break;
}
@@ -2290,6 +2290,7 @@ void Viewport::_drop_mouse_focus() {
mb->set_global_position(c->get_local_mouse_position());
mb->set_button_index(MouseButton(i + 1));
mb->set_pressed(false);
+ mb->set_device(InputEvent::DEVICE_ID_INTERNAL);
c->_call_gui_input(mb);
}
}
@@ -2401,6 +2402,7 @@ void Viewport::_post_gui_grab_click_focus() {
mb->set_position(click);
mb->set_button_index(MouseButton(i + 1));
mb->set_pressed(false);
+ mb->set_device(InputEvent::DEVICE_ID_INTERNAL);
gui.mouse_focus->_call_gui_input(mb);
}
}
@@ -2418,6 +2420,7 @@ void Viewport::_post_gui_grab_click_focus() {
mb->set_position(click);
mb->set_button_index(MouseButton(i + 1));
mb->set_pressed(true);
+ mb->set_device(InputEvent::DEVICE_ID_INTERNAL);
MessageQueue::get_singleton()->push_callable(callable_mp(gui.mouse_focus, &Control::_call_gui_input), mb);
}
}
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 33946246b0..9fcfb29ef7 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -647,6 +647,7 @@ void Window::update_mouse_cursor_shape() {
mm.instantiate();
mm->set_position(pos);
mm->set_global_position(xform.xform(pos));
+ mm->set_device(InputEvent::DEVICE_ID_INTERNAL);
push_input(mm);
}