Tag: arkit

ARKit和CoreLocation:第一部分

使用线性代数(和Trig)导航 示范代码 ARKit和CoreLocation:第一部分 ARKit和CoreLocation:第二部分 ARKit和CoreLocation:第三部分 背景 自从我写了一篇新的博客文章以来已经有一段时间了,所以希望能弥补这一点。 这篇文章和下一篇文章将是我对ARKit和CoreLocation进行实验的两部分系列! 第一部分将介绍ARKit的基础知识,MapKit的指导以及矩阵转换的基础知识。 第二部分将处理计算两个位置之间的方位,以及如何获取位置数据并将其转换为ARKit场景中的位置。 介绍 提到“增强现实”,最先引起人们注意的是PokemonGO。 如果您像大多数人一样,可能曾经玩过一两次(或痴迷过)。PokemonGO证明了在设置方面,没有什么能比我们的世界更好。 就像PokemonGO一样令人敬畏,这只是对增强现实体验的深度和潜力的一瞥。 苹果文档 : 增强现实 (AR)描述了用户体验,这些体验将2D或3D元素添加到设备相机的实时视图中,从而使这些元素看起来像是居住在现实世界中。 ARKit结合了设备运动跟踪,相机场景捕获,高级场景处理和显示便利性,以简化构建AR体验的任务。 借助iOS 11,Apple已将ARKit的功能释放给iOS开发社区。 我们距离iOS 11尚有几周的上线时间,但我们已经看到的情况似乎可能会重新定义移动用户体验的可能性。 首先,一些基本原理 所以,这是魔术吧? 我不想成为这样说的人,但是不,这只是数学。 因此,如果这不是魔术,那么他们如何实现呢? 视觉惯性里程表! (快说十遍。) 定义 视觉惯性里程表(VIO) :ARKit会分析手机摄像头和运动数据,以便跟踪其周围的环境。 计算机视觉记录了环境中的显着特征,并且无论iPhone的移动如何,都能够保持其在现实世界中位置的意识。 苹果公司非常热衷于围绕会话组织代码。 会议是一个 封装包含在应用程序活动的定义时间段内的逻辑和数据的方法。 使用URLSession时,这是您的应用程序发送网络请求并回传数据时的逻辑和数据。 ARSession :在ARKit中, ARSession协调创建增强现实体验所需的逻辑和数据。 这包括相机和运动数据以及跟踪世界时所需的计算。 ARFrame : ARFrame包含视频帧数据和位置跟踪数据,这些数据会在currentFrame属性中传递给ARSession。 ARKit将该图像数据与运动跟踪数据结合起来,以计算iPhone的位置。 ARAncho r : ARAnchor是现实世界中保持的位置,无论摄像机的运动或位置(理论上)如何。 它固定在一个特定的位置,并且大部分将保留在那里。 AR配置 ARWorldTrackingConfiguration :是用于跟踪设备方向,位置并检测特征点(如相机记录的表面)的配置。 ARConfigurations将您和手机所处的物理世界与手机根据摄像头和运动数据生成的虚拟坐标空间进行连接。 worldAlignment: […]

iPhone X:使用脸部追踪功能不止使用Animojis

高级设计技术人员Virakri Jinangkul 今天发布的iPhone X正式为我们的个人设备带来了基于面部的增强现实。 AR已经展示了个人和业务用例,以证明其价值,从教育演示到购买前的产品内部预览。 在公司可以为其移动用户提供什么方面,面部控制将增强现实提升到一个新的水平。 苹果公司以有趣的​​头向我们介绍了基于面部的AR,展示了3D角色复制的面部动作。 虽然Animoji本身可能不是该技术最有用的应用程序,但它有效地展示了Apple的面部跟踪可以在我们的肌肉运动中识别出的细节水平,这可以通过简单的表情变化打开并控制其他应用内命令。 但是比Animoji和游戏更“严肃”的使用呢? 从视频中可以看到,“ Eat It!”的原型使您可以通过转动头来左右移动,并通过张开和合上嘴来向前捕捉食物特征。 这款游戏是作为概念证明而创建的,旨在展示任何数量的面部动作如何与我们选择的任何功能相关联。 随着对应用程序可访问性的需求不断增长,基于面部的AR的未来用例层出不穷。 从导航和安全性,到在连接的设备之间开发基于面部的命令,现在都可以在不触摸屏幕的情况下实现。

