Browse Source

Merge pull request #60954 from V-Sekai/fix_ownership_of_created_nodes

Rémi Verschelde 3 years ago
parent
commit
f263e3ac81

+ 58 - 11
editor/plugins/mesh_instance_3d_editor_plugin.cpp

@@ -77,12 +77,14 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
 				StaticBody3D *body = memnew(StaticBody3D);
 				body->add_child(cshape, true);
 
-				Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner();
+				Node *owner = get_tree()->get_edited_scene_root();
 
 				ur->create_action(TTR("Create Static Trimesh Body"));
 				ur->add_do_method(node, "add_child", body, true);
 				ur->add_do_method(body, "set_owner", owner);
 				ur->add_do_method(cshape, "set_owner", owner);
+				ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", body);
+				ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape);
 				ur->add_do_reference(body);
 				ur->add_undo_method(node, "remove_child", body);
 				ur->commit_action();
@@ -112,11 +114,13 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
 				StaticBody3D *body = memnew(StaticBody3D);
 				body->add_child(cshape, true);
 
-				Node *owner = instance == get_tree()->get_edited_scene_root() ? instance : instance->get_owner();
+				Node *owner = get_tree()->get_edited_scene_root();
 
 				ur->add_do_method(instance, "add_child", body, true);
 				ur->add_do_method(body, "set_owner", owner);
 				ur->add_do_method(cshape, "set_owner", owner);
+				ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", body);
+				ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape);
 				ur->add_do_reference(body);
 				ur->add_undo_method(instance, "remove_child", body);
 			}
@@ -141,7 +145,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
 			cshape->set_shape(shape);
 			cshape->set_transform(node->get_transform());
 
-			Node *owner = node->get_owner();
+			Node *owner = get_tree()->get_edited_scene_root();
 
 			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
 
@@ -150,6 +154,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
 			ur->add_do_method(node->get_parent(), "add_child", cshape, true);
 			ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1);
 			ur->add_do_method(cshape, "set_owner", owner);
+			ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape);
 			ur->add_do_reference(cshape);
 			ur->add_undo_method(node->get_parent(), "remove_child", cshape);
 			ur->commit_action();
@@ -184,11 +189,12 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
 			cshape->set_shape(shape);
 			cshape->set_transform(node->get_transform());
 
-			Node *owner = node->get_owner();
+			Node *owner = get_tree()->get_edited_scene_root();
 
 			ur->add_do_method(node->get_parent(), "add_child", cshape, true);
 			ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1);
 			ur->add_do_method(cshape, "set_owner", owner);
+			ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape);
 			ur->add_do_reference(cshape);
 			ur->add_undo_method(node->get_parent(), "remove_child", cshape);
 
@@ -217,14 +223,17 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
 
 			for (int i = 0; i < shapes.size(); i++) {
 				CollisionShape3D *cshape = memnew(CollisionShape3D);
+				cshape->set_name("CollisionShape3D");
+
 				cshape->set_shape(shapes[i]);
 				cshape->set_transform(node->get_transform());
 
-				Node *owner = node->get_owner();
+				Node *owner = get_tree()->get_edited_scene_root();
 
 				ur->add_do_method(node->get_parent(), "add_child", cshape);
 				ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1);
 				ur->add_do_method(cshape, "set_owner", owner);
+				ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape);
 				ur->add_do_reference(cshape);
 				ur->add_undo_method(node->get_parent(), "remove_child", cshape);
 			}
@@ -243,13 +252,14 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
 			NavigationRegion3D *nmi = memnew(NavigationRegion3D);
 			nmi->set_navigation_mesh(nmesh);
 
-			Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner();
+			Node *owner = get_tree()->get_edited_scene_root();
 
 			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
 			ur->create_action(TTR("Create Navigation Mesh"));
 
 			ur->add_do_method(node, "add_child", nmi, true);
 			ur->add_do_method(nmi, "set_owner", owner);
+			ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", nmi);
 
 			ur->add_do_reference(nmi);
 			ur->add_undo_method(node, "remove_child", nmi);
@@ -267,13 +277,52 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
 				return;
 			}
 
-			Error err = mesh2->lightmap_unwrap(node->get_global_transform());
+			String path = mesh2->get_path();
+			int srpos = path.find("::");
+			if (srpos != -1) {
+				String base = path.substr(0, srpos);
+				if (ResourceLoader::get_resource_type(base) == "PackedScene") {
+					if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) {
+						err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it does not belong to the edited scene. Make it unique first."));
+						err_dialog->popup_centered();
+						return;
+					}
+				} else {
+					if (FileAccess::exists(path + ".import")) {
+						err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it belongs to another resource which was imported from another file type. Make it unique first."));
+						err_dialog->popup_centered();
+						return;
+					}
+				}
+			} else {
+				if (FileAccess::exists(path + ".import")) {
+					err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it was imported from another file type. Make it unique first."));
+					err_dialog->popup_centered();
+					return;
+				}
+			}
+
+			Ref<ArrayMesh> unwrapped_mesh = mesh2->duplicate(false);
+
+			Error err = unwrapped_mesh->lightmap_unwrap(node->get_global_transform());
 			if (err != OK) {
 				err_dialog->set_text(TTR("UV Unwrap failed, mesh may not be manifold?"));
 				err_dialog->popup_centered();
 				return;
 			}
 
