Skip to content

Commit e0781e4

Browse files
committed
Fix multiple skins per gltf bug
1 parent e60cff6 commit e0781e4

File tree

1 file changed

+56
-12
lines changed

1 file changed

+56
-12
lines changed

Sources/GateEngine/Resources/Import & Export/Importers/GLTransmissionFormat.swift

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -607,13 +607,40 @@ public extension GLTransmissionFormat {
607607
for primitive in mesh.primitives {
608608
if primitive.material == materialIndex {
609609
names.insert(mesh.name)
610-
continue
611610
}
612611
}
613612
}
614613
return Array(names)
615614
}
616615

616+
func skinName(forMesh meshName: String) -> String? {
617+
if let meshIndex = gltf.meshes?.firstIndex(where: {$0.name == meshName}) {
618+
func findIn(_ parent: Int) -> Int? {
619+
let node = gltf.nodes[parent]
620+
for index in node.children ?? [] {
621+
let node = gltf.nodes[index]
622+
if let skinID = node.skin, node.mesh == meshIndex {
623+
return skinID
624+
}
625+
}
626+
for index in node.children ?? [] {
627+
if let value = findIn(index) {
628+
return value
629+
}
630+
}
631+
return nil
632+
}
633+
if let sceneNodes = gltf.scenes[gltf.scene].nodes {
634+
for index in sceneNodes {
635+
if let value = findIn(index) {
636+
return gltf.skins?[value].name
637+
}
638+
}
639+
}
640+
}
641+
return nil
642+
}
643+
617644
func meshNamesWithNoMaterial() -> [String] {
618645
var names: Set<String> = []
619646
for mesh in gltf.meshes ?? [] {
@@ -923,20 +950,37 @@ extension GLTransmissionFormat: SkinImporter {
923950
throw GateEngineError.failedToDecode("File contains no skins.")
924951
}
925952

926-
guard gltf.meshes != nil else {throw GateEngineError.failedToDecode("File contains no geometry.")}
953+
guard let meshes = gltf.meshes else {throw GateEngineError.failedToDecode("File contains no geometry.")}
927954

928955
var skinIndex = 0
929956
if let name = options.subobjectName {
930-
if let direct = gltf.skins?.firstIndex(where: {
931-
$0.name.caseInsensitiveCompare(name) == .orderedSame
932-
}) {
933-
skinIndex = direct
934-
} else if let nodeSkinIndex = gltf.nodes.first(where: {
935-
$0.skin != nil && $0.name == name
936-
})?.skin {
937-
skinIndex = nodeSkinIndex
957+
if let skinName = self.skinName(forMesh: name), let index = skins.firstIndex(where: {$0.name == skinName}) {
958+
skinIndex = index
959+
}else{
960+
throw GateEngineError.failedToDecode(
961+
"Couldn't find skin named \(name)."
962+
)
938963
}
939964
}
965+
966+
var meshIndex = 0
967+
if let name = options.subobjectName {
968+
if let meshID = gltf.nodes.first(where: { $0.name == name })?.mesh {
969+
meshIndex = meshID
970+
} else if let _mesh = meshes.firstIndex(where: { $0.name == name }) {
971+
meshIndex = _mesh
972+
} else {
973+
let meshNames = meshes.map({ $0.name })
974+
let nodeNames = gltf.nodes.filter({ $0.mesh != nil }).map({ $0.name })
975+
throw GateEngineError.failedToDecode(
976+
"Couldn't find geometry named \(name).\nAvailable mesh names: \(meshNames)\nAvaliable node names: \(nodeNames)"
977+
)
978+
}
979+
}else if let meshID = meshForSkin(skinID: skinIndex) {
980+
meshIndex = meshID
981+
}else{
982+
throw GateEngineError.failedToDecode("Couldn't locate skin geometry.")
983+
}
940984

941985
let skin = skins[skinIndex]
942986
guard let inverseBindMatrices = await inverseBindMatrices(
@@ -946,10 +990,10 @@ extension GLTransmissionFormat: SkinImporter {
946990
throw GateEngineError.failedToDecode("Failed to parse skin.")
947991
}
948992

949-
guard let meshID = meshForSkin(skinID: skinIndex) else {
993+
guard meshes.indices.contains(meshIndex) else {
950994
throw GateEngineError.failedToDecode("Couldn't locate skin geometry.")
951995
}
952-
let mesh = gltf.meshes![meshID]
996+
let mesh = meshes[meshIndex]
953997

954998
guard let meshJoints: [UInt32] = await gltf.values(forAccessor: mesh.primitives[0][.joints]!) else {
955999
throw GateEngineError.failedToDecode("Failed to parse skin.")

0 commit comments

Comments
 (0)