mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Add lenient model export mode
This commit is contained in:
parent
6689e326ee
commit
1166c9e297
5 changed files with 42 additions and 6 deletions
|
|
@ -3,4 +3,5 @@ namespace Penumbra.Import.Models.Export;
|
|||
public struct ExportConfig
|
||||
{
|
||||
public bool GenerateMissingBones;
|
||||
public bool LenientMode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ public class MeshExporter
|
|||
return new VertexTexture2ColorFfxiv(
|
||||
new Vector2(uv.X, uv.Y),
|
||||
new Vector2(uv.Z, uv.W),
|
||||
ToVector4(GetFirstSafe(attributes, MdlFile.VertexUsage.Color))
|
||||
ToVector4(_config.LenientMode ? GetFirstUnsafe(attributes, MdlFile.VertexUsage.Color) : GetFirstSafe(attributes, MdlFile.VertexUsage.Color))
|
||||
);
|
||||
}
|
||||
if (_materialType == typeof(VertexTexture3))
|
||||
|
|
@ -468,7 +468,7 @@ public class MeshExporter
|
|||
new Vector2(uv0.X, uv0.Y),
|
||||
new Vector2(uv0.Z, uv0.W),
|
||||
new Vector2(uv1.X, uv1.Y),
|
||||
ToVector4(GetFirstSafe(attributes, MdlFile.VertexUsage.Color))
|
||||
ToVector4(_config.LenientMode ? GetFirstUnsafe(attributes, MdlFile.VertexUsage.Color) : GetFirstSafe(attributes, MdlFile.VertexUsage.Color))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -537,6 +537,23 @@ public class MeshExporter
|
|||
|
||||
return list[0];
|
||||
}
|
||||
|
||||
/// <summary> Check that the list has length 1 for any case where this is expected and return the one entry. Otherwise, report a warning. </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
private T GetFirstUnsafe<T>(IReadOnlyDictionary<MdlFile.VertexUsage, List<T>> attributes, MdlFile.VertexUsage usage)
|
||||
{
|
||||
var list = attributes[usage];
|
||||
switch (list.Count)
|
||||
{
|
||||
case > 1:
|
||||
_notifier.Warning($"Multiple usage indices encountered for {usage}.", true);
|
||||
break;
|
||||
case 0:
|
||||
throw _notifier.Exception($"No usage indices encountered for {usage}");
|
||||
}
|
||||
|
||||
return list[0];
|
||||
}
|
||||
|
||||
/// <summary> Convert a vertex attribute value to a Vector2. Supported inputs are Vector2, Vector3, and Vector4. </summary>
|
||||
private static Vector2 ToVector2(object data)
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ public record class IoNotifier
|
|||
=> this with { _context = $"{_context}{context}: "};
|
||||
|
||||
/// <summary> Send a warning with any current context to notification channels. </summary>
|
||||
public void Warning(string content)
|
||||
=> SendMessage(content, Logger.LogLevel.Warning);
|
||||
public void Warning(string content, bool ignoreDuplicates = false)
|
||||
=> SendMessage(content, Logger.LogLevel.Warning, ignoreDuplicates);
|
||||
|
||||
/// <summary> Get the current warnings for this notifier. </summary>
|
||||
/// <remarks> This does not currently filter to notifications with the current notifier's context - it will return all IO notifications from all notifiers. </remarks>
|
||||
|
|
@ -31,9 +31,15 @@ public record class IoNotifier
|
|||
where TException : Exception, new()
|
||||
=> (TException)Activator.CreateInstance(typeof(TException), $"{_context}{message}")!;
|
||||
|
||||
private void SendMessage(string message, Logger.LogLevel type)
|
||||
private void SendMessage(string message, Logger.LogLevel type, bool ignoreDuplicates = false)
|
||||
{
|
||||
var fullText = $"{_context}{message}";
|
||||
|
||||
if (ignoreDuplicates && _messages.Contains(fullText))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Penumbra.Log.Message(type, fullText);
|
||||
_messages.Add(fullText);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ using Penumbra.Meta;
|
|||
using Penumbra.Meta.Files;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using SharpGLTF.Scenes;
|
||||
using SharpGLTF.Validation;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
|
|
@ -216,7 +217,10 @@ public sealed class ModelManager(IFramework framework, MetaFileManager metaFileM
|
|||
|
||||
Penumbra.Log.Debug("[GLTF Export] Saving...");
|
||||
var gltfModel = scene.ToGltf2();
|
||||
gltfModel.Save(outputPath);
|
||||
gltfModel.Save(outputPath, new Schema2.WriteSettings()
|
||||
{
|
||||
Validation = config.LenientMode ? ValidationMode.TryFix : ValidationMode.Strict,
|
||||
});
|
||||
Penumbra.Log.Debug("[GLTF Export] Done.");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -168,6 +168,14 @@ public partial class ModEditWindow
|
|||
+ "It is primarily intended to allow exporting models weighted to bones that do not exist.\n"
|
||||
+ "Before enabling, ensure dependencies are enabled in the current collection, and EST metadata is correctly configured.");
|
||||
|
||||
ImGui.SameLine(200 * UiHelpers.Scale + ImGui.GetStyle().ItemSpacing.X + ImGui.GetStyle().WindowPadding.X);
|
||||
|
||||
ImGui.Checkbox("##tryFixValidation", ref tab.ExportConfig.LenientMode);
|
||||
ImGui.SameLine();
|
||||
ImGuiUtil.LabeledHelpMarker("Lenient mode",
|
||||
"Try fixing potential errors during model validation and ignore superfluous color information.\n"
|
||||
+ "This may result in a broken model, or one missing information, so use with care!");
|
||||
|
||||
var gamePath = tab.GamePathIndex >= 0 && tab.GamePathIndex < tab.GamePaths.Count
|
||||
? tab.GamePaths[tab.GamePathIndex]
|
||||
: _customGamePath;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue