Загрузить.obj в.scn с несколькими подобъектами, текстурами, материалами в SceneKit & Model I/O?

В настоящее время я работаю с большими файлами.obj в Apple SceneKit/Model I/O, которые содержат несколько объектов внутри, каждый с отдельными текстурами и материалами. Это означает, что я не могу применить одну текстуру к файлу, как предлагают многие другие посты формы. Есть ли хороший способ импортировать в материалы и текстуры?

У меня есть мои 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 вручную, а затем создать и назначить материалы вручную. Это кажется совершенно неразумным, и я полагаю, что должен быть лучший способ, о котором я не знаю.

1 ответ

Когда вы импортируете OBJ-файл через Model I/O в качестве MDLAsset, он поступит как коллекция из одного или нескольких MDLMeshes. С сетками будут связаны MDLMaterials, а у MDLMaterial будут атрибуты. Эти атрибуты будут числовыми, путями к файлам или изображениями. Вам нужно перебрать свойства и проверить, есть ли путь.

https://developer.apple.com/documentation/modelio/mdlmaterialproperty

Если это так, то, скорее всего, это будет fileURL с тем же содержимым, что и в соответствующем MTL-файле OBJ-файла.

Свойства, описанные в функции MDLScatteringFunction, соответствуют различным свойствам в типичном файле MTL.

https://developer.apple.com/documentation/modelio/mdlscatteringfunction

MDLAsset.loadTextures добавит значение MDLTextureSampler к свойству, если Model IO действительно сможет найти текстуру, на которую есть ссылка в файле MTL.

Другие вопросы по тегам