Swift 如何使用ARKit从远程服务器加载模型和纹理?

Swift 如何使用ARKit从远程服务器加载模型和纹理?,swift,arkit,Swift,Arkit,我正在使用Xcode中的Swift开发ARKit应用程序,试图从远程服务器加载模型,但在将模型和纹理/材质加载到一起并正确显示纹理/材质时遇到问题 我已经浏览了一些链接和教程,并加载了模型,但是材料没有显示出来。我已经在场景编辑器中创建了模型,或者下载并转换为.scn文件,在Finder中找到它们,然后将它们上传到web服务器。只有.scn文件和材料(图像) 我希望模型能够像本地加载一样正确加载,显示具有应用纹理的模型,但是我得到的模型没有纹理,只是预期材质的颜色或白色 我收到以下错误,看起来它

我正在使用Xcode中的Swift开发ARKit应用程序,试图从远程服务器加载模型,但在将模型和纹理/材质加载到一起并正确显示纹理/材质时遇到问题

我已经浏览了一些链接和教程,并加载了模型,但是材料没有显示出来。我已经在场景编辑器中创建了模型,或者下载并转换为.scn文件,在Finder中找到它们,然后将它们上传到web服务器。只有.scn文件和材料(图像)

我希望模型能够像本地加载一样正确加载,显示具有应用纹理的模型,但是我得到的模型没有纹理,只是预期材质的颜色或白色

我收到以下错误,看起来它正在本地加载它

ARKitModels[10386:3406637] [SceneKit] Error: Failed to load : <C3DImage 0x281e45180 src:file:///var/containers/Bundle/Application/233AE78F-748F-420B-96AD-30F591ADF80C/ARKitModels.app/material/iPhoneX_Screen.jpg [0.000000x0.000000]>
ARKitModels[10386:3406637][SceneKit]错误:未能加载:

非常感谢您的帮助,如果有更好的方法,请告诉我。谢谢大家!

尝试将预下载的UIImage设置为几何体中所有材质的内容。比如:

geometry.materials.forEach{$0.diffuse.contents = textureImage}

因此,由于我想从远程服务器加载所有内容,由于@ATV的帮助,我在本地没有得到任何东西

解决方案:循环子节点并将纹理设置为与node.name相同的名称。可以在“场景编辑器”(scene editor)中设置节点的名称,然后在适当的文件夹中具有相同的命名图像文件。这允许动态加载。仅当您可以控制模型/服务器或具有明确的指令时,此操作才有效

@objc func handleTap(_ gesture: UITapGestureRecognizer) {

    let results = self.sceneView.hitTest(gesture.location(in: gesture.view), types: ARHitTestResult.ResultType.featurePoint)

    guard let result: ARHitTestResult = results.first else {
        return
    }

    let myURL = NSURL(string: "https://www.website.com/scnfiles/model/model.scn")

    guard let scene = try? SCNScene(url: myURL! as URL, options: nil) else {
        return
    }

    let node = scene.rootNode.childNode(withName: "SketchUp", recursively: true)

    // Solution //
    let children = (node?.childNodes)!

    for child in children {
        child.geometry?.materials.forEach{$0.diffuse.contents = "https://www.website.com/scnfiles/model/materials/" + child.name! + ".jpg"
    }

    node?.scale = SCNVector3(0.025, 0.025, 0.025)

    let position = SCNVector3Make(result.worldTransform.columns.3.x, 
                                  result.worldTransform.columns.3.y, 
                                  result.worldTransform.columns.3.z)
    node?.position = position
    self.sceneView.scene.rootNode.addChildNode(node!)
}

谢谢如何处理所有纹理/在不同曲面上具有许多纹理和不同图像的模型?它只是将纹理放置在所有曲面周围。通常,如果您使用多纹理-您有以下文件列表:-
.obj
(或任何模型的格式)具有定义纹理坐标的文件-
.mtl
具有定义材质、照明设置等的文件-资源(.jpg.png)在
.mtl
中定义为材质纹理的文件您可以阅读更多关于此@Eric.18上面列出的所有这些文件应位于一个目录中-在这种情况下,纹理将自动显示在初始化SCNScene上。所有文件都位于服务器上的同一目录中。纹理不会按预期显示。在你的回答中,什么是纹理年龄?你认为只要把图片和.scn放在同一个目录中,就可以不设置任何材质而直接显示吗?我应该以特定的方式调用init SCNScene吗?@Eric.18“应该位于一个目录中”-我的意思是在电话本地,而不是在服务器上。作为第一步-您应该下载(例如使用
URLSession.shared.downloadTask…
)模型和纹理文件,并将它们保存到本地存储(例如使用
FileManager.default
NSTemporaryDirectory()
)。在此之后,您应该通过向本地模型传递URL来启动
SCNScene
。纹理应该出现在模型上,而不需要手动设置。@Eric.18您能告诉我从远程url获取模型的格式吗?请共享url@Eric.18中的任何一个远程url。您能告诉我如何在服务器端放置.scn模式吗。
@objc func handleTap(_ gesture: UITapGestureRecognizer) {

    let results = self.sceneView.hitTest(gesture.location(in: gesture.view), types: ARHitTestResult.ResultType.featurePoint)

    guard let result: ARHitTestResult = results.first else {
        return
    }

    let myURL = NSURL(string: "https://www.website.com/scnfiles/model/model.scn")

    guard let scene = try? SCNScene(url: myURL! as URL, options: nil) else {
        return
    }

    let node = scene.rootNode.childNode(withName: "SketchUp", recursively: true)

    // Solution //
    let children = (node?.childNodes)!

    for child in children {
        child.geometry?.materials.forEach{$0.diffuse.contents = "https://www.website.com/scnfiles/model/materials/" + child.name! + ".jpg"
    }

    node?.scale = SCNVector3(0.025, 0.025, 0.025)

    let position = SCNVector3Make(result.worldTransform.columns.3.x, 
                                  result.worldTransform.columns.3.y, 
                                  result.worldTransform.columns.3.z)
    node?.position = position
    self.sceneView.scene.rootNode.addChildNode(node!)
}