自己紹介
sadaと申します
はじめに
HoloLens複数台とか、スマホ複数台とかで同じ場所で同じものを見れるようにしたいですよね?
でもどうするの?
というのを解決するお話です。
まずそもそも
空間の共有を実装する前に知っておかなければならないことがあります。
座標系のお話です。
Unityにおける座標
多分知ってる人多いと思うけど
ワールド座標
空間のどこかを原点にしてその世界のたった一つの原点を決めます。
その座標を元に全てのオブジェクトの位置が決まります。
この座標を元にオブジェクトを配置していくことになります。
ローカル座標
ローカル座標はオブジェクトの位置と向きを基準とした座標系です。
オブジェクトごとに座標があるので一つとは限りません。
原点は親のオブジェクトのワールド座標の位置が原点となります。
また、UnityのインスペクターのTransformはローカル座標系であるので注意!
ARにおける座標
ARKitやHoloLens等の自分が動ける、マーカーレスのAR全般で共通の座標系になっています。
それはアプリを起動した時にワールド座標系が決まります。
まずワールド座標の原点はアプリを起動した時の端末の場所
が原点になります。
また、
Y軸の正の方向は起動時のジャイロで計測した天井の方向
X軸の正の方向はYの正の方向に頭があると仮定したときの右手の方向
Z軸の正の方向はYの正の方向に頭があり、Xの正の方向に右手があると仮定した時の正面の方向
が何も設定を変えない場合の軸の方向となります。
下に向けて起動をした場合、ひっくり返して起動した場合は少し違いますが、
おおよそほとんどの場合自分の体を基準に右がX軸、上がY軸、前がZ軸となります。
ここで大事なのは
起動した場所が原点となるので、原点が端末ごとに違うと言う事です。
空間を共有する際に原点が違うと言うのは致命的な問題です。
例えば次のようにに現実の場所が違うにも関わらずアプリの中のWorld座標が同じになっています。
このような事を解決するためには原点を合わせる必要があります。
どうにかして原点を現実空間上の同じ場所に設定ができればAR空間を共有できます。
原点を合わせるには
おおよそ3つくらい方法がります
その1 起動位置をあわせる
ある意味一番簡単な事です。アプリを起動する位置が原点になるので起動する場所を同じ場所にすれば原点が同じになります。
しかし、わざわざ同じ場所で起動をする必要がある上に起動直後は空間がまだ不安定であるためズレが起こる事が多いです。
その2 マーカートラッキングで行う
ARKit1.5で画像のマーカーを検出してその画像がある場所にオブジェクトを生成ができるようになりました。
また、任意のTransformを与えることによりその場所を原点にすることができるようになりました。
この2つを組み合わせて現実世界のとある場所にあるマーカーを検出すると
その場所をWorld座標の原点にするということができます。
こうすることにより同じアプリを起動して少し離れた場所で起動してもマーカーを検出さえすれば現実空間の同じ場所にオブジェクトが配置できます。
ARKit以外での方法
ある座標を空間の原点にするという機能はARKitでしか使えないのでARCore,HoloLens等ではマーカーから生成されたオブジェクトをすべてのオブジェクトの親オブジェクトにするという方法を使います。
こうすることによってすべてのオブジェクトがマーカーの座標からの相対座標となるので実質的にマーカーの座標がワールド座標の原点となります。
その3 ARWorldMapを使う(ARKit以外にも類似機能あり)
ARkit2.0から追加されたARWorldMapという機能を使うとARKitで取得した空間情報をもとにして位置の共有ができるようになりました。
他の人とだいたい同じような場所で起動すればマーカーも必要なくて楽だと思いますよね?
これを使うためには
- 一度取得した空間情報をサーバ等からもってきてそれを使う
- 空間情報を複数人で送り合う
といったようなことが必要であったりして結構めんどくさい。