+			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+			ur->create_action(TTR("Unwrap UV2"));
+
+			ur->add_do_method(node, "set_mesh", unwrapped_mesh);
+			ur->add_do_reference(node);
+			ur->add_do_reference(mesh2.ptr());
+
+			ur->add_undo_method(node, "set_mesh", mesh2);
+			ur->add_undo_reference(unwrapped_mesh.ptr());
+
+			ur->commit_action();
+
 		} break;
 		case MENU_OPTION_DEBUG_UV1: {
 			Ref<Mesh> mesh2 = node->get_mesh();
@@ -418,10 +467,7 @@ void MeshInstance3DEditor::_create_outline_mesh() {
 
 	MeshInstance3D *mi = memnew(MeshInstance3D);
 	mi->set_mesh(mesho);
-	Node *owner = node->get_owner();
-	if (get_tree()->get_edited_scene_root() == node) {
-		owner = node;
-	}
+	Node *owner = get_tree()->get_edited_scene_root();
 
 	UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
 
@@ -429,6 +475,7 @@ void MeshInstance3DEditor::_create_outline_mesh() {
 
 	ur->add_do_method(node, "add_child", mi, true);
 	ur->add_do_method(mi, "set_owner", owner);
+	ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", mi);
 
 	ur->add_do_reference(mi);
 	ur->add_undo_method(node, "remove_child", mi);

+ 37 - 26
editor/plugins/skeleton_3d_editor_plugin.cpp

@@ -357,7 +357,7 @@ void Skeleton3DEditor::pose_to_rest(const bool p_all_bones) {
 void Skeleton3DEditor::create_physical_skeleton() {
 	UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
 	ERR_FAIL_COND(!get_tree());
-	Node *owner = skeleton == get_tree()->get_edited_scene_root() ? skeleton : skeleton->get_owner();
+	Node *owner = get_tree()->get_edited_scene_root();
 
 	const int bc = skeleton->get_bone_count();
 
@@ -368,37 +368,47 @@ void Skeleton3DEditor::create_physical_skeleton() {
 	Vector<BoneInfo> bones_infos;
 	bones_infos.resize(bc);
 
-	for (int bone_id = 0; bc > bone_id; ++bone_id) {
-		const int parent = skeleton->get_bone_parent(bone_id);
+	if (bc > 0) {
+		ur->create_action(TTR("Create physical bones"), UndoRedo::MERGE_ALL);
+		for (int bone_id = 0; bc > bone_id; ++bone_id) {
+			const int parent = skeleton->get_bone_parent(bone_id);
 
-		if (parent < 0) {
-			bones_infos.write[bone_id].relative_rest = skeleton->get_bone_rest(bone_id);
-
-		} else {
-			const int parent_parent = skeleton->get_bone_parent(parent);
-
-			bones_infos.write[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id);
-
-			// Create physical bone on parent.
-			if (!bones_infos[parent].physical_bone) {
-				bones_infos.write[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
-
-				ur->create_action(TTR("Create physical bones"), UndoRedo::MERGE_ALL);
-				ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone);
-				ur->add_do_reference(bones_infos[parent].physical_bone);
-				ur->add_undo_method(skeleton, "remove_child", bones_infos[parent].physical_bone);
-				ur->commit_action();
+			if (parent < 0) {
+				bones_infos.write[bone_id].relative_rest = skeleton->get_bone_rest(bone_id);
+			} else {
+				const int parent_parent = skeleton->get_bone_parent(parent);
+
+				bones_infos.write[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id);
+
+				// Create physical bone on parent.
+				if (!bones_infos[parent].physical_bone) {
+					PhysicalBone3D *physical_bone = create_physical_bone(parent, bone_id, bones_infos);
+					if (physical_bone && physical_bone->get_child(0)) {
+						CollisionShape3D *collision_shape = Object::cast_to<CollisionShape3D>(physical_bone->get_child(0));
+						if (collision_shape) {
+							bones_infos.write[parent].physical_bone = physical_bone;
+
+							ur->add_do_method(skeleton, "add_child", physical_bone);
+							ur->add_do_method(physical_bone, "set_owner", owner);
+							ur->add_do_method(collision_shape, "set_owner", owner);
+							ur->add_do_property(physical_bone, "bone_name", skeleton->get_bone_name(parent));
+
+							// Create joint between parent of parent.
+							if (parent_parent != -1) {
+								ur->add_do_method(physical_bone, "set_joint_type", PhysicalBone3D::JOINT_TYPE_PIN);
+							}
 
-				bones_infos[parent].physical_bone->set_bone_name(skeleton->get_bone_name(parent));
-				bones_infos[parent].physical_bone->set_owner(owner);
-				bones_infos[parent].physical_bone->get_child(0)->set_owner(owner); // set shape owner
+							ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", physical_bone);
+							ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", collision_shape);
 
-				// Create joint between parent of parent.
-				if (-1 != parent_parent) {
-					bones_infos[parent].physical_bone->set_joint_type(PhysicalBone3D::JOINT_TYPE_PIN);
+							ur->add_do_reference(physical_bone);
+							ur->add_undo_method(skeleton, "remove_child", physical_bone);
+						}
+					}
 				}
 			}
 		}
+		ur->commit_action();
 	}
 }
 
@@ -414,6 +424,7 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi
 
 	CollisionShape3D *bone_shape = memnew(CollisionShape3D);
 	bone_shape->set_shape(bone_shape_capsule);
+	bone_shape->set_name("CollisionShape3D");
 
 	Transform3D capsule_transform;
 	capsule_transform.basis = Basis(Vector3(1, 0, 0), Vector3(0, 0, 1), Vector3(0, -1, 0));