iOSのARKitを使いこなしたい

# はじめに。

ARKitが提供されたのが、iOS11から。（iOS11: 2017/9/20）
そのARKitも3.0まで発表され、多くのことができるようになりました。

ARを使いこなせるようにするために、**ARKitとARKitに関連したSceneKit・SpriteKitの概要やそのフレームワークらを使用する上で理解しておきたい用語・技術**を記しておきます。

（あくまで自分用に書いているため、少し解釈が違う部分があると思います。できるだけ他の人にもわかりやすいように努力していますが、わかりずらかったり違っていたらごめんなさい。。。）

# Sample
- [ARKit1.0 SampleCode](https://github.com/shu223/ARKit-Sampler)
- [ARKit2.0 SampleCode](https://github.com/kboy-silvergym/ARKit-Emperor)
- [ARKit3.0 SampleCode](https://github.com/1901drama/ARKit-Invader)


# ARKitとSceneKit・SpriteKit・RealityKit

ARKitとARKitに関連したSceneKit・SpriteKit・RealityKitの概要。
知識として知っておく必要はあるため、書いておきます。

## **1. [ARKit](https://developer.apple.com/documentation/arkit)**

iOS11.0+

ARKitは、iOSデバイスのカメラとデバイスの動きを統合することでアプリやゲームでARが体験できるフレームワーク。iOSデバイスのモーショントラッキングやカメラのシーンキャプチャ、高度なシーン処理などを組み合わせて、ARのビルドを簡易化する。

iOSデバイスのバックカメラからのView表示が、最も一般的なAR体験ができる。最近では、iPhoneXの存在からフロントカメラを使用してユーザーの顔のポーズや表情などの情報取得することができるようになった。

※ AR(Augmented reality)は、iOSデバイスのカメラから2Dや3Dの要素を現実世界にあるように見せるようにするやり方で、それらの要素をライブビューに追加するUX。

## **2. [SceneKit](https://developer.apple.com/documentation/scenekit)**

iOS 8.0+

SceneKitは、高性能なシーン描写を使用してアプリに3Dコンテンツを追加することができるフレームワーク。アニメーションや物理シミュレーション、パーティクルエフェクトおよび現実的な物理ベースのレンダリングを簡易に追加することができる。

OpenGLやMetalのようなAPIとは違い、シーンの内容やアクションまたはアニメーションの記述だけで簡単に追加ができる。

※ 今後、SCNViewやSCNNode、SCNGeometryのようにSCNがついた用語が出てくる。SCNは、Sceneの意味である。

## **3. [SpriteKit](https://developer.apple.com/documentation/spritekit)**

iOS 7.0+

スムーズなアニメーションを用いて高性能な2Dコンテンツをアプリに追加するフレームワーク。Metalのように高性能なレンダリングを実現しながら、グラフィックスを多用するアプリケーションを簡単に作成できる。


## **要点**

- ARの技術をiOSで実現するには、ARKitを使用する。
- ARでオブジェクトを扱う際には、ARKitの他にSceneKitやSpriteKitを使用する必要がある。
- 3Dでは、ARKit + SceneKit
- 2Dでは、ARKit + SpriteKit


# ARKit・SceneKit/SpriteKitを扱うために理解しておきたい用語・技術

    理解しておきたい用語・技術の説明。ARをiOSで扱う上で知っておかなくてはいけない用語・技術が多くあったため、まとめておく。基本、Documentの日本語訳だが、自分なりに解釈している部分もある。

## **1. [ARSession](https://developer.apple.com/documentation/arkit/arsession)**

  ```swift
  class ARSession: NSObject
  ```

  iOSデバイスのカメラとモーション処理を管理するclass。このclassは、ARKitが開発者に代わって行うARを作成する大部分のプロセスをまとめている。

  ※ ARを作成する大部分のプロセスは、iOSデバイス内のモーションセンシングハードウェアからのデータ読み取りやiOSデバイスの内蔵カメラの制御、キャプチャしたカメラ画像の画像解析である。

  sessionはARを作成する大部分のプロセスを統合し、現実空間と仮想空間との間の対応関係を確立する。 -> これにより、現実と仮想との間をsessionで管理することができる。

## **2. [ARConfiguration](https://developer.apple.com/documentation/arkit/arconfiguration)**

  ```swift
  class ARConfiguration: NSObject
  ```

  sessionを設定するためのclass。sessionに関しての様々な設定classが存在する。設定オブジェクトのプロパティを設定し、その設定をsessionに渡すことで、ARをモデル化することができる。

  - [ARWorldTrackingConfiguration](https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration)

    バックカメラを使用して、iOSデバイスの位置や向きを感知し、平面や画像、オブジェクトの検出ができる。

  - [AROrientationTrackingConfiguration](https://developer.apple.com/documentation/arkit/arorientationtrackingconfiguration)

    ARWorldTrackingConfigurationとは別に、バックカメラを使用してiOSデバイスの向きのみを感知する。

  - [ARImageTrackingConfiguration](https://developer.apple.com/documentation/arkit/arimagetrackingconfiguration)

    バックカメラを使用して、画像を感知することができる。

  - [ARFaceTrackingConfiguration](https://developer.apple.com/documentation/arkit/arfacetrackingconfiguration)

    フロントカメラを使用し、ユーザーの顔の動きや表情を感知することができる。

  - [ARObjectScanningConfiguration](https://developer.apple.com/documentation/arkit/arobjectscanningconfiguration)

    バックカメラを使用し、空間やオブジェクトを感知することができる。

## **3. [ARAnchor](https://developer.apple.com/documentation/arkit/aranchor)**

  ```swift
  class ARAnchor: NSObject
  ```

  scene内にオブジェクトを配置するために使われる現実世界の位置と向き。-> 現実世界の情報

  カメラに写っている現実または仮想空間にあるオブジェクトの静的な位置と向きを検出するために、anchorオブジェクトを作成し、[add(anchor:)](https://developer.apple.com/documentation/arkit/arsession/2865612-add)メソッドを使用する。これにより、ARSessionにanchorが追加される。

  ※ 3D空間においたオブジェクトが動いた時は、実際にそのオブジェクトが動いているわけではない。これはAnchorによりもので、元々あった所のAnchorが削除され、動いた先の位置にAnchorが追加されているため、動いているように見えている。

  ARKitは自動的にAnchorをSessionに追加する。機能を有効にするときは、ARPlaneAnchorやARObjectAnchor、ARImageAnchorオブジェクトを追加する。

  - [ARPlaneAnchor](https://developer.apple.com/documentation/arkit/arplaneanchor)

    sessionで検出した現実世界の平面の位置と向きの情報。平面検出する際に使用する。

  - [ARObjectAnchor](https://developer.apple.com/documentation/arkit/arobjectanchor)

    sessionで検出した現実世界の3Dオブジェクトの位置と向きの情報。物体感知する際に使用する。

  - [ARImageAnchor](https://developer.apple.com/documentation/arkit/arimageanchor)

    sessionで検出した画像の位置と向きの情報。画像認識する際に使用する。

## **4. [ARWorldMap](https://developer.apple.com/documentation/arkit/arworldmap)**

  ```swift
  class ARWorldMap: NSObject
  ```

  ワールドトラッキングsessionからのspace-mappingの状態とanchorのセットのこと。

  ワールドマップ内のsessionの状態は、ユーザーがiOSデバイスを動かしている物理的空間（ARKitがiOSデバイスの位置や向きを特定するために使う）のARKitの認識(=sessionに追加されているanchor)を含んでいる。

## **5. [ARSCNView](https://developer.apple.com/documentation/arkit/arscnview)**

  ```swift
  class ARSCNView: SCNView
  ```

  AR体験を表示するためのView。SceneKitのコンテンツをAR用に機能を補っている。sessionを実行すると、Viewはカメラからのライブビデオフィードをsceneの背景としてレンダリングしたり、SceneKitカメラを自動的に動かしてiOSデバイスの実際の動きに合わせたりする。

  ARSCNViewdelegeteメソッドを実行することで、ARKitが検出したanchorをSceneKitに加える。

  ARKit + ScreneKit


  __ここからは、SceneKitに関係する用語・技術をまとめる。__


## **6. [SCNScene](https://developer.apple.com/documentation/scenekit/scnscene)**

  ```swift
  class SCNScene: NSObject
  ```

  一緒に表示可能な3Dsceneを形成するグローバルプロパティとnode階層のためのコンテナ。

  3DコンテンツをSceneKitで表示するためには、視覚要素を表すnodeと属性階層を含んでいるsceneを作成する。node階層については、SCNNodeで詳しく。

  Viewに表示されている描写そのもの。

## **7. [SCNNode](https://developer.apple.com/documentation/scenekit/scnnode)**

  ```swift
  class SCNNode: NSObject
  ```

  形状や光、カメラなどの表示可能なコンテンツを表示することができる3D空間での位置や向きを示すscenegraphの構造的要素。-> sceneに写っている物体。

  screnegraph（= scene内のnodeの階層）は、そのコンテンツの構成と、SceneKitを使用しているそれらのコンテンツを表示および操作する能力の両方を定義している。

  scene内のrootNodeは、SceneKitでレンダリングされた世界の座標系を定義している。rootNodeに追加された各子nodeは、それ自体の座標系を作成し、さらにその子nodeへ継承されていく。

## **8. [SCNGeometry](https://developer.apple.com/documentation/scenekit/scngeometry)**

  ```swift
  class SCNGeometry: NSObject
  ```

  外観を定義するマテリアルを添付して、シーンに表示できる3次元形状。
  modelやmeshとも言われる。