mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-15 05:04:15 +01:00
I don't know what I'm doing
This commit is contained in:
parent
1641166d6e
commit
ef1bbb6d9d
9 changed files with 65 additions and 59 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit fe9d563d9845630673cf098f7a6bfbd26e600fb4
|
||||
Subproject commit 845d1f99a752f4d23288a316e42d4bfa32fa987f
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using Lumina.Data.Parsing;
|
||||
using Penumbra.GameData.Files;
|
||||
using Penumbra.GameData.Files.MaterialStructs;
|
||||
using SharpGLTF.Materials;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Advanced;
|
||||
|
|
@ -102,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<Rgba32> normal, MtrlFile.ColorTable table) : IRowOperation
|
||||
private readonly struct ProcessCharacterNormalOperation(Image<Rgba32> normal, ColorTable table) : IRowOperation
|
||||
{
|
||||
public Image<Rgba32> Normal { get; } = normal.Clone();
|
||||
public Image<Rgba32> BaseColor { get; } = new(normal.Width, normal.Height);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using Lumina.Data.Parsing;
|
|||
using Lumina.Extensions;
|
||||
using OtterGui;
|
||||
using Penumbra.GameData.Files;
|
||||
using Penumbra.GameData.Files.ModelStructs;
|
||||
using SharpGLTF.Geometry;
|
||||
using SharpGLTF.Geometry.VertexTypes;
|
||||
using SharpGLTF.IO;
|
||||
|
|
@ -55,7 +56,7 @@ public class MeshExporter
|
|||
private readonly byte _lod;
|
||||
private readonly ushort _meshIndex;
|
||||
|
||||
private MdlStructs.MeshStruct XivMesh
|
||||
private MeshStruct XivMesh
|
||||
=> _mdl.Meshes[_meshIndex];
|
||||
|
||||
private readonly MaterialBuilder _material;
|
||||
|
|
@ -109,8 +110,8 @@ public class MeshExporter
|
|||
var xivBoneTable = _mdl.BoneTables[XivMesh.BoneTableIndex];
|
||||
|
||||
var indexMap = new Dictionary<ushort, int>();
|
||||
|
||||
foreach (var (xivBoneIndex, tableIndex) in xivBoneTable.BoneIndex.Take(xivBoneTable.BoneCount).WithIndex())
|
||||
// #TODO @ackwell maybe fix for V6 Models, I think this works fine.
|
||||
foreach (var (xivBoneIndex, tableIndex) in xivBoneTable.BoneIndex.Take((int)xivBoneTable.BoneCount).WithIndex())
|
||||
{
|
||||
var boneName = _mdl.Bones[xivBoneIndex];
|
||||
if (!skeleton.Names.TryGetValue(boneName, out var gltfBoneIndex))
|
||||
|
|
@ -238,19 +239,15 @@ public class MeshExporter
|
|||
{ "targetNames", shapeNames },
|
||||
});
|
||||
|
||||
string[] attributes = [];
|
||||
var maxAttribute = 31 - BitOperations.LeadingZeroCount(attributeMask);
|
||||
string[] attributes = [];
|
||||
var maxAttribute = 31 - BitOperations.LeadingZeroCount(attributeMask);
|
||||
if (maxAttribute < _mdl.Attributes.Length)
|
||||
{
|
||||
attributes = Enumerable.Range(0, 32)
|
||||
.Where(index => ((attributeMask >> index) & 1) == 1)
|
||||
.Select(index => _mdl.Attributes[index])
|
||||
.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
_notifier.Warning("Invalid attribute data, ignoring.");
|
||||
}
|
||||
|
||||
return new MeshData
|
||||
{
|
||||
|
|
@ -278,7 +275,7 @@ public class MeshExporter
|
|||
for (var streamIndex = 0; streamIndex < MaximumMeshBufferStreams; streamIndex++)
|
||||
{
|
||||
streams[streamIndex] = new BinaryReader(new MemoryStream(_mdl.RemainingData));
|
||||
streams[streamIndex].Seek(_mdl.VertexOffset[_lod] + XivMesh.VertexBufferOffset[streamIndex]);
|
||||
streams[streamIndex].Seek(_mdl.VertexOffset[_lod] + XivMesh.VertexBufferOffset(streamIndex));
|
||||
}
|
||||
|
||||
var sortedElements = _mdl.VertexDeclarations[_meshIndex].VertexElements
|
||||
|
|
@ -315,7 +312,7 @@ public class MeshExporter
|
|||
MdlFile.VertexType.Single3 => new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()),
|
||||
MdlFile.VertexType.Single4 => new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()),
|
||||
MdlFile.VertexType.UByte4 => reader.ReadBytes(4),
|
||||
MdlFile.VertexType.NByte4 => new Vector4(reader.ReadByte() / 255f, reader.ReadByte() / 255f, reader.ReadByte() / 255f,
|
||||
MdlFile.VertexType.NByte4 => new Vector4(reader.ReadByte() / 255f, reader.ReadByte() / 255f, reader.ReadByte() / 255f,
|
||||
reader.ReadByte() / 255f),
|
||||
MdlFile.VertexType.Half2 => new Vector2((float)reader.ReadHalf(), (float)reader.ReadHalf()),
|
||||
MdlFile.VertexType.Half4 => new Vector4((float)reader.ReadHalf(), (float)reader.ReadHalf(), (float)reader.ReadHalf(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Lumina.Data.Parsing;
|
||||
using OtterGui;
|
||||
using Penumbra.GameData.Files.ModelStructs;
|
||||
using SharpGLTF.Schema2;
|
||||
|
||||
namespace Penumbra.Import.Models.Import;
|
||||
|
|
@ -8,7 +9,7 @@ public class MeshImporter(IEnumerable<Node> nodes, IoNotifier notifier)
|
|||
{
|
||||
public struct Mesh
|
||||
{
|
||||
public MdlStructs.MeshStruct MeshStruct;
|
||||
public MeshStruct MeshStruct;
|
||||
public List<MdlStructs.SubmeshStruct> SubMeshStructs;
|
||||
|
||||
public string? Material;
|
||||
|
|
@ -69,10 +70,14 @@ public class MeshImporter(IEnumerable<Node> nodes, IoNotifier notifier)
|
|||
|
||||
return new Mesh
|
||||
{
|
||||
MeshStruct = new MdlStructs.MeshStruct
|
||||
MeshStruct = new MeshStruct
|
||||
{
|
||||
VertexBufferOffset = [0, (uint)_streams[0].Count, (uint)(_streams[0].Count + _streams[1].Count)],
|
||||
VertexBufferStride = _strides,
|
||||
VertexBufferOffset1 = 0,
|
||||
VertexBufferOffset2 = (uint)_streams[0].Count,
|
||||
VertexBufferOffset3 = (uint)(_streams[0].Count + _streams[1].Count),
|
||||
VertexBufferStride1 = _strides[0],
|
||||
VertexBufferStride2 = _strides[1],
|
||||
VertexBufferStride3 = _strides[2],
|
||||
VertexCount = _vertexCount,
|
||||
VertexStreamCount = (byte)_vertexDeclaration.Value.VertexElements
|
||||
.Select(element => element.Stream + 1)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Lumina.Data.Parsing;
|
||||
using OtterGui;
|
||||
using Penumbra.GameData.Files;
|
||||
using Penumbra.GameData.Files.ModelStructs;
|
||||
using SharpGLTF.Schema2;
|
||||
|
||||
namespace Penumbra.Import.Models.Import;
|
||||
|
|
@ -14,10 +15,11 @@ public partial class ModelImporter(ModelRoot model, IoNotifier notifier)
|
|||
}
|
||||
|
||||
// NOTE: This is intended to match TexTool's grouping regex, ".*[_ ^]([0-9]+)[\\.\\-]?([0-9]+)?$"
|
||||
[GeneratedRegex(@"[_ ^](?'Mesh'[0-9]+)[.-]?(?'SubMesh'[0-9]+)?$", RegexOptions.Compiled | RegexOptions.NonBacktracking | RegexOptions.ExplicitCapture)]
|
||||
[GeneratedRegex(@"[_ ^](?'Mesh'[0-9]+)[.-]?(?'SubMesh'[0-9]+)?$",
|
||||
RegexOptions.Compiled | RegexOptions.NonBacktracking | RegexOptions.ExplicitCapture)]
|
||||
private static partial Regex MeshNameGroupingRegex();
|
||||
|
||||
private readonly List<MdlStructs.MeshStruct> _meshes = [];
|
||||
private readonly List<MeshStruct> _meshes = [];
|
||||
private readonly List<MdlStructs.SubmeshStruct> _subMeshes = [];
|
||||
|
||||
private readonly List<string> _materials = [];
|
||||
|
|
@ -27,10 +29,10 @@ public partial class ModelImporter(ModelRoot model, IoNotifier notifier)
|
|||
|
||||
private readonly List<ushort> _indices = [];
|
||||
|
||||
private readonly List<string> _bones = [];
|
||||
private readonly List<MdlStructs.BoneTableStruct> _boneTables = [];
|
||||
private readonly List<string> _bones = [];
|
||||
private readonly List<BoneTableStruct> _boneTables = [];
|
||||
|
||||
private readonly BoundingBox _boundingBox = new BoundingBox();
|
||||
private readonly BoundingBox _boundingBox = new();
|
||||
|
||||
private readonly List<string> _metaAttributes = [];
|
||||
|
||||
|
|
@ -95,9 +97,7 @@ public partial class ModelImporter(ModelRoot model, IoNotifier notifier)
|
|||
IndexBufferSize = (uint)indexBuffer.Length,
|
||||
},
|
||||
],
|
||||
|
||||
Materials = [.. materials],
|
||||
|
||||
Materials = [.. materials],
|
||||
BoundingBoxes = _boundingBox.ToStruct(),
|
||||
|
||||
// TODO: Would be good to calculate all of this up the tree.
|
||||
|
|
@ -132,9 +132,9 @@ public partial class ModelImporter(ModelRoot model, IoNotifier notifier)
|
|||
private void BuildMeshForGroup(IEnumerable<Node> subMeshNodes, int index)
|
||||
{
|
||||
// Record some offsets we'll be using later, before they get mutated with mesh values.
|
||||
var subMeshOffset = _subMeshes.Count;
|
||||
var vertexOffset = _vertexBuffer.Count;
|
||||
var indexOffset = _indices.Count;
|
||||
var subMeshOffset = _subMeshes.Count;
|
||||
var vertexOffset = _vertexBuffer.Count;
|
||||
var indexOffset = _indices.Count;
|
||||
|
||||
var mesh = MeshImporter.Import(subMeshNodes, notifier.WithContext($"Mesh {index}"));
|
||||
var meshStartIndex = (uint)(mesh.MeshStruct.StartIndex + indexOffset);
|
||||
|
|
@ -154,9 +154,9 @@ public partial class ModelImporter(ModelRoot model, IoNotifier notifier)
|
|||
SubMeshIndex = (ushort)(mesh.MeshStruct.SubMeshIndex + subMeshOffset),
|
||||
BoneTableIndex = boneTableIndex,
|
||||
StartIndex = meshStartIndex,
|
||||
VertexBufferOffset = mesh.MeshStruct.VertexBufferOffset
|
||||
.Select(offset => (uint)(offset + vertexOffset))
|
||||
.ToArray(),
|
||||
VertexBufferOffset1 = (uint)(mesh.MeshStruct.VertexBufferOffset1 + vertexOffset),
|
||||
VertexBufferOffset2 = (uint)(mesh.MeshStruct.VertexBufferOffset2 + vertexOffset),
|
||||
VertexBufferOffset3 = (uint)(mesh.MeshStruct.VertexBufferOffset3 + vertexOffset),
|
||||
});
|
||||
|
||||
_boundingBox.Merge(mesh.BoundingBox);
|
||||
|
|
@ -196,7 +196,8 @@ public partial class ModelImporter(ModelRoot model, IoNotifier notifier)
|
|||
// 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 notifier.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.");
|
||||
throw notifier.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 GetMaterialIndex(string materialName)
|
||||
|
|
@ -216,6 +217,7 @@ public partial class ModelImporter(ModelRoot model, IoNotifier notifier)
|
|||
return (ushort)count;
|
||||
}
|
||||
|
||||
// #TODO @ackwell fix for V6 Models
|
||||
private ushort BuildBoneTable(List<string> boneNames)
|
||||
{
|
||||
var boneIndices = new List<ushort>();
|
||||
|
|
@ -238,7 +240,7 @@ public partial class ModelImporter(ModelRoot model, IoNotifier notifier)
|
|||
Array.Copy(boneIndices.ToArray(), boneIndicesArray, boneIndices.Count);
|
||||
|
||||
var boneTableIndex = _boneTables.Count;
|
||||
_boneTables.Add(new MdlStructs.BoneTableStruct()
|
||||
_boneTables.Add(new BoneTableStruct()
|
||||
{
|
||||
BoneIndex = boneIndicesArray,
|
||||
BoneCount = (byte)boneIndices.Count,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
|
||||
using Penumbra.GameData.Files;
|
||||
using Penumbra.GameData.Interop;
|
||||
using Penumbra.Interop.SafeHandles;
|
||||
|
||||
|
|
@ -9,7 +8,7 @@ namespace Penumbra.Interop.MaterialPreview;
|
|||
public sealed unsafe class LiveColorTablePreviewer : LiveMaterialPreviewerBase
|
||||
{
|
||||
public const int TextureWidth = 4;
|
||||
public const int TextureHeight = MtrlFile.ColorTable.NumRows;
|
||||
public const int TextureHeight = GameData.Files.MaterialStructs.ColorTable.NumUsedRows;
|
||||
public const int TextureLength = TextureWidth * TextureHeight * 4;
|
||||
|
||||
private readonly IFramework _framework;
|
||||
|
|
@ -17,7 +16,7 @@ public sealed unsafe class LiveColorTablePreviewer : LiveMaterialPreviewerBase
|
|||
private readonly Texture** _colorTableTexture;
|
||||
private readonly SafeTextureHandle _originalColorTableTexture;
|
||||
|
||||
private bool _updatePending;
|
||||
private bool _updatePending;
|
||||
|
||||
public Half[] ColorTable { get; }
|
||||
|
||||
|
|
@ -40,7 +39,7 @@ public sealed unsafe class LiveColorTablePreviewer : LiveMaterialPreviewerBase
|
|||
if (_originalColorTableTexture == null)
|
||||
throw new InvalidOperationException("Material doesn't have a color table");
|
||||
|
||||
ColorTable = new Half[TextureLength];
|
||||
ColorTable = new Half[TextureLength];
|
||||
_updatePending = true;
|
||||
|
||||
framework.Update += OnFrameworkUpdate;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using ImGuiNET;
|
|||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.GameData.Files;
|
||||
using Penumbra.GameData.Files.MaterialStructs;
|
||||
using Penumbra.String.Functions;
|
||||
|
||||
namespace Penumbra.UI.AdvancedWindow;
|
||||
|
|
@ -74,7 +75,7 @@ public partial class ModEditWindow
|
|||
ImGui.TableHeader("Dye Preview");
|
||||
}
|
||||
|
||||
for (var i = 0; i < MtrlFile.ColorTable.NumRows; ++i)
|
||||
for (var i = 0; i < ColorTable.NumUsedRows; ++i)
|
||||
{
|
||||
ret |= DrawColorTableRow(tab, i, disabled);
|
||||
ImGui.TableNextRow();
|
||||
|
|
@ -115,8 +116,8 @@ public partial class ModEditWindow
|
|||
{
|
||||
var ret = false;
|
||||
if (tab.Mtrl.HasDyeTable)
|
||||
for (var i = 0; i < MtrlFile.ColorTable.NumRows; ++i)
|
||||
ret |= tab.Mtrl.ApplyDyeTemplate(_stainService.StmFile, i, dyeId);
|
||||
for (var i = 0; i < ColorTable.NumUsedRows; ++i)
|
||||
ret |= tab.Mtrl.ApplyDyeTemplate(_stainService.StmFile, i, dyeId, 0);
|
||||
|
||||
tab.UpdateColorTablePreview();
|
||||
|
||||
|
|
@ -140,21 +141,21 @@ public partial class ModEditWindow
|
|||
{
|
||||
var text = ImGui.GetClipboardText();
|
||||
var data = Convert.FromBase64String(text);
|
||||
if (data.Length < Marshal.SizeOf<MtrlFile.ColorTable>())
|
||||
if (data.Length < Marshal.SizeOf<ColorTable>())
|
||||
return false;
|
||||
|
||||
ref var rows = ref tab.Mtrl.Table;
|
||||
fixed (void* ptr = data, output = &rows)
|
||||
{
|
||||
MemoryUtility.MemCpyUnchecked(output, ptr, Marshal.SizeOf<MtrlFile.ColorTable>());
|
||||
if (data.Length >= Marshal.SizeOf<MtrlFile.ColorTable>() + Marshal.SizeOf<MtrlFile.ColorDyeTable>()
|
||||
MemoryUtility.MemCpyUnchecked(output, ptr, Marshal.SizeOf<ColorTable>());
|
||||
if (data.Length >= Marshal.SizeOf<ColorTable>() + Marshal.SizeOf<ColorDyeTable>()
|
||||
&& tab.Mtrl.HasDyeTable)
|
||||
{
|
||||
ref var dyeRows = ref tab.Mtrl.DyeTable;
|
||||
fixed (void* output2 = &dyeRows)
|
||||
{
|
||||
MemoryUtility.MemCpyUnchecked(output2, (byte*)ptr + Marshal.SizeOf<MtrlFile.ColorTable>(),
|
||||
Marshal.SizeOf<MtrlFile.ColorDyeTable>());
|
||||
MemoryUtility.MemCpyUnchecked(output2, (byte*)ptr + Marshal.SizeOf<ColorTable>(),
|
||||
Marshal.SizeOf<ColorDyeTable>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -169,7 +170,7 @@ public partial class ModEditWindow
|
|||
}
|
||||
}
|
||||
|
||||
private static unsafe void ColorTableCopyClipboardButton(MtrlFile.ColorTable.Row row, MtrlFile.ColorDyeTable.Row dye)
|
||||
private static unsafe void ColorTableCopyClipboardButton(ColorTable.Row row, ColorDyeTable.Row dye)
|
||||
{
|
||||
if (!ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Clipboard.ToIconString(), ImGui.GetFrameHeight() * Vector2.One,
|
||||
"Export this row to your clipboard.", false, true))
|
||||
|
|
@ -177,11 +178,11 @@ public partial class ModEditWindow
|
|||
|
||||
try
|
||||
{
|
||||
var data = new byte[MtrlFile.ColorTable.Row.Size + 2];
|
||||
var data = new byte[ColorTable.Row.Size + 2];
|
||||
fixed (byte* ptr = data)
|
||||
{
|
||||
MemoryUtility.MemCpyUnchecked(ptr, &row, MtrlFile.ColorTable.Row.Size);
|
||||
MemoryUtility.MemCpyUnchecked(ptr + MtrlFile.ColorTable.Row.Size, &dye, 2);
|
||||
MemoryUtility.MemCpyUnchecked(ptr, &row, ColorTable.Row.Size);
|
||||
MemoryUtility.MemCpyUnchecked(ptr + ColorTable.Row.Size, &dye, 2);
|
||||
}
|
||||
|
||||
var text = Convert.ToBase64String(data);
|
||||
|
|
@ -217,15 +218,15 @@ public partial class ModEditWindow
|
|||
{
|
||||
var text = ImGui.GetClipboardText();
|
||||
var data = Convert.FromBase64String(text);
|
||||
if (data.Length != MtrlFile.ColorTable.Row.Size + 2
|
||||
if (data.Length != ColorTable.Row.Size + 2
|
||||
|| !tab.Mtrl.HasTable)
|
||||
return false;
|
||||
|
||||
fixed (byte* ptr = data)
|
||||
{
|
||||
tab.Mtrl.Table[rowIdx] = *(MtrlFile.ColorTable.Row*)ptr;
|
||||
tab.Mtrl.Table[rowIdx] = *(ColorTable.Row*)ptr;
|
||||
if (tab.Mtrl.HasDyeTable)
|
||||
tab.Mtrl.DyeTable[rowIdx] = *(MtrlFile.ColorDyeTable.Row*)(ptr + MtrlFile.ColorTable.Row.Size);
|
||||
tab.Mtrl.DyeTable[rowIdx] = *(ColorDyeTable.Row*)(ptr + ColorTable.Row.Size);
|
||||
}
|
||||
|
||||
tab.UpdateColorTableRowPreview(rowIdx);
|
||||
|
|
@ -451,7 +452,7 @@ public partial class ModEditWindow
|
|||
return ret;
|
||||
}
|
||||
|
||||
private bool DrawDyePreview(MtrlTab tab, int rowIdx, bool disabled, MtrlFile.ColorDyeTable.Row dye, float floatSize)
|
||||
private bool DrawDyePreview(MtrlTab tab, int rowIdx, bool disabled, ColorDyeTable.Row dye, float floatSize)
|
||||
{
|
||||
var stain = _stainService.StainCombo.CurrentSelection.Key;
|
||||
if (stain == 0 || !_stainService.StmFile.Entries.TryGetValue(dye.Template, out var entry))
|
||||
|
|
@ -463,7 +464,7 @@ public partial class ModEditWindow
|
|||
var ret = ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.PaintBrush.ToIconString(), new Vector2(ImGui.GetFrameHeight()),
|
||||
"Apply the selected dye to this row.", disabled, true);
|
||||
|
||||
ret = ret && tab.Mtrl.ApplyDyeTemplate(_stainService.StmFile, rowIdx, stain);
|
||||
ret = ret && tab.Mtrl.ApplyDyeTemplate(_stainService.StmFile, rowIdx, stain, 0);
|
||||
if (ret)
|
||||
tab.UpdateColorTableRowPreview(rowIdx);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using OtterGui.Classes;
|
|||
using OtterGui.Raii;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.GameData.Files;
|
||||
using Penumbra.GameData.Files.MaterialStructs;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.Hooks.Objects;
|
||||
using Penumbra.Interop.MaterialPreview;
|
||||
|
|
@ -601,7 +602,7 @@ public partial class ModEditWindow
|
|||
var stm = _edit._stainService.StmFile;
|
||||
var dye = Mtrl.DyeTable[rowIdx];
|
||||
if (stm.TryGetValue(dye.Template, _edit._stainService.StainCombo.CurrentSelection.Key, out var dyes))
|
||||
row.ApplyDyeTemplate(dye, dyes);
|
||||
row.ApplyDyeTemplate(dye, dyes, default);
|
||||
}
|
||||
|
||||
if (HighlightedColorTableRow == rowIdx)
|
||||
|
|
@ -628,12 +629,12 @@ public partial class ModEditWindow
|
|||
{
|
||||
var stm = _edit._stainService.StmFile;
|
||||
var stainId = (StainId)_edit._stainService.StainCombo.CurrentSelection.Key;
|
||||
for (var i = 0; i < MtrlFile.ColorTable.NumRows; ++i)
|
||||
for (var i = 0; i < ColorTable.NumUsedRows; ++i)
|
||||
{
|
||||
ref var row = ref rows[i];
|
||||
var dye = Mtrl.DyeTable[i];
|
||||
if (stm.TryGetValue(dye.Template, stainId, out var dyes))
|
||||
row.ApplyDyeTemplate(dye, dyes);
|
||||
row.ApplyDyeTemplate(dye, dyes, default);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -647,7 +648,7 @@ public partial class ModEditWindow
|
|||
}
|
||||
}
|
||||
|
||||
private static void ApplyHighlight(ref MtrlFile.ColorTable.Row row, float time)
|
||||
private static void ApplyHighlight(ref ColorTable.Row row, float time)
|
||||
{
|
||||
var level = (MathF.Sin(time * 2.0f * MathF.PI) + 2.0f) / 3.0f / 255.0f;
|
||||
var baseColor = ColorId.InGameHighlight.Value();
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ public partial class ModEditWindow
|
|||
if (table)
|
||||
{
|
||||
ImGuiUtil.DrawTableColumn("Version");
|
||||
ImGuiUtil.DrawTableColumn(_lastFile.Version.ToString());
|
||||
ImGuiUtil.DrawTableColumn($"0x{_lastFile.Version:X}");
|
||||
ImGuiUtil.DrawTableColumn("Radius");
|
||||
ImGuiUtil.DrawTableColumn(_lastFile.Radius.ToString(CultureInfo.InvariantCulture));
|
||||
ImGuiUtil.DrawTableColumn("Model Clip Out Distance");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue