Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion editor/animation/animation_blend_space_1d_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,8 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
}

void AnimationNodeBlendSpace1DEditor::_update_space() {
if (updating) {
// edge case when undoing action after editor has changed
if (updating || !blend_space.is_valid()) {
return;
}

Expand Down
15 changes: 9 additions & 6 deletions editor/animation/animation_blend_space_2d_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ void AnimationNodeBlendSpace2DEditor::_snap_toggled() {
}

void AnimationNodeBlendSpace2DEditor::_update_space() {
if (updating) {
if (updating || !blend_space.is_valid()) {
return;
}

Expand Down Expand Up @@ -852,12 +852,15 @@ void AnimationNodeBlendSpace2DEditor::_erase_selected() {
undo_redo->add_do_method(blend_space.ptr(), "remove_blend_point", selected_point);
undo_redo->add_undo_method(blend_space.ptr(), "add_blend_point", node, position, selected_point, point_name);

// if auto triangles is off
//restore triangles using this point
for (int i = 0; i < blend_space->get_triangle_count(); i++) {
for (int j = 0; j < 3; j++) {
if (blend_space->get_triangle_point(i, j) == selected_point) {
undo_redo->add_undo_method(blend_space.ptr(), "add_triangle", blend_space->get_triangle_point(i, 0), blend_space->get_triangle_point(i, 1), blend_space->get_triangle_point(i, 2), i);
break;
if (!blend_space->get_auto_triangles()) {
for (int i = 0; i < blend_space->get_triangle_count(); i++) {
for (int j = 0; j < 3; j++) {
if (blend_space->get_triangle_point(i, j) == selected_point) {
undo_redo->add_undo_method(blend_space.ptr(), "add_triangle", blend_space->get_triangle_point(i, 0), blend_space->get_triangle_point(i, 1), blend_space->get_triangle_point(i, 2), i);
break;
}
}
}
}
Expand Down
18 changes: 12 additions & 6 deletions scene/animation/animation_blend_space_1d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,12 @@ void AnimationNodeBlendSpace1D::add_blend_point(const Ref<AnimationRootNode> &p_
#else
ERR_FAIL_COND(p_name == StringName());
#endif
ERR_FAIL_COND(p_name.is_empty() || String(p_name).contains_char('.') || String(p_name).contains_char('/'));
ERR_FAIL_COND_MSG(find_blend_point_by_name(p_name) != -1, "Blend point name must be unique.");
if (p_at_index == -1 || p_at_index == blend_points_used) {
p_at_index = blend_points_used;
} else {
for (int i = blend_points_used - 1; i > p_at_index; i--) {
for (int i = blend_points_used; i > p_at_index; i--) {
blend_points[i] = blend_points[i - 1];
}
}
Expand Down Expand Up @@ -207,19 +209,21 @@ void AnimationNodeBlendSpace1D::set_blend_point_node(int p_point, const Ref<Anim
}

float AnimationNodeBlendSpace1D::get_blend_point_position(int p_point) const {
ERR_FAIL_INDEX_V(p_point, MAX_BLEND_POINTS, 0);
ERR_FAIL_INDEX_V(p_point, blend_points_used, 0);
return blend_points[p_point].position;
}

Ref<AnimationRootNode> AnimationNodeBlendSpace1D::get_blend_point_node(int p_point) const {
ERR_FAIL_INDEX_V(p_point, MAX_BLEND_POINTS, Ref<AnimationRootNode>());
ERR_FAIL_INDEX_V(p_point, blend_points_used, Ref<AnimationRootNode>());
return blend_points[p_point].node;
}

void AnimationNodeBlendSpace1D::set_blend_point_name(int p_point, const StringName &p_name) {
ERR_FAIL_INDEX(p_point, blend_points_used);
String new_name = p_name;
ERR_FAIL_COND(new_name.is_empty() || new_name.contains_char('.') || new_name.contains_char('/'));
int existing_index = find_blend_point_by_name(p_name);
ERR_FAIL_COND_MSG(existing_index != -1 && existing_index != p_point, "Blend point name must be unique.");

String old_name = blend_points[p_point].name;
if (new_name != old_name) {
Expand Down Expand Up @@ -247,6 +251,7 @@ void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) {
ERR_FAIL_INDEX(p_point, blend_points_used);

ERR_FAIL_COND(blend_points[p_point].node.is_null());
String removed_name = blend_points[p_point].name;
_remove_node(blend_points[p_point].node);

for (int i = p_point; i < blend_points_used - 1; i++) {
Expand All @@ -255,10 +260,10 @@ void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) {

blend_points_used--;

blend_points[blend_points_used].name = StringName();
blend_points[blend_points_used].reset();
lengths_dirty = true;

emit_signal(SNAME("animation_node_removed"), get_instance_id(), itos(p_point));
emit_signal(SNAME("animation_node_removed"), get_instance_id(), removed_name);
_tree_changed();
}

Expand Down Expand Up @@ -556,8 +561,9 @@ AnimationNode::NodeTimeInfo AnimationNodeBlendSpace1D::_process(ProcessState &p_
}

// Special case for discrete carry.
AnimationNodeInstance *instance_current_closest = p_instance.get_child_instance_by_path_or_null(get_blend_point_name(cur_closest));
if (new_closest != cur_closest && new_closest != -1 && cur_closest != -1 && blend_mode == BLEND_MODE_DISCRETE_CARRY && sync_mode < SYNC_MODE_CYCLIC_MUTABLE) {
// I don't even think these can (or should) ever be null.
AnimationNodeInstance *instance_current_closest = p_instance.get_child_instance_by_path_or_null(get_blend_point_name(cur_closest));
AnimationNodeInstance *instance_new_closest = p_instance.get_child_instance_by_path_or_null(get_blend_point_name(new_closest));
NodeTimeInfo from;
// For ping-pong loop.
Expand Down
6 changes: 6 additions & 0 deletions scene/animation/animation_blend_space_1d.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode {
StringName name;
Ref<AnimationRootNode> node;
float position = 0.0;

void reset() {
name = StringName();
node = Ref<AnimationRootNode>();
position = 0.0;
}
};

BlendPoint blend_points[MAX_BLEND_POINTS];
Expand Down
21 changes: 16 additions & 5 deletions scene/animation/animation_blend_space_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_
ERR_FAIL_COND(p_name == StringName());
#endif

ERR_FAIL_COND(p_name.is_empty() || String(p_name).contains_char('.') || String(p_name).contains_char('/'));
ERR_FAIL_COND_MSG(find_blend_point_by_name(p_name) != -1, "Blend point name must be unique.");
if (p_at_index == -1 || p_at_index == blend_points_used) {
p_at_index = blend_points_used;
} else {
for (int i = blend_points_used - 1; i > p_at_index; i--) {
for (int i = blend_points_used; i > p_at_index; i--) {
blend_points[i] = blend_points[i - 1];
}
for (int i = 0; i < triangles.size(); i++) {
Expand Down Expand Up @@ -126,19 +128,21 @@ void AnimationNodeBlendSpace2D::set_blend_point_node(int p_point, const Ref<Anim
}

Vector2 AnimationNodeBlendSpace2D::get_blend_point_position(int p_point) const {
ERR_FAIL_INDEX_V(p_point, MAX_BLEND_POINTS, Vector2());
ERR_FAIL_INDEX_V(p_point, blend_points_used, Vector2());
return blend_points[p_point].position;
}

Ref<AnimationRootNode> AnimationNodeBlendSpace2D::get_blend_point_node(int p_point) const {
ERR_FAIL_INDEX_V(p_point, MAX_BLEND_POINTS, Ref<AnimationRootNode>());
ERR_FAIL_INDEX_V(p_point, blend_points_used, Ref<AnimationRootNode>());
return blend_points[p_point].node;
}

void AnimationNodeBlendSpace2D::set_blend_point_name(int p_point, const StringName &p_name) {
ERR_FAIL_INDEX(p_point, blend_points_used);
String new_name = p_name;
ERR_FAIL_COND(new_name.is_empty() || new_name.contains_char('.') || new_name.contains_char('/'));
int existing_index = find_blend_point_by_name(p_name);
ERR_FAIL_COND_MSG(existing_index != -1 && existing_index != p_point, "Blend point name must be unique.");

String old_name = blend_points[p_point].name;
if (new_name != old_name) {
Expand Down Expand Up @@ -166,6 +170,7 @@ void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
ERR_FAIL_INDEX(p_point, blend_points_used);

ERR_FAIL_COND(blend_points[p_point].node.is_null());
String removed_name = blend_points[p_point].name;
_remove_node(blend_points[p_point].node);

for (int i = 0; i < triangles.size(); i++) {
Expand All @@ -190,10 +195,12 @@ void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
}
blend_points_used--;

blend_points[blend_points_used].name = StringName();
blend_points[blend_points_used].reset();
lengths_dirty = true;

emit_signal(SNAME("animation_node_removed"), get_instance_id(), itos(p_point));
_queue_auto_triangles();

emit_signal(SNAME("animation_node_removed"), get_instance_id(), removed_name);
_tree_changed();
}

Expand Down Expand Up @@ -293,6 +300,7 @@ void AnimationNodeBlendSpace2D::add_triangle(int p_x, int p_y, int p_z, int p_at
} else {
triangles.insert(p_at_index, t);
}
_node_updated(get_instance_id());
}

int AnimationNodeBlendSpace2D::get_triangle_point(int p_triangle, int p_point) {
Expand All @@ -307,6 +315,7 @@ void AnimationNodeBlendSpace2D::remove_triangle(int p_triangle) {
ERR_FAIL_INDEX(p_triangle, triangles.size());

triangles.remove_at(p_triangle);
_node_updated(get_instance_id());
}

int AnimationNodeBlendSpace2D::get_triangle_count() const {
Expand Down Expand Up @@ -458,6 +467,7 @@ void AnimationNodeBlendSpace2D::_update_triangles() {
triangles.clear();
if (blend_points_used < 3) {
emit_signal(SNAME("triangles_updated"));
_node_updated(get_instance_id());
return;
}

Expand All @@ -473,6 +483,7 @@ void AnimationNodeBlendSpace2D::_update_triangles() {
add_triangle(tr[i].points[0], tr[i].points[1], tr[i].points[2]);
}
emit_signal(SNAME("triangles_updated"));
_node_updated(get_instance_id());
}

Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) {
Expand Down
6 changes: 6 additions & 0 deletions scene/animation/animation_blend_space_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ class AnimationNodeBlendSpace2D : public AnimationRootNode {
StringName name;
Ref<AnimationRootNode> node;
Vector2 position;

void reset() {
name = StringName();
node = Ref<AnimationRootNode>();
position = Vector2();
}
};

BlendPoint blend_points[MAX_BLEND_POINTS];
Expand Down
18 changes: 17 additions & 1 deletion scene/animation/animation_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,14 +781,30 @@ void AnimationTree::_animation_node_renamed(const ObjectID &p_oid, const String
}

void AnimationTree::_animation_node_removed(const ObjectID &p_oid, const StringName &p_node) {
Object *obj = ObjectDB::get_instance(p_oid);
bool is_blend_space = obj && (obj->is_class("AnimationNodeBlendSpace1D") || obj->is_class("AnimationNodeBlendSpace2D"));

for (const StringName &parent_path : instance_paths[p_oid]) {
String base_path = String(parent_path) + String(p_node);
String base_path = String(parent_path) + String(p_node) + "/";

for (const PropertyInfo &E : properties) {
if (E.name.begins_with(base_path)) {
property_map.erase(E.name);
}
}

// When a child is removed from the blend space, the indices may shift,
// so the "closest" parameter may point to the wrong child or be out of bounds.
//
// The proper fix is to change the "closest" parameter from the child's index to the child's name.
// At the moment, we have to reset it even if the closest child was not the one that changed.
//
// TODO: In a future release consider removing "closest" (int) and replacing it with "closest_name" (StringName).
if (is_blend_space) {
if (Pair<Variant, bool> *closest_param = property_map.getptr(String(parent_path) + "closest")) {
closest_param->first = -1;
}
}
}

// Update tree second.
Expand Down
Loading