diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.MdlTab.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.MdlTab.cs index f9e19599..bd599133 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.MdlTab.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.MdlTab.cs @@ -15,6 +15,8 @@ public partial class ModEditWindow public MdlFile Mdl { get; private set; } private List[] _attributes; + public bool ImportKeepMaterials; + public List? GamePaths { get; private set; } public int GamePathIndex; @@ -110,6 +112,7 @@ public partial class ModEditWindow /// Export model to an interchange format. /// Disk path to save the resulting file to. + /// .mdl game path to resolve satellite files such as skeletons relative to. public void Export(string outputPath, Utf8GamePath mdlPath) { IEnumerable skeletons; @@ -143,14 +146,37 @@ public partial class ModEditWindow { IoException = task.Exception?.ToString(); if (task is { IsCompletedSuccessfully: true, Result: not null }) - { - Initialize(task.Result); - _dirty = true; - } + FinalizeImport(task.Result); PendingIo = false; }); } + /// Finalise the import of a .mdl, applying any post-import transformations and state updates. + /// Model data to finalize. + private void FinalizeImport(MdlFile newMdl) + { + if (ImportKeepMaterials) + MergeMaterials(newMdl, Mdl); + + Initialize(newMdl); + _dirty = true; + } + + /// Merge material configuration from the source onto the target. + /// Model that will be updated. + /// Model to copy material configuration from. + public void MergeMaterials(MdlFile target, MdlFile source) + { + target.Materials = source.Materials; + + for (var meshIndex = 0; meshIndex < target.Meshes.Length; meshIndex++) + { + target.Meshes[meshIndex].MaterialIndex = meshIndex < source.Meshes.Length + ? source.Meshes[meshIndex].MaterialIndex + : (ushort)0; + } + } + /// Read a .sklb from the active collection or game. /// Game path to the .sklb to load. private SklbFile ReadSklb(string sklbPath) diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.cs index 4f9303f8..9a69a4e8 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.cs @@ -79,6 +79,8 @@ public partial class ModEditWindow using (var frame = ImRaii.FramedGroup("Import", size, headerPreIcon: FontAwesomeIcon.FileImport)) { + ImGui.Checkbox("Keep current materials", ref tab.ImportKeepMaterials); + if (ImGuiUtil.DrawDisabledButton("Import from glTF", Vector2.Zero, "Imports a glTF file, overriding the content of this mdl.", tab.PendingIo)) _fileDialog.OpenFilePicker("Load model from glTF.", "glTF{.gltf,.glb}", (success, paths) => @@ -86,7 +88,6 @@ public partial class ModEditWindow if (success && paths.Count > 0) tab.Import(paths[0]); }, 1, _mod!.ModPath.FullName, false); - ImGui.Dummy(new Vector2(ImGui.GetFrameHeight())); } if (_dragDropManager.CreateImGuiTarget("ModelDragDrop", out var files, out _) && GetFirstModel(files, out var importFile))