使用ARAnchor插入节点和直接插入节点有什么区别?

2023-12-23

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

  1. 插入 ARAnchor 然后在中创建节点renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? https://developer.apple.com/documentation/arkit/arscnviewdelegate/2865801-renderer

     let anchor = ARAnchor(transform:hit.worldTransform)
     sceneView.session.add(anchor:anchor)
    
  2. 直接插入节点

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

两者看起来都适合我,但为什么要采用其中一种呢?


Update:从 iOS 11.3(又名“ARKit 1.5”)开始,is添加之间的区别ARAnchor到会话(然后通过将 SceneKit 内容与其关联ARSCNViewDelegate回调)并将内容放置在 SceneKit 空间中。

当您向会话添加锚点时,您是在告诉 ARKit 世界空间中的某个点与您的应用程序相关。然后,ARKit 可以做一些额外的工作,以确保其世界坐标空间与现实世界准确对齐,至少在该点附近。

因此,如果您试图使虚拟内容看起来“附加”到某些现实世界的兴趣点,例如将物体放在桌子或墙上,那么您应该会看到由于世界跟踪不准确而导致的“漂移”较少,如果您给出该对象是一个锚点,而不是将其放置在 SceneKit 空间中。如果该对象从一个静态位置移动到另一个静态位置,您将需要删除原始锚点并随后在新位置添加一个锚点。

此外,在 iOS 11.3 中,您可以opt in https://developer.apple.com/documentation/arkit/arsessionobserver/2941046-sessionshouldattemptrelocalizati到“重新定位”,这是一个帮助 ARKit 在会话中断(通过电话、切换应用程序等)后恢复会话的过程。该会话在尝试找出如何将您之前所在的位置映射到现在所在的位置时仍然有效,这可能会导致一旦重新定位成功,锚点的世界空间位置就会发生变化。

(另一方面,如果你只是制作漂浮在空中的太空入侵者,那么完美匹配的世界空间并不那么重要,因此你不会真正看到基于锚点和非基于锚点之间的太大区别定位。)

请参阅 Apple 中有关“使用锚点提高虚拟对象周围的跟踪质量”的部分处理增强现实中的 3D 交互和 UI 控件 https://developer.apple.com/documentation/arkit/handling_3d_interaction_and_ui_controls_in_augmented_reality文章/示例代码。

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


首先考虑使用ARAnchor without场景套件。

  • 如果您正在使用ARSKView,您需要一种方法来参考 3D(真实世界)空间中的位置/方向,因为 SpriteKit 不是 3D。你需要ARAnchor跟踪 3D 中的位置,以便将它们映射到 2D 中。

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

所以在某些情况下你需要ARAnchor因为这是引用 3D 位置的唯一合理方式。 (当然,如果你使用平面检测,你需要ARPlaneAnchor因为 ARKit 实际上会相对于场景空间移动那些,因为它改进了对飞机位置的估计。)


With ARSCNView,SceneKit 已经有了一个 3D 世界坐标空间,ARKit 完成了使该空间与 ARKit 映射的真实世界空间相匹配的所有工作。所以,给定一个float4x4描述世界空间中的位置(和方向等)的变换,您可以:

  • 创建一个ARAnchor,将其添加到会话中,并响应ARSCNViewDelegate回调为每个锚点提供 SceneKit 内容,ARKit 将为您添加到场景中并在场景中定位。
  • 创建一个SCNNode,设置其simdTransform,并将其添加为场景的子级rootNode.

只要你有跑步的习惯ARSession,这两种方法之间没有区别——它们是表达同一件事的等效方式。因此,如果您喜欢以 SceneKit 方式做事,那没有什么问题。 (你甚至可以使用SCNVector3 and SCNMatrix4如果需要,可以使用 SIMD 类型来代替 SIMD 类型,但如果您还从 ARKit API 获取 SIMD 类型,则必须来回转换。)


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

在这种情况下,您可以让 ARKit 从会话中删除锚点 - 请参阅run(_:options:) https://developer.apple.com/documentation/arkit/arsession/2875735-run方法和ARSession.RunOptions https://developer.apple.com/documentation/arkit/arsession.runoptions。 (是的,所有这些,因为此时您不能相信它们中的任何一个都有效。)如果您使用锚点和委托回调将内容放置在场景中,ARKit 将删除所有内容。 (您会收到正在删除的委托回调。)如果您使用 SceneKit API 放置内容,它会保留在场景中(但很可能位于错误的位置)。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用ARAnchor插入节点和直接插入节点有什么区别? 的相关文章

