2015年7月8日水曜日

Android と Unity の座標系

ども、モーション認識部分を担当している太田です。

meleap では Android + Unity で開発を進めています。端末の位置情報なりを入力として用いてますがこれが一筋縄では行きません。なぜなら、両者で空間座標系の定義が異なるんです。涙
今回はそんな面倒くささをちょこっと紹介しておきます。

【Unity の座標】


上の図は Unity マニュアルから引っ張ってきました。Unity を使ったことのある人からすると、見慣れた座標系ですよね?でもこの座標系、ちょっと違和感感じませんか?上向きに y 軸があるって、3次元座標系として見慣れない感じじゃありません?少なくとも僕は違和感ありまくりで、初見でとても気持ち悪かったです。

この違和感、数学や物理での3次元空間座標の表現と『異なる』からです。
数学や物理はいわゆる「右手系」で「右ねじの法則」からなる座標系を設定することが多いです。対して Untiy では上図のように「左手系」を採用しています。

「だからどうした?それのどこが問題なんだ!」と思われるかもしれません。問題はここからです。
同じく Unity マニュアルから引用しましょう。
モバイルデバイス: 
(中略) 
各軸に沿った加速が重力の値としてハードウェアにより直接報告されます。 値が 1.0 の場合、与えられた軸に対する +1 G の力を示し、-1.0 の値は -1 G を示します。 目の前にデバイスを垂直に持ち(ホームボタンが下)、X 軸は右向きが正の値を示し、 Y 軸は上向きが正の値を示し、Z 軸は自身に向かう向きが正の値を示します。
Unity からもデバイスの加速度センサの値を取得することができます。上記は Input のリファレンスから一部抜粋して引用しました。ここで出てくる3軸の定義は、なんと「右手系」です!つまり、Input.acceleration で得られる値を直接 Unity 内の座標系に適応すると、期待通りには動いてくれません。

これは何も加速度に限ったことではありません。ジャイロに関しても同様のことが言えます。回転方向の定義も「右ねじ」と「左ねじ」で異なるので注意が必要です。

というわけでデバイスからの入力を Unity 内で使うには都合の良い座標変換を入れる必要が有ります。座標変換の一例として下記のサイトを参考にしてください。
http://qiita.com/fuqunaga/items/b1a3e38af71f062f0781
座標変換は一意に決まるものではないので、仕様に合った選択をするようにしましょう。

ではでは今日はこの辺で。。。