Immersalのサンプルプロジェクト

#はじめに
Immersalとは一つのARサービスを現実とバーチャルの世界を組み込んで、AR経験を向上させる。Immersalを使って、大きな空間をマップして、そのマップでバーチャル的な物を付けて、みんなに楽しませる。

Immersal
https://immersal.com/

Immersalサンプルプロジェクト
https://github.com/immersal/arcloud-sdk-samples


#準備

* Unity 2019.4
* AR Foundation 4
* ARCoreかARKitをサポートされる携帯デバイス
* [Immersal Developerアカウント](https://developers.immersal.com/)

この記事ではARCoreサポートされたAndroid携帯、Xiaomi Redmi Note 7を利用します。

#プロジェクト設定

GithubプロジェクトのClone
https://github.com/immersal/arcloud-sdk-samples

Immersal SDKを入れる
ImmersalのポータルサイトからImmersal SDKをダウンロードして、プロジェクトに入れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/c61706f7-0814-ea42-1341-b2be9d3ec9cd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/1ddc55a0-ef97-eda9-31f6-25236f862e64.png)

GithubからCloneすれば、ARFoundation, ARCore, ARKitはすでにプロジェクトにいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/24b3a3a3-9afe-6bc8-6f2d-eafe689ac41c.png)

Build設定はデバイスに対応して、変更します。



#サンプルの纏め
Immersal SDKのサンプルはAssets→Immersal SDK→Sample→Scenesであります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/d35e8e1a-a60c-89c2-751a-c5bc800e7422.png)



###Mapping App
MappingAppとは複数の画像から3Dモデルを作成します。MappingAppのシーンをビルドしてください。
アプリを使って、空間をスキャンをします。スキャンする時は、色々の観点から写った方がおすすめです。
明るいところでスキャンしてもおすすめです。

参考
https://immersal.gitbook.io/sdk/tutorials/how-to-map

スキャンが終わりましたら、Submit For Map Constructionボタンを押してください。
ポータルで、マッピングの状況が見られます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/80e9ac46-528c-e18c-875c-067b9819a2bd.png)

アプリからでも処理状況は見れます。まずはモードを変換して、「Download Maps」を押したら、作ったマップの処理状況を表示されます。

<img width="400" alt="tempsnip.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/244661f4-2c16-126f-388d-7c9ab5cd1d43.png">


マッピング結果はポータルから見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/41d82bf6-29de-0e07-371b-b398e41b5844.png)

`.bytes`とはマップファイルです。このファイルはUnityプロジェクトで利用します。
`sparse.ply`とはPoint Cloudのスパース/展開を見える。
`dense.ply`とはベルテクス色のメッシュモデルを見える
`.glb`テクスチャーモデルを見える



参考
https://immersal.gitbook.io/sdk/cloud-service/developer-portal

右の目のボタンを押せば、ウェッブでその結果を見える。下のサンプルでは23枚の画像からロッカーをマップします。少ない画像と多い過ぎて画像の場合はモデルの結果はあまりよくないです。

https://twitter.com/hf_mandak/status/1409818195091886083?s=20

同じ場所で画像の数を比べました。9枚、23枚、と57枚の画像で試した。GLBの結果はこちらになります。

<img width="400" alt="tempsnip.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/ba37079d-e120-964b-fd2b-de8a1061b920.png">

マッピングを完成した後、Point Cloudを空間で表示します。

https://twitter.com/hf_mandak/status/1409821847126827011?s=20

###Content Placement / モデル配置

次は「ContentPlacement」シーンを発行します。その前に、まずは前回作成したマップを「Developer Portal」から、`.bytes`ファイルをダウンロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/1af2f931-3a1c-bae7-6dcc-1bbb41b56039.png)

この`.bytes`ファイルをUnityプロジェクトに入れます。「ContentPlacementSample」シーンを開きます。「AR Space」のオブジェクトの下に全てを無効にします。一個のオブジェクトをコピーします。ARMapのスクリプトで「Map File」に、自分の作成した`.bytes`ファイルを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/bdf76007-ebbe-cc80-786d-77334bda8b14.png)

次、「ContentPlacement」オブジェクトの下に「ContentStorageManager」で、ARSpaceオブジェクトを登録します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/dbcbd117-44b3-574b-9653-9acdf95659a2.png)

