Remarked changes.

This commit is contained in:
Ottermandias 2024-03-21 21:31:30 +01:00
parent 0ad769e08e
commit 72979a9743
2 changed files with 82 additions and 59 deletions

@ -1 +1 @@
Subproject commit b4b14367d8235eabedd561ad3626beb1d2a83889 Subproject commit 2bbb9b2a8a4479461b252594b9d1b788b551c13c

View file

@ -7,6 +7,7 @@ using OtterGui.Widgets;
using Penumbra.GameData; using Penumbra.GameData;
using Penumbra.GameData.Files; using Penumbra.GameData.Files;
using Penumbra.Import.Models; using Penumbra.Import.Models;
using Penumbra.Mods;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.UI.Classes; using Penumbra.UI.Classes;
@ -15,8 +16,12 @@ namespace Penumbra.UI.AdvancedWindow;
public partial class ModEditWindow public partial class ModEditWindow
{ {
private const int MdlMaterialMaximum = 4; private const int MdlMaterialMaximum = 4;
private const string MdlImportDocumentation = @"https://github.com/xivdev/Penumbra/wiki/Model-IO#user-content-9b49d296-23ab-410a-845b-a3be769b71ea";
private const string MdlExportDocumentation = @"https://github.com/xivdev/Penumbra/wiki/Model-IO#user-content-25968400-ebe5-4861-b610-cb1556db7ec4"; private const string MdlImportDocumentation =
@"https://github.com/xivdev/Penumbra/wiki/Model-IO#user-content-9b49d296-23ab-410a-845b-a3be769b71ea";
private const string MdlExportDocumentation =
@"https://github.com/xivdev/Penumbra/wiki/Model-IO#user-content-25968400-ebe5-4861-b610-cb1556db7ec4";
private readonly FileEditor<MdlTab> _modelTab; private readonly FileEditor<MdlTab> _modelTab;
private readonly ModelManager _models; private readonly ModelManager _models;
@ -25,11 +30,27 @@ public partial class ModEditWindow
private readonly List<TagButtons> _subMeshAttributeTagWidgets = []; private readonly List<TagButtons> _subMeshAttributeTagWidgets = [];
private string _customPath = string.Empty; private string _customPath = string.Empty;
private Utf8GamePath _customGamePath = Utf8GamePath.Empty; private Utf8GamePath _customGamePath = Utf8GamePath.Empty;
private MdlFile _lastFile = null!;
private long[] _lodTriCount = [];
private bool DrawModelPanel(MdlTab tab, bool disabled) private void UpdateFile(MdlFile file, bool force)
{ {
var file = tab.Mdl; if (file == _lastFile)
{
if (force)
UpdateMeshes();
}
else
{
UpdateMeshes();
_lastFile = file;
_lodTriCount = Enumerable.Range(0, file.Lods.Length).Select(l => GetTriangleCountForLod(file, l)).ToArray();
}
return;
void UpdateMeshes()
{
var subMeshTotal = file.Meshes.Aggregate(0, (count, mesh) => count + mesh.SubMeshCount); var subMeshTotal = file.Meshes.Aggregate(0, (count, mesh) => count + mesh.SubMeshCount);
if (_subMeshAttributeTagWidgets.Count != subMeshTotal) if (_subMeshAttributeTagWidgets.Count != subMeshTotal)
{ {
@ -38,18 +59,22 @@ public partial class ModEditWindow
Enumerable.Range(0, subMeshTotal).Select(_ => new TagButtons()) Enumerable.Range(0, subMeshTotal).Select(_ => new TagButtons())
); );
} }
}
}
private bool DrawModelPanel(MdlTab tab, bool disabled)
{
UpdateFile(tab.Mdl, tab.Dirty);
DrawImportExport(tab, disabled); DrawImportExport(tab, disabled);
var ret = tab.Dirty; var ret = tab.Dirty;
ret |= DrawModelMaterialDetails(tab, disabled); ret |= DrawModelMaterialDetails(tab, disabled);
if (ImGui.CollapsingHeader($"Meshes ({file.Meshes.Length})###meshes")) if (ImGui.CollapsingHeader($"Meshes ({_lastFile.Meshes.Length})###meshes"))
for (var i = 0; i < file.LodCount; ++i) for (var i = 0; i < _lastFile.LodCount; ++i)
ret |= DrawModelLodDetails(tab, i, disabled); ret |= DrawModelLodDetails(tab, i, disabled);
ret |= DrawOtherModelDetails(file, disabled); ret |= DrawOtherModelDetails(disabled);
return !disabled && ret; return !disabled && ret;
} }
@ -111,10 +136,7 @@ public partial class ModEditWindow
if (tab.GamePaths == null) if (tab.GamePaths == null)
{ {
if (tab.IoExceptions.Count == 0) ImGui.TextUnformatted(tab.IoExceptions.Count == 0 ? "Resolving model game paths." : "Failed to resolve model game paths.");
ImGui.TextUnformatted("Resolving model game paths.");
else
ImGui.TextUnformatted("Failed to resolve model game paths.");
return; return;
} }
@ -156,7 +178,8 @@ public partial class ModEditWindow
return; return;
var size = new Vector2(ImGui.GetContentRegionAvail().X, 0); var size = new Vector2(ImGui.GetContentRegionAvail().X, 0);
using var frame = ImRaii.FramedGroup("Exceptions", size, headerPreIcon: FontAwesomeIcon.TimesCircle, borderColor: Colors.RegexWarningBorder); using var frame = ImRaii.FramedGroup("Exceptions", size, headerPreIcon: FontAwesomeIcon.TimesCircle,
borderColor: Colors.RegexWarningBorder);
var spaceAvail = ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X - 100; var spaceAvail = ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X - 100;
foreach (var (exception, index) in tab.IoExceptions.WithIndex()) foreach (var (exception, index) in tab.IoExceptions.WithIndex())
@ -460,7 +483,7 @@ public partial class ModEditWindow
return true; return true;
} }
private static bool DrawOtherModelDetails(MdlFile file, bool _) private bool DrawOtherModelDetails(bool _)
{ {
using var header = ImRaii.CollapsingHeader("Further Content"); using var header = ImRaii.CollapsingHeader("Further Content");
if (!header) if (!header)
@ -471,47 +494,47 @@ public partial class ModEditWindow
if (table) if (table)
{ {
ImGuiUtil.DrawTableColumn("Version"); ImGuiUtil.DrawTableColumn("Version");
ImGuiUtil.DrawTableColumn(file.Version.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.Version.ToString());
ImGuiUtil.DrawTableColumn("Radius"); ImGuiUtil.DrawTableColumn("Radius");
ImGuiUtil.DrawTableColumn(file.Radius.ToString(CultureInfo.InvariantCulture)); ImGuiUtil.DrawTableColumn(_lastFile.Radius.ToString(CultureInfo.InvariantCulture));
ImGuiUtil.DrawTableColumn("Model Clip Out Distance"); ImGuiUtil.DrawTableColumn("Model Clip Out Distance");
ImGuiUtil.DrawTableColumn(file.ModelClipOutDistance.ToString(CultureInfo.InvariantCulture)); ImGuiUtil.DrawTableColumn(_lastFile.ModelClipOutDistance.ToString(CultureInfo.InvariantCulture));
ImGuiUtil.DrawTableColumn("Shadow Clip Out Distance"); ImGuiUtil.DrawTableColumn("Shadow Clip Out Distance");
ImGuiUtil.DrawTableColumn(file.ShadowClipOutDistance.ToString(CultureInfo.InvariantCulture)); ImGuiUtil.DrawTableColumn(_lastFile.ShadowClipOutDistance.ToString(CultureInfo.InvariantCulture));
ImGuiUtil.DrawTableColumn("LOD Count"); ImGuiUtil.DrawTableColumn("LOD Count");
ImGuiUtil.DrawTableColumn(file.LodCount.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.LodCount.ToString());
ImGuiUtil.DrawTableColumn("Enable Index Buffer Streaming"); ImGuiUtil.DrawTableColumn("Enable Index Buffer Streaming");
ImGuiUtil.DrawTableColumn(file.EnableIndexBufferStreaming.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.EnableIndexBufferStreaming.ToString());
ImGuiUtil.DrawTableColumn("Enable Edge Geometry"); ImGuiUtil.DrawTableColumn("Enable Edge Geometry");
ImGuiUtil.DrawTableColumn(file.EnableEdgeGeometry.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.EnableEdgeGeometry.ToString());
ImGuiUtil.DrawTableColumn("Flags 1"); ImGuiUtil.DrawTableColumn("Flags 1");
ImGuiUtil.DrawTableColumn(file.Flags1.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.Flags1.ToString());
ImGuiUtil.DrawTableColumn("Flags 2"); ImGuiUtil.DrawTableColumn("Flags 2");
ImGuiUtil.DrawTableColumn(file.Flags2.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.Flags2.ToString());
ImGuiUtil.DrawTableColumn("Vertex Declarations"); ImGuiUtil.DrawTableColumn("Vertex Declarations");
ImGuiUtil.DrawTableColumn(file.VertexDeclarations.Length.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.VertexDeclarations.Length.ToString());
ImGuiUtil.DrawTableColumn("Bone Bounding Boxes"); ImGuiUtil.DrawTableColumn("Bone Bounding Boxes");
ImGuiUtil.DrawTableColumn(file.BoneBoundingBoxes.Length.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.BoneBoundingBoxes.Length.ToString());
ImGuiUtil.DrawTableColumn("Bone Tables"); ImGuiUtil.DrawTableColumn("Bone Tables");
ImGuiUtil.DrawTableColumn(file.BoneTables.Length.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.BoneTables.Length.ToString());
ImGuiUtil.DrawTableColumn("Element IDs"); ImGuiUtil.DrawTableColumn("Element IDs");
ImGuiUtil.DrawTableColumn(file.ElementIds.Length.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.ElementIds.Length.ToString());
ImGuiUtil.DrawTableColumn("Extra LoDs"); ImGuiUtil.DrawTableColumn("Extra LoDs");
ImGuiUtil.DrawTableColumn(file.ExtraLods.Length.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.ExtraLods.Length.ToString());
ImGuiUtil.DrawTableColumn("Meshes"); ImGuiUtil.DrawTableColumn("Meshes");
ImGuiUtil.DrawTableColumn(file.Meshes.Length.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.Meshes.Length.ToString());
ImGuiUtil.DrawTableColumn("Shape Meshes"); ImGuiUtil.DrawTableColumn("Shape Meshes");
ImGuiUtil.DrawTableColumn(file.ShapeMeshes.Length.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.ShapeMeshes.Length.ToString());
ImGuiUtil.DrawTableColumn("LoDs"); ImGuiUtil.DrawTableColumn("LoDs");
ImGuiUtil.DrawTableColumn(file.Lods.Length.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.Lods.Length.ToString());
ImGuiUtil.DrawTableColumn("Vertex Declarations"); ImGuiUtil.DrawTableColumn("Vertex Declarations");
ImGuiUtil.DrawTableColumn(file.VertexDeclarations.Length.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.VertexDeclarations.Length.ToString());
ImGuiUtil.DrawTableColumn("Stack Size"); ImGuiUtil.DrawTableColumn("Stack Size");
ImGuiUtil.DrawTableColumn(file.StackSize.ToString()); ImGuiUtil.DrawTableColumn(_lastFile.StackSize.ToString());
for (var lod = 0; lod < file.Lods.Length; lod++) foreach (var (triCount, lod) in _lodTriCount.WithIndex())
{ {
ImGuiUtil.DrawTableColumn("LoD " + lod + " Triangle Count"); ImGuiUtil.DrawTableColumn($"LOD #{lod + 1} Triangle Count");
ImGuiUtil.DrawTableColumn(GetTriangleCountForLod(file, lod).ToString()); ImGuiUtil.DrawTableColumn(triCount.ToString());
} }
} }
} }
@ -519,36 +542,36 @@ public partial class ModEditWindow
using (var materials = ImRaii.TreeNode("Materials", ImGuiTreeNodeFlags.DefaultOpen)) using (var materials = ImRaii.TreeNode("Materials", ImGuiTreeNodeFlags.DefaultOpen))
{ {
if (materials) if (materials)
foreach (var material in file.Materials) foreach (var material in _lastFile.Materials)
ImRaii.TreeNode(material, ImGuiTreeNodeFlags.Leaf).Dispose(); ImRaii.TreeNode(material, ImGuiTreeNodeFlags.Leaf).Dispose();
} }
using (var attributes = ImRaii.TreeNode("Attributes", ImGuiTreeNodeFlags.DefaultOpen)) using (var attributes = ImRaii.TreeNode("Attributes", ImGuiTreeNodeFlags.DefaultOpen))
{ {
if (attributes) if (attributes)
foreach (var attribute in file.Attributes) foreach (var attribute in _lastFile.Attributes)
ImRaii.TreeNode(attribute, ImGuiTreeNodeFlags.Leaf).Dispose(); ImRaii.TreeNode(attribute, ImGuiTreeNodeFlags.Leaf).Dispose();
} }
using (var bones = ImRaii.TreeNode("Bones", ImGuiTreeNodeFlags.DefaultOpen)) using (var bones = ImRaii.TreeNode("Bones", ImGuiTreeNodeFlags.DefaultOpen))
{ {
if (bones) if (bones)
foreach (var bone in file.Bones) foreach (var bone in _lastFile.Bones)
ImRaii.TreeNode(bone, ImGuiTreeNodeFlags.Leaf).Dispose(); ImRaii.TreeNode(bone, ImGuiTreeNodeFlags.Leaf).Dispose();
} }
using (var shapes = ImRaii.TreeNode("Shapes", ImGuiTreeNodeFlags.DefaultOpen)) using (var shapes = ImRaii.TreeNode("Shapes", ImGuiTreeNodeFlags.DefaultOpen))
{ {
if (shapes) if (shapes)
foreach (var shape in file.Shapes) foreach (var shape in _lastFile.Shapes)
ImRaii.TreeNode(shape.ShapeName, ImGuiTreeNodeFlags.Leaf).Dispose(); ImRaii.TreeNode(shape.ShapeName, ImGuiTreeNodeFlags.Leaf).Dispose();
} }
if (file.RemainingData.Length > 0) if (_lastFile.RemainingData.Length > 0)
{ {
using var t = ImRaii.TreeNode($"Additional Data (Size: {file.RemainingData.Length})###AdditionalData"); using var t = ImRaii.TreeNode($"Additional Data (Size: {_lastFile.RemainingData.Length})###AdditionalData");
if (t) if (t)
ImGuiUtil.TextWrapped(string.Join(' ', file.RemainingData.Select(c => $"{c:X2}"))); ImGuiUtil.TextWrapped(string.Join(' ', _lastFile.RemainingData.Select(c => $"{c:X2}")));
} }
return false; return false;