静岡県の点群データをUnityで表示してOculus Questで見る

#はじめに
静岡県が蓄積・公開している3次元点群データをUnityで表示してVRで中に入ってみよう、という試みの忘備録として。
このやり方だと遠景はきれいだけど近付くと見えなくなってしまいます。点なので。
また、無料の範囲で、あまり難しいことを考えず、とりあえず表示するだけ表示してみたい…程度の気持ちによるものなので途中でズルをしています。今のところ動いていますが問題があったら教えていただけるとありがたいです。

#環境と使用ソフト
OS：Windows10
Unity：2018.4.10f
点群データ処理：[MeshLab](https://github.com/cnr-isti-vclab/meshlab/releases/tag/v2016.12)、[CloudCompare](http://www.danielgm.net/cc/)
#手順
##Unityでの設定
最初にOculus Questで実行可能なapkファイルを作成するための設定を行います。
若干時間がかかるため、実行中に他の作業を進めるのがいいかと思います。
1. File>Build SettingsをAndroidに設定（switch platform）
2. Edit>Project Settings>XR SettingsのVirtual Reality Supportedにチェックを入れ、リストにOculusを追加
3. Other Settings>Identification>Minimum API Levelを「marshmallow」に設定（KitKatでもいけた）し、Package Nameを適当に設定
4. AssetStoreで「Oculus Integration」をImport（特に時間かかるため他の作業を進める）
5. Assets内のOculus>VR>Prefabsの「OVRPlayerContoroller」をHierarchyにドラッグ＆ドロップし、もとからあったMain Cameraを削除

##静岡県点群DBのデータ（lasデータ）を取得
[静岡県点群DB](https://pointcloud.pref.shizuoka.jp/)にアクセスし、「閲覧・DL」をクリックします。
すると地図が表示されるので、行ってみたい場所のマークアップをクリックします。
クリックすると地図上に赤い四角形が表示されます。これが点群データを取得している範囲です。
赤い四角をクリックするとダウンロードページが表示されるため、「3Dデータ」項目内の「.las」のデータを全てダウンロードします。
今回は「白糸の滝」付近のデータを取得しました。

##lasデータをUnityで読める形に変換
lasデータのままだと読み込めないのでoffデータに変換していきます。
###lasデータをtxtデータに変換
CloudCompareを使用してtxtデータに変換します。
変換のために以下のバッチファイルを用意します。
書きやすさのためCloudCompareのディレクトリを環境変数PATHに設定しています。
また、各ファイルのパスを絶対パスで書いたため一部伏せています。適宜書き換えてください。
（[バッチファイル作成のため参考にした記事](https://note.com/jujunjun110/n/nddc6da415ae9)）

```bat
CloudCompare -SILENT ^
-AUTO_SAVE OFF ^
-O -GLOBAL_SHIFT AUTO "***\Downloads\28XXX00030006-1.las" ^
-O -GLOBAL_SHIFT AUTO "***\Downloads\28XXX00030006-2.las" ^
-O -GLOBAL_SHIFT AUTO "***\Downloads\28XXX00030006-3.las" ^
-O -GLOBAL_SHIFT AUTO "***\Downloads\28XXX00030006-4.las" ^
-DROP_GLOBAL_SHIFT ^
-MERGE_CLOUDS ^
-SS SPATIAL 0.2 ^
-REMOVE_ALL_SFS ^
-C_EXPORT_FMT ASC ^
-PREC 3 ^
-SAVE_CLOUDS FILE "***\shiraito.txt"
```
これを実行すれば
X Y Z R G B
の形でshiraito.txtファイルが作られます。

###txtデータをoffデータに変換
txtファイルをMeshLabで開きます。（Import Mesh）
開く際のオプションでは以下の二つをこのように変更します。
Point format:X Y Z R G B
Separator:SPACE
読み込めたら「Export Mesh As」で「.off」形式を選び、出力します。
ここでは「shiraito.off」とします。

※ここで「Filters」→「Point Set」→「Compute normals for point sets」→「Apply」→もう一度「Flters」→「Remeshing, （略）」→「Surface Reconstruction: Ball Pivoting」→数時間待つ、でメッシュを作成することができますが、off形式で出すとVert（頂点）しか出せないのでこの場では無意味

##Unityで読み込む（ズルするところ）
ここがズルです！！
Point Cloud Free Viewerを使用して点群のPrefabを作ります。
1. 点群Prefab作成用のUnityのプロジェクトを新しく作成します！ここではVR用の特別な設定は要りません。
2. AssetStoreで「Point Cloud Free Viewer」を検索してImport。まずは全部Importします。
3. インポートされたアセット内のPointCloudフォルダに作成したoffファイルを入れます。
4. AssetsのPointCloudの中にある「Example」というSceneを選択します。
5. Hierarchy内のPointCloudManagerを選択し、InspectorのDataPathを書き換えます。PointCloudフォルダ内にshiraito.offがあるはずなので、「/PointCloud/shiraito」とします。
6. Scaleの値を書き換えます。ここでは「1」とします。（デフォルトの「100」だとカスカスになったため）
7. 「Play」を押すとAssets>Resource>PointCloudMeshes内にshiraitoのPrefabが作られます。

※一度Playを押してしまうと、そのあとScaleの値を変更してもPrefabは変わりません。PointCloudMeshes内のPrefabを削除してからPlayを押すと反映されたものが作られます。

##Oculus Questで表示する
ここからはもとのUnityに戻ります。
1. Point Cloud Free ViewerをImportします。ただし、ここではMaterialsとShadersにだけチェックを入れます。
2. 先ほどのUnityプロジェクトの、ResourceフォルダにあるPointCloudMeshesを、こちらのプロジェクトのResourceフォルダにコピペしてきます。
3. Unity画面に戻り、PointCloudMeshes内のshiraitoのPrefabをHierarchyにドラッグ＆ドロップします。このとき角度がおかしければInspectorで角度を編集します。（私の場合X軸が90度回転していたためRotateのXを「-90」としました）
4. apkファイルを作成し、SideQuestでインストールすれば「提供元不明のアプリ」から点群データの景色を見ることができます。
![スクショ画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343311/4c0d0e2e-8751-ca9a-aab4-687dac765839.jpeg)


#最後に
PointCloudをMaterialsとShadersだけ残して消してしまうのは良くないやり方だとは思います…。