その後アプリを発行します。こちらはサンプルのデモ動画です。

https://twitter.com/hf_mandak/status/1409830579223236610?s=20

ContentPlacementサンプルで、マップの対応にして、モデルを直接に配置をしてもできます。こんな風にモデル配置はマップに直接入れました。

https://twitter.com/hf_mandak/status/1409843976731955206?s=20

そのためにOcclusionオブジェクトは必要です。

新しいMaterialを作成して、MaterialのShaderをVR→SpatialMapping→Occlusionに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/c78b0edc-828d-efe7-1cc0-6fa1acceb076.png)

Point Cloudの位置は想像難しいので、「Developer Portal」からglbをダウンロードして、fbxに変換して、Unity Projectに入れます。シーンに入れた後Point Cloudとモデル合わせます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/d1bab12d-6019-d625-936d-d186571cdefd.png)

その後Occlusion Objectを作って、Mesh RendererにOcclusion Materialを入れて、完成です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/b7a1da92-a84a-7c82-b9d6-e7e2158f6d01.png)

で使用したいモデルを入れて発行します。この手順で、竜のモデルをロッカーの裏に隠したいと「HELLO」メッセージをロッカーをぐるぐる周りにしたいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/2ce2deb5-9a34-2813-1fe9-0ed5eb00faa7.png)


###Multimap / 複数のマップ
Multimapとは複数のマップを同時に表示します。このサンプルでオフィスの一部から二つに割れます。左側の赤いボックス「Map A」、右側の黄色のボックスは「Map B」。この二つのボックスから、プリンターのところで（真ん中の緑ボックス）重なっています。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/3b9a2c42-80bb-050a-19cf-73a7b8240a3f.png)

Map Aの場合、22枚画像を取りました。Map Bの場合、19枚画像を取りました。

![image20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/3b2f3512-c837-14b2-3a90-d950c2ead869.png)

前回、ContentPlacementでマップ入れる方法とモデル入れる方法を学びました。が、今回は少し違います。複数のマップを入れたら、Point Cloudの位置はめちゃくちゃ二つのPoint Cloudは全く合わってないです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/d17333e4-5fd2-2854-a686-4e1325e00b81.png)

その場合、Immersalからの複数なヒントを上げます。

1. もしこの二つのマップから合わってるところがあれば、ポータルから自動合わせ「Align Maps」とステッチ「Stitch Maps」。
1. もしこの二つのマップから合わってるところがなかった場合は参考なポイントが知ってるなら、手動で位置あわせができます。
1. 参考的なポイント知らないし、合わせポイントもなかった場合は、この[動画](https://youtu.be/aWlG1NSFvrI)を参考してください。

最初の方法はポータルを開けて、合わせしたいマップを選択して、位置だけを合わせか、モデルもステッチしたいか選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/e8c4593d-851e-be83-193e-321dc8ca234e.png)

ステッチの結果はかなりできました。下の画像はそのステッチの結果です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/aad52152-28f6-b3cb-f4cd-c74e4f5ae32c.png)

2番目の方法は自明です。3番目はマッピングサンプルから複数のマップをダウンロードして、位置合わせます。

https://twitter.com/hf_mandak/status/1412368462589009927?s=20

位置を合わせたら、MultimapSampleシーンを開けて、DeveloperTokenを入れます。DeveloperTokenはポータルから貰う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/5db7f798-1039-a6a4-3cef-6f571f2ee352.png)

終わったら、Immersal SDKからAR Map Downloaderを開けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/cb5a5724-5622-db36-db4a-24b473690e38.png)

AR Space GameObjectをAR Map DownloaderのAR Spaceに入れます。「,」で別れて、Map Idを入れます。下の画像には例として、適当なMap IDを入れました。Map IDはポータルから貰います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/d333d963-23f2-0786-8f65-11c3a654b771.png)


「Download and Setup Maps」を押したら、マップを自動でAR Space GameObjectのしたに入れました。赤いボックスのマークされたところは画像の合わせのところでしょう、それで確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/a99e358e-e9a8-448e-8196-9fff6a54a00e.png)

そのプリンターの位置でOcclusionボックスを作って、モデルを配置にします。その結果は下の映像に上げます。

https://twitter.com/hf_mandak/status/1412382491545980929?s=20

