远程托管3D模型

我们正在为家具制造商开发增强现实应用程序。 您可以将家具虚拟地放置在想要布置的空间中,这样一来,您就可以准确地看到其实际外观。

基本要求是:

  • 检测平坦的表面(通常是地板)以放置3D模型;
  • 尽可能逼真的渲染模型;
  • 更改模型的大小(如果存在不同的大小);
  • 更改放置的模型上的纹理。

除此之外,我们还需要支持大量的模型和纹理。 需要随时添加或更改它们,而无需发布该应用程序的新版本或扩大应用程序的大小。 那就是我们面临的挑战-这就是我们的经验。

在开始尝试ARKit时,我们将模型保存在.scnassets中。 我们研究了模型应包含的内容,如何对齐它们,应用哪些照明模型等。这是测试模型更改的不错选择。 然后我们意识到这不是我们应用程序的解决方案。 缺点是应用程序具有所有模型和纹理的大小。 同样,在不发布新版本应用程序的情况下,无法添加,更改或删除模型。 下一步是找到一种解决方案,将资产保留在其他位置,并在需要时提取它们。 经过研究,我们发现了Apple On-Demand Resources。 对于我们的案例,这似乎是一个很好的解决方案。

按需资源是Apple提供的即用型解决方案。 它将资产与应用程序分离,并在需要时提取它们。 资产与应用程序一起上传到App Store,但在安装应用程序时未下载到设备。 而是,应用程序在必要时下载它们。 那解决了我们的第一个问题:在App Store上应用程序的大小。

因此,我们实施了此解决方案,并遵循了Apple文档。 通过将“启用按需资源”的“构建设置”更改为“是”,我们在项目中启用了按需资源。下一步是为资产分配标签。 标签是远程服务器上一组资产的密钥,这些资产一起下载。 这意味着,当我们从应用程序请求带有特定标签的资产时,我们将下载带有该标签的所有资产,而不是一个一个地下载。 可以为一个资源分配一个标签,但是Apple不推荐这样做。 有两种添加标签的方法:

  1. 在资源标签中添加资产
  2. 将标签写入资产的标签属性中。

带有标签的资产将部署到App Store。 如果应用程序不是通过App Store分发的,则可以将其存储在自己的Web服务器上。 当我们在应用程序中请求资产时,它会检查它们是否已在设备上。 如果没有,它将下载它们。 这样可以防止重复,节省内存空间和网络使用率。 当用户在移动网络上时,这特别有用。

我们的问题是无法确定资产将永久保存在您的设备上。 应用关闭后,它们可能随时消失,我们需要通过多次运行来保存它们。 可以对保留进行优先级排序,并告诉系统哪些资源在保留中具有更高的优先级。 但这仍然不是解决方案。 此外,上载新资源的唯一方法是发布新版本以及新资产。 比我们需要找出新的解决方案而忘记Apple On-demand资源。

最后,我们同意我们需要自己的定制解决方案来解决所有现有问题。 我们不想为此构建整个后端。 相反,我们使用Firebase Realtime数据库和存储。 它可以是任何存储或任何类似JSON的数据库,但我们决定使用Firebase。 在最终解决方案中,我们将存储更改为Amazon,但保留了Firebase数据库。

接下来,我们必须定义数据库的结构。 它必须具有所有必要的信息,以及添加,更改或删除模型或纹理的能力。 我们必须考虑到产品具有多种尺寸,多种材料组合。

我们的结构如下:

我们有一系列产品,其中包含每个变体中共有的数据。 该产品包含一系列变体。 它们是不同大小的模型,带有模型URL,尺寸和阴影URL。 同样,该变体具有带有节点名称和纹理的节点列表,可以将其应用于该节点。 纹理具有用于漫反射,金属度,粗糙度和法线以及显示名称的URL。 所有资产均已上载到存储。 要下载的网址会输入到Firebase实时数据库中。 材料是数据库中一个单独的节点。 它具有按类别分类的所有可能材料和缩略图。 我们将其保存在一个单独的节点中,因为我们不想为每个变体多次下载相同的东西并复制数据库中的数据。 我们将版本节点作为材料和产品的父节点。 这条路。 如果结构在应用程序的下一版本中发生更改,则先前的版本不会崩溃。

我们从Firebase SDK开始,以从应用程序中的数据库检索数据。 但这不是我们的选择,因为我们的数据嵌套在许多级别中。 数据快照无法映射到对象。 为了避免嵌套循环,我们创建了Cloud函数,该函数从数据库返回JSON数据。 云函数会检索应用程序的版本作为参数,并返回给定版本的数据库节点。 在Swift 4中,数据通过JSONDecoder直接映射到对象。我们在数据库中定义了与数据结构相对应的类,并继承了Decodable。 另外,如果类属性与数据库中的键不同,则可以定义编码键来匹配它。

实施云功能使我们能够在将数据发送到应用程序之前对其进行处理。

Firebase Realtime数据库是无模式的NoSQL数据库。 这样,可能会丢失键中的字段或错字,并可能导致应用崩溃。 因此,我们将所有值标记为可选值,并在出现错误或缺失时处理情况。

对于缓存,我们使用url哈希名称保留文件。 在下载时,我们检查文件是否已经存在,所以我们没有重复的下载。 资产中的所有内容均已完成。 这样,仅当哈希在数据库中更改时才下载新文件。

如果要构建具有大量资产(例如图像,视频或3D模型)的应用程序,则应将内容远程保存以减小应用程序的大小。 根据资产更改的频率,您可以使用自己的Web服务器或Apple On Demand资源。 选择什么取决于您的需求。 对于我们来说,Firebase拥有我们所需的一切。 那里有很多选择,每个都有各自的优缺点。 您可能需要自定义后端,而不是Firebase或类似的后端。 在实施之前进行研究。 快乐的编码。


最初发布在 www.rubicon-world.com上