@@ -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) . \n Available mesh names: \( meshNames) \n Avaliable 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