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

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

У меня есть мои obj mtl и jpg в одном каталоге, куда я также помещаю сцену scn.

Код в настоящее времяСледуя этой схеме, я получаю к нему доступ из соответствующего местоположения, загружаю его в набор MDLAsset, затем помещаю его в сцену SCNS, где он сохраняется обратно в файл, который будет загружен позже в коде.

//...  

// 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 Ответ

0 голосов
/ 11 сентября 2018

Когда вы импортируете 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.

...