iOS ARKit入门2 - 工作原理及流程介绍
前言
勇敢的小伙伴们,大家好,很高兴在初七这年后的第一个工作日能够摆脱假期综合症、调整心态继续ARKit的相关文章,不知道你们的假期怎么样,反正我的就很平淡啦,年纪大了,发现再也找不到志同道合的人了呢,不知道为什么,找不到愿意和我一起出去玩耍的人,想看一部电影身边的人都不愿意去看,想出去旅行身边的人都不想出去旅行,想聚会打牌,身边的人都没有时间,我们在逐渐衰老的过程中到底收获了什么,所谓的青春到底应该怎么做,才能了无遗憾,我们拼命努力的现在真的是为了遥远的以后吗?日复一日,年复一年,心智逐渐健全,却发现年幼的时候总是很容易满足,很容易感觉到幸福和快乐,但是长大的我们却越来越难收获到快乐呢?学习一门新技术你会感到快乐吗?买一件新衣服你会感到快乐吗?出去旅行一次你会感觉到快乐吗?
嗯,学习一门新技术我会感到快乐。
好,开始学习!
正文
1.1 预防针
ARKit这个技术的年纪尚小,了解它的人很少,不知道它身上有什么缺点,就会产生畏惧心理,但是我们要去认识它,然后了解它,克服它的小缺点,和它成为朋友。
所以这一篇博客主要是为了带大家熟悉ARKit本身,说到ARKit我们还需要了解SceneKit(3D)框架。
那坤小的博客给大家做了一个比较详细的介绍,当然不一定没有错误,所以大家如果有其他见解也可以指出来,互相学习嘛。
另外在3D世界里,我们需要学习的是空间立体坐标系,而不是平面坐标系,对于这两个坐标系之间的区别和转换也是我们所需要学习和了解的难点。
先给大家打个预防针,让大家了解一下想与ARKit交好所需要做的准备。
1.2 ARKit和SceneKit难舍难分的情谊
AR是增强现实的意思,也就是说在我们捕捉到的现实世界的图像里添加其他的东西,当然这些东西是用3D模型去表达的,这一过程可以分为两个步骤:
1.相机捕捉现实世界的图像,这部分由ARKit实现,
2.在图像中显示3D模型,这部分由SceneKit实现。
ARKit和SceneKit框架关系如图所示:
从上面的框架图我们可以看出:
1.<ARKit>中显示3D虚拟增强显示视图的ARSCNView继承与<SceneKit>中的SCNView,而SCNView继承与<UIKit>中的UIView。
UIView:将视图显示在window中。
SCNView:显示一个3D场景,可以展示3D模型,可以旋转,缩放等操作。
ARSCNView:也是显示一个3D场景,但场景是摄像头捕捉到的现实世界。
2.ARSCNView只是一个视图容器,它的作用是管理一个ARSession。
3.在一个完整的增强现实体验中,ARKit负责将现实世界界面转变为一个3D场景,这个过程主要分为两个环节:由ARCamera负责捕捉摄像头画面,由ARSession负责搭建3D场景。SceneKit负责将虚拟物体显示在3D场景中,每一个虚拟的物体都是一个节点SCNNode,每一个节点构成了一个场景SCNScene,无数个SCNScene构成了3D世界。
4.综上所述,ARKit捕捉3D现实世界使用的是自身的功能,这个功能是在iOS11新增的,而ARKit在3D显示场景中添加虚拟物体使用的是父类SCNView的功能,这个功能早在iOS8时就已经添加。
可以简单的理解为:ARSCNView所有跟场景和虚拟物体相关的属性及方法都是其父类SCNView的属性和方法。
1.3 ARKit工作的原理
1.3.1 ARSCNView与ARSession
1.ARKit提供两种增强现实视图,一种是3D效果的ARSCNView,一种是2D效果的ARSKView。
无论是使用哪一种视图都是用相机捕捉到的现实世界的场景作为3D场景,而捕捉现实世界场景的相机便是ARCamera类。
2.ARSCNView和ARCamera两者并没有直接的关系,它们直接通过ARSession搭建沟通桥梁的。
这里需要注意的是在iOS框架中,凡是带session或者context后缀的,这种类一般自己不干活,一般是为了管理其他类,帮助它们搭建沟通桥梁,好处就是解耦,或者负责帮助我们管理复杂环境下的内存。
session和context的不同之处在于,session一般是和硬件打交道,比如摄像头捕捉ARSession,网卡调用NSURLSession等,context则没有硬件参与,绘图上下文CGContextRef,自定义转场上下文UIViewControllerContextTransitioning等。
3.要想运行一个ARSession,你必须要制定一个称为会话追踪配置的对象:ARSessionConfiguration,ARSessionConfiguration的主要
目的是负责追踪相机在3D世界中的位置以及一些特征场景的捕捉(例如平面捕捉),这个类本身比较简单却作用巨大。
ARSessionConfiguration是一个父类,为了更好的看到增强显示的效果,苹果官方建议我们使用它的子类ARWorldTrackingConfiguration。
该类只支持A9芯片之后的机型,也就是iPhone 6s之后的机型,这点需要注意。
1.3.2 ARWorldTrackingConfiguration与ARFrame
1.ARSession搭建沟通桥梁的参与者主要有两个ARWorldTrakingConfiguration与ARFrame。
2.ARWorldTrackingConfiguration的作用是追踪设备的方向和位置,以及检测设备摄像头看得的现实世界的表面,它的内部实现了一系列
非常庞大的算法计算以及调用了你的iPhone必要的传感器来检测手机的移动、旋转及翻滚。
3.当ARWorldTracingConfiguration计算出相机在3D世界中的位置时,它本身并不持有这个位置数据,而是将其计算出的位置数据交给ARSession去管理,
而相机的位置数据对应的类就是ARFrame,ARSession类的一个属性叫做currentFrame,维护的就是ARFrame这个对象。如下图所示。
4.ARCamera只负责捕捉图像,不参与数据的处理,它属于3D场景中的一个环节,ARCamera,它决定了我们看物体的视野。
ARSCNView有ARSession类的属性session,ARSession有ARFrame类的属性currentFrame,ARFrame有ARCamera类的属性camera。
这里需要注意的是ARCamera和SCNCamera。
三者之间关系如图所示:
ARCamera在3D世界的位置看起来是这样的:
我们可以调整camera的前后左右,来调整我们的视角。
1.4 ARKit工作完整流程
第一步:我们需要一个ARSCNView来加载场景SCNScene
第二步:ARSCNView启动相机ARCamera开始捕捉场景(此处存疑,这里的确是ARSCNView
才会启动ARCamera,如果是SCNView则没有ARCamera,原作者写的是SCNScene启动ARCamera)
第三步:捕捉场景后ARSCNView开始将场景数据交给Session
第四步:Session通过管理ARSessionConfiguration实现场景的追踪并且返回一个ARFrame
第五步:给ARSCNView的scene添加一个子节点SCNNode(3D模型)
ARSessionConfiguration捕捉相机3D位置的意义就在于能够在添加3D物体模型的时候计算出
3D物体模型相对于相机的真实的矩阵位置。
在3D坐标系统中,有一个世界坐标系和一个本地坐标系。类似于UIView的Frame和Bounds的区别,
这种坐标的转换可以说是ARKit最难的部分。
此处原作者的架构图存疑。
我认为在SCNScene下有一个SCNNode类的属性rootNode,SCNNode类有个SCNCamera类的属性camera,
而不是ARCamera。ARCamera是在ARFrame下面有的。