diff --git a/Documentation~/manual/ChangeColorByAttrs.md b/Documentation~/manual/ChangeColorByAttrs.md index 965731e84..b83baa398 100644 --- a/Documentation~/manual/ChangeColorByAttrs.md +++ b/Documentation~/manual/ChangeColorByAttrs.md @@ -1,11 +1,17 @@ # 属性情報によって色分けする ![](../resources/manual/changeColorByAttrs/screenShot.png) -このサンプルでは、土地計画決定情報および建物の水害時の想定浸水高に関する属性情報を読み取り、それに応じてランタイムで色を変えます。 +上図は土地計画の区分を色分けするサンプルです。 + +![](../resources/manual/changeColorByAttrs/screenShot2.png) +上図は水害リスクを色分けするサンプルです。 + +このサンプルでは、土地計画決定情報および水害時の想定浸水高に関する属性情報を読み取り、それに応じてランタイムで色を変えます。 ## サンプルを開く このサンプルは次の場所にあります: ```(PLATEAU SDKのサンプルディレクトリ)/AttributesColorSample/AttributesSample.unity``` サンプルシーンを開き、Unityの再生ボタンを押すと地域ごとに色が付きます。 +また、左上のボタンから色分けする区分を変更できます。 なお、実行には時間がかかる場合があります。 属性情報を読み取り、色を変えるスクリプトは次の場所にあります: @@ -17,8 +23,6 @@ 属性情報に応じて色分けするサンプルコード、`AttributesColorSample.cs`の内容は以下のとおりです。 ```csharp -using System.Collections; -using System.Collections.Generic; using PLATEAU.CityInfo; using UnityEngine; @@ -29,7 +33,7 @@ public class AttributesColorSample : MonoBehaviour { /// 色分けしたいターゲットを指定します。 [SerializeField] private Transform targetParent; - private void Start() + private void Awake() { // PLATEAUCityObjectGroupコンポーネントに属性情報が格納されており、ランタイムで読み込むことができます。 var cityObjGroups = targetParent.GetComponentsInChildren(); @@ -50,12 +54,12 @@ public class AttributesColorSample : MonoBehaviour } // 属性情報のうち、水害時の想定浸水高さを取得します。 - if (attributes.TryGetValue("uro:buildingDisasterRiskAttribute", out var disasterRiskAttr)) + if (attributes.TryGetValue("uro:floodingRiskAttribute", out var disasterRiskAttr)) { - if (disasterRiskAttr.AttributesMapValue.TryGetValue("uro:depth", out var depthValue)) + if (disasterRiskAttr.AttributesMapValue.TryGetValue("uro:rank", out var depthValue)) { - var depth = depthValue.DoubleValue; - var color = ColorByDepth(depth); + var rank = depthValue.StringValue; + var color = ColorByFloodingRank(rank); ChangeMaterialByColor(target, color); } } @@ -100,10 +104,23 @@ public class AttributesColorSample : MonoBehaviour return matColor; } - private Color ColorByDepth(double depth) + private Color ColorByFloodingRank(string rank) { - float t = (float)depth / 3f; - return Color.Lerp(Color.blue, Color.red, t); + Color matColor = Color.white; + if (rank == "0.5m未満") + { + matColor = new Color(0f, 0f, 1f); + } + else if (rank == "0.5m以上3m未満") + { + matColor = new Color(1.0f, 1.0f, 0f); + } + else if (rank == "3m以上5m未満") + { + matColor = new Color(1.0f, 0f, 0f); + } + + return matColor; } private void ChangeMaterialByColor(Transform target, Color color) @@ -120,6 +137,7 @@ public class AttributesColorSample : MonoBehaviour } + ``` ### サンプルコード解説 @@ -170,15 +188,15 @@ if (attributes.TryGetValue("urf:function", out var landFuncAttr)) ``` 下は、属性情報が入れ子になっているパターン(バリューがキーバリューセットである)ときに値を取得する例です。 -`uro:buildingDisasterRiskAttribute`をキーとする入れ子で、キー`uro:depth`の値を取得しています。 +`uro:floodingRiskAttribute`をキーとする入れ子で、キー`uro:rank`の値を取得しています。 ```csharp // 属性情報のうち、水害時の想定浸水高さを取得します。 -if (attributes.TryGetValue("uro:buildingDisasterRiskAttribute", out var disasterRiskAttr)) +if (attributes.TryGetValue("uro:floodingRiskAttribute", out var disasterRiskAttr)) { - if (disasterRiskAttr.AttributesMapValue.TryGetValue("uro:depth", out var depthValue)) + if (disasterRiskAttr.AttributesMapValue.TryGetValue("uro:rank", out var depthValue)) { - var depth = depthValue.DoubleValue; // stringをdoubleにパースした値を取得します。 - var color = ColorByDepth(depth); + var rank = depthValue.StringValue; + var color = ColorByFloodingRank(rank); ChangeMaterialByColor(target, color); } } diff --git a/Documentation~/manual/ExportCityModels.md b/Documentation~/manual/ExportCityModels.md index cdcf9e598..841de2777 100644 --- a/Documentation~/manual/ExportCityModels.md +++ b/Documentation~/manual/ExportCityModels.md @@ -99,4 +99,11 @@ Unityのシーンに都市モデルがインポートされていることが前 - 指定のフォルダに3Dモデルファイルが出力されます。 ![](../resources/manual/exportCityModels/tokyoBlender.png) -上図はエクスポートしたobjファイルを Blender で読み込んだものです。 \ No newline at end of file +上図はエクスポートしたobjファイルを Blender で読み込んだものです。 + +>[!NOTE] +> **エクスポートした3Dモデルを再度Unityに取り込む場合** +> +> テクスチャ込みでエクスポートしたものを再度Unityにインポートする場合は、 +> 3Dモデルファイルとそれに対応するテクスチャフォルダを複数選択して +> Unityのプロジェクトビューにドラッグ&ドロップしてインポートしてください。 \ No newline at end of file diff --git a/Documentation~/manual/ImportCityModels.md b/Documentation~/manual/ImportCityModels.md index 70c1472df..449f2839d 100644 --- a/Documentation~/manual/ImportCityModels.md +++ b/Documentation~/manual/ImportCityModels.md @@ -104,8 +104,22 @@ その場合はチェックを外した時と同様にデフォルトマテリアルが適用されます。 - `テクスチャを結合する` - テクスチャを含める場合、テクスチャを結合するかしないかを設定します。 - - PLATEAUのデータはテクスチャの枚数が多い傾向にあり、結合しないと描画負荷が高くなる傾向にあります。 - 結合機能を有効にすると、複数のテクスチャを1枚の画像にまとめ、3DモデルのUVも合わせて調整されます。それによって描画負荷を改善できます。 + +>[!NOTE] +> **テクスチャ結合すると描画負荷が良くなります** +> +> PLATEAUのデータはテクスチャの枚数が多い傾向にあり、 +> 結合しないと描画負荷が高くなる傾向にあります。 +> +> 結合機能を有効にすると、複数のテクスチャを1枚の画像にまとめ、 +> 3DモデルのUVも合わせて調整されます。 +> それによって描画負荷を改善できます。 +> +> 例えば、新宿区の2km×2kmのデータについて +> テクスチャ結合して4096×4096のテクスチャサイズにまとめたとき、 +> ドローコール数は4160から483に向上し、 +> あるPCではFPSが70から90に向上しました。 + - `テクスチャ解像度` - テクスチャを結合する場合の、結合後のテクスチャの大きさを指定します。 - `Mesh Collider をセットする` @@ -242,46 +256,6 @@ このインスペクタから緯度、経度などの情報を確認できます。 ![](../resources/manual/importCityModels/InstancedCityModelInspector.png) -### デフォルトマテリアルの見た目を変えたいとき -PLATEAU SDKでは地物タイプごとにデフォルトマテリアルが用意されています。 -例えば、下図の建物には建築物のデフォルトマテリアルが適用されています。 -![](../resources/manual/importCityModels/defaultBuilding.png) -このマテリアルは独自のPlateauTriplanarシェーダーを利用しているため、UVのない地物にもテクスチャを投影できます。 -PLATEAUのモデルにはUVが**ない**場合があります。 -そのため、ご自分で見た目をカスタマイズする場合でも、SDK付属のPlateauTriplanarシェーダー、またはそれと同様のTriplanar機能を有したシェーダーを利用することを推奨します。 -以下に同シェーダーを使ったマテリアルの作成方法を説明します。 -#### SDK付属のシェーダーについて -PLATEAU SDKには以下の3つのシェーダーが付属しています。 -どれもUVなしでテクスチャを投影できるのが特徴です。 -- `PlateauTriplanarShader(Opaque)` - - 通常のTriplanarシェーダーです。 -- `PlateauTriplanarShader(Transparent)` - - 半透明なTriplanarシェーダーです。 -- `PlateauTriplanarShader(DualTextures)` - - 上下を向いた面と横を向いた面で異なる見た目を表現するTriplanarシェーダーです。 - - 利用例:建築物の上を向いた面をコンクリートの屋根に、側面を窓付きの壁にしたい場合などに利用できます。 - -このシェーダーを使ってマテリアルを作成する手順は次のとおりです: -- 新しいマテリアルを新規作成し、そのシェーダーを PlateauTriplanarShader/PlateauTriplanarShader(Opaque, Transparent, DualTexturesのいずれか)にします。 -- マテリアルにテクスチャを割り当て、設定します。設定項目は次のとおりです: - - `MainTexture` : メインのテクスチャです。 - - `NormalMap` : ノーマルマップです。 - - `NormalMapStrength` : ノーマルマップの強さです。 - - `Tiling` : テクスチャをタイリングさせる大きさです。 - - `Blend` : ポリゴンの向きに応じてテクスチャをブレンドさせる程度です。 - - `Metallic` : メタリック(金属感の強さ)です。 - - `MetallicTexture` : メタリックを表現するテクスチャです。 - - `Roughness` : ラフネス(ざらざら感の強さ)です。 - - `RoughnessTexture` : ラフネスを表現する強さです。 - - `AmbientOcclusion` : アンビエントオクルージョン(環境光の影響を受ける程度)です。 - - `AmbientOcclusionTex` : アンビエントオクルージョンを表現するテクスチャです。 - - `EmissionColor` : エミッション(発光)の色です。 - - `EmissionTexture` : エミッションを表現するテクスチャです。 - - `Opacity`(Transparentシェーダーのみ) : 不透明度です。 - - DualTextureシェーダーでは、上記の設定値がそれぞれ`Top`と`Side`の2つに分かれます。Topは上下面、Sideは側面の見た目を設定します。 - -- 自作したマテリアルは、インポート後にドラッグ&ドロップ等で適用できるほか、インポートの設定項目として「デフォルトマテリアル」に指定できます。 ### エラーログの確認 diff --git a/Documentation~/manual/ModelAdjust.md b/Documentation~/manual/ModelAdjust.md index b734d3ab9..27f00f46c 100644 --- a/Documentation~/manual/ModelAdjust.md +++ b/Documentation~/manual/ModelAdjust.md @@ -6,6 +6,8 @@ PLATEAUウィンドウの`モデル修正`では、インポートした都市 次の機能があります。 - ゲームオブジェクトON/OFF - 条件指定で一括でアクティブ化・非アクティブ化します。 +- マテリアル分け + - 地物型に応じてマテリアルを分けます。 - 結合・分離 - モデルを結合・分離し、ゲームオブジェクトの粒度を変更します。 @@ -35,6 +37,26 @@ PLATEAUウィンドウの`モデル修正`では、インポートした都市 > 分類指定のチェックマークは入れ子構造になっていますが、第1階層の「建築物」「道路」といった分類は結合単位によらず必ず動作し、 > 第2階層の「窓」「屋根面」といった細かい分類はインポート時に「最小値物単位」にした場合のみ動作します。 +## マテリアル分け機能 +![](../resources/manual/cityAdjust/materialByType.png) +### できること +- 地物型に応じてマテリアルを設定できます。 +- 例えば上図は、建築物の屋根面を緑色のマテリアルに設定した例です。 + +### 操作方法 +- `選択オブジェクト`には、現在選択中のゲームオブジェクトが表示されます。これが処理の対象になります。複数選択可能です。 + - 対象は、コンポーネント`PLATEAUCityObjectGroup`が付与されているゲームオブジェクト、またはその親である必要があります。 + - 対象に`PLATEAUCityObjectGroup`がない場合、インポート時に属性情報を含める設定にしたことを確認してください。 +- `マテリアル分類`には`地物型`と表示され、地物型に応じてマテリアルを張り替えることを示しています。 + - 今は地物型しか選べませんが、今後は属性情報で分けるモードも追加予定です。 +- `検索`ボタンを押すと、選択対象に含まれる地物型が検索され、ボタン下に列挙されます。 + - このあとで対象オブジェクトを変更したい場合は、`再選択`ボタンを押します。 +- `粒度`では、処理後に3Dモデルがどの粒度でゲームオブジェクトに分けられるかを選択します。 +- 処理前のゲームオブジェクトを削除するか、残すかを選択します。 +- 地物型ごとにマテリアルを選択します。 + - 画面には、選択した地物に含まれる地物型が列挙されています。 + - それぞれの地物型について、マテリアルを変更するか、変更する場合はどのマテリアルにするかを指定します。 +- 実行ボタンを押すと、処理を実行します。 ## 結合/分離機能 ![](../resources/manual/cityAdjust/splitCombineWindow.png) diff --git a/Documentation~/manual/runtimeAPI.md b/Documentation~/manual/runtimeAPI.md new file mode 100644 index 000000000..dfffc0890 --- /dev/null +++ b/Documentation~/manual/runtimeAPI.md @@ -0,0 +1,118 @@ +# ランタイムAPI + +このページでは、PLATEAU SDKの機能をUnityエディタ内だけでなくランタイム(実行時)にも利用するための方法を説明します。 + +## APIサンプルの実行方法 + +ランタイムAPIのサンプルシーンを次の方法で開いて実行できます。 +- Package ManagerからPLATEAU SDKのサンプルをインポートします。 +- `Assets/Samples/PLATEAU SDK for Unity/(バージョン)/PLATEAU Samples/APISample/RuntimeSample` のシーンを開きます + +![](../resources/manual/runtimeAPI/runtimeSample.png) + +- 事前に東京都23区のPLATEAUデータをダウンロードしておきます。 +- サンプルシーンを再生し、「インポート実行」ボタンの上にある入力欄にダウンロードしたフォルダのパスを入力してインポート実行します。 +- しばらく待つと、シーン中に都市モデルが表示されます。 +- 都市モデルがインポートされた状態で、エクスポートと分割結合を試すことができます。 +- エクスポートするには、入力欄にエクスポート先のフォルダパスを入力してからエクスポート実行します。 +- 分割結合すると、見た目は変わりませんが、ゲームオブジェクトの粒度が主要地物単位から地域単位に変わっていることをインスペクタから確認できます。 + +## サンプルコードの解説 +サンプルコードは次の場所にあります。 +`Assets/Samples/PLATEAU SDK for Unity/(バージョン)/PLATEAU Samples/APISample/RuntimeAPISample.cs` + +以下にそのコードを解説します。 + +### インポート +```csharp +/// +/// ランタイムでインポートするコードです。 +/// +public async void Import() +{ + // インポートのパスをUnityのテキストフィールドから取得します。 + string importPath = importPathInputField.text; + // PLATEAUのデータセットの場所をセットします。 + var datasetConf = new DatasetSourceConfigLocal(importPath); + // インポート対象のメッシュコード(範囲)を指定します。文字列形式の番号の配列からMeshCodeListを生成できます。 + var meshCodesStr = new string[] { "53393652" }; + var meshCodeList = MeshCodeList.CreateFromMeshCodesStr(meshCodesStr); + // データセットやメッシュコードから、インポート設定を生成します。 + var conf = CityImportConfig.CreateWithAreaSelectResult( + new AreaSelectResult(new ConfigBeforeAreaSelect(datasetConf, 9), meshCodeList)); + // ここでconfを編集することも可能ですが、このサンプルではデフォルトでインポートします。 + await CityImporter.ImportAsync(conf, null, null); +} +``` +インポート処理は`await CityImporter.ImportAsync(conf, null, null);`で実行できます。 +ここでconfはインポート設定となります。 +インポート設定`conf`のうち、最低限指定が必要となる項目は次の通りです。 +- データ一式がどこにあるのか(`DatasetSourceConfigLocal`) +- 座標系の番号は何か(上のサンプルでは`9`としています) +- インポート対象のメッシュコード(範囲、`MeshCodeList`)はどこか + +したがって、上のサンプルでは`DatasetSourceConfigLocal`, `MeshCodeList`のインスタンスを設定しています。 +他にも`conf`には、地物別の設定など、エディタのGUIで設定可能な項目が含まれています。 +このサンプルではそれらの値はデフォルトのままとしています。 + +### エクスポート +```csharp +/// +/// ラインタイムでエクスポートするコードです。 +/// +public void Export() +{ + // 前提条件: + // 実行するには、ターゲットのstatic batchingをオフにする必要があります。 + // そのためにはstaticのチェックをインスペクタから外します。 + + // エクスポート先をUnityのテキストフィールドから取得します。 + string exportDir = exportPathInputField.text; + // エクスポート設定です。 + var option = new MeshExportOptions(MeshExportOptions.MeshTransformType.Local, true, false, + MeshFileFormat.FBX, CoordinateSystem.ENU, new CityExporterFbx()); + // 都市モデルを取得します。 + var target = FindObjectOfType(); + if (target == null) + { + Debug.LogError("都市モデルが見つかりませんでした。"); + return; + } + // エクスポートします。 + UnityModelExporter.Export(exportDir, target, option); +} +``` +エクスポート処理は `UnityModelExporter.Export(exportDir, target, option)` でできます。 +ここで`exportDir`はエクスポート先のパス、`target`はエクスポートする都市モデル、`option`がエクスポートに関する設定値です。 +`option`こと`MeshExportOptions`には座標変換、ファイル形式、座標軸の向きが含まれます。 +`new MeshExportOptions()`の最後の引数には、ファイル形式に対応したExporterのインスタンスを渡します。 +`new CityExporterXXX` (XXXはファイル形式) と書けば大丈夫です。 + +### 分割結合 +```csharp +/// +/// ランタイムで結合分割(ゲームオブジェクトの粒度の変更)をするコードです。 +/// +public async void GranularityConvert() +{ + // 都市オブジェクトを取得します。 + var target = FindObjectOfType(); + if (target == null) + { + Debug.LogError("都市モデルが見つかりませんでした。"); + return; + } + + // 分割結合の設定です。 + var conf = new GranularityConvertOptionUnity(new GranularityConvertOption(MeshGranularity.PerCityModelArea, 1), + new[] { target.gameObject }, true); + // 分割結合します。 + await new CityGranularityConverter().ConvertAsync(conf); +} +``` +オブジェクトを分割結合し、粒度を変更します。 +`await new CityGranularityConverter().ConvertAsync(conf)` で実行できます。 +ここで`conf`は分割結合の設定であり、次のように設定できます。 +`new GranularityConvertOptionUnity(new GranularityConvertOption(ここに粒度を入れる, 1), +ここに変換対象の配列を入れる, 元のオブジェクトを消すならtrueで残すならfalse);` +なお`new GranularityConvertOption`の2つ目の引数である`1`は、未実装の設定項目のためどの数値をいれても動作に影響しません。 \ No newline at end of file diff --git a/Documentation~/manual/sdkMaterial.md b/Documentation~/manual/sdkMaterial.md new file mode 100644 index 000000000..b50936fae --- /dev/null +++ b/Documentation~/manual/sdkMaterial.md @@ -0,0 +1,43 @@ +# PLATEAU SDKのマテリアルについて + +## デフォルトマテリアルの見た目を変えたいとき +PLATEAU SDKでは地物タイプごとにデフォルトマテリアルが用意されています。 +例えば、下図の建物には建築物のデフォルトマテリアルが適用されています。 +![](../resources/manual/importCityModels/defaultBuilding.png) +このマテリアルは独自のPlateauTriplanarシェーダーを利用しているため、UVのない地物にもテクスチャを投影できます。 +PLATEAUのモデルにはUVが**ない**場合があります。 +そのため、ご自分で見た目をカスタマイズする場合でも、SDK付属のPlateauTriplanarシェーダー、またはそれと同様のTriplanar機能を有したシェーダーを利用することを推奨します。 +以下に同シェーダーを使ったマテリアルの作成方法を説明します。 +### SDK付属のシェーダーについて +PLATEAU SDKには以下の3つのシェーダーが付属しています。 +どれもUVなしでテクスチャを投影できるのが特徴です。 +- `PlateauTriplanarShader(Opaque)` + - 通常のTriplanarシェーダーです。 +- `PlateauTriplanarShader(Transparent)` + - 半透明なTriplanarシェーダーです。 +- `PlateauTriplanarShader(DualTextures)` + - 上下を向いた面と横を向いた面で異なる見た目を表現するTriplanarシェーダーです。 + - 利用例:建築物の上を向いた面をコンクリートの屋根に、側面を窓付きの壁にしたい場合などに利用できます。 + +### マテリアルの作り方 +このシェーダーを使ってマテリアルを作成する手順は次のとおりです: +- 新しいマテリアルを新規作成し、そのシェーダーを PlateauTriplanarShader/PlateauTriplanarShader(Opaque, Transparent, DualTexturesのいずれか)にします。 +- マテリアルにテクスチャを割り当て、設定します。設定項目は次のとおりです: + - `MainTexture` : メインのテクスチャです。 + - `NormalMap` : ノーマルマップです。 + - `NormalMapStrength` : ノーマルマップの強さです。 + - `Tiling` : テクスチャをタイリングさせる大きさです。 + - `Blend` : ポリゴンの向きに応じてテクスチャをブレンドさせる程度です。 + - `Metallic` : メタリック(金属感の強さ)です。 + - `MetallicTexture` : メタリックを表現するテクスチャです。 + - `Roughness` : ラフネス(ざらざら感の強さ)です。 + - `RoughnessTexture` : ラフネスを表現する強さです。 + - `AmbientOcclusion` : アンビエントオクルージョン(環境光の影響を受ける程度)です。 + - `AmbientOcclusionTex` : アンビエントオクルージョンを表現するテクスチャです。 + - `EmissionColor` : エミッション(発光)の色です。 + - `EmissionTexture` : エミッションを表現するテクスチャです。 + - `Opacity`(Transparentシェーダーのみ) : 不透明度です。 + + DualTextureシェーダーでは、上記の設定値がそれぞれ`Top`と`Side`の2つに分かれます。Topは上下面、Sideは側面の見た目を設定します。 + +- 自作したマテリアルは、インポート後にドラッグ&ドロップ等で適用できるほか、インポートの設定項目として「デフォルトマテリアル」に指定できます。 \ No newline at end of file diff --git a/Documentation~/manual/toc.yml b/Documentation~/manual/toc.yml index 1375458dc..7cc65c2e8 100644 --- a/Documentation~/manual/toc.yml +++ b/Documentation~/manual/toc.yml @@ -12,9 +12,15 @@ href: ModelAdjust.md - name: 都市情報へのアクセス href: AccessCityObject.md + - name: SDKのマテリアルについて + href: sdkMaterial.md - name: チュートリアル items: - name: 属性情報によって色分けする href: ChangeColorByAttrs.md - name: 属性情報を表示する - href: DisplayAttrs.md \ No newline at end of file + href: DisplayAttrs.md +- name: API + items: + - name: ランタイムAPI + href: runtimeAPI.md \ No newline at end of file diff --git a/Documentation~/resources/manual/changeColorByAttrs/screenShot.png b/Documentation~/resources/manual/changeColorByAttrs/screenShot.png index 046122f8d..fb54cf789 100644 Binary files a/Documentation~/resources/manual/changeColorByAttrs/screenShot.png and b/Documentation~/resources/manual/changeColorByAttrs/screenShot.png differ diff --git a/Documentation~/resources/manual/changeColorByAttrs/screenShot2.png b/Documentation~/resources/manual/changeColorByAttrs/screenShot2.png new file mode 100644 index 000000000..63733be3c Binary files /dev/null and b/Documentation~/resources/manual/changeColorByAttrs/screenShot2.png differ diff --git a/Documentation~/resources/manual/cityAdjust/materialByType.png b/Documentation~/resources/manual/cityAdjust/materialByType.png new file mode 100644 index 000000000..9902874e5 Binary files /dev/null and b/Documentation~/resources/manual/cityAdjust/materialByType.png differ diff --git a/Documentation~/resources/manual/runtimeAPI.meta b/Documentation~/resources/manual/runtimeAPI.meta new file mode 100644 index 000000000..b9dc05d4f --- /dev/null +++ b/Documentation~/resources/manual/runtimeAPI.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1111a21fc6aa4196984791cd928202d2 +timeCreated: 1702635143 \ No newline at end of file diff --git a/Documentation~/resources/manual/runtimeAPI/runtimeSample.png b/Documentation~/resources/manual/runtimeAPI/runtimeSample.png new file mode 100644 index 000000000..03f6bcde1 Binary files /dev/null and b/Documentation~/resources/manual/runtimeAPI/runtimeSample.png differ diff --git a/Editor/CityExport.meta b/Editor/CityExport.meta deleted file mode 100644 index 393b998b5..000000000 --- a/Editor/CityExport.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2694c0bf02b84352b40697ddc0112947 -timeCreated: 1666237768 \ No newline at end of file diff --git a/Editor/CityImport/AreaSelector/AreaSelectorStarter.cs b/Editor/CityImport/AreaSelector/AreaSelectorStarter.cs index 423a9ca33..a04be5170 100644 --- a/Editor/CityImport/AreaSelector/AreaSelectorStarter.cs +++ b/Editor/CityImport/AreaSelector/AreaSelectorStarter.cs @@ -1,4 +1,5 @@ using PLATEAU.CityImport.AreaSelector; +using PLATEAU.CityImport.Config; using PLATEAU.Dataset; using PLATEAU.Editor.EditorWindow.PlateauWindow; using PLATEAU.Util; @@ -24,7 +25,7 @@ internal static class AreaSelectorStarter /// 範囲選択の専用シーンを立ち上げます。 /// ただし、現在のシーンに変更があれば保存するかどうかユーザーに尋ね、キャンセルが選択されたならば中止します。 /// - public static void Start(DatasetSourceConfig datasetSourceConfig, IAreaSelectResultReceiver areaSelectResultReceiver, int coordinateZoneID) + public static void Start(ConfigBeforeAreaSelect confBeforeAreaSelect, IAreaSelectResultReceiver areaSelectResultReceiver) { if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) { @@ -48,7 +49,7 @@ public static void Start(DatasetSourceConfig datasetSourceConfig, IAreaSelectRes SetUpTemporaryScene(); var behaviour = Object.FindObjectOfType(); - behaviour.Init(prevScenePath, datasetSourceConfig, areaSelectResultReceiver, coordinateZoneID, UnityEditor.EditorWindow.GetWindow()); + behaviour.Init(prevScenePath, confBeforeAreaSelect, areaSelectResultReceiver, UnityEditor.EditorWindow.GetWindow()); } private static void SetUpTemporaryScene() diff --git a/Editor/CityImport/CityLoadConfigGUI.cs b/Editor/CityImport/CityImportConfigGUI.cs similarity index 50% rename from Editor/CityImport/CityLoadConfigGUI.cs rename to Editor/CityImport/CityImportConfigGUI.cs index a9e95d068..54330232d 100644 --- a/Editor/CityImport/CityLoadConfigGUI.cs +++ b/Editor/CityImport/CityImportConfigGUI.cs @@ -1,32 +1,32 @@ using System; using PLATEAU.CityImport.Config; -using PLATEAU.CityImport.Config.PackageLoadConfigs; -using PLATEAU.Editor.CityImport.PackageLoadConfigGUIs; -using PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Components; +using PLATEAU.CityImport.Config.PackageImportConfigs; +using PLATEAU.Editor.CityImport.PackageImportConfigGUIs; +using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components; using PLATEAU.Editor.EditorWindow.Common; namespace PLATEAU.Editor.CityImport { /// - /// を設定するGUIです。 + /// を設定するGUIです。 /// - internal class CityLoadConfigGUI + internal class CityImportConfigGUI { private readonly IEditorDrawable[] guiComponents; - public CityLoadConfigGUI(CityLoadConfig cityLoadConf, PackageToLodDict availablePackageLodsArg) + public CityImportConfigGUI(CityImportConfig cityImportConf, PackageToLodDict availablePackageLodsArg) { - if(cityLoadConf == null) throw new ArgumentNullException(nameof(cityLoadConf)); + if(cityImportConf == null) throw new ArgumentNullException(nameof(cityImportConf)); // パッケージ種ごとの設定GUI、その下に基準座標設定GUIが表示されるようにGUIコンポーネントを置きます。 guiComponents = new IEditorDrawable[] { - new PackageLoadConfigGUIList(availablePackageLodsArg, cityLoadConf), - new PositionConfGUI(cityLoadConf) + new PackageImportConfigGUIList(availablePackageLodsArg, cityImportConf), + new PositionConfGUI(cityImportConf) }; } /// - /// を設定するGUIを描画します。 + /// を設定するGUIを描画します。 /// public void Draw() { diff --git a/Editor/CityImport/CityLoadConfigGUI.cs.meta b/Editor/CityImport/CityImportConfigGUI.cs.meta similarity index 100% rename from Editor/CityImport/CityLoadConfigGUI.cs.meta rename to Editor/CityImport/CityImportConfigGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs.meta b/Editor/CityImport/PackageImportConfigGUIs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs.meta rename to Editor/CityImport/PackageImportConfigGUIs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Components.meta b/Editor/CityImport/PackageImportConfigGUIs/Components.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Components.meta rename to Editor/CityImport/PackageImportConfigGUIs/Components.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Components/FallbackMaterialGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Components/FallbackMaterialGUI.cs similarity index 59% rename from Editor/CityImport/PackageLoadConfigGUIs/Components/FallbackMaterialGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/Components/FallbackMaterialGUI.cs index 1b344ea43..5eb81b88b 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/Components/FallbackMaterialGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Components/FallbackMaterialGUI.cs @@ -1,15 +1,15 @@ -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using UnityEditor; using UnityEngine; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Components +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components { /// /// デフォルトマテリアルの設定GUIです。 /// - internal class FallbackMaterialGUI : PackageLoadConfigGUIComponent + internal class FallbackMaterialGUI : PackageImportConfigGUIComponent { - public FallbackMaterialGUI(PackageLoadConfig conf) : base(conf) + public FallbackMaterialGUI(PackageImportConfig conf) : base(conf) { } diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Components/FallbackMaterialGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Components/FallbackMaterialGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Components/FallbackMaterialGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Components/FallbackMaterialGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Components/LodGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Components/LodGUI.cs similarity index 74% rename from Editor/CityImport/PackageLoadConfigGUIs/Components/LodGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/Components/LodGUI.cs index 3566338bf..45b89bb6b 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/Components/LodGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Components/LodGUI.cs @@ -1,16 +1,16 @@ using System; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; using PLATEAU.Editor.EditorWindow.Common; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Components +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components { /// /// LOD範囲の設定GUIです。 /// - internal class LodGUI : PackageLoadConfigGUIComponent + internal class LodGUI : PackageImportConfigGUIComponent { - public LodGUI(PackageLoadConfig conf) : base(conf) + public LodGUI(PackageImportConfig conf) : base(conf) { } diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Components/LodGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Components/LodGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Components/LodGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Components/LodGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Components/MapZoomLevelSelectGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Components/MapZoomLevelSelectGUI.cs similarity index 94% rename from Editor/CityImport/PackageLoadConfigGUIs/Components/MapZoomLevelSelectGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/Components/MapZoomLevelSelectGUI.cs index fd7c4d78c..a0c636a9c 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/Components/MapZoomLevelSelectGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Components/MapZoomLevelSelectGUI.cs @@ -8,19 +8,19 @@ using PLATEAU.Util; using UnityEditor; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Components +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components { /// /// 地図タイルのズームレベルを選択するGUIです。 /// internal class MapZoomLevelSelectGUI : IEditorDrawable { - private readonly ReliefLoadConfig config; + private readonly ReliefImportConfig config; private bool zoomLevelSearchButtonPushed; private readonly GeoCoordinate geoCoord; private MapZoomLevelSearchResult zoomLevelSearchResult = new MapZoomLevelSearchResult{AvailableZoomLevelMax = -1, AvailableZoomLevelMin = -1, IsValid = false}; private string mapTileUrl; - public MapZoomLevelSelectGUI(ReliefLoadConfig conf, string mapTileUrl, MeshCode firstMeshCode) + public MapZoomLevelSelectGUI(ReliefImportConfig conf, string mapTileUrl, MeshCode firstMeshCode) { config = conf; geoCoord = firstMeshCode.Extent.Center; @@ -57,8 +57,8 @@ public void Draw() else { zoomLevel = EditorGUILayout.IntField("ズームレベル", config.MapTileZoomLevel); - zoomLevel = Math.Min(zoomLevel, ReliefLoadConfig.MaxZoomLevel); - zoomLevel = Math.Max(zoomLevel, ReliefLoadConfig.MinZoomLevel); + zoomLevel = Math.Min(zoomLevel, ReliefImportConfig.MaxZoomLevel); + zoomLevel = Math.Max(zoomLevel, ReliefImportConfig.MinZoomLevel); } config.MapTileZoomLevel = zoomLevel; diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Components/MapZoomLevelSelectGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Components/MapZoomLevelSelectGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Components/MapZoomLevelSelectGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Components/MapZoomLevelSelectGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Components/PositionConfGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Components/PositionConfGUI.cs similarity index 79% rename from Editor/CityImport/PackageLoadConfigGUIs/Components/PositionConfGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/Components/PositionConfGUI.cs index 84519e29e..3d0200493 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/Components/PositionConfGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Components/PositionConfGUI.cs @@ -3,15 +3,15 @@ using UnityEditor; using UnityEngine; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Components +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components { /// /// インポートの基準座標を選択するGUIです。 /// internal class PositionConfGUI : IEditorDrawable { - private readonly CityLoadConfig conf; - public PositionConfGUI(CityLoadConfig conf) + private readonly CityImportConfig conf; + public PositionConfGUI(CityImportConfig conf) { this.conf = conf; } @@ -24,16 +24,16 @@ public void Draw() using (PlateauEditorStyle.VerticalScopeLevel1()) { - var refPoint = conf.ReferencePoint; PlateauEditorStyle.CenterAlignHorizontal(() => { if (PlateauEditorStyle.MiniButton("範囲の中心点を入力", 140)) { GUI.FocusControl(""); - refPoint = conf.SetReferencePointToExtentCenter(); + var extentCenter = conf.AreaMeshCodes.ExtentCenter(conf.ConfBeforeAreaSelect.CoordinateZoneID); + conf.ReferencePoint = extentCenter; } }); - + var refPoint = conf.ReferencePoint; refPoint.X = EditorGUILayout.DoubleField("X (東が正方向)", refPoint.X); refPoint.Y = EditorGUILayout.DoubleField("Y (高さ)", refPoint.Y); refPoint.Z = EditorGUILayout.DoubleField("Z (北が正方向)", refPoint.Z); diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Components/PositionConfGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Components/PositionConfGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Components/PositionConfGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Components/PositionConfGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables.meta b/Editor/CityImport/PackageImportConfigGUIs/Extendables.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables.meta rename to Editor/CityImport/PackageImportConfigGUIs/Extendables.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components.meta b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components.meta rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/Components.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/MeshColliderSetGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/MeshColliderSetGUI.cs similarity index 65% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/MeshColliderSetGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/MeshColliderSetGUI.cs index 264122349..63dd56c7a 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/MeshColliderSetGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/MeshColliderSetGUI.cs @@ -1,7 +1,7 @@ -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using UnityEditor; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables.Components +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables.Components { /// /// MeshColliderをセットするかどうかの設定GUIです。 @@ -9,7 +9,7 @@ namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables.Components internal class MeshColliderSetGUI : ExtendableConfigGUIBase { - public MeshColliderSetGUI(PackageLoadConfigExtendable conf) : base(conf) + public MeshColliderSetGUI(PackageImportConfigExtendable conf) : base(conf) { } diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/MeshColliderSetGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/MeshColliderSetGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/MeshColliderSetGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/MeshColliderSetGUI.cs.meta diff --git a/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/MeshGranularityGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/MeshGranularityGUI.cs new file mode 100644 index 000000000..3e38a0987 --- /dev/null +++ b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/MeshGranularityGUI.cs @@ -0,0 +1,29 @@ +using PLATEAU.CityImport.Config.PackageImportConfigs; +using PLATEAU.PolygonMesh; +using UnityEditor; + +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables.Components +{ + /// + /// メッシュ粒度の設定GUIです。 + /// + internal class MeshGranularityGUI : ExtendableConfigGUIBase + { + + public MeshGranularityGUI(PackageImportConfigExtendable conf) : base(conf){} + + public override void Draw() + { + Conf.MeshGranularity = GranularityGUI.Draw("モデル結合", Conf.MeshGranularity); + } + } + + internal static class GranularityGUI + { + public static MeshGranularity Draw(string label, MeshGranularity current) + { + return (MeshGranularity)EditorGUILayout.Popup(label, + (int)current, new[] { "最小地物単位(壁面,屋根面等)", "主要地物単位(建築物,道路等)", "地域単位" }); + } + } +} \ No newline at end of file diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/MeshGranularityGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/MeshGranularityGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/MeshGranularityGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/MeshGranularityGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/SetAttrInfoGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/SetAttrInfoGUI.cs similarity index 63% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/SetAttrInfoGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/SetAttrInfoGUI.cs index 6c2bddd0e..96995bd4a 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/SetAttrInfoGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/SetAttrInfoGUI.cs @@ -1,7 +1,7 @@ -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using UnityEditor; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables.Components +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables.Components { /// /// 属性情報を含めるかどうかの設定GUIです。 @@ -9,7 +9,7 @@ namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables.Components internal class SetAttrInfoGUI : ExtendableConfigGUIBase { - public SetAttrInfoGUI(PackageLoadConfigExtendable conf) : base(conf){} + public SetAttrInfoGUI(PackageImportConfigExtendable conf) : base(conf){} public override void Draw() { diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/SetAttrInfoGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/SetAttrInfoGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/SetAttrInfoGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/SetAttrInfoGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/TextureIncludeGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/TextureIncludeGUI.cs similarity index 87% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/TextureIncludeGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/TextureIncludeGUI.cs index d037eaa70..e87bdd779 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/TextureIncludeGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/TextureIncludeGUI.cs @@ -1,8 +1,8 @@ -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Editor.EditorWindow.Common; using UnityEditor; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables.Components +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables.Components { /// /// テクスチャに関する設定GUIです。 @@ -13,7 +13,7 @@ internal class TextureIncludeGUI : ExtendableConfigGUIBase /// 仕様上、テクスチャが存在する可能性があるか(パッケージ種によってはない) /// public bool MayTextureExist { get; set; } = true; - public TextureIncludeGUI(PackageLoadConfigExtendable conf) : base(conf) + public TextureIncludeGUI(PackageImportConfigExtendable conf) : base(conf) { } diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/TextureIncludeGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/TextureIncludeGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/TextureIncludeGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/TextureIncludeGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/ExtendableConfigBase.cs b/Editor/CityImport/PackageImportConfigGUIs/Extendables/ExtendableConfigBase.cs similarity index 55% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/ExtendableConfigBase.cs rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/ExtendableConfigBase.cs index 8da989b10..57f18f2ae 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/ExtendableConfigBase.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Extendables/ExtendableConfigBase.cs @@ -1,6 +1,6 @@ -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables { /// /// 一括設定の中にある各項目を抽象化したものです。 @@ -8,9 +8,9 @@ namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables /// internal abstract class ExtendableConfigGUIBase { - protected readonly PackageLoadConfigExtendable Conf; + protected readonly PackageImportConfigExtendable Conf; - protected ExtendableConfigGUIBase(PackageLoadConfigExtendable conf) + protected ExtendableConfigGUIBase(PackageImportConfigExtendable conf) { Conf = conf; } diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/ExtendableConfigBase.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Extendables/ExtendableConfigBase.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/ExtendableConfigBase.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/ExtendableConfigBase.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/PackageLoadConfigExtendableGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigExtendableGUI.cs similarity index 67% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/PackageLoadConfigExtendableGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigExtendableGUI.cs index cadbdb3c6..cefb0c7a6 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/PackageLoadConfigExtendableGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigExtendableGUI.cs @@ -1,20 +1,20 @@ using System.Collections.Generic; using System.Linq; -using PLATEAU.CityImport.Config.PackageLoadConfigs; -using PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables.Components; +using PLATEAU.CityImport.Config.PackageImportConfigs; +using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables.Components; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables { /// /// インポートのパッケージごとの設定GUIのうち、一括設定の部分です。 - /// 加えて、各パッケージで一括設定をオーバーライドするGUI でも利用します。 + /// 加えて、各パッケージで一括設定をオーバーライドするGUI でも利用します。 /// - internal class PackageLoadConfigExtendableGUI + internal class PackageImportConfigExtendableGUI { private readonly List guis; - public PackageLoadConfigExtendable Conf { get; } + public PackageImportConfigExtendable Conf { get; } - public PackageLoadConfigExtendableGUI(PackageLoadConfigExtendable conf) + public PackageImportConfigExtendableGUI(PackageImportConfigExtendable conf) { Conf = conf; guis = new List diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/PackageLoadConfigExtendableGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigExtendableGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/PackageLoadConfigExtendableGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigExtendableGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/PackageLoadConfigOverrideGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigOverrideGUI.cs similarity index 69% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/PackageLoadConfigOverrideGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigOverrideGUI.cs index d5598a18d..d7a00ecd5 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/PackageLoadConfigOverrideGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigOverrideGUI.cs @@ -1,28 +1,28 @@ -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; -using PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables.Components; +using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables.Components; using PLATEAU.Editor.EditorWindow.Common; using UnityEditor; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables { /// /// インポートのパッケージごとの設定GUIのうち、 /// 一括設定を各パッケージでオーバーライドする部分です。 /// - internal class PackageLoadConfigOverrideGUI : PackageLoadConfigGUIComponent + internal class PackageImportConfigOverrideGUI : PackageImportConfigGUIComponent { - private readonly PackageLoadConfigExtendableGUI gui; + private readonly PackageImportConfigExtendableGUI gui; private bool DoUseMasterConfig { get; set; } = true; /// 「一括設定と同じ」場合に使用する一括設定への参照です。 - private PackageLoadConfigExtendable MasterConf { get; } + private PackageImportConfigExtendable MasterConf { get; } - public PackageLoadConfigOverrideGUI( - PackageLoadConfig packageConf, PackageLoadConfigExtendable masterConf) + public PackageImportConfigOverrideGUI( + PackageImportConfig packageConf, PackageImportConfigExtendable masterConf) : base(packageConf) { MasterConf = masterConf; - gui = new PackageLoadConfigExtendableGUI(packageConf.ConfExtendable); + gui = new PackageImportConfigExtendableGUI(packageConf.ConfExtendable); bool mayTextureExist = CityModelPackageInfo.GetPredefined(Conf.Package).hasAppearance; gui.GetGUIByType().MayTextureExist = mayTextureExist; diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/PackageLoadConfigOverrideGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigOverrideGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/Extendables/PackageLoadConfigOverrideGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigOverrideGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUI.cs similarity index 64% rename from Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUI.cs index 867527aeb..8cfcada6a 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUI.cs @@ -1,36 +1,36 @@ using System.Collections.Generic; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; -using PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Components; -using PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables; +using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components; +using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables; using PLATEAU.Editor.EditorWindow.Common; using UnityEditor; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs { /// /// インポート設定のうち、パッケージ種1つの設定GUIです。 - /// 具体的には、を1つ設定するGUIです。 + /// 具体的には、を1つ設定するGUIです。 /// 他クラスとの関係: - /// パッケージ設定GUIを、利用可能な全種類について集めたクラスが です。 + /// パッケージ設定GUIを、利用可能な全種類について集めたクラスが です。 /// - internal class PackageLoadConfigGUI + internal class PackageImportConfigGUI { - private readonly PackageLoadConfig config; + private readonly PackageImportConfig config; /// 設定GUIのリスト - private readonly List guisForInclude; + private readonly List guisForInclude; /// GUIで設定を表示する(true)か、折りたたむ(false)か private bool guiFoldOutState = true; - public PackageLoadConfigGUI(PackageLoadConfig packageConf, PackageLoadConfigExtendable masterConf) + public PackageImportConfigGUI(PackageImportConfig packageConf, PackageImportConfigExtendable masterConf) { config = packageConf; - guisForInclude = new List + guisForInclude = new List { // ここに設定項目を列挙します - new PackageLoadConfigOverrideGUI(packageConf, masterConf), + new PackageImportConfigOverrideGUI(packageConf, masterConf), new LodGUI(packageConf), new FallbackMaterialGUI(packageConf) }; @@ -44,8 +44,8 @@ public void Draw() { using (PlateauEditorStyle.VerticalScopeLevel1()) { - conf.LoadPackage = EditorGUILayout.Toggle("インポートする", conf.LoadPackage); - if (!conf.LoadPackage) return; + conf.ImportPackage = EditorGUILayout.Toggle("インポートする", conf.ImportPackage); + if (!conf.ImportPackage) return; using (PlateauEditorStyle.VerticalScopeLevel1(1)) { AdditionalSettingGUI(); diff --git a/Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUIComponent.cs b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIComponent.cs similarity index 72% rename from Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUIComponent.cs rename to Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIComponent.cs index 45c2d9c77..6c27dc230 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUIComponent.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIComponent.cs @@ -1,7 +1,7 @@ -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Editor.EditorWindow.Common; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs { /// /// パッケージごとの設定GUIについて、各設定項目ごとのGUIをコンポーネントと呼ぶことにします。 @@ -10,11 +10,11 @@ namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs /// その中でユーザーのGUI操作に応じて設定値を変更します。 /// そのコンポーネントという概念を抽象化したものがこのクラスです。 /// - internal abstract class PackageLoadConfigGUIComponent : IEditorDrawable + internal abstract class PackageImportConfigGUIComponent : IEditorDrawable { - protected readonly PackageLoadConfig Conf; + protected readonly PackageImportConfig Conf; - protected PackageLoadConfigGUIComponent(PackageLoadConfig conf) + protected PackageImportConfigGUIComponent(PackageImportConfig conf) { Conf = conf; } diff --git a/Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUIComponent.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIComponent.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUIComponent.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIComponent.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUIList.cs b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIList.cs similarity index 60% rename from Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUIList.cs rename to Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIList.cs index 2a869c1c3..d900d4368 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUIList.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIList.cs @@ -1,32 +1,31 @@ using System.Collections.Generic; using PLATEAU.CityImport.Config; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; -using PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables; +using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables; using PLATEAU.Editor.EditorWindow.Common; - -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs { /// - /// インポート設定GUIのうち、パッケージ種ごとの設定GUI を、利用可能パッケージ分だけ集めたものです。 + /// インポート設定GUIのうち、パッケージ種ごとの設定GUI を、利用可能パッケージ分だけ集めたものです。 /// また一括設定のGUIも描画します。 /// 参照: - /// 具体的な設定GUIについてはを参照してください。 - /// 設定値のクラスについては を参照してください。 + /// 具体的な設定GUIについてはを参照してください。 + /// 設定値のクラスについては を参照してください。 /// - internal class PackageLoadConfigGUIList : IEditorDrawable + internal class PackageImportConfigGUIList : IEditorDrawable { /// パッケージ種ごとのGUIをパッケージごとに集めたものです。 - private readonly List packageGUIList; + private readonly List packageGUIList; /// 一括設定のGUIです。 - private readonly PackageLoadConfigExtendableGUI masterConfGUI; + private readonly PackageImportConfigExtendableGUI masterConfGUI; /// 一括設定です。 - private readonly PackageLoadConfigExtendable masterConf = new (); + private readonly PackageImportConfigExtendable masterConf = new (); private bool masterConfFoldOut = true; - public PackageLoadConfigGUIList(PackageToLodDict availablePackageLODDict, CityLoadConfig cityLoadConf) + public PackageImportConfigGUIList(PackageToLodDict availablePackageLODDict, CityImportConfig cityImportConf) { // 初期化では、利用可能なパッケージ種1つにつき、それに対応するGUIインスタンスを1つ生成します。 this.packageGUIList = new(); @@ -37,19 +36,19 @@ public PackageLoadConfigGUIList(PackageToLodDict availablePackageLODDict, CityLo continue; } - var packageConf = cityLoadConf.GetConfigForPackage(package); + var packageConf = cityImportConf.GetConfigForPackage(package); // パッケージ種による場合分けです。 // これと似たロジックが PackageLoadSetting.CreateSettingFor にあるので、変更時はそちらも合わせて変更をお願いします。 var gui = package switch { - PredefinedCityModelPackage.Relief => new ReliefLoadConfigGUI((ReliefLoadConfig)packageConf, masterConf, MeshCode.Parse(cityLoadConf.AreaMeshCodes[0])), - _ => new PackageLoadConfigGUI(packageConf, masterConf) + PredefinedCityModelPackage.Relief => new ReliefImportConfigGUI((ReliefImportConfig)packageConf, masterConf, cityImportConf.AreaMeshCodes.At(0)), + _ => new PackageImportConfigGUI(packageConf, masterConf) }; this.packageGUIList.Add(gui); } - masterConfGUI = new PackageLoadConfigExtendableGUI(masterConf); + masterConfGUI = new PackageImportConfigExtendableGUI(masterConf); } public void Draw() diff --git a/Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUIList.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIList.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/PackageLoadConfigGUIList.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIList.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/ReliefLoadConfigGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/ReliefImportConfigGUI.cs similarity index 77% rename from Editor/CityImport/PackageLoadConfigGUIs/ReliefLoadConfigGUI.cs rename to Editor/CityImport/PackageImportConfigGUIs/ReliefImportConfigGUI.cs index 7d5bcfe62..575fe49a5 100644 --- a/Editor/CityImport/PackageLoadConfigGUIs/ReliefLoadConfigGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/ReliefImportConfigGUI.cs @@ -1,26 +1,26 @@ using System; using PLATEAU.CityImport.Config; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; -using PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Components; +using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components; using PLATEAU.Editor.EditorWindow.Common; using UnityEditor; using UnityEngine; -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs +namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs { /// - /// に対応するGUIクラスです。 - /// を継承し、土地特有の設定GUIを追加したクラスです。 + /// に対応するGUIクラスです。 + /// を継承し、土地特有の設定GUIを追加したクラスです。 /// - internal class ReliefLoadConfigGUI : PackageLoadConfigGUI + internal class ReliefImportConfigGUI : PackageImportConfigGUI { - private readonly ReliefLoadConfig config; + private readonly ReliefImportConfig config; private readonly MapZoomLevelSelectGUI zoomLevelSelectGUI; private string mapTileURLOnGUI; - public ReliefLoadConfigGUI(ReliefLoadConfig config, PackageLoadConfigExtendable masterConf, + public ReliefImportConfigGUI(ReliefImportConfig config, PackageImportConfigExtendable masterConf, MeshCode firstMeshCode) : base(config, masterConf) { this.config = config; @@ -56,13 +56,13 @@ protected override void AdditionalSettingGUI() EditorGUILayout.HelpBox("URLが正しくありません。", MessageType.Error); } - if (this.mapTileURLOnGUI != ReliefLoadConfig.DefaultMapTileUrl) + if (this.mapTileURLOnGUI != ReliefImportConfig.DefaultMapTileUrl) { PlateauEditorStyle.CenterAlignHorizontal(() => { if (PlateauEditorStyle.MiniButton("デフォルトURLに戻す", 150)) { - string defaultURL = ReliefLoadConfig.DefaultMapTileUrl; + string defaultURL = ReliefImportConfig.DefaultMapTileUrl; this.mapTileURLOnGUI = defaultURL; conf.MapTileURL = defaultURL; zoomLevelSelectGUI.OnMapTileUrlChanged(defaultURL); diff --git a/Editor/CityImport/PackageLoadConfigGUIs/ReliefLoadConfigGUI.cs.meta b/Editor/CityImport/PackageImportConfigGUIs/ReliefImportConfigGUI.cs.meta similarity index 100% rename from Editor/CityImport/PackageLoadConfigGUIs/ReliefLoadConfigGUI.cs.meta rename to Editor/CityImport/PackageImportConfigGUIs/ReliefImportConfigGUI.cs.meta diff --git a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/MeshGranularityGUI.cs b/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/MeshGranularityGUI.cs deleted file mode 100644 index 8ff04f51e..000000000 --- a/Editor/CityImport/PackageLoadConfigGUIs/Extendables/Components/MeshGranularityGUI.cs +++ /dev/null @@ -1,21 +0,0 @@ -using PLATEAU.CityImport.Config.PackageLoadConfigs; -using PLATEAU.PolygonMesh; -using UnityEditor; - -namespace PLATEAU.Editor.CityImport.PackageLoadConfigGUIs.Extendables.Components -{ - /// - /// メッシュ粒度の設定GUIです。 - /// - internal class MeshGranularityGUI : ExtendableConfigGUIBase - { - - public MeshGranularityGUI(PackageLoadConfigExtendable conf) : base(conf){} - - public override void Draw() - { - Conf.MeshGranularity = (MeshGranularity)EditorGUILayout.Popup("モデル結合", - (int)Conf.MeshGranularity, new[] { "最小地物単位(壁面,屋根面等)", "主要地物単位(建築物,道路等)", "地域単位" }); - } - } -} \ No newline at end of file diff --git a/Editor/CityInfo/PLATEAUCityObjectGroupEditor.cs b/Editor/CityInfo/PLATEAUCityObjectGroupEditor.cs index 87a4e80d2..ca2f02070 100644 --- a/Editor/CityInfo/PLATEAUCityObjectGroupEditor.cs +++ b/Editor/CityInfo/PLATEAUCityObjectGroupEditor.cs @@ -1,5 +1,6 @@ using PLATEAU.CityInfo; using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.PolygonMesh; using UnityEditor; using UnityEditorInternal; using UnityEngine; @@ -20,6 +21,10 @@ public override void OnInspectorGUI() { var cog = target as PLATEAUCityObjectGroup; if (cog == null) return; + + PlateauEditorStyle.Heading("粒度", null); + EditorGUILayout.LabelField(cog.Granularity.ToJapaneseString()); + SerializedProperty prop = serializedObject.FindProperty("serializedCityObjects"); var json = prop.stringValue; diff --git a/Editor/EditorWindow/Common/PlateauEditorStyle.cs b/Editor/EditorWindow/Common/PlateauEditorStyle.cs index 4a80fc507..da62ca725 100644 --- a/Editor/EditorWindow/Common/PlateauEditorStyle.cs +++ b/Editor/EditorWindow/Common/PlateauEditorStyle.cs @@ -843,6 +843,19 @@ public static string TextFieldWithDefaultValue(string label, string currentValue return nextValue; } + /// + /// EditorGUILayout.Popup の、 + /// ラベルの幅を指定できる版です。 + /// + public static int PopupWithLabelWidth(string label, int selectedIndex, string[] displayedOptions, int labelWidth) + { + var prevWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = labelWidth; + var ret = EditorGUILayout.Popup(label, selectedIndex, displayedOptions); + EditorGUIUtility.labelWidth = prevWidth; + return ret; + } + /// /// テクスチャをロードし、キャッシュに追加してから返します。 /// すでにキャッシュにあれば、ファイルロードの代わりにキャッシュから返します。 diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/DestroyOrPreserveSrcGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/DestroyOrPreserveSrcGUI.cs new file mode 100644 index 000000000..d81ed0549 --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/DestroyOrPreserveSrcGUI.cs @@ -0,0 +1,25 @@ +using PLATEAU.Editor.EditorWindow.Common; + +namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.AdjustGUIParts +{ + /// + /// 元のオブジェクトを削除するか残すか選択するGUIを描画します。 + /// + internal class DestroyOrPreserveSrcGUI + { + public enum PreserveOrDestroy + { + Preserve, Destroy + } + + private static readonly string[] DestroySrcOptions = { "残す", "削除する" }; + public PreserveOrDestroy Current { get; private set; } = PreserveOrDestroy.Preserve; + + public void Draw() + { + Current = (PreserveOrDestroy) + PlateauEditorStyle.PopupWithLabelWidth( + "元のオブジェクトを", (int)Current, DestroySrcOptions, 90); + } + } +} \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/DestroyOrPreserveSrcGUI.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/DestroyOrPreserveSrcGUI.cs.meta new file mode 100644 index 000000000..0d1f0d8b2 --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/DestroyOrPreserveSrcGUI.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dbdc28b6a19b4b528ef309c35e6eecb2 +timeCreated: 1701158349 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/FilterConditionGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/FilterConditionGUI.cs index f4d11756a..70bdc4fba 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/FilterConditionGUI.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/FilterConditionGUI.cs @@ -26,7 +26,7 @@ internal class FilterConditionGUI private PackageLod sliderPackageLod; - public void Draw(CityAdjustGUI.PackageToLodMinMax packageToLodMinMax) + public void Draw(CityChangeActiveGUI.PackageToLodMinMax packageToLodMinMax) { using (new EditorGUILayout.HorizontalScope()) @@ -50,7 +50,7 @@ public void Draw(CityAdjustGUI.PackageToLodMinMax packageToLodMinMax) } } - private void DrawNodeRecursive(Hierarchy.Node node, CityAdjustGUI.PackageToLodMinMax packageToLodMinMax, int depth) + private void DrawNodeRecursive(Hierarchy.Node node, CityChangeActiveGUI.PackageToLodMinMax packageToLodMinMax, int depth) { if (!this.selectionDict.ContainsKey(node)) { @@ -129,7 +129,7 @@ private void SetSelectionAll(bool isActive) /// /// 初期化時と対象の都市モデルが変わったときに呼びます。 /// - public void RefreshPackageAndLods(CityAdjustGUI.PackageToLodMinMax packageToLodMinMax) + public void RefreshPackageAndLods(CityChangeActiveGUI.PackageToLodMinMax packageToLodMinMax) { // data を初期化します。 this.sliderPackageLod = new Dictionary(); diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAddGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAddGUI.cs index ea4599f01..3209da1e0 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAddGUI.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAddGUI.cs @@ -1,4 +1,5 @@ using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ImportGUIParts; using UnityEditor; using UnityEngine; @@ -13,8 +14,8 @@ public CityAddGUI(UnityEditor.EditorWindow parentEditorWindow) { this.importTabGUIArray = new IEditorDrawable[] { - new CityImportLocalGUI(parentEditorWindow), - new CityImportRemoteGUI(parentEditorWindow) + CityImportConfigGUI.CreateLocal(parentEditorWindow), + CityImportConfigGUI.CreateRemote(parentEditorWindow) }; } diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAdjustGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityChangeActiveGUI.cs similarity index 98% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAdjustGUI.cs rename to Editor/EditorWindow/PlateauWindow/MainTabGUI/CityChangeActiveGUI.cs index 8edb155c4..4dfaab467 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAdjustGUI.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityChangeActiveGUI.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using PLATEAU.CityAdjust; +using PLATEAU.CityAdjust.ChangeActive; using PLATEAU.CityInfo; using PLATEAU.Dataset; using PLATEAU.Editor.EditorWindow.Common; @@ -16,7 +17,7 @@ namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI /// /// PLATEAU SDK ウィンドウで「モデル調整」タブが選択されている時のGUIです。 /// - internal class CityAdjustGUI : IEditorDrawable + internal class CityChangeActiveGUI : IEditorDrawable { private PLATEAUInstancedCityModel adjustTarget; private readonly FilterConditionGUI filterConditionGUI = new FilterConditionGUI(); diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAdjustGUI.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityChangeActiveGUI.cs.meta similarity index 100% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAdjustGUI.cs.meta rename to Editor/EditorWindow/PlateauWindow/MainTabGUI/CityChangeActiveGUI.cs.meta diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityExportGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityExportGUI.cs index d014f134a..b507f2327 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityExportGUI.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityExportGUI.cs @@ -1,14 +1,15 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using PLATEAU.CityExport; using PLATEAU.CityInfo; -using PLATEAU.Editor.CityExport; using PLATEAU.Editor.EditorWindow.Common; using PLATEAU.Editor.EditorWindow.Common.PathSelector; using PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts; using PLATEAU.Geometries; +using PLATEAU.Util; using UnityEditor; -using UnityEngine; using Directory = System.IO.Directory; namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI @@ -33,11 +34,11 @@ internal class CityExportGUI : IEditorDrawable private PLATEAUInstancedCityModel exportTarget; private MeshFileFormat meshFileFormat = MeshFileFormat.OBJ; - private readonly Dictionary formatToExporter = new() + private readonly Dictionary formatToExporterGUI = new() { - { MeshFileFormat.OBJ, new ObjModelExporter() }, - { MeshFileFormat.FBX, new FbxModelExporter() }, - { MeshFileFormat.GLTF, new GltfModelExporter() } + { MeshFileFormat.OBJ, new ExportConfigGuiObj() }, + { MeshFileFormat.FBX, new ExportConfigGuiFbx() }, + { MeshFileFormat.GLTF, new ExportConfigGuiGltf() } }; private bool exportTextures = true; @@ -72,7 +73,7 @@ public void Draw() using (PlateauEditorStyle.VerticalScopeLevel1()) { // 選択した出力設定に固有の設定 - this.formatToExporter[this.meshFileFormat].DrawConfigGUI(); + this.formatToExporterGUI[this.meshFileFormat].Draw(); this.exportTextures = EditorGUILayout.Toggle("テクスチャ", this.exportTextures); this.exportHiddenObject = EditorGUILayout.Toggle("非アクティブオブジェクトを含める", this.exportHiddenObject); @@ -96,29 +97,81 @@ public void Draw() } } - // FIXME 出力したファイルパスのリストを返すようにできるか? private void Export(string destinationDir, PLATEAUInstancedCityModel target) { if (target == null) { - Debug.LogError("エクスポート対象が指定されていません。"); + Dialogue.Display("エクスポート失敗:\nエクスポート対象を指定してください。", "OK"); return; } if (string.IsNullOrEmpty(destinationDir)) { - Debug.LogError("エクスポート先が指定されていません。"); + Dialogue.Display("エクスポート失敗:\nエクスポート先を指定してください。", "OK"); return; } if (!Directory.Exists(destinationDir)) { - Debug.LogError("エクスポート先フォルダが実在しません。"); + Dialogue.Display("エクスポート失敗:\nエクスポート先フォルダが実在しません。\n再度エクスポート先を指定してください。", "OK"); + return; + } + + if (!WarnIfFileExist(destinationDir)) + { return; } var meshExportOptions = new MeshExportOptions(this.meshTransformType, this.exportTextures, this.exportHiddenObject, - this.meshFileFormat, this.meshAxis, this.formatToExporter[this.meshFileFormat]); - UnityModelExporter.Export(destinationDir, target, meshExportOptions); + this.meshFileFormat, this.meshAxis, this.formatToExporterGUI[this.meshFileFormat].GetExporter()); + using (var progress = new ProgressBar("エクスポート中...")) + { + progress.Display(0.5f); + UnityModelExporter.Export(destinationDir, target, meshExportOptions); + EditorUtility.RevealInFinder(destinationDir +"/"); + } + + Dialogue.Display("エクスポートが完了しました。", "OK"); + } + + /// + /// フォルダ内に、出力しようとしているファイルと同じ拡張子のものがあれば上書きの警告を出します。 + /// ユーザーが警告に了承すればtrueを、拒否すればfalseを返します。 + /// + private bool WarnIfFileExist(string destinationDir) + { + // 厳密には、拡張子チェックだけするよりも、出力しようとしているファイル名をすべて調べるのがベストです。 + // しかし、エクスポートを共通ライブラリに任せている都合上それは難しいので、拡張子のみのチェックとします。 + bool found = meshFileFormat.ToExtensions().Any(extension => FileExistsWithinDepth1(destinationDir, extension, 0)); + + if (found) + { + return Dialogue.Display("同名のファイルは上書きされます。よろしいですか?", "OK", "キャンセル"); + } + + return true; + } + + /// + /// ディレクトリを再帰探索したとき、再帰の深さが0をトップとして1以内に指定拡張子のファイルがあるかを調べます。 + /// エクスポートの上書きチェックの用途なら、深さは1以内で探せば十分です。 + /// + private bool FileExistsWithinDepth1(string destinationDir, string extension, int depth) + { + if (depth > 1) return false; + var files = + Directory.EnumerateFiles(destinationDir, "*" + extension, SearchOption.TopDirectoryOnly); + if (files.Any()) + { + return true; + } + + foreach (var dir in Directory.EnumerateDirectories(destinationDir)) + { + bool result = FileExistsWithinDepth1(dir, extension, depth + 1); + if (result) return true; + } + + return false; } public void Dispose() { } diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityGranularityConvertGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityGranularityConvertGUI.cs index 5c748813c..e949dd7a9 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityGranularityConvertGUI.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityGranularityConvertGUI.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.AdjustGUIParts; using PLATEAU.GranularityConvert; using PLATEAU.PolygonMesh; using PLATEAU.Util.Async; @@ -14,14 +15,14 @@ namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI /// internal class CityGranularityConvertGUI : IEditorDrawable { - private UnityEditor.EditorWindow parentEditorWindow; + private readonly UnityEditor.EditorWindow parentEditorWindow; private GameObject[] selected = Array.Empty(); private Vector2 scrollSelected; private int selectedUnit = 2; private static readonly string[] UnitOptions = { "最小地物単位(壁面,屋根面等)", "主要地物単位(建築物,道路等)", "地域単位" }; - // private bool foldOutOption = true; - // private bool toggleMaxSize = true; - private bool isExecTaskRunning = false; + private readonly DestroyOrPreserveSrcGUI destroyOrPreserveGUI = new(); + + private readonly bool isExecTaskRunning = false; public CityGranularityConvertGUI(UnityEditor.EditorWindow parentEditorWindow) { @@ -56,13 +57,16 @@ public void Draw() EditorGUILayout.EndScrollView(); } - PlateauEditorStyle.Heading("結合・分離単位", null); + PlateauEditorStyle.Heading("設定", null); using (PlateauEditorStyle.VerticalScopeWithPadding(16, 0, 8, 16)) { EditorGUIUtility.labelWidth = 50; - this.selectedUnit = EditorGUILayout.Popup("単位", this.selectedUnit, UnitOptions); - }; + this.selectedUnit = + PlateauEditorStyle.PopupWithLabelWidth( + "分割・結合単位", this.selectedUnit, UnitOptions, 90); + destroyOrPreserveGUI.Draw(); + } // if(selectedUnit == 0 ) // { @@ -89,9 +93,13 @@ public void Draw() private async Task Exec() { Debug.Log("変換開始"); - var option = new GranularityConvertOption((MeshGranularity)this.selectedUnit, 1); var converter = new CityGranularityConverter(); - await converter.ConvertAsync(selected, option); + var convertConf = new GranularityConvertOptionUnity( + new GranularityConvertOption((MeshGranularity)selectedUnit, 1), + selected, + destroyOrPreserveGUI.Current == DestroyOrPreserveSrcGUI.PreserveOrDestroy.Destroy + ); + await converter.ConvertAsync(convertConf); selected = new GameObject[] { }; } } diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportConfigGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportConfigGUI.cs new file mode 100644 index 000000000..e7e9ea80c --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportConfigGUI.cs @@ -0,0 +1,81 @@ +using System.Runtime.CompilerServices; +using PLATEAU.CityImport.AreaSelector; +using PLATEAU.CityImport.Config; +using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ImportGUIParts; +using PLATEAU.Editor.EditorWindow.ProgressDisplay; + +namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI +{ + /// + /// インポート画面の設定GUIです。 + /// + public class CityImportConfigGUI : IAreaSelectResultReceiver, IEditorDrawable + { + private CityImportConfig config = CityImportConfig.CreateDefault(); + private readonly IConfigGUIBeforeAreaSelect configGUIBeforeAreaSelect; + + /// GUIのうち、範囲選択後に表示する部分です。 + private ImportGUIAfterAreaSelect guiAfterAreaSelect; + + // インポートの処理状況はウィンドウを消しても残しておきたいので static にします。 + private static ProgressDisplayGUI progressGUI; + + /// + /// コンストラクタです。、 + /// 範囲選択するより前のインポート設定GUIはローカルかリモートかによって異なるので、引数によって処理を分けます。 + /// + private CityImportConfigGUI(IConfigGUIBeforeAreaSelect configGUIBeforeAreaSelect, UnityEditor.EditorWindow parentEditorWindow) + { + this.configGUIBeforeAreaSelect = configGUIBeforeAreaSelect; + progressGUI = new ProgressDisplayGUI(parentEditorWindow); + } + + /// + /// ローカルインポートの設定GUIを作ります。 + /// + public static CityImportConfigGUI CreateLocal(UnityEditor.EditorWindow parentWindow) + { + return new CityImportConfigGUI(new ConfigGUIBeforeAreaSelectLocal(), parentWindow); + } + + /// + /// サーバーインポートの設定GUIを作ります。 + /// + public static CityImportConfigGUI CreateRemote(UnityEditor.EditorWindow parentWindow) + { + return new CityImportConfigGUI(new ConfigGUIBeforeAreaSelectRemote(parentWindow), parentWindow); + } + + public void Draw() + { + config.ConfBeforeAreaSelect = this.configGUIBeforeAreaSelect.Draw(); + + PlateauEditorStyle.Heading("マップ範囲選択", "num2.png"); + + bool isAreaSelectComplete = AreaSelectButton.Draw(this.config.AreaMeshCodes, + this.config.ConfBeforeAreaSelect, + this); + + if (isAreaSelectComplete) + { + this.guiAfterAreaSelect.Draw(); + } + + progressGUI.Draw(); + } + + public void Dispose() + { + } + + public void ReceiveResult(AreaSelectResult result) + { + this.config = CityImportConfig.CreateWithAreaSelectResult(result); + this.guiAfterAreaSelect = new ImportGUIAfterAreaSelect(this.config, result.PackageToLodDict, progressGUI); + } + + // テスト用 + internal static string NameOfConfigGUIBeforeAreaSelect => nameof(configGUIBeforeAreaSelect); + } +} \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportConfigGUI.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportConfigGUI.cs.meta new file mode 100644 index 000000000..77907ae40 --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportConfigGUI.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2764dbcbb4624537af7b238b85fa7cd7 +timeCreated: 1702054079 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportLocalGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportLocalGUI.cs deleted file mode 100644 index 1078580ed..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportLocalGUI.cs +++ /dev/null @@ -1,93 +0,0 @@ -using PLATEAU.CityImport.AreaSelector; -using PLATEAU.CityImport.Config; -using PLATEAU.Editor.EditorWindow.Common; -using PLATEAU.Editor.EditorWindow.Common.PathSelector; -using PLATEAU.Editor.EditorWindow.ProgressDisplay; -using PLATEAU.Dataset; -using PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ImportGUIParts; - -namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI -{ - internal class CityImportLocalGUI : IEditorDrawable, IAreaSelectResultReceiver - { - - private readonly CityLoadConfig config = new (); - - /// GUIのうち、範囲選択前に表示する部分です。 - private readonly GUIBeforeAreaSelect guiBeforeAreaSelect; - - /// GUIのうち、範囲選択後に表示する部分です。 - private ImportGUIAfterAreaSelect guiAfterAreaSelect; - - // インポートの処理状況はウィンドウを消しても残しておきたいので static にします。 - private static ProgressDisplayGUI progressGUI; - - /// - /// メインスレッドから呼ばれることを前提とします。 - /// - public CityImportLocalGUI(UnityEditor.EditorWindow parentEditorWindow) - { - progressGUI = new ProgressDisplayGUI(parentEditorWindow); - guiBeforeAreaSelect = new GUIBeforeAreaSelect(this.config, this); - } - - public void Draw() - { - guiBeforeAreaSelect.Draw(); - - if (guiBeforeAreaSelect.IsAreaSelectComplete) - { - guiAfterAreaSelect.Draw(); - } - - progressGUI.Draw(); - } - - public void ReceiveResult(AreaSelectResult result) - { - this.config.InitWithAreaSelectResult(result); - guiAfterAreaSelect = new ImportGUIAfterAreaSelect(this.config, result.PackageToLodDict, progressGUI); - } - - /// - /// ローカルインポートのGUIのうち、範囲選択前に表示するものです。 - /// - private class GUIBeforeAreaSelect : IEditorDrawable - { - public bool IsAreaSelectComplete { get; private set; } - private readonly PathSelectorFolderPlateauInput folderSelector = new (); - private bool foldOutSourceFolderPath = true; - private readonly CityLoadConfig config; - private readonly IAreaSelectResultReceiver areaSelectResultReceiver; - - public GUIBeforeAreaSelect(CityLoadConfig config, IAreaSelectResultReceiver areaSelectResultReceiver) - { - this.config = config; - this.areaSelectResultReceiver = areaSelectResultReceiver; - } - - public void Draw() - { - this.foldOutSourceFolderPath = PlateauEditorStyle.FoldOut(this.foldOutSourceFolderPath, "入力フォルダ", () => - { - this.config.DatasetSourceConfig ??= new DatasetSourceConfig(false, "", "", "", ""); - this.config.DatasetSourceConfig.LocalSourcePath = this.folderSelector.Draw("フォルダパス"); - }); - - PlateauEditorStyle.Separator(0); - PlateauEditorStyle.SubTitle("モデルデータの配置を行います。"); - PlateauEditorStyle.Heading("基準座標系の選択", "num1.png"); - CoordinateZonePopup.DrawAndSet(this.config); - - - PlateauEditorStyle.Heading("マップ範囲選択", "num2.png"); - IsAreaSelectComplete = AreaSelectButton.Draw(this.config.AreaMeshCodes, this.config.DatasetSourceConfig, - areaSelectResultReceiver, this.config.CoordinateZoneID); - } - - public void Dispose() { } - } - - public void Dispose() { } - } -} diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportLocalGUI.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportLocalGUI.cs.meta deleted file mode 100644 index fb880c81e..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportLocalGUI.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: d6a6fc0b45594027976c1cce873a3765 -timeCreated: 1662360514 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportRemoteGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportRemoteGUI.cs deleted file mode 100644 index 28d920396..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportRemoteGUI.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System.Linq; -using PLATEAU.CityImport.AreaSelector; -using PLATEAU.CityImport.Config; -using PLATEAU.Dataset; -using PLATEAU.Editor.EditorWindow.Common; -using PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ImportGUIParts; -using PLATEAU.Editor.EditorWindow.ProgressDisplay; -using UnityEditor; - -namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI -{ - /// - /// インポート画面で「サーバー」が選択されたときのGUIです。 - /// - internal class CityImportRemoteGUI : IEditorDrawable, IAreaSelectResultReceiver - { - private readonly CityLoadConfig config = new CityLoadConfig(); - private readonly GUIBeforeAreaSelect guiBeforeAreaSelect; - private ImportGUIAfterAreaSelect guiAfterAreaSelect; - - // インポートの処理状況はウィンドウを消しても残しておきたいので static にします。 - private static ProgressDisplayGUI progressGUI; - - - public CityImportRemoteGUI(UnityEditor.EditorWindow parentEditorWindow) - { - this.guiBeforeAreaSelect = new GUIBeforeAreaSelect(parentEditorWindow, config, this); - progressGUI = new ProgressDisplayGUI(parentEditorWindow); - } - - public void Draw() - { - this.guiBeforeAreaSelect.Draw(); - - if (this.guiBeforeAreaSelect.IsAreaSelectComplete) - { - this.guiAfterAreaSelect.Draw(); - } - - progressGUI.Draw(); - } - - public void Dispose() { } - - public void ReceiveResult(AreaSelectResult result) - { - this.config.InitWithAreaSelectResult(result); - this.guiAfterAreaSelect = new ImportGUIAfterAreaSelect(this.config, result.PackageToLodDict, progressGUI); - } - - // テストで使う用です。 - internal ServerDatasetFetchGUI.LoadStatusEnum DatasetFetchStatus => guiBeforeAreaSelect.DatasetFetchStatus; - - - /// - /// リモートインポートGUIのうち、範囲選択前に表示する部分です。 - /// - private class GUIBeforeAreaSelect : IEditorDrawable - { - private readonly ServerDatasetFetchGUI serverDatasetFetchGUI; - private int selectedDatasetGroupIndex; - private int selectedDatasetIndex; - private readonly CityLoadConfig cityLoadConfig; - private readonly IAreaSelectResultReceiver areaSelectResultReceiver; - public bool IsAreaSelectComplete { get; private set; } - public ServerDatasetFetchGUI.LoadStatusEnum DatasetFetchStatus => this.serverDatasetFetchGUI.LoadStatus; - - public GUIBeforeAreaSelect(UnityEditor.EditorWindow parentEditorWindow, CityLoadConfig config, - IAreaSelectResultReceiver areaSelectResultReceiver) - { - this.serverDatasetFetchGUI = new ServerDatasetFetchGUI(parentEditorWindow); - this.cityLoadConfig = config; - this.areaSelectResultReceiver = areaSelectResultReceiver; - } - - public void Draw() - { - EditorGUILayout.Space(15); - this.serverDatasetFetchGUI.Draw(); - - - if (this.serverDatasetFetchGUI.LoadStatus != ServerDatasetFetchGUI.LoadStatusEnum.Success) - { - return; - } - - // どのようなデータセットが利用可能であるか、サーバーからの返答があるまでは以下は実行されません。 - - PlateauEditorStyle.Heading("データセットの選択", "num1.png"); - - var datasetGroups = this.serverDatasetFetchGUI.DatasetGroups; - using (var groupChangeCheck = new EditorGUI.ChangeCheckScope()) - { - var datasetGroupTitles = datasetGroups.Select(dg => dg.Title).ToArray(); - this.selectedDatasetGroupIndex = - EditorGUILayout.Popup("都道府県", this.selectedDatasetGroupIndex, datasetGroupTitles); - if (groupChangeCheck.changed) - { - this.selectedDatasetIndex = 0; - } - } - - var datasetGroup = datasetGroups.At(this.selectedDatasetGroupIndex); - var datasets = datasetGroup.Datasets; - var datasetTitles = datasets.Select(d => d.Title).ToArray(); - this.selectedDatasetIndex = EditorGUILayout.Popup("データセット", this.selectedDatasetIndex, datasetTitles); - var dataset = datasets.At(this.selectedDatasetIndex); - PlateauEditorStyle.MultiLineLabelWithBox( - $"タイトル: {dataset.Title}\n説明 : {dataset.Description}\n種別: {dataset.PackageFlags.ToJapaneseName()}"); - - this.cityLoadConfig.DatasetSourceConfig ??= new DatasetSourceConfig(true, "", "", "", ""); - var sourceConf = this.cityLoadConfig.DatasetSourceConfig; - sourceConf.ServerDatasetID = dataset.ID; - sourceConf.ServerUrl = this.serverDatasetFetchGUI.ServerUrl; - sourceConf.ServerToken = this.serverDatasetFetchGUI.ServerToken; - - CoordinateZonePopup.DrawAndSet(this.cityLoadConfig); - - PlateauEditorStyle.Heading("マップ範囲選択", "num2.png"); - - IsAreaSelectComplete = AreaSelectButton.Draw(this.cityLoadConfig.AreaMeshCodes, sourceConf, - this.areaSelectResultReceiver, this.cityLoadConfig.CoordinateZoneID); - } - - public void Dispose() { } - } - } -} \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportRemoteGUI.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportRemoteGUI.cs.meta deleted file mode 100644 index 4ed4fd85c..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportRemoteGUI.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 052df94f3a5a471b9410267e7b991f58 -timeCreated: 1662360538 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityMaterialAdjustGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityMaterialAdjustGUI.cs index a089b34c1..7280226f7 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityMaterialAdjustGUI.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityMaterialAdjustGUI.cs @@ -1,7 +1,13 @@ using System; +using PLATEAU.CityAdjust.MaterialAdjust; +using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables.Components; using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.AdjustGUIParts; +using PLATEAU.Util; +using PLATEAU.Util.Async; using UnityEditor; using UnityEngine; +using Material = UnityEngine.Material; namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI { @@ -11,52 +17,100 @@ namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI internal class CityMaterialAdjustGUI : IEditorDrawable { private UnityEditor.EditorWindow parentEditorWindow; - private GameObject[] Selected = new GameObject[0]; + private GameObject[] selectedObjs = new GameObject[0]; private Vector2 scrollSelected; private int selectedType; - private string[] typeOptions = { "属性情報", "地物型" }; + private string[] typeOptions = { "地物型" /*, "属性情報"*/ }; private string attrKey = ""; - private bool changeMat1 = false; - private bool changeMat2 = false; - private Material mat1 = null; - private Material mat2 = null; - private bool isSearchTaskRunning = false; - private bool isExecTaskRunning = false; + private readonly DestroyOrPreserveSrcGUI destroyOrPreserveSrcGUI = new(); + + private CityMaterialAdjuster adjuster; // 「検索」ボタンを押すまでこれはnullになります。 public CityMaterialAdjustGUI(UnityEditor.EditorWindow parentEditorWindow) { this.parentEditorWindow = parentEditorWindow; Selection.selectionChanged += OnSelectionChanged; + OnSelectionChanged(); } public void Dispose() { Selection.selectionChanged -= OnSelectionChanged; - Array.Clear(Selected, 0, Selected.Length); + Array.Clear(selectedObjs, 0, selectedObjs.Length); } private void OnSelectionChanged() { - //選択アイテムのフィルタリング処理 - //Selected = Selection.gameObjects.Where(x => x.GetComponent() != null).ToArray(); - Selected = Selection.gameObjects; + if (adjuster != null) return; // 「検索」ボタンを押したら対象は変更できないようにします。 + selectedObjs = Selection.gameObjects; parentEditorWindow.Repaint(); } public void Draw() { PlateauEditorStyle.SubTitle("分類に応じたマテリアル分けを行います。"); + + DisplaySelectedObjects(); + DisplayClassificationChoice(); + + if (selectedType == 1) + { + using (PlateauEditorStyle.VerticalScopeWithPadding(8, 0, 8, 8)) + { + EditorGUIUtility.labelWidth = 100; + attrKey = EditorGUILayout.TextField("属性情報キー", attrKey); + } + } + + DisplayCityObjTypeSearchButton(); + + if (adjuster == null) return; + + // 検索後にのみ以下を表示します + + using (PlateauEditorStyle.VerticalScopeLevel1()) + { + adjuster.granularity = GranularityGUI.Draw("粒度", adjuster.granularity); + destroyOrPreserveSrcGUI.Draw(); + adjuster.DoDestroySrcObjects = destroyOrPreserveSrcGUI.Current == + DestroyOrPreserveSrcGUI.PreserveOrDestroy.Destroy; + } + + DisplayCityObjectTypeMaterialConfGUI(); + + + PlateauEditorStyle.Separator(0); + + if (PlateauEditorStyle.MainButton("実行")) + { + adjuster.Exec().ContinueWithErrorCatch(); // ここで実行します。 + } + } + + private void DisplaySelectedObjects() + { PlateauEditorStyle.Heading("選択オブジェクト", null); using (PlateauEditorStyle.VerticalScopeLevel2()) { scrollSelected = EditorGUILayout.BeginScrollView(scrollSelected, GUILayout.MaxHeight(100)); - foreach (GameObject obj in Selected) + foreach (GameObject obj in selectedObjs) { - EditorGUILayout.LabelField(obj.name); + if (obj == null) + { + EditorGUILayout.LabelField("(削除されたゲームオブジェクト)"); + } + else + { + EditorGUILayout.LabelField(obj.name); + } } + EditorGUILayout.EndScrollView(); } + } + private void DisplayClassificationChoice() + { PlateauEditorStyle.Heading("マテリアル分類", null); using (PlateauEditorStyle.VerticalScopeWithPadding(16, 0, 8, 8)) @@ -65,65 +119,65 @@ public void Draw() this.selectedType = EditorGUILayout.Popup("分類", this.selectedType, typeOptions); } - if(selectedType == 0) - { - using (PlateauEditorStyle.VerticalScopeWithPadding(8, 0, 8, 8)) - { - EditorGUIUtility.labelWidth = 100; - attrKey = EditorGUILayout.TextField("属性情報キー", attrKey); - } - } + ; + } + private void DisplayCityObjTypeSearchButton() + { using (PlateauEditorStyle.VerticalScopeWithPadding(0, 0, 15, 0)) { PlateauEditorStyle.CenterAlignHorizontal(() => { - using (new EditorGUI.DisabledScope(isSearchTaskRunning)) + if (adjuster == null) { - if (PlateauEditorStyle.MiniButton(isSearchTaskRunning ? "処理中..." : "検索", 150)) + if (PlateauEditorStyle.MiniButton("検索", 150)) { - //isSearchTaskRunning = true; - //TODO: 検索処理 - + using var progressBar = new ProgressBar("検索中です..."); + progressBar.Display(0.4f); + adjuster = new CityMaterialAdjuster(selectedObjs); // ここで検索します。 + if (adjuster.MaterialAdjustConf.Length <= 0) + { + Dialogue.Display("地物型が見つかりませんでした。\n属性情報を含む都市オブジェクトかその親を選択してください。", "OK"); + adjuster = null; + } + + parentEditorWindow.Repaint(); + } + } + else + { + if (PlateauEditorStyle.MiniButton("再選択", 150)) + { + adjuster = null; + OnSelectionChanged(); } } }); } + } - using (PlateauEditorStyle.VerticalScopeLevel1()) - { - PlateauEditorStyle.CategoryTitle("属性情報①"); - using (PlateauEditorStyle.VerticalScopeWithPadding(16, 0, 8, 0)) - { - changeMat1 = EditorGUILayout.ToggleLeft("マテリアルを変更する", changeMat1); - mat1 = (Material)EditorGUILayout.ObjectField("マテリアル", - mat1, typeof(Material), false); - } - } + private void DisplayCityObjectTypeMaterialConfGUI() + { + var conf = adjuster.MaterialAdjustConf; + int displayIndex = 1; - using (PlateauEditorStyle.VerticalScopeLevel1()) + // 存在する地物型を列挙します + foreach (var (typeNode, typeConf) in conf) { - PlateauEditorStyle.CategoryTitle("属性情報②"); - using (PlateauEditorStyle.VerticalScopeWithPadding(16, 0, 8, 0)) + using (PlateauEditorStyle.VerticalScopeLevel1()) { - changeMat2 = EditorGUILayout.ToggleLeft("マテリアルを変更する", changeMat2); - mat2 = (Material)EditorGUILayout.ObjectField("マテリアル", - mat2, typeof(Material), false); + PlateauEditorStyle.CategoryTitle( + $"地物型{displayIndex} : {typeNode.GetDisplayName()}"); + typeConf.ChangeMaterial = EditorGUILayout.ToggleLeft("マテリアルを変更する", typeConf.ChangeMaterial); + if (typeConf.ChangeMaterial) + { + typeConf.Material = (Material)EditorGUILayout.ObjectField("マテリアル", + typeConf.Material, typeof(Material), false); + } } - } - - PlateauEditorStyle.Separator(0); - - using (new EditorGUI.DisabledScope(isExecTaskRunning)) - { - if (PlateauEditorStyle.MainButton(isExecTaskRunning ? "処理中..." : "実行")) - { - //isExecTaskRunning = true; - //TODO: 実行処理 - } + displayIndex++; } } - } -} +} \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityModificationFrameGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityModificationFrameGUI.cs index c415c7dc1..21f7b6b73 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityModificationFrameGUI.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityModificationFrameGUI.cs @@ -9,15 +9,14 @@ internal class CityModificationFrameGUI : IEditorDrawable { private int tabIndex; private readonly IEditorDrawable[] tabGUIArray; - //private string[] tabNames = { "ゲームオブジェクト\nON/OFF" , "マテリアル分け", "結合/分離" }; - private string[] tabNames = { "ゲームオブジェクト\nON/OFF", "結合/分離" }; + private string[] tabNames = { "ゲームオブジェクト\nON/OFF" , "マテリアル分け", "結合/分離" }; public CityModificationFrameGUI(UnityEditor.EditorWindow parentEditorWindow) { this.tabGUIArray = new IEditorDrawable[] { - new CityAdjustGUI(), - //new CityMaterialAdjustGUI(parentEditorWindow), + new CityChangeActiveGUI(), + new CityMaterialAdjustGUI(parentEditorWindow), new CityGranularityConvertGUI(parentEditorWindow) }; } diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiFbx.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiFbx.cs new file mode 100644 index 000000000..8641813c7 --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiFbx.cs @@ -0,0 +1,24 @@ +using System.IO; +using PLATEAU.CityExport.Exporters; +using PLATEAU.MeshWriter; +using PLATEAU.PolygonMesh; +using UnityEditor; + +namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts +{ + /// + /// Model(中間形式)をFBXファイルに出力します。 + /// + internal class ExportConfigGuiFbx : IExportConfigGUI + { + private CityExporterFbx cityExporterFbx = new CityExporterFbx(); + + public void Draw() + { + cityExporterFbx.FbxFileFormat = (FbxFileFormat)EditorGUILayout.EnumPopup("FBXフォーマット", cityExporterFbx.FbxFileFormat); + } + + public ICityExporter GetExporter() => cityExporterFbx; + + } +} diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/FbxModelExporter.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiFbx.cs.meta similarity index 100% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/FbxModelExporter.cs.meta rename to Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiFbx.cs.meta diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiGltf.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiGltf.cs new file mode 100644 index 000000000..8e2a01573 --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiGltf.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; +using PLATEAU.CityExport.Exporters; +using PLATEAU.MeshWriter; +using PLATEAU.PolygonMesh; +using UnityEditor; + +namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts +{ + /// + /// Model(中間形式)をGLTFファイルにエクスポートします。 + /// + internal class ExportConfigGuiGltf : IExportConfigGUI + { + private CityExporterGltf cityExporterGltf = new CityExporterGltf(); + + + public void Draw() + { + cityExporterGltf.GltfFileFormat = (GltfFileFormat)EditorGUILayout.EnumPopup("Gltfフォーマット", cityExporterGltf.GltfFileFormat); + } + + public ICityExporter GetExporter() => cityExporterGltf; + + } +} diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/GltfModelExporter.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiGltf.cs.meta similarity index 100% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/GltfModelExporter.cs.meta rename to Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiGltf.cs.meta diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiObj.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiObj.cs new file mode 100644 index 000000000..5964dad31 --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiObj.cs @@ -0,0 +1,24 @@ +using System.IO; +using PLATEAU.CityExport.Exporters; +using PLATEAU.MeshWriter; +using PLATEAU.PolygonMesh; + +namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts +{ + /// + /// OBJ形式でエクスポートする設定GUIとエクスポーターです。(なお設定GUIは、今のところOBJ固有の項目がないので空です。) + /// + internal class ExportConfigGuiObj : IExportConfigGUI + { + private CityExporterObj cityExporterObj = new CityExporterObj(); + + + public void Draw() + { + // OBJファイルに固有の設定項目はありません。 + } + + public ICityExporter GetExporter() => cityExporterObj; + + } +} diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ObjModelExporter.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiObj.cs.meta similarity index 100% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ObjModelExporter.cs.meta rename to Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ExportConfigGuiObj.cs.meta diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/FbxModelExporter.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/FbxModelExporter.cs deleted file mode 100644 index ed3ba4c66..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/FbxModelExporter.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.IO; -using PLATEAU.MeshWriter; -using PLATEAU.PolygonMesh; -using UnityEditor; - -namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts -{ - /// - /// Model(中間形式)をFBXファイルに出力します。 - /// - internal class FbxModelExporter : IPlateauModelExporter - { - private FbxFileFormat FbxFileFormat { get; set; } = FbxFileFormat.Binary; - - public void DrawConfigGUI() - { - FbxFileFormat = (FbxFileFormat)EditorGUILayout.EnumPopup("FBXフォーマット", FbxFileFormat); - } - - public void Export(string destDir, string fileNameWithoutExtension, Model model) - { - string destPath = Path.Combine(destDir, fileNameWithoutExtension + ".fbx"); - FbxWriter.Write(destPath, model, new FbxWriteOptions(FbxFileFormat)); - } - } -} diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/IExportConfigGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/IExportConfigGUI.cs new file mode 100644 index 000000000..0f56ecf14 --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/IExportConfigGUI.cs @@ -0,0 +1,20 @@ +using PLATEAU.CityExport.Exporters; +using PLATEAU.PolygonMesh; + +namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts +{ + /// + /// あるエクスポート形式について、その形式固有のエクスポート設定とエクスポーターを保持するインターフェイスです。 + /// OBJ, FBX, GLTFのファイル形式ごとにこのインターフェイスを実装します。 + /// それにより形式による設定の差異を吸収します。 + /// + internal interface IExportConfigGUI + { + /// + /// ファイルフォーマットに固有の設定項目のGUIを描画します。 + /// + public void Draw(); + + public ICityExporter GetExporter(); + } +} diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/IPlateauModelExporter.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/IExportConfigGUI.cs.meta similarity index 100% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/IPlateauModelExporter.cs.meta rename to Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/IExportConfigGUI.cs.meta diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/AreaSelectButton.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/AreaSelectButton.cs index 6c811fb8d..463089094 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/AreaSelectButton.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/AreaSelectButton.cs @@ -1,5 +1,6 @@ using System.IO; using PLATEAU.CityImport.AreaSelector; +using PLATEAU.CityImport.Config; using PLATEAU.Dataset; using PLATEAU.Editor.CityImport.AreaSelector; using PLATEAU.Editor.EditorWindow.Common; @@ -18,7 +19,7 @@ internal static class AreaSelectButton /// 「範囲選択」ボタンを表示し、押された時に範囲選択を開始します。 /// 範囲が選択されているかどうかをboolで返します。 /// - public static bool Draw(string[] areaMeshCodes, DatasetSourceConfig datasetSourceConfig, IAreaSelectResultReceiver resultReceiver, int coordinateZoneID) + public static bool Draw(MeshCodeList areaMeshCodes, ConfigBeforeAreaSelect confBeforeAreaSelect, IAreaSelectResultReceiver resultReceiver) { using (PlateauEditorStyle.VerticalScopeLevel1()) { @@ -26,12 +27,12 @@ public static bool Draw(string[] areaMeshCodes, DatasetSourceConfig datasetSourc if (PlateauEditorStyle.MainButton("範囲選択")) { // ボタンを実行します。 - StartAreaSelect(datasetSourceConfig, resultReceiver, coordinateZoneID); + StartAreaSelect(confBeforeAreaSelect, resultReceiver); GUIUtility.ExitGUI(); } // 範囲選択が済かどうかを表示します。 - bool isAreaSelectComplete = areaMeshCodes != null && areaMeshCodes.Length > 0; + bool isAreaSelectComplete = areaMeshCodes != null && areaMeshCodes.Count > 0; PlateauEditorStyle.CenterAlignHorizontal(() => { string str = isAreaSelectComplete ? "範囲選択 : セット済" : "範囲選択 : 未"; @@ -41,14 +42,14 @@ public static bool Draw(string[] areaMeshCodes, DatasetSourceConfig datasetSourc } } - private static void StartAreaSelect(DatasetSourceConfig datasetSourceConfig, IAreaSelectResultReceiver resultReceiver, int coordinateZoneID) + private static void StartAreaSelect(ConfigBeforeAreaSelect confBeforeAreaSelect, IAreaSelectResultReceiver resultReceiver) { - if ((!datasetSourceConfig.IsServer) && (!Directory.Exists(datasetSourceConfig.LocalSourcePath))) + if ((confBeforeAreaSelect.DatasetSourceConfig is DatasetSourceConfigLocal localConf) && (!Directory.Exists(localConf.LocalSourcePath))) { Dialogue.Display($"入力フォルダが存在しません。\nフォルダを指定してください。", "OK"); return; } - AreaSelectorStarter.Start(datasetSourceConfig, resultReceiver, coordinateZoneID); + AreaSelectorStarter.Start(confBeforeAreaSelect, resultReceiver); } } } diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectLocal.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectLocal.cs new file mode 100644 index 000000000..1afafa02b --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectLocal.cs @@ -0,0 +1,33 @@ +using PLATEAU.CityImport.Config; +using PLATEAU.Dataset; +using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.EditorWindow.Common.PathSelector; + +namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ImportGUIParts +{ + /// + /// ローカルインポートのGUIのうち、範囲選択前に表示するものです。 + /// + internal class ConfigGUIBeforeAreaSelectLocal : IConfigGUIBeforeAreaSelect + { + + private readonly ConfigBeforeAreaSelect confBeforeAreaSelect = new(); + private readonly PathSelectorFolderPlateauInput folderSelector = new (); + private bool foldOutSourceFolderPath = true; + + public ConfigBeforeAreaSelect Draw() + { + this.foldOutSourceFolderPath = PlateauEditorStyle.FoldOut(this.foldOutSourceFolderPath, "入力フォルダ", () => + { + this.confBeforeAreaSelect.DatasetSourceConfig ??= new DatasetSourceConfigLocal(""); + ((DatasetSourceConfigLocal)confBeforeAreaSelect.DatasetSourceConfig).LocalSourcePath = this.folderSelector.Draw("フォルダパス"); + }); + + PlateauEditorStyle.Separator(0); + PlateauEditorStyle.SubTitle("モデルデータの配置を行います。"); + PlateauEditorStyle.Heading("基準座標系の選択", "num1.png"); + confBeforeAreaSelect.CoordinateZoneID = CoordinateZonePopup.Draw(confBeforeAreaSelect.CoordinateZoneID); + return confBeforeAreaSelect; + } + } +} \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectLocal.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectLocal.cs.meta new file mode 100644 index 000000000..f274a6e16 --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectLocal.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 435bab4a84e4476fae601c8819703d4a +timeCreated: 1702053620 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectRemote.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectRemote.cs new file mode 100644 index 000000000..dd4de4f6d --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectRemote.cs @@ -0,0 +1,71 @@ +using System.Linq; +using PLATEAU.CityImport.Config; +using PLATEAU.Dataset; +using PLATEAU.Editor.EditorWindow.Common; +using UnityEditor; + +namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ImportGUIParts +{ + /// + /// リモートインポートGUIのうち、範囲選択前に表示する部分です。 + /// + internal class ConfigGUIBeforeAreaSelectRemote : IConfigGUIBeforeAreaSelect + { + private readonly ConfigBeforeAreaSelect confBeforeAreaSelect; + private readonly ServerDatasetFetchGUI serverDatasetFetchGUI; + private int selectedDatasetGroupIndex; + private int selectedDatasetIndex; + public ServerDatasetFetchGUI.LoadStatusEnum DatasetFetchStatus => this.serverDatasetFetchGUI.LoadStatus; + + public ConfigGUIBeforeAreaSelectRemote(UnityEditor.EditorWindow parentEditorWindow) + { + serverDatasetFetchGUI = new ServerDatasetFetchGUI(parentEditorWindow); + confBeforeAreaSelect = new ConfigBeforeAreaSelect(); + } + + public ConfigBeforeAreaSelect Draw() + { + EditorGUILayout.Space(15); + this.serverDatasetFetchGUI.Draw(); + + + if (this.serverDatasetFetchGUI.LoadStatus != ServerDatasetFetchGUI.LoadStatusEnum.Success) + { + return confBeforeAreaSelect; + } + + // どのようなデータセットが利用可能であるか、サーバーからの返答があるまでは以下は実行されません。 + + PlateauEditorStyle.Heading("データセットの選択", "num1.png"); + + var datasetGroups = this.serverDatasetFetchGUI.DatasetGroups; + using (var groupChangeCheck = new EditorGUI.ChangeCheckScope()) + { + var datasetGroupTitles = datasetGroups.Select(dg => dg.Title).ToArray(); + this.selectedDatasetGroupIndex = + EditorGUILayout.Popup("都道府県", this.selectedDatasetGroupIndex, datasetGroupTitles); + if (groupChangeCheck.changed) + { + this.selectedDatasetIndex = 0; + } + } + + var datasetGroup = datasetGroups.At(this.selectedDatasetGroupIndex); + var datasets = datasetGroup.Datasets; + var datasetTitles = datasets.Select(d => d.Title).ToArray(); + this.selectedDatasetIndex = EditorGUILayout.Popup("データセット", this.selectedDatasetIndex, datasetTitles); + var dataset = datasets.At(this.selectedDatasetIndex); + PlateauEditorStyle.MultiLineLabelWithBox( + $"タイトル: {dataset.Title}\n説明 : {dataset.Description}\n種別: {dataset.PackageFlags.ToJapaneseName()}"); + + this.confBeforeAreaSelect.DatasetSourceConfig ??= new DatasetSourceConfigRemote("", "", ""); + var sourceConf = (DatasetSourceConfigRemote)this.confBeforeAreaSelect.DatasetSourceConfig; + sourceConf.ServerDatasetID = dataset.ID; + sourceConf.ServerUrl = this.serverDatasetFetchGUI.ServerUrl; + sourceConf.ServerToken = this.serverDatasetFetchGUI.ServerToken; + + confBeforeAreaSelect.CoordinateZoneID = CoordinateZonePopup.Draw(confBeforeAreaSelect.CoordinateZoneID); + return confBeforeAreaSelect; + } + } +} \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectRemote.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectRemote.cs.meta new file mode 100644 index 000000000..c3dec9b1d --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ConfigGUIBeforeAreaSelectRemote.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ca531a968fb14a618912a9f1658e6980 +timeCreated: 1702053747 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/CoordinateZonePopup.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/CoordinateZonePopup.cs index b4e943ab3..4a13306e7 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/CoordinateZonePopup.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/CoordinateZonePopup.cs @@ -1,5 +1,4 @@ -using PLATEAU.CityImport.Config; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.EditorWindow.Common; using PLATEAU.Geometries; using UnityEditor; @@ -14,14 +13,14 @@ namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ImportGUIParts internal static class CoordinateZonePopup { /// - /// 基準座標系を選択するGUIを表示し、結果を にセットします。 + /// 基準座標系を選択するGUIを表示し、結果をintで返します。 /// - public static void DrawAndSet(CityLoadConfig conf) + public static int Draw(int current) { using (PlateauEditorStyle.VerticalScopeLevel1()) { - conf.CoordinateZoneID = EditorGUILayout.Popup( - "基準座標系", conf.CoordinateZoneID - 1, + return EditorGUILayout.Popup( + "基準座標系", current - 1, GeoReference.ZoneIdExplanation ) + 1; // 番号は 1 スタート } diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/IConfigGUIBeforeAreaSelect.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/IConfigGUIBeforeAreaSelect.cs new file mode 100644 index 000000000..c83efd957 --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/IConfigGUIBeforeAreaSelect.cs @@ -0,0 +1,12 @@ +using PLATEAU.CityImport.Config; + +namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ImportGUIParts +{ + /// + /// インポートの設定GUIにおいて、範囲選択前の設定GUIでローカルとサーバーの差異を吸収するインターフェイスです。 + /// + public interface IConfigGUIBeforeAreaSelect + { + ConfigBeforeAreaSelect Draw(); + } +} \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/IConfigGUIBeforeAreaSelect.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/IConfigGUIBeforeAreaSelect.cs.meta new file mode 100644 index 000000000..0f5c032a4 --- /dev/null +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/IConfigGUIBeforeAreaSelect.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a0212d85e6ab44a982dd2db0c6ac91a1 +timeCreated: 1702054154 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ImportButton.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ImportButton.cs index 277d71761..f39a90d31 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ImportButton.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ImportButton.cs @@ -1,6 +1,6 @@ using System.Threading; -using PLATEAU.CityImport.Load; using PLATEAU.CityImport.Config; +using PLATEAU.CityImport.Import; using PLATEAU.Editor.EditorWindow.Common; using PLATEAU.Util; using PLATEAU.Util.Async; @@ -23,7 +23,7 @@ internal static class ImportButton /// /// 「モデルをインポート」ボタンの描画と実行を行います。 /// - public static void Draw(CityLoadConfig config, IProgressDisplay progressDisplay) + public static void Draw(CityImportConfig config, IProgressDisplay progressDisplay) { using (PlateauEditorStyle.VerticalScopeLevel1()) { diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ImportGUIAfterAreaSelect.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ImportGUIAfterAreaSelect.cs index d3ebe59c8..fd972b0de 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ImportGUIAfterAreaSelect.cs +++ b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts/ImportGUIAfterAreaSelect.cs @@ -1,5 +1,5 @@ using PLATEAU.CityImport.Config; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Editor.CityImport; using PLATEAU.Editor.EditorWindow.Common; using PLATEAU.Editor.EditorWindow.ProgressDisplay; @@ -12,26 +12,26 @@ namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ImportGUIParts /// internal class ImportGUIAfterAreaSelect { - private readonly CityLoadConfigGUI cityLoadConfigGUI; - private readonly CityLoadConfig cityLoadConfig; + private readonly CityImport.CityImportConfigGUI cityImportConfigGUI; + private readonly CityImportConfig cityImportConfig; private readonly ProgressDisplayGUI progressGui; - public ImportGUIAfterAreaSelect(CityLoadConfig config, PackageToLodDict packageToLodDict, ProgressDisplayGUI progressGui) + public ImportGUIAfterAreaSelect(CityImportConfig config, PackageToLodDict packageToLodDict, ProgressDisplayGUI progressGui) { - this.cityLoadConfigGUI = new CityLoadConfigGUI(config, packageToLodDict); - this.cityLoadConfig = config; + this.cityImportConfigGUI = new CityImport.CityImportConfigGUI(config, packageToLodDict); + this.cityImportConfig = config; this.progressGui = progressGui; } public void Draw() { PlateauEditorStyle.Heading("地物別設定", "num3.png"); - this.cityLoadConfigGUI.Draw(); + this.cityImportConfigGUI.Draw(); PlateauEditorStyle.Separator(0); PlateauEditorStyle.Separator(0); - ImportButton.Draw(this.cityLoadConfig, progressGui); + ImportButton.Draw(this.cityImportConfig, progressGui); } } } \ No newline at end of file diff --git a/Plugins/Android/libplateau.so b/Plugins/Android/libplateau.so index d60e144f0..4f5b9d23e 100644 --- a/Plugins/Android/libplateau.so +++ b/Plugins/Android/libplateau.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f9e389ac204eb6d0f77786addf12eac880d289fd37d6f4973ddfd2ff3273c6f -size 11579352 +oid sha256:747ba99cb9348e9ca6d26ef3b5e6e17be539e1a946b5a944638596484972faeb +size 11587896 diff --git a/Plugins/Linux/x86_64/libplateau.so b/Plugins/Linux/x86_64/libplateau.so index 0e3c2c90e..30986163c 100644 --- a/Plugins/Linux/x86_64/libplateau.so +++ b/Plugins/Linux/x86_64/libplateau.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e7d2f848b587ac7e22a9a18d2b491514d862486d2bda854ef7afec527b720f86 -size 152484976 +oid sha256:f5c998e2efdc8f88c397dae9d5d06ea9cc1917d6359ae571e0d269af1a1a69da +size 152641448 diff --git a/Plugins/MacOS/arm64/libplateau.dylib b/Plugins/MacOS/arm64/libplateau.dylib index 3c10a4f40..fca47f56b 100644 --- a/Plugins/MacOS/arm64/libplateau.dylib +++ b/Plugins/MacOS/arm64/libplateau.dylib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:302b5261e653ab48c6b2008e06f7d3633206edf4f75b12b587a66e399397d67f -size 21066253 +oid sha256:fa066adaa764a211e31f1f176759ac81c65ea86057808f27c988baf771264350 +size 21070973 diff --git a/Plugins/MacOS/arm64/libz.1.2.13.dylib b/Plugins/MacOS/arm64/libz.1.2.13.dylib index cd82c9205..7015e1f40 100644 --- a/Plugins/MacOS/arm64/libz.1.2.13.dylib +++ b/Plugins/MacOS/arm64/libz.1.2.13.dylib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0940f15ca053229d761b02417228c94cebba144c35b07228b7f25bb04419a18a +oid sha256:a40eb1845d7d9d5131bbef7537ecc2e42a5bf09ab012600556f7412717389901 size 135721 diff --git a/Plugins/MacOS/arm64/libz.1.dylib b/Plugins/MacOS/arm64/libz.1.dylib index cd82c9205..7015e1f40 100644 --- a/Plugins/MacOS/arm64/libz.1.dylib +++ b/Plugins/MacOS/arm64/libz.1.dylib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0940f15ca053229d761b02417228c94cebba144c35b07228b7f25bb04419a18a +oid sha256:a40eb1845d7d9d5131bbef7537ecc2e42a5bf09ab012600556f7412717389901 size 135721 diff --git a/Plugins/MacOS/arm64/libz.dylib b/Plugins/MacOS/arm64/libz.dylib index cd82c9205..7015e1f40 100644 --- a/Plugins/MacOS/arm64/libz.dylib +++ b/Plugins/MacOS/arm64/libz.dylib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0940f15ca053229d761b02417228c94cebba144c35b07228b7f25bb04419a18a +oid sha256:a40eb1845d7d9d5131bbef7537ecc2e42a5bf09ab012600556f7412717389901 size 135721 diff --git a/Plugins/MacOS/x86_64/libplateau.dylib b/Plugins/MacOS/x86_64/libplateau.dylib index de2adfd61..ea696aad9 100755 --- a/Plugins/MacOS/x86_64/libplateau.dylib +++ b/Plugins/MacOS/x86_64/libplateau.dylib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c3d1a91a59982f2fb41090524dfcc23547ce0fc479e258cd3b537dd9141ddd0 -size 22264180 +oid sha256:d30835839ac17426d4b80ca243086b360ec8da2d07867f3680d7831c32ed5dd1 +size 22277428 diff --git a/Plugins/MacOS/x86_64/libz.1.2.13.dylib b/Plugins/MacOS/x86_64/libz.1.2.13.dylib index 9954f88d6..b5044ade2 100755 --- a/Plugins/MacOS/x86_64/libz.1.2.13.dylib +++ b/Plugins/MacOS/x86_64/libz.1.2.13.dylib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f8a2ce2632dc21569cb00b025a45d60f996bb44b13e958ac765ca42f077b60c2 -size 118312 +oid sha256:bde89c752a4cb391254bf8e1b773d300a435751d79706b01d331e91d2e4f6f7c +size 151032 diff --git a/Plugins/MacOS/x86_64/libz.1.dylib b/Plugins/MacOS/x86_64/libz.1.dylib new file mode 100644 index 000000000..b5044ade2 --- /dev/null +++ b/Plugins/MacOS/x86_64/libz.1.dylib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bde89c752a4cb391254bf8e1b773d300a435751d79706b01d331e91d2e4f6f7c +size 151032 diff --git a/Plugins/MacOS/x86_64/libz.1.dylib.meta b/Plugins/MacOS/x86_64/libz.1.dylib.meta new file mode 100644 index 000000000..35445aead --- /dev/null +++ b/Plugins/MacOS/x86_64/libz.1.dylib.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: b3e62a71a6e8f3b4393a66bcb894e85f +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 1 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + DefaultValueInitialized: true + - first: + Standalone: OSXUniversal + second: + enabled: 1 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/MacOS/x86_64/libz.dylib b/Plugins/MacOS/x86_64/libz.dylib new file mode 100644 index 000000000..b5044ade2 --- /dev/null +++ b/Plugins/MacOS/x86_64/libz.dylib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bde89c752a4cb391254bf8e1b773d300a435751d79706b01d331e91d2e4f6f7c +size 151032 diff --git a/Plugins/MacOS/x86_64/libz.dylib.meta b/Plugins/MacOS/x86_64/libz.dylib.meta new file mode 100644 index 000000000..9561ff1fe --- /dev/null +++ b/Plugins/MacOS/x86_64/libz.dylib.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 0d5efc0df5ca03448b65702a0f608d03 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 1 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + DefaultValueInitialized: true + - first: + Standalone: OSXUniversal + second: + enabled: 1 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/Windows/x86_64/plateau.dll b/Plugins/Windows/x86_64/plateau.dll index b6bd45c77..842b27388 100644 --- a/Plugins/Windows/x86_64/plateau.dll +++ b/Plugins/Windows/x86_64/plateau.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9086c475b7d72425b65a8a73725ed5c6581d823b81131bafd6431645e4ce7a68 -size 21715968 +oid sha256:42ba9c28a1d863b82e9c887c398a7cbd642f8be08fa6db610beac128e3b235fb +size 21727232 diff --git a/Plugins/iOS/plateau.framework/Info.plist b/Plugins/iOS/plateau.framework/Info.plist index 11981033d..f60dd1f7f 100644 Binary files a/Plugins/iOS/plateau.framework/Info.plist and b/Plugins/iOS/plateau.framework/Info.plist differ diff --git a/Plugins/iOS/plateau.framework/plateau b/Plugins/iOS/plateau.framework/plateau index c9623ac74..c1327df63 100755 Binary files a/Plugins/iOS/plateau.framework/plateau and b/Plugins/iOS/plateau.framework/plateau differ diff --git a/README.md b/README.md index a71346b8b..09a28398b 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,12 @@ PLATEAU SDK for Unityは、[PLATEAU](https://www.mlit.go.jp/plateau/)の3D都市 - 地図上での範囲選択による3D都市モデルの抽出 - PLATEAUのサーバーで提供されるCityGMLデータへのアクセス - 地形3Dモデルへの航空写真および地図の貼り付け + - テクスチャの自動結合 - 3D都市モデルに含まれる地物のフィルタリング - 3D都市モデルの3Dファイル形式へのエクスポート - 3D都市モデルの属性にアクセスするためのC# API、およびエディタ上での確認 +- 3D都市モデルに含まれる地物の分割・結合 +- 地物型によるマテリアル分割 ![](Documentation~/resources/index/sdk_outline.png) diff --git a/Resources.meta b/Resources.meta new file mode 100644 index 000000000..6b21c6fa4 --- /dev/null +++ b/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0e58d3432830d6d4f87406a1283cb5b1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Resources/PlateauSdkDefaultMaterials.meta b/Resources/PlateauSdkDefaultMaterials.meta new file mode 100644 index 000000000..f27e07eab --- /dev/null +++ b/Resources/PlateauSdkDefaultMaterials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 391eb9c7f3642ef4e9770c32b49f52f7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Materials/Fallback/PlateauDefaultBridge.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultBridge.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultBridge.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultBridge.mat diff --git a/Materials/Fallback/PlateauDefaultBridge.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultBridge.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultBridge.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultBridge.mat.meta diff --git a/Materials/Fallback/PlateauDefaultBuilding.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultBuilding.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultBuilding.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultBuilding.mat diff --git a/Materials/Fallback/PlateauDefaultBuilding.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultBuilding.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultBuilding.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultBuilding.mat.meta diff --git a/Materials/Fallback/PlateauDefaultCityFurniture.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultCityFurniture.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultCityFurniture.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultCityFurniture.mat diff --git a/Materials/Fallback/PlateauDefaultCityFurniture.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultCityFurniture.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultCityFurniture.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultCityFurniture.mat.meta diff --git a/Materials/Fallback/PlateauDefaultDisasterRisk.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultDisasterRisk.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultDisasterRisk.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultDisasterRisk.mat diff --git a/Materials/Fallback/PlateauDefaultDisasterRisk.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultDisasterRisk.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultDisasterRisk.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultDisasterRisk.mat.meta diff --git a/Materials/Fallback/PlateauDefaultLandUse.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultLandUse.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultLandUse.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultLandUse.mat diff --git a/Materials/Fallback/PlateauDefaultLandUse.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultLandUse.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultLandUse.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultLandUse.mat.meta diff --git a/Materials/Fallback/PlateauDefaultRailway.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultRailway.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultRailway.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultRailway.mat diff --git a/Materials/Fallback/PlateauDefaultRailway.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultRailway.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultRailway.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultRailway.mat.meta diff --git a/Materials/Fallback/PlateauDefaultRelief.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultRelief.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultRelief.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultRelief.mat diff --git a/Materials/Fallback/PlateauDefaultRelief.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultRelief.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultRelief.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultRelief.mat.meta diff --git a/Materials/Fallback/PlateauDefaultRoad.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultRoad.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultRoad.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultRoad.mat diff --git a/Materials/Fallback/PlateauDefaultRoad.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultRoad.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultRoad.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultRoad.mat.meta diff --git a/Materials/Fallback/PlateauDefaultSquare.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultSquare.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultSquare.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultSquare.mat diff --git a/Materials/Fallback/PlateauDefaultSquare.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultSquare.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultSquare.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultSquare.mat.meta diff --git a/Materials/Fallback/PlateauDefaultTrack.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultTrack.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultTrack.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultTrack.mat diff --git a/Materials/Fallback/PlateauDefaultTrack.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultTrack.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultTrack.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultTrack.mat.meta diff --git a/Materials/Fallback/PlateauDefaultTunnel.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultTunnel.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultTunnel.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultTunnel.mat diff --git a/Materials/Fallback/PlateauDefaultTunnel.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultTunnel.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultTunnel.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultTunnel.mat.meta diff --git a/Materials/Fallback/PlateauDefaultUndergroundBuilding.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultUndergroundBuilding.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultUndergroundBuilding.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultUndergroundBuilding.mat diff --git a/Materials/Fallback/PlateauDefaultUndergroundBuilding.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultUndergroundBuilding.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultUndergroundBuilding.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultUndergroundBuilding.mat.meta diff --git a/Materials/Fallback/PlateauDefaultUndergroundFacility.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultUndergroundFacility.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultUndergroundFacility.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultUndergroundFacility.mat diff --git a/Materials/Fallback/PlateauDefaultUndergroundFacility.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultUndergroundFacility.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultUndergroundFacility.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultUndergroundFacility.mat.meta diff --git a/Materials/Fallback/PlateauDefaultUnknown.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultUnknown.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultUnknown.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultUnknown.mat diff --git a/Materials/Fallback/PlateauDefaultUnknown.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultUnknown.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultUnknown.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultUnknown.mat.meta diff --git a/Materials/Fallback/PlateauDefaultUrbanPlanningDecision.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultUrbanPlanningDecision.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultUrbanPlanningDecision.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultUrbanPlanningDecision.mat diff --git a/Materials/Fallback/PlateauDefaultUrbanPlanningDecision.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultUrbanPlanningDecision.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultUrbanPlanningDecision.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultUrbanPlanningDecision.mat.meta diff --git a/Materials/Fallback/PlateauDefaultVegetation.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultVegetation.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultVegetation.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultVegetation.mat diff --git a/Materials/Fallback/PlateauDefaultVegetation.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultVegetation.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultVegetation.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultVegetation.mat.meta diff --git a/Materials/Fallback/PlateauDefaultWaterBody.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultWaterBody.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultWaterBody.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultWaterBody.mat diff --git a/Materials/Fallback/PlateauDefaultWaterBody.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultWaterBody.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultWaterBody.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultWaterBody.mat.meta diff --git a/Materials/Fallback/PlateauDefaultWaterway.mat b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultWaterway.mat similarity index 100% rename from Materials/Fallback/PlateauDefaultWaterway.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultWaterway.mat diff --git a/Materials/Fallback/PlateauDefaultWaterway.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauDefaultWaterway.mat.meta similarity index 100% rename from Materials/Fallback/PlateauDefaultWaterway.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauDefaultWaterway.mat.meta diff --git a/Materials/Fallback/PlateauGenericHouse.mat b/Resources/PlateauSdkDefaultMaterials/PlateauGenericHouse.mat similarity index 100% rename from Materials/Fallback/PlateauGenericHouse.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauGenericHouse.mat diff --git a/Materials/Fallback/PlateauGenericHouse.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauGenericHouse.mat.meta similarity index 100% rename from Materials/Fallback/PlateauGenericHouse.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauGenericHouse.mat.meta diff --git a/Materials/Fallback/PlateauGenericWood.mat b/Resources/PlateauSdkDefaultMaterials/PlateauGenericWood.mat similarity index 100% rename from Materials/Fallback/PlateauGenericWood.mat rename to Resources/PlateauSdkDefaultMaterials/PlateauGenericWood.mat diff --git a/Materials/Fallback/PlateauGenericWood.mat.meta b/Resources/PlateauSdkDefaultMaterials/PlateauGenericWood.mat.meta similarity index 100% rename from Materials/Fallback/PlateauGenericWood.mat.meta rename to Resources/PlateauSdkDefaultMaterials/PlateauGenericWood.mat.meta diff --git a/Runtime/CityAdjust/ChangeActive.meta b/Runtime/CityAdjust/ChangeActive.meta new file mode 100644 index 000000000..335d546d6 --- /dev/null +++ b/Runtime/CityAdjust/ChangeActive.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5a2843e945a745e6bfca4fbf124e54f4 +timeCreated: 1699592223 \ No newline at end of file diff --git a/Runtime/CityAdjust/CityDuplicateProcessor.cs b/Runtime/CityAdjust/ChangeActive/CityDuplicateProcessor.cs similarity index 98% rename from Runtime/CityAdjust/CityDuplicateProcessor.cs rename to Runtime/CityAdjust/ChangeActive/CityDuplicateProcessor.cs index 70bc6cd36..a332aeef4 100644 --- a/Runtime/CityAdjust/CityDuplicateProcessor.cs +++ b/Runtime/CityAdjust/ChangeActive/CityDuplicateProcessor.cs @@ -3,7 +3,7 @@ using PLATEAU.CityInfo; using UnityEngine; -namespace PLATEAU.CityAdjust +namespace PLATEAU.CityAdjust.ChangeActive { /// /// 重複した地物があるか検索し、重複して表示されないようにします。 diff --git a/Runtime/CityAdjust/CityDuplicateProcessor.cs.meta b/Runtime/CityAdjust/ChangeActive/CityDuplicateProcessor.cs.meta similarity index 100% rename from Runtime/CityAdjust/CityDuplicateProcessor.cs.meta rename to Runtime/CityAdjust/ChangeActive/CityDuplicateProcessor.cs.meta diff --git a/Runtime/CityAdjust/CityFilter.cs b/Runtime/CityAdjust/ChangeActive/CityFilter.cs similarity index 99% rename from Runtime/CityAdjust/CityFilter.cs rename to Runtime/CityAdjust/ChangeActive/CityFilter.cs index d39569392..020d170b5 100644 --- a/Runtime/CityAdjust/CityFilter.cs +++ b/Runtime/CityAdjust/ChangeActive/CityFilter.cs @@ -6,7 +6,7 @@ using PLATEAU.Dataset; using UnityEngine; -namespace PLATEAU.CityAdjust +namespace PLATEAU.CityAdjust.ChangeActive { internal static class CityFilter { diff --git a/Runtime/CityAdjust/CityFilter.cs.meta b/Runtime/CityAdjust/ChangeActive/CityFilter.cs.meta similarity index 100% rename from Runtime/CityAdjust/CityFilter.cs.meta rename to Runtime/CityAdjust/ChangeActive/CityFilter.cs.meta diff --git a/Runtime/CityAdjust/MaterialAdjust.meta b/Runtime/CityAdjust/MaterialAdjust.meta new file mode 100644 index 000000000..efff807fd --- /dev/null +++ b/Runtime/CityAdjust/MaterialAdjust.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fc1f6f7997c749ecadb57a3629fbfb85 +timeCreated: 1699592254 \ No newline at end of file diff --git a/Runtime/CityAdjust/MaterialAdjust/CityMaterialAdjuster.cs b/Runtime/CityAdjust/MaterialAdjust/CityMaterialAdjuster.cs new file mode 100644 index 000000000..92c8f416b --- /dev/null +++ b/Runtime/CityAdjust/MaterialAdjust/CityMaterialAdjuster.cs @@ -0,0 +1,87 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using PLATEAU.CityInfo; +using PLATEAU.GranularityConvert; +using PLATEAU.PolygonMesh; +using PLATEAU.Util; +using UnityEngine; + +namespace PLATEAU.CityAdjust.MaterialAdjust +{ + /// + /// SDKのモデル調整のマテリアル分けに関する機能を担います。 + /// + internal class CityMaterialAdjuster + { + private readonly IReadOnlyCollection targetObjs; + public MeshGranularity granularity = MeshGranularity.PerPrimaryFeatureObject; + public MaterialAdjustConf MaterialAdjustConf { get; } + public bool DoDestroySrcObjects { get; set; } + + public CityMaterialAdjuster(IReadOnlyCollection targetObjs) + { + this.targetObjs = targetObjs; + var targetTransforms = targetObjs.Select(obj => obj.transform).ToArray(); + var foundTypes = new CityTypeSearcher().Search(targetTransforms); + MaterialAdjustConf = new MaterialAdjustConf(foundTypes); + } + + public async Task Exec() + { + if (targetObjs.Any(obj => obj == null)) + { + Dialogue.Display("対象に削除されたゲームオブジェクトが含まれています。\n選択し直してください。", "OK"); + return; + } + + // 地物タイプに応じてマテリアルを変える下準備として、都市オブジェクトを最小地物単位に分解します。 + var granularityConverter = new CityGranularityConverter(); + var granularityConvertConf = new GranularityConvertOptionUnity( + new GranularityConvertOption(MeshGranularity.PerAtomicFeatureObject, 1), + targetObjs.ToArray(), DoDestroySrcObjects + ); + var result = await granularityConverter.ConvertAsync(granularityConvertConf); + if (!result.IsSucceed) + { + Debug.LogError("ゲームオブジェクトの分解に失敗しました。"); + return; + } + + // マテリアルを変更します。 + foreach (var obj in result.GeneratedObjs) + { + var cityObjGroups = obj.GetComponent(); + if (cityObjGroups == null || cityObjGroups.CityObjects.rootCityObjects.Count == 0) continue; + // 最小地物単位にしたので、rootCityObjectsの数は1つのはずです。 + var cityObj = cityObjGroups.CityObjects.rootCityObjects[0]; + var typeConf = MaterialAdjustConf.GetConfFor(cityObj.type); + if (typeConf == null || !typeConf.ShouldChangeMaterial) continue; + var renderer = obj.GetComponent(); + if (renderer == null) continue; + var materialConf = typeConf.Material; + var materials = renderer.sharedMaterials; + for (int i = 0; i < materials.Length; i++) + { + materials[i] = materialConf; + } + renderer.sharedMaterials = materials; + } + + // 結合し直します。 + var granularityConverterAfter = new CityGranularityConverter(); + var granularityConvertConfAfter = new GranularityConvertOptionUnity( + new GranularityConvertOption(granularity, 1), + result.GeneratedRootObjs.ToArray(), true + ); + var resultAfter = await granularityConverterAfter.ConvertAsync(granularityConvertConfAfter); + if (!resultAfter.IsSucceed) + { + Debug.LogError("ゲームオブジェクトの結合に失敗しました。"); + return; + } + } + } + + +} \ No newline at end of file diff --git a/Runtime/CityAdjust/MaterialAdjust/CityMaterialAdjuster.cs.meta b/Runtime/CityAdjust/MaterialAdjust/CityMaterialAdjuster.cs.meta new file mode 100644 index 000000000..5805d7db9 --- /dev/null +++ b/Runtime/CityAdjust/MaterialAdjust/CityMaterialAdjuster.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8b1a17849e554e30aabb615b0d6333c8 +timeCreated: 1699592265 \ No newline at end of file diff --git a/Runtime/CityAdjust/MaterialAdjust/CityTypeSearcher.cs b/Runtime/CityAdjust/MaterialAdjust/CityTypeSearcher.cs new file mode 100644 index 000000000..2bfac95e7 --- /dev/null +++ b/Runtime/CityAdjust/MaterialAdjust/CityTypeSearcher.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using System.Linq; +using PLATEAU.CityGML; +using PLATEAU.CityInfo; +using PLATEAU.PolygonMesh; +using UnityEngine; + +namespace PLATEAU.CityAdjust.MaterialAdjust +{ + /// + /// ゲームオブジェクトに含まれるCityObjectTypeを探し列挙します。 + /// + internal class CityTypeSearcher + { + /// + /// 引数とその子に含まれるCityObjectTypeを列挙します。 + /// + public CityObjectType[] Search(IReadOnlyCollection targets) + { + HashSet found = new(); + foreach(var target in targets) + { + var cityObjGroups = target.GetComponentsInChildren(); + foreach (var cityObjGroup in cityObjGroups) + { + var meshFilter = cityObjGroup.GetComponent(); + if (meshFilter == null) continue; + var mesh = meshFilter.sharedMesh; + if (mesh == null || mesh.vertices.Length <= 0) continue; + + var indicesInMesh = SearchIndicesInMesh(mesh); + + var cityObjs = cityObjGroup.GetAllCityObjects(); + foreach (var cityObj in cityObjs) + { + // CityObjectIndexのうち、mesh中に実際には存在しないものを除きます。 + var coi = cityObj.IndexInMesh; + if (!indicesInMesh.Contains(coi)) continue; + // 追加します + found.Add(cityObj.CityObjectType); + } + } + + } + + return found.ToArray(); + } + + HashSet SearchIndicesInMesh(UnityEngine.Mesh mesh) + { + HashSet indicesInMesh = new(); + var uv4 = mesh.uv4; + int len = uv4.Length; + for (int i = 0; i < len; i++) + { + var vec = uv4[i]; + indicesInMesh.Add(new CityObjectIndex(Mathf.RoundToInt(vec.x), Mathf.RoundToInt(vec.y))); + + } + + return indicesInMesh; + } + } +} \ No newline at end of file diff --git a/Runtime/CityAdjust/MaterialAdjust/CityTypeSearcher.cs.meta b/Runtime/CityAdjust/MaterialAdjust/CityTypeSearcher.cs.meta new file mode 100644 index 000000000..2932c8461 --- /dev/null +++ b/Runtime/CityAdjust/MaterialAdjust/CityTypeSearcher.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5557058e65a0421a92bce5732997d8b9 +timeCreated: 1699592591 \ No newline at end of file diff --git a/Runtime/CityAdjust/MaterialAdjust/MaterialAdjustConf.cs b/Runtime/CityAdjust/MaterialAdjust/MaterialAdjustConf.cs new file mode 100644 index 000000000..843a622db --- /dev/null +++ b/Runtime/CityAdjust/MaterialAdjust/MaterialAdjustConf.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using PLATEAU.CityGML; +using PLATEAU.CityInfo; +using Material = UnityEngine.Material; + +namespace PLATEAU.CityAdjust.MaterialAdjust +{ + /// + /// 各に対して、そのマテリアルをどのように変更するかの設定値の辞書です。 + /// + internal class MaterialAdjustConf : IEnumerable> + { + private readonly SortedDictionary data; + + /// + /// の配列をキーとして初期化します。 + /// + public MaterialAdjustConf(IReadOnlyCollection types) + { + data = new(); + foreach (var type in types) + { + var typeNode = CityObjectTypeHierarchy.GetNodeByType(type); + if (typeNode == null) + { + throw new ArgumentOutOfRangeException(nameof(types), $"Unknown Type: {type.ToString()}"); + } + data.TryAdd(CityObjectTypeHierarchy.GetNodeByType(type), new MaterialAdjustConfPerType()); + } + } + + /// + /// 引数のに応じた設定を返します。 + /// なければnullを返します。 + /// + public MaterialAdjustConfPerType GetConfFor(CityObjectType type) + { + var typeNode = CityObjectTypeHierarchy.GetNodeByType(type); + if (typeNode != null && data.TryGetValue(typeNode, out var typeConf)) + { + return typeConf; + } + + return null; + } + + /// 対象の地物型の種類数です。 + public int Length => data.Count; + + /// foreachで回せるようにします + public IEnumerator> GetEnumerator() + { + return data.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + internal class MaterialAdjustConfPerType + { + public bool ChangeMaterial { get; set; } + public Material Material { get; set; } + + public bool ShouldChangeMaterial => ChangeMaterial && Material != null; + } +} \ No newline at end of file diff --git a/Runtime/CityAdjust/MaterialAdjust/MaterialAdjustConf.cs.meta b/Runtime/CityAdjust/MaterialAdjust/MaterialAdjustConf.cs.meta new file mode 100644 index 000000000..2a0a9e90f --- /dev/null +++ b/Runtime/CityAdjust/MaterialAdjust/MaterialAdjustConf.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b27a563686944cf986682533e26f9a7e +timeCreated: 1699608108 \ No newline at end of file diff --git a/Runtime/CityExport/Exporters.meta b/Runtime/CityExport/Exporters.meta new file mode 100644 index 000000000..deb81b114 --- /dev/null +++ b/Runtime/CityExport/Exporters.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fdeb0b65841f4fed99e1927a62041779 +timeCreated: 1702319658 \ No newline at end of file diff --git a/Runtime/CityExport/Exporters/CityExporterFbx.cs b/Runtime/CityExport/Exporters/CityExporterFbx.cs new file mode 100644 index 000000000..7d0140a3d --- /dev/null +++ b/Runtime/CityExport/Exporters/CityExporterFbx.cs @@ -0,0 +1,17 @@ +using System.IO; +using PLATEAU.MeshWriter; +using PLATEAU.PolygonMesh; + +namespace PLATEAU.CityExport.Exporters +{ + public class CityExporterFbx : ICityExporter + { + public FbxFileFormat FbxFileFormat { get; set; } = FbxFileFormat.Binary; + + public void Export(string destDir, string fileNameWithoutExtension, Model model) + { + string destPath = Path.Combine(destDir, fileNameWithoutExtension + ".fbx"); + FbxWriter.Write(destPath, model, new FbxWriteOptions(FbxFileFormat)); + } + } +} \ No newline at end of file diff --git a/Runtime/CityExport/Exporters/CityExporterFbx.cs.meta b/Runtime/CityExport/Exporters/CityExporterFbx.cs.meta new file mode 100644 index 000000000..277b61c5d --- /dev/null +++ b/Runtime/CityExport/Exporters/CityExporterFbx.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7033b35386fd449e811655ac35ce07f5 +timeCreated: 1702319672 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/GltfModelExporter.cs b/Runtime/CityExport/Exporters/CityExporterGltf.cs similarity index 70% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/GltfModelExporter.cs rename to Runtime/CityExport/Exporters/CityExporterGltf.cs index ca7a3ace7..3e0339086 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/GltfModelExporter.cs +++ b/Runtime/CityExport/Exporters/CityExporterGltf.cs @@ -1,24 +1,17 @@ -using System; +using System; using System.IO; using PLATEAU.MeshWriter; using PLATEAU.PolygonMesh; -using UnityEditor; -namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts +namespace PLATEAU.CityExport.Exporters { /// - /// Model(中間形式)をGLTFファイルにエクスポートします。 + /// をGLTF形式のファイルにします。 /// - internal class GltfModelExporter : IPlateauModelExporter + public class CityExporterGltf : ICityExporter { public GltfFileFormat GltfFileFormat { get; set; } = GltfFileFormat.GLB; - - public void DrawConfigGUI() - { - GltfFileFormat = (GltfFileFormat)EditorGUILayout.EnumPopup("Gltfフォーマット", GltfFileFormat); - } - public void Export(string destDir, string fileNameWithoutExtension, Model model) { using var gltfWriter = new GltfWriter(); @@ -35,5 +28,6 @@ public void Export(string destDir, string fileNameWithoutExtension, Model model) gltfWriter.Write(gltfFilePath, model, new GltfWriteOptions(GltfFileFormat, textureDir)); } + } -} +} \ No newline at end of file diff --git a/Runtime/CityExport/Exporters/CityExporterGltf.cs.meta b/Runtime/CityExport/Exporters/CityExporterGltf.cs.meta new file mode 100644 index 000000000..3c3320fc7 --- /dev/null +++ b/Runtime/CityExport/Exporters/CityExporterGltf.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a6ce33a8243d4e4885b870fc8c81dcfd +timeCreated: 1702319692 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ObjModelExporter.cs b/Runtime/CityExport/Exporters/CityExporterObj.cs similarity index 54% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ObjModelExporter.cs rename to Runtime/CityExport/Exporters/CityExporterObj.cs index 659dfd3c9..84f76e7b7 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/ObjModelExporter.cs +++ b/Runtime/CityExport/Exporters/CityExporterObj.cs @@ -1,19 +1,14 @@ -using System.IO; +using System.IO; using PLATEAU.MeshWriter; using PLATEAU.PolygonMesh; -namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts +namespace PLATEAU.CityExport.Exporters { /// - /// Model(中間形式)をOBJファイルにエクスポートします。 + /// をOBJ形式のファイルにします。 /// - internal class ObjModelExporter : IPlateauModelExporter + public class CityExporterObj : ICityExporter { - public void DrawConfigGUI() - { - // OBJファイルに固有の設定項目はありません。 - } - public void Export(string destDir, string fileNameWithoutExtension, Model model) { string filePathWithoutExtension = Path.Combine(destDir, fileNameWithoutExtension).Replace('\\', '/'); @@ -21,4 +16,4 @@ public void Export(string destDir, string fileNameWithoutExtension, Model model) objWriter.Write(filePathWithoutExtension + ".obj", model); } } -} +} \ No newline at end of file diff --git a/Runtime/CityExport/Exporters/CityExporterObj.cs.meta b/Runtime/CityExport/Exporters/CityExporterObj.cs.meta new file mode 100644 index 000000000..e79d57aec --- /dev/null +++ b/Runtime/CityExport/Exporters/CityExporterObj.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 191b0a15d07b426e9a037b3204382788 +timeCreated: 1702319686 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/IPlateauModelExporter.cs b/Runtime/CityExport/Exporters/ICityExporter.cs similarity index 64% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/IPlateauModelExporter.cs rename to Runtime/CityExport/Exporters/ICityExporter.cs index a81ce623e..a1e77a302 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts/IPlateauModelExporter.cs +++ b/Runtime/CityExport/Exporters/ICityExporter.cs @@ -1,19 +1,14 @@ -using PLATEAU.PolygonMesh; +using PLATEAU.PolygonMesh; -namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts +namespace PLATEAU.CityExport.Exporters { /// /// (中間形式) をファイルにエクスポートするインターフェイスです。 /// 対応ファイルフォーマットである FBX, GLTF, OBJ ごとにクラスを作ってこのインターフェイスを実装することで、 - /// ファイルフォーマットごとの設定項目の差異とエクスポート方法の差異を吸収します。 + /// ファイルフォーマットごとのエクスポート方法の差異を吸収します。 /// - internal interface IPlateauModelExporter + public interface ICityExporter { - /// - /// ファイルフォーマットに固有の設定項目のGUIを描画します。 - /// - public void DrawConfigGUI(); - /// /// Model(中間形式)をファイルにエクスポートします。 /// @@ -22,4 +17,4 @@ internal interface IPlateauModelExporter /// モデル(中間形式)です。 public void Export(string destDir, string fileNameWithoutExtension, Model model); } -} +} \ No newline at end of file diff --git a/Runtime/CityExport/Exporters/ICityExporter.cs.meta b/Runtime/CityExport/Exporters/ICityExporter.cs.meta new file mode 100644 index 000000000..22595200c --- /dev/null +++ b/Runtime/CityExport/Exporters/ICityExporter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1eac889724284645950a6f73eaf5cc8b +timeCreated: 1702319980 \ No newline at end of file diff --git a/Editor/CityExport/MeshExportOptions.cs b/Runtime/CityExport/MeshExportOptions.cs similarity index 52% rename from Editor/CityExport/MeshExportOptions.cs rename to Runtime/CityExport/MeshExportOptions.cs index f94b54a6e..9df008fd5 100644 --- a/Editor/CityExport/MeshExportOptions.cs +++ b/Runtime/CityExport/MeshExportOptions.cs @@ -1,11 +1,26 @@ -using PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts; +using System; +using PLATEAU.CityExport.Exporters; using PLATEAU.Geometries; -namespace PLATEAU.Editor.CityExport +namespace PLATEAU.CityExport { public enum MeshFileFormat{OBJ, GLTF, FBX} + + public static class MeshFileFormatExtension + { + public static string[] ToExtensions(this MeshFileFormat format) + { + return format switch + { + MeshFileFormat.OBJ => new[] { ".obj" }, + MeshFileFormat.GLTF => new[] { ".glb", ".gltf"}, + MeshFileFormat.FBX => new[] {".fbx"}, + _ => throw new ArgumentOutOfRangeException(nameof(format), "Unknown format.") + }; + } + } - internal struct MeshExportOptions + public struct MeshExportOptions { public enum MeshTransformType{Local/*ローカル座標系*/, PlaneCartesian/*平面直角座標系*/} @@ -15,16 +30,16 @@ public enum MeshTransformType{Local/*ローカル座標系*/, PlaneCartesian/* public MeshFileFormat FileFormat { get; } public CoordinateSystem MeshAxis { get; } - public IPlateauModelExporter PlateauModelExporter { get; } + public ICityExporter Exporter { get; } - public MeshExportOptions(MeshTransformType transformType, bool exportTextures, bool exportHiddenObjects, MeshFileFormat fileFormat, CoordinateSystem meshAxis, IPlateauModelExporter plateauModelExporter) + public MeshExportOptions(MeshTransformType transformType, bool exportTextures, bool exportHiddenObjects, MeshFileFormat fileFormat, CoordinateSystem meshAxis, ICityExporter exporter) { TransformType = transformType; ExportTextures = exportTextures; ExportHiddenObjects = exportHiddenObjects; FileFormat = fileFormat; MeshAxis = meshAxis; - PlateauModelExporter = plateauModelExporter; + Exporter = exporter; } } } diff --git a/Editor/CityExport/MeshExportOptions.cs.meta b/Runtime/CityExport/MeshExportOptions.cs.meta similarity index 100% rename from Editor/CityExport/MeshExportOptions.cs.meta rename to Runtime/CityExport/MeshExportOptions.cs.meta diff --git a/Runtime/CityExport/ModelConvert/SubMeshConvert.meta b/Runtime/CityExport/ModelConvert/SubMeshConvert.meta new file mode 100644 index 000000000..c3fdab7d4 --- /dev/null +++ b/Runtime/CityExport/ModelConvert/SubMeshConvert.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0ccb910515ad4546b02e55b9daef853c +timeCreated: 1701075589 \ No newline at end of file diff --git a/Runtime/CityExport/ModelConvert/SubMeshConvert/IUnityMeshToDllSubMeshConverter.cs b/Runtime/CityExport/ModelConvert/SubMeshConvert/IUnityMeshToDllSubMeshConverter.cs new file mode 100644 index 000000000..0eb241f9e --- /dev/null +++ b/Runtime/CityExport/ModelConvert/SubMeshConvert/IUnityMeshToDllSubMeshConverter.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using PLATEAU.PolygonMesh; +using UnityEngine; +using UnityEngine.Assertions; +using Mesh = UnityEngine.Mesh; + +namespace PLATEAU.CityExport.ModelConvert.SubMeshConvert +{ + /// + /// UnityのMeshから共通ライブラリのSubMeshを構築する機能を抽象化したものです。 + /// なぜ抽象化する必要があるかというと、SubMeshの構築方法にはいくつか種類があるからです。 + /// 具体的には、 + /// エクスポート時にテクスチャを含む設定であれば、テクスチャパスをSubMeshに含めることになります。 + /// エクスポート時にテクスチャを含まない設定であれば、空のSubMeshを用意することになります。 + /// 結合分割時は、ゲームエンジンのマテリアルをIDに変換してSubMeshに含めることになります。 + /// + public interface IUnityMeshToDllSubMeshConverter + { + List Convert(Mesh unityMesh, Renderer renderer); + + delegate SubMesh ForEachUnitySubMeshToDllSubMesh(int startIndex, int endIndex, Material material); + + + /// + /// 変換に使う共通機能です。 + /// Unityの各SubMeshに対して、でDllSubMeshを追加し、そのリストを返します。 + /// + public static List ForEachUnitySubMesh(Mesh unityMesh, Renderer renderer, ForEachUnitySubMeshToDllSubMesh predicate) + { + var indices = unityMesh.triangles; + int subMeshCount = unityMesh.subMeshCount; + var dllSubMeshes = new List(); + Material[] materials = null; + if (renderer != null) materials = renderer.sharedMaterials; + for (int i = 0; i < subMeshCount; i++) + { + var unitySubMesh = unityMesh.GetSubMesh(i); + int startIndex = unitySubMesh.indexStart; + int endIndex = startIndex + unitySubMesh.indexCount - 1; + if (startIndex >= endIndex) continue; + Assert.IsTrue(startIndex < endIndex); + Assert.IsTrue(endIndex < indices.Length); + Assert.IsTrue(startIndex < indices.Length); + Assert.IsTrue(0 <= startIndex); + + var dllSubMesh = predicate(startIndex, endIndex, materials?[i]); + + dllSubMeshes.Add(dllSubMesh); + + } + + return dllSubMeshes; + } + } +} \ No newline at end of file diff --git a/Runtime/CityExport/ModelConvert/SubMeshConvert/IUnityMeshToDllSubMeshConverter.cs.meta b/Runtime/CityExport/ModelConvert/SubMeshConvert/IUnityMeshToDllSubMeshConverter.cs.meta new file mode 100644 index 000000000..493561c98 --- /dev/null +++ b/Runtime/CityExport/ModelConvert/SubMeshConvert/IUnityMeshToDllSubMeshConverter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5aea6fd5e8f54c16b5420f1d5f5723d3 +timeCreated: 1701075621 \ No newline at end of file diff --git a/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithEmptyMaterial.cs b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithEmptyMaterial.cs new file mode 100644 index 000000000..3065b912a --- /dev/null +++ b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithEmptyMaterial.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using PLATEAU.PolygonMesh; +using UnityEngine; +using Mesh = UnityEngine.Mesh; + +namespace PLATEAU.CityExport.ModelConvert.SubMeshConvert +{ + /// + /// UnityのMeshから、見た目情報が空であるSubMeshを生成します。 + /// 特に、エクスポートでテクスチャを含めない設定にしたときに利用されます。 + /// + public class UnityMeshToDllSubMeshWithEmptyMaterial : IUnityMeshToDllSubMeshConverter + { + public List Convert(Mesh unityMesh, Renderer renderer) + { + // 空のSubMeshを1つ生成します。 + var indices = unityMesh.triangles; + return new List + { + SubMesh.Create(0, indices.Length - 1, "") + }; + } + } +} \ No newline at end of file diff --git a/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithEmptyMaterial.cs.meta b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithEmptyMaterial.cs.meta new file mode 100644 index 000000000..ca4758e7c --- /dev/null +++ b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithEmptyMaterial.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 209de076901d4977b4dfa5e81388caeb +timeCreated: 1701076314 \ No newline at end of file diff --git a/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithGameMaterial.cs b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithGameMaterial.cs new file mode 100644 index 000000000..b62e235ed --- /dev/null +++ b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithGameMaterial.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using PLATEAU.PolygonMesh; +using UnityEngine; +using Mesh = UnityEngine.Mesh; + +namespace PLATEAU.CityExport.ModelConvert.SubMeshConvert +{ + /// + /// Unityのから共通ライブラリのを作るにあたって、 + /// 具体的な見た目情報ではなく、UnityマテリアルのIDのみをに記録する変換モードです。 + /// 用途は結合分割機能で、あとでUnityマテリアルの番号からマテリアルを復元するために使う変換モードです。 + /// ここでいうマテリアルIDとは、のインデックスを指します。 + /// + public class UnityMeshToDllSubMeshWithGameMaterial : IUnityMeshToDllSubMeshConverter + { + public List GameMaterials { get; } = new(); + public List Convert(Mesh unityMesh, Renderer renderer) + { + var dllSubMeshes = IUnityMeshToDllSubMeshConverter.ForEachUnitySubMesh( + unityMesh, renderer, + (int startIndex, int endIndex, Material material) => + { + // 各Unity SubMeshについて、マテリアルを記録しながらそのインデックスをDLL SubMeshに送ります。 + var dllSubMesh = SubMesh.Create(startIndex, endIndex, ""); + int found = GameMaterials.IndexOf(material); + if (found < 0) + { + GameMaterials.Add(material); + found = GameMaterials.Count - 1; + } + dllSubMesh.GameMaterialID = found; + return dllSubMesh; + }); + return dllSubMeshes; + } + } +} \ No newline at end of file diff --git a/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithGameMaterial.cs.meta b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithGameMaterial.cs.meta new file mode 100644 index 000000000..3f63a7072 --- /dev/null +++ b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithGameMaterial.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: da313a76296c41eba178d4103cb9f728 +timeCreated: 1701077226 \ No newline at end of file diff --git a/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithTexture.cs b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithTexture.cs new file mode 100644 index 000000000..37584f333 --- /dev/null +++ b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithTexture.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using PLATEAU.CityImport.Import.Convert.MaterialConvert; +using PLATEAU.PolygonMesh; +using UnityEngine; +using Mesh = UnityEngine.Mesh; + +namespace PLATEAU.CityExport.ModelConvert.SubMeshConvert +{ + /// + /// UnityのMeshから共通ライブラリのSubMeshを生成します。 + /// テクスチャ情報を含みます。 + /// 特にエクスポート機能で利用されます。 + /// + public class UnityMeshToDllSubMeshWithTexture : IUnityMeshToDllSubMeshConverter + { + public List Convert(Mesh unityMesh, Renderer renderer) + { + var dllSubMeshes = IUnityMeshToDllSubMeshConverter.ForEachUnitySubMesh( + unityMesh, renderer, + (int startIndex, int endIndex, Material material) => + { + // テクスチャパスは、Unityシーン内のテクスチャの名前に記載してあるので取得します。 + string texturePath = ""; + if (material != null) + { + texturePath = MaterialConverter.MaterialToSubMeshTexturePath(material); + } + return SubMesh.Create(startIndex, endIndex, texturePath); + } + ); + + return dllSubMeshes; + } + } +} \ No newline at end of file diff --git a/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithTexture.cs.meta b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithTexture.cs.meta new file mode 100644 index 000000000..f775000e8 --- /dev/null +++ b/Runtime/CityExport/ModelConvert/SubMeshConvert/UnityMeshToDllSubMeshWithTexture.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 17aef0327959415bb1736c4a39ababf0 +timeCreated: 1701075887 \ No newline at end of file diff --git a/Runtime/CityExport/ModelConvert/UnityMeshToDllModelConverter.cs b/Runtime/CityExport/ModelConvert/UnityMeshToDllModelConverter.cs index 5c0e6f511..ff50401c4 100644 --- a/Runtime/CityExport/ModelConvert/UnityMeshToDllModelConverter.cs +++ b/Runtime/CityExport/ModelConvert/UnityMeshToDllModelConverter.cs @@ -1,11 +1,9 @@ using System.Collections.Generic; -using System.IO; using System.Linq; +using PLATEAU.CityExport.ModelConvert.SubMeshConvert; using PLATEAU.CityInfo; using PLATEAU.Native; using PLATEAU.PolygonMesh; -using PLATEAU.Util; -using UnityEditor; using UnityEngine; using UnityEngine.Assertions; using CityObjectList = PLATEAU.PolygonMesh.CityObjectList; @@ -25,16 +23,17 @@ internal static class UnityMeshToDllModelConverter /// 引数で与えられたゲームオブジェクトとその子(再帰的)を に変換して返します。 /// /// 変換対象ゲームオブジェクトのルートです。 - /// + /// /// false のとき、非Activeのものは対象外とします。 /// 頂点座標を変換するメソッドで、 Vector3 から PlateauVector3d に変換する方法を指定します。 - public static Model Convert(IEnumerable gameObjs, bool includeTexture, bool exportDisabledGameObj, VertexConvertFunc vertexConvertFunc) + /// /// true : Mesh Normalを反転します + public static Model Convert(IEnumerable gameObjs, IUnityMeshToDllSubMeshConverter unityMeshToDllSubMeshConverter, bool exportDisabledGameObj, VertexConvertFunc vertexConvertFunc, bool InvertMesh = false) { var model = Model.Create(); foreach(var go in gameObjs) { var trans = go.transform; - ConvertRecursive(null, trans, model, includeTexture, exportDisabledGameObj, vertexConvertFunc); + ConvertRecursive(null, trans, model, unityMeshToDllSubMeshConverter , exportDisabledGameObj, vertexConvertFunc, InvertMesh); } return model; } @@ -46,16 +45,18 @@ public static Model Convert(IEnumerable gameObjs, bool includeTextur /// の親 Transform に対応する親 Node です。親がない(ルート)のときは null にします。 /// このゲームオブジェクトとその子を再帰的に にします。 /// が null のとき、 に追加されます。 - /// + /// /// false のとき、ActiveでないGameObjectは対象から除外します。 /// - private static void ConvertRecursive(Node parentNode, Transform trans, Model model, bool includeTexture, - bool exportDisabledGameObj, VertexConvertFunc vertexConvertFunc) + /// true : Mesh Normalを反転します + private static void ConvertRecursive(Node parentNode, Transform trans, Model model, IUnityMeshToDllSubMeshConverter unityMeshToDllSubMeshConverter, + bool exportDisabledGameObj, VertexConvertFunc vertexConvertFunc, bool invertMesh) { - if ((!trans.gameObject.activeInHierarchy) && (!exportDisabledGameObj)) return; + bool activeInHierarchy = trans.gameObject.activeInHierarchy; + if ((!activeInHierarchy) && (!exportDisabledGameObj)) return; // メッシュを変換して Node を作ります。 - var node = GameObjToNode(trans, includeTexture, vertexConvertFunc); + var node = GameObjToNode(trans, unityMeshToDllSubMeshConverter, vertexConvertFunc, invertMesh); if (parentNode == null) { @@ -71,20 +72,23 @@ private static void ConvertRecursive(Node parentNode, Transform trans, Model mod node = parentNode.GetChildAt(parentNode.ChildCount - 1); } + node.IsActive = activeInHierarchy; + int numChild = trans.childCount; for (int i = 0; i < numChild; i++) { var childTrans = trans.GetChild(i); - ConvertRecursive(node, childTrans, model, includeTexture, exportDisabledGameObj, vertexConvertFunc); + ConvertRecursive(node, childTrans, model, unityMeshToDllSubMeshConverter, exportDisabledGameObj, vertexConvertFunc, invertMesh); } } - private static Node GameObjToNode(Transform trans, bool includeTexture, - VertexConvertFunc vertexConvertFunc) + private static Node GameObjToNode(Transform trans, IUnityMeshToDllSubMeshConverter unityMeshToDllSubMeshConverter, + VertexConvertFunc vertexConvertFunc, bool invertMesh) { // ノード生成します。 var node = Node.Create(trans.name); - + node.IsActive = trans.gameObject.activeInHierarchy; + // ゲームオブジェクトにメッシュがあるかどうか判定します。 bool hasMesh = false; Mesh unityMesh = null; @@ -102,7 +106,7 @@ private static Node GameObjToNode(Transform trans, bool includeTexture, if (hasMesh) { // メッシュを変換します。 - nativeMesh = ConvertMesh(unityMesh, trans.GetComponent(), includeTexture, vertexConvertFunc); + nativeMesh = ConvertMesh(unityMesh, trans.GetComponent(), unityMeshToDllSubMeshConverter, vertexConvertFunc, invertMesh); int subMeshCount = unityMesh.subMeshCount; for (int i = 0; i < subMeshCount; i++) @@ -154,8 +158,9 @@ private static void AttachCityObjectGroupToNativeMesh(PLATEAUCityObjectGroup cit nativeMesh.CityObjectList = cityObjList; } - private static PolygonMesh.Mesh ConvertMesh(Mesh unityMesh, MeshRenderer meshRenderer, bool includeTexture, - VertexConvertFunc vertexConvertFunc) + private static PolygonMesh.Mesh ConvertMesh(Mesh unityMesh, MeshRenderer meshRenderer, + IUnityMeshToDllSubMeshConverter unityMeshToDllSubMeshConverter, + VertexConvertFunc vertexConvertFunc, bool invertMesh) { var vertices = unityMesh @@ -177,38 +182,21 @@ private static PolygonMesh.Mesh ConvertMesh(Mesh unityMesh, MeshRenderer meshRen .Select(uv => new PlateauVector2f(uv.x, uv.y)) .ToArray(); - Material[] materials = null; - if (meshRenderer != null) materials = meshRenderer.sharedMaterials; - - int subMeshCount = unityMesh.subMeshCount; - var dllSubMeshes = new List(); - if (includeTexture) + if (invertMesh) { - for (int i = 0; i < subMeshCount; i++) + for(int i = 0; i < indices.Length; i += 3) { - var unitySubMesh = unityMesh.GetSubMesh(i); - int startIndex = unitySubMesh.indexStart; - int endIndex = startIndex + unitySubMesh.indexCount - 1; - if (startIndex >= endIndex) continue; - Assert.IsTrue(startIndex < endIndex); - Assert.IsTrue(endIndex < indices.Length); - Assert.IsTrue(startIndex < indices.Length); - Assert.IsTrue(0 <= startIndex); - - // テクスチャパスは、Unityシーン内のテクスチャの名前に記載してあるので取得します。 - string texturePath = ""; - if (materials != null && i < materials.Length) - { - texturePath = GetTexturePathFromMaterialName(materials[i]); - } - dllSubMeshes.Add(SubMesh.Create(startIndex, endIndex, texturePath)); - + var first = indices[i]; + var third = indices[i+2]; + indices[i] = third; + indices[i+2] = first; } } - else - { // テクスチャを含めない設定のとき、サブメッシュはただ1つです。 - dllSubMeshes.Add(SubMesh.Create(0, indices.Length - 1, "")); - } + + Material[] materials = null; + if (meshRenderer != null) materials = meshRenderer.sharedMaterials; + + var dllSubMeshes = unityMeshToDllSubMeshConverter.Convert(unityMesh, meshRenderer); Assert.AreEqual(uv1.Length, vertices.Length); @@ -223,26 +211,5 @@ private static PolygonMesh.Mesh ConvertMesh(Mesh unityMesh, MeshRenderer meshRen return dllMesh; } - - private static string GetTexturePathFromMaterialName(Material mat) - { - if (mat == null) return ""; - var tex = mat.mainTexture; - if (tex == null) return ""; - - #if UNITY_EDITOR - // デフォルトマテリアルのテクスチャは、GetAssetPathでパスを取得できます。 - string texAssetPath = AssetDatabase.GetAssetPath(tex); - if (texAssetPath != "") - { - return Path.GetFullPath(texAssetPath); - } - #endif - - // PLATEAUのテクスチャは、テクスチャ名がパスを表すこととしています。 - // 土地の航空写真もこのケースに含まれます。 - return Path.Combine(PathUtil.PLATEAUSrcFetchDir, tex.name); - - } } } diff --git a/Editor/CityExport/UnityModelExporter.cs b/Runtime/CityExport/UnityModelExporter.cs similarity index 71% rename from Editor/CityExport/UnityModelExporter.cs rename to Runtime/CityExport/UnityModelExporter.cs index b2b8bbdbc..0ce05112b 100644 --- a/Editor/CityExport/UnityModelExporter.cs +++ b/Runtime/CityExport/UnityModelExporter.cs @@ -1,16 +1,18 @@ using System; using System.IO; using PLATEAU.CityExport.ModelConvert; +using PLATEAU.CityExport.ModelConvert.SubMeshConvert; using PLATEAU.CityInfo; +using PLATEAU.Geometries; using PLATEAU.Native; using UnityEngine; -namespace PLATEAU.Editor.CityExport +namespace PLATEAU.CityExport { /// /// Unityのモデルを (中間形式) にしてから 3Dモデルファイルに出力します。 /// - internal static class UnityModelExporter + public static class UnityModelExporter { public static void Export(string destDir, PLATEAUInstancedCityModel instancedCityModel, MeshExportOptions options) { @@ -40,23 +42,30 @@ public static void Export(string destDir, PLATEAUInstancedCityModel instancedCit } using var geoReference = instancedCityModel.GeoReference; + var referencePoint = geoReference.ReferencePoint; var rootPos = trans.position; - + UnityMeshToDllModelConverter.VertexConvertFunc vertexConvertFunc = options.TransformType switch { MeshExportOptions.MeshTransformType.Local => src => { // instancedCityModel を基準とする座標にします。 var pos = src - rootPos; - return new PlateauVector3d(pos.x, pos.y, pos.z); - }, + var Vertex = GeoReference.ConvertAxisToENU(CoordinateSystem.EUN, new PlateauVector3d(pos.x, pos.y, pos.z)); + Vertex = GeoReference.ConvertAxisFromENUTo(options.MeshAxis, Vertex); + return Vertex; + } + , MeshExportOptions.MeshTransformType.PlaneCartesian => src => { // 変換時の referencePoint をオフセットします。 var pos = referencePoint + new PlateauVector3d(src.x - rootPos.x, src.y - rootPos.y, src.z - rootPos.z); - return pos; - }, + var Vertex = GeoReference.ConvertAxisToENU(CoordinateSystem.EUN, pos); + Vertex = GeoReference.ConvertAxisFromENUTo(options.MeshAxis, Vertex); + return Vertex; + } + , _ => throw new Exception("Unknown transform type.") }; @@ -66,12 +75,18 @@ public static void Export(string destDir, PLATEAUInstancedCityModel instancedCit { convertTargets[j] = childTrans.GetChild(j).gameObject; } - using var model = UnityMeshToDllModelConverter.Convert(convertTargets, options.ExportTextures, options.ExportHiddenObjects, vertexConvertFunc); + + IUnityMeshToDllSubMeshConverter unityMeshToDllSubMeshConverter = options.ExportTextures + ? new UnityMeshToDllSubMeshWithTexture() + : new UnityMeshToDllSubMeshWithEmptyMaterial(); + + bool InvertMesh = (options.MeshAxis == CoordinateSystem.ENU || options.MeshAxis == CoordinateSystem.WUN); + using var model = UnityMeshToDllModelConverter.Convert(convertTargets, unityMeshToDllSubMeshConverter, options.ExportHiddenObjects, vertexConvertFunc, InvertMesh); // Model をファイルにして出力します。 // options.PlateauModelExporter は、ファイルフォーマットに応じて FbxModelExporter, GltfModelExporter, ObjModelExporter のいずれかです。 string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(childName); - options.PlateauModelExporter.Export(destDir, fileNameWithoutExtension, model); + options.Exporter.Export(destDir, fileNameWithoutExtension, model); } } } diff --git a/Editor/CityExport/UnityModelExporter.cs.meta b/Runtime/CityExport/UnityModelExporter.cs.meta similarity index 100% rename from Editor/CityExport/UnityModelExporter.cs.meta rename to Runtime/CityExport/UnityModelExporter.cs.meta diff --git a/Runtime/CityImport/AreaSelector/AreaSelectorBehaviour.cs b/Runtime/CityImport/AreaSelector/AreaSelectorBehaviour.cs index b775e533c..fb266cf95 100644 --- a/Runtime/CityImport/AreaSelector/AreaSelectorBehaviour.cs +++ b/Runtime/CityImport/AreaSelector/AreaSelectorBehaviour.cs @@ -5,7 +5,8 @@ using PLATEAU.CityImport.AreaSelector.Display.Gizmos; using PLATEAU.CityImport.AreaSelector.Display.Maps; using PLATEAU.CityImport.AreaSelector.Display.Windows; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Geometries; using PLATEAU.Dataset; using PLATEAU.Native; @@ -26,10 +27,9 @@ namespace PLATEAU.CityImport.AreaSelector internal class AreaSelectorBehaviour : MonoBehaviour { [SerializeField] private string prevScenePath; - [SerializeField] private DatasetSourceConfig datasetSourceConfig; + private ConfigBeforeAreaSelect confBeforeAreaSelect; private AreaSelectGizmosDrawer gizmosDrawer; private IAreaSelectResultReceiver areaSelectResultReceiver; - private int coordinateZoneID; private GeoReference geoReference; private bool prevSceneCameraRotationLocked; private GSIMapLoaderZoomSwitch mapLoader; @@ -42,13 +42,12 @@ internal class AreaSelectorBehaviour : MonoBehaviour public static bool IsAreaSelectEnabled { get; set; } #if UNITY_EDITOR - public void Init(string prevScenePathArg, DatasetSourceConfig datasetSourceConfigArg, IAreaSelectResultReceiver areaSelectResultReceiverArg, int coordinateZoneIDArg, EditorWindow prevEditorWindowArg) + public void Init(string prevScenePathArg, ConfigBeforeAreaSelect confBeforeAreaSelectArg, IAreaSelectResultReceiver areaSelectResultReceiverArg, EditorWindow prevEditorWindowArg) { IsAreaSelectEnabled = true; this.prevScenePath = prevScenePathArg; - this.datasetSourceConfig = datasetSourceConfigArg; + this.confBeforeAreaSelect = confBeforeAreaSelectArg; this.areaSelectResultReceiver = areaSelectResultReceiverArg; - this.coordinateZoneID = coordinateZoneIDArg; this.prevSceneCameraRotationLocked = SceneView.lastActiveSceneView.isRotationLocked; this.prevEditorWindow = prevEditorWindowArg; } @@ -64,7 +63,7 @@ private void Start() ReadOnlyCollection meshCodes; try { - GatherMeshCodes(this.datasetSourceConfig, out meshCodes); + GatherMeshCodes(this.confBeforeAreaSelect.DatasetSourceConfig, out meshCodes); } catch (Exception e) { @@ -85,7 +84,7 @@ private void Start() var drawerObj = new GameObject($"{nameof(AreaSelectGizmosDrawer)}"); this.gizmosDrawer = drawerObj.AddComponent(); - this.gizmosDrawer.Init(meshCodes, this.datasetSourceConfig, this.coordinateZoneID, out this.geoReference); + this.gizmosDrawer.Init(meshCodes, this.confBeforeAreaSelect.DatasetSourceConfig, this.confBeforeAreaSelect.CoordinateZoneID, out this.geoReference); entireExtent = CalcExtentCoversAllMeshCodes(meshCodes); this.mapLoader = new GSIMapLoaderZoomSwitch(this.geoReference, entireExtent); SetInitialCamera(entireExtent); @@ -158,7 +157,7 @@ private static Extent CalcExtentCoversAllMeshCodes(IEnumerable meshCod return entireExtent; } - private static void GatherMeshCodes(DatasetSourceConfig datasetSourceConfig, out ReadOnlyCollection meshCodes) + private static void GatherMeshCodes(IDatasetSourceConfig datasetSourceConfig, out ReadOnlyCollection meshCodes) { using var datasetSource = DatasetSource.Create(datasetSourceConfig); using var accessor = datasetSource.Accessor; @@ -181,46 +180,24 @@ internal void EndAreaSelection() AreaSelectorMenuWindow.Disable(); AreaSelectorGuideWindow.Disable(); LodLegendGUI.Disable(); - var selectedMeshCodes = this.gizmosDrawer.SelectedMeshCodes.ToArray(); - var availablePackageLods = CalcAvailablePackageLodInMeshCodes(selectedMeshCodes, this.datasetSourceConfig); + var selectedMeshCodes = this.gizmosDrawer.SelectedMeshCodes; + var areaSelectResult = new AreaSelectResult(confBeforeAreaSelect, selectedMeshCodes); // 無名関数のキャプチャを利用して、シーン終了後も必要なデータが渡るようにします。 #if UNITY_EDITOR - AreaSelectorDataPass.Exec(this.prevScenePath, selectedMeshCodes, this.areaSelectResultReceiver, availablePackageLods, this.prevEditorWindow); + AreaSelectorDataPass.Exec(this.prevScenePath, areaSelectResult, this.areaSelectResultReceiver, this.prevEditorWindow); #endif } - private static PackageToLodDict CalcAvailablePackageLodInMeshCodes(IEnumerable meshCodes, DatasetSourceConfig datasetSourceConfig) - { - using var datasetSource = DatasetSource.Create(datasetSourceConfig); - using var accessorAll = datasetSource.Accessor; - using var accessor = accessorAll.FilterByMeshCodes(meshCodes); - using var gmlFiles = accessor.GetAllGmlFiles(); - var ret = new PackageToLodDict(); - int gmlCount = gmlFiles.Length; - using var progressBar = new ProgressBar(); - for (int i = 0; i < gmlCount; i++) - { - var gml = gmlFiles.At(i); - int maxLod = gml.GetMaxLod(); - ret.MergePackage(gml.Package, maxLod); - - //Progress表示 - float progress = (float)i / gmlCount; - progressBar.Display("利用可能なデータを検索中です...", progress); - } - return ret; - } - internal void CancelAreaSelection() { AreaSelectorMenuWindow.Disable(); AreaSelectorGuideWindow.Disable(); LodLegendGUI.Disable(); IsAreaSelectEnabled = false; - var emptyAreaSelectResult = new MeshCode[] { }; + var emptyAreaSelectResult = new AreaSelectResult(confBeforeAreaSelect, MeshCodeList.Empty); #if UNITY_EDITOR - AreaSelectorDataPass.Exec(this.prevScenePath, emptyAreaSelectResult, this.areaSelectResultReceiver, new PackageToLodDict(), this.prevEditorWindow); + AreaSelectorDataPass.Exec(this.prevScenePath, emptyAreaSelectResult, this.areaSelectResultReceiver, this.prevEditorWindow); #endif } diff --git a/Runtime/CityImport/AreaSelector/AreaSelectorDataPass.cs b/Runtime/CityImport/AreaSelector/AreaSelectorDataPass.cs index 148108db5..6a714c1af 100644 --- a/Runtime/CityImport/AreaSelector/AreaSelectorDataPass.cs +++ b/Runtime/CityImport/AreaSelector/AreaSelectorDataPass.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.Linq; -using PLATEAU.CityImport.Config.PackageLoadConfigs; -using PLATEAU.Dataset; +using PLATEAU.CityImport.Config; using UnityEngine; using UnityEngine.SceneManagement; @@ -20,20 +17,18 @@ internal static class AreaSelectorDataPass { // シーンをまたいで渡したいデータ private static string prevScenePath; - private static IEnumerable selectedMeshCodes; + private static AreaSelectResult areaSelectResult; private static IAreaSelectResultReceiver areaSelectResultReceiver; - private static PackageToLodDict availablePackageLods; #if UNITY_EDITOR public static void Exec( - string prevScenePathArg, IEnumerable selectedMeshCodesArg, - IAreaSelectResultReceiver areaSelectResultReceiverArg, PackageToLodDict availablePackageLodsArg, + string prevScenePathArg, AreaSelectResult areaSelectResultArg, + IAreaSelectResultReceiver areaSelectResultReceiverArg, EditorWindow prevEditorWindow) { prevScenePath = prevScenePathArg; - selectedMeshCodes = selectedMeshCodesArg; + areaSelectResult = areaSelectResultArg; areaSelectResultReceiver = areaSelectResultReceiverArg; - availablePackageLods = availablePackageLodsArg; EditorSceneManager.sceneOpened += OnBackToPrevScene; EditorSceneManager.OpenScene(prevScenePath); @@ -57,15 +52,10 @@ private static void OnBackToPrevScene(Scene scene, OpenSceneMode __) /// private static void PassAreaSelectDataToBehaviour() { - var areaMeshCodes = selectedMeshCodes - .Select(meshCode => meshCode.ToString()) - .ToArray(); - if (areaMeshCodes.Length == 0) + if (areaSelectResult.AreaMeshCodes.Count == 0) { Debug.Log("地域は選択されませんでした。"); } - - var areaSelectResult = new AreaSelectResult(areaMeshCodes, availablePackageLods); areaSelectResultReceiver.ReceiveResult(areaSelectResult); } } diff --git a/Runtime/CityImport/AreaSelector/Display/Gizmos/AreaSelectGizmosDrawer.cs b/Runtime/CityImport/AreaSelector/Display/Gizmos/AreaSelectGizmosDrawer.cs index e9634fdc7..a6f591f36 100644 --- a/Runtime/CityImport/AreaSelector/Display/Gizmos/AreaSelectGizmosDrawer.cs +++ b/Runtime/CityImport/AreaSelector/Display/Gizmos/AreaSelectGizmosDrawer.cs @@ -4,6 +4,7 @@ using PLATEAU.CityImport.AreaSelector.Display.Gizmos.AreaRectangles; using PLATEAU.CityImport.AreaSelector.Display.Gizmos.LODIcons; using PLATEAU.CityImport.AreaSelector.Display.Maps; +using PLATEAU.CityImport.Config; using PLATEAU.Dataset; using PLATEAU.Geometries; using PLATEAU.Native; @@ -33,7 +34,7 @@ internal class AreaSelectGizmosDrawer : HandlesBase private bool isLeftMouseAndShiftButtonMoved; public void Init( - ReadOnlyCollection meshCodes, DatasetSourceConfig datasetSourceConfig, + ReadOnlyCollection meshCodes, IDatasetSourceConfig datasetSourceConfig, int coordinateZoneID, out GeoReference outGeoReference) { using var progressBar = new ProgressBar(); @@ -75,18 +76,7 @@ public void Init( this.areaSelectionGizmoDrawer.SetUp(); } - public IEnumerable SelectedMeshCodes - { - get - { - List meshCodes = new List(); - foreach (var meshCodeGizmoDrawer in this.meshCodeDrawers) - { - meshCodes.AddRange(meshCodeGizmoDrawer.GetSelectedMeshIds().Select(id => MeshCode.Parse(id)).ToList()); - } - return meshCodes; - } - } + public MeshCodeList SelectedMeshCodes => MeshCodeList.CreateFromMeshCodeDrawers(this.meshCodeDrawers); public void ResetSelectedArea() { diff --git a/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodController.cs b/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodController.cs index 887c4b7a1..7edc573ed 100644 --- a/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodController.cs +++ b/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodController.cs @@ -23,7 +23,7 @@ public class AreaLodController private readonly GeoReference geoReference; private readonly HashSet showLods; - public AreaLodController(DatasetSourceConfig datasetSourceConfig, GeoReference geoReference, IEnumerable allMeshCodes) + public AreaLodController(IDatasetSourceConfig datasetSourceConfig, GeoReference geoReference, IEnumerable allMeshCodes) { this.searcher = new AreaLodSearcher(datasetSourceConfig); this.geoReference = geoReference; diff --git a/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodSearcher.cs b/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodSearcher.cs index 4cc1680e8..824dde4df 100644 --- a/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodSearcher.cs +++ b/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodSearcher.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; namespace PLATEAU.CityImport.AreaSelector.Display.Gizmos.LODIcons @@ -16,7 +16,7 @@ public class AreaLodSearcher private readonly ConcurrentDictionary meshCodeToPackageLodDict; private readonly DatasetSource datasetSource; - public AreaLodSearcher(DatasetSourceConfig datasetSourceConfig) + public AreaLodSearcher(IDatasetSourceConfig datasetSourceConfig) { this.meshCodeToPackageLodDict = new ConcurrentDictionary(); this.datasetSource = DatasetSource.Create(datasetSourceConfig); diff --git a/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodView.cs b/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodView.cs index 2dc9c6717..0d5ba5cc4 100644 --- a/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodView.cs +++ b/Runtime/CityImport/AreaSelector/Display/Gizmos/LODIcons/AreaLodView.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; using PLATEAU.Util; using UnityEditor; diff --git a/Runtime/CityImport/AreaSelector/IAreaSelectResultReceiver.cs b/Runtime/CityImport/AreaSelector/IAreaSelectResultReceiver.cs index 15f43abf0..8daebffff 100644 --- a/Runtime/CityImport/AreaSelector/IAreaSelectResultReceiver.cs +++ b/Runtime/CityImport/AreaSelector/IAreaSelectResultReceiver.cs @@ -1,21 +1,31 @@ -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config; +using PLATEAU.CityImport.Config.PackageImportConfigs; namespace PLATEAU.CityImport.AreaSelector { + /// + /// 範囲選択画面の結果を受け取るインターフェイスです。 + /// internal interface IAreaSelectResultReceiver { public void ReceiveResult(AreaSelectResult areaSelectResult); } + /// + /// 範囲選択画面の結果を格納するクラスです。 + /// public class AreaSelectResult { - public string[] AreaMeshCodes { get; } + public ConfigBeforeAreaSelect ConfBeforeAreaSelect { get; } + public MeshCodeList AreaMeshCodes { get; } public PackageToLodDict PackageToLodDict { get; } - public AreaSelectResult(string[] areaMeshCodes, PackageToLodDict packageToLodDict) + public AreaSelectResult(ConfigBeforeAreaSelect confBeforeAreaSelect, MeshCodeList areaMeshCodes) { + ConfBeforeAreaSelect = confBeforeAreaSelect; AreaMeshCodes = areaMeshCodes; - PackageToLodDict = packageToLodDict; + PackageToLodDict = areaMeshCodes.CalcAvailablePackageLodInMeshCodes(ConfBeforeAreaSelect.DatasetSourceConfig); } + } } diff --git a/Runtime/CityImport/Config/CityLoadConfig.cs b/Runtime/CityImport/Config/CityImportConfig.cs similarity index 54% rename from Runtime/CityImport/Config/CityLoadConfig.cs rename to Runtime/CityImport/Config/CityImportConfig.cs index c6c975284..b76db640c 100644 --- a/Runtime/CityImport/Config/CityLoadConfig.cs +++ b/Runtime/CityImport/Config/CityImportConfig.cs @@ -1,40 +1,28 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using System.Threading; using PLATEAU.CityImport.AreaSelector; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; using PLATEAU.Native; using PLATEAU.PolygonMesh; -using PLATEAU.Util; namespace PLATEAU.CityImport.Config { /// /// 都市インポートの設定です。 /// インポート画面の設定GUIでユーザーはこの設定値を書き換えていくことになります。 - /// パッケージごとのインポート設定についてはを参照してください。 + /// パッケージごとのインポート設定についてはを参照してください。 /// 設定GUIについてはCityAddGUIおよびCityLoadConfigGUIを参照してください。 /// - internal class CityLoadConfig + public class CityImportConfig { - /// - /// 都市モデル読み込み元に関する設定です。 - /// - public DatasetSourceConfig DatasetSourceConfig { get; set; } + public ConfigBeforeAreaSelect ConfBeforeAreaSelect { get; set; } = new ConfigBeforeAreaSelect(); /// /// 範囲選択で選択された範囲です。 /// - public string[] AreaMeshCodes { get; private set; } + public MeshCodeList AreaMeshCodes { get; private set; } - /// - /// 平面直角座標系の番号です。 - /// 次のサイトで示される平面直角座標系の番号です。 - /// https://www.gsi.go.jp/sokuchikijun/jpc.html - /// - public int CoordinateZoneID { get; set; } = 9; /// /// 基準点です。 @@ -45,13 +33,37 @@ internal class CityLoadConfig /// /// 都市モデル読み込みの、パッケージ種ごとの設定です。 /// - public PackageLoadConfigDict PackageLoadConfigDict { get; private set; } + public PackageImportConfigDict PackageImportConfigDict { get; private set; } + private CityImportConfig(){} + + /// + /// デフォルト設定のを作ります。 + /// + public static CityImportConfig CreateDefault() + { + return new CityImportConfig(); + } + /// + /// 範囲選択画面の結果から設定値を作ります。 + /// ユーザーがGUIでインポート設定する場合: + /// ここで設定する値は、範囲選択後にインポート設定GUIで表示される初期値となります。 + /// このあと、ユーザーのGUI操作によって設定値を書き換えていくことになります。 + /// + public static CityImportConfig CreateWithAreaSelectResult(AreaSelectResult result) + { + var ret = CityImportConfig.CreateDefault(); + ret.ConfBeforeAreaSelect = result.ConfBeforeAreaSelect; + ret.InitWithPackageLodsDict(result.PackageToLodDict); + ret.AreaMeshCodes = result.AreaMeshCodes; + ret.ReferencePoint = ret.AreaMeshCodes.ExtentCenter(ret.ConfBeforeAreaSelect.CoordinateZoneID); + return ret; + } - public PackageLoadConfig GetConfigForPackage(PredefinedCityModelPackage package) + public PackageImportConfig GetConfigForPackage(PredefinedCityModelPackage package) { - return PackageLoadConfigDict.GetConfigForPackage(package); + return PackageImportConfigDict.GetConfigForPackage(package); } /// @@ -59,19 +71,18 @@ public PackageLoadConfig GetConfigForPackage(PredefinedCityModelPackage package) /// 多数のファイルから検索するので、実行時間が長くなりがちである点にご注意ください。 /// /// 検索にヒットしたGMLのリストです。 - public List SearchMatchingGMLList( CancellationToken token ) + public List SearchMatchingGMLList( CancellationToken? token ) { - token.ThrowIfCancellationRequested(); + token?.ThrowIfCancellationRequested(); // 地域ID(メッシュコード)で絞り込みます。 - var meshCodes = AreaMeshCodes.Select(MeshCode.Parse).Where(code => code.IsValid).ToArray(); - using var datasetSource = DatasetSource.Create(DatasetSourceConfig); - using var datasetAccessor = datasetSource.Accessor.FilterByMeshCodes(meshCodes); + using var datasetSource = DatasetSource.Create(ConfBeforeAreaSelect.DatasetSourceConfig); + using var datasetAccessor = datasetSource.Accessor.FilterByMeshCodes(AreaMeshCodes.Data); // パッケージ種ごとの設定で「ロードする」にチェックが入っているパッケージ種で絞り込みます。 - var targetPackages = PackageLoadConfigDict.PackagesToLoad(); + var targetPackages = PackageImportConfigDict.PackagesToLoad(); var foundGMLList = new List(); // 絞り込まれたGMLパスを戻り値のリストに追加します。 @@ -88,61 +99,23 @@ public List SearchMatchingGMLList( CancellationToken token ) return foundGMLList; } - - /// - /// 範囲選択画面の結果から設定値を作ります。 - /// ここで設定する値は、範囲選択後にインポート設定GUIで表示される初期値となります。 - /// このあと、ユーザーのGUI操作によって設定値を書き換えていくことになります。 - /// - public void InitWithAreaSelectResult(AreaSelectResult result) - { - InitWithPackageLodsDict(result.PackageToLodDict); - AreaMeshCodes = result.AreaMeshCodes; - SetReferencePointToExtentCenter(); - } /// /// パッケージ種とLODの組から設定値を作ります。 /// private void InitWithPackageLodsDict(PackageToLodDict dict) { - PackageLoadConfigDict = new PackageLoadConfigDict(dict); + PackageImportConfigDict = new PackageImportConfigDict(dict); } - /// - /// 範囲の中心を基準点として設定します。 - /// これは基準点設定GUIに表示される初期値であり、ユーザーが「範囲の中心を入力」ボタンを押したときに設定される値でもあります。 - /// - public PlateauVector3d SetReferencePointToExtentCenter() - { - using var geoReference = CoordinatesConvertUtil.UnityStandardGeoReference(CoordinateZoneID); - - // 選択エリアを囲むExtentを計算 - var extent = new Extent - { - Min = new GeoCoordinate(180.0, 180.0, 0.0), - Max = new GeoCoordinate(-180.0, -180.0, 0.0) - }; - foreach (var meshCode in AreaMeshCodes) - { - var partialExtent = MeshCode.Parse(meshCode).Extent; - extent.Min.Latitude = Math.Min(partialExtent.Min.Latitude, extent.Min.Latitude); - extent.Min.Longitude = Math.Min(partialExtent.Min.Longitude, extent.Min.Longitude); - extent.Max.Latitude = Math.Max(partialExtent.Max.Latitude, extent.Max.Latitude); - extent.Max.Longitude = Math.Max(partialExtent.Max.Longitude, extent.Max.Longitude); - } - var center = geoReference.Project(extent.Center); - ReferencePoint = center; - return center; - } /// /// インポート設定について、C++のstructに変換します。 /// internal MeshExtractOptions CreateNativeConfigFor(PredefinedCityModelPackage package) { var packageConf = GetConfigForPackage(package); - return packageConf.ConvertToNativeOption(ReferencePoint, CoordinateZoneID); + return packageConf.ConvertToNativeOption(ReferencePoint, ConfBeforeAreaSelect.CoordinateZoneID); } private static bool ShouldExcludeCityObjectOutsideExtent(PredefinedCityModelPackage package) diff --git a/Runtime/CityImport/Config/CityLoadConfig.cs.meta b/Runtime/CityImport/Config/CityImportConfig.cs.meta similarity index 100% rename from Runtime/CityImport/Config/CityLoadConfig.cs.meta rename to Runtime/CityImport/Config/CityImportConfig.cs.meta diff --git a/Runtime/CityImport/Config/ConfigBeforeAreaSelect.cs b/Runtime/CityImport/Config/ConfigBeforeAreaSelect.cs new file mode 100644 index 000000000..7b08da6ad --- /dev/null +++ b/Runtime/CityImport/Config/ConfigBeforeAreaSelect.cs @@ -0,0 +1,33 @@ +using PLATEAU.Dataset; + +namespace PLATEAU.CityImport.Config +{ + /// + /// インポート設定のうち、範囲選択より前に行う部分です。 + /// + public class ConfigBeforeAreaSelect + { + /// + /// ローカルかサーバーかは、の型によって処理が分かれます。 + /// + public ConfigBeforeAreaSelect(IDatasetSourceConfig datasetSourceConfig, int coordinateZoneID) + { + DatasetSourceConfig = datasetSourceConfig; + CoordinateZoneID = coordinateZoneID; + } + + public ConfigBeforeAreaSelect(){} + + /// + /// 都市モデル読み込み元に関する設定です。 + /// + public IDatasetSourceConfig DatasetSourceConfig { get; set; } + + /// + /// 平面直角座標系の番号です。 + /// 次のサイトで示される平面直角座標系の番号です。 + /// https://www.gsi.go.jp/sokuchikijun/jpc.html + /// + public int CoordinateZoneID { get; set; } = 9; + } +} \ No newline at end of file diff --git a/Runtime/CityImport/Config/ConfigBeforeAreaSelect.cs.meta b/Runtime/CityImport/Config/ConfigBeforeAreaSelect.cs.meta new file mode 100644 index 000000000..27729125d --- /dev/null +++ b/Runtime/CityImport/Config/ConfigBeforeAreaSelect.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c0077bb4f9bb4f78b38d1acb1d24d1b7 +timeCreated: 1702047506 \ No newline at end of file diff --git a/Runtime/CityImport/Config/MeshCodeList.cs b/Runtime/CityImport/Config/MeshCodeList.cs new file mode 100644 index 000000000..22d849c47 --- /dev/null +++ b/Runtime/CityImport/Config/MeshCodeList.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using PLATEAU.CityImport.AreaSelector.Display.Gizmos.AreaRectangles; +using PLATEAU.CityImport.Config.PackageImportConfigs; +using PLATEAU.Dataset; +using PLATEAU.Native; +using PLATEAU.Util; + +namespace PLATEAU.CityImport.Config +{ + /// + /// メッシュコードのリストによって範囲を表現したクラスです。 + /// + public class MeshCodeList + { + private List data; + public List Data => data; + + private MeshCodeList(IEnumerable data) + { + this.data = data.ToList(); + } + + /// + /// 範囲選択画面のから選択範囲を生成します。 + /// + internal static MeshCodeList CreateFromMeshCodeDrawers(IEnumerable drawers) + { + var meshCodes = new List(); + foreach (var drawer in drawers) + { + meshCodes.AddRange(drawer.GetSelectedMeshIds().Select(MeshCode.Parse).ToList()); + } + + return new MeshCodeList(meshCodes); + } + + /// + /// メッシュコード番号の文字列としての配列から範囲を生成します。 + /// + public static MeshCodeList CreateFromMeshCodesStr(IEnumerable meshCodesStr) + { + return new MeshCodeList(meshCodesStr.Select(MeshCode.Parse).Where(code => code.IsValid)); + } + + /// + /// 空の範囲を生成します。 + /// + internal static MeshCodeList Empty => new MeshCodeList(new List{}); + + /// + /// メッシュコードの数を返します。 + /// + public int Count => data.Count; + + + /// + /// データセットのうち範囲を取り出したとき、利用可能なパッケージとそのLODを求めます。 + /// + public PackageToLodDict CalcAvailablePackageLodInMeshCodes(IDatasetSourceConfig datasetSourceConfig) + { + using var datasetSource = DatasetSource.Create(datasetSourceConfig); + using var accessorAll = datasetSource.Accessor; + using var accessor = accessorAll.FilterByMeshCodes(data); + using var gmlFiles = accessor.GetAllGmlFiles(); + var ret = new PackageToLodDict(); + int gmlCount = gmlFiles.Length; + using var progressBar = new ProgressBar(); + for (int i = 0; i < gmlCount; i++) + { + var gml = gmlFiles.At(i); + int maxLod = gml.GetMaxLod(); + ret.MergePackage(gml.Package, maxLod); + + //Progress表示 + float progress = (float)i / gmlCount; + progressBar.Display("利用可能なデータを検索中です...", progress); + } + return ret; + } + + /// + /// インデックス指定でメッシュコードを取得します。 + /// + public MeshCode At(int index) + { + return data[index]; + } + + /// + /// 範囲の中心を返します。 + /// これは基準点設定GUIに表示される初期値であり、ユーザーが「範囲の中心を入力」ボタンを押したときに設定される値でもあります。 + /// + public PlateauVector3d ExtentCenter(int coordinateZoneID) + { + using var geoReference = CoordinatesConvertUtil.UnityStandardGeoReference(coordinateZoneID); + + // 選択エリアを囲むExtentを計算 + var extent = new Extent + { + Min = new GeoCoordinate(180.0, 180.0, 0.0), + Max = new GeoCoordinate(-180.0, -180.0, 0.0) + }; + foreach (var meshCode in data) + { + var partialExtent = meshCode.Extent; + extent.Min.Latitude = Math.Min(partialExtent.Min.Latitude, extent.Min.Latitude); + extent.Min.Longitude = Math.Min(partialExtent.Min.Longitude, extent.Min.Longitude); + extent.Max.Latitude = Math.Max(partialExtent.Max.Latitude, extent.Max.Latitude); + extent.Max.Longitude = Math.Max(partialExtent.Max.Longitude, extent.Max.Longitude); + } + + var center = geoReference.Project(extent.Center); + return center; + } + } +} \ No newline at end of file diff --git a/Runtime/CityImport/Config/MeshCodeList.cs.meta b/Runtime/CityImport/Config/MeshCodeList.cs.meta new file mode 100644 index 000000000..531a83b7c --- /dev/null +++ b/Runtime/CityImport/Config/MeshCodeList.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6af73fb9ae8948ac87b69c28ccb5c1e1 +timeCreated: 1701939069 \ No newline at end of file diff --git a/Runtime/CityImport/Config/PackageLoadConfigs.meta b/Runtime/CityImport/Config/PackageImportConfigs.meta similarity index 100% rename from Runtime/CityImport/Config/PackageLoadConfigs.meta rename to Runtime/CityImport/Config/PackageImportConfigs.meta diff --git a/Runtime/CityImport/Config/PackageLoadConfigs/LODRange.cs b/Runtime/CityImport/Config/PackageImportConfigs/LODRange.cs similarity index 89% rename from Runtime/CityImport/Config/PackageLoadConfigs/LODRange.cs rename to Runtime/CityImport/Config/PackageImportConfigs/LODRange.cs index f0d5ec5c7..028b78272 100644 --- a/Runtime/CityImport/Config/PackageLoadConfigs/LODRange.cs +++ b/Runtime/CityImport/Config/PackageImportConfigs/LODRange.cs @@ -1,8 +1,8 @@ using System; -namespace PLATEAU.CityImport.Config.PackageLoadConfigs +namespace PLATEAU.CityImport.Config.PackageImportConfigs { - internal struct LODRange + public struct LODRange { /// ユーザーが選択したLOD範囲の下限 public int MinLOD { get; } diff --git a/Runtime/CityImport/Config/PackageLoadConfigs/LODRange.cs.meta b/Runtime/CityImport/Config/PackageImportConfigs/LODRange.cs.meta similarity index 100% rename from Runtime/CityImport/Config/PackageLoadConfigs/LODRange.cs.meta rename to Runtime/CityImport/Config/PackageImportConfigs/LODRange.cs.meta diff --git a/Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfig.cs b/Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfig.cs similarity index 80% rename from Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfig.cs rename to Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfig.cs index 23f5a875a..5bf229b7e 100644 --- a/Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfig.cs +++ b/Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfig.cs @@ -5,24 +5,24 @@ using PLATEAU.PolygonMesh; using UnityEngine; -namespace PLATEAU.CityImport.Config.PackageLoadConfigs +namespace PLATEAU.CityImport.Config.PackageImportConfigs { /// /// PLATEAUCityModelLoader の設定のうち、パッケージごとの設定です。 - /// によって保持されます。 + /// によって保持されます。 /// このクラスに対応するGUIクラスは PackageLoadConfigGUI です。 - /// 設定のうち、一括設定可能な部分はが担います。 + /// 設定のうち、一括設定可能な部分はが担います。 /// /// 実装上の注意: /// ・特定のパッケージ種で追加の設定項目がある場合はサブクラスで実装します。 /// ・この設定項目を追加・削除する場合、も合わせて実装しないと反映されないことに注意してください。 /// - internal class PackageLoadConfig + public class PackageImportConfig { public PredefinedCityModelPackage Package { get; } - public PackageLoadConfigExtendable ConfExtendable { get; } - public bool LoadPackage { get; set; } + public PackageImportConfigExtendable ConfExtendable { get; } + public bool ImportPackage { get; set; } public bool IncludeTexture { @@ -67,13 +67,13 @@ public bool DoSetAttrInfo public Material FallbackMaterial { get; set; } - private PackageLoadConfig(PredefinedCityModelPackage package, bool loadPackage, bool includeTexture, + private PackageImportConfig(PredefinedCityModelPackage package, bool importPackage, bool includeTexture, LODRange lodRange, MeshGranularity meshGranularity, bool doSetMeshCollider, bool doSetAttrInfo, Material fallbackMaterial, bool enableTexturePacking, TexturePackingResolution texturePackingResolution) { Package = package; - LoadPackage = loadPackage; - ConfExtendable = new PackageLoadConfigExtendable( + ImportPackage = importPackage; + ConfExtendable = new PackageImportConfigExtendable( includeTexture, meshGranularity, doSetMeshCollider, doSetAttrInfo, enableTexturePacking, texturePackingResolution ); @@ -82,8 +82,8 @@ private PackageLoadConfig(PredefinedCityModelPackage package, bool loadPackage, } /// コピーコンストラクタ - protected PackageLoadConfig(PackageLoadConfig src) : this( - src.Package, src.LoadPackage, src.IncludeTexture, src.LODRange, + protected PackageImportConfig(PackageImportConfig src) : this( + src.Package, src.ImportPackage, src.IncludeTexture, src.LODRange, src.MeshGranularity, src.DoSetMeshCollider, src.DoSetAttrInfo, src.FallbackMaterial, src.EnableTexturePacking, src.TexturePackingResolution @@ -96,12 +96,12 @@ protected PackageLoadConfig(PackageLoadConfig src) : this( public const float UnitScale = 1.0f; /// - /// に対応した またはそのサブクラスを返します。 + /// に対応した またはそのサブクラスを返します。 /// 具体的には、 - /// 土地以外の場合はを返します。 - /// 土地の場合は追加の設定項目があるので、のサブクラスであるを返します。 + /// 土地以外の場合はを返します。 + /// 土地の場合は追加の設定項目があるので、のサブクラスであるを返します。 /// - public static PackageLoadConfig CreateConfigFor(PredefinedCityModelPackage package, int availableMaxLOD) + public static PackageImportConfig CreateConfigFor(PredefinedCityModelPackage package, int availableMaxLOD) { // 範囲選択の結果が引数に入っているので、それをもとに初期値を決めます。 var predefined = CityModelPackageInfo.GetPredefined(package); @@ -109,9 +109,9 @@ public static PackageLoadConfig CreateConfigFor(PredefinedCityModelPackage packa var lodRange = availableMaxLOD >= 0 ? new LODRange(minLOD, Math.Max(availableMaxLOD, minLOD), Math.Max(availableMaxLOD, minLOD)) : new LODRange(0, 0, 0); - var val = new PackageLoadConfig( + var val = new PackageImportConfig( package: package, - loadPackage: availableMaxLOD >= 0, // 存在しないものはロードしません + importPackage: availableMaxLOD >= 0, // 存在しないものはロードしません includeTexture: predefined.hasAppearance, lodRange: lodRange, MeshGranularity.PerPrimaryFeatureObject, @@ -125,8 +125,8 @@ public static PackageLoadConfig CreateConfigFor(PredefinedCityModelPackage packa // これと似たロジックが PackageLoadSettingGUI.PackageLoadSettingGUIList にあるので、変更時はそちらも合わせて変更をお願いします。 return package switch { - PredefinedCityModelPackage.Relief => new ReliefLoadConfig(val), - _ => new PackageLoadConfig(val) + PredefinedCityModelPackage.Relief => new ReliefImportConfig(val), + _ => new PackageImportConfig(val) }; } @@ -151,7 +151,7 @@ public virtual MeshExtractOptions ConvertToNativeOption(PlateauVector3d referenc texturePackingResolution: (uint)ConfExtendable.TexturePackingResolution.ToPixelCount(), attachMapTile: false, // 土地専用の設定は ReliefLoadSetting で行うので、ここでは false に固定します。 mapTileZoomLevel: 15, // 土地専用の設定は ReliefLoadSetting で行うので、ここでは仮の値にします。 - mapTileURL: ReliefLoadConfig.DefaultMapTileUrl); // 土地専用の設定 + mapTileURL: ReliefImportConfig.DefaultMapTileUrl); // 土地専用の設定 } private static bool ShouldExcludeCityObjectOutsideExtent(PredefinedCityModelPackage package) diff --git a/Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfig.cs.meta b/Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfig.cs.meta similarity index 100% rename from Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfig.cs.meta rename to Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfig.cs.meta diff --git a/Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfigDict.cs b/Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfigDict.cs similarity index 70% rename from Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfigDict.cs rename to Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfigDict.cs index 8efabd9b3..19bd31ce7 100644 --- a/Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfigDict.cs +++ b/Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfigDict.cs @@ -2,37 +2,37 @@ using System.Linq; using PLATEAU.Dataset; -namespace PLATEAU.CityImport.Config.PackageLoadConfigs +namespace PLATEAU.CityImport.Config.PackageImportConfigs { /// /// 都市インポートの設定のうち、パッケージごとのインポート設定をまとめたクラスです。 /// 参照: - /// 具体的な設定については を参照してください。 + /// 具体的な設定については を参照してください。 /// GUIについては PackageLoadConfigGUIList を参照してください。 /// - internal class PackageLoadConfigDict + public class PackageImportConfigDict { - private readonly Dictionary data; + private readonly Dictionary data; /// /// パッケージ種とLODの組から設定値を作ります。 /// - public PackageLoadConfigDict(PackageToLodDict dict) + public PackageImportConfigDict(PackageToLodDict dict) { - data = new Dictionary(); + data = new Dictionary(); foreach (var (package, availableMaxLOD) in dict) { - data.Add(package, PackageLoadConfig.CreateConfigFor(package, availableMaxLOD)); + data.Add(package, PackageImportConfig.CreateConfigFor(package, availableMaxLOD)); } } /// /// 値ペア (パッケージ種, そのパッケージに関する設定) を、パッケージごとの IEnumerable にして返します。 /// - public IEnumerable> ForEachPackagePair => + public IEnumerable> ForEachPackagePair => this.data; - public PackageLoadConfig GetConfigForPackage(PredefinedCityModelPackage package) + public PackageImportConfig GetConfigForPackage(PredefinedCityModelPackage package) { return this.data[package]; } @@ -43,7 +43,7 @@ public PackageLoadConfig GetConfigForPackage(PredefinedCityModelPackage package) public PredefinedCityModelPackage[] PackagesToLoad() { return ForEachPackagePair - .Where(pair => pair.Value.LoadPackage) + .Where(pair => pair.Value.ImportPackage) .Select(pair => pair.Key) .ToArray(); } diff --git a/Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfigDict.cs.meta b/Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfigDict.cs.meta similarity index 100% rename from Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfigDict.cs.meta rename to Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfigDict.cs.meta diff --git a/Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfigExtendable.cs b/Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfigExtendable.cs similarity index 84% rename from Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfigExtendable.cs rename to Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfigExtendable.cs index 6cf950d58..1fdcbef12 100644 --- a/Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfigExtendable.cs +++ b/Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfigExtendable.cs @@ -1,12 +1,12 @@ using System; using PLATEAU.PolygonMesh; -namespace PLATEAU.CityImport.Config.PackageLoadConfigs +namespace PLATEAU.CityImport.Config.PackageImportConfigs { /// - /// のうち、一括設定から設定を引き継ぐことが可能な部分の設定値クラスです。 + /// のうち、一括設定から設定を引き継ぐことが可能な部分の設定値クラスです。 /// - internal class PackageLoadConfigExtendable + public class PackageImportConfigExtendable { public bool IncludeTexture { get; set; } public MeshGranularity MeshGranularity { get; set; } @@ -15,11 +15,11 @@ internal class PackageLoadConfigExtendable public bool EnableTexturePacking { get; set; } public TexturePackingResolution TexturePackingResolution { get; set; } - public PackageLoadConfigExtendable() + public PackageImportConfigExtendable() : this(true, MeshGranularity.PerPrimaryFeatureObject, true, true, true, TexturePackingResolution.W2048H2048){} - public PackageLoadConfigExtendable( + public PackageImportConfigExtendable( bool includeTexture, MeshGranularity meshGranularity, bool doSetMeshCollider, bool doSetAttrInfo, bool enableTexturePacking, TexturePackingResolution texturePackingResolution) @@ -32,7 +32,7 @@ public PackageLoadConfigExtendable( TexturePackingResolution = texturePackingResolution; } - public void CopyFrom(PackageLoadConfigExtendable other) + public void CopyFrom(PackageImportConfigExtendable other) { IncludeTexture = other.IncludeTexture; MeshGranularity = other.MeshGranularity; @@ -58,7 +58,7 @@ public uint GetTexturePackingResolution() /// /// テクスチャ結合後の解像度です。 /// - internal enum TexturePackingResolution : int + public enum TexturePackingResolution : int { W2048H2048 = 0, W4096H4096 = 1, diff --git a/Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfigExtendable.cs.meta b/Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfigExtendable.cs.meta similarity index 100% rename from Runtime/CityImport/Config/PackageLoadConfigs/PackageLoadConfigExtendable.cs.meta rename to Runtime/CityImport/Config/PackageImportConfigs/PackageImportConfigExtendable.cs.meta diff --git a/Runtime/CityImport/Config/PackageLoadConfigs/PackageToLodDict.cs b/Runtime/CityImport/Config/PackageImportConfigs/PackageToLodDict.cs similarity index 97% rename from Runtime/CityImport/Config/PackageLoadConfigs/PackageToLodDict.cs rename to Runtime/CityImport/Config/PackageImportConfigs/PackageToLodDict.cs index 7a30cb312..299d51512 100644 --- a/Runtime/CityImport/Config/PackageLoadConfigs/PackageToLodDict.cs +++ b/Runtime/CityImport/Config/PackageImportConfigs/PackageToLodDict.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using PLATEAU.Dataset; -namespace PLATEAU.CityImport.Config.PackageLoadConfigs +namespace PLATEAU.CityImport.Config.PackageImportConfigs { /// /// パッケージとそこに含まれる最大LODの組です。 diff --git a/Runtime/CityImport/Config/PackageLoadConfigs/PackageToLodDict.cs.meta b/Runtime/CityImport/Config/PackageImportConfigs/PackageToLodDict.cs.meta similarity index 100% rename from Runtime/CityImport/Config/PackageLoadConfigs/PackageToLodDict.cs.meta rename to Runtime/CityImport/Config/PackageImportConfigs/PackageToLodDict.cs.meta diff --git a/Runtime/CityImport/Config/ReliefLoadConfig.cs b/Runtime/CityImport/Config/ReliefImportConfig.cs similarity index 93% rename from Runtime/CityImport/Config/ReliefLoadConfig.cs rename to Runtime/CityImport/Config/ReliefImportConfig.cs index 5b3961d1e..eaf4a874d 100644 --- a/Runtime/CityImport/Config/ReliefLoadConfig.cs +++ b/Runtime/CityImport/Config/ReliefImportConfig.cs @@ -1,5 +1,5 @@ using System; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Native; using PLATEAU.PolygonMesh; @@ -9,7 +9,7 @@ namespace PLATEAU.CityImport.Config /// パッケージごとの設定項目に、土地特有の設定項目を追加したクラスです。 /// これに対応するGUIクラスは ReliefLoadSettingGUI を参照してください。 /// - internal class ReliefLoadConfig : PackageLoadConfig + internal class ReliefImportConfig : PackageImportConfig { public bool AttachMapTile { get; set; } @@ -48,7 +48,7 @@ public string MapTileURL } } - public ReliefLoadConfig(PackageLoadConfig baseConfig) : + public ReliefImportConfig(PackageImportConfig baseConfig) : base(baseConfig) { // 初期値を決めます。 diff --git a/Runtime/CityImport/Config/ReliefLoadConfig.cs.meta b/Runtime/CityImport/Config/ReliefImportConfig.cs.meta similarity index 100% rename from Runtime/CityImport/Config/ReliefLoadConfig.cs.meta rename to Runtime/CityImport/Config/ReliefImportConfig.cs.meta diff --git a/Runtime/CityImport/Load.meta b/Runtime/CityImport/Import.meta similarity index 100% rename from Runtime/CityImport/Load.meta rename to Runtime/CityImport/Import.meta diff --git a/Runtime/CityImport/Load/CityImportProcedure.meta b/Runtime/CityImport/Import/CityImportProcedure.meta similarity index 100% rename from Runtime/CityImport/Load/CityImportProcedure.meta rename to Runtime/CityImport/Import/CityImportProcedure.meta diff --git a/Runtime/CityImport/Load/CityImportProcedure/GmlFetcher.cs b/Runtime/CityImport/Import/CityImportProcedure/GmlFetcher.cs similarity index 91% rename from Runtime/CityImport/Load/CityImportProcedure/GmlFetcher.cs rename to Runtime/CityImport/Import/CityImportProcedure/GmlFetcher.cs index 889689942..001fa92e1 100644 --- a/Runtime/CityImport/Load/CityImportProcedure/GmlFetcher.cs +++ b/Runtime/CityImport/Import/CityImportProcedure/GmlFetcher.cs @@ -1,12 +1,11 @@ using System.Collections.Generic; using System.Linq; -using System.Threading; using System.Threading.Tasks; using PLATEAU.Dataset; using PLATEAU.Util; using UnityEngine; -namespace PLATEAU.CityImport.Load.CityImportProcedure +namespace PLATEAU.CityImport.Import.CityImportProcedure { /// /// PLATEAU インポート処理の1つとして、GMLと関連ファイルを @@ -19,17 +18,17 @@ internal static class GmlFetcher /// GMLと関連ファイルを StreamingAssets フォルダにコピー(サーバーの場合はダウンロード)します。 /// /// Fetch後のGMLファイルの情報を返します。 - public static async Task FetchAsync(GmlFile gmlFileBeforeFetch, string destPath, string gmlName, IProgressDisplay progressDisplay, bool isServer, CancellationToken token) + public static async Task FetchAsync(GmlFile gmlFileBeforeFetch, string destPath, string gmlName, IProgressDisplay progressDisplay, bool isServer) { var fetchedGmlFile = isServer switch { - false => await FetchLocalAsync(gmlFileBeforeFetch, destPath, gmlName, progressDisplay, token), - true => await FetchRemoteAsync(gmlFileBeforeFetch, destPath, gmlName, progressDisplay, token) + false => await FetchLocalAsync(gmlFileBeforeFetch, destPath, gmlName, progressDisplay), + true => await FetchRemoteAsync(gmlFileBeforeFetch, destPath, gmlName, progressDisplay) }; return fetchedGmlFile; } - private static async Task FetchLocalAsync(GmlFile gmlFile, string destPath, string gmlName, IProgressDisplay progressDisplay, CancellationToken token) + private static async Task FetchLocalAsync(GmlFile gmlFile, string destPath, string gmlName, IProgressDisplay progressDisplay) { progressDisplay.SetProgress(gmlName, 5f, "ファイルコピー中"); @@ -38,7 +37,7 @@ private static async Task FetchLocalAsync(GmlFile gmlFile, string destP return fetchedGml; } - private static async Task FetchRemoteAsync(GmlFile remoteGmlFile, string destPath, string gmlName, IProgressDisplay progressDisplay, CancellationToken token) + private static async Task FetchRemoteAsync(GmlFile remoteGmlFile, string destPath, string gmlName, IProgressDisplay progressDisplay) { progressDisplay.SetProgress(gmlName, 5f, $"ダウンロード中 :{gmlName}"); // GMLファイルを StreamingAssets にダウンロードします。 diff --git a/Runtime/CityImport/Load/CityImportProcedure/GmlFetcher.cs.meta b/Runtime/CityImport/Import/CityImportProcedure/GmlFetcher.cs.meta similarity index 100% rename from Runtime/CityImport/Load/CityImportProcedure/GmlFetcher.cs.meta rename to Runtime/CityImport/Import/CityImportProcedure/GmlFetcher.cs.meta diff --git a/Runtime/CityImport/Load/CityImportProcedure/GmlImporter.cs b/Runtime/CityImport/Import/CityImportProcedure/GmlImporter.cs similarity index 89% rename from Runtime/CityImport/Load/CityImportProcedure/GmlImporter.cs rename to Runtime/CityImport/Import/CityImportProcedure/GmlImporter.cs index 4cb74764f..ae6bc302d 100644 --- a/Runtime/CityImport/Load/CityImportProcedure/GmlImporter.cs +++ b/Runtime/CityImport/Import/CityImportProcedure/GmlImporter.cs @@ -3,15 +3,15 @@ using System.Threading; using System.Threading.Tasks; using PLATEAU.CityGML; -using PLATEAU.CityImport.Load.Convert; using PLATEAU.CityImport.Config; +using PLATEAU.CityImport.Import.Convert; using PLATEAU.CityInfo; using PLATEAU.Dataset; using PLATEAU.PolygonMesh; using PLATEAU.Util; using UnityEngine; -namespace PLATEAU.CityImport.Load.CityImportProcedure +namespace PLATEAU.CityImport.Import.CityImportProcedure { /// /// PLATEAU インポート処理の一部として、GMLファイルを1つインポートします。 @@ -22,9 +22,9 @@ internal static class GmlImporter /// /// GMLファイルを1つ fetch (ローカルならコピー、サーバーならダウンロード)し、fetch先の を返します。 /// - internal static async Task Fetch(GmlFile gmlFile, string destPath, CityLoadConfig conf, IProgressDisplay progressDisplay, CancellationToken token) + internal static async Task Fetch(GmlFile gmlFile, string destPath, CityImportConfig conf, IProgressDisplay progressDisplay, CancellationToken? token) { - token.ThrowIfCancellationRequested(); + token?.ThrowIfCancellationRequested(); if (gmlFile.Path == null) { @@ -35,7 +35,7 @@ internal static async Task Fetch(GmlFile gmlFile, string destPath, City destPath = destPath.Replace('\\', '/'); if (!destPath.EndsWith("/")) destPath += "/"; - var fetchedGmlFile = await GmlFetcher.FetchAsync(gmlFile, destPath, gmlName, progressDisplay, conf.DatasetSourceConfig.IsServer, token); + var fetchedGmlFile = await GmlFetcher.FetchAsync(gmlFile, destPath, gmlName, progressDisplay, conf.ConfBeforeAreaSelect.DatasetSourceConfig is DatasetSourceConfigRemote); return fetchedGmlFile; } @@ -44,11 +44,11 @@ internal static async Task Fetch(GmlFile gmlFile, string destPath, City /// fetch済みのGMLファイルを1つインポートします。 /// メインスレッドで呼ぶ必要があります。 /// - internal static async Task Import(GmlFile fetchedGmlFile , CityLoadConfig conf, + internal static async Task Import(GmlFile fetchedGmlFile , CityImportConfig conf, Transform rootTrans, IProgressDisplay progressDisplay, - CancellationToken token) + CancellationToken? token) { - token.ThrowIfCancellationRequested(); + token?.ThrowIfCancellationRequested(); string gmlName = Path.GetFileName(fetchedGmlFile.Path); @@ -91,7 +91,7 @@ internal static async Task Import(GmlFile fetchedGmlFile , CityLoadConfig conf, var placingResult = await PlateauToUnityModelConverter.CityModelToScene( cityModel, meshExtractOptions, conf.AreaMeshCodes, gmlTrans, progressDisplay, gmlName, packageConf.DoSetMeshCollider, packageConf.DoSetAttrInfo, token, packageConf.FallbackMaterial, - infoForToolkits + infoForToolkits, packageConf.MeshGranularity ); if (placingResult.IsSucceed) @@ -104,7 +104,7 @@ internal static async Task Import(GmlFile fetchedGmlFile , CityLoadConfig conf, } } - private static async Task LoadGmlAsync(GmlFile gmlInfo, CancellationToken token) + private static async Task LoadGmlAsync(GmlFile gmlInfo, CancellationToken? token) { string gmlPath = gmlInfo.Path.Replace('\\', '/'); @@ -118,9 +118,9 @@ private static async Task LoadGmlAsync(GmlFile gmlInfo, CancellationT /// gmlファイルをパースします。 /// gmlファイルのパスです。 /// を返します。ロードに問題があった場合は null を返します。 - private static CityModel ParseGML(string gmlAbsolutePath, CancellationToken token) + private static CityModel ParseGML(string gmlAbsolutePath, CancellationToken? token) { - token.ThrowIfCancellationRequested(); + token?.ThrowIfCancellationRequested(); if (!File.Exists(gmlAbsolutePath)) { diff --git a/Runtime/CityImport/Load/CityImportProcedure/GmlImporter.cs.meta b/Runtime/CityImport/Import/CityImportProcedure/GmlImporter.cs.meta similarity index 100% rename from Runtime/CityImport/Load/CityImportProcedure/GmlImporter.cs.meta rename to Runtime/CityImport/Import/CityImportProcedure/GmlImporter.cs.meta diff --git a/Runtime/CityImport/Load/CityImporter.cs b/Runtime/CityImport/Import/CityImporter.cs similarity index 87% rename from Runtime/CityImport/Load/CityImporter.cs rename to Runtime/CityImport/Import/CityImporter.cs index 308968cee..55898d7a9 100644 --- a/Runtime/CityImport/Load/CityImporter.cs +++ b/Runtime/CityImport/Import/CityImporter.cs @@ -4,22 +4,22 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using PLATEAU.CityAdjust; -using PLATEAU.CityImport.Load.CityImportProcedure; +using PLATEAU.CityAdjust.ChangeActive; using PLATEAU.CityImport.Config; -using PLATEAU.CityImport.Config.PackageLoadConfigs; +using PLATEAU.CityImport.Config.PackageImportConfigs; +using PLATEAU.CityImport.Import.CityImportProcedure; using PLATEAU.CityInfo; -using PLATEAU.Geometries; using PLATEAU.Dataset; +using PLATEAU.Geometries; using PLATEAU.Util; using UnityEngine; -namespace PLATEAU.CityImport.Load +namespace PLATEAU.CityImport.Import { /// /// GMLファイルに記載された都市モデルを Unity にインポートします。 /// - internal static class CityImporter + public static class CityImporter { static string lastFetchedGmlRootPath = ""; /// @@ -27,14 +27,15 @@ internal static class CityImporter /// GMLファイルから都市モデルを読み、そのメッシュをUnity向けに変換してシーンに配置します。 /// メインスレッドで呼ぶ必要があります。 /// - public static async Task ImportAsync(CityLoadConfig config, IProgressDisplay progressDisplay, CancellationToken token) + public static async Task ImportAsync(CityImportConfig config, IProgressDisplay progressDisplay, CancellationToken? token) { - var datasetSourceConfig = config.DatasetSourceConfig; + progressDisplay ??= new DummyProgressDisplay(); + var datasetSourceConfig = config.ConfBeforeAreaSelect.DatasetSourceConfig; string destPath = PathUtil.PLATEAUSrcFetchDir; - if ((!datasetSourceConfig.IsServer) && (!Directory.Exists(datasetSourceConfig.LocalSourcePath))) + if ((datasetSourceConfig is DatasetSourceConfigLocal localConf) && (!Directory.Exists(localConf.LocalSourcePath))) { - Debug.LogError($"インポート元パスが存在しません。 sourcePath = {datasetSourceConfig.LocalSourcePath}"); + Debug.LogError($"インポート元パスが存在しません。 sourcePath = {localConf.LocalSourcePath}"); return; } @@ -56,7 +57,7 @@ public static async Task ImportAsync(CityLoadConfig config, IProgressDisplay pro progressDisplay.SetProgress("GMLファイル検索", 100f, "完了"); - if (targetGmls.Count <= 0) + if (targetGmls == null || targetGmls.Count <= 0) { Debug.LogError("該当するGMLファイルがありません。"); return; @@ -77,7 +78,7 @@ public static async Task ImportAsync(CityLoadConfig config, IProgressDisplay pro // ルートのGameObjectにコンポーネントを付けます。 var cityModelComponent = rootTrans.gameObject.AddComponent(); cityModelComponent.GeoReference = - GeoReference.Create(referencePoint, PackageLoadConfig.UnitScale, PackageLoadConfig.MeshAxes, config.CoordinateZoneID); + GeoReference.Create(referencePoint, PackageImportConfig.UnitScale, PackageImportConfig.MeshAxes, config.ConfBeforeAreaSelect.CoordinateZoneID); // GMLファイルを fetch します。これは同期処理にします。 // なぜなら、ファイルコピー が並列で動くのはトラブルの元(特に同じ codelist を同時にコピーしようとしがち) だからです。 diff --git a/Runtime/CityImport/Load/CityImporter.cs.meta b/Runtime/CityImport/Import/CityImporter.cs.meta similarity index 100% rename from Runtime/CityImport/Load/CityImporter.cs.meta rename to Runtime/CityImport/Import/CityImporter.cs.meta diff --git a/Runtime/CityImport/Load/Convert.meta b/Runtime/CityImport/Import/Convert.meta similarity index 100% rename from Runtime/CityImport/Load/Convert.meta rename to Runtime/CityImport/Import/Convert.meta diff --git a/Runtime/CityImport/Load/Convert/AttributeDataHelper.cs b/Runtime/CityImport/Import/Convert/AttributeDataHelper.cs similarity index 99% rename from Runtime/CityImport/Load/Convert/AttributeDataHelper.cs rename to Runtime/CityImport/Import/Convert/AttributeDataHelper.cs index dd069714c..b88199ab6 100644 --- a/Runtime/CityImport/Load/Convert/AttributeDataHelper.cs +++ b/Runtime/CityImport/Import/Convert/AttributeDataHelper.cs @@ -7,7 +7,7 @@ using CityObjectList = PLATEAU.CityInfo.CityObjectList; using PLATEAUCityObjectList = PLATEAU.PolygonMesh.CityObjectList; -namespace PLATEAU.CityImport.Load.Convert +namespace PLATEAU.CityImport.Import.Convert { /// /// PLATEAU の属性情報を Unity の GameObjectで扱えるようにするためのHelperクラスです diff --git a/Runtime/CityImport/Load/Convert/AttributeDataHelper.cs.meta b/Runtime/CityImport/Import/Convert/AttributeDataHelper.cs.meta similarity index 100% rename from Runtime/CityImport/Load/Convert/AttributeDataHelper.cs.meta rename to Runtime/CityImport/Import/Convert/AttributeDataHelper.cs.meta diff --git a/Runtime/CityImport/Load/Convert/ConvertedGameObjData.cs b/Runtime/CityImport/Import/Convert/ConvertedGameObjData.cs similarity index 78% rename from Runtime/CityImport/Load/Convert/ConvertedGameObjData.cs rename to Runtime/CityImport/Import/Convert/ConvertedGameObjData.cs index 529b7694a..60072a954 100644 --- a/Runtime/CityImport/Load/Convert/ConvertedGameObjData.cs +++ b/Runtime/CityImport/Import/Convert/ConvertedGameObjData.cs @@ -2,11 +2,12 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using PLATEAU.CityImport.Import.Convert.MaterialConvert; using PLATEAU.CityInfo; using PLATEAU.PolygonMesh; using UnityEngine; -namespace PLATEAU.CityImport.Load.Convert +namespace PLATEAU.CityImport.Import.Convert { /// /// PLATEAU から Unity の GameObject を生成するためのデータです。 @@ -19,8 +20,12 @@ internal class ConvertedGameObjData { private readonly ConvertedMeshData meshData; private readonly string name; + + /// 再帰的な子です。 private readonly List children = new List(); + private readonly AttributeDataHelper attributeDataHelper; + private bool isActive; /// /// C++側の から変換して @@ -33,6 +38,7 @@ public ConvertedGameObjData(Model plateauModel, AttributeDataHelper attributeDat this.name = "CityRoot"; this.attributeDataHelper = attributeDataHelper; this.attributeDataHelper.SetId(this.name); + this.isActive = true; // RootはActive for (int i = 0; i < plateauModel.RootNodesCount; i++) { var rootNode = plateauModel.GetRootNodeAt(i); @@ -51,6 +57,7 @@ private ConvertedGameObjData(Node plateauNode, AttributeDataHelper attributeData { this.meshData = MeshConverter.Convert(plateauNode.Mesh, plateauNode.Name); this.name = plateauNode.Name; + this.isActive = plateauNode.IsActive; this.attributeDataHelper = attributeDataHelper; this.attributeDataHelper.SetId(this.name); if (meshData != null) @@ -69,31 +76,26 @@ private ConvertedGameObjData(Node plateauNode, AttributeDataHelper attributeData /// 再帰によって子も配置します。 /// 配置したゲームオブジェクトのリストを返します。 /// - public async Task PlaceToScene( - Transform parent, Dictionary cachedMaterials, bool skipRoot, bool doSetMeshCollider, - CancellationToken? token, Material fallbackMaterial, CityObjectGroupInfoForToolkits infoForToolkits) + public async Task PlaceToScene(Transform parent, PlaceToSceneConfig conf, bool skipRoot) { - var result = new PlateauToUnityModelConverter.ConvertResult(); + var result = new GranularityConvertResult(); try { - await PlaceToSceneRecursive(result, parent, cachedMaterials, skipRoot, doSetMeshCollider, token, - fallbackMaterial, 0, infoForToolkits); + await PlaceToSceneRecursive(result, parent, conf, skipRoot, 0); } catch (Exception e) { Debug.LogError($"Failed to placing to scene.\n{e.Message}\n{e.StackTrace}"); - result = PlateauToUnityModelConverter.ConvertResult.Fail(); + result = GranularityConvertResult.Fail(); } return result; } - private async Task PlaceToSceneRecursive(PlateauToUnityModelConverter.ConvertResult result, Transform parent, - Dictionary cachedMaterials, bool skipRoot, bool doSetMeshCollider, - CancellationToken? token, Material fallbackMaterial, int recursiveDepth, - CityObjectGroupInfoForToolkits infoForToolkits) + private async Task PlaceToSceneRecursive(GranularityConvertResult result, Transform parent, + PlaceToSceneConfig conf, bool skipRoot, int recursiveDepth) { - token?.ThrowIfCancellationRequested(); + conf.CancellationToken?.ThrowIfCancellationRequested(); var nextParent = parent; if (!skipRoot) @@ -101,26 +103,28 @@ private async Task PlaceToSceneRecursive(PlateauToUnityModelConverter.ConvertRes if (this.meshData == null || this.meshData.VerticesCount <= 0) { // メッシュがなければ、中身のないゲームオブジェクトを作成します。 - nextParent = new GameObject + var obj = new GameObject { transform = { parent = parent }, name = this.name, - isStatic = true - }.transform; + isStatic = true, + }; + obj.SetActive(isActive); + nextParent = obj.transform; result.Add(nextParent.gameObject, recursiveDepth == 0); } else { // メッシュがあれば、それを配置します。(ただし頂点数が0の場合は配置しません。) - var placedObj = await this.meshData.PlaceToScene(parent, cachedMaterials, fallbackMaterial); + var placedObj = await this.meshData.PlaceToScene(parent, conf.MaterialConverter, conf.FallbackMaterial, isActive); if (placedObj != null) { nextParent = placedObj.transform; - if (doSetMeshCollider) + if (conf.DoSetMeshCollider) { placedObj.AddComponent(); } @@ -135,7 +139,7 @@ private async Task PlaceToSceneRecursive(PlateauToUnityModelConverter.ConvertRes if (serialized != null) { var attrInfo = nextParent.gameObject.AddComponent(); - attrInfo.Init(serialized, infoForToolkits); + attrInfo.Init(serialized, conf.InfoForToolkits, conf.Granularity); } } } @@ -144,7 +148,7 @@ private async Task PlaceToSceneRecursive(PlateauToUnityModelConverter.ConvertRes // 子を再帰的に配置します。 foreach (var child in this.children) { - await child.PlaceToSceneRecursive(result, nextParent, cachedMaterials, false, doSetMeshCollider, token, fallbackMaterial, nextRecursiveDepth, infoForToolkits); + await child.PlaceToSceneRecursive(result, nextParent, conf, false, nextRecursiveDepth); } } } diff --git a/Runtime/CityImport/Load/Convert/ConvertedGameObjData.cs.meta b/Runtime/CityImport/Import/Convert/ConvertedGameObjData.cs.meta similarity index 100% rename from Runtime/CityImport/Load/Convert/ConvertedGameObjData.cs.meta rename to Runtime/CityImport/Import/Convert/ConvertedGameObjData.cs.meta diff --git a/Runtime/CityImport/Import/Convert/ConvertedMeshData.cs b/Runtime/CityImport/Import/Convert/ConvertedMeshData.cs new file mode 100644 index 000000000..623627592 --- /dev/null +++ b/Runtime/CityImport/Import/Convert/ConvertedMeshData.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using PLATEAU.CityImport.Import.Convert.MaterialConvert; +using PLATEAU.Util; +using UnityEngine; +using UnityEngine.Rendering; +using Mesh = UnityEngine.Mesh; + +namespace PLATEAU.CityImport.Import.Convert +{ + /// + /// DLL側の Mesh を Unity向けに変換したものです。 + /// + internal class ConvertedMeshData + { + private readonly Vector3[] vertices; + private readonly Vector2[] uv1; + private readonly Vector2[] uv4; + private readonly List> subMeshTriangles; + public List TextureUrls { get; } + public List GmlMaterials { get; } + public List GameMaterialIDs { get; } + + private string Name { get; } + private int SubMeshCount => this.subMeshTriangles.Count; + + public ConvertedMeshData(Vector3[] vertices, Vector2[] uv1, Vector2[] uv4, List> subMeshTriangles, + List textureUrls, List materials, List gameMaterialIDs, string name) + { + this.vertices = vertices; + this.uv1 = uv1; + this.uv4 = uv4; + this.subMeshTriangles = subMeshTriangles; + TextureUrls = textureUrls; + GmlMaterials = materials; + GameMaterialIDs = gameMaterialIDs; + Name = name; + } + + /// + /// メッシュの形状を変更したあとに必要な後処理です。 + /// + private static void PostProcess(Mesh mesh) + { + mesh.RecalculateNormals(); + mesh.RecalculateTangents(); + mesh.RecalculateBounds(); + } + + /// + /// ゲームオブジェクト、メッシュ、テクスチャの実体を作ってシーンに配置します。 + /// 頂点がない場合は nullが返ります。 + /// + public async Task PlaceToScene(Transform parentTrans, + IDllSubMeshToUnityMaterialConverter materialConverter, Material fallbackMaterial, bool isActive) + { + var mesh = GenerateUnityMesh(); + if (mesh.vertexCount <= 0) return null; + var meshObj = new GameObject(Name) + { + transform = + { + parent = parentTrans + }, + isStatic = true + }; + meshObj.SetActive(isActive); + var meshFilter = GameObjectUtil.AssureComponent(meshObj); + meshFilter.mesh = mesh; + var renderer = GameObjectUtil.AssureComponent(meshObj); + + var materials = new Material[mesh.subMeshCount]; + for (int i = 0; i < mesh.subMeshCount; i++) + { + + //Material設定 + materials[i] = await materialConverter.ConvertAsync( + this, i, fallbackMaterial); + } + + renderer.materials = materials; + return meshObj; + } + + public int VerticesCount => this.vertices.Length; + + /// + /// データをもとにUnity のメッシュを生成します。 + /// + private Mesh GenerateUnityMesh() + { + var mesh = new Mesh + { + indexFormat = IndexFormat.UInt32, + vertices = this.vertices, + uv = this.uv1, + uv4 = this.uv4, + subMeshCount = this.subMeshTriangles.Count + }; + + // subMesh ごとに Indices(Triangles) を UnityのMeshにコピーします。 + for (int i = 0; i < this.subMeshTriangles.Count; i++) + { + mesh.SetTriangles(this.subMeshTriangles[i], i); + } + + PostProcess(mesh); + mesh.name = Name; + return mesh; + } + + + + /// + /// マテリアルとテクスチャのセットをDictionary Keyとして使用するための構造体です。 + /// + internal struct MaterialSet : IEquatable + { + public MaterialSet(CityGML.Material mat, string texturePathPath) + { + if (mat == null) + { + Diffuse = Emissive = Specular = Vector3.zero; + AmbientIntensity = Shininess = Transparency = 0f; + IsSmooth = false; + TexturePath = texturePathPath; + HasMaterial = false; + } + else + { + Diffuse = new Vector3(mat.Diffuse.X, mat.Diffuse.Y, mat.Diffuse.Z); + Emissive = new Vector3(mat.Emissive.X, mat.Emissive.Y, mat.Emissive.Z); + Specular = new Vector3(mat.Specular.X, mat.Specular.Y, mat.Specular.Z); + AmbientIntensity = mat.AmbientIntensity; + Shininess = mat.Shininess; + Transparency = mat.Transparency; + IsSmooth = mat.IsSmooth; + TexturePath = texturePathPath; + HasMaterial = true; + } + } + + public Vector3 Diffuse { get; } + public Vector3 Emissive { get; } + public Vector3 Specular { get; } + public float AmbientIntensity { get; } + public float Shininess { get; } + public float Transparency { get; } + public bool IsSmooth { get; } + public string TexturePath { get; } + public bool HasMaterial { get; } + + public bool Equals(MaterialSet other) + { + return Diffuse.Equals(other.Diffuse) && + Emissive.Equals(other.Emissive) && + Specular.Equals(other.Specular) && + AmbientIntensity.Equals(other.AmbientIntensity) && + Shininess.Equals(other.Shininess) && + Transparency.Equals(other.Transparency) && + IsSmooth.Equals(other.IsSmooth) && + TexturePath.Equals(other.TexturePath) && + HasMaterial.Equals(other.HasMaterial); + } + + public override int GetHashCode() + { + return new + { + Diffuse, Emissive, Specular, AmbientIntensity, Shininess, Transparency, IsSmooth, + Texture = TexturePath, HasMaterial + }.GetHashCode(); + ; + } + } + } +} \ No newline at end of file diff --git a/Runtime/CityImport/Load/Convert/ConvertedMeshData.cs.meta b/Runtime/CityImport/Import/Convert/ConvertedMeshData.cs.meta similarity index 100% rename from Runtime/CityImport/Load/Convert/ConvertedMeshData.cs.meta rename to Runtime/CityImport/Import/Convert/ConvertedMeshData.cs.meta diff --git a/Runtime/CityImport/Import/Convert/MaterialConvert.meta b/Runtime/CityImport/Import/Convert/MaterialConvert.meta new file mode 100644 index 000000000..ae06cc6e8 --- /dev/null +++ b/Runtime/CityImport/Import/Convert/MaterialConvert.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1d3cc50d223d43a3885dcc0bbf5270c8 +timeCreated: 1701097120 \ No newline at end of file diff --git a/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByGameMaterial.cs b/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByGameMaterial.cs new file mode 100644 index 000000000..d2d67892e --- /dev/null +++ b/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByGameMaterial.cs @@ -0,0 +1,41 @@ +using System.Threading.Tasks; +using PLATEAU.CityExport.ModelConvert.SubMeshConvert; +using PLATEAU.Util; +using UnityEngine; + +namespace PLATEAU.CityImport.Import.Convert.MaterialConvert +{ + /// + /// 共通ライブラリのSubMeshをUnityのマテリアルに変換する方法の1つを提供します。 + /// その方法とは、事前に記録したUnityのマテリアルをインデックスから復元します。 + /// + internal class DllSubMeshToUnityMaterialByGameMaterial : IDllSubMeshToUnityMaterialConverter + { + /// + /// 共通ライブラリに変換したときの情報を元にマテリアルを復元します。 + /// + private readonly UnityMeshToDllSubMeshWithGameMaterial toDllMatConverter; + + public DllSubMeshToUnityMaterialByGameMaterial(UnityMeshToDllSubMeshWithGameMaterial toDllMatConverter) + { + this.toDllMatConverter = toDllMatConverter; + } + + public Task ConvertAsync(ConvertedMeshData meshData, int subMeshIndex, Material fallbackMaterial) + { + // このメソッドは同期的に実行可能ですが、インターフェイスの戻り値型に合わせるために戻り値をTaskにします。 + + if (subMeshIndex < 0 || subMeshIndex >= meshData.GameMaterialIDs.Count) + { + return Task.FromResult(RenderUtil.CreateDefaultMaterial()); + } + int gameMaterialID = meshData.GameMaterialIDs[subMeshIndex]; + + if (gameMaterialID < 0) + { + return Task.FromResult(RenderUtil.CreateDefaultMaterial()); + } + return Task.FromResult(toDllMatConverter.GameMaterials[gameMaterialID]); + } + } +} \ No newline at end of file diff --git a/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByGameMaterial.cs.meta b/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByGameMaterial.cs.meta new file mode 100644 index 000000000..c94a8932a --- /dev/null +++ b/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByGameMaterial.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d601dff6c4bd487c8cbfe857b6234b51 +timeCreated: 1701098634 \ No newline at end of file diff --git a/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByTextureMaterial.cs b/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByTextureMaterial.cs new file mode 100644 index 000000000..b57103ad9 --- /dev/null +++ b/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByTextureMaterial.cs @@ -0,0 +1,82 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using PLATEAU.Util; +using PLATEAU.Util.Async; +using UnityEngine; + +namespace PLATEAU.CityImport.Import.Convert.MaterialConvert +{ + /// + /// 共通ライブラリのSubMeshをUnityのマテリアルに変換する方法の1つを提供します。 + /// その方法とは、CityGMLに記載されているテクスチャパスとマテリアルからUnityのマテリアルを生成します。 + /// + internal class DllSubMeshToUnityMaterialByTextureMaterial : IDllSubMeshToUnityMaterialConverter + { + //GMLマテリアル、 テクスチャパス と マテリアルを紐付ける辞書です。同じマテリアルが重複して生成されることを防ぎます。 + private readonly Dictionary cachedMaterials = new (); + + /// + /// DLLのSubMesh情報をUnityのマテリアルに変換します。 + /// 追加可能なら結果をキャッシュにも追加します。 + /// + public async Task ConvertAsync( + ConvertedMeshData meshData, int subMeshIndex, Material fallbackMaterial) + { + // テクスチャがフォールバックマテリアルのものである場合は、フォールバックマテリアルにします。 + var texturePath = meshData.TextureUrls[subMeshIndex]; + var gmlMaterial = meshData.GmlMaterials[subMeshIndex]; + Material fallbackMat = FallbackMaterial.ByMainTextureName(texturePath); + if (fallbackMat != null) + { + return fallbackMat; + } + + // マテリアルがキャッシュ済みの場合はキャッシュを使用 + ConvertedMeshData.MaterialSet materialSet = new ConvertedMeshData.MaterialSet(gmlMaterial, texturePath); + if (cachedMaterials.TryGetValue(materialSet, out var cachedMaterial)) + { + return cachedMaterial; + } + + Material material; + var texture = await TextureLoader.LoadPlateauTextureAsync(texturePath); + // マテリアルを決めるための場合分けです。 + if (gmlMaterial == null && texture == null) + { + // マテリアル指定もテクスチャ指定もない場合、fallbackMaterialを使います。それもない場合、デフォルトマテリアルを使います。 + if (fallbackMaterial == null) + { + material = RenderUtil.CreateDefaultMaterial(); + } + else + { + material = fallbackMaterial; + } + } + else + { + // マテリアル指定があればそれを使い、なければデフォルトマテリアルを使います。 + if (gmlMaterial != null) + { + material = RenderUtil.GetPLATEAUX3DMaterialByCityGMLMaterial(gmlMaterial); + material.name = gmlMaterial.ID; + } + else + { + material = RenderUtil.CreateDefaultMaterial(); + } + + //Textureがあればそれを使います。 + if (texture != null) + { + material.mainTexture = texture; + material.name = texture.name; + } + + } + + cachedMaterials.Add(materialSet, material); + return material; + } + } +} \ No newline at end of file diff --git a/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByTextureMaterial.cs.meta b/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByTextureMaterial.cs.meta new file mode 100644 index 000000000..71d1ef95d --- /dev/null +++ b/Runtime/CityImport/Import/Convert/MaterialConvert/DllSubMeshToUnityMaterialByTextureMaterial.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c5a723cebcbc4e8b84e6c9a1b08cdadc +timeCreated: 1701097401 \ No newline at end of file diff --git a/Runtime/CityImport/Import/Convert/MaterialConvert/IDllSubMeshToUnityMaterialConverter.cs b/Runtime/CityImport/Import/Convert/MaterialConvert/IDllSubMeshToUnityMaterialConverter.cs new file mode 100644 index 000000000..56de81d6f --- /dev/null +++ b/Runtime/CityImport/Import/Convert/MaterialConvert/IDllSubMeshToUnityMaterialConverter.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using UnityEngine; + +namespace PLATEAU.CityImport.Import.Convert.MaterialConvert +{ + /// + /// 共通ライブラリのSubMeshをUnityのマテリアルに変換する機能を抽象化したものです。 + /// なぜ抽象化するかというと、マテリアルの変換の方法が次のとおり複数あるためです。 + /// 1つ目は、インポート時に、CityGMLのテクスチャとマテリアル情報からマテリアルを生成する方法。 + /// 2つ目は、分割結合時に、ゲームエンジンのマテリアル番号からマテリアルを復元する方法です。 + /// それぞれ子クラスで実装し、クラスによって挙動を切り替えます。 + /// + internal interface IDllSubMeshToUnityMaterialConverter + { + Task ConvertAsync(ConvertedMeshData meshData, int subMeshIndex, Material fallbackMaterial); + } +} \ No newline at end of file diff --git a/Runtime/CityImport/Import/Convert/MaterialConvert/IDllSubMeshToUnityMaterialConverter.cs.meta b/Runtime/CityImport/Import/Convert/MaterialConvert/IDllSubMeshToUnityMaterialConverter.cs.meta new file mode 100644 index 000000000..d03a64b77 --- /dev/null +++ b/Runtime/CityImport/Import/Convert/MaterialConvert/IDllSubMeshToUnityMaterialConverter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 66004396e52546808058b0898f84c995 +timeCreated: 1701097821 \ No newline at end of file diff --git a/Runtime/CityImport/Import/Convert/MaterialConvert/MaterialConverter.cs b/Runtime/CityImport/Import/Convert/MaterialConvert/MaterialConverter.cs new file mode 100644 index 000000000..9b2ebab56 --- /dev/null +++ b/Runtime/CityImport/Import/Convert/MaterialConvert/MaterialConverter.cs @@ -0,0 +1,38 @@ +using System.IO; +using PLATEAU.Util; +using UnityEditor; +using UnityEngine; + +namespace PLATEAU.CityImport.Import.Convert.MaterialConvert +{ + /// + /// Unityのマテリアルと、DLLのSubMesh情報を相互変換します。 + /// + internal class MaterialConverter + { + + + /// + /// Unityのマテリアルを、DLLのSubMeshのTexturePathに変換します。 + /// + public static string MaterialToSubMeshTexturePath(Material mat) + { + if (mat == null) return ""; + var tex = mat.mainTexture; + if (tex == null) return ""; + +#if UNITY_EDITOR + // デフォルトマテリアルのテクスチャは、GetAssetPathでパスを取得できます。 + string texAssetPath = AssetDatabase.GetAssetPath(tex); + if (texAssetPath != "") + { + return Path.GetFullPath(texAssetPath); + } +#endif + // PLATEAUのテクスチャは、テクスチャ名がパスを表すこととしています。 + // 土地の航空写真もこのケースに含まれます。 + return Path.Combine(PathUtil.PLATEAUSrcFetchDir, tex.name); + } + + } +} \ No newline at end of file diff --git a/Runtime/CityImport/Import/Convert/MaterialConvert/MaterialConverter.cs.meta b/Runtime/CityImport/Import/Convert/MaterialConvert/MaterialConverter.cs.meta new file mode 100644 index 000000000..90ef47505 --- /dev/null +++ b/Runtime/CityImport/Import/Convert/MaterialConvert/MaterialConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6efb44c14923bfe44a9005d65f07c716 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/CityImport/Import/Convert/PlaceToSceneConfig.cs b/Runtime/CityImport/Import/Convert/PlaceToSceneConfig.cs new file mode 100644 index 000000000..95ce1a70e --- /dev/null +++ b/Runtime/CityImport/Import/Convert/PlaceToSceneConfig.cs @@ -0,0 +1,42 @@ +using System.Threading; +using PLATEAU.CityGML; +using PLATEAU.CityImport.Import.Convert.MaterialConvert; +using PLATEAU.CityInfo; +using PLATEAU.PolygonMesh; + +namespace PLATEAU.CityImport.Import.Convert +{ + /// + /// PLATEAUモデルをシーンに配置するときの設定のうち、1つのモデルの処理中の間は値が不変であるものを集めたクラスです。 + /// + internal class PlaceToSceneConfig + { + /// マテリアルを変換する方法です。 + public IDllSubMeshToUnityMaterialConverter MaterialConverter { get; } + + /// メッシュコライダーをセットするかしないかです。 + public bool DoSetMeshCollider { get; } + + /// キャンセル用トークンです。 + public CancellationToken? CancellationToken { get; } + + /// モデル中にテクスチャやマテリアル指定がない場合に利用するデフォルトマテリアルです。 + public UnityEngine.Material FallbackMaterial { get; } + + /// PLATEAU SDK Toolkits for Unityとの連携のために必要となるデータです。 + public CityObjectGroupInfoForToolkits InfoForToolkits { get; } + + public MeshGranularity Granularity { get; } + + + public PlaceToSceneConfig(IDllSubMeshToUnityMaterialConverter materialConverter, bool doSetMeshCollider, CancellationToken? cancellationToken, UnityEngine.Material fallbackMaterial, CityObjectGroupInfoForToolkits infoForToolkits, MeshGranularity granularity) + { + MaterialConverter = materialConverter; + DoSetMeshCollider = doSetMeshCollider; + CancellationToken = cancellationToken; + FallbackMaterial = fallbackMaterial; + InfoForToolkits = infoForToolkits; + Granularity = granularity; + } + } +} \ No newline at end of file diff --git a/Runtime/CityImport/Import/Convert/PlaceToSceneConfig.cs.meta b/Runtime/CityImport/Import/Convert/PlaceToSceneConfig.cs.meta new file mode 100644 index 000000000..1bae2655b --- /dev/null +++ b/Runtime/CityImport/Import/Convert/PlaceToSceneConfig.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4d280558b1394339a10ed4275b6d57ee +timeCreated: 1702365879 \ No newline at end of file diff --git a/Runtime/CityImport/Load/Convert/PlateauPolygonConverter.cs b/Runtime/CityImport/Import/Convert/PlateauPolygonConverter.cs similarity index 82% rename from Runtime/CityImport/Load/Convert/PlateauPolygonConverter.cs rename to Runtime/CityImport/Import/Convert/PlateauPolygonConverter.cs index df1e75f60..2d6bd479e 100644 --- a/Runtime/CityImport/Load/Convert/PlateauPolygonConverter.cs +++ b/Runtime/CityImport/Import/Convert/PlateauPolygonConverter.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; -namespace PLATEAU.CityImport.Load.Convert +namespace PLATEAU.CityImport.Import.Convert { /// /// PLATEAUの を Unityの Mesh 用データに変換します。 @@ -19,8 +19,11 @@ public static ConvertedMeshData Convert(PolygonMesh.Mesh plateauMesh, string mes { if (plateauMesh == null) return null; CopyVerticesAndUV(plateauMesh, out var unityVerts, out var unityUV1, out var unityUV4); - CopySubMeshInfo(plateauMesh, out var subMeshTriangles, out var texturePaths, out var materials); - var meshData = new ConvertedMeshData(unityVerts, unityUV1, unityUV4, subMeshTriangles, texturePaths, materials, meshName); + CopySubMeshInfo( + plateauMesh, + out var subMeshTriangles, out var texturePaths, out var materials, + out var gameMaterialIDs); + var meshData = new ConvertedMeshData(unityVerts, unityUV1, unityUV4, subMeshTriangles, texturePaths, materials, gameMaterialIDs, meshName); return meshData; } @@ -42,11 +45,15 @@ private static void CopyVerticesAndUV(PolygonMesh.Mesh plateauMesh, out Vector3[ } } - private static void CopySubMeshInfo(PolygonMesh.Mesh plateauMesh, out List> subMeshTriangles, out List texturePaths, out List materials) + private static void CopySubMeshInfo( + PolygonMesh.Mesh plateauMesh, + out List> subMeshTriangles, out List texturePaths, out List materials, + out List gameMaterialIDs) { subMeshTriangles = new List>(); texturePaths = new List(); materials = new List(); + gameMaterialIDs = new List(); int numSubMesh = plateauMesh.SubMeshCount; for (int i = 0; i < numSubMesh; i++) { @@ -64,6 +71,7 @@ private static void CopySubMeshInfo(PolygonMesh.Mesh plateauMesh, out List /// 都市の3Dモデルを PLATEAU から Unity に変換してシーンに配置します。 @@ -29,42 +28,46 @@ internal static class PlateauToUnityModelConverter /// 非同期処理です。必ずメインスレッドで呼ぶ必要があります。 /// 成否を bool で返します。 /// - public static async Task CityModelToScene( - CityModel cityModel, MeshExtractOptions meshExtractOptions, string[] selectedMeshCodes, + public static async Task CityModelToScene( + CityModel cityModel, MeshExtractOptions meshExtractOptions, MeshCodeList selectedMeshCodes, Transform parentTrans, IProgressDisplay progressDisplay, string progressName, - bool doSetMeshCollider, bool doSetAttrInfo, CancellationToken token, UnityEngine.Material fallbackMaterial, - CityObjectGroupInfoForToolkits infoForToolkits + bool doSetMeshCollider, bool doSetAttrInfo, CancellationToken? token, UnityEngine.Material fallbackMaterial, + CityObjectGroupInfoForToolkits infoForToolkits, MeshGranularity granularity ) { Debug.Log($"load started"); - token.ThrowIfCancellationRequested(); + token?.ThrowIfCancellationRequested(); AttributeDataHelper attributeDataHelper = new AttributeDataHelper(new SerializedCityObjectGetterFromCityModel(cityModel), meshExtractOptions.MeshGranularity, doSetAttrInfo); Model plateauModel; try { - plateauModel = await Task.Run(() => ExtractMeshes(cityModel, meshExtractOptions, selectedMeshCodes, token)); + plateauModel = await Task.Run(() => ExtractMeshes(cityModel, meshExtractOptions, selectedMeshCodes)); } catch (Exception e) { Debug.LogError("メッシュデータの抽出に失敗しました。\n" + e); - return ConvertResult.Fail(); + return GranularityConvertResult.Fail(); } + + var materialConverter = new DllSubMeshToUnityMaterialByTextureMaterial(); + var placeToSceneConf = new PlaceToSceneConfig(materialConverter, doSetMeshCollider, token, fallbackMaterial, + infoForToolkits, granularity); return await PlateauModelToScene( - parentTrans, progressDisplay, progressName, doSetMeshCollider, token, - fallbackMaterial, plateauModel, attributeDataHelper, true, infoForToolkits); + parentTrans, progressDisplay, progressName, placeToSceneConf, + plateauModel, attributeDataHelper, true); } /// /// 共通ライブラリのModelをUnityのゲームオブジェクトに変換してシーンに配置します。 /// これにより配置されたゲームオブジェクトを引数 に追加します。 /// - public static async Task PlateauModelToScene(Transform parentTrans, IProgressDisplay progressDisplay, - string progressName, bool doSetMeshCollider, CancellationToken? token, Material fallbackMaterial, Model plateauModel, - AttributeDataHelper attributeDataHelper, bool skipRoot, CityObjectGroupInfoForToolkits infoForToolkits) + public static async Task PlateauModelToScene(Transform parentTrans, IProgressDisplay progressDisplay, + string progressName, PlaceToSceneConfig placeToSceneConf, Model plateauModel, + AttributeDataHelper attributeDataHelper, bool skipRoot) { // ここの処理は 処理A と 処理B に分割されています。 // Unityのメッシュデータを操作するのは 処理B のみであり、 @@ -89,22 +92,18 @@ public static async Task PlateauModelToScene(Transform parentTran catch (Exception e) { Debug.LogError("メッシュデータの取得に失敗しました。\n" + e); - return ConvertResult.Fail(); + return GranularityConvertResult.Fail(); } // 処理B : // 実際にメッシュを操作してシーンに配置します。 // こちらはメインスレッドでのみ実行可能なので、Loadメソッドはメインスレッドから呼ぶ必要があります。 - //GMLマテリアル、 テクスチャパス と マテリアルを紐付ける辞書です。同じマテリアルが重複して生成されることを防ぎます。 - Dictionary cachedMaterials = new Dictionary(); - progressDisplay.SetProgress(progressName, 80f, "シーンに配置中"); - var result = new ConvertResult(); + var result = new GranularityConvertResult(); - var innerResult = await meshObjsData.PlaceToScene(parentTrans, cachedMaterials, skipRoot, doSetMeshCollider, - token, fallbackMaterial, infoForToolkits); + var innerResult = await meshObjsData.PlaceToScene(parentTrans, placeToSceneConf, skipRoot); if (innerResult.IsSucceed) { result.Merge(innerResult); @@ -112,7 +111,7 @@ public static async Task PlateauModelToScene(Transform parentTran else { Debug.LogError("メッシュデータの配置に失敗しました。"); - return ConvertResult.Fail(); + return GranularityConvertResult.Fail(); } @@ -120,7 +119,7 @@ public static async Task PlateauModelToScene(Transform parentTran // エディター内での実行であれば、生成したメッシュ,テクスチャ等をシーンに保存したいので // シーンにダーティフラグを付けます。 #if UNITY_EDITOR - if (Application.isEditor) + if (Application.isEditor && !EditorApplication.isPlaying) { EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); } @@ -135,12 +134,12 @@ public static async Task PlateauModelToScene(Transform parentTran /// メインスレッドでなくても動作します。 /// private static Model ExtractMeshes( - CityModel cityModel, MeshExtractOptions meshExtractOptions, string[] selectedMeshCodes, CancellationToken token) + CityModel cityModel, MeshExtractOptions meshExtractOptions, MeshCodeList selectedMeshCodes) { var model = Model.Create(); if (cityModel == null) return model; - var extents = selectedMeshCodes.Select(code => { - var extent = MeshCode.Parse(code).Extent; + var extents = selectedMeshCodes.Data.Select(code => { + var extent = code.Extent; extent.Min.Height = -999999.0; extent.Max.Height = 999999.0; return extent; @@ -149,42 +148,42 @@ private static Model ExtractMeshes( Debug.Log("model extracted."); return model; } + } + + /// + /// 粒度変換(分割結合)してシーンに配置した結果が格納されるクラスです。 + /// + public class GranularityConvertResult + { + public bool IsSucceed { get; set; } = true; + /// 変換によってシーンに配置したゲームオブジェクトのリスト + public List GeneratedObjs { get; } = new (); + /// - /// 変換してシーンに配置した結果です。 + /// 変換によってシーンに配置したゲームオブジェクトのうち、ヒエラルキーが最上位であるもののリスト /// - public class ConvertResult - { - public bool IsSucceed { get; set; } = true; - - /// 変換によってシーンに配置したゲームオブジェクトのリスト - public List GeneratedObjs { get; } = new (); - - /// - /// 変換によってシーンに配置したゲームオブジェクトのうち、ヒエラルキーが最上位であるもののリスト - /// - public List RootObjs { get; } = new(); + public List GeneratedRootObjs { get; } = new(); - /// 結果のゲームオブジェクトの一覧に追加します。 - public void Add(GameObject obj, bool isRoot) - { - GeneratedObjs.Add(obj); - if(isRoot) RootObjs.Add(obj); - } + /// 結果のゲームオブジェクトの一覧に追加します。 + public void Add(GameObject obj, bool isRoot) + { + GeneratedObjs.Add(obj); + if(isRoot) GeneratedRootObjs.Add(obj); + } - /// 複数のを統合します。 - public void Merge(ConvertResult other) - { - IsSucceed &= other.IsSucceed; - GeneratedObjs.AddRange(other.GeneratedObjs); - RootObjs.AddRange(other.RootObjs); - } + /// 複数のを統合します。 + public void Merge(GranularityConvertResult other) + { + IsSucceed &= other.IsSucceed; + GeneratedObjs.AddRange(other.GeneratedObjs); + GeneratedRootObjs.AddRange(other.GeneratedRootObjs); + } - public static ConvertResult Fail() - { - return new ConvertResult() { IsSucceed = false }; - } - + public static GranularityConvertResult Fail() + { + return new GranularityConvertResult() { IsSucceed = false }; } + } } diff --git a/Runtime/CityImport/Load/Convert/PlateauToUnityModelConverter.cs.meta b/Runtime/CityImport/Import/Convert/PlateauToUnityModelConverter.cs.meta similarity index 100% rename from Runtime/CityImport/Load/Convert/PlateauToUnityModelConverter.cs.meta rename to Runtime/CityImport/Import/Convert/PlateauToUnityModelConverter.cs.meta diff --git a/Runtime/CityImport/Load/Convert/ConvertedMeshData.cs b/Runtime/CityImport/Load/Convert/ConvertedMeshData.cs deleted file mode 100644 index 15f6f3a77..000000000 --- a/Runtime/CityImport/Load/Convert/ConvertedMeshData.cs +++ /dev/null @@ -1,277 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using PLATEAU.Util; -using PLATEAU.Util.Async; -using UnityEngine; -using UnityEngine.Rendering; -using Mesh = UnityEngine.Mesh; - -namespace PLATEAU.CityImport.Load.Convert -{ - /// - /// DLL側の Mesh を Unity向けに変換したものです。 - /// - internal class ConvertedMeshData - { - private readonly Vector3[] vertices; - private readonly Vector2[] uv1; - private readonly Vector2[] uv4; - private readonly List> subMeshTriangles; - private readonly List textureUrls; - private readonly List gmlMaterials; - - private string Name { get; } - private int SubMeshCount => this.subMeshTriangles.Count; - - public ConvertedMeshData(Vector3[] vertices, Vector2[] uv1, Vector2[] uv4, List> subMeshTriangles, List textureUrls, List materials, string name) - { - this.vertices = vertices; - this.uv1 = uv1; - this.uv4 = uv4; - this.subMeshTriangles = subMeshTriangles; - this.textureUrls = textureUrls; - this.gmlMaterials = materials; - Name = name; - } - - /// - /// メッシュの形状を変更したあとに必要な後処理です。 - /// - private static void PostProcess(Mesh mesh) - { - mesh.RecalculateNormals(); - mesh.RecalculateTangents(); - mesh.RecalculateBounds(); - } - - /// - /// ゲームオブジェクト、メッシュ、テクスチャの実体を作ってシーンに配置します。 - /// 頂点がない場合は nullが返ります。 - /// - public async Task PlaceToScene(Transform parentTrans, Dictionary cachedMaterials, Material fallbackMaterial) - { - var mesh = GenerateUnityMesh(); - if (mesh.vertexCount <= 0) return null; - var meshObj = new GameObject(Name) - { - transform = - { - parent = parentTrans - }, - isStatic = true - }; - var meshFilter = GameObjectUtil.AssureComponent(meshObj); - meshFilter.mesh = mesh; - var renderer = GameObjectUtil.AssureComponent(meshObj); - - var materials = new Material[mesh.subMeshCount]; - for (int i = 0; i < mesh.subMeshCount; i++) - { - - //Material設定 - var texturePath = textureUrls[i]; - var gmlMaterial = gmlMaterials[i]; - MaterialSet materialSet = new MaterialSet(gmlMaterial, texturePath); - - // テクスチャがフォールバックマテリアルのものである場合は、フォールバックマテリアルにします。 - Material fallbackMat = FallbackMaterial.ByMainTextureName(texturePath); - if (fallbackMat != null) - { - materials[i] = fallbackMat; - continue; - } - - // マテリアルがキャッシュ済みの場合はキャッシュを使用 - if (cachedMaterials.TryGetValue(materialSet, out var cachedMaterial)) - { - materials[i] = cachedMaterial; - continue; - } - - Material material = null; - var texture = await LoadTexture(texturePath); - // マテリアルを決めるための場合分けです。 - if (gmlMaterial == null && texture == null) - { - // マテリアル指定もテクスチャ指定もない場合、fallbackMaterialを使います。それもない場合、デフォルトマテリアルを使います。 - if (fallbackMaterial == null) - { - material = RenderUtil.CreateDefaultMaterial(); - } - else - { - material = fallbackMaterial; - } - } - else - { - // マテリアル指定があればそれを使い、なければデフォルトマテリアルを使います。 - if (gmlMaterial != null) - { - material = RenderUtil.GetPLATEAUX3DMaterialByCityGMLMaterial(gmlMaterial); - material.name = gmlMaterial.ID; - } - else - { - material = RenderUtil.CreateDefaultMaterial(); - } - - //Textureがあればそれを使います。 - if (texture != null) - { - material.mainTexture = texture; - material.name = texture.name; - } - - } - materials[i] = material; - cachedMaterials.Add(materialSet, material); - } - renderer.materials = materials; - return meshObj; - } - - public int VerticesCount => this.vertices.Length; - - /// - /// データをもとにUnity のメッシュを生成します。 - /// - private Mesh GenerateUnityMesh() - { - var mesh = new Mesh - { - indexFormat = IndexFormat.UInt32, - vertices = this.vertices, - uv = this.uv1, - uv4 = this.uv4, - subMeshCount = this.subMeshTriangles.Count - }; - - // subMesh ごとに Indices(Triangles) を UnityのMeshにコピーします。 - for (int i = 0; i < this.subMeshTriangles.Count; i++) - { - mesh.SetTriangles(this.subMeshTriangles[i], i); - } - - PostProcess(mesh); - mesh.name = Name; - return mesh; - } - - /// - /// テクスチャのURL(パス) から、テクスチャを非同期でロードします。 - /// 生成した Unity の Textureインスタンスへの参照を に追加します。 - /// - private static async Task LoadTexture(string texturePath) - { - if (string.IsNullOrEmpty(texturePath)) - return null; - - // .PLATEAU からの相対パスを求めます。 - string pathToReplace = (PathUtil.PLATEAUSrcFetchDir + "/").Replace('\\', '/'); - string relativePath = (texturePath.Replace('\\', '/')).Replace(pathToReplace, ""); - - Debug.Log($"Loading Texture : {texturePath}"); - - // 非同期でテクスチャをロードします。 - var texture = await TextureLoader.LoadAsync(texturePath, 3); - - if (texture == null) - return null; - - // この Compress によってテクスチャ容量が 6分の1 になります。 - // 松山市のLOD2の建物モデルで計測したところ、 テクスチャのメモリ使用量が 2.6GB から 421.3MB になりました。 - // 画質は下がりますが、メモリ使用量を適正にするために必須と思われます。 - var compressedTex = Compress(texture); - - compressedTex.name = relativePath; - return compressedTex; - } - - // テクスチャを圧縮します。 - private static Texture2D Compress(Texture2D src) - { - // Compressメソッドで圧縮する準備として、幅・高さを4の倍数にする必要があります。 - // 最も近い4の倍数を求めます。 - var widthX4 = (src.width + 2) / 4 * 4; - var heightX4 = (src.height + 2) / 4 * 4; - widthX4 = Math.Max(4, widthX4); // 幅・高さが 1ピクセルのケースで 0 に丸められてしまうのを防止します。 - heightX4 = Math.Max(4, heightX4); - - // テクスチャをリサイズします。 - // 参考: https://light11.hatenadiary.com/entry/2018/04/19/194015 - var rt = RenderTexture.GetTemporary(widthX4, heightX4); - Graphics.Blit(src, rt); - var prevRt = RenderTexture.active; - RenderTexture.active = rt; - var dst = new Texture2D(widthX4, heightX4); - dst.ReadPixels(new Rect(0, 0, widthX4, heightX4), 0, 0); - dst.Apply(); - RenderTexture.active = prevRt; - RenderTexture.ReleaseTemporary(rt); - - // 圧縮のキモです。 - dst.Compress(true); - return dst; - } - } - - /// - /// マテリアルとテクスチャのセットをDictionary Keyとして使用するための構造体です。 - /// - internal struct MaterialSet : IEquatable - { - public MaterialSet(CityGML.Material mat, string texturePath) - { - if (mat == null) - { - Diffuse = Emissive = Specular = Vector3.zero; - AmbientIntensity = Shininess = Transparency = 0f; - IsSmooth = false; - Texture = texturePath; - HasMaterial = false; - } - else - { - Diffuse = new Vector3(mat.Diffuse.X, mat.Diffuse.Y, mat.Diffuse.Z); - Emissive = new Vector3(mat.Emissive.X, mat.Emissive.Y, mat.Emissive.Z); - Specular = new Vector3(mat.Specular.X, mat.Specular.Y, mat.Specular.Z); - AmbientIntensity = mat.AmbientIntensity; - Shininess = mat.Shininess; - Transparency = mat.Transparency; - IsSmooth = mat.IsSmooth; - Texture = texturePath; - HasMaterial = true; - } - } - - public Vector3 Diffuse { get; } - public Vector3 Emissive { get; } - public Vector3 Specular { get; } - public float AmbientIntensity { get; } - public float Shininess { get; } - public float Transparency { get; } - public bool IsSmooth { get; } - public string Texture { get; } - public bool HasMaterial { get; } - - public bool Equals(MaterialSet other) - { - return Diffuse.Equals(other.Diffuse) && - Emissive.Equals(other.Emissive) && - Specular.Equals(other.Specular) && - AmbientIntensity.Equals(other.AmbientIntensity) && - Shininess.Equals(other.Shininess) && - Transparency.Equals(other.Transparency) && - IsSmooth.Equals(other.IsSmooth) && - Texture.Equals(other.Texture) && - HasMaterial.Equals(other.HasMaterial); - } - - public override int GetHashCode() - { - return new { Diffuse, Emissive, Specular, AmbientIntensity, Shininess, Transparency, IsSmooth, Texture, HasMaterial }.GetHashCode(); ; - } - } -} \ No newline at end of file diff --git a/Runtime/CityInfo/CityObjectTypeHierarchy.cs b/Runtime/CityInfo/CityObjectTypeHierarchy.cs index ddf7e5000..e198f572b 100644 --- a/Runtime/CityInfo/CityObjectTypeHierarchy.cs +++ b/Runtime/CityInfo/CityObjectTypeHierarchy.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Text; using PLATEAU.CityGML; using PLATEAU.Dataset; using Package = PLATEAU.Dataset.PredefinedCityModelPackage; @@ -12,6 +13,7 @@ public static class CityObjectTypeHierarchy { /// /// 都市オブジェクトの分類を階層構造のノードで表現したものです。 + /// ここでいう階層構造やノードとは、都市オブジェクトの分類についての上位概念・下位概念を示すものであり、実際の都市Modelデータとは異なることに注意してください。 /// // 前提 : // ・ヒエラルキーの中で 各CityObjectType が登場するのは1回以下で、ダブりはありません。 @@ -32,7 +34,13 @@ public static class CityObjectTypeHierarchy new Node("接地面 (GroundSurface)", Package.None, new[] { COType.COT_GroundSurface }, null), new Node("開口部 (ClosureSurface)", Package.None, new[] { COType.COT_ClosureSurface }, null), new Node("外側の天井 (OuterCeilingSurface)", Package.None, new[] { COType.COT_OuterCeilingSurface }, null), - new Node("屋根の通行可能部分 (OuterFloorSurface)", Package.None, new[] { COType.COT_OuterFloorSurface }, null) + new Node("屋根の通行可能部分 (OuterFloorSurface)", Package.None, new[] { COType.COT_OuterFloorSurface }, null), + new Node("部屋(Room)", Package.None, new[]{COType.COT_Room}, null), + new Node("天井(CeilingSurface)", Package.None, new[]{COType.COT_CeilingSurface}, null), + new Node("床(FloorSurface)", Package.None, new[]{COType.COT_FloorSurface}, null), + new Node("内装壁(InteriorWallSurface)", Package.None, new[]{COType.COT_InteriorWallSurface}, null), + new Node("内装付属設備(IntBuildingInstallation)", Package.None, new[]{COType.COT_IntBuildingInstallation}, null), + }), new Node("道路 (Road)", Package.Road, new[] { COType.COT_Road }, null), new Node("都市設備 (CityFurniture)", Package.CityFurniture, new[] { COType.COT_CityFurniture }, null), @@ -43,21 +51,21 @@ public static class CityObjectTypeHierarchy new Node("ポリゴンによる起伏表現 (TINRelief)", Package.None, new[] { COType.COT_TINRelief }, null), new Node("点群による起伏表現 (MassPointRelief)", Package.None, new[] { COType.COT_MassPointRelief }, null) }), - new Node("植生 (Vegetation)", Package.Vegetation, null, null), + new Node("植生 (Vegetation)", Package.Vegetation, new[]{COType.COT_SolitaryVegetationObject, COType.COT_PlantCover}, null), new Node("災害リスク (DisasterRisk)", Package.DisasterRisk, null, null), - new Node("鉄道 (Railway)", Package.Railway, null, null), + new Node("鉄道 (Railway)", Package.Railway, new[]{COType.COT_Railway}, null), new Node("航路 (Waterway)", Package.Waterway, null, null), - new Node("水部 (WaterBody)", Package.WaterBody, null, null), - new Node("橋梁 (Bridge)", Package.Bridge, null, null), - new Node("徒歩道 (Track)", Package.Track, null, null), - new Node("広場 (Square)", Package.Square, null, null), - new Node("トンネル (Tunnel)", Package.Tunnel, null, null), + new Node("水部 (WaterBody)", Package.WaterBody, new[]{COType.COT_WaterBody}, null), + new Node("橋梁 (Bridge)", Package.Bridge, new[]{COType.COT_Bridge}, null), + new Node("徒歩道 (Track)", Package.Track, new[]{COType.COT_Track}, null), + new Node("広場 (Square)", Package.Square, new[]{COType.COT_Square}, null), + new Node("トンネル (Tunnel)", Package.Tunnel, new[]{COType.COT_Tunnel}, null), new Node("地下埋設物 (UndergroundFacility)", Package.UndergroundFacility, null, null), new Node("地下街 (UndergroundBuilding)", Package.UndergroundBuilding, null, null), new Node("区域 (Area)", Package.Area, null, null), new Node("その他の構造物 (OtherConstruction)", Package.OtherConstruction, null, null), - new Node("汎用都市 (Generic)", Package.Generic, null, null), - new Node("その他 (Unknown)", Package.Unknown, null, null) + new Node("汎用都市 (Generic)", Package.Generic, new[]{COType.COT_GenericCityObject}, null), + new Node("その他 (Unknown)", Package.Unknown, new[]{COType.COT_Unknown}, null) } ); @@ -72,6 +80,31 @@ public static Node GetNodeByPackage(Package p) if (packageToNode.TryGetValue(p, out var node)) return node; throw new ArgumentOutOfRangeException(nameof(p), $"Package {p} is not found in the hierarchy."); } + + /// + /// タイプ分類の中で、引数のは何番目かを計算します。 + /// 順番はヒエラルキーの深さ優先探索の順とします。 + /// + private static int CalcIndexOf(Node targetNode) + { + Stack nodeStack = new(); + nodeStack.Push(RootNode); + int index = 0; + Node currentNode = RootNode; + while (nodeStack.Count > 0) + { + for(int i=currentNode.Children.Count-1; i>=0; i--) // 子番号の若いほうから検索したいので逆順にpushします。 + { + nodeStack.Push(currentNode.Children[i]); + } + + currentNode = nodeStack.Pop(); + + if (currentNode == targetNode) return index; + index++; + } + throw new KeyNotFoundException("targetNode is not found."); + } @@ -85,7 +118,7 @@ public static Node GetNodeByPackage(Package p) /// private static Dictionary packageToNode; - public class Node + public class Node : IComparable { public string NodeName { get; } public PredefinedCityModelPackage Package { get; } @@ -119,6 +152,34 @@ public Node(string nodeName, PredefinedCityModelPackage package, CityObjectType[ child.Parent = this; } } + + /// + /// 分類のディスプレイ名を返します。 + /// + public string GetDisplayName() + { + // 親の分類がある場合、それらをスラッシュで繋ぎます + Stack pathStack = new(); + Node current = this; + // 親を辿ってパスを記録します。 + while(current != null) + { + pathStack.Push(current); + current = current.Parent; + } + // ルートノードは不要なので除きます + pathStack.Pop(); + // パスをもとに文字列にします。 + StringBuilder sb = new(); + while (pathStack.Count > 0) + { + var node = pathStack.Pop(); + sb.Append(node.NodeName); + if (pathStack.Count > 0) sb.Append("/"); + } + + return sb.ToString(); + } /// /// Nodeの親子関係を自身から上へ調べて、PackageがNoneでない初めて見つかったPackageを返します。 @@ -138,6 +199,18 @@ public Package UpperPackage return PredefinedCityModelPackage.None; } } + + /// + /// 都市オブジェクトの種類をGUIで列挙するなどの場合に、列挙の順序を定義します。 + /// の深さ優先探索の順番とします。 + /// + public int CompareTo(Node other) + { + int thisIndex = CalcIndexOf(this); + int otherIndex = CalcIndexOf(other); + int result = thisIndex.CompareTo(otherIndex); + return result; + } } } } diff --git a/Runtime/CityInfo/PLATEAUCityObjectGroup.cs b/Runtime/CityInfo/PLATEAUCityObjectGroup.cs index 5b1c2e501..0c8e7bb64 100644 --- a/Runtime/CityInfo/PLATEAUCityObjectGroup.cs +++ b/Runtime/CityInfo/PLATEAUCityObjectGroup.cs @@ -26,7 +26,10 @@ public class PLATEAUCityObjectGroup : MonoBehaviour /// Toolkits向けの情報です。 [SerializeField] private CityObjectGroupInfoForToolkits infoForToolkits; + + [SerializeField] private MeshGranularity granularity; public CityObjectGroupInfoForToolkits InfoForToolkits => infoForToolkits; + public MeshGranularity Granularity => granularity; public CityObjectList CityObjects { @@ -43,10 +46,11 @@ public CityObjectList CityObjects } } - public void Init(CityObjectList cityObjectSerializable, CityObjectGroupInfoForToolkits cogInfoForToolkits) + public void Init(CityObjectList cityObjectSerializable, CityObjectGroupInfoForToolkits cogInfoForToolkits, MeshGranularity granularityArg) { serializedCityObjects = JsonConvert.SerializeObject(cityObjectSerializable, Formatting.Indented); - infoForToolkits = cogInfoForToolkits; + infoForToolkits = cogInfoForToolkits; + granularity = granularityArg; } /// @@ -276,6 +280,10 @@ public IEnumerable PrimaryCityObjects } } + /// + /// コンポーネントが保持するから、 + /// すべてのを返します。 + /// public IEnumerable GetAllCityObjects() { List objs = new List(); diff --git a/Runtime/GranularityConvert/CityGranularityConverter.cs b/Runtime/GranularityConvert/CityGranularityConverter.cs index 879637109..df39d99ee 100644 --- a/Runtime/GranularityConvert/CityGranularityConverter.cs +++ b/Runtime/GranularityConvert/CityGranularityConverter.cs @@ -3,7 +3,9 @@ using System.Linq; using System.Threading.Tasks; using PLATEAU.CityExport.ModelConvert; -using PLATEAU.CityImport.Load.Convert; +using PLATEAU.CityExport.ModelConvert.SubMeshConvert; +using PLATEAU.CityImport.Import.Convert; +using PLATEAU.CityImport.Import.Convert.MaterialConvert; using PLATEAU.CityInfo; using PLATEAU.Native; using PLATEAU.PolygonMesh; @@ -13,69 +15,84 @@ using Debug = UnityEngine.Debug; using Object = UnityEngine.Object; -#if UNITY_EDITOR -#endif namespace PLATEAU.GranularityConvert { + /// + /// オブジェクトの分割と結合を行います。 + /// public class CityGranularityConverter { - public async Task ConvertAsync(IReadOnlyList srcGameObjs, GranularityConvertOption option) + public async Task ConvertAsync(GranularityConvertOptionUnity conf) { try { + if (!conf.IsValid()) + { + return GranularityConvertResult.Fail(); + } + using var progressBar = new ProgressBar(); progressBar.Display("属性情報を取得中...", 0.1f); // 属性情報を覚えておきます。 - var attributes = GmlIdToSerializedCityObj.ComposeFrom(srcGameObjs); + var attributes = GmlIdToSerializedCityObj.ComposeFrom(conf.SrcGameObjs); // PLATEAUInstancedCityModel が含まれる場合、これもコピーしたいので覚えておきます。 - var instancedCityModelDict = InstancedCityModelDict.ComposeFrom(srcGameObjs); + var instancedCityModelDict = InstancedCityModelDict.ComposeFrom(conf.SrcGameObjs); progressBar.Display("ゲームオブジェクトを共通モデルに変換中...", 0.2f); + var unityMeshToDllSubMeshConverter = new UnityMeshToDllSubMeshWithGameMaterial(); + // ゲームオブジェクトを共通ライブラリのModelに変換します。 - using var srcModel = UnityMeshToDllModelConverter.Convert(srcGameObjs, true, false, ConvertVertex); + using var srcModel = UnityMeshToDllModelConverter.Convert( + conf.SrcGameObjs, + unityMeshToDllSubMeshConverter, + true, // 非表示のゲームオブジェクトも対象に含めます。なぜなら、LOD0とLOD1のうちLOD1だけがActiveになっているという状況で、変換後もToolkitsのLOD機能を使えるようにするためです。 + ConvertVertex); progressBar.Display("共通モデルの変換中...", 0.5f); // 共通ライブラリの機能でモデルを分割・結合します。 var converter = new GranularityConverter(); - using var dstModel = converter.Convert(srcModel, option); + using var dstModel = converter.Convert(srcModel, conf.NativeOption); progressBar.Display("変換後の3Dモデルを配置中...", 0.8f); // Toolkits向けの処理です - bool isTextureCombined = SearchFirstCityObjGroup(srcGameObjs).InfoForToolkits.IsTextureCombined; + bool isTextureCombined = SearchFirstCityObjGroup(conf.SrcGameObjs).InfoForToolkits.IsTextureCombined; var infoForToolkits = new CityObjectGroupInfoForToolkits(isTextureCombined, true); // Modelをゲームオブジェクトに変換して配置します。 - var commonParent = CalcCommonParent(srcGameObjs.Select(obj => obj.transform).ToArray()); - + var commonParent = CalcCommonParent(conf.SrcGameObjs.Select(obj => obj.transform).ToArray()); + + var materialConverterToUnity = new DllSubMeshToUnityMaterialByGameMaterial(unityMeshToDllSubMeshConverter); + var placeToSceneConf = + new PlaceToSceneConfig(materialConverterToUnity, true, null, null, infoForToolkits, conf.NativeOption.Granularity); + var result = await PlateauToUnityModelConverter.PlateauModelToScene( - commonParent, new DummyProgressDisplay(), "", true, - null, null, dstModel, - new AttributeDataHelper(new SerializedCityObjectGetterFromDict(attributes), option.Granularity, - true), true, infoForToolkits); + commonParent, new DummyProgressDisplay(), "", placeToSceneConf, dstModel, + new AttributeDataHelper(new SerializedCityObjectGetterFromDict(attributes), conf.NativeOption.Granularity, + true), true); if (!result.IsSucceed) { throw new Exception("Failed to convert plateau model to scene game objects."); } - if (result.RootObjs.Count <= 0) + if (result.GeneratedRootObjs.Count <= 0) { Dialogue.Display("変換対象がありません。\nアクティブなオブジェクトを選択してください。", "OK"); - return; + return GranularityConvertResult.Fail(); } // PLATEAUInstancedCityModelを復元します。 - instancedCityModelDict.Restore(result.RootObjs); + instancedCityModelDict.Restore(result.GeneratedRootObjs); - if (Dialogue.Display("変換前のゲームオブジェクトを削除しますか? 残しますか?", "削除", "残す")) + if (conf.DoDestroySrcObjs) { - foreach (var srcObj in srcGameObjs) + foreach (var srcObj in conf.SrcGameObjs) { Object.DestroyImmediate(srcObj); } @@ -83,12 +100,14 @@ public async Task ConvertAsync(IReadOnlyList srcGameObjs, Granularit #if UNITY_EDITOR // 変換後のゲームオブジェクトを選択状態にします。 - Selection.objects = result.RootObjs.Select(go => (Object)go).ToArray(); + Selection.objects = result.GeneratedRootObjs.Select(go => (Object)go).ToArray(); #endif + return result; } catch (Exception e) { Debug.LogError($"{e.Message}\n{e.StackTrace}"); + return GranularityConvertResult.Fail(); } } diff --git a/Runtime/GranularityConvert/GranularityConvertOptionUnity.cs b/Runtime/GranularityConvert/GranularityConvertOptionUnity.cs new file mode 100644 index 000000000..358de5223 --- /dev/null +++ b/Runtime/GranularityConvert/GranularityConvertOptionUnity.cs @@ -0,0 +1,56 @@ +using PLATEAU.CityInfo; +using PLATEAU.Util; +using UnityEngine; + +namespace PLATEAU.GranularityConvert +{ + /// + /// 分割結合の設定値です。 + /// DLL向けの設定とUnity向けの設定をまとめたものです。 + /// + public class GranularityConvertOptionUnity + { + /// DLL向けの設定です。 + public GranularityConvertOption NativeOption { get; } + public GameObject[] SrcGameObjs { get; } + public bool DoDestroySrcObjs { get; } + + public GranularityConvertOptionUnity( + GranularityConvertOption nativeOption, // 注意: GranularityConvertOption.GridCountの設定は未実装であり、何の値に設定しても動作に影響しません。 + GameObject[] srcGameObjs, + bool doDestroySrcObjs) + { + NativeOption = nativeOption; + SrcGameObjs = srcGameObjs; + DoDestroySrcObjs = doDestroySrcObjs; + } + + public bool IsValid() + { + if (SrcGameObjs.Length == 0) + { + Dialogue.Display("ゲームオブジェクトが選択されていません。\n選択してから実行してください。", "OK"); + return false; + } + + bool containsCog = false; + foreach (var srcObj in SrcGameObjs) + { + if (srcObj.GetComponentInChildren() != null) + { + containsCog = true; + break; + } + } + + if (!containsCog) + { + Dialogue.Display( + "選択されたゲームオブジェクトまたはその子に地物情報が含まれていないため分割結合できません。\nPLATEAUInstancedCityObjectまたはその親を選択してください。", "OK"); + return false; + } + + return true; + } + } +} \ No newline at end of file diff --git a/Runtime/GranularityConvert/GranularityConvertOptionUnity.cs.meta b/Runtime/GranularityConvert/GranularityConvertOptionUnity.cs.meta new file mode 100644 index 000000000..8b522ce08 --- /dev/null +++ b/Runtime/GranularityConvert/GranularityConvertOptionUnity.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 723a9f0365b143c0a56077b98fc7a4d0 +timeCreated: 1700037956 \ No newline at end of file diff --git a/Runtime/Util/Async/TextureLoader.cs b/Runtime/Util/Async/TextureLoader.cs index 1dd73f9cd..8d54dee27 100644 --- a/Runtime/Util/Async/TextureLoader.cs +++ b/Runtime/Util/Async/TextureLoader.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using UnityEngine; using UnityEngine.Networking; @@ -16,7 +17,7 @@ public static class TextureLoader /// public static async Task LoadAsync(string url, int timeOutSec) { - System.Uri uri = new System.Uri(url); + Uri uri = new Uri(url); var request = UnityWebRequestTexture.GetTexture(uri); request.timeout = timeOutSec; @@ -34,5 +35,64 @@ public static async Task LoadAsync(string url, int timeOutSec) var texture = ((DownloadHandlerTexture)request.downloadHandler).texture; return texture; } + + + /// + /// テクスチャのURL(パス) から、PLATEAUのテクスチャを非同期でロードします。 + /// 内容はに、PLATEAUテクスチャ用の処理を加えたものになります。 + /// メインスレッドで実行する必要があります。 + /// + public static async Task LoadPlateauTextureAsync(string texturePath) + { + if (string.IsNullOrEmpty(texturePath)) + return null; + + // .PLATEAU からの相対パスを求めます。 + string pathToReplace = (PathUtil.PLATEAUSrcFetchDir + "/").Replace('\\', '/'); + string relativePath = (texturePath.Replace('\\', '/')).Replace(pathToReplace, ""); + + Debug.Log($"Loading Texture : {texturePath}"); + + // 非同期でテクスチャをロードします。 + var texture = await LoadAsync(texturePath, 3); + + if (texture == null) + return null; + + // この Compress によってテクスチャ容量が 6分の1 になります。 + // 松山市のLOD2の建物モデルで計測したところ、 テクスチャのメモリ使用量が 2.6GB から 421.3MB になりました。 + // 画質は下がりますが、メモリ使用量を適正にするために必須と思われます。 + var compressedTex = Compress(texture); + + compressedTex.name = relativePath; + return compressedTex; + } + + // テクスチャを圧縮します。 + private static Texture2D Compress(Texture2D src) + { + // Compressメソッドで圧縮する準備として、幅・高さを4の倍数にする必要があります。 + // 最も近い4の倍数を求めます。 + var widthX4 = (src.width + 2) / 4 * 4; + var heightX4 = (src.height + 2) / 4 * 4; + widthX4 = Math.Max(4, widthX4); // 幅・高さが 1ピクセルのケースで 0 に丸められてしまうのを防止します。 + heightX4 = Math.Max(4, heightX4); + + // テクスチャをリサイズします。 + // 参考: https://light11.hatenadiary.com/entry/2018/04/19/194015 + var rt = RenderTexture.GetTemporary(widthX4, heightX4); + Graphics.Blit(src, rt); + var prevRt = RenderTexture.active; + RenderTexture.active = rt; + var dst = new Texture2D(widthX4, heightX4); + dst.ReadPixels(new Rect(0, 0, widthX4, heightX4), 0, 0); + dst.Apply(); + RenderTexture.active = prevRt; + RenderTexture.ReleaseTemporary(rt); + + // 圧縮のキモです。 + dst.Compress(true); + return dst; + } } } diff --git a/Runtime/Util/FallbackMaterial.cs b/Runtime/Util/FallbackMaterial.cs index bb4efe87e..422bcab2a 100644 --- a/Runtime/Util/FallbackMaterial.cs +++ b/Runtime/Util/FallbackMaterial.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.IO; using PLATEAU.Dataset; -using UnityEditor; using UnityEngine; #if !UNITY_EDITOR using System; @@ -17,26 +16,26 @@ public class FallbackMaterial private static readonly IReadOnlyDictionary PackageToMaterialFileName = new Dictionary { - {PredefinedCityModelPackage.Building, "PlateauDefaultBuilding.mat"}, - {PredefinedCityModelPackage.Road, "PlateauDefaultRoad.mat"}, - {PredefinedCityModelPackage.UrbanPlanningDecision, "PlateauDefaultUrbanPlanningDecision.mat"}, - {PredefinedCityModelPackage.LandUse, "PlateauDefaultLandUse.mat"}, - {PredefinedCityModelPackage.CityFurniture, "PlateauDefaultCityFurniture.mat"}, - {PredefinedCityModelPackage.Vegetation, "PlateauDefaultVegetation.mat"}, - {PredefinedCityModelPackage.Relief, "PlateauDefaultRelief.mat"}, - {PredefinedCityModelPackage.DisasterRisk, "PlateauDefaultDisasterRisk.mat"}, - {PredefinedCityModelPackage.Railway, "PlateauDefaultRailway.mat"}, - {PredefinedCityModelPackage.Waterway, "PlateauDefaultWaterway.mat"}, - {PredefinedCityModelPackage.WaterBody, "PlateauDefaultWaterBody.mat"}, - {PredefinedCityModelPackage.Bridge, "PlateauDefaultBridge.mat"}, - {PredefinedCityModelPackage.Track, "PlateauDefaultTrack.mat"}, - {PredefinedCityModelPackage.Square, "PlateauDefaultSquare.mat"}, - {PredefinedCityModelPackage.Tunnel, "PlateauDefaultTunnel.mat"}, - {PredefinedCityModelPackage.UndergroundFacility, "PlateauDefaultUndergroundFacility.mat"}, - {PredefinedCityModelPackage.UndergroundBuilding, "PlateauDefaultUndergroundBuilding.mat"}, - {PredefinedCityModelPackage.Area, "PlateauDefaultLandUse.mat"}, // 土地利用を流用 - {PredefinedCityModelPackage.Unknown, "PlateauDefaultUnknown.mat"}, - {PredefinedCityModelPackage.OtherConstruction, "PlateauDefaultUnknown.mat"} + {PredefinedCityModelPackage.Building, "PlateauDefaultBuilding"}, + {PredefinedCityModelPackage.Road, "PlateauDefaultRoad"}, + {PredefinedCityModelPackage.UrbanPlanningDecision, "PlateauDefaultUrbanPlanningDecision"}, + {PredefinedCityModelPackage.LandUse, "PlateauDefaultLandUse"}, + {PredefinedCityModelPackage.CityFurniture, "PlateauDefaultCityFurniture"}, + {PredefinedCityModelPackage.Vegetation, "PlateauDefaultVegetation"}, + {PredefinedCityModelPackage.Relief, "PlateauDefaultRelief"}, + {PredefinedCityModelPackage.DisasterRisk, "PlateauDefaultDisasterRisk"}, + {PredefinedCityModelPackage.Railway, "PlateauDefaultRailway"}, + {PredefinedCityModelPackage.Waterway, "PlateauDefaultWaterway"}, + {PredefinedCityModelPackage.WaterBody, "PlateauDefaultWaterBody"}, + {PredefinedCityModelPackage.Bridge, "PlateauDefaultBridge"}, + {PredefinedCityModelPackage.Track, "PlateauDefaultTrack"}, + {PredefinedCityModelPackage.Square, "PlateauDefaultSquare"}, + {PredefinedCityModelPackage.Tunnel, "PlateauDefaultTunnel"}, + {PredefinedCityModelPackage.UndergroundFacility, "PlateauDefaultUndergroundFacility"}, + {PredefinedCityModelPackage.UndergroundBuilding, "PlateauDefaultUndergroundBuilding"}, + {PredefinedCityModelPackage.Area, "PlateauDefaultLandUse"}, // 土地利用を流用 + {PredefinedCityModelPackage.Unknown, "PlateauDefaultUnknown"}, + {PredefinedCityModelPackage.OtherConstruction, "PlateauDefaultUnknown"} }; private static Dictionary mainTexNameToMaterial = null; @@ -52,13 +51,15 @@ public static Material LoadByPackage(PredefinedCityModelPackage pack) return new Material(RenderUtil.DefaultMaterial); } - string matPath = Path.Combine(MaterialPathUtil.BaseMaterialDir, FallbackFolderName, matFileName); - #if UNITY_EDITOR - var mat = AssetDatabase.LoadAssetAtPath(matPath); + // string matPath = Path.Combine(MaterialPathUtil.BaseMaterialDir, FallbackFolderName, matFileName); + // #if UNITY_EDITOR + // var mat = AssetDatabase.LoadAssetAtPath(matPath); + // return mat ? mat : new Material(RenderUtil.DefaultMaterial); + // #else + // throw new NotImplementedException("This function is only supported in editor."); + // #endif + var mat = Resources.Load("PlateauSdkDefaultMaterials/" + matFileName); return mat ? mat : new Material(RenderUtil.DefaultMaterial); - #else - throw new NotImplementedException("This function is only supported in editor."); - #endif } /// @@ -67,7 +68,7 @@ public static Material LoadByPackage(PredefinedCityModelPackage pack) /// public static Material ByMainTextureName(string mainTexNameArg) { - string mainTexName = Path.GetFileName(mainTexNameArg); + string mainTexName = Path.GetFileNameWithoutExtension(mainTexNameArg); if (mainTexNameToMaterial == null) { // テクスチャ名をキー、マテリアルをバリューとする辞書を作ります。 diff --git a/Samples~/APISample/RuntimeAPISample.cs b/Samples~/APISample/RuntimeAPISample.cs new file mode 100644 index 000000000..5984ac488 --- /dev/null +++ b/Samples~/APISample/RuntimeAPISample.cs @@ -0,0 +1,82 @@ +using PLATEAU.CityExport; +using PLATEAU.CityExport.Exporters; +using PLATEAU.CityImport.AreaSelector; +using PLATEAU.CityImport.Config; +using PLATEAU.CityImport.Import; +using PLATEAU.CityInfo; +using PLATEAU.Dataset; +using PLATEAU.Geometries; +using PLATEAU.GranularityConvert; +using PLATEAU.PolygonMesh; +using UnityEngine; +using UnityEngine.UI; + +public class RuntimeAPISample : MonoBehaviour +{ + [SerializeField] private InputField importPathInputField; + [SerializeField] private InputField exportPathInputField; + + /// + /// ランタイムでインポートするコードです。 + /// + public async void Import() + { + // インポートのパスをUnityのテキストフィールドから取得します。 + string importPath = importPathInputField.text; + // PLATEAUのデータセットの場所をセットします。 + var datasetConf = new DatasetSourceConfigLocal(importPath); + // インポート対象のメッシュコード(範囲)を指定します。文字列形式の番号の配列からMeshCodeListを生成できます。 + var meshCodesStr = new string[] { "53393652" }; + var meshCodeList = MeshCodeList.CreateFromMeshCodesStr(meshCodesStr); + // データセットやメッシュコードから、インポート設定を生成します。 + var conf = CityImportConfig.CreateWithAreaSelectResult( + new AreaSelectResult(new ConfigBeforeAreaSelect(datasetConf, 9), meshCodeList)); + // ここでconfを編集することも可能ですが、このサンプルではデフォルトでインポートします。 + await CityImporter.ImportAsync(conf, null, null); + } + + /// + /// ラインタイムでエクスポートするコードです。 + /// + public void Export() + { + // 前提条件: + // 実行するには、ターゲットのstatic batchingをオフにする必要があります。 + // そのためにはstaticのチェックをインスペクタから外します。 + + // エクスポート先をUnityのテキストフィールドから取得します。 + string exportDir = exportPathInputField.text; + // エクスポート設定です。 + var option = new MeshExportOptions(MeshExportOptions.MeshTransformType.Local, true, false, + MeshFileFormat.FBX, CoordinateSystem.ENU, new CityExporterFbx()); + // 都市モデルを取得します。 + var target = FindObjectOfType(); + if (target == null) + { + Debug.LogError("都市モデルが見つかりませんでした。"); + return; + } + // エクスポートします。 + UnityModelExporter.Export(exportDir, target, option); + } + + /// + /// ランタイムで結合分割(ゲームオブジェクトの粒度の変更)をするコードです。 + /// + public async void GranularityConvert() + { + // 都市オブジェクトを取得します。 + var target = FindObjectOfType(); + if (target == null) + { + Debug.LogError("都市モデルが見つかりませんでした。"); + return; + } + + // 分割結合の設定です。 + var conf = new GranularityConvertOptionUnity(new GranularityConvertOption(MeshGranularity.PerCityModelArea, 1), + new[] { target.gameObject }, true); + // 分割結合します。 + await new CityGranularityConverter().ConvertAsync(conf); + } +} diff --git a/Samples~/APISample/RuntimeAPISample.cs.meta b/Samples~/APISample/RuntimeAPISample.cs.meta new file mode 100644 index 000000000..952a24a78 --- /dev/null +++ b/Samples~/APISample/RuntimeAPISample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c534fa7eebab6744a2c929fa8a9a2b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/APISample/RuntimeSample.unity b/Samples~/APISample/RuntimeSample.unity new file mode 100644 index 000000000..8fd2a7951 --- /dev/null +++ b/Samples~/APISample/RuntimeSample.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4afac3a85d98cf12618864c554a248887af740a501578b86111579e5bb44cf06 +size 68719 diff --git a/Samples~/APISample/RuntimeSample.unity.meta b/Samples~/APISample/RuntimeSample.unity.meta new file mode 100644 index 000000000..bbaae3e25 --- /dev/null +++ b/Samples~/APISample/RuntimeSample.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 45d837ccbdfe5dd4b97e4ba3618f069d +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/AttributesColorSample/AttributesColorSample.cs b/Samples~/AttributesColorSample/AttributesColorSample.cs index 6e4dbab19..fca5605f9 100644 --- a/Samples~/AttributesColorSample/AttributesColorSample.cs +++ b/Samples~/AttributesColorSample/AttributesColorSample.cs @@ -1,5 +1,3 @@ -using System.Collections; -using System.Collections.Generic; using PLATEAU.CityInfo; using UnityEngine; @@ -10,7 +8,7 @@ public class AttributesColorSample : MonoBehaviour { /// 色分けしたいターゲットを指定します。 [SerializeField] private Transform targetParent; - private void Start() + private void Awake() { // PLATEAUCityObjectGroupコンポーネントに属性情報が格納されており、ランタイムで読み込むことができます。 var cityObjGroups = targetParent.GetComponentsInChildren(); @@ -19,12 +17,28 @@ private void Start() var target = cityObjGroup.transform; foreach (var cityObj in cityObjGroup.GetAllCityObjects()) { - // 属性情報(キーバリューペア)を取得します。 + // 属性情報(キーバリューペアが集まったもの)を取得します。 var attributes = cityObj.AttributesMap; - if (!attributes.TryGetValue("urf:function", out var landFuncAttr)) continue; - string landFuncName = landFuncAttr.StringValue; - var color = ColorByLandFuncName(landFuncName); - ChangeMaterialByColor(target, color); + + // 属性情報のうち、土地計画上の区分を取得して色分けします。 + if (attributes.TryGetValue("urf:function", out var landFuncAttr)) + { + string landFuncName = landFuncAttr.StringValue; + var color = ColorByLandFuncName(landFuncName); + ChangeMaterialByColor(target, color); + } + + // 属性情報のうち、水害時の想定浸水高さを取得します。 + if (attributes.TryGetValue("uro:floodingRiskAttribute", out var disasterRiskAttr)) + { + if (disasterRiskAttr.AttributesMapValue.TryGetValue("uro:rank", out var depthValue)) + { + var rank = depthValue.StringValue; + var color = ColorByFloodingRank(rank); + ChangeMaterialByColor(target, color); + } + } + } } } @@ -65,6 +79,25 @@ private Color ColorByLandFuncName(string landFuncName) return matColor; } + private Color ColorByFloodingRank(string rank) + { + Color matColor = Color.white; + if (rank == "0.5m未満") + { + matColor = new Color(0f, 0f, 1f); + } + else if (rank == "0.5m以上3m未満") + { + matColor = new Color(1.0f, 1.0f, 0f); + } + else if (rank == "3m以上5m未満") + { + matColor = new Color(1.0f, 0f, 0f); + } + + return matColor; + } + private void ChangeMaterialByColor(Transform target, Color color) { var meshRenderer = target.GetComponent(); diff --git a/Samples~/AttributesColorSample/AttributesColorSample.unity b/Samples~/AttributesColorSample/AttributesColorSample.unity index b413fba3b..103409e46 100644 --- a/Samples~/AttributesColorSample/AttributesColorSample.unity +++ b/Samples~/AttributesColorSample/AttributesColorSample.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:005c894b15dbee494821c59489cdf0452f33dfd94f75fa3e49adbe990c49656b -size 140999407 +oid sha256:5b8ed6ef12514250cd8eb1ba6bf098212659f309fe86d9f9aeeaae9bfc812b9b +size 301717467 diff --git a/Samples~/AttributesColorSample/ObjectSwitchSample.cs b/Samples~/AttributesColorSample/ObjectSwitchSample.cs new file mode 100644 index 000000000..72e99b5fc --- /dev/null +++ b/Samples~/AttributesColorSample/ObjectSwitchSample.cs @@ -0,0 +1,44 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Serialization; + +namespace PLATEAU +{ + /// + /// 表示するゲームオブジェクトを切り替えるシンプルなスクリプトです。 + /// + public class ObjectSwitchSample : MonoBehaviour + { + [SerializeField] private GameObject[] urbanPlanningObjects; + [SerializeField] private GameObject[] floodObjects; + + private void Start() + { + DisplayLandUse(); + } + + public void DisplayLandUse() + { + Switch(true); + } + + public void DisplayFlood() + { + Switch(false); + } + + private void Switch(bool mode) + { + foreach (var land in urbanPlanningObjects) + { + land.SetActive(mode); + } + + foreach (var flood in floodObjects) + { + flood.SetActive(!mode); + } + } + } +} diff --git a/Samples~/AttributesColorSample/ObjectSwitchSample.cs.meta b/Samples~/AttributesColorSample/ObjectSwitchSample.cs.meta new file mode 100644 index 000000000..bd37617f1 --- /dev/null +++ b/Samples~/AttributesColorSample/ObjectSwitchSample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 472a532b7380f5049baa488ae4d53714 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/EditModeTests/GUITests/PlateauWindowTests.cs b/Tests/EditModeTests/GUITests/PlateauWindowTests.cs index ec1f049ba..b68fe8895 100644 --- a/Tests/EditModeTests/GUITests/PlateauWindowTests.cs +++ b/Tests/EditModeTests/GUITests/PlateauWindowTests.cs @@ -57,9 +57,13 @@ public IEnumerator OpenCityImportRemoteGuiAndWaitForFewSecondsThenDatasetFetchCo // サーバーインポートに切り替え、そのGUIを取得します。 const int remoteImportTabIndex = 1; ReflectionUtil.SetPrivateFieldVal(typeof(CityAddGUI), gui, CityAddGUI.NameOfImportTabIndex, remoteImportTabIndex); - var remoteGui = - (CityImportRemoteGUI)ReflectionUtil.GetPrivateFieldVal(typeof(CityAddGUI), gui, + var confGUI = + (CityImportConfigGUI)ReflectionUtil.GetPrivateFieldVal(typeof(CityAddGUI), gui, CityAddGUI.NameOfImportTabGUIArray)[remoteImportTabIndex]; + var remoteGUI = + (ConfigGUIBeforeAreaSelectRemote)ReflectionUtil.GetPrivateFieldVal( + typeof(CityImportConfigGUI), confGUI, + CityImportConfigGUI.NameOfConfigGUIBeforeAreaSelect); yield return null; this.window.Repaint(); @@ -69,7 +73,7 @@ public IEnumerator OpenCityImportRemoteGuiAndWaitForFewSecondsThenDatasetFetchCo while ((DateTime.Now - startTime).TotalMilliseconds < 4000) { yield return null; - if (remoteGui.DatasetFetchStatus == ServerDatasetFetchGUI.LoadStatusEnum.Success) + if (remoteGUI.DatasetFetchStatus == ServerDatasetFetchGUI.LoadStatusEnum.Success) { isDatasetFetchSucceed = true; break; diff --git a/Tests/EditModeTests/TestAreaSelector.cs b/Tests/EditModeTests/TestAreaSelector.cs index 2caf1c4bf..6a4294aa8 100644 --- a/Tests/EditModeTests/TestAreaSelector.cs +++ b/Tests/EditModeTests/TestAreaSelector.cs @@ -4,6 +4,7 @@ using PLATEAU.CityImport.AreaSelector; using PLATEAU.CityImport.AreaSelector.Display; using PLATEAU.CityImport.AreaSelector.Display.Gizmos; +using PLATEAU.CityImport.Config; using PLATEAU.Dataset; using PLATEAU.Editor.CityImport.AreaSelector; using PLATEAU.Tests.EditModeTests.TestDoubles; @@ -34,12 +35,12 @@ public IEnumerator Components_Exist_In_Area_Select_Scene() SceneManager.SetActiveScene(emptyScene); // MiniTokyo の範囲選択画面を開始します。 var testDef = TestCityDefinition.MiniTokyo; - var datasetConf = new DatasetSourceConfig(false, testDef.SrcRootDirPathLocal, "", "", ""); + var datasetConf = new DatasetSourceConfigLocal(testDef.SrcRootDirPathLocal); var resultReceiver = new DummyAreaSelectResultReceiver(); LogAssert.ignoreFailingMessages = true; - AreaSelectorStarter.Start(datasetConf, resultReceiver, testDef.CoordinateZoneId); + AreaSelectorStarter.Start(new ConfigBeforeAreaSelect(datasetConf, testDef.CoordinateZoneId), resultReceiver); // EditModeでは yield return new WaitForSeconds() ができないので、原始的なループで地図のダウンロードを待ちます。 var startT = DateTime.Now; diff --git a/Tests/EditModeTests/TestMeshExporter.cs b/Tests/EditModeTests/TestMeshExporter.cs index d8e20e83f..cf6ff2e25 100644 --- a/Tests/EditModeTests/TestMeshExporter.cs +++ b/Tests/EditModeTests/TestMeshExporter.cs @@ -4,8 +4,9 @@ using System.Linq; using System.Text.RegularExpressions; using NUnit.Framework; +using PLATEAU.CityExport; +using PLATEAU.CityExport.Exporters; using PLATEAU.CityInfo; -using PLATEAU.Editor.CityExport; using PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI.ExportGUIParts; using PLATEAU.Geometries; using PLATEAU.MeshWriter; @@ -43,7 +44,7 @@ public void ExportMiniTokyoToObjFiles() var options = new MeshExportOptions( MeshExportOptions.MeshTransformType.Local, true, true, MeshFileFormat.OBJ, CoordinateSystem.ENU, - new ObjModelExporter()); + new ExportConfigGuiObj().GetExporter()); UnityModelExporter.Export(destDirPath, instancedCityModel, options); var expectedObjFiles = TestCityDefinition.MiniTokyo.GmlDefinitions @@ -66,7 +67,7 @@ public void ExportMiniTokyoToFbxFiles() var options = new MeshExportOptions( MeshExportOptions.MeshTransformType.Local, true, false, MeshFileFormat.FBX, CoordinateSystem.ENU, - new FbxModelExporter()); + new ExportConfigGuiFbx().GetExporter()); UnityModelExporter.Export(destDirPath, instancedCityModel, options); var expectedFbxFiles = TestCityDefinition.MiniTokyo.GmlDefinitions .Where(def => def.ContainsMesh) @@ -81,10 +82,12 @@ public void ExportMiniTokyoToGltfFiles() { string destDirPath = Path.Combine(DirectoryUtil.TempCacheFolderPath); var instancedCityModel = Object.FindObjectOfType(); + var gltfExportGui = new ExportConfigGuiGltf(); + ((CityExporterGltf)gltfExportGui.GetExporter()).GltfFileFormat = GltfFileFormat.GLTF; var options = new MeshExportOptions( MeshExportOptions.MeshTransformType.Local, true, false, MeshFileFormat.GLTF, CoordinateSystem.ENU, - new GltfModelExporter{GltfFileFormat = GltfFileFormat.GLTF}); + gltfExportGui.GetExporter()); UnityModelExporter.Export(destDirPath, instancedCityModel, options); var expectedGltfFiles = TestCityDefinition.MiniTokyo.GmlDefinitions .Where(def => def.ContainsMesh) diff --git a/Tests/EmptySceneForTest.unity b/Tests/EmptySceneForTest.unity index 8b1a59ec2..018e4ab4c 100644 --- a/Tests/EmptySceneForTest.unity +++ b/Tests/EmptySceneForTest.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c053b8e3a6533d028c0b69943e45b24291b0c57cfee66e98d25b55762ff93d5 -size 7794 +oid sha256:969ca703ba31e8e02789121f4f7feb74793a83d6cc207244fb4206ef47a585af +size 7887 diff --git a/Tests/TestUtils/TestCityDefinition.cs b/Tests/TestUtils/TestCityDefinition.cs index c5f2a1a66..37a48c5f8 100644 --- a/Tests/TestUtils/TestCityDefinition.cs +++ b/Tests/TestUtils/TestCityDefinition.cs @@ -5,8 +5,8 @@ using NUnit.Framework; using PLATEAU.CityImport.AreaSelector; using PLATEAU.CityImport.Config; -using PLATEAU.CityImport.Config.PackageLoadConfigs; -using PLATEAU.CityImport.Load; +using PLATEAU.CityImport.Config.PackageImportConfigs; +using PLATEAU.CityImport.Import; using PLATEAU.Editor.EditorWindow.ProgressDisplay; using PLATEAU.Dataset; using PLATEAU.Geometries; @@ -23,7 +23,7 @@ namespace PLATEAU.Tests.TestUtils internal class TestCityDefinition { public string SrcRootDirPathLocal => Path.GetFullPath(Path.Combine(testDataDir, this.rootDirName)); - public string[] AreaMeshCodes { get; set; } + public MeshCodeList AreaMeshCodes { get; set; } public int CoordinateZoneId { get; set; } public TestGmlDefinition[] GmlDefinitions { get; set; } @@ -31,7 +31,7 @@ internal class TestCityDefinition private static readonly string testDataDir = Path.Combine(PathUtil.SdkBasePath, "./Tests/TestData/日本語パステスト"); - public TestCityDefinition(string rootDirName, TestGmlDefinition[] gmlDefs, string[] areaMeshCodes, int coordinateZoneId) + public TestCityDefinition(string rootDirName, TestGmlDefinition[] gmlDefs, MeshCodeList areaMeshCodes, int coordinateZoneId) { this.rootDirName = rootDirName; GmlDefinitions = gmlDefs; @@ -73,9 +73,8 @@ public Task ImportServer() /// /// インポートするための設定を返します。 /// - private CityLoadConfig MakeConfig(bool isServer) + private CityImportConfig MakeConfig(bool isServer) { - var conf = new CityLoadConfig(); // TODO どのパッケージと何が対応するかは要テスト var allPackages = EnumUtil.EachFlags(PredefinedCityModelPackageExtension.All()); @@ -84,21 +83,25 @@ private CityLoadConfig MakeConfig(bool isServer) { allPackageLods.MergePackage(package, 3); } - - var dummyAreaSelectResult = new AreaSelectResult(AreaMeshCodes, allPackageLods); - conf.InitWithAreaSelectResult(dummyAreaSelectResult); + + IDatasetSourceConfig datasetSourceConfig = + isServer + ? new DatasetSourceConfigRemote(this.rootDirName, NetworkConfig.MockServerUrl, "") + : new DatasetSourceConfigLocal(SrcRootDirPathLocal); + + var dummyAreaSelectResult = new AreaSelectResult(new ConfigBeforeAreaSelect(datasetSourceConfig, 9), AreaMeshCodes); + var conf = CityImportConfig.CreateWithAreaSelectResult(dummyAreaSelectResult); + // メッシュコードがあるあたりに基準点を設定します。 Extent.Allの中心を基準点にすると極端な座標になるため。 using var geoRef = GeoReference.Create(new PlateauVector3d(0, 0, 0), 1.0f, CoordinateSystem.EUN, - conf.CoordinateZoneID); - conf.ReferencePoint = geoRef.Project(MeshCode.Parse(AreaMeshCodes[0]).Extent.Center); + conf.ConfBeforeAreaSelect.CoordinateZoneID); + conf.ReferencePoint = geoRef.Project(AreaMeshCodes.At(0).Extent.Center); - foreach (var packageConf in conf.PackageLoadConfigDict.ForEachPackagePair) + foreach (var packageConf in conf.PackageImportConfigDict.ForEachPackagePair) { packageConf.Value.IncludeTexture = true; } - - conf.DatasetSourceConfig = new DatasetSourceConfig(isServer, SrcRootDirPathLocal, this.rootDirName, NetworkConfig.MockServerUrl, ""); return conf; } @@ -156,14 +159,18 @@ public TestGmlDefinition(string gmlPath, string gameObjName, bool containsMesh, /// その内容を 形式で説明したものです。 /// public static readonly TestCityDefinition Simple = - new TestCityDefinition("TestDataSimpleGml", new[] - { - new TestGmlDefinition("udx/bldg/53392642_bldg_6697_op2.gml", "53392642_bldg_6697_op2.gml", true, null, - 2) - }, new[] - { - "53392642" - }, 9); + new TestCityDefinition( + "TestDataSimpleGml", + new[] + { + new TestGmlDefinition("udx/bldg/53392642_bldg_6697_op2.gml", "53392642_bldg_6697_op2.gml", true, + null, + 2) + }, MeshCodeList.CreateFromMeshCodesStr(new string[] + { + "53392642" + }), + 9); /// /// テストデータ "MiniTokyo" について、 @@ -188,10 +195,10 @@ public TestGmlDefinition(string gmlPath, string gameObjName, bool containsMesh, new TestGmlDefinition("udx/urf/533925_urf_6668_yoto_op.gml", "533925_urf_6668_yoto_op.gml", false, null, 0), new TestGmlDefinition("udx/fld/natl/tamagawa_tamagawa-asakawa-etc/53392547_fld_6697_l1_op.gml", "natl/tamagawa_tamagawa-asakawa-etc/53392547_fld_6697_l1_op.gml", true, null, 1), new TestGmlDefinition("udx/fld/natl/tamagawa_tamagawa-asakawa-etc/53392547_fld_6697_l2_op.gml", "natl/tamagawa_tamagawa-asakawa-etc/53392547_fld_6697_l2_op.gml", true, null, 1), - }, new [] + }, MeshCodeList.CreateFromMeshCodesStr(new string[] { "53394525", "53392546", "53392547", "533925" - }, 9); + }), 9); /// /// テストデータ "TestServer23Ku" について、 @@ -204,8 +211,8 @@ public TestGmlDefinition(string gmlPath, string gameObjName, bool containsMesh, null, 2), new TestGmlDefinition("udx/bldg/53392670_bldg_6697_2_op.gml", "53392670_bldg_6697_2_op.gml", true, null, 2) - }, new[] + }, MeshCodeList.CreateFromMeshCodesStr(new string[] { "53392642", "53392670" } - , 9); + ), 9); } } diff --git a/libplateau/CSharpPLATEAU/Dataset/DatasetSource.cs b/libplateau/CSharpPLATEAU/Dataset/DatasetSource.cs index 5ea8f5900..4553cb9c4 100644 --- a/libplateau/CSharpPLATEAU/Dataset/DatasetSource.cs +++ b/libplateau/CSharpPLATEAU/Dataset/DatasetSource.cs @@ -11,56 +11,52 @@ public class DatasetSource : PInvokeDisposable private DatasetSource(IntPtr handle) : base(handle) { } - + /// - /// を生成します。 + /// を生成します。 + /// ローカルかサーバーかは、引数の型によって判別します。 /// - /// データの場所は true ならサーバー、falseならローカルです。 - /// ローカルモードでのみ利用します。インポート元のパスを渡します。 - /// - /// サーバーモードでのみ利用します。データセットのIDを渡します。 - /// そのIDとは、APIサーバーにデータセットの一覧を問い合わせたときに得られるID文字列です。例: 東京23区のデータセットのIDは "23ku" - /// - /// サーバーモードでのみ利用します。サーバーのURLです。 - private static DatasetSource Create(bool isServer, string localSourcePath, string serverDatasetID, string serverUrl) - { - return Create(new DatasetSourceConfig(isServer, localSourcePath, serverDatasetID, serverUrl, "")); - } - - - public static DatasetSource Create(DatasetSourceConfig config) + public static DatasetSource Create(IDatasetSourceConfig conf) { - return config.IsServer ? - CreateServer(config.ServerDatasetID, config.ServerUrl, config.ServerToken) : - CreateLocal(config.LocalSourcePath); + switch (conf) + { + case DatasetSourceConfigLocal localConf: + return CreateLocal(localConf); + case DatasetSourceConfigRemote remoteConf: + return CreateServer(remoteConf); + default: + throw new ArgumentOutOfRangeException(nameof(conf)); + } } + /// - /// ローカルPCのデータセットを指す を作ります。 - /// - public static DatasetSource CreateLocal(string path) - { - var pathUtf8 = DLLUtil.StrToUtf8Bytes(path); - var result = NativeMethods.plateau_create_dataset_source_local(out var datasetSourcePtr, pathUtf8); - DLLUtil.CheckDllError(result); - return new DatasetSource(datasetSourcePtr); - } + /// ローカルPCのデータセットを指す を作ります。 + /// + private static DatasetSource CreateLocal(DatasetSourceConfigLocal conf) + { + var pathUtf8 = DLLUtil.StrToUtf8Bytes(conf.LocalSourcePath); + var result = NativeMethods.plateau_create_dataset_source_local(out var datasetSourcePtr, pathUtf8); + DLLUtil.CheckDllError(result); + return new DatasetSource(datasetSourcePtr); + } /// /// リモートPCのデータセットを指す を作ります。 /// - public static DatasetSource CreateServer(string datasetID, string serverUrl, string apiToken) + private static DatasetSource CreateServer(DatasetSourceConfigRemote conf) { - Client client = Client.Create(serverUrl, apiToken); + Client client = Client.Create(conf.ServerUrl, conf.ServerToken); var result = NativeMethods.plateau_create_dataset_source_server( - out var ptr, datasetID, client.Handle); + out var ptr, conf.ServerDatasetID, client.Handle); DLLUtil.CheckDllError(result); return new DatasetSource(ptr); } public static DatasetSource CreateForMockServer(string datasetID) { - return CreateServer(datasetID, NetworkConfig.MockServerUrl, ""); + var conf = new DatasetSourceConfigRemote(datasetID, NetworkConfig.MockServerUrl, ""); + return CreateServer(conf); } public DatasetAccessor Accessor diff --git a/libplateau/CSharpPLATEAU/Dataset/DatasetSourceConfig.cs b/libplateau/CSharpPLATEAU/Dataset/DatasetSourceConfig.cs index d1afab11f..1027211ff 100644 --- a/libplateau/CSharpPLATEAU/Dataset/DatasetSourceConfig.cs +++ b/libplateau/CSharpPLATEAU/Dataset/DatasetSourceConfig.cs @@ -3,36 +3,49 @@ namespace PLATEAU.Dataset { /// - /// の初期化方法は、データの場所がローカルかサーバーかで異なりますが、 - /// その違いを吸収するためのクラスです。 + /// データセット設定のローカルとサーバーの違いを吸収するインターフェイスです。 /// - [Serializable] - public class DatasetSourceConfig + public interface IDatasetSourceConfig + { + + } + + /// + /// ローカルインポートで利用するの設定です。 + /// + public class DatasetSourceConfigLocal : IDatasetSourceConfig { - public bool IsServer { get; set; } public string LocalSourcePath { get; set; } + + /// インポート元のパスです。 + public DatasetSourceConfigLocal(string localSourcePath) + { + LocalSourcePath = localSourcePath; + } + + } + + /// + /// サーバーインポートで利用するの設定です。 + /// + public class DatasetSourceConfigRemote : IDatasetSourceConfig + { public string ServerDatasetID { get; set; } public string ServerUrl { get; set; } public string ServerToken { get; set; } - /// - /// の初期化のための情報を渡すコンストラクタです。 - /// - /// データの場所は true ならサーバー、falseならローカルです。 - /// ローカルモードでのみ利用します。インポート元のパスを渡します。 /// - /// サーバーモードでのみ利用します。データセットのIDを渡します。 - /// そのIDとは、APIサーバーにデータセットの一覧を問い合わせたときに得られるID文字列です。例: 東京23区のデータセットのIDは "23ku" + /// データセットのIDを渡します。 + /// そのIDとは、APIサーバーにデータセットの一覧を問い合わせたときに得られるID文字列です。 /// - /// サーバーモードでのみ利用します。サーバーのURLです。 - /// サーバーモードでのみ利用します。サーバー認証のトークンです。 - public DatasetSourceConfig(bool isServer, string localSourcePath, string serverDatasetID, string serverUrl, string serverToken) + /// サーバーのURLです。 + /// サーバー認証のトークンです。 + public DatasetSourceConfigRemote(string serverDatasetID, string serverUrl, string serverToken) { - IsServer = isServer; - LocalSourcePath = localSourcePath; ServerDatasetID = serverDatasetID; ServerUrl = serverUrl; ServerToken = serverToken; } } + } diff --git a/libplateau/CSharpPLATEAU/Geometries/GeoReference.cs b/libplateau/CSharpPLATEAU/Geometries/GeoReference.cs index 3f9c470b5..fe5df111d 100644 --- a/libplateau/CSharpPLATEAU/Geometries/GeoReference.cs +++ b/libplateau/CSharpPLATEAU/Geometries/GeoReference.cs @@ -106,6 +106,20 @@ public GeoCoordinate Unproject(PlateauVector3d point) return outLatLon; } + public static PlateauVector3d ConvertAxisToENU(CoordinateSystem axis, PlateauVector3d vertex) + { + var result = NativeMethods.plateau_geo_reference_convert_axis_to_enu(axis, vertex, out var outVertex); + DLLUtil.CheckDllError(result); + return outVertex; + } + + public static PlateauVector3d ConvertAxisFromENUTo(CoordinateSystem axis, PlateauVector3d vertex) + { + var result = NativeMethods.plateau_geo_reference_convert_axis_from_enu_to(axis, vertex, out var outVertex); + DLLUtil.CheckDllError(result); + return outVertex; + } + public PlateauVector3d ReferencePoint => DLLUtil.GetNativeValue(Handle, NativeMethods.plateau_geo_reference_get_reference_point); @@ -200,6 +214,20 @@ internal static extern APIResult plateau_geo_reference_get_unit_scale( internal static extern APIResult plateau_geo_reference_get_coordinate_system( [In] IntPtr handle, out CoordinateSystem outCoordinateSystem); + + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_geo_reference_convert_axis_to_enu( + CoordinateSystem axis, + PlateauVector3d vertex, + out PlateauVector3d outVertex); + + + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_geo_reference_convert_axis_from_enu_to( + CoordinateSystem axis, + PlateauVector3d vertex, + out PlateauVector3d outVertex); + } } } diff --git a/libplateau/CSharpPLATEAU/PolygonMesh/CityObjectList.cs b/libplateau/CSharpPLATEAU/PolygonMesh/CityObjectList.cs index bc2cd19da..20b4112d8 100644 --- a/libplateau/CSharpPLATEAU/PolygonMesh/CityObjectList.cs +++ b/libplateau/CSharpPLATEAU/PolygonMesh/CityObjectList.cs @@ -26,6 +26,18 @@ public static CityObjectIndex FromUV(PlateauVector2f uv) AtomicIndex = (int)Math.Round(uv.Y) }; } + + public override int GetHashCode() + { + return PrimaryIndex * 10000 + AtomicIndex; + } + + public override bool Equals(object obj) + { + var other = obj as CityObjectIndex?; + if (other == null) return false; + return PrimaryIndex == other.Value.PrimaryIndex && AtomicIndex == other.Value.AtomicIndex; + } } diff --git a/libplateau/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs b/libplateau/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs index 37ac431d0..6cd33fa36 100644 --- a/libplateau/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs +++ b/libplateau/CSharpPLATEAU/PolygonMesh/MeshExtractOptions.cs @@ -26,6 +26,25 @@ public enum MeshGranularity PerCityModelArea } + public static class MeshGranularityExtension + { + public static string ToJapaneseString(this MeshGranularity granularity) + { + switch (granularity) + { + case MeshGranularity.PerAtomicFeatureObject: + return "最小地物単位"; + case MeshGranularity.PerPrimaryFeatureObject: + return "主要地物単位"; + case MeshGranularity.PerCityModelArea: + return "地域単位"; + default: + throw new ArgumentOutOfRangeException(nameof(granularity)); + } + } + } + + /// /// GMLファイルから3Dメッシュを取り出すための設定です。 diff --git a/libplateau/CSharpPLATEAU/PolygonMesh/Node.cs b/libplateau/CSharpPLATEAU/PolygonMesh/Node.cs index 56486cc37..2d25cd6a5 100644 --- a/libplateau/CSharpPLATEAU/PolygonMesh/Node.cs +++ b/libplateau/CSharpPLATEAU/PolygonMesh/Node.cs @@ -93,6 +93,25 @@ public Mesh Mesh } } + public bool IsActive + { + get + { + ThrowIfInvalid(); + bool isActive = DLLUtil.GetNativeValue( + this.Handle, + NativeMethods.plateau_node_get_is_active); + return isActive; + } + + set + { + ThrowIfInvalid(); + var result = NativeMethods.plateau_node_set_is_active(this.Handle, value); + DLLUtil.CheckDllError(result); + } + } + /// /// にセットします。 /// 取扱注意: @@ -184,6 +203,18 @@ internal static extern APIResult plateau_node_get_child_count( [In] IntPtr nodeHandle, out int outChildCount); + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_node_get_is_active( + [In] IntPtr nodePtr, + [MarshalAs(UnmanagedType.U1)] out bool outIsActive + ); + + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_node_set_is_active( + [In] IntPtr nodePtr, + [MarshalAs(UnmanagedType.U1)] bool isActive + ); + [DllImport(DLLUtil.DllName)] internal static extern APIResult plateau_node_get_child_at_index( [In] IntPtr nodeHandle, diff --git a/libplateau/CSharpPLATEAU/PolygonMesh/SubMesh.cs b/libplateau/CSharpPLATEAU/PolygonMesh/SubMesh.cs index 50d7e4c23..ad2966e3c 100644 --- a/libplateau/CSharpPLATEAU/PolygonMesh/SubMesh.cs +++ b/libplateau/CSharpPLATEAU/PolygonMesh/SubMesh.cs @@ -74,6 +74,29 @@ public PLATEAU.CityGML.Material Material } } + /// + /// は、にゲームエンジンのマテリアルを持たせたい場合に、 + /// の代わりに利用するIDです。 + /// 特に分割結合でゲームエンジンのマテリアルを維持するために利用します。 + /// IDがどのマテリアルを指すかはゲームエンジンが決めます。 + /// + public int GameMaterialID + { + get + { + ThrowIfInvalid(); + int gameMaterialID = + DLLUtil.GetNativeValue(Handle, NativeMethods.plateau_sub_mesh_get_game_material_id); + return gameMaterialID; + } + set + { + ThrowIfInvalid(); + var result = NativeMethods.plateau_sub_mesh_set_game_material_id(Handle, value); + DLLUtil.CheckDllError(result); + } + } + /// /// 取扱注意: /// 通常は が廃棄されるときに C++側で も廃棄されるので、 @@ -123,6 +146,17 @@ internal static extern APIResult plateau_sub_mesh_get_texture_path( internal static extern APIResult plateau_sub_mesh_get_material( [In] IntPtr subMeshPtr, out IntPtr matPtr); + + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_sub_mesh_set_game_material_id( + [In] IntPtr subMeshPtr, + int gameMaterialID); + + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_sub_mesh_get_game_material_id( + [In] IntPtr subMeshPtr, + out int outGameMaterialID); + [DllImport(DLLUtil.DllName, CharSet = CharSet.Ansi)] internal static extern APIResult plateau_create_sub_mesh( diff --git a/package.json b/package.json index 12c5ec651..581c876b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.synesthesias.plateau-unity-sdk", - "version": "2.2.1-alpha", + "version": "2.3.0", "displayName": "PLATEAU SDK for Unity", "description": "このパッケージには、PLATEAUの3D都市モデルデータを利用するためのAPI、サンプルが含まれます。PLATEAU SDK for Unityを利用することで、実世界を舞台にしたゲームの開発や、PLATEAUの豊富なデータを活用したシミュレーションを簡単に行うことができます。", "unity": "2021.3",