mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-15 13:14:17 +01:00
Init support for DT model i/o
This commit is contained in:
parent
389c42e68f
commit
8084f48144
3 changed files with 281 additions and 78 deletions
|
|
@ -311,15 +311,28 @@ 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,
|
||||
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(),
|
||||
(float)reader.ReadHalf()),
|
||||
|
||||
MdlFile.VertexType.Half4 => new Vector4((float)reader.ReadHalf(), (float)reader.ReadHalf(), (float)reader.ReadHalf(), (float)reader.ReadHalf()),
|
||||
MdlFile.VertexType.UShort4 => ReadUShort4(reader),
|
||||
var other => throw _notifier.Exception<ArgumentOutOfRangeException>($"Unhandled vertex type {other}"),
|
||||
};
|
||||
}
|
||||
|
||||
private byte[] ReadUShort4(BinaryReader reader)
|
||||
{
|
||||
var buffer = reader.ReadBytes(8);
|
||||
var byteValues = new byte[8];
|
||||
byteValues[0] = buffer[0];
|
||||
byteValues[4] = buffer[1];
|
||||
byteValues[1] = buffer[2];
|
||||
byteValues[5] = buffer[3];
|
||||
byteValues[2] = buffer[4];
|
||||
byteValues[6] = buffer[5];
|
||||
byteValues[3] = buffer[6];
|
||||
byteValues[7] = buffer[7];
|
||||
return byteValues;
|
||||
}
|
||||
|
||||
/// <summary> Get the vertex geometry type for this mesh's vertex usages. </summary>
|
||||
private Type GetGeometryType(IReadOnlyDictionary<MdlFile.VertexUsage, MdlFile.VertexType> usages)
|
||||
|
|
@ -444,7 +457,16 @@ public class MeshExporter
|
|||
private static Type GetSkinningType(IReadOnlyDictionary<MdlFile.VertexUsage, MdlFile.VertexType> usages)
|
||||
{
|
||||
if (usages.ContainsKey(MdlFile.VertexUsage.BlendWeights) && usages.ContainsKey(MdlFile.VertexUsage.BlendIndices))
|
||||
return typeof(VertexJoints4);
|
||||
{
|
||||
if (usages[MdlFile.VertexUsage.BlendWeights] == MdlFile.VertexType.UShort4)
|
||||
{
|
||||
return typeof(VertexJoints8);
|
||||
}
|
||||
else
|
||||
{
|
||||
return typeof(VertexJoints4);
|
||||
}
|
||||
}
|
||||
|
||||
return typeof(VertexEmpty);
|
||||
}
|
||||
|
|
@ -455,15 +477,17 @@ public class MeshExporter
|
|||
if (_skinningType == typeof(VertexEmpty))
|
||||
return new VertexEmpty();
|
||||
|
||||
if (_skinningType == typeof(VertexJoints4))
|
||||
if (_skinningType == typeof(VertexJoints4) || _skinningType == typeof(VertexJoints8))
|
||||
{
|
||||
if (_boneIndexMap == null)
|
||||
throw _notifier.Exception("Tried to build skinned vertex but no bone mappings are available.");
|
||||
|
||||
var indices = ToByteArray(attributes[MdlFile.VertexUsage.BlendIndices]);
|
||||
var weights = ToVector4(attributes[MdlFile.VertexUsage.BlendWeights]);
|
||||
|
||||
var bindings = Enumerable.Range(0, 4)
|
||||
var indiciesData = attributes[MdlFile.VertexUsage.BlendIndices];
|
||||
var weightsData = attributes[MdlFile.VertexUsage.BlendWeights];
|
||||
var indices = ToByteArray(indiciesData);
|
||||
var weights = ToFloatArray(weightsData);
|
||||
|
||||
var bindings = Enumerable.Range(0, indices.Length)
|
||||
.Select(bindingIndex =>
|
||||
{
|
||||
// NOTE: I've not seen any files that throw this error that aren't completely broken.
|
||||
|
|
@ -474,7 +498,13 @@ public class MeshExporter
|
|||
return (jointIndex, weights[bindingIndex]);
|
||||
})
|
||||
.ToArray();
|
||||
return new VertexJoints4(bindings);
|
||||
|
||||
return bindings.Length switch
|
||||
{
|
||||
4 => new VertexJoints4(bindings),
|
||||
8 => new VertexJoints8(bindings),
|
||||
_ => throw _notifier.Exception($"Invalid number of bone bindings {bindings.Length}.")
|
||||
};
|
||||
}
|
||||
|
||||
throw _notifier.Exception($"Unknown skinning type {_skinningType}");
|
||||
|
|
@ -517,4 +547,12 @@ public class MeshExporter
|
|||
byte[] value => value,
|
||||
_ => throw new ArgumentOutOfRangeException($"Invalid byte[] input {data}"),
|
||||
};
|
||||
|
||||
private static float[] ToFloatArray(object data)
|
||||
=> data switch
|
||||
{
|
||||
byte[] value => value.Select(x => x / 255f).ToArray(),
|
||||
_ => throw new ArgumentOutOfRangeException($"Invalid float[] input {data}"),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue