diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 4f878380142..f73eb814730 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1279,11 +1279,9 @@ void EditorNode::save_resource_as(const Ref &p_resource, const String return; } } - } else { - if (FileAccess::exists(path + ".import")) { - show_warning(TTR("This resource can't be saved because it was imported from another file. Make it unique first.")); - return; - } + } else if (FileAccess::exists(path + ".import")) { + show_warning(TTR("This resource can't be saved because it was imported from another file. Make it unique first.")); + return; } } @@ -4063,11 +4061,9 @@ bool EditorNode::is_resource_read_only(Ref p_resource, bool p_foreign_ } } } - } else { + } else if (FileAccess::exists(path + ".import")) { // The resource is not a subresource, but if it has an .import file, it's imported so treat it as read only. - if (FileAccess::exists(path + ".import")) { - return true; - } + return true; } return false; diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index eec375cbea8..fc220c56a81 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -301,7 +301,40 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->commit_action(); } break; case MENU_OPTION_CREATE_UV2: { - Ref primitive_mesh = Object::cast_to(*node->get_mesh()); + Ref mesh2 = node->get_mesh(); + if (!mesh.is_valid()) { + err_dialog->set_text(TTR("No mesh to unwrap.")); + err_dialog->popup_centered(); + return; + } + + // Test if we are allowed to unwrap this mesh resource. + 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 primitive_mesh = mesh2; if (primitive_mesh.is_valid()) { EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); ur->create_action(TTR("Unwrap UV2")); @@ -309,39 +342,40 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_undo_method(*primitive_mesh, "set_add_uv2", primitive_mesh->get_add_uv2()); ur->commit_action(); } else { - Ref mesh2 = node->get_mesh(); - if (!mesh2.is_valid()) { + Ref array_mesh = mesh2; + if (!array_mesh.is_valid()) { err_dialog->set_text(TTR("Contained Mesh is not of type ArrayMesh.")); err_dialog->popup_centered(); return; } - 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.")); + // Preemptively evaluate common fail cases for lightmap unwrapping. + { + if (array_mesh->get_blend_shape_count() > 0) { + err_dialog->set_text(TTR("Can't unwrap mesh with blend shapes.")); err_dialog->popup_centered(); return; } + + for (int i = 0; i < array_mesh->get_surface_count(); i++) { + Mesh::PrimitiveType primitive = array_mesh->surface_get_primitive_type(i); + + if (primitive != Mesh::PRIMITIVE_TRIANGLES) { + err_dialog->set_text(TTR("Only triangles are supported for lightmap unwrap.")); + err_dialog->popup_centered(); + return; + } + + uint64_t format = array_mesh->surface_get_format(i); + if (format & Mesh::ArrayFormat::ARRAY_FORMAT_NORMAL) { + err_dialog->set_text(TTR("Normals are required for lightmap unwrap.")); + err_dialog->popup_centered(); + return; + } + } } - Ref unwrapped_mesh = mesh2->duplicate(false); + Ref unwrapped_mesh = array_mesh->duplicate(false); Error err = unwrapped_mesh->lightmap_unwrap(node->get_global_transform()); if (err != OK) { @@ -355,9 +389,9 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_do_method(node, "set_mesh", unwrapped_mesh); ur->add_do_reference(node); - ur->add_do_reference(mesh2.ptr()); + ur->add_do_reference(array_mesh.ptr()); - ur->add_undo_method(node, "set_mesh", mesh2); + ur->add_undo_method(node, "set_mesh", array_mesh); ur->add_undo_reference(unwrapped_mesh.ptr()); ur->commit_action();