diff --git a/Penumbra/Import/Models/ModelManager.cs b/Penumbra/Import/Models/ModelManager.cs index 217450dd..35a5e53e 100644 --- a/Penumbra/Import/Models/ModelManager.cs +++ b/Penumbra/Import/Models/ModelManager.cs @@ -93,7 +93,6 @@ public sealed class ModelManager : SingleTaskQueue, IDisposable if (_sklb == null) return null; - // TODO: work out how i handle this havok deal. running it outside the framework causes an immediate ctd. var xmlTask = _manager._framework.RunOnFrameworkThread(() => HavokConverter.HkxToXml(_sklb.Skeleton)); xmlTask.Wait(cancel); var xml = xmlTask.Result; diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.MdlTab.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.MdlTab.cs index ba6435c7..38c1c6bd 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.MdlTab.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.MdlTab.cs @@ -13,8 +13,10 @@ public partial class ModEditWindow private ModEditWindow _edit; public readonly MdlFile Mdl; - public List? GamePaths { get; private set ;} private readonly List[] _attributes; + + public List? GamePaths { get; private set ;} + public int GamePathIndex; public bool PendingIo { get; private set; } = false; public string? IoException { get; private set; } = null; diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.cs index 9af2dd91..aa69953b 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.Models.cs @@ -34,16 +34,7 @@ public partial class ModEditWindow ); } - if (tab.GamePaths != null) - if (ImGuiUtil.DrawDisabledButton("bingo bango", Vector2.Zero, "description", tab.PendingIo)) - tab.Export("C:\\Users\\ackwell\\blender\\gltf-tests\\bingo.gltf", tab.GamePaths.First()); - ImGui.TextUnformatted("blippity blap"); - if (tab.GamePaths != null) - foreach (var gamePath in tab.GamePaths) - ImGui.TextUnformatted(gamePath.ToString()); - - if (tab.IoException != null) - ImGui.TextUnformatted(tab.IoException); + DrawExport(tab, disabled); var ret = false; @@ -58,6 +49,68 @@ public partial class ModEditWindow return !disabled && ret; } + private void DrawExport(MdlTab tab, bool disabled) + { + // IO on a disabled panel doesn't really make sense. + if (disabled) + return; + + if (!ImGui.CollapsingHeader("Export")) + return; + + if (tab.GamePaths == null) + { + if (tab.IoException == null) + ImGui.TextUnformatted("Resolving model game paths."); + else + ImGuiUtil.TextWrapped(tab.IoException); + + return; + } + + DrawGamePathCombo(tab); + + if (ImGuiUtil.DrawDisabledButton("Export to glTF", Vector2.Zero, "Exports this mdl file to glTF, for use in 3D authoring applications.", tab.PendingIo)) + { + var gamePath = tab.GamePaths[tab.GamePathIndex]; + + _fileDialog.OpenSavePicker( + "Save model as glTF.", + ".gltf", + Path.GetFileNameWithoutExtension(gamePath.Filename().ToString()), + ".gltf", + (valid, path) => { + if (!valid) + return; + + tab.Export(path, gamePath); + }, + _mod!.ModPath.FullName, + false + ); + } + + if (tab.IoException != null) + ImGuiUtil.TextWrapped(tab.IoException); + + return; + } + + private void DrawGamePathCombo(MdlTab tab) + { + using var combo = ImRaii.Combo("Game Path", tab.GamePaths![tab.GamePathIndex].ToString()); + if (!combo) + return; + + foreach (var (path, index) in tab.GamePaths.WithIndex()) + { + if (!ImGui.Selectable(path.ToString(), index == tab.GamePathIndex)) + continue; + + tab.GamePathIndex = index; + } + } + private bool DrawModelMaterialDetails(MdlTab tab, bool disabled) { if (!ImGui.CollapsingHeader("Materials"))