ARKitのまとめ(実装)
Jul 23, 2017 · iosarkit
概要
WWDC2017で発表されたARKit
の実装についてのまとめ
ARKit
はARSession
というセッションを通して利用できる
基本的な流れは、セッションを実行しデリゲートで状況の変化を受け取ることになる
Metal
を使う場合など自分でレンダリングのループを回したい様な場合は、デリゲートを使わずに一定時間ごとにセッションのオブジェクトにアクセスしてチェックしてもOK
レンダリング用のフレームワークとの連携
ARKit
の特徴の一つは、SceneKit
やSpriteKit
にそれぞれ専用のクラスが準備されていて、オブジェクトのレンダリングまで簡単に連携できる点である
SceneKit
: 3Dの描画用ARSCNView
(SCNView
のサブクラス)ARSCNViewDelegate
(SCNViewDelegate
+ARSessionDelegate
)
SpriteKit
:ARSKView
(SKView
のサブクラス)ARSKViewDelegate
(SKViewDelegate
+ARSessionDelegate
)
それぞれのクラスには、あらかじめARSession
がメンバとして存在している。また、カメラでキャプチャされた画像を背景として描画する
使い方
初期設定〜実行
初期設定
カメラのパーミッション
ARKit
のアプリを実行するにあたり、カメラのキャプチャを行うので、Info.plist
でカメラの利用設定が必須
Privacy - Camera Usage Description
: 利用目的の説明文(初回利用時の許可ダイアログに表示される)
なお、これがないと実行時に落ちる
対応機種の確認
ARKit
は実行可能なデバイスが限られている(A9
チップ以降)ので、以下のどちらかで対応機種の確認を行う
- インストール自体の制限
ARKit
が必須の場合はInfo.plist
で以下の制限を追加し、非対応機種にインストールできなくするRequired device capabilities
:arkit
- 実行時の確認
実行時の確認で良い場合は、以下のフラグで確認するARWorldTrackingSessionConfiguration.isSupported
実行〜停止
ARSessionの生成
ARSCNView
やARSKView
を使う場合は、特に自分で生成する必要はない。
使わずに自分で生成する場合は、ViewController
などのメンバとして保持しておく
設定
何をトラッキングするかといった設定はARSessionConfiguration
で指定する
例えば、水平面(床)を検出したい場合は、
let configuration = ARWorldTrackingSessionConfiguration()
configuration.planeDetection = .horizontal
というように設定をする
実行(開始)
セッションを開始するには、一つ前で作成したARSessionConfiguration
の設定を引数にしてrun
を呼ぶ
// let session = ARSession()
session.run(configuration)
なお、run
でオプションの.resetTracking
を指定すると、前回実行時のトラッキング情報をリセットが可能(他にもオプションあり)
停止
セッションはpause
で一時停止できる
session.pause()
再開時は再度、run
を呼び出せば良い。ただし、都度ARSessionConfiguration
を指定する必要がある
(再開前と同じトラッキングをしたければ、同じ設定を渡す必要がある。
逆に別の設定に切り替えて再開しても良い)
なお、アプリがバックグラウンドにいった場合などは、カメラが利用不可となる為、トラッキングが停止されてしまうので、viewWillDisappear
で明示的に停止した方が良いかもしれない(停止時の通知は受信可能)
結果の取得
ARSession
のイベントは、ARSessionDelegate
で通知されるので、delegate
を登録して受信する
class ViewController: UIViewController, ARSessionDelegate {
var session: ARSession!
override func viewDidLoad() {
...
session = ARSession()
session.delegate = self
}
...
}
なお、ARSCNView
やARSKView
を使う場合はそれぞれ専用のデリゲートが用意されている。
セッション状態のハンドリングは共通であるが、コンテンツのハンドリングはそれぞれ専用になっている
セッション状態のハンドリング
エラー発生時
func session(ARSession, didFailWithError: Error)
セッションが中断した時
アプリがバックグラウンドに行ってカメラのキャプチャが中断された場合などfunc sessionWasInterrupted(ARSession)
中断したセッションが再開された時
func sessionInterruptionEnded(ARSession)
sessionWasInterrupted
の後に呼ばれるトラッキング状態(品質)が変わった時
func session(ARSession, cameraDidChangeTrackingState: ARCamera)
コンテンツのハンドリング
カメラのキャプチャ画像が更新された時
キャプチャ画像と同時にその画像から解析されたAR情報を取得できるfunc session(ARSession, didUpdate: ARFrame)
Metal
などで独自レンダリングをする場合に使う想定アンカーが追加された時
func session(ARSession, didAdd: [ARAnchor])
アンカーが更新された時
func session(ARSession, didUpdate: [ARAnchor])
アンカーが削除された時
func session(ARSession, didRemove: [ARAnchor])
それぞれの具体的な使い方は次回
確認環境
- Xcode9.0 beta3