如何使用 ARKit 从远程服务器加载模型和纹理? [英] How to load a model and textures from a remote server using ARKit?

查看:30
本文介绍了如何使用 ARKit 从远程服务器加载模型和纹理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on an ARKit app using Swift in Xcode trying to load models from a remote server but am having an issue getting the model and the textures / materials to load together and have the textures / materials display correctly.

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

I have gone through a few links and tutorials and get the model to load but the materials do not show. I have created models in the scene editor, or downloaded them and converted to .scn files, locate them in Finder and then uploaded them to a web-server. Just the .scn file and material (images).

//Tap Gesture 
@objc func handleTap(_ gesture: UITapGestureRecognizer) {

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

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

    //Set URL of location of model
    let myURL = NSURL(string: "https://www.website.com/scnfiles/iPhoneX.scn")

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

    //Set the node to be the model
    let node = scene.rootNode.childNode(withName: "SketchUp", recursively: true)

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

    //The material image is located in the same directory
    node?.geometry?.firstMaterial?.diffuse.contents = UIImage(named: "https://website/scnfiles/iPhoneX_Screen.jpg")

    //set the position of the model
    let position = SCNVector3Make(result.worldTransform.columns.3.x, result.worldTransform.columns.3.y, result.worldTransform.columns.3.z)
        node?.position = position

    //Add to scene
    self.sceneView.scene.rootNode.addChildNode(node!)
}

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

I would like the model to load correctly as it would locally, showing the model with the applied textures but instead I get the model with no textures, just colors or white where the material is expected.

我收到以下错误,看起来像是在尝试在本地加载?

I receive the following error which looks like it is trying to load it locally?

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]>

感谢任何帮助,如果有更好的方法来做到这一点,请告诉我.谢谢!

Any help is appreciated and if there is a better way to do this please let me know. Thank you!

推荐答案

因此,由于我想从远程服务器加载所有内容,因此多亏了 @ATV 的一些帮助,我在本地没有想到这里的任何内容.

So, since I want to load everything from a remote server, nothing locally here is what I came up with thanks to some help from @ATV.

解决方案:循环遍历子节点并将纹理设置为与 node.name 相同的名称.您可以在场景编辑器中设置节点的名称,然后在适当的文件夹中具有相同命名的图像文件.这允许动态加载.这仅适用于您可以控制模型/服务器或有明确说明的情况.

Solution: Loop though child nodes and set texture to the same name as the node.name. You can set the name of the node in scene editor and then have the same named image files in the proper folder. This allows for dynamic loading. This only works if you have control over the models / server or have explicit instructions.

@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!)
}

这篇关于如何使用 ARKit 从远程服务器加载模型和纹理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