首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >定位ARKIT模型

定位ARKIT模型
EN

Stack Overflow用户
提问于 2020-02-19 23:21:05
回答 1查看 158关注 0票数 1

我在屏幕上定位模型时遇到了一点问题。模型出现了,但它出现在我的上方,而不是我的前面。理想情况下,我希望模型出现在它被点击的地方。请帮帮我!

此函数用于从AWS成功下载模型:

代码语言:javascript
复制
 private func dowloadModel(){
        let url = URL(string: "url_string")!

        URLSession.shared.dataTask(with: url) { data, response, error in

            if let error = error{
                print(error.localizedDescription)
                return
            }

            if let data = data{
                print(data)

                let documentDirectories = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)

                if let documentDirectory = documentDirectories.first{

                    let fileURL = documentDirectory.appendingPathComponent("Food.scn")
                    let dataNS : NSData? = data as NSData

                    try! dataNS?.write(to: fileURL, options: .atomic)

                    print("Saved!")
                }
            }

        }.resume()
    }

这里我将模型渲染到屏幕上:

代码语言:javascript
复制
private func registerGestureRecogniser(){
        print("Tapped")
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        self.sceneView.addGestureRecognizer(tapGestureRecognizer)
    }

下面是被点击的函数:

代码语言:javascript
复制
 @objc func handleTap(gesture: UITapGestureRecognizer) {

        let documentDirectories = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)

        if let documentDirectory = documentDirectories.first{
            let fileURL = documentDirectory.appendingPathComponent("Food.scn")

            do{
                let scene = try SCNScene(url: fileURL, options: nil)
                let node = scene.rootNode.childNode(withName: "Burger", recursively: true)!

                node.position = SCNVector3Make(0, 0, 0);

                self.sceneView.scene.rootNode.addChildNode(node)
            }
            catch{
                print(error)
            }

        }
    }

我也得到了这个错误:

代码语言:javascript
复制
Error: Failed to load <C3DImage
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-19 23:49:09

当你这样做的时候

代码语言:javascript
复制
node.position = SCNVector3Make(0, 0, 0);
self.sceneView.scene.rootNode.addChildNode(node)

将模型节点定位在场景的rootNode处,场景启动时,场景的位置由ARKit确定。

如果希望模型出现在摄影机的前面,则需要抓取摄影机变换(session.currentFrame?.camera.transform),修改-z组件,并将其设置为节点的位置。或者,如果要将模型放置在曲面上,请执行光线投射并使用raycastResult simdWorldPosition作为节点的simdWorldPosition

肯定有raycast的例子,但简而言之,您首先需要定义一个查询:

代码语言:javascript
复制
let bounds = sceneView.bounds
let screenCenter = CGPoint(x: bounds.midX, y: bounds.midY)
let query = sceneView.raycastQuery(from: screenCenter, allowing: .estimatedPlane, alignment: .horizontal)

上面定义了从屏幕中心延伸的光线投射,并且只找到水平表面。有关allowingalignment选项的更多信息,请浏览docs

然后可以使用session投射光线:

代码语言:javascript
复制
session.raycast(query)

这将返回一个ARRaycastResult数组。如果愿意,您可以检查它们并进行选择,但我通常只使用.first one (注意:它可以是空的)。

然后,您需要获取raycastResult转换的转换组件,并将其指定为节点的simdWorldPosition。请注意,可以将整个变换指定给节点simdWorldTransform,但这也会改变节点的方向,您可能希望也可能不希望这样做。

代码语言:javascript
复制
if let raycastResult = session.raycast(query).first {
    node.simdWorldPosition = raycastResult.worldTransform.translation
}

哦,还有,我发现这个小扩展很方便:

代码语言:javascript
复制
extension float4x4 {
    /**
     Treats matrix as a (right-hand column-major convention) transform matrix
     and factors out the translation component of the transform.
    */
    var translation: SIMD3<Float> {
        let translation = columns.3
        return SIMD3<Float>(translation.x, translation.y, translation.z)
    }
}

它允许您在上面的代码中执行worldTransform.translation

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60303610

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档