Fail soft on invalid attribute masks

This commit is contained in:
ackwell 2024-01-20 17:49:39 +11:00
parent c11519c95e
commit 655d1722c1
2 changed files with 27 additions and 10 deletions

View file

@ -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)

View file

@ -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)