我目前正在使用 Apple 的 SceneKit/Model I/O 中的大型 .obj 文件,其中包含多个对象,每个对象都有单独的纹理和材质。这意味着我不能像许多其他表单帖子所建议的那样将单个纹理应用于文件。有没有很好的方法来导入材质和纹理?
我的 obj mtl 和 jpg 都在一个目录中,我也将 scn 场景放在该目录中。
代码当前遵循此设计,我从其各自的位置访问它,将其加载到 MDLAsset 中,然后将其放置到 SCNScene 中,然后将其保存回文件中,以便稍后在代码中加载。
//...
// Get the mesh from the obj object
let asset = MDLAsset(url:url)
//asset.loadTextures()
guard let object = asset.object(at: 0) as? MDLMesh else {
fatalError("Failed to get mesh from obj asset.")
}
// Wrap the ModelIO object in a SceneKit object
let scene = SCNScene()
let node = SCNNode(mdlObject: object)
scene.rootNode.addChildNode(node)
// Get the document directory name the write a url for the object replacing its extention with scn
let dirPaths = FileManager().urls(for: .documentDirectory, in: .userDomainMask)
let fileUrl = dirPaths[0].appendingPathComponent(url.lastPathComponent.replacingOccurrences(of: ".obj", with: ".scn"))
// Write the scene to the new url
if !scene.write(to: fileUrl, delegate: nil) {
print("Failed to write scn scene to file!")
return nil
}
// ...
MDLAsset.loadTextures 函数没有文档,只会导致内存泄漏,因此在本文发布时,它不是一个选项。手动打开模型并点击转换为 SCNScene 也不起作用,因为我仍然丢失了材料。此外,我希望这在代码中实现自动化,以允许在运行时下载和转换模型。
似乎没有内置的方法可以做到这一点,除了在代码中手工制作每个纹理和材料,当它只有一个完整的纹理时这很容易,但这个模型可能有 100 种不同的材料。看起来它需要我手动解析 obj/mtl,然后手动创建和分配材料。这似乎完全不合理,我认为一定有更好的方法,我不知道。