mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-14 04:34:19 +01:00
Fail soft on invalid attribute masks
This commit is contained in:
parent
c11519c95e
commit
655d1722c1
2 changed files with 27 additions and 10 deletions
|
|
@ -14,7 +14,7 @@ public partial class ModEditWindow
|
||||||
private readonly ModEditWindow _edit;
|
private readonly ModEditWindow _edit;
|
||||||
|
|
||||||
public MdlFile Mdl { get; private set; }
|
public MdlFile Mdl { get; private set; }
|
||||||
private List<string>[] _attributes;
|
private List<string>?[] _attributes;
|
||||||
|
|
||||||
public bool ImportKeepMaterials;
|
public bool ImportKeepMaterials;
|
||||||
public bool ImportKeepAttributes;
|
public bool ImportKeepAttributes;
|
||||||
|
|
@ -290,15 +290,21 @@ public partial class ModEditWindow
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Create a list of attributes per sub mesh. </summary>
|
/// <summary> Create a list of attributes per sub mesh. </summary>
|
||||||
private static List<string>[] CreateAttributes(MdlFile mdl)
|
private static List<string>?[] CreateAttributes(MdlFile mdl)
|
||||||
=> mdl.SubMeshes.Select(s => Enumerable.Range(0, 32)
|
=> mdl.SubMeshes.Select(s =>
|
||||||
|
{
|
||||||
|
var maxAttribute = 31 - BitOperations.LeadingZeroCount(s.AttributeIndexMask);
|
||||||
|
// TODO: Research what results in this - it seems to primarily be reproducible on bgparts, is it garbage data, or an alternative usage of the value?
|
||||||
|
return maxAttribute < mdl.Attributes.Length
|
||||||
|
? Enumerable.Range(0, 32)
|
||||||
.Where(idx => ((s.AttributeIndexMask >> idx) & 1) == 1)
|
.Where(idx => ((s.AttributeIndexMask >> idx) & 1) == 1)
|
||||||
.Select(idx => mdl.Attributes[idx])
|
.Select(idx => mdl.Attributes[idx])
|
||||||
.ToList()
|
.ToList()
|
||||||
).ToArray();
|
: null;
|
||||||
|
}).ToArray();
|
||||||
|
|
||||||
/// <summary> Obtain the attributes associated with a sub mesh by its index. </summary>
|
/// <summary> Obtain the attributes associated with a sub mesh by its index. </summary>
|
||||||
public IReadOnlyList<string> GetSubMeshAttributes(int subMeshIndex)
|
public IReadOnlyList<string>? GetSubMeshAttributes(int subMeshIndex)
|
||||||
=> _attributes[subMeshIndex];
|
=> _attributes[subMeshIndex];
|
||||||
|
|
||||||
/// <summary> Remove or add attributes from a sub mesh by its index. </summary>
|
/// <summary> Remove or add attributes from a sub mesh by its index. </summary>
|
||||||
|
|
@ -308,6 +314,8 @@ public partial class ModEditWindow
|
||||||
public void UpdateSubMeshAttribute(int subMeshIndex, string? old, string? @new)
|
public void UpdateSubMeshAttribute(int subMeshIndex, string? old, string? @new)
|
||||||
{
|
{
|
||||||
var attributes = _attributes[subMeshIndex];
|
var attributes = _attributes[subMeshIndex];
|
||||||
|
if (attributes == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (old != null)
|
if (old != null)
|
||||||
attributes.Remove(old);
|
attributes.Remove(old);
|
||||||
|
|
@ -325,6 +333,9 @@ public partial class ModEditWindow
|
||||||
|
|
||||||
foreach (var (attributes, subMeshIndex) in _attributes.WithIndex())
|
foreach (var (attributes, subMeshIndex) in _attributes.WithIndex())
|
||||||
{
|
{
|
||||||
|
if (attributes == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
var mask = 0u;
|
var mask = 0u;
|
||||||
|
|
||||||
foreach (var attribute in attributes)
|
foreach (var attribute in attributes)
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,7 @@ public partial class ModEditWindow
|
||||||
|
|
||||||
// Sub meshes
|
// Sub meshes
|
||||||
for (var subMeshOffset = 0; subMeshOffset < mesh.SubMeshCount; subMeshOffset++)
|
for (var subMeshOffset = 0; subMeshOffset < mesh.SubMeshCount; subMeshOffset++)
|
||||||
ret |= DrawSubMeshAttributes(tab, meshIndex, disabled, subMeshOffset);
|
ret |= DrawSubMeshAttributes(tab, meshIndex, subMeshOffset, disabled);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -354,7 +354,7 @@ public partial class ModEditWindow
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool DrawSubMeshAttributes(MdlTab tab, int meshIndex, bool disabled, int subMeshOffset)
|
private bool DrawSubMeshAttributes(MdlTab tab, int meshIndex, int subMeshOffset, bool disabled)
|
||||||
{
|
{
|
||||||
using var _ = ImRaii.PushId(subMeshOffset);
|
using var _ = ImRaii.PushId(subMeshOffset);
|
||||||
|
|
||||||
|
|
@ -369,6 +369,12 @@ public partial class ModEditWindow
|
||||||
var widget = _subMeshAttributeTagWidgets[subMeshIndex];
|
var widget = _subMeshAttributeTagWidgets[subMeshIndex];
|
||||||
var attributes = tab.GetSubMeshAttributes(subMeshIndex);
|
var attributes = tab.GetSubMeshAttributes(subMeshIndex);
|
||||||
|
|
||||||
|
if (attributes == null)
|
||||||
|
{
|
||||||
|
attributes = ["invalid attribute data"];
|
||||||
|
disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
var tagIndex = widget.Draw(string.Empty, string.Empty, attributes,
|
var tagIndex = widget.Draw(string.Empty, string.Empty, attributes,
|
||||||
out var editedAttribute, !disabled);
|
out var editedAttribute, !disabled);
|
||||||
if (tagIndex < 0)
|
if (tagIndex < 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue