第2章 ARKit 堤 修一/@shu223
2.7.2 デバイスの移動に対するインタラクション
ARKitは現実空間におけるデバイスの位置や向きをトラッキングします。すなわち、現実空間内におけるデバイスの移動や向きの変化に追従して、ARKitの空間内におけるカメラの位置や向きを更新します。この情報を利用すると、ユーザーがiPhoneを持って移動したり、iPhoneを動かしたりといったデバイスの動きに合わせて仮想オブジェクトにアクションを取らせることができます。
たとえば、WWDC 2017のデモにあったように、空間内に設置した仮想のキャラクターにずっとユーザーの方を向かせる、といったことが可能です。
図2.12 WWDC 2017のデモより。仮想のカメレオンが常にユーザーの方を向く
■最新フレームにおけるカメラの情報を取得する
「2.6.2 特徴点のIDや座標を取得する」でもすでに触れましたが、ARKitではカメラから新しい入力があるたびにARSessionDelegateプロトコルのsession(_, didUpdate:)メソッドが呼ばれます。その第2引数に渡されるARFrameオブジェクトから、最新フレームが持つさまざまな情報を取得できます。
func session(_ session: ARSession, didUpdate frame: ARFrame)
最新フレームにおけるカメラの情報は、cameraプロパティからARCamera型で取得できます。
let camera = frame.camera // ARCamera
■カメラのワールド変換行列から、カメラの位置・向きを取得する
ARCameraはmatrix_float4x4型のtransformプロパティを持っており、この4×4の行列がワールド座標系注23)におけるカメラの変位と回転(つまり位置と向き)を表します。
let transform = camera.transform // matrix_float4x4
この4×4行列は、ワールド座標系における変換行列という意味で「ワールド変換行列」と呼ばれます。このワールド変換行列から、ARKitの空間内における位置を得るには、次のように行列の要素を取り出して3次元ベクトルを作成します。
let pos = SCNVector3Make(transform.columns.3.x, transform.columns.3.y, transform.columns.3.z)
もしくはSceneKitに用意されている4×4行列を表す型SCNMatrix4にいったん変換してから、位置を表す3次元ベクトルを得る方法もあります。
let mat = SCNMatrix4(transform) let pos = SCNVector3(mat.m41, mat.m42, mat.m43)