在本教程中,您将学习如何:
对于本教程,您需要一部带有前置 TrueDepth 摄像头的 iPhone。在撰写本文时,这意味着 iPhone X,但谁知道未来会带来什么?
您可能已经使用本教程顶部或底部的下载材料链接下载了本教程的材料,并注意到没有启动项目。这不是一个错误。您将从头开始编写这个应用程序 - Emoji Bling!
启动 Xcode 并基于Single View App模板创建一个新项目并将其命名为Emoji Bling。
您应该做的第一件事是给默认值ViewController一个更好的名称。在左侧的 Project navigator 中选择ViewController.swift 。
在标准编辑器中出现的代码中,右键单击类的名称,然后从弹出的上下文菜单中ViewController选择重构 重命名。
将类的名称更改为EmojiBlingViewController并按Return或单击蓝色的重命名按钮。
注意:有时重构过程会忘记重命名ViewController.swift文件。如果发生这种情况,只需在Finder中手动执行此操作,然后再次将文件添加到项目中。
既然您已经在EmojiBlingViewController.swift中闲逛,请继续将以下导入添加到顶部:
导入ARKit毕竟,您是在制作增强现实应用程序,对吧?
接下来,在Main.storyboard中,选择Emoji Bling View Controller中的顶级View,将类更改为ARSCNView。
ARSCNView是使用SceneKit内容显示增强现实体验的特殊视图。它可以显示相机馈送和显示器SCNNode。
将顶层视图更改为 后ARSCNView,您希望为您的类IBOutlet中的视图创建一个。EmojiBlingViewController
为此,请通过单击带有互锁环的按钮来调出助手编辑器。
这应该会自动在助手编辑器中显示EmojiBlingViewController.swift的内容。如果没有,您可以在项目导航器中按住 Option 键单击它以在其中显示它。
现在,从情节提要中按住 Control 并拖动到EmojiBlingViewController.swift中类定义的正下方,并命名为 outlet 。ARSCNView``EmojiBlingViewController``sceneView
在构建和运行之前,需要一些代码来显示相机源并开始跟踪您的面部。
在EmojiBlingViewController.swift中,将以下函数添加到EmojiBlingViewController类中:
在视图出现之前,您:
ARSession_ARSCNView在视图消失之前,请确保:
到目前为止,此代码存在一个很小的问题。ARFaceTrackingConfiguration仅适用于配备前置原深感摄像头的手机。您需要确保在做任何事情之前检查这一点。
在同一个文件中,将以下内容添加到viewDidLoad()应该已经存在的函数末尾:
有了这个,您检查以确保设备支持面部跟踪(即,具有前置 TrueDepth 摄像头),否则停止。这不是处理这个问题的优雅方式,但由于这个应用程序只进行面部跟踪,所以其他任何事情都毫无意义!
在运行您的应用程序之前,您还需要在Info.plist 中指定需要使用相机权限的原因。
在 Project navigator 中选择Info.plist并添加一个带有 键的条目Privacy - Camera Usage Description。它应该默认为 type String。对于该值,请键入EmojiBling 需要访问您的相机才能跟踪您的面部。
最后。是时候构建和运行这只小狗了……呃……应用程序……appuppy?
当你这样做时,你应该看到你美丽的笑脸正盯着你。
好的,足够的鸭面。你还有更多的工作要做!
注意:此项目的某些构建步骤可能需要很长时间。虽然看起来 Xcode 已经去喝咖啡了,但它可能还没有,你只需要耐心等待它。
您已经看到了ARFaceTrackingConfiguration,它用于配置设备以使用 TrueDepth 摄像头跟踪您的面部。凉爽的。
但是您还需要了解有关面部跟踪的哪些信息?
您将很快使用的三个非常重要的类ARFaceAnchor是ARFaceGeometry和ARSCNFaceGeometry。
ARFaceAnchor继承自ARAnchor。如果你以前用ARKit做过任何事情,你就会知道ARAnchors 是它如此强大和简单的原因。它们是ARKit跟踪的现实世界中的位置,当您移动手机时它们不会移动。ARFaceAnchors 还包括有关人脸的信息,例如拓扑和表情。
ARFaceGeometry听起来很像。vertices它是包含和的人脸的 3D 描述textureCoordinates。
ARSCNFaceGeometry使用来自 an 的数据ARFaceGeometry来创建 a SCNGeometry,它可以用来创建SceneKit节点——基本上就是你在屏幕上看到的。
好的,够了。是时候使用其中一些类了。回到编码!
从表面上看,您似乎只打开了前置摄像头。但是,您没有看到的是您的 iPhone 已经在跟踪您的脸部。毛骨悚然,小 iPhone。
看看 iPhone 正在跟踪什么不是很好吗?多么巧合,因为这正是你接下来要做的!
EmojiBlingViewController在类定义的右大括号后添加以下代码:
在此代码中,您:
EmojiBlingViewController实现ARSCNViewDelegate协议。renderer(_:nodeFor:)从协议中定义方法。注意:ARSCNFaceGeometry仅在使用 Metal 渲染的SceneKit视图中可用,这就是为什么您需要在初始化期间传入 Metal 设备的原因。此外,此代码仅在您针对真实硬件时才会编译;如果您以模拟器为目标,它将无法编译。
在运行它之前,您需要将此类设置为ARSCNView的委托。
在viewDidLoad()函数末尾添加:
好的,是每个人最喜欢的步骤的时间了。构建并运行该应用程序!
您是否注意到网格蒙版有点……静态?当然,当您移动头部时,它会跟踪您的面部位置并随之移动,但是当您眨眼或张开嘴时会发生什么?没有。
多么令人失望。
幸运的是,这很容易解决。您只需要添加另一种ARSCNViewDelegate方法!
在ARSCNViewDelegate扩展的末尾,添加以下方法:
在这里,你:
didUpdate版本。renderer(_:didUpdate:for:)ARFaceAnchor并且节点的几何形状是ARSCNFaceGeometry.ARSCNFaceGeometry使用ARFaceAnchor's更新ARFaceGeometry现在,当您构建并运行时,您应该会看到网格蒙版形式并更改以匹配您的面部表情。
如果您还没有这样做,请继续通过教程顶部或底部的按钮下载本教程的材料。
在里面,你会发现一个名为SuperUsefulCode的文件夹,里面有一些 Swift 文件。将它们拖到 EmojiBlingViewController.swift下方的项目中。选择Copy items if needed,Create groups,并确保选择Emoji Bling目标
StringExtension.swift包含一个String可以将 a 转换String为 a的扩展UIImage。
EmojiNode.swift包含一个SCNNode被调用的子类EmojiNode,它可以渲染一个String. 它需要一个 s 数组,String并且可以根据需要循环它们。
随意探索这两个文件,但深入了解此代码的工作原理超出了本教程的范围。
有了这些,是时候增加你的鼻子了。并不是说它有什么问题。你已经是这么漂亮的人了。:]
在EmojiBlingViewController类的顶部,定义以下常量:
数组末尾的空白区域是为了让您可以选择清除鼻子工作。如果您愿意,可以随意选择其他鼻子选项。
接下来,将以下辅助函数添加到您的EmojiBlingViewController类中:
在这里,你:
node名字为“nose”且属于 type 的孩子EmojiNodeARFaceGeometry从 的属性中获取索引 9 处的顶点ARFaceAnchor并将其放入数组中。EmojiNode根据顶点更新其位置。此updatePosition(for:)方法采用顶点数组并将节点的位置设置为其中心。注意:那么索引 9 是从哪里来的?这是一个神奇的数字。其中ARFaceGeometry有 1220 个顶点,索引 9 在鼻子上。这目前有效,但稍后您将简要阅读使用这些索引常量的危险以及您可以做些什么。
使用辅助函数来更新单个节点可能看起来很愚蠢,但稍后您将加强此函数并严重依赖它。
现在你只需要添加一个EmojiNode到你的人脸节点。return在方法中的语句之前添加以下代码renderer(_:nodeFor:):
在此代码中,您:
EmojiNode使用您定义的鼻子选项创建一个。您会注意到编译器错误,因为faceAnchor未定义。要解决此问题,guard请将同一方法顶部的语句更改为以下内容:
在运行您的应用程序之前,您还应该做一件事。在中,在右大括号之前renderer(_:didUpdate:for:)添加一个调用:updateFeatures(for:using:)
这将确保当您抬起脸或摆动鼻子时,表情符号的位置会随着您的动作而更新。
现在是构建和运行的时候了!
现在,那个新鼻子很好,但也许有些日子你想换个鼻子?
当您点击它们时,您将添加代码以循环浏览您的鼻子选项。
打开Main.storyboard并找到Tap Gesture Recognizer。您可以通过打开故事板右上角的对象库来找到它。
将其拖到ARSCNView您的视图控制器中。
Main.storyboard在标准编辑器中依旧打开,像以前一样在助手编辑器中打开EmojiBlingViewController.swift 。现在按住 Control 并从Tap Gesture Recognizer拖动到您的主类。EmojiBlingViewController
释放鼠标并添加一个名为.handleTap``UITapGestureRecognizer
注意:由于某种原因,您只能按住 Control 并拖动到原始类定义而不是扩展。但是,如果您愿意,您可以稍后将生成的存根剪切并粘贴到扩展中。
现在,将以下代码添加到您的新handleTap(_:)方法中:
在这里,你:
sceneView.EmojiNode.next()方法以切换EmojiNode到您使用的列表中的下一个选项。现在是时候了。最美妙的时光。构建和运行时间。去做吧!当你点击你的表情符号鼻子时,它会改变。
更多表情符号金光闪闪
有了对 emoji bling 的新口味,是时候添加更多的 bling 了。
在EmojiBlingViewController类的顶部,在常量下方添加以下noseOptions常量:
再一次,如果您愿意,可以随意选择不同的表情符号。
在您的renderer(_:nodeFor:)方法中,在对 的调用上方updateFeatures(for:using:),添加其余的子节点定义:
这些面部特征节点就像noseNode您已经定义的一样。唯一略有不同的是设置leftEyeNode.rotation. 这会导致节点绕 y 轴旋转 180 度。由于EmojiNodes 从两侧可见,这基本上反映了左眼的表情符号。
如果您现在运行代码,您会注意到所有新表情符号都位于您脸部的中心,并且不会随着您的脸部旋转。这是因为该方法到目前为止updateFeatures(for:using:)只更新了鼻子。其他一切都放在头部的原点。
你真的应该解决这个问题!
在文件顶部,在您的下方添加以下常量hatOptions:
features是您为每个特征指定的节点名称的数组,并且是对应于这些特征featureIndices的顶点索引(还记得幻数吗?)。ARFaceGeometry
您会注意到“嘴”有两个与之关联的索引。由于张开的嘴巴是网状面具上的一个洞,因此定位嘴巴表情符号的最佳方法是平均上唇和下唇的位置。
注意:功能的硬编码索引是技术债务的潜在来源。目前,anARFaceGeometry有 1220 个顶点,但如果 Apple 决定它想要高分辨率会怎样?突然间,这些索引可能不再符合您的预期。一种可能的稳健解决方案是使用 Apple 的 Vision 框架来初步检测面部特征并将其位置映射到最近的顶点ARFaceGeometry
接下来,将您当前的实现替换updateFeatures(for:using:)为以下内容:
这看起来非常相似,但有一些变化需要考虑。在此代码中,您:
featuresand 。featureIndexesEmojiNode.ARFaceGeometry使用 的属性将索引数组映射到顶点数组ARFaceAnchor。开始构建并运行您的应用程序。你知道你想。
ARFaceAnchor不仅包含面部的几何形状。它还包含混合形状系数。混合形状系数描述了您的面部表现出多少表情。系数范围从 0.0(无表达式)到 1.0(最大表达式)。
例如,当您的脸颊脸颊松弛时,以及当您的脸颊像海豚一样膨胀到最大的时候,ARFaceAnchor.BlendShapeLocation.cheekPuff会记录下来!这……厚皮。0.0``1.0
目前有 52 个混合形状因子可供选择。在 Apple 的官方文档中查看它们。
在阅读上一节关于混合形状的内容时,您是否想知道是否可以使用它们来展示您的表情?
在updateFeatures(for:using:)中,就在for循环的右边大括号之前,添加以下代码:
在这里,你:
switch在功能名称上使用声明。case为实施leftEye。eyeBlinkLeft如果未找到,则获取混合形状系数并默认为 0.0(未隐藏)。case以使switch特工无遗体。很简单,对吧?制造并运行!
这将与左眼的代码非常相似。将以下内容添加case到相同的switch语句中:
再次,并运行您的应用程序,您应该可以用眼睛看到了!
现在,在应用程序中,张开嘴巴巴,巴巴表情符号会暂停在嘴巴巴之间,但有点覆盖嘴巴。这有点,如果你不是说呢?
你要解决这个问题。现在将下面的内容添加case到同一个switch语句中:
在这里,是jawOpen混合的形状,但它适合0.0你吗?但您可以使用一下吗?可靠。这就是你使用的。1.0``mouthClose``.jawOpen
继续您的最后一次制作并运行您的应用程序,并运行于您的创作。
您可以使用教程中的所有代码部分下载最终项目。
这里也推荐一些面试相关的内容!
上一篇:作为展馆,要怎么使用好AR技术?
下一篇:AR眼镜离替代手机还有多远?