This commit is contained in:
Ottermandias 2024-01-23 23:23:03 +01:00
parent b2bd31a166
commit a159ef28c3
5 changed files with 47 additions and 39 deletions

View file

@ -2,11 +2,11 @@ using Lumina.Data.Parsing;
namespace Penumbra.Import.Models.Import; namespace Penumbra.Import.Models.Import;
/// <summary> Mutable representation of the bounding box surrouding a collection of vertices. </summary> /// <summary> Mutable representation of the bounding box surrounding a collection of vertices. </summary>
public class BoundingBox public class BoundingBox
{ {
private Vector3 _minimum = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); private Vector3 _minimum = new(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
private Vector3 _maximum = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity); private Vector3 _maximum = new(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity);
/// <summary> Use the specified position to update this bounding box, expanding it if necessary. </summary> /// <summary> Use the specified position to update this bounding box, expanding it if necessary. </summary>
public void Merge(Vector3 position) public void Merge(Vector3 position)
@ -25,7 +25,7 @@ public class BoundingBox
/// <summary> Convert this bounding box to the struct format used in .mdl data structures. </summary> /// <summary> Convert this bounding box to the struct format used in .mdl data structures. </summary>
public MdlStructs.BoundingBoxStruct ToStruct() public MdlStructs.BoundingBoxStruct ToStruct()
=> new MdlStructs.BoundingBoxStruct => new()
{ {
Min = [_minimum.X, _minimum.Y, _minimum.Z, 1], Min = [_minimum.X, _minimum.Y, _minimum.Z, 1],
Max = [_maximum.X, _maximum.Y, _maximum.Z, 1], Max = [_maximum.X, _maximum.Y, _maximum.Z, 1],

View file

@ -53,7 +53,7 @@ public class MeshImporter(IEnumerable<Node> nodes, IoNotifier notifier)
private List<string>? _bones; private List<string>? _bones;
private readonly BoundingBox _boundingBox = new BoundingBox(); private readonly BoundingBox _boundingBox = new();
private readonly List<string> _metaAttributes = []; private readonly List<string> _metaAttributes = [];
@ -124,7 +124,8 @@ public class MeshImporter(IEnumerable<Node> nodes, IoNotifier notifier)
_material ??= subMesh.Material; _material ??= subMesh.Material;
if (subMesh.Material != null && _material != subMesh.Material) if (subMesh.Material != null && _material != subMesh.Material)
notifier.Warning($"Meshes may only reference one material. Sub-mesh {subMeshName} material \"{subMesh.Material}\" has been ignored."); notifier.Warning(
$"Meshes may only reference one material. Sub-mesh {subMeshName} material \"{subMesh.Material}\" has been ignored.");
// Check that vertex declarations match - we need to combine the buffers, so a mismatch would take a whole load of resolution. // Check that vertex declarations match - we need to combine the buffers, so a mismatch would take a whole load of resolution.
if (_vertexDeclaration == null) if (_vertexDeclaration == null)

View file

@ -42,7 +42,7 @@ public class PrimitiveImporter
private byte[] _strides = [0, 0, 0]; private byte[] _strides = [0, 0, 0];
private readonly List<byte>[] _streams = [[], [], []]; private readonly List<byte>[] _streams = [[], [], []];
private BoundingBox _boundingBox = new BoundingBox(); private readonly BoundingBox _boundingBox = new();
private List<List<MdlStructs.ShapeValueStruct>>? _shapeValues; private List<List<MdlStructs.ShapeValueStruct>>? _shapeValues;
@ -154,9 +154,10 @@ public class PrimitiveImporter
_streams[attribute.Stream].AddRange(attribute.Build(vertexIndex)); _streams[attribute.Stream].AddRange(attribute.Build(vertexIndex));
// Record which morph targets have values for this vertex, if any. // Record which morph targets have values for this vertex, if any.
var index = vertexIndex;
var changedMorphs = morphModifiedVertices var changedMorphs = morphModifiedVertices
.WithIndex() .WithIndex()
.Where(pair => _vertexAttributes.Any(attribute => attribute.HasMorph(pair.Index, vertexIndex))) .Where(pair => _vertexAttributes.Any(attribute => attribute.HasMorph(pair.Index, index)))
.Select(pair => pair.Value); .Select(pair => pair.Value);
foreach (var modifiedVertices in changedMorphs) foreach (var modifiedVertices in changedMorphs)
modifiedVertices.Add(vertexIndex); modifiedVertices.Add(vertexIndex);

View file

@ -46,12 +46,12 @@ public class SubMeshImporter
private byte[]? _strides; private byte[]? _strides;
private readonly List<byte>[] _streams = [[], [], []]; private readonly List<byte>[] _streams = [[], [], []];
private List<ushort> _indices = []; private readonly List<ushort> _indices = [];
private BoundingBox _boundingBox = new BoundingBox(); private readonly BoundingBox _boundingBox = new();
private readonly List<string>? _morphNames; private readonly List<string>? _morphNames;
private Dictionary<string, List<MdlStructs.ShapeValueStruct>> _shapeValues = []; private readonly Dictionary<string, List<MdlStructs.ShapeValueStruct>> _shapeValues = [];
private SubMeshImporter(Node node, IDictionary<ushort, ushort>? nodeBoneMap, IoNotifier notifier) private SubMeshImporter(Node node, IDictionary<ushort, ushort>? nodeBoneMap, IoNotifier notifier)
{ {
@ -141,7 +141,7 @@ public class SubMeshImporter
stream.AddRange(primitiveStream); stream.AddRange(primitiveStream);
// Indices // Indices
_indices.AddRange(primitive.Indices.Select(index => (ushort)(index + vertexOffset))); _indices.AddRange(primitive.Indices.Select(i => (ushort)(i + vertexOffset)));
// Shape values // Shape values
foreach (var (primitiveShapeValues, morphIndex) in primitive.ShapeValues.WithIndex()) foreach (var (primitiveShapeValues, morphIndex) in primitive.ShapeValues.WithIndex())
@ -183,6 +183,7 @@ public class SubMeshImporter
return nodeExtras? return nodeExtras?
.Where(pair => pair.Value.ValueKind == JsonValueKind.True) .Where(pair => pair.Value.ValueKind == JsonValueKind.True)
.Select(pair => pair.Key) .Select(pair => pair.Key)
.ToArray() ?? []; .ToArray()
?? [];
} }
} }

View file

@ -28,6 +28,7 @@ public static class Utility
newAttributes.Add(metaAttribute); newAttributes.Add(metaAttribute);
attributeIndex = newAttributes.Count - 1; attributeIndex = newAttributes.Count - 1;
} }
newMask |= 1u << attributeIndex; newMask |= 1u << attributeIndex;
} }
@ -35,18 +36,22 @@ public static class Utility
} }
/// <summary> Ensures that the two vertex declarations provided are equal, throwing if not. </summary> /// <summary> Ensures that the two vertex declarations provided are equal, throwing if not. </summary>
public static void EnsureVertexDeclarationMatch(MdlStructs.VertexDeclarationStruct current, MdlStructs.VertexDeclarationStruct @new, IoNotifier notifier) public static void EnsureVertexDeclarationMatch(MdlStructs.VertexDeclarationStruct current, MdlStructs.VertexDeclarationStruct @new,
IoNotifier notifier)
{ {
if (VertexDeclarationMismatch(current, @new)) if (VertexDeclarationMismatch(current, @new))
throw notifier.Exception( throw notifier.Exception(
$@"All sub-meshes of a mesh must have equivalent vertex declarations. $"""
All sub-meshes of a mesh must have equivalent vertex declarations.
Current: {FormatVertexDeclaration(current)} Current: {FormatVertexDeclaration(current)}
New: {FormatVertexDeclaration(@new)}" New: {FormatVertexDeclaration(@new)}
"""
); );
} }
private static string FormatVertexDeclaration(MdlStructs.VertexDeclarationStruct vertexDeclaration) private static string FormatVertexDeclaration(MdlStructs.VertexDeclarationStruct vertexDeclaration)
=> string.Join(", ", vertexDeclaration.VertexElements.Select(element => $"{element.Usage} ({element.Type}@{element.Stream}:{element.Offset})")); => string.Join(", ",
vertexDeclaration.VertexElements.Select(element => $"{element.Usage} ({element.Type}@{element.Stream}:{element.Offset})"));
private static bool VertexDeclarationMismatch(MdlStructs.VertexDeclarationStruct a, MdlStructs.VertexDeclarationStruct b) private static bool VertexDeclarationMismatch(MdlStructs.VertexDeclarationStruct a, MdlStructs.VertexDeclarationStruct b)
{ {