Apple Watch(+α)のxR開発で使う座標系を調べた

エンジニアの岡村です。

先月、Synamon初のアドベントカレンダー企画を行いました(無事完走!)。その中で自分は仕事で触っていない技術へのチャレンジを行い、ほぼ初めてのSwiftとApple系デバイスを使った開発を行いました。

synamon.hatenablog.com

自分はUnityやDirectX以外の座標系をあまり触ったことがなく、開発の際に座標系に少し戸惑ったので、この記事に軽く調べてみた情報を纏めておきます。

座標系の種類

座標系には大きく分けて右手系と左手系が存在します。それぞれの座標系は、親指をX軸、人差し指をY軸、中指をZ軸とし、各指が90度で直交する形を作り、回転することでその形と一致するかどうかで確かめることができます。これらの座標系が異なる場合、回転により一致させることが出来ず、相互変換する際に座標の解釈を変更する必要があります。

例えば、Unityの座標系は左手系であり、Blenderの座標系は右手系です。BlenderとUnityを使ってコンテンツを作成している方は、いつもこの座標系の違いを乗り越えているんですね。

また、座標系にはどの軸を上方向とするのか(Y-up、Z-up)という基準もあります。しかし、デバイスの座標系を考えたとき、机に置いた状態の上方向と、立てて使用している時の上方向など、その瞬間におけるデバイスの状態によって解釈が異なる為、この基準を簡単に適用することはできません。代わりに、デバイスのどの方向が何軸に対応しているのかを明示しておきます。

Apple系デバイスの座標系

Apple系デバイスのネイティブアプリを開発する際、モーションセンサーの値を取得するにはCoreMotionというフレームワークを利用します。このフレームワーク内において利用されている座標系は右手系となっており、これは公式ドキュメント内のこちらのページで確認することが出来ます。

https://developer.apple.com/documentation/coremotion/getting_processed_device-motion_data/understanding_reference_frames_and_device_attitude

また、この図によると、ディスプレイ正面方向がZ+ディスプレイ上方向がY+となっており、これが画面が付いてるデバイスにおける標準となっているようです。

f:id:Sokuhatiku:20220117181330p:plain:w300

Apple Watch

Apple Watchでも基本的には同じです。ただし、Apple Watchは左右どちらの手首に装着するか、Digital Clownの向きを左右どちらにするかで4通りの装着方法が考えられます。

f:id:Sokuhatiku:20220117191956p:plain:w300

ですが、どの向きでもディスプレイ正面がZ+Digital Clownのある方向がX+となっています。Digital Clownの向きを変えると画面の上下が反転しますが、CoreMotionにおける軸方向は変化しません。つまり左にDigital Clownが来るような状態にした場合、腕を下に下げるとデバイスのY+方向に加速度がかかることになります。

f:id:Sokuhatiku:20220117193118p:plain

ちなみに

今まで画面が付いているデバイスの話をしていましたが、画面がついていないAirPodsもCoreMotionでモーションセンサーの値を取得出来ます。ただし、AirPodsの場合は、回転量の差分のみが取得可能なようです(3DoF)*1。この場合はデバイスの面と軸の対応を考えることは出来ません。

おまけ(Android)

ついでにAndroidにおけるセンサーの座標系も調べてみました。公式情報はこちらのページにあります。 https://developer.android.com/guide/topics/sensors/sensors_overview?hl=ja#sensors-coords

f:id:Sokuhatiku:20220117193512p:plain:w300

座標系はAppleと同様に右手系ディスプレイ正面がZ+ディスプレイ上がY+ となっているようです。

おわりに

基本的にUnity等のゲームエンジンを使っている限り、それ用に用意されたライブラリが座標系を合わせてくれるのが凄く有難いです。しかし、何らかの事情でネイティブ開発をする必要が出てきた場合、座標系の違いは(特にドキュメントが充実していない場合)大変になるでしょう。それに備えて知識だけは持っておきたいと思います。