ARKit - How to load .scn and texture file from server URL

前端 未结 1 1870
南旧
南旧 2021-02-06 09:20

I try to load dynamically .scn and texture files from server URL in ARKit application. I have achieved loading .scn file from web url this way.. But after running I am not seei

1条回答
  •  一向
    一向 (楼主)
    2021-02-06 10:06

    Here's the relevant code. I use Alamofire to download from the server and ZIPFoundation for unzipping. In my case I work with mtl/obj files, but working with scn or dae, should work just fine too.

    let modelsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    
    func loadNodeWithID(_ id: String, completion: @escaping (SCNNode?) -> Void) {
        // Check that assets for that model are not already downloaded
        let fileManager = FileManager.default
        let dirForModel = modelsDirectory.appendingPathComponent(id)
        let dirExists = fileManager.fileExists(atPath: dirForModel.path)
        if dirExists {
            completion(loadNodeWithIdFromDisk(id))
        } else {
            let dumbURL = "http://yourserver/yourfile.zip"
            downloadZip(from: dumbURL, at: id) {
                if let url = $0 {
                    print("Downloaded and unzipped at: \(url.absoluteString)")
                    completion(self.loadNodeWithIdFromDisk(id))
                } else {
                    print("Something went wrong!")
                    completion(nil)
                }
            }
        }
    }
    
    func loadNodeWithIdFromDisk(_ id: String) -> SCNNode? {
        let fileManager = FileManager.default
        let dirForModel = modelsDirectory.appendingPathComponent(id) 
        do {
            let files = try fileManager.contentsOfDirectory(atPath: dirForModel.path)
            if let objFile = files.first(where: { $0.hasSuffix(".obj") }) {
                let objScene = try? SCNScene(url: dirForModel.appendingPathComponent(objFile), options: nil)
                let objNode = objScene?.rootNode.firstChild()
                return objNode
            } else {
                print("No obj file in directory: \(dirForModel.path)")
                return nil
            }
        } catch {
            print("Could not enumarate files or load scene: \(error)")
            return nil
        }
    }
    
    func downloadZip(from urlString: String, at destFileName: String, completion: ((URL?) -> Void)?) {
        print("Downloading \(urlString)")
        let fullDestName = destFileName + ".zip"
    
        let destination: DownloadRequest.DownloadFileDestination = { _, _ in
            let fileURL = modelsDirectory.appendingPathComponent(fullDestName)
            return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
        }
    
        Alamofire.download(urlString, to: destination).response { response in
            let error = response.error
            if error == nil {
                if let filePath = response.destinationURL?.path {
                    let nStr = NSString(string: filePath)
                    let id = NSString(string: nStr.lastPathComponent).deletingPathExtension
                    print(response)
                    print("file downloaded at: \(filePath)")
                    let fileManager = FileManager()
                    let sourceURL = URL(fileURLWithPath: filePath)
                    var destinationURL = modelsDirectory
                    destinationURL.appendPathComponent(id)
                    do {
                        try fileManager.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)
                        try fileManager.unzipItem(at: sourceURL, to: destinationURL)
                        completion?(destinationURL)
                    } catch {
                        completion?(nil)
                        print("Extraction of ZIP archive failed with error: \(error)")
                    }
                } else {
                    completion?(nil)
                    print("File path not found")
                }
            } else {
                // Handle error
                completion?(nil)
            }
        }
    }
    

    0 讨论(0)
提交回复
热议问题