ARKit基础知识—世界跟踪和定位101🗺

在本教程中,我们从头开始设置一个基本的ARKit应用程序,并了解ARKit应用程序中包含的组件。 具体来说,我们将专注于世界跟踪和定位。 定位🎯 关于定位的第一件事是节点的位置始终相对于父节点。 为了定义节点的位置,我们使用SCNVector3。 SCNVector3是3D向量。 在我们的SCNVector3节点中,有三个参数分别代表我们的x,y和z轴。 node.position = SCNVector3(0,0,0) 您可以通过将节点设为场景根节点的子节点来将其放置在场景视图中。 根节点是一个节点,没有形状,大小或颜色。 sceneView.scene.rootNode.addChildNode(节点) 如果我们运行我们的应用程序并触摸“添加”按钮,我们会发现我们的盒子直接添加到了我们的世界原点。 现在只剩下这些,直到下一次。 #TFH✌🏾

iOS 11来了

开始准备iOS 11的最佳时间是在6月的WWDC,当时苹果宣布了它,第二好的时间是现在。 根据最近几年的iPhone和iOS版本,我们预计将在9月的第一周或第二周举行活动,届时将发布新的iPhone型号,以及最终版本的iOS 11供开发人员使用。 预计新手机将在活动后的下一个星期五开始发货,并且绝大多数iOS用户将在此之后开始更新到iOS 11。 开发人员已经发布了多个beta版本,我们现在确信最新版本与下个月将向客户的iPhone和iPad设备发布的版本非常相似。 发布后的短短几天内,您可能会发现与其他任何iOS版本相比,iOS 11上的客户数量更多。 在撰写本文时,将近90%的活动iOS设备都在运行iOS 10,而几乎所有其余设备都在运行iOS9。这通常很容易吸引任何用户,并致力于开发以使您的应用程序在旧版本上运行,但我们的经验表明,与仅支持最新版本相比,这通常需要付出更多的努力,并且显然为更少的客户提供服务。 通过确保您的应用已为iOS 11做好准备,您的客户可以放心升级,因为您知道您的应用仍然可以为他们服务,因此您和您的客户可以享受iOS 11提供的所有安全增强功能和新功能。 如何为iOS 11做准备 为iOS 11做好准备的最好方法是为iOS 10做准备。如果您一直在维护应用程序并定期在新的OS版本上进行测试,那么继续使用iOS 11所需的工作可能很少。 Xcode 9中的11 SDK,您可以期望它可以正常工作。 但是,如果您没有及时了解最新信息,则需要注意一些事项。 不再支持32位 iOS 11是不支持32位架构的iOS的第一个版本。 这意味着旧版32位设备(iPhone 5 / iPad 4th Gen及更早版本)上没有iOS 11,也意味着iOS 11上没有32位应用程序。自2015年以来,Apple要求64位支持才能提交到App Store,并且应用程序能够在单个构建中同时支持两种体系结构,但是如果您一直坚持进行更新,那么您的时间就用光了。 在许多情况下,为64位体系结构构建应用程序可能就像更改构建配置一样简单,但是如果您的应用程序是使用第三方框架和库构建的,那么您也需要这些版本的64位版本。 对于大多数流行的库来说,这应该不是问题,但是如果您依赖于特定的版本,或者如果库的开发人员不在了,那么您将可以做。 视觉变化 iOS 11带来了一些视觉上的变化,使iOS变得更清晰,更受欢迎。 更大,更重的字体功能贯穿始终,最明显的是屏幕标题。 尖锐的边缘和轮廓为圆角和填充提供了空间,并且在许多地方甚至还提供了“ buttony”按钮的替换,取代了iOS 7的浮动文本链接。 卡界面出现在更多默认应用程序中,它们的圆角边缘,略带弹性的动画和足够的阴影都可以让您清楚地知道它们在空间上的位置以及何时可以滑动和拖动它们。 尽管自iOS 7以来,iOS的视觉语言并未发生太大变化,但自那时以来的逐步改进使iOS 11感觉像一个截然不同的操作系统。 如果您尚未保持应用程序界面的最新状态,那么在您的客户经常使用的系统应用程序旁边可能会感觉不合适。 用户可以快速学习最新的OS约定,并期望他们在所有应用程序中提供的功能–如果您不了解最新信息,则应用程序很快就会显得陈旧破旧。 为新设备做准备 通常的供应链泄漏,猜测和HomePod固件意外发布的“今年新动向”,意味着我们对iOS 11发行后出现的一些硬件变化有了很好的了解。 新的屏幕尺寸肯定会出现,但是如果您一直在使用自动布局,并且已经支持多种屏幕尺寸和方向,那么您的应用在新尺寸上看起来会很好。 […]

