如何使用 ARKit 添加相对于跟踪图像位置的节点?

How to add node relative to tracked image position with ARKit?

当检测到图像时,我在它前面添加一个节点。

Image - what i need garantee

节点是这张图片,关于这张图片,我添加了其他节点,一个在图片上方 (1),另一个在下方 (2)。节点1总是在正确的位置,但节点2有时会在图像前面,这是错误的,有时会像照片一样在正确的位置。

Image - wrong

for anchor in sceneView.session.currentFrame!.anchors {
     let imageAnchor = anchor as! ARImageAnchor
     nodeInformation.position = SCNVector3Make(imageAnchor.transform.columns.3.x/100, imageAnchor.transform.columns.3.y/100 + 0.3, imageAnchor.transform.columns.3.z/100) //node 1
     nodeAuthorInformation.position = SCNVector3Make(imageAnchor.transform.columns.3.x/100 + 0.3, imageAnchor.transform.columns.3.y/100, imageAnchor.transform.columns.3.z/100) //node 2

这是我用来设置我的两个节点的初始位置的代码。

所以我想知道如何保证我的第二个节点始终保持在正确的位置,它在图片旁边.

我如何添加节点:

let tappedNode = self.sceneView.hitTest(gesture.location(in: gesture.view), options: [:])

        if let result = tappedNode.first{
            nodeInformation.transform = result.modelTransform
            nodeAuthorInformation.transform = result.modelTransform
        }
        print("TAP PLACE = ", gesture.location(in: gesture.view))
        if !tappedNode.isEmpty{
            let node = tappedNode[0].node
            print("NODE TAP = ", node.position)
            let artPlane = SCNPlane(width: 0.3, height: 0.3)

            artPlane.firstMaterial?.diffuse.contents = arArtDetailsScene
            artPlane.firstMaterial?.isDoubleSided = true

            let planeNode = SCNNode(geometry: artPlane)
            planeNode.eulerAngles.x = .pi

            authorPlane = SCNPlane(width: 0.2, height: 0.3)
            authorPlane.firstMaterial?.diffuse.contents = arAuthorDetailsScene
            authorPlane.firstMaterial?.isDoubleSided = true

            let planeAuthorNode = SCNNode(geometry: authorPlane)
            planeAuthorNode.eulerAngles.x = .pi

            nodeInformation.addChildNode(planeNode)
            nodeAuthorInformation.addChildNode(planeAuthorNode)
            changeArtDetails(artId: artIndex + 1)

            sceneView.scene.rootNode.addChildNode(nodeInformation)
            sceneView.scene.rootNode.addChildNode(nodeAuthorInformation)
            if sceneView.session.currentFrame != nil {
                for anchor in sceneView.session.currentFrame!.anchors {
                    let imageAnchor = anchor as! ARImageAnchor
                    nodeInformation.position = SCNVector3Make(imageAnchor.transform.columns.3.x/100, imageAnchor.transform.columns.3.y/100 + 0.3, imageAnchor.transform.columns.3.z/100) // initial position node 1
                    nodeAuthorInformation.position = SCNVector3Make(imageAnchor.transform.columns.3.x/100 + 0.3, imageAnchor.transform.columns.3.y/100, imageAnchor.transform.columns.3.z/100) // initial position node 2
                }
            }

我这样更新节点的位置:

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

    if sceneView.session.currentFrame != nil {
        for anchor in sceneView.session.currentFrame!.anchors {
            if let imageAnchor = anchor as? ARImageAnchor{
                DispatchQueue.main.async {

                    self.nodeInformation.position = SCNVector3Make(imageAnchor.transform.columns.3.x/100, imageAnchor.transform.columns.3.y/100 + 0.3, imageAnchor.transform.columns.3.z/100)
                    self.nodeAuthorInformation.position = SCNVector3Make(self.nodeInformation.position.x + 0.3, self.nodeInformation.position.y - 0.3, self.nodeInformation.position.z)//SCNVector3Make(imageAnchor.transform.columns.3.x/100 + 0.3, imageAnchor.transform.columns.3.y/100, imageAnchor.transform.columns.3.z/100)

                }
            } 
        }
    }
}

ARKit 更新锚点的位置,而不是节点。如果锚点是 ARImageAnchor,则需要在 ARSCNViewDelegate.renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? 中提供一个具有三个自定义节点的子节点,而不是手动将其添加到场景中。