# ARKit的工作原理及流程介绍

## ARKit介绍

### AR技术简介:

AR 全称 Augmented Reality(增强现实),实时计算摄影机相机位置及角度并且增加图像/视频/3D模型的技术,将虚拟现实与现实世界结合在一起,并且进行互动.

一个最简单地AR场景实现所需要的技术以及步骤包含如下: 1.多媒体捕捉现实图像：如摄像头 2.三维建模:3D立体模型 3.传感器追踪:主要追踪现实世界动态物体的六轴变化，这六轴分别是X、Y、Z轴位移及旋转。其中位移三轴决定物体的方位和大小，旋转三周决定物体显示的区域。 4.坐标识别及转换：3D模型显示在现实图像中不是单纯的frame坐标点，而是一个三维的矩阵坐标。这基本上也是学习AR最难的部分，好在ARKit帮助我们大大简化了这一过程。 4.除此之外，AR还可以与虚拟物体进行一些交互。

### ARKit概述及特点介绍

WWDC 2017全球开发者大会上,苹果发布了iOS11系统所新增框架:AR开发ARKit,它能够帮助我们以最简单快捷的方式实现AR技术功能。

* ARKit框架提供了两种AR技术，一种是基于3D场景(SceneKit)实现的增强现实，一种是基于2D场景(SpriktKit)实现的增强现实

一般主流都是基于3D实现AR技术，ARKit不仅支持3D游戏引擎SceneKit还支持2D游戏引擎SpriktKit.

* 要想显示AR效果，必须要依赖于苹果的游戏引擎框架（3D引擎SceneKit，2D引擎SpriktKit），主要原因是游戏引擎才可以加载物体模型。

虽然ARKit框架中视图对象继承于UIView，但是由于目前ARKit框架本身只包含相机追踪，不能直接加载物体模型，所以只能依赖于游戏引擎加载ARKit

* ARKit虽然是iOS11新出的框架，但并不是所有的iOS11系统都可以使用，而是必须要是处理器A9及以上才能够使用，苹果从iPhone6s开始使用A9处理器，也就是iPhone6及以前的机型无法使用ARKit

### 开发环境:

1.Xcode版本:Xcode9及以上

2.iOS系统:iOS11及以上

3.iOS设备:处理器A9及以上(6s机型及以上)

4.MacOS系统：10.12.4及以上（安装Xcode9对Mac系统版本有要求）

## 使用ARKit

### 3D效果

* 创建项目时选择Augmented Reality App类型.
* 在包含技术选型中选择SceneKit

### 2d效果

2d效果 和3d的显示效果不一样,使用的是Sprite kit,创建项目时,在包含技术选型中选择Sprite Kit.

## ARKit工作原理

### ARKit与SceneKit的关系

AR技术就是在相机捕捉到的现实世界的图像中显示一个虚拟的3D模型。这一过程可以分为两个步骤：

1：相机捕捉现实世界图像,这由ARKit来实现

2：在图像中显示虚拟3D模型,由SceneKit来实现

ARKit与SceneKit的关系为:

* ARKit 框架中中显示3D虚拟增强现实的视图ARSCNView继承于SceneKit框架中的SCNView,而SCNView又继承于UIKit框架中的UIView

UIView的作用是将视图显示在iOS设备的window中，SCNView的作用是显示一个3D场景，ARScnView的作用也是显示一个3D场景，只不过这个3D场景是由摄像头捕捉到的现实世界图像构成的

* ARSCNView只是一个视图容器，它的作用是管理一个ARSession.
* 在一个完整的虚拟增强现实体验中，ARKit框架只负责将真实世界画面转变为一个3D场景，这一个转变的过程主要分为两个环节：由ARCamera负责捕捉摄像头画面，由ARSession负责搭建3D场景。
* 在一个完整的虚拟增强现实体验中，将虚拟物体现实在3D场景中是由框架来完成中：每一个虚拟的物体都是一个节点SCNNode,每一个节点构成了一个场景SCNScene,无数个场景构成了3D世界

综上所述，ARKit捕捉3D现实世界使用的是自身的功能，这个功能是在iOS11新增的。而ARKit在3D现实场景中添加虚拟物体使用的是父类SCNView的功能，这个功能早在iOS8时就已经添加（SceneKit是iOS8新增）

可以简单的理解为：ARSCNView所有跟场景和虚拟物体相关的属性及方法都是自己父类SCNView的.

### ARSCNView与ARSession

ARKit提供两种虚拟增强现实视图，他们分别是3D效果的ARSCNView和2D效果的ARSKView，无论是使用哪一个视图都是用了相机图像作为背景视图（这里可以参考iOS自定义相机中的预览图层），而这一个相机的图像就是由ARKit框架中的相机类ARCamera来捕捉的。

ARSCNView与ARCamera两者之间并没有直接的关系，它们之间是通过AR会话，也就是ARKit框架中非常重量级的一个类ARSession来搭建沟通桥梁的.

在iOS框架中，凡是带session或者context后缀的，这种类一般自己不干活，作用一般都是两个：

* 管理其他类，帮助他们搭建沟通桥梁，好处就是解耦.
* 负责帮助我们管理复杂环境下的内存

context与session不同之处是：一般与硬件打交道，例如摄像头捕捉ARSession，网卡的调用NSURLSession等使用的都是session后缀。没有硬件参与，一般用context，如绘图上下文，自定义转场上下文等.

要想运行一个ARSession会话，必须要指定一个称之为会话追踪配置的对象:ARSessionConfiguration,ARSessionConfiguration的主要目的就是负责追踪相机在3D世界中的位置以及一些特征场景的捕捉（例如平面捕捉），这个类本身比较简单却作用巨大

ARSessionConfiguration是一个父类，为了更好的看到增强现实的效果，苹果官方建议我们使用它的子类ARWorldTrackingSessionConfiguration.

### ARWorldTrackingSessionConfiguration与ARFrame

ARSession搭建沟通桥梁的参与者主要有两个ARWorldTrackingSessionConfiguration与ARFrame

* ARWorldTrackingSessionConfiguration（会话追踪配置）的作用是跟踪设备的方向和位置,以及检测设备摄像头看到的现实世界的表面。它的内部实现了一系列非常庞大的算法计算以及调用了你的iPhone必要的传感器来检测手机的移动及旋转甚至是翻滚.
* 当ARWorldTrackingSessionConfiguration计算出相机在3D世界中的位置时，它本身并不持有这个位置数据，而是将其计算出的位置数据交给ARSession去管理，而相机的位置数据对应的类就是ARFrame.ARSession类一个属性叫做currentFrame，维护的就是ARFrame这个对象
* ARCamera只负责捕捉图像，不参与数据的处理。它属于3D场景中的一个环节，每一个3D Scene都会有一个Camera，它决定了我们看物体的视野

### ARKit工作完整流程

1.ARSCNView加载场景SCNScene

2.SCNScene启动相机ARCamera开始捕捉场景

3.捕捉场景后ARSCNView开始将场景数据交给Session

4.Session通过管理ARSessionConfiguration实现场景的追踪并且返回一个ARFrame

5.给ARSCNView的scene添加一个子节点（3D物体模型）

ARSessionConfiguration捕捉相机3D位置的意义就在于能够在添加3D物体模型的时候计算出3D物体模型相对于相机的真实的矩阵位置

在3D坐标系统中，有一个世界坐标系和一个本地坐标系。类似于UIView的Frame和Bounds的区别，这种坐标之间的转换可以说是ARKit中最难的部分
