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

查看:93
本文介绍了如何使用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中找到它们,然后将其上传到Web服务器.只是.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!

推荐答案

因此,由于我想从远程服务器加载所有内容,因此@@@@@@@@@@@@@@@的一些帮助,使我在本地没有想到.

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天全站免登陆