mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-15 05:04:15 +01:00
Merge remote-tracking branch 'ackwell/mdl-error-messaging'
This commit is contained in:
commit
401704712e
4 changed files with 60 additions and 14 deletions
|
|
@ -4,7 +4,7 @@ using SharpGLTF.Schema2;
|
|||
|
||||
namespace Penumbra.Import.Models.Import;
|
||||
|
||||
public partial class ModelImporter(ModelRoot _model)
|
||||
public partial class ModelImporter(ModelRoot model)
|
||||
{
|
||||
public static MdlFile Import(ModelRoot model)
|
||||
{
|
||||
|
|
@ -99,7 +99,7 @@ public partial class ModelImporter(ModelRoot _model)
|
|||
|
||||
/// <summary> Returns an iterator over sorted, grouped mesh nodes. </summary>
|
||||
private IEnumerable<IEnumerable<Node>> GroupedMeshNodes()
|
||||
=> _model.LogicalNodes
|
||||
=> model.LogicalNodes
|
||||
.Where(node => node.Mesh != null)
|
||||
.Select(node =>
|
||||
{
|
||||
|
|
@ -171,6 +171,14 @@ public partial class ModelImporter(ModelRoot _model)
|
|||
|
||||
_shapeValues.AddRange(meshShapeKey.ShapeValues);
|
||||
}
|
||||
|
||||
// The number of shape values in a model is bounded by the count
|
||||
// value, which is stored as a u16.
|
||||
// While technically there are similar bounds on other shape struct
|
||||
// arrays, values is practically guaranteed to be the highest of the
|
||||
// group, so a failure on any of them will be a failure on it.
|
||||
if (_shapeValues.Count > ushort.MaxValue)
|
||||
throw new Exception($"Importing this file would require more than the maximum of {ushort.MaxValue} shape values.\nTry removing or applying shape keys that do not need to be changed at runtime in-game.");
|
||||
}
|
||||
|
||||
private ushort BuildBoneTable(List<string> boneNames)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,12 @@ public sealed class ModelManager(IFramework framework, ActiveCollections collect
|
|||
public Task<MdlFile?> ImportGltf(string inputPath)
|
||||
{
|
||||
var action = new ImportGltfAction(inputPath);
|
||||
return Enqueue(action).ContinueWith(_ => action.Out);
|
||||
return Enqueue(action).ContinueWith(task =>
|
||||
{
|
||||
if (task.IsFaulted && task.Exception != null)
|
||||
throw task.Exception;
|
||||
return action.Out;
|
||||
});
|
||||
}
|
||||
/// <summary> Try to find the .sklb paths for a .mdl file. </summary>
|
||||
/// <param name="mdlPath"> .mdl file to look up the skeletons for. </param>
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ public partial class ModEditWindow
|
|||
public List<Utf8GamePath>? GamePaths { get; private set; }
|
||||
public int GamePathIndex;
|
||||
|
||||
private bool _dirty;
|
||||
public bool PendingIo { get; private set; }
|
||||
public string? IoException { get; private set; }
|
||||
private bool _dirty;
|
||||
public bool PendingIo { get; private set; }
|
||||
public List<Exception> IoExceptions { get; private set; } = [];
|
||||
|
||||
public MdlTab(ModEditWindow edit, byte[] bytes, string path)
|
||||
{
|
||||
|
|
@ -85,7 +85,7 @@ public partial class ModEditWindow
|
|||
|
||||
task.ContinueWith(t =>
|
||||
{
|
||||
IoException = t.Exception?.ToString();
|
||||
RecordIoExceptions(t.Exception);
|
||||
GamePaths = t.Result;
|
||||
PendingIo = false;
|
||||
});
|
||||
|
|
@ -120,7 +120,7 @@ public partial class ModEditWindow
|
|||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
IoException = exception.ToString();
|
||||
RecordIoExceptions(exception);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ public partial class ModEditWindow
|
|||
_edit._models.ExportToGltf(Mdl, skeletons, outputPath)
|
||||
.ContinueWith(task =>
|
||||
{
|
||||
IoException = task.Exception?.ToString();
|
||||
RecordIoExceptions(task.Exception);
|
||||
PendingIo = false;
|
||||
});
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ public partial class ModEditWindow
|
|||
_edit._models.ImportGltf(inputPath)
|
||||
.ContinueWith(task =>
|
||||
{
|
||||
IoException = task.Exception?.ToString();
|
||||
RecordIoExceptions(task.Exception);
|
||||
if (task is { IsCompletedSuccessfully: true, Result: not null })
|
||||
{
|
||||
Initialize(task.Result);
|
||||
|
|
@ -151,6 +151,15 @@ public partial class ModEditWindow
|
|||
});
|
||||
}
|
||||
|
||||
private void RecordIoExceptions(Exception? exception)
|
||||
{
|
||||
IoExceptions = exception switch {
|
||||
null => [],
|
||||
AggregateException ae => ae.Flatten().InnerExceptions.ToList(),
|
||||
Exception other => [other],
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary> Read a .sklb from the active collection or game. </summary>
|
||||
/// <param name="sklbPath"> Game path to the .sklb to load. </param>
|
||||
private SklbFile ReadSklb(string sklbPath)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using Penumbra.GameData;
|
|||
using Penumbra.GameData.Files;
|
||||
using Penumbra.Import.Models;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.UI.Classes;
|
||||
|
||||
namespace Penumbra.UI.AdvancedWindow;
|
||||
|
||||
|
|
@ -61,8 +62,7 @@ public partial class ModEditWindow
|
|||
ImGui.SameLine();
|
||||
DrawExport(tab, childSize, disabled);
|
||||
|
||||
if (tab.IoException != null)
|
||||
ImGuiUtil.TextWrapped(tab.IoException);
|
||||
DrawIoExceptions(tab);
|
||||
}
|
||||
|
||||
private void DrawImport(MdlTab tab, Vector2 size, bool _1)
|
||||
|
|
@ -99,10 +99,10 @@ public partial class ModEditWindow
|
|||
|
||||
if (tab.GamePaths == null)
|
||||
{
|
||||
if (tab.IoException == null)
|
||||
if (tab.IoExceptions.Count == 0)
|
||||
ImGui.TextUnformatted("Resolving model game paths.");
|
||||
else
|
||||
ImGuiUtil.TextWrapped(tab.IoException);
|
||||
ImGui.TextUnformatted("Failed to resolve model game paths.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -126,6 +126,30 @@ public partial class ModEditWindow
|
|||
false
|
||||
);
|
||||
}
|
||||
|
||||
private void DrawIoExceptions(MdlTab tab)
|
||||
{
|
||||
if (tab.IoExceptions.Count == 0)
|
||||
return;
|
||||
|
||||
var size = new Vector2(ImGui.GetContentRegionAvail().X, 0);
|
||||
using var frame = ImRaii.FramedGroup("Exceptions", size, headerPreIcon: FontAwesomeIcon.TimesCircle, borderColor: Colors.RegexWarningBorder);
|
||||
|
||||
var spaceAvail = ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X - 100;
|
||||
foreach (var exception in tab.IoExceptions)
|
||||
{
|
||||
var message = $"{exception.GetType().Name}: {exception.Message}";
|
||||
var textSize = ImGui.CalcTextSize(message).X;
|
||||
if (textSize > spaceAvail)
|
||||
message = message.Substring(0, (int)Math.Floor(message.Length * (spaceAvail / textSize))) + "...";
|
||||
|
||||
using (var exceptionNode = ImRaii.TreeNode(message))
|
||||
{
|
||||
if (exceptionNode)
|
||||
ImGuiUtil.TextWrapped(exception.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGamePathCombo(MdlTab tab)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue