【问题标题】:.obj file from server URL doesn't work来自服务器 URL 的 .obj 文件不起作用
【发布时间】:2018-02-15 09:32:16
【问题描述】:

我需要从服务器 URL 导入 3D 模型,但它不能正常工作。 这是我的代码:

guard let path = modelPath, !path.isEmpty else {
    fatalError("Failed to find model file path.")
}

guard let modelURL = URL(string: path) else {
    fatalError("Failed to find model URL.")
}

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

...在object 崩溃。

【问题讨论】:

  • 所以你有一个像example.com/download/myfile.obj这样的网址?您是否可以通过浏览器下载或收到 HTTP 错误?
  • url 类似于“https://****1_3d-model.obj***35b679b0e04927f”。是的,我可以从浏览器下载它而不会出错。

标签: ios swift4 scenekit modelio


【解决方案1】:

MDLAsset(url:) 不处理从服务器下载模型,它仅适用于指向本地存储的URLs。

您必须自己下载它(使用 URLSession 或像 Alamofire 这样的框架)。

使用URLSession的示例:

下载任务将返回在回调闭包返回后将被删除的文件的临时位置,因此如果您需要重用该文件,则必须将其重新保存在某个地方。

tempLocation 文件的扩展名为 .tmpMDLAsset 将无法处理。即使您不需要保留文件,我也没有想出比使用所需扩展名(.obj 即)重新保存文件更好的方法。

let fileManager = FileManager.default
let localModelName = "model.obj"
let serverModelURL = URL(...)
let localModelURL = fileManager
        .urls(for: .documentDirectory, in: .userDomainMask[0]
        .appendingPathComponent(localModelName)

let session = URLSession(configuration: .default)
let task = session.downloadTask(with: modelURL) { tempLocation, response, error in
    guard let tempLocation = tempLocation else {
        // handle error
        return
    }

    do {
        // FileManager's copyItem throws an error if the file exist
        // so we check and remove previously downloaded file
        // That's just for testing purposes, you probably wouldn't want to download
        // the same model multiple times instead of just persisting it

        if fileManager.fileExists(atPath: localModelURL.path) {
            try fileManager.removeItem(at: localModelURL)
        }

        try fileManager.copyItem(at: tempLocation, to: localModelURL)

    } catch {
        // handle error
    }

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

task.resume() // don't forget to call resume to start downloading

【讨论】:

    【解决方案2】:

    我认为 .obj 对象还需要至少一个 .mlt 文件,可能还有一个 .jpg 文件用于纹理,请检查您是否有错误,因为这些文件丢失了

    【讨论】:

    • 没有 .obj 和 .jpg 就足够了。我在项目中有 .jpg。如果我从捆绑包中获取 .obj,它可以正常工作,但如果我为 .obj 提供服务器 URL 则无法正常工作
    • @iBeginner 只需要 .obj 来加载网格,不需要纹理。此外,MDLAsset 需要一个本地 URL。您必须自己从服务器下载 .obj
    猜你喜欢
    • 2012-12-08
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 2018-08-06
    • 2010-10-31
    相关资源
    最近更新 更多