Merge pull request #83498 from SaracenOne/mesh_unwrap_rules

Mesh instance UV2 unwrapping improvements
This commit is contained in:
Rémi Verschelde 2023-10-28 12:30:22 +02:00
commit fe64786a91
No known key found for this signature in database
GPG Key ID: C3336907360768E1
2 changed files with 65 additions and 35 deletions

View File

@ -1279,11 +1279,9 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String
return; return;
} }
} }
} else { } else if (FileAccess::exists(path + ".import")) {
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."));
show_warning(TTR("This resource can't be saved because it was imported from another file. Make it unique first.")); return;
return;
}
} }
} }
@ -4063,11 +4061,9 @@ bool EditorNode::is_resource_read_only(Ref<Resource> 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. // 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; return false;

View File

@ -301,7 +301,40 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
ur->commit_action(); ur->commit_action();
} break; } break;
case MENU_OPTION_CREATE_UV2: { case MENU_OPTION_CREATE_UV2: {
Ref<PrimitiveMesh> primitive_mesh = Object::cast_to<PrimitiveMesh>(*node->get_mesh()); Ref<Mesh> 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<PrimitiveMesh> primitive_mesh = mesh2;
if (primitive_mesh.is_valid()) { if (primitive_mesh.is_valid()) {
EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
ur->create_action(TTR("Unwrap UV2")); 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->add_undo_method(*primitive_mesh, "set_add_uv2", primitive_mesh->get_add_uv2());
ur->commit_action(); ur->commit_action();
} else { } else {
Ref<ArrayMesh> mesh2 = node->get_mesh(); Ref<ArrayMesh> array_mesh = mesh2;
if (!mesh2.is_valid()) { if (!array_mesh.is_valid()) {
err_dialog->set_text(TTR("Contained Mesh is not of type ArrayMesh.")); err_dialog->set_text(TTR("Contained Mesh is not of type ArrayMesh."));
err_dialog->popup_centered(); err_dialog->popup_centered();
return; return;
} }
String path = mesh2->get_path(); // Preemptively evaluate common fail cases for lightmap unwrapping.
int srpos = path.find("::"); {
if (srpos != -1) { if (array_mesh->get_blend_shape_count() > 0) {
String base = path.substr(0, srpos); err_dialog->set_text(TTR("Can't unwrap mesh with blend shapes."));
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(); err_dialog->popup_centered();
return; 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<ArrayMesh> unwrapped_mesh = mesh2->duplicate(false); Ref<ArrayMesh> unwrapped_mesh = array_mesh->duplicate(false);
Error err = unwrapped_mesh->lightmap_unwrap(node->get_global_transform()); Error err = unwrapped_mesh->lightmap_unwrap(node->get_global_transform());
if (err != OK) { 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_method(node, "set_mesh", unwrapped_mesh);
ur->add_do_reference(node); 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->add_undo_reference(unwrapped_mesh.ptr());
ur->commit_action(); ur->commit_action();