Plateau SDK for Unityのざっくり流れを見てみた（メモ）

# 何でこんなことやろうと思ったか
- 自分でDTMしたMVで夜景の街並みを使いたい
    - 国交省が公開しているOpenDataで、日本国の地図データを配布している
    - それをゲームなどに応用出来る様にUnityやUnreal Engine向けのSDKも配布している
    - Plateau SDKはCityGMLを読み込んで動的にメッシュを生成する
    - 生成されたメッシュに動的にテクスチャを張り付ける
    - Shader Graphでマテリアルを微調整している

- SDKが動的に行っている動作に対して、様々なアプローチでオブジェクトの外観を変える事が出来る
    - メッシュのみ流用（スクリプトでテクスチャとマテリアルを全部剥がして再生成）
    - テクスチャのみそっくり差し替えてアニメ調にする→Shador Graghを弄って雰囲気を出す


などなどいろいろあるので、SDKの動きを実際に見ながら一番効率的なアプローチを考えたかった。

SDKはここ（Unity用）
https://project-plateau.github.io/PLATEAU-SDK-for-Unity/

##  PLATEAU SDK：GML → Unityの流れ（全体像）

SDKがCity GMLを読んで、マテリアルを生成するまでの流れを読んでみた
```
CityGML (XML/JSON)  
   ↓  
CityGml.Load()                        ← GMLファイルをパース  
   ↓  
CityModel                             ← 全建物・地物の親コンテナ  
 ├── RootCityObjects[]               ← 建物などのトップレベルCityObject  
 └── GetCityObjectsByType()         ← COT_Building 等でフィルタ  
        ↓  
   CityObject                         ← 建物/道路/橋などの個別オブジェクト  
    ├── Geometries[]                ← 面・体の3D形状  
    ├── Appearances[]              ← テクスチャ・マテリアル情報  
    └── Attributes[]               ← 属性（用途/高さ/住所など）
        ↓  
   Geometry                          ← 建物の形状構造  
    ├── Polygons[]                 ← 面（屋根/壁など）  
    └── TextureTargetDefinitions[]← ポリゴンとテクスチャの対応づけ情報
        ↓  
   TextureTargetDefinition           ← 面と画像（Texture）の対応  
    ├── TargetID                   ← ポリゴンID  
    └── Appearance (Texture)      ← テクスチャ画像とUV情報
        ↓  
   Texture                            ← UnityのTexture2D相当  
    ├── URL                         ← Assets内のファイルパス  
    └── TextureCoordinates         ← UV情報
        ↓  
   UnityEngine:  
   Mesh + UV + Material + Texture2D を生成し、ビルオブジェクトとして配置
```

## 各クラスの役割（ざっくり一覧）
|クラス名|役割|
| - | - |
|CityGml.cs|GMLファイルのエントリポイント。全体読み込み|
|CityModel.cs|全体をまとめる親コンテナ（複数のCityObjectを持つ）|
|CityObject.cs|1つの建物や地物など。GeometryやAppearance、属性を保持|
|Geometry.cs|ポリゴンやUV情報を持つ形状構造|
|Polygon.cs|1つの面（壁や屋根など）を表す|
|LinearRing.cs|ポリゴンの辺を構成する頂点座標群|
|Appearance.cs|テクスチャ/マテリアル（≒MaterialSet）情報|
|AppearanceTarget.cs|ポリゴンとAppearanceの関係づけ（1対多）|
|TextureTargetDefinition.cs|ポリゴンとTextureのマッピング|
|TextureCoordinates.cs|各頂点に対するUV座標を保持|
|Texture.cs|実際の画像（BaseColor / Emission など）|
|Material.cs|Unity的なマテリアル構成（Shaderへの情報）|
|MaterialTargetDefinition.cs|Materialと面の対応（= UnityのMaterial割当）|
|Object.cs|全てのCityObject・FeatureObjectの共通親|
|FeatureObject.cs|Addressや建物属性などの情報ブロック|
|Address.cs|建物の住所情報|
|NativeAttributesMap.cs|GMLの属性名/型のマッピング管理|
|NativeAttributeValue.cs|属性の型と値を表すユニット|
|CitygmlParserParams.cs|GML読み込み時のオプション設定|

## 処理フロー（超ざっくり）
```
1.CityGMLファイルを読み込む
・CityGml.Load() がエントリポイント
・Scriptの中でネイティブDLLに渡してパースされる（高速）
↓
2.CityModel（全体構造）を作成
・すべての地物（CityObject）を保持する親
↓
3.CityObject（建物など）を1つずつ処理
・GML内の属性（高さ・用途・住所）もこの時点で取得
・cityObjectType == COT_Building で建物だけ抽出可
↓
4.各オブジェクトに対応する形状（Geometry）とマテリアル（Appearance）を構成
・面単位でポリゴンを生成
・TextureTargetDefinition 経由でテクスチャを取得
・MaterialTargetDefinition でマテリアルを適用
↓
5.UV座標（TextureCoordinates）と一緒にMesh生成
・頂点に Vector2(U, V) を付与
・テクスチャが正しく貼られる
↓
6.Unity上にGameObjectとして建物が出現
・メッシュ＋マテリアル＋テクスチャを持つ
・ShaderGraph のスロット名（例：_SideMainTexture）にテクスチャが自動でバインドされる
```




以下蛇足
## PLATEAU SDKは結局CityGMLを読み込んで何をやっているのか
- 建物メッシュの生成
- UV展開
- テクスチャの読み込みとマッピング
- ShaderGraphへの割当
- GML属性データの構造化

## メッシュのみ再利用してみた時の画像例
### Plateau SDKでCityGMLを読み込んだ時の画像
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229420/4c5bb783-71dd-46ec-b6d0-6c39aacfa966.png" width="500", height="500">
### マテリアルやテクスチャを全部剥がしてピンク色にしてみた
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229420/a7f86cb7-b434-49cc-9b36-f713b2632b2c.png" width="500", height="500">