如何保存和加载AR世界地图数据以创建持久的AR体验

保存并加载ARKit世界地图数据,以允许用户返回相同现实环境中的以前的AR体验。

本教程要求您对ARKit有基本的了解。 如果您不熟悉ARKit,建议您阅读 AppCoda RayWenderlich的 这些教程

iOS 12上的ARKit 2.0提供了在会话之间持续提供AR体验并可以在以后恢复的可能性。 用户可以在桌子上启动一个AR拼图,然后以相同的状态稍后再使用它,也可以在几天之内解决室内装饰项目而无需重新开始。

通过在此处下载入门项目开始教程。 入门项目具有预构建的UI元素和操作方法,因此我们可以专注于使用ARKit的世界地图持久性的核心元素。 在Xcode 10的帮助下,在运行iOS 12并支持ARKit的iOS设备上构建并运行下载的入门项目。 应提示您允许在应用程序中访问相机,请点按确定。

一次,允许摄像机访问,ARKit借助特征点映射可见区域,点击屏幕上的任意位置以在该点添加球体节点。

因此,现在我们可以借助UITapGestureRecognizer将3D对象添加到真实表面。 现在,让我们跳到教程的主要部分,以保存世界地图。

什么是ARWorldMap?

ARWorldMap对象包含ARKit用于在现实世界中定位用户设备的所有空间映射信息的快照。 ARWorldMap对象表示物理世界中的映射空间。 我们可以将ARWorldMap对象存档到Data对象中,并将其保存在设备的本地目录中。 如果要加载地图,请进入设备的本地目录,在该目录中保存了世界地图Data对象以将其取消存档。

您可能已经在入门项目中注意到,直到完全映射可见区域后,才启用保存按钮。 ARKit提供了一个worldMappingStatus值,该值指示当前是否是捕获世界地图的好时机(或者最好等到ARKit绘制更多的本地环境时再捕获)。 我们使用worldMappingStatus提供视觉反馈,并选择何时使saveButton可用。

首先,我们首先声明一个URL类型的变量,该变量为我们提供了用于写入和读取世界地图数据的文档目录路径。 将属性添加到ViewController类:

现在,将以下代码复制到func saveButtonAction(_ sender: Any)方法中。 这样您的方法看起来像这样:

因此,基本上,当我们点击saveButton ,将调用getCurrentWorldMap(completionHandler:)从正在运行的ARSession捕获地图,然后使用NSKeyedArchiver将其序列化为Data对象并将其写入本地存储。 我们使用.atomic选项进行写入,因为这样可以保证文件是否完全写入您的设备。

现在,将以下代码复制到func loadButtonAction(_ sender: Any)方法中,使其看起来像这样:

在这里,我们检查本地存储中是否存在世界地图文件,如果该文件存在并且可以反序列化为ARWorldMap对象,那么我们告诉ARWorldTrackingConfiguration通过使用该地图创建并运行ARWorldTrackingConfiguration来尝试恢复在该世界地图中捕获的会话。作为initialWorldMap 。 然后,ARKit尝试重新定位到新的世界地图-也就是说,将接收到的空间映射信息与它对本地环境的感知进行协调。 如果用户移至他们在上一个会话期间访问过的本地环境区域,则此过程更有可能成功。

现在让我们尝试测试我们构建的应用程序。 在设备上构建并运行该应用程序,然后在绘制区域后,在现实世界中添加一些3D球体,然后点击“ Save按钮以Save地图。 收到“地图已保存”警报后,请点击“ Reset按钮以还原AR世界地图,或者也可以通过从应用程序抽屉中关闭该应用程序来完成。 如果您完全关闭了该应用程序,请重新启动该应用程序,然后点击“ Load ,然后移至保存该应用程序的同一区域。 一旦该区域被完全映射,保存的世界地图就会成功加载到场景视图中。

您可以在此处获得完成的项目。 如果您想深入了解ARKit的持久性,请确保从Apple中签出示例代码。


本文由我们的一位iOS开发人员Ananth Bhamidipati撰写。 要了解有关黄色球衣的更多信息,请查看我们的网站和Instagram。 我们希望您喜欢本教程。 如果您喜欢本教程,请随时在您的社交网络中分享。