Handle mesh skeleton edge cases

This commit is contained in:
ackwell 2024-01-01 11:31:38 +11:00
parent 518117b25a
commit 08ed3ca447

View file

@ -69,11 +69,18 @@ public class MeshExporter
_geometryType = GetGeometryType(usages); _geometryType = GetGeometryType(usages);
_materialType = GetMaterialType(usages); _materialType = GetMaterialType(usages);
_skinningType = GetSkinningType(usages); _skinningType = GetSkinningType(usages);
// If there's skinning usages but no bone mapping, there's probably something wrong with the data.
if (_skinningType != typeof(VertexEmpty) && _boneIndexMap == null)
Penumbra.Log.Warning($"Mesh {meshIndex} has skinned vertex usages but no bone information was provided.");
} }
private Dictionary<ushort, int> BuildBoneIndexMap(Dictionary<string, int> boneNameMap) private Dictionary<ushort, int>? BuildBoneIndexMap(Dictionary<string, int> boneNameMap)
{ {
// TODO: BoneTableIndex of 255 means null? if so, it should probably feed into the attributes we assign... // A BoneTableIndex of 255 means that this mesh is not skinned.
if (XivMesh.BoneTableIndex == 255)
return null;
var xivBoneTable = _mdl.BoneTables[XivMesh.BoneTableIndex]; var xivBoneTable = _mdl.BoneTables[XivMesh.BoneTableIndex];
var indexMap = new Dictionary<ushort, int>(); var indexMap = new Dictionary<ushort, int>();
@ -82,8 +89,7 @@ public class MeshExporter
{ {
var boneName = _mdl.Bones[xivBoneIndex]; var boneName = _mdl.Bones[xivBoneIndex];
if (!boneNameMap.TryGetValue(boneName, out var gltfBoneIndex)) if (!boneNameMap.TryGetValue(boneName, out var gltfBoneIndex))
// TODO: handle - i think this is a hard failure, it means that a bone name in the model doesn't exist in the armature. throw new Exception($"Armature does not contain bone \"{boneName}\" requested by mesh {_meshIndex}.");
throw new Exception($"looking for {boneName} in {string.Join(", ", boneNameMap.Keys)}");
indexMap.Add(xivBoneIndex, gltfBoneIndex); indexMap.Add(xivBoneIndex, gltfBoneIndex);
} }