简体   繁体   中英

import 3d model in SceneKit on iOS

I have a problem when importing a .obj file from a URL and convert it to a SCNNode

here's the code (swift3):

    let url = URL.init(string: "https://cloud.box.com/shared/static/ock9d81kakj91dz1x4ea.obj")
    let asset = MDLAsset(url: url! as URL)
    let object = asset.object(at: 0)
    let node = SCNNode(mdlObject: object)

but when i run the project, the console shows that:

Could not open OBJ file

how to deal with this?

I think you are exceeding some internal iOS limit with your OBJ file. Please file a report at https://bugreport.apple.com .

This slightly modified version of your code works perfectly in a macOS playground (Xcode 8.0). But in an iOS playground, I see the same "Could not open OBJ file" in the console.

import SceneKit
import ModelIO
import SceneKit.ModelIO

if let url = URL.init(string: "https://cloud.box.com/shared/static/ock9d81kakj91dz1x4ea.obj") {
    let asset = MDLAsset(url: url)
    print(asset)
    let object = asset.object(at: 0)
    print(object)
    let node = SCNNode.init(mdlObject: object)
    print(node)
}

I was able to download and open the OBJ file with Xcode. Then within the scene editor, I converted it to SCN format. That gave me a .SCN file that could be embedded in the iOS project and opened with SCNScene (like the famous spinning spaceship). So if you can live with embedding a static file in your iOS app, that's a way to get your model in. But if you need dynamically loaded models, it won't work.

By they way, if you had the obj file locally, you could just have used:

guard let url = Bundle.main.url(forResource: "ock9d81kakj91dz1x4ea", withExtension: "obj") else { return nil }
    let asset = MDLAsset(url: url)
    let object = asset.object(at: 0)
    let node = SCNNode(mdlObject: object)

This should let you load an obj/dae file in swift 4.2/xcode 10.2+:

Create a scenekit model catalog by going to File --> New --> File and selecting "SceneKit Catalog" from the list.

import SceneKit.ModelIO

Then:

guard let url = Bundle.main.url(
 forResource: "your_obj_filename",
 withExtension: "obj",
 subdirectory: "your_folder.scnassets") 
     else { fatalError("Failed to find model file.") }

let asset = MDLAsset(url:url)
guard let object = asset.object(at: 0) as? MDLMesh 
     else { fatalError("Failed to get mesh from asset.") }

let newNode  = SCNNode(mdlObject: object)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM