From b30de460e729c4d0eb6ccdfcab298738f10ef54a Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Tue, 28 May 2024 00:11:54 +0200 Subject: [PATCH] Fix ColorTable preview with legacy color tables. --- Penumbra.GameData | 2 +- .../Import/Models/Export/MaterialExporter.cs | 4 ++-- .../LiveColorTablePreviewer.cs | 2 +- .../ModEditWindow.Materials.ColorTable.cs | 13 ++++++------ .../ModEditWindow.Materials.MtrlTab.cs | 21 +++++++++++-------- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/Penumbra.GameData b/Penumbra.GameData index b8282970..b83ce830 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit b8282970ee78a2c085e740f60450fecf7ea58b9c +Subproject commit b83ce830919ca56e8b066d48d588c889df3af39b diff --git a/Penumbra/Import/Models/Export/MaterialExporter.cs b/Penumbra/Import/Models/Export/MaterialExporter.cs index 73a5e725..5df9e1c1 100644 --- a/Penumbra/Import/Models/Export/MaterialExporter.cs +++ b/Penumbra/Import/Models/Export/MaterialExporter.cs @@ -49,7 +49,7 @@ public class MaterialExporter private static MaterialBuilder BuildCharacter(Material material, string name) { // Build the textures from the color table. - var table = material.Mtrl.Table; + var table = new LegacyColorTable(material.Mtrl.Table); var normal = material.Textures[TextureUsage.SamplerNormal]; @@ -103,7 +103,7 @@ public class MaterialExporter // TODO: It feels a little silly to request the entire normal here when extracting the normal only needs some of the components. // As a future refactor, it would be neat to accept a single-channel field here, and then do composition of other stuff later. - private readonly struct ProcessCharacterNormalOperation(Image normal, ColorTable table) : IRowOperation + private readonly struct ProcessCharacterNormalOperation(Image normal, LegacyColorTable table) : IRowOperation { public Image Normal { get; } = normal.Clone(); public Image BaseColor { get; } = new(normal.Width, normal.Height); diff --git a/Penumbra/Interop/MaterialPreview/LiveColorTablePreviewer.cs b/Penumbra/Interop/MaterialPreview/LiveColorTablePreviewer.cs index f211e0bc..8e75a895 100644 --- a/Penumbra/Interop/MaterialPreview/LiveColorTablePreviewer.cs +++ b/Penumbra/Interop/MaterialPreview/LiveColorTablePreviewer.cs @@ -8,7 +8,7 @@ namespace Penumbra.Interop.MaterialPreview; public sealed unsafe class LiveColorTablePreviewer : LiveMaterialPreviewerBase { public const int TextureWidth = 4; - public const int TextureHeight = GameData.Files.MaterialStructs.ColorTable.NumUsedRows; + public const int TextureHeight = GameData.Files.MaterialStructs.LegacyColorTable.NumUsedRows; public const int TextureLength = TextureWidth * TextureHeight * 4; private readonly IFramework _framework; diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.Materials.ColorTable.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.Materials.ColorTable.cs index 54c0eff6..15bd7cc9 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.Materials.ColorTable.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.Materials.ColorTable.cs @@ -116,7 +116,7 @@ public partial class ModEditWindow { var ret = false; if (tab.Mtrl.HasDyeTable) - for (var i = 0; i < ColorTable.NumUsedRows; ++i) + for (var i = 0; i < LegacyColorTable.NumUsedRows; ++i) ret |= tab.Mtrl.ApplyDyeTemplate(_stainService.StmFile, i, dyeId, 0); tab.UpdateColorTablePreview(); @@ -170,6 +170,7 @@ public partial class ModEditWindow } } + [SkipLocalsInit] private static unsafe void ColorTableCopyClipboardButton(ColorTable.Row row, ColorDyeTable.Row dye) { if (!ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Clipboard.ToIconString(), ImGui.GetFrameHeight() * Vector2.One, @@ -178,11 +179,11 @@ public partial class ModEditWindow try { - var data = new byte[ColorTable.Row.Size + 2]; + Span data = stackalloc byte[ColorTable.Row.Size + ColorDyeTable.Row.Size]; fixed (byte* ptr = data) { - MemoryUtility.MemCpyUnchecked(ptr, &row, ColorTable.Row.Size); - MemoryUtility.MemCpyUnchecked(ptr + ColorTable.Row.Size, &dye, 2); + MemoryUtility.MemCpyUnchecked(ptr, &row, ColorTable.Row.Size); + MemoryUtility.MemCpyUnchecked(ptr + ColorTable.Row.Size, &dye, ColorDyeTable.Row.Size); } var text = Convert.ToBase64String(data); @@ -218,7 +219,7 @@ public partial class ModEditWindow { var text = ImGui.GetClipboardText(); var data = Convert.FromBase64String(text); - if (data.Length != ColorTable.Row.Size + 2 + if (data.Length != ColorTable.Row.Size + ColorDyeTable.Row.Size || !tab.Mtrl.HasTable) return false; @@ -349,7 +350,7 @@ public partial class ModEditWindow ImGui.TableNextColumn(); tmpFloat = row.GlossStrength; ImGui.SetNextItemWidth(floatSize); - float glossStrengthMin = ImGui.GetIO().KeyCtrl ? 0.0f : HalfEpsilon; + var glossStrengthMin = ImGui.GetIO().KeyCtrl ? 0.0f : HalfEpsilon; if (ImGui.DragFloat("##GlossStrength", ref tmpFloat, Math.Max(0.1f, tmpFloat * 0.025f), glossStrengthMin, HalfMaxValue, "%.1f") && FixFloat(ref tmpFloat, row.GlossStrength)) { diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.Materials.MtrlTab.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.Materials.MtrlTab.cs index 9421493e..56e9482b 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.Materials.MtrlTab.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.Materials.MtrlTab.cs @@ -455,7 +455,8 @@ public partial class ModEditWindow { UnbindFromMaterialInstances(); - var instances = MaterialInfo.FindMaterials(_edit._resourceTreeFactory.GetLocalPlayerRelatedCharacters().Select(ch => ch.Address), FilePath); + var instances = MaterialInfo.FindMaterials(_edit._resourceTreeFactory.GetLocalPlayerRelatedCharacters().Select(ch => ch.Address), + FilePath); var foundMaterials = new HashSet(); foreach (var materialInfo in instances) @@ -596,13 +597,13 @@ public partial class ModEditWindow if (!Mtrl.HasTable) return; - var row = Mtrl.Table[rowIdx]; + var row = new LegacyColorTable.Row(Mtrl.Table[rowIdx]); if (Mtrl.HasDyeTable) { var stm = _edit._stainService.StmFile; - var dye = Mtrl.DyeTable[rowIdx]; + var dye = new LegacyColorDyeTable.Row(Mtrl.DyeTable[rowIdx]); if (stm.TryGetValue(dye.Template, _edit._stainService.StainCombo.CurrentSelection.Key, out var dyes)) - row.ApplyDyeTemplate(dye, dyes, default); + row.ApplyDyeTemplate(dye, dyes); } if (HighlightedColorTableRow == rowIdx) @@ -624,17 +625,18 @@ public partial class ModEditWindow if (!Mtrl.HasTable) return; - var rows = Mtrl.Table; + var rows = new LegacyColorTable(Mtrl.Table); + var dyeRows = new LegacyColorDyeTable(Mtrl.DyeTable); if (Mtrl.HasDyeTable) { var stm = _edit._stainService.StmFile; var stainId = (StainId)_edit._stainService.StainCombo.CurrentSelection.Key; - for (var i = 0; i < ColorTable.NumUsedRows; ++i) + for (var i = 0; i < LegacyColorTable.NumUsedRows; ++i) { ref var row = ref rows[i]; - var dye = Mtrl.DyeTable[i]; + var dye = dyeRows[i]; if (stm.TryGetValue(dye.Template, stainId, out var dyes)) - row.ApplyDyeTemplate(dye, dyes, default); + row.ApplyDyeTemplate(dye, dyes); } } @@ -643,12 +645,13 @@ public partial class ModEditWindow foreach (var previewer in ColorTablePreviewers) { + // TODO: Dawntrail rows.AsHalves().CopyTo(previewer.ColorTable); previewer.ScheduleUpdate(); } } - private static void ApplyHighlight(ref ColorTable.Row row, float time) + private static void ApplyHighlight(ref LegacyColorTable.Row row, float time) { var level = (MathF.Sin(time * 2.0f * MathF.PI) + 2.0f) / 3.0f / 255.0f; var baseColor = ColorId.InGameHighlight.Value();