何でこんなことやろうと思ったか
-
自分で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属性データの構造化