mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Clean up model import UI/wiring
This commit is contained in:
parent
1a88cefd52
commit
b62bc44564
3 changed files with 72 additions and 31 deletions
|
|
@ -10,7 +10,7 @@ using SharpGLTF.Schema2;
|
|||
|
||||
namespace Penumbra.Import.Models;
|
||||
|
||||
public sealed class ModelManager(IFramework framework, GamePathParser _parser) : SingleTaskQueue, IDisposable
|
||||
public sealed class ModelManager(IFramework framework, GamePathParser parser) : SingleTaskQueue, IDisposable
|
||||
{
|
||||
private readonly IFramework _framework = framework;
|
||||
|
||||
|
|
@ -29,17 +29,17 @@ public sealed class ModelManager(IFramework framework, GamePathParser _parser) :
|
|||
public Task ExportToGltf(MdlFile mdl, SklbFile? sklb, string outputPath)
|
||||
=> Enqueue(new ExportToGltfAction(this, mdl, sklb, outputPath));
|
||||
|
||||
public Task<MdlFile> ImportGltf()
|
||||
public Task<MdlFile?> ImportGltf(string inputPath)
|
||||
{
|
||||
var action = new ImportGltfAction();
|
||||
return Enqueue(action).ContinueWith(_ => action.Out!);
|
||||
var action = new ImportGltfAction(inputPath);
|
||||
return Enqueue(action).ContinueWith(_ => action.Out);
|
||||
}
|
||||
|
||||
/// <summary> Try to find the .sklb path for a .mdl file. </summary>
|
||||
/// <param name="mdlPath"> .mdl file to look up the skeleton for. </param>
|
||||
public string? ResolveSklbForMdl(string mdlPath)
|
||||
{
|
||||
var info = _parser.GetFileInfo(mdlPath);
|
||||
var info = parser.GetFileInfo(mdlPath);
|
||||
if (info.FileType is not FileType.Model)
|
||||
return null;
|
||||
|
||||
|
|
@ -126,18 +126,13 @@ public sealed class ModelManager(IFramework framework, GamePathParser _parser) :
|
|||
}
|
||||
}
|
||||
|
||||
private partial class ImportGltfAction : IAction
|
||||
private partial class ImportGltfAction(string inputPath) : IAction
|
||||
{
|
||||
public MdlFile? Out;
|
||||
|
||||
public ImportGltfAction()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public void Execute(CancellationToken cancel)
|
||||
{
|
||||
var model = ModelRoot.Load("C:\\Users\\ackwell\\blender\\gltf-tests\\c0201e6180_top.gltf");
|
||||
var model = ModelRoot.Load(inputPath);
|
||||
|
||||
Out = ModelImporter.Import(model);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@ public partial class ModEditWindow
|
|||
public List<Utf8GamePath>? GamePaths { get; private set; }
|
||||
public int GamePathIndex;
|
||||
|
||||
public bool PendingIo { get; private set; }
|
||||
public string? IoException { get; private set; }
|
||||
private bool _dirty;
|
||||
public bool PendingIo { get; private set; }
|
||||
public string? IoException { get; private set; }
|
||||
|
||||
public MdlTab(ModEditWindow edit, byte[] bytes, string path, IMod? mod)
|
||||
{
|
||||
|
|
@ -46,6 +47,16 @@ public partial class ModEditWindow
|
|||
public byte[] Write()
|
||||
=> Mdl.Write();
|
||||
|
||||
public bool Dirty
|
||||
{
|
||||
get
|
||||
{
|
||||
var dirty = _dirty;
|
||||
_dirty = false;
|
||||
return dirty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Find the list of game paths that may correspond to this model. </summary>
|
||||
/// <param name="path"> Resolved path to a .mdl. </param>
|
||||
/// <param name="mod"> Mod within which the .mdl is resolved. </param>
|
||||
|
|
@ -77,14 +88,28 @@ public partial class ModEditWindow
|
|||
});
|
||||
}
|
||||
|
||||
public void Import()
|
||||
/// <summary> Import a model from an interchange format. </summary>
|
||||
/// <param name="inputPath"> Disk path to load model data from. </param>
|
||||
public void Import(string inputPath)
|
||||
{
|
||||
// TODO: this needs to be fleshed out a bunch.
|
||||
_edit._models.ImportGltf().ContinueWith(v => Initialize(v.Result ?? Mdl));
|
||||
PendingIo = true;
|
||||
_edit._models.ImportGltf(inputPath)
|
||||
.ContinueWith(task =>
|
||||
{
|
||||
IoException = task.Exception?.ToString();
|
||||
PendingIo = false;
|
||||
|
||||
if (task.IsCompletedSuccessfully && task.Result != null)
|
||||
{
|
||||
Initialize(task.Result);
|
||||
_dirty = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary> Export model to an interchange format. </summary>
|
||||
/// <param name="outputPath"> Disk path to save the resulting file to. </param>
|
||||
/// <param name="mdlPath"> Game path to consider as the canonical .mdl path during export, used for resolution of other files. </param>
|
||||
public void Export(string outputPath, Utf8GamePath mdlPath)
|
||||
{
|
||||
SklbFile? sklb = null;
|
||||
|
|
|
|||
|
|
@ -35,15 +35,9 @@ public partial class ModEditWindow
|
|||
);
|
||||
}
|
||||
|
||||
DrawExport(tab, disabled);
|
||||
DrawImportExport(tab, disabled);
|
||||
|
||||
var ret = false;
|
||||
|
||||
if (ImGui.Button("import test"))
|
||||
{
|
||||
tab.Import();
|
||||
ret |= true;
|
||||
}
|
||||
var ret = tab.Dirty;
|
||||
|
||||
ret |= DrawModelMaterialDetails(tab, disabled);
|
||||
|
||||
|
|
@ -56,11 +50,41 @@ public partial class ModEditWindow
|
|||
return !disabled && ret;
|
||||
}
|
||||
|
||||
private void DrawExport(MdlTab tab, bool disabled)
|
||||
private void DrawImportExport(MdlTab tab, bool disabled)
|
||||
{
|
||||
if (!ImGui.CollapsingHeader("Export"))
|
||||
if (!ImGui.CollapsingHeader("Import / Export"))
|
||||
return;
|
||||
|
||||
var windowWidth = ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X;
|
||||
var childWidth = (windowWidth - ImGui.GetStyle().ItemSpacing.X * 3) / 2;
|
||||
var childSize = new Vector2(childWidth, 0);
|
||||
|
||||
DrawImport(tab, childSize, disabled);
|
||||
ImGui.SameLine();
|
||||
DrawExport(tab, childSize, disabled);
|
||||
|
||||
if (tab.IoException != null)
|
||||
ImGuiUtil.TextWrapped(tab.IoException);
|
||||
}
|
||||
|
||||
private void DrawImport(MdlTab tab, Vector2 size, bool disabled)
|
||||
{
|
||||
using var frame = ImRaii.FramedGroup("Import", size);
|
||||
|
||||
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) =>
|
||||
{
|
||||
if (success && paths.Count > 0)
|
||||
tab.Import(paths[0]);
|
||||
}, 1, _mod!.ModPath.FullName, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawExport(MdlTab tab, Vector2 size, bool disabled)
|
||||
{
|
||||
using var frame = ImRaii.FramedGroup("Export", size);
|
||||
|
||||
if (tab.GamePaths == null)
|
||||
{
|
||||
if (tab.IoException == null)
|
||||
|
|
@ -89,9 +113,6 @@ public partial class ModEditWindow
|
|||
_mod!.ModPath.FullName,
|
||||
false
|
||||
);
|
||||
|
||||
if (tab.IoException != null)
|
||||
ImGuiUtil.TextWrapped(tab.IoException);
|
||||
}
|
||||
|
||||
private void DrawGamePathCombo(MdlTab tab)
|
||||
|
|
@ -116,7 +137,7 @@ public partial class ModEditWindow
|
|||
const string label = "Game Path";
|
||||
var preview = tab.GamePaths![tab.GamePathIndex].ToString();
|
||||
var labelWidth = ImGui.CalcTextSize(label).X + ImGui.GetStyle().ItemInnerSpacing.X;
|
||||
var buttonWidth = ImGui.GetContentRegionAvail().X - labelWidth;
|
||||
var buttonWidth = ImGui.GetContentRegionAvail().X - labelWidth - ImGui.GetStyle().ItemSpacing.X;
|
||||
if (tab.GamePaths!.Count == 1)
|
||||
{
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0, 0.5f));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue