diff --git a/Penumbra.GameData b/Penumbra.GameData index ab09e21f..63f4de73 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit ab09e21fa46be83f82c400dfd2fe05a281b6f28d +Subproject commit 63f4de7305616b6cb8921513e5d83baa8913353f diff --git a/Penumbra/Import/Models/Export/MeshExporter.cs b/Penumbra/Import/Models/Export/MeshExporter.cs index 928c8670..d5e168a3 100644 --- a/Penumbra/Import/Models/Export/MeshExporter.cs +++ b/Penumbra/Import/Models/Export/MeshExporter.cs @@ -297,8 +297,8 @@ 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.UInt => reader.ReadBytes(4), - MdlFile.VertexType.ByteFloat4 => new Vector4(reader.ReadByte() / 255f, reader.ReadByte() / 255f, reader.ReadByte() / 255f, + MdlFile.VertexType.UByte4 => reader.ReadBytes(4), + 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(), diff --git a/Penumbra/Import/Models/Import/VertexAttribute.cs b/Penumbra/Import/Models/Import/VertexAttribute.cs index b73f6a89..74a29f72 100644 --- a/Penumbra/Import/Models/Import/VertexAttribute.cs +++ b/Penumbra/Import/Models/Import/VertexAttribute.cs @@ -30,12 +30,16 @@ public class VertexAttribute public byte Size => (MdlFile.VertexType)Element.Type switch { - MdlFile.VertexType.Single3 => 12, - MdlFile.VertexType.Single4 => 16, - MdlFile.VertexType.UInt => 4, - MdlFile.VertexType.ByteFloat4 => 4, - MdlFile.VertexType.Half2 => 4, - MdlFile.VertexType.Half4 => 8, + MdlFile.VertexType.Single1 => 4, + MdlFile.VertexType.Single2 => 8, + MdlFile.VertexType.Single3 => 12, + MdlFile.VertexType.Single4 => 16, + MdlFile.VertexType.UByte4 => 4, + MdlFile.VertexType.Short2 => 4, + MdlFile.VertexType.Short4 => 8, + MdlFile.VertexType.NByte4 => 4, + MdlFile.VertexType.Half2 => 4, + MdlFile.VertexType.Half4 => 8, _ => throw new Exception($"Unhandled vertex type {(MdlFile.VertexType)Element.Type}"), }; @@ -126,7 +130,7 @@ public class VertexAttribute var element = new MdlStructs.VertexElement() { Stream = 0, - Type = (byte)MdlFile.VertexType.ByteFloat4, + Type = (byte)MdlFile.VertexType.NByte4, Usage = (byte)MdlFile.VertexUsage.BlendWeights, }; @@ -134,7 +138,7 @@ public class VertexAttribute return new VertexAttribute( element, - index => BuildByteFloat4(values[index]) + index => BuildNByte4(values[index]) ); } @@ -152,7 +156,7 @@ public class VertexAttribute var element = new MdlStructs.VertexElement() { Stream = 0, - Type = (byte)MdlFile.VertexType.UInt, + Type = (byte)MdlFile.VertexType.UByte4, Usage = (byte)MdlFile.VertexUsage.BlendIndices, }; @@ -163,7 +167,7 @@ public class VertexAttribute index => { var gltfIndices = values[index]; - return BuildUInt(new Vector4( + return BuildUByte4(new Vector4( boneMap[(ushort)gltfIndices.X], boneMap[(ushort)gltfIndices.Y], boneMap[(ushort)gltfIndices.Z], @@ -181,7 +185,7 @@ public class VertexAttribute var element = new MdlStructs.VertexElement() { Stream = 1, - Type = (byte)MdlFile.VertexType.Half4, + Type = (byte)MdlFile.VertexType.Single3, Usage = (byte)MdlFile.VertexUsage.Normal, }; @@ -193,7 +197,7 @@ public class VertexAttribute return new VertexAttribute( element, - index => BuildHalf4(new Vector4(values[index], 0)), + index => BuildSingle3(values[index]), buildMorph: (morphIndex, vertexIndex) => { var value = values[vertexIndex]; @@ -202,7 +206,7 @@ public class VertexAttribute if (delta != null) value += delta.Value; - return BuildHalf4(new Vector4(value, 0)); + return BuildSingle3(value); } ); } @@ -224,20 +228,20 @@ public class VertexAttribute // There's only one TEXCOORD, output UV coordinates as vec2s. if (!accessors.TryGetValue("TEXCOORD_1", out var accessor2)) return new VertexAttribute( - element with { Type = (byte)MdlFile.VertexType.Half2 }, - index => BuildHalf2(values1[index]) + element with { Type = (byte)MdlFile.VertexType.Single2 }, + index => BuildSingle2(values1[index]) ); var values2 = accessor2.AsVector2Array(); // Two TEXCOORDs are available, repack them into xiv's vec4 [0X, 0Y, 1X, 1Y] format. return new VertexAttribute( - element with { Type = (byte)MdlFile.VertexType.Half4 }, + element with { Type = (byte)MdlFile.VertexType.Single4 }, index => { var value1 = values1[index]; var value2 = values2[index]; - return BuildHalf4(new Vector4(value1.X, value1.Y, value2.X, value2.Y)); + return BuildSingle4(new Vector4(value1.X, value1.Y, value2.X, value2.Y)); } ); } @@ -264,7 +268,7 @@ public class VertexAttribute var element = new MdlStructs.VertexElement { Stream = 1, - Type = (byte)MdlFile.VertexType.ByteFloat4, + Type = (byte)MdlFile.VertexType.NByte4, Usage = (byte)MdlFile.VertexUsage.Tangent1, }; @@ -305,7 +309,7 @@ public class VertexAttribute // Byte floats encode 0..1, and bitangents are stored as -1..1. Convert. bitangent = (bitangent + Vector3.One) / 2; - return BuildByteFloat4(new Vector4(bitangent, handedness)); + return BuildNByte4(new Vector4(bitangent, handedness)); } /// Attempt to calculate tangent values based on other pre-existing data. @@ -400,7 +404,7 @@ public class VertexAttribute var element = new MdlStructs.VertexElement() { Stream = 1, - Type = (byte)MdlFile.VertexType.ByteFloat4, + Type = (byte)MdlFile.VertexType.NByte4, Usage = (byte)MdlFile.VertexUsage.Color, }; @@ -409,10 +413,17 @@ public class VertexAttribute return new VertexAttribute( element, - index => BuildByteFloat4(values?[index] ?? Vector4.One) + index => BuildNByte4(values?[index] ?? Vector4.One) ); } + private static byte[] BuildSingle2(Vector2 input) + => + [ + ..BitConverter.GetBytes(input.X), + ..BitConverter.GetBytes(input.Y), + ]; + private static byte[] BuildSingle3(Vector3 input) => [ @@ -421,7 +432,16 @@ public class VertexAttribute ..BitConverter.GetBytes(input.Z), ]; - private static byte[] BuildUInt(Vector4 input) + private static byte[] BuildSingle4(Vector4 input) + => + [ + ..BitConverter.GetBytes(input.X), + ..BitConverter.GetBytes(input.Y), + ..BitConverter.GetBytes(input.Z), + ..BitConverter.GetBytes(input.W), + ]; + + private static byte[] BuildUByte4(Vector4 input) => [ (byte)input.X, @@ -430,7 +450,7 @@ public class VertexAttribute (byte)input.W, ]; - private static byte[] BuildByteFloat4(Vector4 input) + private static byte[] BuildNByte4(Vector4 input) => [ (byte)Math.Round(input.X * 255f), @@ -438,20 +458,4 @@ public class VertexAttribute (byte)Math.Round(input.Z * 255f), (byte)Math.Round(input.W * 255f), ]; - - private static byte[] BuildHalf2(Vector2 input) - => - [ - ..BitConverter.GetBytes((Half)input.X), - ..BitConverter.GetBytes((Half)input.Y), - ]; - - private static byte[] BuildHalf4(Vector4 input) - => - [ - ..BitConverter.GetBytes((Half)input.X), - ..BitConverter.GetBytes((Half)input.Y), - ..BitConverter.GetBytes((Half)input.Z), - ..BitConverter.GetBytes((Half)input.W), - ]; }