#この投稿はなに?
ARKit で ARアプリケーションを作成するには、3Dプログラミングが欠かせないことがわかりました。
iOS には、3Dプログラミングのためのフレームワーク SceneKit が用意されています。
この投稿では、SceneKit と ARKit で使用される 空間座標系 を表現するデータ型について、まとめてみました。
空間の情報は、行列で表現される
ARKit および SceneKit では、空間情報を表現するために「4行4列」の行列が多く使用されます。
空間情報は transform プロパティに格納されていることが多いようです。
行列型オブジェクト transform
プロパティに対して、.columns
を参照すると、「行列の列」を配列要素のように取得できます。
この結果に対して、さらにインデックスを指定してアクセスすることもできます。
4列目の値を取得するには、columns.3
と記述します。すると、「1行4列目, 2行4列目, 3行4列目, 4行4列目」の値が取得できます。
let positionInSpace = currentFrame.camera.transform.columns.3
この方法では、インデックスが 0 から始まることに注意 ですね。
空間情報に含まれる値
transform と呼ばれる空間情報には、以下の情報が含まれています。
- 1列目: x軸方向の回転角
- 2列目: y軸方向の回転角
- 3列目: z軸方向の回転角
- 4列目: 3D座標系(x, y, z)
これらの値が、列となっています。
前述の「カメラのtransformから、4列目の値をすべて取得する」コードでは .3
で、4列目の「3D座標系」を取得したことになります。
フレームワークごとに異なる行列の名称
空間を表現するために「4x4行列」が使われるのは、ARKit でも SceneKit でも同じですが、そのデータ型の名称が異なるようです。
worldTransform プロパティ
simd_float4x4
型。
この型のオブジェクトは、ARKit ではヒットテストの結果である ARHitTestResult のプロパティとして含まれている。
smid_float4x4 型
Float
型の値を含んでいる4行4列の行列です。
simd とは、Single Instruction / Multiple Data の略で、「1つの命令を複数の値に対して実行できる」という利点があるようです。
struct simd_float4x4
「4行4列の行列」を表現するデータ型では、この simd_float4x4
が最もプリミティブなようです。
matrix_float4x4 型
ARKit のカメラの空間情報は matrix_float4x4
型で表現される。
typealias matrix_float4x4 = simd_float4x4
定義を見ると、simd_float4x4
型のタイプエイリアス(別名称)になっています。
SCNMatrix4 型
構造体。
SceneKit の空間(シーン)に配置されるノードの空間情報は SCNMatrix4
型で表現される。
つまり、ノードの transform
プロパティは SCNMatrix4
型オブジェクトです。
ARKit の現実空間において、ノードを追加したい場合は
struct SCNMatrix4
行列に含まれる値は、それぞれ...
m11, m12, m13, m14
m21, m22, m23, m24
m31, m32, m33, m34
m41, m42, m43, m44
をドットシンタックスで参照できます。
例えば、「3行4列目の値」にアクセスしたいなら .m34
と記述します。
#データ型を変換する
例えば、ノードをカメラと同じ空間情報(transform
プロパティ)に配置したいとします。
このとき、以下の点を留意しておく必要があります。
- ノードの
transform
プロパティは、SCNMatrix
型 - カメラの
transform
プロパティは、matrix_float4x4
型
この違いを吸収するには SCNMatrix
型イニシャライザを使って、カメラ空間情報と同じ値の SCNMatrix
オブジェクトを生成します。
let cameraTransform = SCNMatrix4(currentFrame.camera.transform)
node.transform = cameraTransform
#まとめ
何故、行列を表現するデータ型がこんなにたくさんあるのか?
4x4行列には、他にどんな値が含まれているのか?
いつか、名称が統一されるのか?
...など、混乱と不思議はつきませんが、現時点で自分が理解できるところをまとめておきました。
皆様からご指摘や助言等いただけると、とても嬉しいです。