首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ARKit - ARRreferenceImage跟踪

ARKit - ARRreferenceImage跟踪
EN

Stack Overflow用户
提问于 2018-03-23 20:56:56
回答 1查看 1.7K关注 0票数 0

我正在使用ARReferenceImages在ARKit中玩,当一个引用图像被识别时,我尝试添加一个SCNNode,然后不管是否在其他地方识别相同的引用映像,都保留该节点的位置。

我可以正确地添加我的SCNode,但是如果我移动我的标记,它会再次捡起它,并将我放置的节点移动到标记的位置。

我要添加的代码如下:

代码语言:javascript
复制
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let imageAnchor = anchor as? ARImageAnchor else { return }
        let referenceImage = imageAnchor.referenceImage
        print("MAPNODE IS NIL = \(self.mapNode == nil)")
        updateQueue.async {
            if self.mapNode == nil {

            // Create a plane to visualize the initial position of the detected image.
            let plane = SCNPlane(width: 1.2912,
                                 height: 1.2912)
            let planeNode = SCNNode(geometry: plane)
            planeNode.opacity = 1

            /*
             `SCNPlane` is vertically oriented in its local coordinate space, but
             `ARImageAnchor` assumes the image is horizontal in its local space, so
             rotate the plane to match.
             */
            planeNode.eulerAngles.x = -.pi / 2

            self.mapNode = planeNode
            /*
             Image anchors are not tracked after initial detection, so create an
             animation that limits the duration for which the plane visualization appears.
             */
            // Add the plane visualization to the scene.
            node.addChildNode(planeNode)
            }
        }
 }

在这里读取文档experience#2958517声明

应用最佳做法 这个示例应用程序简单地可视化了ARKit在用户环境中检测每个参考图像的位置,但是您的应用程序可以做得更多。按照下面的提示设计AR经验,很好地使用图像检测。 使用检测到的图像来设置AR场景的参考框架。与其要求用户选择虚拟内容的位置,或者在用户的环境中任意放置内容,不如使用检测到的图像来锚定虚拟场景。您甚至可以使用多个检测到的图像。例如,零售商店的应用程序可以通过识别放置在店门两侧的海报,然后在海报之间直接计算字符的位置,从而使虚拟角色从商店的前门出现。 备注 使用ARSession setWorldOrigin(relativeTransform:)方法重新定义世界坐标系,以便您可以将所有锚点和其他内容相对于您选择的参考点放置。 设计您的AR体验使用检测到的图像作为虚拟内容的起点。ARKit不跟踪每个检测到的图像的位置或方向的变化。如果试图放置与检测到的图像相关联的虚拟内容,则该内容可能会出现不正确的位置。相反,使用检测到的图像作为启动动态场景的参考框架。例如,你的应用程序可能识别科幻电影的戏剧海报,然后虚拟宇宙飞船出现在海报上并在环境中飞行。

所以我试着把我的世界变换设置为等同于我的形象锚的转换。

代码语言:javascript
复制
 self.session.setWorldOrigin(relativeTransform: imageAnchor.transform)

然而,我的mapNode在它移动的地方遵循imageAnchor。我还没有实现renderer update方法,所以我不知道为什么这个方法会继续前进。

我假设setWorldOrigin方法不断地更新到imageAnchor.transform,而不仅仅是那个时刻,这很奇怪,因为该代码只被调用一次。有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-24 02:07:56

如果要在mapNode的位置添加ARImageAnchor,可以在转换ARImageAnchor时设置mapNode的位置,并将其添加到场景中,但如果这有意义,则不链接到参考图像。

这样做是可以的:

代码语言:javascript
复制
 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

        //1. If Out Target Image Has Been Detected Than Get The Corresponding Anchor
        guard let currentImageAnchor = anchor as? ARImageAnchor else { return }

        //2. An ImageAnchor Is Only Added Once For Each Identified Target
        print("Anchor ID = \(currentImageAnchor.identifier)")

        //3. Add An SCNNode At The Position Of The Identified ImageTarget
        let nodeHolder = SCNNode()

        let nodeGeometry = SCNBox(width: 0.02, height: 0.02, length: 0.02, chamferRadius: 0)
        nodeGeometry.firstMaterial?.diffuse.contents = UIColor.cyan
        nodeHolder.geometry = nodeGeometry

        nodeHolder.position = SCNVector3(currentImageAnchor.transform.columns.3.x,
                                         currentImageAnchor.transform.columns.3.y,
                                         currentImageAnchor.transform.columns.3.z)

        augmentedRealityView?.scene.rootNode.addChildNode(nodeHolder)

 }

在问题的另一部分中,您似乎暗示要检测同一图像的多次出现。我可能错了,但我认为唯一的方法是删除引用映像的相应ARImageAnchor,这可以这样做(在最后一个代码片段的末尾添加它):

代码语言:javascript
复制
 augmentedRealitySession.remove(anchor: currentImageAnchor)

这里的问题是,一旦ARImageAnchor被删除,每当再次检测到它时,您都必须处理是否应该添加内容,这是很棘手的,因为ARImageAnchor.identifier对于referenceImage来说总是一样的,而不管它是否被删除,然后重新添加,因此很难存储在dictionary中等等。因此,根据您的需要,您需要找到一种方法来确定是否存在该位置的内容,以及是否重新添加它等等。

关于setWorldOrigin的问题的最后一部分看起来有点奇怪,就像您说的那样,但是也许您可以添加一个Bool来防止它可能发生变化,例如:

代码语言:javascript
复制
var hasSetWorldOrigin = false

然后,在此基础上,您可以确保只设置一次,例如:

代码语言:javascript
复制
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

        //1. If Out Target Image Has Been Detected Than Get The Corresponding Anchor
        guard let currentImageAnchor = anchor as? ARImageAnchor else { return }


        //2. If We Havent Set The World Origin Set It Based On The ImageAnchorTranform
        if !hasSetWorldOrigin{

            self.augmentedRealitySession.setWorldOrigin(relativeTransform: currentImageAnchor.transform)
            hasSetWorldOrigin = true

            //3. Create Two Nodes To Add To The Scene And Distribute Them
            let nodeHolderA = SCNNode()
            let nodeGeometryA = SCNBox(width: 0.04, height: 0.04, length: 0.04, chamferRadius: 0)
            nodeGeometryA.firstMaterial?.diffuse.contents = UIColor.green
            nodeHolderA.geometry = nodeGeometryA

            let nodeHolderB = SCNNode()
            let nodeGeometryB = SCNBox(width: 0.04, height: 0.04, length: 0.04, chamferRadius: 0)
            nodeGeometryB.firstMaterial?.diffuse.contents = UIColor.red
            nodeHolderB.geometry = nodeGeometryB

            if let cameraTransform = augmentedRealitySession.currentFrame?.camera.transform{
                nodeHolderA.simdPosition =  float3(cameraTransform.columns.3.x,
                                                   cameraTransform.columns.3.y,
                                                   cameraTransform.columns.3.z)

                nodeHolderB.simdPosition =  float3(cameraTransform.columns.3.x + 0.2,
                                                   cameraTransform.columns.3.y,
                                                   cameraTransform.columns.3.z)
            }


            augmentedRealityView?.scene.rootNode.addChildNode(nodeHolderA)
            augmentedRealityView?.scene.rootNode.addChildNode(nodeHolderB)
        }

}

希望我的回答能为你提供一个有用的起点,假设我已经正确地解释了你的问题,

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

https://stackoverflow.com/questions/49458193

复制
相关文章

相似问题

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