HoloToolkit-UnityのSharingの仕組みをできるだけ簡単に理解する

# Sharingへの理解
HoloLensの醍醐味の一つとして複数のHoloLensで空間を共有することができる機能があります。HoloToolKitとして提供される一機能なのです。が、なかなか理解が進まず、いろいろ試している中でようやく基本的な事を理解した(はず)ので備忘録として残しておきます。何かの参考になれば。
## Sharingとは
複数台のHoloLensを同じ仮想空間上（+同じ場所）で同じアプリケーションによる共通の体験ができる仕組みです。sharingに参加している人達は同じ空間を共有し同じ物体が見えるアプリを構築することが可能です。HoloLensはsharing機能が搭載されたアプリを利用することでsharing用のサーバを介して空間の共有を行います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/e9268cc0-e793-6854-a454-a8b71091043a.png)
上図のような構造で実現しています。
## 実際の動き
HoloLensでSharingした際に見える空間は全員で同じものを共有しているわけではないです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/663e5552-8868-6287-94ef-1d91114a58cb.png)
上図の様に目の前にキューブがあっても同じオブジェクトを見ているわけではありません。それぞれのHoloLensでsharingサーバを介して座標の同期を取ることで同じ状況を再現しているといえます。
## 位置合わせの仕組み
### 位置合わせの必要性
sharingは座標を同期することでそれぞれのHoloLensに同じ空間を再現します。ここで一つの問題が発生します。それは、Sharingするアプリケーションが同一の部屋で使う場合です。つまり「現実の空間」、「HoloLens内の空間」両方を共有している場合、「現実の空間」も含めた位置合わせが必要になります。なお、「HoloLens内の空間」のみ共有すればいいだけの場合（例えば遠隔地で利用するようなアプリ）であれば「現実の空間」の位置合わせが不要なためさほど問題視されないと思います。
### 何が困るのか
「現実の空間」、「HoloLens内の空間」両方を共有している場合の位置合わせの重要性ですが、簡単にいえば、位置合わせなしにSharingすると「現実の空間」に対して同じ位置に仮想の物体が見えない状況が発生します。つまり物体がずれるという事象です。極端な例ですが、２人背中合わせにアプリケーションを起動すると位置合わせしていない場合、同じ立方体が図のようにずれた状態で表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/e11ba6a1-46e7-bc01-fbcc-4f97c7129dd8.png)
この場合左側のHoloLensと、右側のHoloLensで全然違う場所にオブジェクトが出ている状態になります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/276c4ac0-a20a-8fc3-cb61-81b151c9d86b.png)
でも実際には上図のようにどの向きに関係なく同じ場所に出す必要があります。

### 位置がずれるのはなぜか
HoloLensで3Dのアプリを起動した場合、アプリ内の空間について起動時点のHoloLensの座標と向いている方向を起点して座標軸(0,0,0)、カメラ角(0,0,0)で処理されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/8f0aada3-7b22-f598-0b00-b567bb1217a7.png)
このため、同じアプリケーションを他の人が起動するとき<font color="OrangeRed">寸分たがわず</font>同じ場所、同じ向きでアプリケーションを起動しない限り「現実の空間」の同じ位置で物体を共有することができません。

### アンカーの共有
さすがに先のような運用は不便ですので、位置合わせのための機能も用意されています。それが<font color="OrangeRed">「アンカーの共有」</font>という仕組みです。アンカーとは船の錨の意味で空間内で絶対的な位置に居座ることができるオブジェクトになります。Sharingの機能を使うことでこのアンカーを各HoloLensで同じ位置に設置することができます。Sharing内のオブジェクトはこのアンカーからの相対座標で表現することで位置合わせを行うことができます。

まず一番初めにアプリを立ち上げた人が基準となるアンカーを設置します（これは手動/自動どちらでもよい）。
以降アプリを立ち上げた人はSharingのアンカーの共有機能を利用してすでに設置されたアンカーを取得し、同じ位置に設置します（設置自体は自動で実施）。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/2b7813ca-a5b0-eea3-a4d1-18f6bddc282e.png)

アンカーの共有後はアプリケーションでオブジェクトの生成や移動をSharingサーバを介して同期化します。
これで空間共有を図っています。


## Sharingがうまくいかない場合とその考察
実はこのSharingを使ったアプリなのですが、うまく起動しないことが結構あります。具体的にはSharingサーバへのアクセスが成功せずに待ち状態になるといったものです。これ自体明確な理由はないのですが、有志が確率をぐっと上げる方法を見つけてくれています。[^1]
[^1]: [お手軽にSharingの接続成功率と精度をあげる(dyama7さん)](http://blog.d-yama7.com/archives/569)

この記事の中にも書かれてはいるのですが、向きがかなり影響しているようです。つまり、<font color="OrangeRed">「アンカーとなる物体を正確に同じ場所に置く」</font>ために<font color="OrangeRed">「HoloLensのカメラの画像に対して何らかの解析を行い同じ場所にアンカーを設置している」</font>ということになります。おそらく全く同じ位置からではなくてもある程度の補正がかけられるようになっていると思われますが、<font color="OrangeRed">おおむね「同じ方向」</font>が正解ではないかという話です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/f5da4006-83f8-2b7c-be09-f85491f439de.png)

図にしてみるとこのような形になるんだと思います。確かに共有している物体の位置を正確に合わせるにはアンカーのずれをどれだけ低減できるかがカギになるので、カメラ画像からの解析というのは合点は行きますが詳細はわからない状態です。

## Sharingのほかの機能
Sharingにはこの他に、オンラインゲームでよくある「部屋」の管理機能やユーザ管理などの機能も提供されています。必要に応じてこれらの機能を利用することも可能です。

## 最後に
概要としてはこのような形なんだと思います。細かい話で行くと補正の話であるとか実際の使い方というのも出てきます。そのあたりはこれからTipsとして蓄積するしかないので何かわかり次第また書きたいと思います。また、Tokyo HoloLensハッカソンで作っていたブロックの生成と消去するシンプルなSharingアプリを通して座標同期などの仕組みについても書きたいと思います。