问题
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 seeing any textures on device. I get following error message.
ARKitExample[3016:995067] [SceneKit] Error: Failed loading : <C3DImage 0x1d42e1980 src:file:///var/containers/Bundle/Application/622ACF79-2318-4953-A9AE-9A7F2B453AFB/ARKitExample.app/textures/lamp_DIFFUSE.png [0.000000x0.000000]>
ARKitExample[3016:995067] [SceneKit] Error: Failed loading : <C3DImage 0x1d00fe800 src:file:///var/containers/Bundle/Application/622ACF79-2318-4953-A9AE-9A7F2B453AFB/ARKitExample.app/textures/lamp_NORMAL.png [0.000000x0.000000]>
ARKitExample[3016:995067] [SceneKit] Error: Failed loading : <C3DImage 0x1d40ff800 src:file:///var/containers/Bundle/Application/622ACF79-2318-4953-A9AE-9A7F2B453AFB/ARKitExample.app/textures/lamp_METALLIC.png [0.000000x0.000000]>
ARKitExample[3016:995067] [SceneKit] Error: Failed loading : <C3DImage 0x1d42e0d80 src:file:///var/containers/Bundle/Application/622ACF79-2318-4953-A9AE-9A7F2B453AFB/ARKitExample.app/textures/lamp_ROUGHNESS.png [0.000000x0.000000]>
ARKitExample[3016:995067] [SceneKit] Error: Failed loading : <C3DImage 0x1d02e2e00 src:file:///var/containers/Bundle/Application/622ACF79-2318-4953-A9AE-9A7F2B453AFB/ARKitExample.app/textures/lamp_SHADOW.png [0.000000x0.000000]>
how to resolve this issues. Thank you
@ Xartec I have tried your mentioned way but I did not get any response.How can I fix it?
let urlString = "\("https://d533c2fd.ngrok.io/")\("mode")"
let url = URL.init(string: urlString)
let request = URLRequest(url: url!)
let session = URLSession.shared
let downloadTask = session.downloadTask(with: request,
completionHandler: { (location:URL?, response:URLResponse?, error:Error?)
-> Void in
print("location:\(String(describing: location))")
let locationPath = location!.path
// let documents:String = NSHomeDirectory() + "/Documents/"+"\(self.modelName).\(self.fileExtension)"
// let documents:String = NSHomeDirectory() + "/Documents/"+"\("model5").\("scn")"
let documents:String = NSHomeDirectory() + "/Documents/"+"\("mode")"
ls = NSHomeDirectory() + "/Documents"
let fileManager = FileManager.default
if (fileManager.fileExists(atPath: documents)){
try! fileManager.removeItem(atPath: documents)
}
try! fileManager.moveItem(atPath: locationPath, toPath: documents)
print("new location:\(documents)")
let node = SCNNode()
do {
let documentss = documents + "\("model5").\("scn")"
let scene = try SCNScene(url: URL(fileURLWithPath: documentss), options: [.overrideAssetURLs: true])
let nodess = scene.rootNode.childNode(withName: "SketchUp", recursively: true)
node.addChildNode(nodess!)
self.addChildNode(node)
self.modelLoaded = true
} catch {}
})
downloadTask.resume()
回答1:
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)
}
}
}
来源:https://stackoverflow.com/questions/48636461/arkit-how-to-load-scn-and-texture-file-from-server-url