伴随着许多其他已被现代技术淘汰的工具,似乎通用的卷尺可能会成为下一步。 在本教程中,我们将通过使用增强现实和iOS设备上的摄像头创建一个可测量两点之间距离的应用程序,来弥合现实与技术之间的鸿沟。
在本文中,我们将启动该应用程序并为其主要界面元素编码。 明天,我们将通过测量AR场景中的两个点来完成它。
入门
让我们开始制作虚拟标尺,它可以让我们测量任何两个现实世界点之间的距离。 如果您考虑一下,您甚至可能甚至不再需要卷尺进行日常测量!
创建一个ARKit应用
新项目
首先,请确保您具有支持ARKit的Xcode版本。 然后,您需要创建一个新的Xcode项目。
继续并打开Xcode,然后单击“ 创建新的Xcode项目”。
![图1创建一个Xcode项目](https://i-blog.csdnimg.cn/blog_migrate/e715c5ec76bbf1172b088a82e4d57036.png)
您可能习惯于制作Single View应用程序 ,但是对于本教程,您将需要选择Augmented Reality App ,然后单击Next。
![图2选择一个增强现实应用](https://i-blog.csdnimg.cn/blog_migrate/f4156eb4b6db00dd405d93c595282d9b.png)
游戏框架
您可以根据自己的喜好为项目命名,但我将命名为ARPlanets。 您还将注意到,底部有一个选项,您可以从其中选择SceneKit,SpriteKit和Metal。 这些都是Apple的游戏框架,在本教程中,我们将使用SceneKit 。
继续并选择SceneKit(如果尚未选择)。 您的屏幕应如下所示:
![图3创建您的项目](https://i-blog.csdnimg.cn/blog_migrate/005ba634f49663fbe5a4bc792e136aeb.png)
准备测试
连接iPhone
由于Xcode Simulator没有相机,因此您需要插入iPhone。 不幸的是,如果您没有iPhone,则需要借用一本才能随本教程一起使用(以及与其他任何与相机或AR相关的应用程序)。 如果您已经将iPhone连接到Xcode,则可以跳到下一步。
Xcode 9中的一个新奇功能是,您可以在设备上无线调试应用程序,所以现在就进行设置。
在顶部菜单栏中,选择“ 窗口” >“ 设备和模拟器”。 在出现的窗口中,确保在顶部选择了设备 。
现在,使用避雷线插入设备。 这应该使您的设备出现在“ 设备和模拟器”窗口的左窗格中。 只需单击您的设备,然后选中通过网络连接框。
![图4设备和模拟器](https://i-blog.csdnimg.cn/blog_migrate/4123c59b3469afbe7bdfebc3f6ced30c.png)
现在,您将可以在所有未来的应用程序的iPhone上进行无线调试。
完成设定
现在您的设置完成。 您应该有一个运行良好的ARKit应用程序,并且可以在刚刚连接的iPhone上对其进行测试。 在Xcode左上方的“ 运行”和“ 停止”按钮旁边,选择 模拟器下拉菜单中的设备。
![图5选择一个模拟器](https://i-blog.csdnimg.cn/blog_migrate/7ac932871e960c17254e507adab79d13.png)
现在,如果您单击“运行”,您应该会看到虚拟飞船出现在您的世界中!
![增强现实飞船](https://i-blog.csdnimg.cn/blog_migrate/76a2482d3bedf849bccb858202f3ad7e.png)
我们的下一步将是删除太空飞船,并开始为我们的测量应用程序编码界面。
测量应用
启动并运行ARKit应用程序的出色工作! 现在,让我们继续摆脱宇宙飞船,从头开始创建距离测量应用程序。 我们的应用将通过让用户在AR场景中放置两个球体,然后计算它们之间的距离来工作。 听起来很简单,但确实需要进行一些编程,所以戴上思想的帽子,让我们开始吧!
我不会在本教程中解释入门代码,因此,如果您不了解某些内容,请确保先阅读有关ARKit入门的教程 。
从头开始
卸下太空飞船
我们宁愿不要在测量应用程序中显示随机的太空船,所以让我们从项目中删除它及其代码。
如果转到项目目录中的Assets.xcassets文件夹,您会注意到组成飞船的两个文件: ship.scn和texture.png 。 这两个文件告诉Xcode太空船的外观。 不过,在我们的应用程序中,我们将以编程方式定义球体。 如果要添加更复杂的节点,可以使用.scn方法,但如果可以,最好在代码中执行操作。
删除示例代码
现在,您已经删除了船上的资产,此时您可能会收到错误消息(如果没有,则代码运行时会收到错误消息)。 这是因为仍然有对我们删除的文件的最新引用。 不过不要担心。 我们将摆脱该示例代码,以便我们可以从头开始编程。
转到ViewController.swift文件并删除以下两行代码:
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
完成后,您的viewDidLoad()
方法应如下所示:
override func viewDidLoad() {
super.viewDidLoad()
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
}
我们仍然可以在我们的新应用中使用它们。 应用程序中剩余的启动程序代码只是样板,它执行诸如运行SceneKit视图之类的事情以及其他类似的事情。
创建标签
当然,如果我们有一个测量应用程序,我们将需要某种方式来告诉用户最终的测量结果,还有什么比使用标签更好的方法? 作为练习,我们不会在标签上使用情节提要,而是以编程方式添加。
变量和类实例
要创建标签,请在类的顶部声明一个变量,如下所示:
var measurementLabel = UILabel()
在这里,我们仅创建了UILabel
类的实例,并在viewDidLoad()
方法中可以配置其各种属性。
将以下内容添加到顶部的viewDidLoad()
方法中以创建背景:
制作背景
measurementLabel.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 100)
measurementLabel.backgroundColor = .white
这里的第一行为标签设置了白色背景,以便可见并且不会与背面的实时视图融合。 该背景将与顶部对齐,并且高度为100。
对齐和添加标签
接下来,我们需要设置文本及其对齐方式,然后将标签添加到视图中。 为此,将以下内容添加到您的viewDidLoad()
方法中:
measurementLabel.text = "0 inches"
measurementLabel.textAlignment = .center
view.addSubview(measurementLabel)
代码的第一行将标签的默认文本设置为“ 0英寸”。 另外,我们希望该应用看起来相当精致,因此我们将标签放在画布上居中。 最后,我们将标签添加到视图。
创建一个球体
由于我们的应用程序将基于放置两个球体,然后测量它们之间的距离,因此我们显而易见的第一步是学习如何创建球体,所以现在就开始做吧。
制定可重用的方法
我们要多次制作球体,因此在viewDidLoad()
方法中对其进行编码没有任何意义。 相反,让我们创建一个可以在需要的地方重复使用和调用的方法。 因此,将以下函数粘贴到您的项目中:
func newSphere(at position: SCNVector3) -> SCNNode {
// Your code goes here
}
如您所见,我们将SCNVector3
一个SCNNode
类型的位置,然后返回一个SCNNode
,它将是球形。 目前,它似乎并不十分重要,但我们将回到为什么以后要使用SCNVector3
作为职位的原因。
创建一个实际球体
现在让我们开始实际创建球体。 将以下三行添加到刚创建的newSphere()
方法中:
// Creates an SCNSphere with a radius of 0.4
let sphere = SCNSphere(radius: 0.01)
// Converts the sphere into an SCNNode
let node = SCNNode(geometry: sphere)
// Positions the node based on the passed in position
node.position = position
代码的第一行只是创建一个SCNSphere
类型的球体,并在SceneKit坐标系中将其初始半径设置为0.01 米 ,这恰好是正确的大小。 不过,如果需要,您可以尝试使用不同大小的球体。
下一行代码将SCNSphere
类型的几何网格更改为实际对象-我们可以实际更改并执行其他操作。 无论如何, SCNNode
将成为我们返回到函数调用的对象。
最后,通过从函数中获取position参数,我们只需根据水龙头(尚未创建)将节点放置在需要放置的节点上即可。
照明,阴影和外观
这部分并不是真正需要的,但是使您的应用程序看起来很好总是有好处的,而且,它将帮助您了解如何为将来的应用程序照明这些人造对象。
首先创建一个空的材料:
// Creates a material that is recognized by SceneKit
let material = SCNMaterial()
在这里,我们只是简单地告诉SceneKit,将有一种新材料,稍后我们将添加属性。 换句话说,我们只是创建了SCNMaterial()
的实例,并将其分配给名为material
的常量。
接下来,通过执行以下操作将材质设置为橙色:
// Converts the contents of the PNG file into the material
material.diffuse.contents = UIColor.orange
由于我们没有要环绕球体的图像,因此将其颜色设置为橙色。 是的,只是纯橙色。 但是,如果要使用图像,则需要做同样的事情,而应将material.diffuse.contents
设置为图像。
最后,设置照明配置并将材料添加到球体中,如下所示:
// Creates realistic shadows around the sphere
material.lightingModel = .blinn
// Wraps the newly made material around the sphere
sphere.firstMaterial = material
现在,您将在这里看到的是我们正在改变环境中的灯光如何影响我们创建的材质。 通过将模型设置为.blinn
模型,我们使用Blinn-Phong公式计算高光。 我们现在不需要深入细节,但是这种特定的照明模型将最适合我们的目的。 最后,我们用刚创建的材料替换了球体的当前材料。
如果您对我们刚刚使用的照明模型感到好奇,请参阅以下Apple文档关于.blinn
照明模型的说明:
合并了环境,漫反射和镜面反射特性的阴影,其中使用Blinn-Phong公式计算镜面反射高光。
回归我们的领域
最后,在创建球体之后,我们的最后一步是将SCNNode
类型的球体简单地返回到函数调用站点。 只需将此行粘贴在函数结尾的花括号之前:
return node
全做完了! 这个方法全都准备好制作球体,然后返回它们。 但是请记住,除非您实际调用该方法,然后将它们添加到父视图中,否则这些球体不会出现。
我们在我们的应用程序上取得了良好的开端。 明天再查看,我将向您展示如何添加轻击手势识别器,以使用户将球体放置在他们想要测量的点上。
结论
我们已经取得了很多成就:我们建立了一个ARKit应用程序,并为我们的距离测量工具构建了基本的界面元素。 明天,我们将通过让用户将这些球体放置在现实世界中的各个点上,然后计算它们之间的距离来完成。
而当您在这里时,请观看我们的视频课程,了解如何在iOS上进行ARKit编码 。 在本课程中,您将了解如何从头到尾编写一个ARKit应用程序!
翻译自: https://code.tutsplus.com/tutorials/virtual-measuring-with-augmented-reality--cms-30296