ARKit 2简介-世界地图

按照系列,第二部分介绍ARKit 2中的World Mapping 。系列的其余部分如下: 影像追踪 世界地图 物体扫描 视觉整合(即将推出) 金属和反射性表面(即将推出) World Mapping是ARKit 2中一个了不起的新功能,它允许用户在以前的AR体验中保存的环境中进行保存和加载。 例如,您可以在后院的桌子周围移动,捕获尽可能多的东西,然后在桌子中间放一碗水果。 当天晚些时候,您可以将应用重新打开到同一张桌子。 该应用程序会自动检测到您之前保存的同一张桌子,然后重新加载之前的场景-在这种情况下,桌子上放着一碗水果。 物理3D映射 使用ARKit 2,您的应用程序将基本上能够以3D映射您的物理空间。 通过移动对象(如上表),您将为您的应用提供相同物理环境的多个视角。 这些观点通常称为锚点。 特征点 使用世界地图,您的设备还将扫描许多特征点,这些特征点将再次用于识别空间。 这些特征可以驻留在平面,拐角,点上,或者仅驻留在唯一的感兴趣的随机区域上。 分享经验 ARKit中的世界地图允许您与另一台设备共享地图,例如另一台具有ARKit 2(iOS 12或更高版本)的iPad或iPhone。 这样,您就可以进行实时交互并体验相同的事物,然后再次返回。 您还可以建立网络体验,并在诸如游戏之类的事物上同时互动。 Apple演示的一个示例(是开源的)是SwiftShot。 你可以在这里下载。 持久的AR体验 这样,您可以在关闭应用程序之前保存世界地图,然后在下次打开应用程序时将其加载。 如果在与保存时相同的物理空间中打开,则虚拟体验将继续。 一个示例用例是在墙上或桌子上加载并保存一个木板,该木板上有您需要记住的东西列表(非常乏味的示例,但无论如何)。 每次您在办公桌附近或与该板子在同一位置打开该应用程序时,它都会像从未离开过一样重新加载。 实例化和使用世界地图所需的主要方法是getCurrentWorldMap(completionHandler:) 。 这使您可以保存会话的世界地图。 然后,可以将其分配给配置的initialWorldMap属性,并使用run(_:options:)启动具有相同锚点和物理世界地图的另一个会话。 从会话对象中检索世界地图 会议。 getCurrentWorldMap {worldMap,错误 守卫 let worldMap = worldMap else { showAlert(错误) 返回 } return […]

远程托管3D模型

我们正在为家具制造商开发增强现实应用程序。 您可以将家具虚拟地放置在想要布置的空间中,这样一来,您就可以准确地看到其实际外观。 基本要求是: 检测平坦的表面(通常是地板)以放置3D模型; 尽可能逼真的渲染模型; 更改模型的大小(如果存在不同的大小); 更改放置的模型上的纹理。 除此之外,我们还需要支持大量的模型和纹理。 需要随时添加或更改它们,而无需发布该应用程序的新版本或扩大应用程序的大小。 那就是我们面临的挑战-这就是我们的经验。 在开始尝试ARKit时,我们将模型保存在.scnassets中。 我们研究了模型应包含的内容,如何对齐它们,应用哪些照明模型等。这是测试模型更改的不错选择。 然后我们意识到这不是我们应用程序的解决方案。 缺点是应用程序具有所有模型和纹理的大小。 同样,在不发布新版本应用程序的情况下,无法添加,更改或删除模型。 下一步是找到一种解决方案,将资产保留在其他位置,并在需要时提取它们。 经过研究,我们发现了Apple On-Demand Resources。 对于我们的案例,这似乎是一个很好的解决方案。 按需资源是Apple提供的即用型解决方案。 它将资产与应用程序分离,并在需要时提取它们。 资产与应用程序一起上传到App Store,但在安装应用程序时未下载到设备。 而是,应用程序在必要时下载它们。 那解决了我们的第一个问题:在App Store上应用程序的大小。 因此,我们实施了此解决方案,并遵循了Apple文档。 通过将“启用按需资源”的“构建设置”更改为“是”,我们在项目中启用了按需资源。下一步是为资产分配标签。 标签是远程服务器上一组资产的密钥,这些资产一起下载。 这意味着,当我们从应用程序请求带有特定标签的资产时,我们将下载带有该标签的所有资产,而不是一个一个地下载。 可以为一个资源分配一个标签,但是Apple不推荐这样做。 有两种添加标签的方法: 在资源标签中添加资产 将标签写入资产的标签属性中。 带有标签的资产将部署到App Store。 如果应用程序不是通过App Store分发的,则可以将其存储在自己的Web服务器上。 当我们在应用程序中请求资产时,它会检查它们是否已在设备上。 如果没有,它将下载它们。 这样可以防止重复,节省内存空间和网络使用率。 当用户在移动网络上时,这特别有用。 我们的问题是无法确定资产将永久保存在您的设备上。 应用关闭后,它们可能随时消失,我们需要通过多次运行来保存它们。 可以对保留进行优先级排序,并告诉系统哪些资源在保留中具有更高的优先级。 但这仍然不是解决方案。 此外,上载新资源的唯一方法是发布新版本以及新资产。 比我们需要找出新的解决方案而忘记Apple On-demand资源。 最后,我们同意我们需要自己的定制解决方案来解决所有现有问题。 我们不想为此构建整个后端。 相反,我们使用Firebase Realtime数据库和存储。 它可以是任何存储或任何类似JSON的数据库,但我们决定使用Firebase。 […]

ARKit飞机,3D文本和命中检测

在本系列的第2部分中,我们通过提供一些交互性并更加熟悉SceneKit来构建我们的AR场景。 我们还查看了渲染相机,并使用它的位置(即用户在现实世界中的位置)在我们的球体对象中驱动动画。 在本文中,我们将开始检测水平面,并将对象附加到这些平面上。 可以在以下位置找到本教程的代码:https://github.com/AbovegroundDan/ARTutorial_Part3 检测飞机 ARKit通过didAdd / didUpdate / didRemove节点回调提供了完整的生命周期回调,以用于何时检测到平面,何时更新平面以及何时移除平面。 需要注意的一件事是,当首次检测到飞机时,它似乎跳了一点。 这是ARKit改进其所见所见的准确性,并调整锚点。 如果继续扫描地板,将继续看到特征点,但是平面不会增长或以任何方式变化以填充新发现的空间。 这是因为我们没有响应来自渲染器的didUpdate调用。 我们可以通过跟踪锚点和属于它们的平面来改善实现。 如果收到didUpdate回调,我们将查找锚点,找到飞机,并使用该锚点的新信息调整飞机。 跟踪飞机 为了跟踪飞机,我们将使用一个简单的字典将锚点映射到飞机。 这为我们提供了一种查找和修改相应平面的简便方法。 在我们的视图控制器中,我们将添加字典定义: 现在我们知道了曲面的位置,我们可以开始添加锚定到其上的项目。 而不是像第1部分和第2部分中那样使用外部3D模型,我们将使用一些3D文本。 让我们开始创建一个给定任意文本的方法,该方法将为我们提供一个具有3D文本几何形状的SCNNode。 接下来,我们将添加一个方法来将此父节点添加到另一个节点。 文字看起来不错,但是是浮动的。 这是因为文本容器的枢轴点位于实际文本所在位置的左下角。 枢轴点描述了对象的原点。 如果旋转对象,则将旋转点用作旋转对象时的中心点。 如果按比例缩放,也将从该点开始。 这可以用来创建一些有趣的效果。 现在,让我们尝试“接地”文本对象,以使它看起来像是坐在飞机上,而不是漂浮在飞机上。 在我们的createTextNode方法中,就在我们返回节点之前,添加以下代码: 现在运行代码将为我们提供假定位置的文本。 我们可以看到我们的文字在那儿投射了一些阴影,但是由于透明的网格,我们看不到它的阴影。 我们可以在SceneKit中做一些技巧来使阴影更好地显示。 我们将在此处使用这些技巧之一,并创建一个不会渲染的平面,但它将接受从其他对象投射的阴影。 在2017年WWDC SceneKit:新增功能(https://developer.apple.com/videos/play/wwdc2017/604/)会话中对此技术进行了说明。 让我们转到定向光定义并向其中添加以下几行: 仅此而已。 如果您在该GIF中注意到,我们将分散文本。 为此,让我们看一下将文本放置在我们点击的位置,而不是平面锚点的当前位置。 为此,我们将一个新参数传递给addText调用,并带有我们希望对象所在的位置。 我们将从SCNHitTestResult对象获得此位置,该对象从我们的点击命中测试返回。 修改didTapScreen调用以获取水龙头的位置,并将该信息传递给addText调用: 现在就这样。 收到了您接下来要看的内容的请求? 让我们在评论中知道! 不要忘记关注s23NYC:工程博客,其中发布了耐克的数字创新团队的很多精彩内容。 AbovegroundDan / ARTutorial_Part3 通过在GitHub上创建一个帐户来为AbovegroundDan / ARTutorial_Part3开发做出贡献。 […]

ARKit,SceneKit和如何控制世界

在本系列的第1部分中,我们经历了一个工作流程,在该工作流程中,我们处理了3D模型,使用Xcode创建了AR项目,开始了AR会话并将模型放入了增强场景。 在本文中,我们将开始使用各种SceneKit方法将模型付诸实践,并开始与我们世界中的对象进行交互。 可以在https://github.com/AbovegroundDan/ARTutorial_Part2上找到此文章的项目。 SceneKit提供了一组可应用于节点的操作。 这些动作可用于设置运动,旋转,缩放和其他节点属性的动画。 可以将它们分组以同时运行,按顺序依次运行,然后重复或颠倒。 完整列表可以在https://developer.apple.com/documentation/scenekit/scnaction中找到 我们将继续修改当前项目,并开始向我们的对象添加一些操作。 让我们从向球体添加旋转开始。 在HoverScene中的addSphere方法之后,添加以下方法: 让我们在球体上添加一些麻烦。 让我们也将其上下浮动。 我们将添加一个悬停动作,一个悬停动作,对这两个动作进行排序,然后将它们与我们现有的旋转动作组合在一起。 这是addAnimation方法的外观: 让我们为场景添加一些交互性。 让我们设定一个目标来开始场景,方法是让用户将球体放置在世界上,然后点按以激活它们。 由于我们的代码变得更加复杂,是时候开始抽象化处理场景对象的方式了。 在我们的项目中创建一个名为“对象”的新组。 在此文件夹中,我们将创建一个新的Swift文件,名为SceneObject.swift。 我们将创建一个派生自SCNNode的基类SceneObject。 我们一直在使用SceneKit做很多事情,但是仅了解ARKit可以做的一些事情。 作为快速了解更多ARKit功能的先导,让我们通过使球体“注视”相机为场景增添一点乐趣。 我们已经钩住了渲染器的updateAtTime方法,并且那里也有对相机的引用。 因此,让我们开始向Sphere类添加一个方法,以使其朝着特定方向发展。 球的“眼睛”已经面向负Z,这是对象的向前方向。 我们要做的是创建一个方法,该方法采用一个向量来标记我们的“眼睛”将要面对的空间中的一点。 请继续关注以获取更多ARKit乐趣! AbovegroundDan / ARTutorial_Part2 通过在GitHub上创建一个帐户来为ARTutorial_Part2开发做出贡献。 github.com

在SceneKit中更新SCNMaterial纹理

在iOS12和ARKit 2的最新发行版中,Fueled决定开发一款名为Toppler的多设备AR游戏,以探索其某些功能。 在构建这种AR体验时,我们需要向用户提供有关将要选择和抓取哪个块的反馈。 我们最终决定对材料纹理进行运行时更新是必须的。 但是,这样做时,我们遇到了在构建SceneKit游戏时其他人也可能遇到的问题。 交换纹理 我们有两个要用作纹理的不同图像,具体取决于块状态: 我将跳过UV贴图,该贴图负责在块上展开纹理,但是如果您想在此处获得更多详细信息,我之前已经写过有关如何将3D模型从Blender导出到SceneKit的信息。 我决定通过根据材料状态提供条件源来处理此问题。 以下是该TopplerBlockMaterial类的简化版本,该类是SCNMaterial子类,负责处理块的可视状态: 事实证明,底层流程花费了将近22%的允许时间来渲染框架和创建图像材料。 CoreGraphics需要在将UIImage应用于材质之前在新的缓冲区中重绘UIImage ,这被证明是非常耗时的。 我们绝对必须寻找其他地方来更新纹理,而又不影响游戏和AR体验,而这需要恒定的帧频。 偏移纹理 花了几个小时在文档中寻找解决方案之后,我终于在SCNMaterialProperty上发现了一个有趣的实例属性   : contentsTransform 。 事实证明,这正是我们所需要的。 这将允许我们创建一个包含两个不同状态的图像文件,然后我们可以偏移contentsTransform以仅显示纹理的所需部分。 这是新的纹理图像,红色矩形说明了可以用作contentsTransform的变换: 因此,我们需要使用两种不同的转换组合,一种用于普通,另一种用于突出显示状态。 这是使用此方法的更新后的TopplerBlockMaterial类: 我们遇到的这种阻止程序是一长串列表的一部分,当从UIKit发出来时,通常不会有人碰到它 。 交换UIImageView的UIImage是一个非常简单的过程,不应引入性能问题。 但是在使用3D环境和SceneKit时 ,我们会遇到一些使用UIKit时通常不会遇到的意外的性能考虑。 希望本文也能对其他人有所帮助。

着色器的ARKit + SceneKit简介

之前我谈到过如何在SceneKit中创建自己的自定义几何,结果您可以使用它们进行某些操作,例如偏斜或动画。 请参阅此处的第2部分的第1部分: ARKit + SceneKit几何图形教程(第1部分) 在SceneKit中创建自己的几何形状,无需离开即可拥有各种场景和动画。 medium.com 在该系列的第二篇文章的结尾处,我展示了如何使用看起来像字符串的标志来设置标志的动画,这是在SceneKit中向几何体或材质添加着色器的一种方法。 在许多情况下,比起我所展示的其他示例,诸如我上一篇文章底部所示的着色器是使几何图形动画化的更好选择。 主要原因是这些功能由SceneKit接受,编译为Metal,然后在设备的GPU上运行,该GPU比要在其他地方运行的CPU强大得多。 这主要是因为GPU是专门为处理图形而构建的(因此,其名称为Gphphics Processing U nit),所以我们希望尽可能多地使用它! 我想在本文中提到的应用着色器的方法主要是通过使用SCNGeometry对象的shaderModifiers属性。 首先,请看这里: SCNShadable – SceneKit | Apple开发人员文档 着色器修改器是Metal着色器语言或OpenGL着色器语言(GLSL)中的源代码片段,可用于… developer.apple.com 作为一个简单的示例,请看以下小片段: 如果(_geometry.position.y> 0){ _geometry.position.x + = 0.5; } 假设我们将其应用于尺寸为SCNBox类型的几何。 _geometry代表顶点,正如我之前的文章中所述,其位置当然是其在3D空间[x, y, z] 。 在此代码段中,我们获取位置在立方体中心上方的所有顶点,并将其向x方向正方向的侧面推0.5m。 我们可以迅速使它变得更有趣,而无需考虑太多,例如: 如果(_geometry.position.y> 0){ _geometry.position.x + = 0.5 * sin(u_time); } u_time是SceneKit开始渲染此着色器以来的时间(以秒为单位)。 因此,这将在正弦缓和之后以平滑的方式将立方体的局部x轴上+0.5的这4个点动画化为-0.5。 最后,我将演示的多维数据集示例是使用单位圆方程将前四个点从沿直线移动更改为沿圆移动。 单击此处以查看Desmos的快速图表,以防万一您不确定该如何组合。 如果(_geometry.position.y> 0.0){ _geometry.position.xz + […]