随机推荐

  • 用于状态处理的多态枚举

    在 C 中 如何在不使用 switch 或 if 语句的情况下处理枚举 例如 enum Pricemethod Max Min Average 我有一篇类文章 public class Article private List
  • 如何从 FluentNHibernate 生成 hbm.xml 文件

    我正在尝试遵循这个tutorial http www dotnetguy co uk post 2009 10 19 using fluent Nhibernate to Export Create hbm files Nhibernate
  • GCC 3.4.6 中与模板函数相关的错误

    今天我在办公室遇到了一个奇怪的编译错误 我怀疑它是我们的 GCC 版本 3 4 6 中的一个错误 我已经能够将其归结为几行代码 如下 我得到的编译错误是 test cpp 26 error expected primary expressi
  • 如何在Python中解析data-uri?

    HTML 图像元素有this http www w3schools com tags tag img asp简化格式 img src something 那东西可以是data uri https www rfc editor org rfc
  • 修改Android的seekbar小部件以垂直操作

    我正在尝试让模拟器使用垂直搜索栏 但我 有点卡住了 我可以让搜索栏按照我想要的方式显示 我可以获得做我想做的事情的进度 并且我可以修改 onTouchEvent 让拇指垂直移动而不是 水平地 我不能做的就是让拇指移到外面 默认 29 水平像
  • 确定时间是否在两个时间之间,无论日期如何

    我创建了一个自定义TimePicker我对 Android Wear 表盘的偏好 用户选择一个时间 它会返回当前时间 以毫秒为单位 代码可以在我的GitHub 仓库 https github com Nxt3 IO Classic Watc
  • 自定义 Jersey 错误处理,如何在客户端捕获响应?

    我正在我的网络服务上尝试一些自定义错误处理 在我的 web 服务中 我创建了一个扩展 WebApplicationException 的自定义异常类 如中所述JAX RS Jersey如何自定义错误处理 https stackoverflo
  • 更新 Python3 pip AttributeError 时出错:模块“lib”没有属性“OpenSSL_add_all_algorithms”

    我在 python3 中安装 更新任何 pip 模块时遇到错误 清除并重新安装pip我能想到的每一个包裹都没有帮助 这是我响应运行时收到的错误python m pip install upgrade pip具体来说 但尝试安装或更新任何 p
  • .NET 的顶级缓存库

    您认为哪些缓存库对 NET 最重要或最有用 我这么问是因为我需要联系他们以了解他们计划支持 NET 4 0 的缓存框架 应用架构 http msdn microsoft com en us windowsserver ee695849 as
  • while 循环读取文件提前结束

    最终目标是让我的 bash 脚本在多个服务器上执行命令 我差不多已经设置好了 我的 SSH 身份验证工作正常 但是这个简单的 while 循环快要我的命了 当我执行 while 循环 读取文件中的主机名时 当我运行 ssh HOST una
  • 在 mac osx 中反汇编 g++ 创建的可执行文件

    如何在 Mac OSx 上查看 C 程序的可执行文件 例如 a out 的反汇编版本 这不完全是你所要求的 但是g S从源代码生成汇编 预计比反汇编版本更具可读性 如果你不能重新编译 S 例如没有源代码 那么gdb让你可以拆卸 就像objd
  • dart - 使用空安全时订阅的正确编码模式?

    我已经启用了 dart 2 8 实验性空安全性 我有以下退出代码 StreamSubscription
  • 增强 python 链接

    我正在为我的游戏添加 boost python 我为我的类编写包装器以在脚本中使用它们 问题在于将该库链接到我的应用程序 我在用着cmake构建系统 现在我有一个简单的应用程序 包含 1 个文件和 makefile PYTHON usr i
  • 如何在AWS-Glue脚本中编写用户定义函数?

    我们如何在动态框架或数据框架上使用 PySpark Python 在 AWS Glue 脚本中编写用户定义的函数 Dynamicframe 并不像 Dataframe API 支持 UDF 那样完全支持它 您将获得的最好结果是 MAP ap
  • 应用程序如何使用 Android 4+ 的 Google 离线地图?

    Android 版本 4 引入了离线地图 我可以在手机上选择要缓存的区域 然后 Google 地图会将该地图数据下载到手机上 正如我收到的评论 我想使用我的设备上已有的数据 如果用户之前已经下载了离线地图使用 并且不要打开与 Google
  • 如何知道Python中海龟图形上特定文本的像素大小?

    如标题所示 当我执行以下代码时 import turtle turtle write some text 我想知道字符串的整体大小 包括高度和宽度 some text画布上的乌龟图形 我怎样才能做到这一点 字体大小只能告诉你half您需要知
  • 将名字和姓氏标记为一个标记

    是否可以对标记中的文本进行标记 以便将名字和姓氏组合在一个标记中 例如 如果我的文本是 text Barack Obama is the President Then text split 结果是 Barack Obama is the P
  • 未找到隧道错误 Pyngrok Streamlit 协作

    我正在开发一个用户界面streamlit并使用pyngrok来自科拉布 一切都工作正常 直到几天前开始出现隧道未找到错误 我正在使用下面的代码 我也升级了pyngrok并尝试过 但同样的问题仍然存在 对于整个 UI 构建和 Colab 来说
  • 在没有中间过程的情况下,如何在 Python 调试器中查看函数的返回值?

    PDB 和其他 Python 调试器 有一种简单的方法来查看任何当前变量的值 只需输入它即可 但是 有时我使用的库不将其返回值存储在中间变量中 这是一个示例函数 def do stuff args kwds return f args kw
  • 使用ARAnchor插入节点和直接插入节点有什么区别?

    在ARKit中 我发现了两种在hitTest之后插入节点的方法 插入 ARAnchor 然后在中创建节点renderer renderer SCNSceneRenderer nodeFor anchor ARAnchor gt SCNNod