使用ARAnchor插入节点和直接插入节点之间有什么区别? [英] What's the difference between using ARAnchor to insert a node and directly insert a node?

查看:215
本文介绍了使用ARAnchor插入节点和直接插入节点之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在ARKit中,我发现了2种在hitTest之后插入节点的方法

In ARKit, I have found 2 ways of inserting a node after the hitTest

  1. 插入ARAnchor,然后在renderer中创建节点(_ renderer:SCNSceneRenderer,nodeFor锚:ARAnchor)-> SCNNode?

let anchor = ARAnchor(transform:hit.worldTransform)
sceneView.session.add(anchor:anchor)

  • 直接插入节点

  • Insert the node directly

    node.position = SCNVector3(hit.worldTransform.columns.3.x, hit.worldTransform.columns.3.y, hit.worldTransform.columns.3.z)
    sceneView.scene.rootNode.addChildNode(node)
    

  • 两种方法都对我有用,但是为什么要用另一种方法呢?

    Both look to work for me, but why one way or the other?

    推荐答案

    更新:从iOS 11.3(又名"ARKit 1.5")开始,之间存在差异ARAnchor添加到会话中(然后通过ARSCNViewDelegate回调将SceneKit内容与会话相关联),然后将内容放置在SceneKit空间中.

    Update: As of iOS 11.3 (aka "ARKit 1.5"), there is a difference between adding an ARAnchor to the session (and then associating SceneKit content with it through ARSCNViewDelegate callbacks) and just placing content in SceneKit space.

    在会话中添加锚点时,是在告诉ARKit世界空间中的某个点与您的应用有关.然后,ARKit可以做一些额外的工作,以确保其世界协调的空间与现实世界准确地对齐,至少在该点附近.

    When you add an anchor to the session, you're telling ARKit that a certain point in world space is relevant to your app. ARKit can then do some extra work to make sure that its world coordinate space lines up accurately with the real world, at least in the vicinity of that point.

    因此,如果您尝试使虚拟内容附加"到某些现实世界的兴趣点(例如将物体放在桌子或墙壁上),则由于世界跟踪的不准确性,您应该会看到较少的漂移"如果为该对象提供锚点,则与其将其放置在SceneKit空间中相比.而且,如果该对象从一个静态位置移动到另一个静态位置,则需要删除原始锚点,然后在新位置添加一个锚点.

    So, if you're trying to make virtual content appear "attached" to some real-world point of interest, like putting an object on a table or wall, you should see less "drift" due to world-tracking inaccuracy if you give that object an anchor than if you just place it in SceneKit space. And if that object moves from one static position to another, you'll want to remove the original anchor and add one at the new position afterward.

    此外,在iOS 11.3中,您可以选择加入以进行重新本地化" ",该过程可帮助ARKit在会话中断(通过电话,切换应用程序等)后恢复会话.在尝试找出如何将以前的位置映射到现在的位置时,该会话仍然有效,一旦重新定位成功,这可能会导致锚的世界空间位置发生变化.

    Additionally, in iOS 11.3 you can opt in to "relocalization", a process that helps ARKit resume a session after it gets interrupted (by a phone call, switching apps, etc). The session still works while it's trying to figure out how to map where you were before to where you are now, which might result in the world-space positions of anchors changing once relocalization succeeds.

    (另一方面,如果您只是让漂浮在空中的太空入侵者,那么,与世界空间完美匹配并不那么重要,因此,基于锚点的和非锚点的之间不会有太大的区别基于锚的定位.)

    (On the other hand, if you're just making space invaders that float in the air, perfectly matching world space isn't as important, and thus you won't really see much difference between anchor-based and non-anchor-based positioning.)

    在Apple的处理3D交互中,请参阅使用锚来改善虚拟对象周围的跟踪质量"一词.和增强现实中的UI控件文章/示例代码.

    See the bit around "Use anchors to improve tracking quality around virtual objects" in Apple's Handling 3D Interaction and UI Controls in Augmented Reality article / sample code.

    此答案的其余部分在历史上仍与iOS 11.0-11.2.5相关,并解释了一些上下文,因此我将其保留在下面...

    首先考虑使用ARAnchor SceneKit.

    Consider first the use of ARAnchor without SceneKit.

    • 如果使用的是ARSKView,则需要一种方法来引用3D(现实世界)空间中的位置/方向,因为SpriteKit不是3D.您需要ARAnchor来跟踪3D中的位置,以便可以将它们映射到2D中.

    • If you're using ARSKView, you need a way to reference positions / orientations in 3D (real-world) space, because SpriteKit isn't 3D. You need ARAnchor to keep track of positions in 3D so that they can get mapped into 2D.

    如果您要使用Metal(或GL,出于某些奇怪的原因)构建自己的引擎...这不是3D场景描述API,而是GPU编程API,因此它实际上没有世界空间的概念.您可以将ARAnchor用作ARKit的世界空间概念与所构建内容之间的桥梁.

    If you're building your own engine with Metal (or GL, for some strange reason)... that's not a 3D scene description API — it's a GPU programming API — so it doesn't really have a notion of world space. You can use ARAnchor as a bridge between ARKit's notion of world space and whatever you build.

    因此,在某些情况下,您需要ARAnchor,因为这是引用3D位置的唯一明智的方法. (当然,如果您使用的是平面检测,则需要ARPlaneAnchor,因为ARKit会在精确估计平面位置的同时将它们相对于场景空间移动.)

    So in some cases you need ARAnchor because that's the only sensible way to refer to 3D positions. (And of course, if you're using plane detection, you need ARPlaneAnchor because ARKit will actually move those relative to scene space as it refined its estimates of where planes are.)

    使用ARSCNView,SceneKit已经具有3D世界坐标空间,ARKit进行了使该空间与ARKit映射的真实空间匹配的所有工作.因此,给定一个描述世界空间位置(和方向等)的float4x4变换,您可以:

    With ARSCNView, SceneKit already has a 3D world coordinate space, and ARKit does all the work of making that space match up to the real-world space ARKit maps out. So, given a float4x4 transform that describes a position (and orientation, etc) in world space, you can either:

    • 创建一个ARAnchor,将其添加到会话中,并响应ARSCNViewDelegate回调以为每个锚点提供SceneKit内容,ARKit会将其添加到场景中并为您定位.
    • 创建一个SCNNode,设置其simdTransform,并将其添加为场景的rootNode的子级.
    • Create an ARAnchor, add it to the session, and respond to ARSCNViewDelegate callback to provide SceneKit content for each anchor, which ARKit will add to and position in the scene for you.
    • Create an SCNNode, set its simdTransform, and add it as a child of the scene's rootNode.

    只要您正在运行ARSession,两种方法之间就没有什么区别-它们是表达同一件事的等效方法.因此,如果您喜欢使用SceneKit的方式进行操作,则没有任何问题. (如果需要,甚至可以使用SCNVector3SCNMatrix4代替SIMD类型,但是如果还要从ARKit API获取SIMD类型,则必须来回转换.)

    As long as you have a running ARSession, there's no difference between the two approaches — they're equivalent ways to say the same thing. So if you like doing things the SceneKit way, there's nothing wrong with that. (You can even use SCNVector3 and SCNMatrix4 instead of SIMD types if you want, but you'll have to convert back and forth if you're also getting SIMD types from ARKit APIs.)

    这些方法的不同之处是重置会话时.如果世界追踪失败,您将恢复被中断的会话,和/或 如果您重新开始会话,则世界空间"可能不再像在场景中放置内容时那样与现实世界对齐.

    The one time these approaches differ is when the session is reset. If world tracking fails, you resume an interrupted session, and/or you start a session over again, "world space" may no longer line up with the real world in the same way it did when you placed content in the scene.

    在这种情况下,您可以让ARKit从会话中删除锚点-请参见 run(_:options:) 方法和 ARSession.RunOptions . (是的,所有这些,因为此时您不能再信任它们中的任何一个了.)如果您使用锚点和委托回调将内容放置在场景中,则ARKit将对所有内容进行核对. (您将获得被删除的委托回调.)如果使用SceneKit API放置了内容,则内容将保留在场景中(但很可能在错误的位置).

    In this case, you can have ARKit remove anchors from the session — see the run(_:options:) method and ARSession.RunOptions. (Yes, all of them, because at this point you can't trust any of them to be valid anymore.) If you placed content in the scene using anchors and delegate callbacks, ARKit will nuke all the content. (You get delegate callbacks that it's being removed.) If you placed content with SceneKit API, it stays in the scene (but most likely in the wrong place).

    因此,使用哪种取决于您要如何处理会话失败和中断(除此之外,没有真正的区别).

    So, which to use sort of depends on how you want to handle session failures and interruptions (and outside of that there's no real difference).

    这篇关于使用ARAnchor插入节点和直接插入节点之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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