Unity上でNays2DHの計算結果を3D表示する【開発記録 vol.5】

# はじめに
<font>$\huge{パーティクルむず過ぎワロタ...}$</font>

表題の通り、iRIC Nays2DHの計算結果をUnity上で3D表示できるようにしよう！
という個人的なプロジェクトの開発記録です。

6月中にパーティクルによる流速表示ができるところまで持っていきたいですが、
~~パーティクル？何それ美味しいの？って感じなので~~
先にPLATEAUと仲良くなることにしました。

# 現状の共有
PLATEAUの建物データを一緒に表示することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/9d3aa6ee-e442-9397-0e28-7b8f00afc42e.png)

PLATEAU SDK for Unityがかっこよくて優秀なので
今回は PLATEAU SDKを使ってインポートする手順を説明します。

# PLATEAUとNays2DHを重ねる
## PLATEAU SDK for Unityを入れる
とにもかくにも、PLATEAU SDK for Unityを入れます。
インストールは以下のページの"**PLATEAU Unity SDK の導入**"に
素直に従えばできると思うので、ここでは割愛します。

https://synesthesias.github.io/PLATEAU-SDK-for-Unity/manual/Installation.html

お手持ちのUnityにPLATEAUって表示されていればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/b8f723bf-32b4-5486-c80d-d36350f0281f.png)

## PLATEAUのモデルを読み込む
都市モデルのインポートも基本的にはマニュアルを読めばできますが、
Nays2DHの結果と重ねるためには注意点もあるので説明します。

"PLATEAU SDK"を起動すると、こんなカッコいい画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/91b0bb78-9087-8950-ce17-ac7fb485cd4a.png)

マニュアルでは、ローカルにCityGMLを落としてくる方法を推奨していますが、
容量でかくてめんどくさいし、今回使う札幌はサーバーにあるので
普通にサーバーから取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/c3d66f84-04ff-dc69-61cc-d57d951eef5e.png)

札幌なので、基準座標系を12系にしてから、範囲選択を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/595fa297-99b6-9811-ad6a-3140d2fbab6d.png)

「なんで札幌は12系なの？」って思った人は、以下をご参考くだされ。

https://www.gsi.go.jp/sokuchikijun/jpc.html

予備知識ゼロの場合、上記ページ読んだだけじゃ疑問は解消しないと思うけど
「まあ、日本って地域ごとに19の座標系が用意されてんだな」って
分かっていれば、ここでは良いです。

手順に戻ります。

UnityのSceneビューに地図が表示されたはずなので、
計算対象領域をカバーするようにオレンジの枠を編集して、
決定ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/12e29311-fa0c-15aa-58f5-96887ee16ec1.png)

PLATEAU SDKウィンドウに戻って、インポートする地物の設定を行います。
ここでは、建築物以外の✓は外しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/47105a57-cc65-0e01-379b-bbcd9e2cbc92.png)

最後に基準座標系からのオフセット値の設定がありますが、
**Nays2DHの計算結果と重ねる場合、全て0にしてください。**
（理由は後で説明します）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/65241fb0-acff-b1eb-f483-bc9062c8aa84.png)

あとは「モデルをインポート」を押して、しばらく待ちます。
インポートが終わったら、読み込んだモデルのInspectorを確認して、
Scaleを全て0.1にします。（これも後述します）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/e5c45637-aaf8-c10f-943d-5ec6283460e7.png)

ちなみに、Hierarchy上で読み込んだPLATEAUモデルをダブルクリックすると
モデルの位置までズームしてくれますよ。見ると「すげぇ...」ってなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/986956e1-9cd2-22c3-e90f-5f80fc4c22fb.png)

Nays2DHの結果を読み込んでいる場合、「あれ？重なってないじゃん」ってなりますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/fbe76766-57df-9bd9-a9ef-c07d9fc6c51e.png)

「え？位置合わせするの...？めんどくさ...」っと思った方、安心してください。
**PLATEAUのRotationのYに180を入れるだけでピッタリ重なります。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/56a67ce0-a2cc-fb8f-8870-fdef3ebbdfb7.png)