###Map Download Sample / マップダウンロードサンプル
名前通り、マップダウンロードサンプル今まで作ったマップを選択して、ダウンロードして、表示します。MapDownloadSampleシーンを開く、Immersal SDKオブジェクトにポータルから「Developer Token」をいれます。

<img width="400" alt="tempsnip.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/a73a938a-c69f-9624-c437-78a7821a62af.png">

アプリを実行して、起動します。ドロップダウンで今まで作ったマップを選択します。

https://twitter.com/hf_mandak/status/1414885607545851905?s=20


###Navigation Mesh Sample / ナビゲーション

Blenderで間取りを作ってみましょう。このオフィスでは部屋の間取りは単純な矩形な形ですので、作りかたはかなり早いです。ポータルからPoint Cloudマップ ```~sparse.ply``` ファイルをダウンロードしてください。次はBlenderに入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/5f96b954-baf5-4fa2-2d7d-d10b293755f8.png)

Point Cloudのオリエンテーションを修正するためにX Axisで90度回転します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/20c20620-f02e-1cdc-4157-7247cd5af59a.png)

そのあとPoint Cloudを参考にして、Planeを使って、オフィス間取りを作ります。必ずPoint Cloudのフロアーレベルと合わせてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/f706e81c-18c1-9074-d3fe-76f6c554e0b7.png)

間取りオブジェクトだけを選択して、fbxとしてエクスポートしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/34989112-e757-44ea-1c1c-ccf4a30b10cd.png)

このFBXファイルをUnityに入れます。Navigation Sample Meshシーンを開きます。Immersal SDKで「Developer Token」を入れます。AR Spaceの下に「Navigation Target~」以外削除してください。「AR Map Downloader」を使って、マップをダウンロードします。今回は「Load Alignment」のチェックを削除してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/51853527-4cb7-13ad-5b79-678f970d2066.png)

間取りのモデルを「AR Space」の下に入れます。間取りはもうマップと合わせましたので、調整は必要はないです。間取りのモデルをNavigation Layerに移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/36528bdc-2564-ab1d-fe80-c759576727ee.png)

「Generate NavMeshSurface Here」を開きます。その機能は「Include Layer」で選択したLayerから歩行可能な領域を「Bake」ボタンで生成します。歩行可能な領域は青い色のサーフェイスでマークされた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/01bdc6a9-c827-5a63-9641-584b98c7a8d6.png)

けれど、自分のオフィスではテーブル、いす、車いす、と様々な動かないものがたくさんありますので、そのためにはOcclusionが必要です。そこはUnityのゲームオブジェクトとOcclusionシェーダーを使って、解決します。作ったCubeをNavigation Layerに入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/1a19a1df-87a3-9028-7ad6-e79b1a682161.png)


もう一回「Bake」をして、歩行可能な領域はまた生成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/87503edf-ef36-bdcc-8fba-17a2e57e6223.png)


アプリを発行して、試します。

https://twitter.com/hf_mandak/status/1414909931552075779?s=20

###Navigation Graph Sample / ナビゲーション
実行中でナビゲーションを作成することも可能です。NavigationSampleGraphシーンで設定します。まずはいつも通り、ImmersalSDKで「Developer Token」を入れます。AR Map Downloaderでマップをダウンロードします。アプリを発行して、実行します。

まずはターゲットを決めてください。ターゲットを決めたらウェイポイント作成します。ウェイポイントを1秒間押し続けると、移動できます。複数のウェイポイントの位置を決めたら、各ウェイポイントを繋がってください。

https://twitter.com/hf_mandak/status/1414935135103815689?s=20

ナビゲーションを表示したら、ターゲットまで道を表示されます。

https://twitter.com/hf_mandak/status/1414935361256443908?s=20

複数のナビゲーションターゲットもできます。

https://twitter.com/hf_mandak/status/1415649356770799622?s=20

ウェイポイントの繋ぐ方向は編集できないらしいので、ご注意ください。

https://twitter.com/hf_mandak/status/1415650469796454406?s=20

あと、一部のところだけがマップとして登録されたのせいで、ずれてる可能性もあることもご注意ください。

https://twitter.com/hf_mandak/status/1415653688325013508?s=20


###Multiplayer Sample / マルチプレイヤー

編集中

#編集中