I think you're on the right track visiting all the child nodes. I saw that allMeshes does have 354 meshes that it found. Unlike OBJ files, USD files typically have a scene graph with transform matrices and meshes that you need to account for. In your case, there's two things I can point out. 1) You declare a local variable allMeshes, but it's never stored in the class, so essentially only the very first model is retrieved. 2) You also need to create a list of sub meshes to draw based on your traversal of the scene graph within the USD. To help you out, please refer to the following code:
private static func findAllMeshes(in object: MDLObject, meshes: inout [MDLMesh]) {
print("\(type(of: object))")
print("Visiting \(type(of: object)) \"\(object.name)\"")
// Print the type of all the components.
for case let component in object.components {
print(" Component: \(type(of: component))")
if let transformStack = component as? MDLTransformStack {
print(" Transform stack: \(transformStack.matrix)")
}
}
if let mesh = object as? MDLMesh {
let submeshCount: Int = mesh.submeshes?.count ?? 0
print(" Mesh: \(mesh.vertexCount) vertices, \(submeshCount) submeshes")
meshes.append(mesh)
}
object.children.objects.forEach { findAllMeshes(in: $0, meshes: &meshes) }
}
It's beyond the scope here to detail how to handle this tree traversal. Specifically, you need to do a depth-first search with preordering (i.e. visiting the node before you visit its children). The goal is to have a transform matrix for each geometry/mesh node that takes into account the transform matrix from the upper level node.
Also, instead of recursion, you may choose to do this depth first search with a visited array and unvisited queue. Add each MDLObject (we'll call it a node) that you visit to a queue of unvisited nodes. Then you have a while loop that pops the front of the unvisited queue until it's empty. You add this node to the visited array. Then you add all its children to the back of the unvisited queue.
When this is done, you will have a list of nodes top to bottom. You probably want to have an integer index that keeps track of where the parent node is in the visited array to maintain the tree of matrix transforms for the current mesh. When you iterate through the visited array, update it's currentTransform with something like the following pseudocode:
// Assume that visited[0] is the root node and already has an identity matrix for its transform.
for index = 1..<visited.count {
let parentIndex = visited[index].parentIndex
let parentTransform = visited[parentIndex].transform
// Here, currentTransform is not a member of MDLObject, but you may choose to have your own "node" object to keep track of the current transform.
visited[index].currentTransform = matmul(parentTransform, visited[index].transform]
}
I hope this gives you some pointers on where to go next.