無事にNays2DHとPLATEAUを重ねて表示することができました。
（不要な建築物は適宜削除してくだされ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/3c8fcb63-64eb-b496-5a29-0d8769db66c7.png)

## 位置合わせについて補足
さて、位置合わせについて、以下の順に説明していきます。
1. なぜ、Scaleを0.1にしたの？
2. なぜ、基準座標系からのオフセット値を0にしたの？
3. なぜ、Y軸周りに180°回転させたら位置がピッタリ合うの？

### Scale=0.1の理由
Nays2DHの結果からOBJファイルを作成した際に、全く説明しませんでしたが
作成したOBJファイルは、**平面直角座標の値に0.1かけて作成しています**。
（つまり、1/10スケールで作ってある）

1/10スケールで作成した理由は、デフォルトのカメラ設定だと
1/1スケールはUnity上で表示されなかったりするからです。

カメラの設定を変えれば、表示できるらしいのですが、
「別に1/10で作っておけばカメラの設定不要で楽じゃん」ということで
私はスケールダウンする方針で行きます。

カメラの設定を変えたい方は、以下が参考になりそうです。
（私は試していませんが）

https://raspberly.hateblo.jp/entry/KusodekaUnityChan

さて、もうお分かりかと思いますが、
PLATEAUのScaleを0.1にした理由は、
**Nays2DHのOBJファイルとスケールを合わせるため**です。

### 基準座標系からのオフセット値
そもそも、基準座標系からのオフセット値ってどういう意味よ？
...ってなりますよね？

<font>$\huge{なりますよね！？（圧}$</font>

前述の通り、PLATEAUのモデルを1/10スケールにする必要があるので
スケールダウンの例で説明します。

PLATEAUモデルをインポートする際に、
始めに入力してある値は、インポート範囲の中心座標です。

これ、何をしたいかというと、モデルの中心に
座標系の原点を設定しようとしているわけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/3f69955e-835a-f87d-fb57-bc54b361d2f0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/79b5190f-1208-be7c-eeef-bc56eae73ce5.png)

ゲーム作ろうとしている時に、大きさ変更すると
全然違う場所にモデルが移動したら嫌ですよね。

そういったクリエイターのことを考えた優しい仕様なのですが、
**Nays2DHのOBJは平面直角座標系の原点と同じ**なので
オフセットするとモデル間で原点のズレが生じてしまいます。

そういった事態を防ぐためにNays2DHと重ねる時は、
オフセット値を全て0にしてインポートしています。

### Y軸周りに180°回転させる
最後にY軸周りに回転させた理由を説明します。

これは、平面直角座標と3Dモデルの座標軸が異なることに起因しています。
説明するより見てもらった方が早いので図で示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/2310451f-23c4-9049-fb9b-c4a9579e4db9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/565ff674-2c2b-7835-1f89-3baa60114e99.png)

図を見たらわかるように、平面直角座標系と3Dモデルの座標系は
どう足掻いても同じ向きにはなりません。
（どんなに頑張っても**右手でフレミング左手の法則は表現できない**のと一緒）

そのため、実物と向きを合わせるためには
**南北反転させる or 東西反転させる**必要があります。

僕がOBJファイルを作る際は南北反転を採用したのですが、
**PLATEAUは東西反転を採用した**のだろうと思います。

その場合、二次元座標でいうところの
(1,1)と(-1,-1)みたいな位置関係なので、
原点周りに180°回転させればピッタリ重なるわけです。

# おわりに
今回はPLATEAUのモデルを重ねる方法について説明しました。
PLATEAU SDK for UnityのUIが本当に格好いいので、
Nays2DHと重ねる予定が無くても一度使ってみて欲しいですね。

あと、タイトル的には余談ですが、
iRIC2BlenderというBlenderのアドオンが開発されています。
iRICの3D可視化に興味がある人はそちらもチェックしてくだされ。

https://i-ric.org/videos/%e3%80%90%e4%ba%88%e5%91%8a%e3%80%91iric2blender/

# （自分用）やりたいことのメモ
- 流速をパーティクルで表示したい
- 水面のシェーダーを流速と合わせたい