Made BlendTree Editor more robust.
This commit is contained in:
parent
50243eafba
commit
89c3c38757
@ -477,11 +477,16 @@ void BLTAnimationNodeBlendTree::BLTBlendTreeGraph::add_node(const Ref<BLTAnimati
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BLTAnimationNodeBlendTree::BLTBlendTreeGraph::remove_node(const Ref<BLTAnimationNode> &node) {
|
void BLTAnimationNodeBlendTree::BLTBlendTreeGraph::remove_node(const Ref<BLTAnimationNode> &node) {
|
||||||
|
if (node == get_output_node()) {
|
||||||
|
// Output node not allowed to be removed
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int removed_node_index = find_node_index(node);
|
int removed_node_index = find_node_index(node);
|
||||||
assert(removed_node_index >= 0);
|
assert(removed_node_index >= 0);
|
||||||
|
|
||||||
// Remove all connections to and from this node
|
// Remove all connections to and from this node
|
||||||
for (uint32_t i = connections.size() - 1; i > 0; i--) {
|
for (int i = static_cast<int>(connections.size()) - 1; i >= 0; i--) {
|
||||||
if (connections[i].source_node == node || connections[i].target_node == node) {
|
if (connections[i].source_node == node || connections[i].target_node == node) {
|
||||||
remove_connection(connections[i].source_node, connections[i].target_node, connections[i].target_port_name);
|
remove_connection(connections[i].source_node, connections[i].target_node, connections[i].target_port_name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -210,9 +210,9 @@ func _on_blend_tree_graph_edit_node_selected(graph_node: Node) -> void:
|
|||||||
EditorInterface.get_inspector().edit(graph_node_to_blend_tree_node[graph_node])
|
EditorInterface.get_inspector().edit(graph_node_to_blend_tree_node[graph_node])
|
||||||
|
|
||||||
|
|
||||||
func _on_blend_tree_graph_edit_node_deselected(node: Node) -> void:
|
func _on_blend_tree_graph_edit_node_deselected(graph_node: Node) -> void:
|
||||||
if selected_nodes.has(node):
|
if selected_nodes.has(graph_node):
|
||||||
selected_nodes.erase(node)
|
selected_nodes.erase(graph_node)
|
||||||
|
|
||||||
|
|
||||||
func _on_blend_tree_graph_edit_popup_request(at_position: Vector2) -> void:
|
func _on_blend_tree_graph_edit_popup_request(at_position: Vector2) -> void:
|
||||||
@ -238,26 +238,41 @@ func _on_add_node_popup_menu_index_pressed(index: int) -> void:
|
|||||||
new_node_position = Vector2.INF
|
new_node_position = Vector2.INF
|
||||||
|
|
||||||
|
|
||||||
|
func _blend_tree_graph_edit_remove_node_connections(graph_node:GraphNode):
|
||||||
|
var node_connections:Array = []
|
||||||
|
|
||||||
|
for connection:Dictionary in blend_tree_graph_edit.connections:
|
||||||
|
if connection["from_node"] == graph_node.name or connection["to_node"] == graph_node.name:
|
||||||
|
node_connections.append(connection)
|
||||||
|
|
||||||
|
for node_connection:Dictionary in node_connections:
|
||||||
|
print("Removing connection %s" % str(node_connection))
|
||||||
|
blend_tree_graph_edit.disconnect_node(node_connection["from_node"], node_connection["from_port"], node_connection["to_node"], node_connection["to_port"])
|
||||||
|
|
||||||
|
|
||||||
func _on_blend_tree_graph_edit_delete_nodes_request(nodes: Array[StringName]) -> void:
|
func _on_blend_tree_graph_edit_delete_nodes_request(nodes: Array[StringName]) -> void:
|
||||||
for node_name:StringName in nodes:
|
for node_name:StringName in nodes:
|
||||||
print("remove node '%s'" % node_name)
|
print("remove node '%s'" % node_name)
|
||||||
var blend_tree_node:BLTAnimationNode = blend_tree.get_node(node_name)
|
var blend_tree_node:BLTAnimationNode = blend_tree.get_node(node_name)
|
||||||
|
|
||||||
if blend_tree_node == null:
|
if blend_tree_node == null:
|
||||||
push_error("Cannot delete node '%s': node not found." % node_name)
|
push_error("Cannot delete node '%s': node not found." % node_name)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if blend_tree_node == blend_tree.get_output_node():
|
||||||
|
push_warning("Output node not allowed to be removed.")
|
||||||
|
continue
|
||||||
|
|
||||||
var graph_node:GraphNode = blend_tree_node_to_graph_node[blend_tree_node]
|
var graph_node:GraphNode = blend_tree_node_to_graph_node[blend_tree_node]
|
||||||
blend_tree.remove_node(blend_tree_node)
|
blend_tree.remove_node(blend_tree_node)
|
||||||
blend_tree_node_to_graph_node.erase(blend_tree_node)
|
blend_tree_node_to_graph_node.erase(blend_tree_node)
|
||||||
|
|
||||||
|
_blend_tree_graph_edit_remove_node_connections(graph_node)
|
||||||
graph_node_to_blend_tree_node.erase(graph_node)
|
graph_node_to_blend_tree_node.erase(graph_node)
|
||||||
blend_tree_graph_edit.remove_child(graph_node)
|
blend_tree_graph_edit.remove_child(graph_node)
|
||||||
graph_node.queue_free()
|
_on_blend_tree_graph_edit_node_deselected(graph_node)
|
||||||
|
|
||||||
blend_tree_graph_edit.clear_connections()
|
EditorInterface.get_inspector().edit(null)
|
||||||
|
|
||||||
if node_name in selected_nodes.keys():
|
|
||||||
selected_nodes.erase(node_name)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_blend_tree_graph_edit_disconnection_request(from_node: StringName, from_port: int, to_node: StringName, to_port: int) -> void:
|
func _on_blend_tree_graph_edit_disconnection_request(from_node: StringName, from_port: int, to_node: StringName, to_port: int) -> void:
|
||||||
|
|||||||
@ -111,7 +111,7 @@ Some nodes have special names in the Blend Tree:
|
|||||||
Except for the output node of a Blend Tree the following properties hold:
|
Except for the output node of a Blend Tree the following properties hold:
|
||||||
|
|
||||||
* all Blend Tree nodes only operate on properties they own and any other data (e.g. inputs and outputs) are specified
|
* all Blend Tree nodes only operate on properties they own and any other data (e.g. inputs and outputs) are specified
|
||||||
via arguments to `SyncedAnimationNode::evaluate(context, inputs, output)` function of the node.
|
via arguments to `BLTAnimationNode::evaluate(context, inputs, output)` function of the node.
|
||||||
|
|
||||||
Advantages:
|
Advantages:
|
||||||
|
|
||||||
|
|||||||
@ -501,7 +501,7 @@ TEST_CASE_FIXTURE(SyncedAnimationGraphFixture, "[SceneTree][SyncedAnimationGraph
|
|||||||
REQUIRE(BLTAnimationNodeBlendTree::CONNECTION_OK == blend_tree_graph.add_connection(blend2_node_a, blend_tree_graph.get_output_node(), "Output"));
|
REQUIRE(BLTAnimationNodeBlendTree::CONNECTION_OK == blend_tree_graph.add_connection(blend2_node_a, blend_tree_graph.get_output_node(), "Output"));
|
||||||
REQUIRE(BLTAnimationNodeBlendTree::CONNECTION_OK == blend_tree_graph.add_connection(animation_sampler_node_a, blend2_node_a, "Input0"));
|
REQUIRE(BLTAnimationNodeBlendTree::CONNECTION_OK == blend_tree_graph.add_connection(animation_sampler_node_a, blend2_node_a, "Input0"));
|
||||||
|
|
||||||
// Connect nodes: Subgraph Blend2A, SamplerB, SamplerB
|
// Connect nodes: Subgraph Blend2A, SamplerB, SamplerC
|
||||||
REQUIRE(BLTAnimationNodeBlendTree::CONNECTION_OK == blend_tree_graph.add_connection(animation_sampler_node_b, blend2_node_b, "Input0"));
|
REQUIRE(BLTAnimationNodeBlendTree::CONNECTION_OK == blend_tree_graph.add_connection(animation_sampler_node_b, blend2_node_b, "Input0"));
|
||||||
REQUIRE(BLTAnimationNodeBlendTree::CONNECTION_OK == blend_tree_graph.add_connection(animation_sampler_node_c, blend2_node_b, "Input1"));
|
REQUIRE(BLTAnimationNodeBlendTree::CONNECTION_OK == blend_tree_graph.add_connection(animation_sampler_node_c, blend2_node_b, "Input1"));
|
||||||
|
|
||||||
@ -537,6 +537,7 @@ TEST_CASE_FIXTURE(SyncedAnimationGraphFixture, "[SceneTree][SyncedAnimationGraph
|
|||||||
CHECK(blend_tree_graph.node_connection_info[0].input_subtree_node_indices.size() == 6);
|
CHECK(blend_tree_graph.node_connection_info[0].input_subtree_node_indices.size() == 6);
|
||||||
CHECK(blend_tree_graph.node_connection_info[blend2_node_a_index_pre_remove].input_subtree_node_indices.size() == 5);
|
CHECK(blend_tree_graph.node_connection_info[blend2_node_a_index_pre_remove].input_subtree_node_indices.size() == 5);
|
||||||
|
|
||||||
|
SUBCASE("Remove animation_sampler_node_a") {
|
||||||
blend_tree_graph.remove_node(animation_sampler_node_a);
|
blend_tree_graph.remove_node(animation_sampler_node_a);
|
||||||
|
|
||||||
for (const BLTBlendTreeConnection &connection : blend_tree_graph.connections) {
|
for (const BLTBlendTreeConnection &connection : blend_tree_graph.connections) {
|
||||||
@ -559,6 +560,31 @@ TEST_CASE_FIXTURE(SyncedAnimationGraphFixture, "[SceneTree][SyncedAnimationGraph
|
|||||||
CHECK(blend_tree_graph.node_connection_info[blend2_node_b_index_post_remove].input_subtree_node_indices.has(blend2_node_b_index_post_remove));
|
CHECK(blend_tree_graph.node_connection_info[blend2_node_b_index_post_remove].input_subtree_node_indices.has(blend2_node_b_index_post_remove));
|
||||||
CHECK(blend_tree_graph.node_connection_info[blend2_node_b_index_post_remove].input_subtree_node_indices.has(animation_sampler_node_b_index_post_remove));
|
CHECK(blend_tree_graph.node_connection_info[blend2_node_b_index_post_remove].input_subtree_node_indices.has(animation_sampler_node_b_index_post_remove));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBCASE("Remove blend2_node_a") {
|
||||||
|
blend_tree_graph.remove_node(blend2_node_a);
|
||||||
|
|
||||||
|
for (const BLTBlendTreeConnection &connection : blend_tree_graph.connections) {
|
||||||
|
bool is_connection_with_removed_node = connection.source_node == blend2_node_a || connection.target_node == blend2_node_a;
|
||||||
|
CHECK(is_connection_with_removed_node == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int animation_sampler_node_b_index_post_remove = blend_tree_graph.find_node_index(animation_sampler_node_b);
|
||||||
|
int animation_sampler_node_c_index_post_remove = blend_tree_graph.find_node_index(animation_sampler_node_c);
|
||||||
|
int blend2_node_b_index_post_remove = blend_tree_graph.find_node_index(blend2_node_b);
|
||||||
|
|
||||||
|
CHECK(blend_tree_graph.find_node_index(blend2_node_a) == -1);
|
||||||
|
CHECK(blend2_node_b_index_post_remove == blend2_node_b_index_pre_remove - 1);
|
||||||
|
CHECK(animation_sampler_node_b_index_post_remove == animation_sampler_node_b_index_pre_remove);
|
||||||
|
|
||||||
|
CHECK(blend_tree_graph.node_connection_info[0].input_subtree_node_indices.size() == 1);
|
||||||
|
CHECK(blend_tree_graph.node_connection_info[blend2_node_b_index_post_remove].input_subtree_node_indices.size() == 3);
|
||||||
|
blend_tree_graph.node_connection_info[blend2_node_b_index_post_remove]._print_subtree();
|
||||||
|
CHECK(blend_tree_graph.node_connection_info[blend2_node_b_index_post_remove].input_subtree_node_indices.has(blend2_node_b_index_post_remove));
|
||||||
|
CHECK(blend_tree_graph.node_connection_info[blend2_node_b_index_post_remove].input_subtree_node_indices.has(animation_sampler_node_b_index_post_remove));
|
||||||
|
CHECK(blend_tree_graph.node_connection_info[blend2_node_b_index_post_remove].input_subtree_node_indices.has(animation_sampler_node_c_index_post_remove));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace TestSyncedAnimationGraph
|
} //namespace TestSyncedAnimationGraph
|
||||||
Loading…
x
Reference in New Issue
Block a user