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

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

问题描述

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

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

  1. 插入一个 ARAnchor 然后在 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 的 Handling 3D Interaction 中有关使用锚点提高虚拟对象跟踪质量"的相关内容和增强现实中的 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 获取 SIMD 类型,则必须来回转换API.)

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