diff --git a/Documentation~/manual/AccessCityObject.md b/Documentation~/manual/AccessCityObject.md index 21c4e814d..c3ee5cc1d 100644 --- a/Documentation~/manual/AccessCityObject.md +++ b/Documentation~/manual/AccessCityObject.md @@ -1,4 +1,4 @@ -# 都市情報へのアクセス +# 属性情報へのアクセス C# APIやPLATEAU SDKの機能によって都市オブジェクトの情報を取得できます。 このページでその方法を説明します。 diff --git a/Documentation~/manual/ExportCityModels.md b/Documentation~/manual/ExportCityModels.md index 841de2777..43627b4fd 100644 --- a/Documentation~/manual/ExportCityModels.md +++ b/Documentation~/manual/ExportCityModels.md @@ -1,5 +1,5 @@ -# 都市モデルのエクスポート -Unityのシーンに配置された都市の3Dモデルを、objファイルや gltfファイルとしてエクスポートできます。 +# 3D都市モデルのエクスポート +Unityのシーンに配置された都市の3Dモデルを、FBX、OBJ、glTFとしてエクスポートできます。 このページではエクスポートの手順を説明します。 ## 前提 @@ -10,7 +10,7 @@ Unityのシーンに都市モデルがインポートされていることが前 ## エクスポート手順 ### エクスポート対象の指定 - Unityのメニューバーから `PLATEAU → PLATEAU SDK` を選択します。 - 表示されるウィンドウの上部に3つのタブ「インポート、モデル調整、エクスポート」があります。 + 表示されるウィンドウの上部に3つのタブ「インポート、モデル調整、エクスポート、属性情報」があります。 このうちエクスポートを選択します。 ![](../resources/manual/exportCityModels/exportWindow.png) @@ -21,8 +21,7 @@ Unityのシーンに都市モデルがインポートされていることが前 - 親子関係の最上位には自動で `PLATEAUInstancedCityModel` コンポーネントが付与されています。 このコンポーネントを持つゲームオブジェクトが選択対象となります。 - 出力形式を選択します。 - - OBJ形式か、GLTF形式かを選択します。 - - ただし、OBJ形式はフォーマットの仕様上、後述の技術的な制約があります。 + - ファイル形式をFBX,OBJ,GLTFから選択できます。 ### 出力オプションの設定 @@ -37,8 +36,14 @@ Unityのシーンに都市モデルがインポートされていることが前 - **GLB** - 3Dモデルとその関連データをまとめて1つのファイルとするフォーマットです。 -- **テクスチャ** +- **テクスチャを含める** - 出力にテクスチャを含めるかどうかを設定します。チェックが付いていれば含みます。 + +- **SDK付属のデフォルトテクスチャを含める** + - 「テクスチャを含める」がオンのときのみ表示される設定項目です。 + - オフの場合、PLATEAU SDK付属のデフォルトマテリアルがマテリアルなしに置き換わって出力されます。 + - SDK付属のデフォルトマテリアルのテクスチャは、SDK付属のTriplanarシェーダーでのみ動作することを想定しています。 + そのためデフォルトではオフとしています。 - **非アクティブオブジェクトを含める** @@ -64,46 +69,41 @@ Unityのシーンに都市モデルがインポートされていることが前 - 原点付近に3Dモデルが来るようにしたいときは Local - 原点から遠い位置に3Dモデルが配置されますが、複数の異なる都市をエクスポートするときに位置の整合性を取りたいときは Plane Cartesian が利用できます。 - `座標軸` - - エクスポートした objファイルを Unityにインポートしたい場合は、 - 後述の理由で WUN を指定してください。 - - **座標軸設定の趣旨:** - - x,y,z 軸がどの方向を向いているかはアプリケーションによって異なりますが、 - この設定項目によって座標軸の違いに合わせて変換できます。 - - 座標軸の名称はアルファベット3文字で表され、 - (1文字目,2文字目,3文字目) が (x軸,y軸,z軸) の向きを表します。 - - 例えば、Unityでは x軸が東(East), y軸が上(Up), z軸が北(North) を向くので、 - 頭文字をとって EUN が Unityの座標系となります。 - - ただし、Unity向けに objをエクスポートするときは、 - 後述の理由で EUN ではなく WUN が正しい指定となります。 - - W は 西(West) を表します。 + - 選択したファイル形式がFBXまたはOBJの場合に表示されます。 + - X,Y,Z軸の向きを決めます。利用したいアプリケーションに応じて選択してください。 + - 例えば、エクスポートしたファイルをUnityにインポートしたい場合は、Y軸が上を指す座標軸を選択してください。 + - GLTF形式の場合は、仕様で座標軸が決まっているため、この設定項目は表示されません。 + ->[!NOTE] -> **OBJファイルの技術的制約について** -> -> OBJファイルはそのフォーマットの仕様上、制約があります。 -> -> 1. オブジェクトが分割されず、1つのオブジェクトとして出力されます。 -> その代わり、頂点グループとしてオブジェクト内で領域分けされます。 -> 例えば、Blenderの場合、インポート時に `頂点グループ` にチェックを入れると、図のように頂点グループが設定されます。 -> ![](../resources/manual/exportCityModels/blenderVertexGroup.png) -> -> 3. objファイルを Unity にインポートするとき、左右が反転します。これを防ぎたい場合は、座標系WUNで出力してください。 -> これは Unity の仕様によるものです。 -> Unityの座標系は EUN ですが、EUNで出力した objファイルをインポートすると左右反転したモデルになります。 -> そこで EUN を左右反転させた座標系である WUN で出力すると、Unityにインポートしたときに正しくなります。 -> このようになる理由は、Unityは objファイルを右手座標系であると解釈し、Unityの左手座標系に合わせるために x座標の正負を反転させるためです。 + +- `FBXフォーマット` + - 出力形式がFBXのときのみ表示される設定項目です。 + - FBXを扱うご利用のソフトウェアに応じて選択してください。 + - BlenderやUnityでご利用あればBinaryを推奨します。 ### エクスポート - 出力先のフォルダを指定します。 - `エクスポート` ボタンを押してしばらく待ちます。 -- 指定のフォルダに3Dモデルファイルが出力されます。 +- 正常終了の場合、指定のフォルダに3Dモデルファイルが出力され、そのフォルダが開きます。 + 異常終了の場合、ダイアログが表示されます。 ![](../resources/manual/exportCityModels/tokyoBlender.png) -上図はエクスポートしたobjファイルを Blender で読み込んだものです。 +上図はエクスポートしたOBJファイルを Blender で読み込んだものです。 + +## エクスポートの仕様 +- OBJファイルはそのフォーマットの仕様上、次の制約があります。 + - オブジェクトが分割されず、1つのオブジェクトとして出力されます。 + その代わり、頂点グループとしてオブジェクト内で領域分けされます。 + 例えば、Blenderの場合、インポート時に `頂点グループ` にチェックを入れると、図のように頂点グループが設定されます。 + ![](../resources/manual/exportCityModels/blenderVertexGroup.png) +- Unity内でのTransform情報(Position, Rotation, Scale)はエクスポートしたファイルに反映されます。 + - FBX,GLTFの場合は、ノードとしてUnityのPosition, Rotation, Scale および親子関係が反映されます。 + - OBJの場合は、OBJの仕様上親子関係が反映されないため、頂点座標が直接Position, Rotation, Scaleにより変形されて出力されます。 >[!NOTE] > **エクスポートした3Dモデルを再度Unityに取り込む場合** > > テクスチャ込みでエクスポートしたものを再度Unityにインポートする場合は、 -> 3Dモデルファイルとそれに対応するテクスチャフォルダを複数選択して -> Unityのプロジェクトビューにドラッグ&ドロップしてインポートしてください。 \ No newline at end of file +> 3Dモデルファイルとそれに対応するテクスチャフォルダをエクスプローラー(Windowsの場合。Macの場合はFinder)から複数選択して +> Unityのプロジェクトビューにドラッグ&ドロップしてインポートしてください。 +> 複数選択による同時インポートでないと、テクスチャが正しく適用されない場合があります。 diff --git a/Documentation~/manual/ImportCityModels.md b/Documentation~/manual/ImportCityModels.md index 449f2839d..29310df0a 100644 --- a/Documentation~/manual/ImportCityModels.md +++ b/Documentation~/manual/ImportCityModels.md @@ -1,9 +1,9 @@ -# 都市モデルのインポート +# 3D都市モデルのインポート このページでは、都市データをUnityプロジェクトにインポートする手順を説明します。 ## 準備 -- PlateauSDK を導入したUnityプロジェクトを用意します。 +- PLATEAU SDK for Unityを導入したUnityプロジェクトを用意します。 SDKの導入方法は [インストール](Installation.md) を参照してください。 ## インポート手順 @@ -12,7 +12,7 @@ 表示されるウィンドウの上部に4つのタブ「インポート、モデル調整、エクスポート、属性情報」があります。 このうちインポートを選択します。 ![](../resources/manual/importCityModels/plateauWindowImport.png) -- インポート先で`ローカル`または`サーバー`を選択します。 +- インポート元で`ローカル`または`サーバー`を選択します。 #### ローカルからインポートする場合 @@ -138,6 +138,7 @@ - モデルのメッシュは結合されて出力されます。 - オブジェクト数を削減して軽量化できますが、建物ごとの地物データは取得不可になります。 - メッシュの結合はある程度の大きさの範囲ごとに行われます。 + - 地域単位でインポートする場合、見た目が同じマテリアルは結合されます。すなわち、色などの数値情報とテクスチャパスが同じ場合に結合されます。 >[!NOTE] @@ -161,9 +162,8 @@ >[!NOTE] > **地物の選択について** -> 地物の中にはインポートに時間がかかるものもあるのでご注意ください。 -> 例えば 土地起伏 はデータの範囲が 10km × 10km と非常に広く、 -> データ容量が重く処理に時間がかかるのでご注意ください。 +> 地物の中にはインポートに時間がかかるものがあります。 +> 特に土地起伏、土地利用はデータ容量が重く処理に時間がかかるのでご注意ください。 >[!NOTE] > **現実の景観と異なる地物について** @@ -176,9 +176,9 @@ >[!NOTE] > **道路の高さについて** -> LOD1 の道路は、PLATEAUの仕様上、高さのデータを含みません。 +> LOD1,LOD2 の道路は、PLATEAUの仕様上、高さのデータを含みません。 > したがって、インポートするとすべて高さ 0 で表現されます。 -> LOD2 以上の道路は高さが反映されます。 +> LOD3 以上の道路は高さが反映されます。 ### 土地に衛星写真や地図を貼り付ける @@ -262,4 +262,11 @@ インポートの結果、計算状況ウィンドウの内容がすべて「完了」となれば良いですが、 ロードできなかったgmlファイルに関しては「失敗」と表示されます。 そのような場合でも、他のgmlファイルのロードが成功していれば、そのgmlに関しては正常にインポートされています。 -失敗の場合は Unityのコンソールにエラーログが出力されます。 \ No newline at end of file +失敗の場合は Unityのコンソールにエラーログが出力されます。 + + +### インポートされた3Dモデルの保存先 +インポートされた3Dモデルやテクスチャは、シーンファイルの中に直接保存されます。 +これによるシーンファイルの肥大化を改善したい場合は、 +モデル調整機能の「Assetsに保存」機能を利用してシーンからFBXに書き出すことができます。 +詳しくは[こちら](ModelAdjust.md#assetsに保存機能)をご覧ください。 diff --git a/Documentation~/manual/Installation.md b/Documentation~/manual/Installation.md index 5e943a173..829d186c0 100644 --- a/Documentation~/manual/Installation.md +++ b/Documentation~/manual/Installation.md @@ -1,9 +1,9 @@ # インストール -このページでは PLATEAU SDK for Unity のインストール方法を説明します。 +このページではPLATEAU SDK for Unityのインストール方法を説明します。 ## 対応Unityバージョンのインストール -- PLATEAU SDK for Unity で想定するUnityバージョンが[リリースページ](https://github.com/Project-PLATEAU/PLATEAU-SDK-for-Unity/releases)に記載されています。 +- PLATEAU SDK for Unityで想定するUnityバージョンが[リリースページ](https://github.com/Project-PLATEAU/PLATEAU-SDK-for-Unity/releases)に記載されています。 そのバージョンがインストールされていない場合は、次の手順でインストールしてください。 - [Unity Hub をこちらからインストールします](https://unity3d.com/jp/get-unity/download)。 - Unity Hub とは、Unityのお好きなバージョンをインストールして起動することのできるソフトウェアです。 @@ -58,6 +58,14 @@ PLATEAU SDK for Unity の導入方法は2通りあります。 - ウィンドウのパッケージ一覧に `Plateau Unity SDK` が表示されたら完了です。 ![](../resources/manual/installation/packageInstalled.png) +### Android向けにビルドする場合 +Android向けにビルドする場合、次のようにUnityプロジェクトを設定してください。 +- メニューバーから Edit → Project Settingsを選びます。 +- 表示されたウィンドウの左パネルからPlayerを選びます。 +- Other Settingsを開きます。 +- Scripting BackendをIL2CPPにします。 +- Target ArchitecturesはARM64だけがチェックが入っているようにします。 + ### トラブルシューティング うまく導入できない場合、次のことをご確認ください。 - お使いのウイルス対策ソフトによっては、SDKに含まれるバイナリファイルが削除されることがあります。ウィルス対策ソフトによってSDKのファイルが削除されないよう設定をお願いします。 diff --git a/Documentation~/manual/ModelAdjust.md b/Documentation~/manual/ModelAdjust.md index 27f00f46c..e7fe35ddd 100644 --- a/Documentation~/manual/ModelAdjust.md +++ b/Documentation~/manual/ModelAdjust.md @@ -1,24 +1,64 @@ -# モデル修正 +# 3D都市モデルの編集 ## 概要 PLATEAUウィンドウの`モデル修正`では、インポートした都市モデルを編集できます。 次の機能があります。 +- Assetsに保存 + - シーン内に直接保存されている都市モデルを、属性情報等を保ったままFBXに書き出します。 + - 肥大化したシーンファイルを軽量化するのに便利です。 - ゲームオブジェクトON/OFF - 条件指定で一括でアクティブ化・非アクティブ化します。 -- マテリアル分け - - 地物型に応じてマテリアルを分けます。 -- 結合・分離 - - モデルを結合・分離し、ゲームオブジェクトの粒度を変更します。 +- 分割/結合/マテリアル分け + - 地物の結合・分離や属性情報・地物型によるマテリアル分けを行います。 +- 地形変換/高さ合わせ + - 地形の平滑化とテレインへの変換、高さ情報が無い地物(LOD1道路モデル等)の地形への高さ合わせを行います。 + +> [!NOTE] +> 地物とは・・建物、道路、地形など、地図上に表示されるもの。物理的なものとは限らず、都市計画区域、土砂災害警戒区域などの目には見えない領域を示すものも地物の一種として扱います。 +> 地形とは・・地表の起伏です。 ### 操作画面の開き方 - Unityのメニューバーから `PLATEAU` → `PLATEAU SDK` を選択します。 - ウィンドウ上部のタブのうち `モデル調整` を選択します。 -- その下のタブで`ゲームオブジェクトON/OFF`、`結合/分離`を切り替えて表示します。 +- その下のタブで各機能を切り替えて表示します。 +## 「Assetsに保存」機能 + +![](../resources/manual/cityAdjust/saveToAssets.png) + +### できること + +- シーン内に直接保存されている都市モデルを、 + 属性情報等を保ったままFBXに書き出すことでシーンファイルを軽量化します。 +- PLATEAU SDKを使ってインポートした3Dモデルやテクスチャは、 + 通常シーンファイルに直接保存されます。 + このデメリットとして、シーンファイルが肥大化し、保存等の操作に時間がかかることがあります。 + そのような状況を改善するため、シーン内に埋め込まれた都市モデルを + FBX形式でAssetsフォルダ内に書き出し、シーンの容量を削減して編集しやすくするための機能です。 + 加えて、UnityのFBXインポート設定が可能になることで調整の幅が広がる利点もあります。 +- Assetsに保存しても、属性情報やマテリアルは維持されます。 + また、別途アドオンであるPLATEAU-SDK-Toolkits-for-Unityの自動テクスチャ機能を適用している場合も、その見た目が維持されます。 + +### 使い方 + +- `元オブジェクト` には、処理の対象にしたいゲームオブジェクトを選択します。 + - そのヒエラルキーの子も対象となります。 +- `出力先選択`ボタンを押して、出力先を選択します。出力先は次の条件を満たす必要があります。 + - UnityプロジェクトのAssetsフォルダ以下であること + - 空のフォルダであること +- `Assetsに保存`ボタンを押して実行します。 +- 実行すると、新しいゲームオブジェクト`Asset_(元のゲームオブジェクト名)`が生成されます。 + - 生成された3Dモデルは、見た目は元と同じですが、 + 3Dモデルとテクスチャの実態は、出力先に生成されたFBXやテクスチャを参照しています。 + - マテリアルと都市の情報(属性情報など)は元オブジェクトからコピーされます。 +- 生成結果に問題がなければ、元のゲームオブジェクトを削除して + シーンを保存することでシーンファイルが軽量化されます。 + ## ゲームオブジェクトON/OFF機能 + ![](../resources/manual/cityAdjust/gameObjOnOff.png) - 条件指定をしてフィルタリングできます。 - ここでいうフィルタリングとは、条件に合致するゲームオブジェクトをアクティブにし、そうでないものを非アクティブにすることを指します。 @@ -37,43 +77,132 @@ PLATEAUウィンドウの`モデル修正`では、インポートした都市 > 分類指定のチェックマークは入れ子構造になっていますが、第1階層の「建築物」「道路」といった分類は結合単位によらず必ず動作し、 > 第2階層の「窓」「屋根面」といった細かい分類はインポート時に「最小値物単位」にした場合のみ動作します。 -## マテリアル分け機能 +## 分割・結合・マテリアル分け機能 + ![](../resources/manual/cityAdjust/materialByType.png) + ### できること -- 地物型に応じてマテリアルを設定できます。 -- 例えば上図は、建築物の屋根面を緑色のマテリアルに設定した例です。 + +- 選択されたゲームオブジェクトの粒度を変更できます。 + - 例えば、主要地物単位でインポートされたものを結合して地域単位にまとめたり、分解して最小地物単位にしたりできます。 + - 属性情報も合わせて分割・結合されます。 +- 地物型や属性情報に応じてマテリアルを設定できます。 + - 例えば上図は、地物型によるマテリアル分けによって建築物の屋根面を緑色のマテリアルに設定した例です。 + - また下図は、属性情報によるマテリアル分けによって道路のうち歩道を茶色、車道を灰色に設定した例です。 + +![](../resources/manual/cityAdjust/materialByAttr.png) ### 操作方法 -- `選択オブジェクト`には、現在選択中のゲームオブジェクトが表示されます。これが処理の対象になります。複数選択可能です。 - - 対象は、コンポーネント`PLATEAUCityObjectGroup`が付与されているゲームオブジェクト、またはその親である必要があります。 - - 対象に`PLATEAUCityObjectGroup`がない場合、インポート時に属性情報を含める設定にしたことを確認してください。 -- `マテリアル分類`には`地物型`と表示され、地物型に応じてマテリアルを張り替えることを示しています。 - - 今は地物型しか選べませんが、今後は属性情報で分けるモードも追加予定です。 -- `検索`ボタンを押すと、選択対象に含まれる地物型が検索され、ボタン下に列挙されます。 - - このあとで対象オブジェクトを変更したい場合は、`再選択`ボタンを押します。 -- `粒度`では、処理後に3Dモデルがどの粒度でゲームオブジェクトに分けられるかを選択します。 -- 処理前のゲームオブジェクトを削除するか、残すかを選択します。 -- 地物型ごとにマテリアルを選択します。 - - 画面には、選択した地物に含まれる地物型が列挙されています。 - - それぞれの地物型について、マテリアルを変更するか、変更する場合はどのマテリアルにするかを指定します。 -- 実行ボタンを押すと、処理を実行します。 - -## 結合/分離機能 -![](../resources/manual/cityAdjust/splitCombineWindow.png) +- PLATEAU Windowの「モデル修正」タブ → 「分割/結合/マテリアル分け」タブを開きます。 + + ![](../resources/manual/cityAdjust/materialAdjustWindow.png) -### できること +#### 対象選択 -- 選択されたゲームオブジェクトの粒度を変更します。 -- 例えば、主要地物単位でインポートされたものを結合して地域単位にまとめたり、分解して最小地物単位にしたりできます。 -- 属性情報も合わせて分割・結合されます。 +`対象選択`では処理の対象となるゲームオブジェクトを指定します。 +指定の方法は次のとおりいくつかあります。 +- `追加`スロットにゲームオブジェクトをドラッグするか選択することで追加します。 +- `選択中のn個を追加`ボタンを押すことで、現在選択中のオブジェクト(複数可)を追加します。 +- `パッケージ種から選択`ボタンを押すことで下図の選択ウィンドウが開き、指定のパッケージ種に該当するものをまとめて指定します。 +![](../resources/manual/cityAdjust/packageSelectWindow.png) + - パッケージ種選択ウィンドウ内でデータセットを選択すると、データセットに含まれるパッケージ種が検索され選択肢として表示されます。 + - 選択肢から任意個のパッケージを選んで`決定`を押して選択できます。 +- 追加したオブジェクトは`除く`ボタンで対象から除きます。 -### 操作方法 +#### 共通設定 + +- `オブジェクト配置`では、変換後に元オブジェクトを削除するか残すかを選択します。 + +#### 分割/結合 + +- `粒度を変更する`にチェックが入っている場合、`粒度`で指定した粒度に変換します。 + - 最小地物単位(壁面・屋根等面等ごと) + - 主要地物内のマテリアルごと(マテリアル分けの結果に応じてゲームオブジェクトを分けた場合に便利です) + - 主要地物単位(建築物・道路等ごと) + - すべて1つに結合(インポート時の地域単位に相当します) +- `粒度を変更する`にチェックが入っていない状態でマテリアル分けした場合、現在と同じ粒度にします。 +- 後述の`マテリアル分けを条件指定で変更する`にチェックが入っていない状態で実行ボタンを押した場合、 + マテリアルを変えずに粒度を変更します。 + +#### マテリアル分け + +条件に応じてマテリアル分けをします。 +また分割/結合で粒度が指定されている場合、その粒度に変換します。 +- `マテリアルを条件指定で変更する` にチェックが入っている場合、以下の設定項目のとおりにマテリアルを分けます。 + チェックが入っていない場合、マテリアルを変更せず分割結合のみ行います。 +- `分類`は、マテリアル分けの基準として`地物型`か`属性情報`を選択できます。 + +#### 地物型でのマテリアル分け + +- `地物型`をマテリアル分けの基準とした場合、設定項目は次のようになります。 + 下図は建築物のうち屋根面のみを緑色にする場合の設定です。 + +![](../resources/manual/cityAdjust/windowByType.png) + +- `検索`ボタンを押すことでマテリアルの設定画面が表示されます。 +- `パターン`で表示される条件に合致するマテリアルを指定します。 +- `マテリアルを変更する`にチェックが入っていないものはマテリアルを変更しません。 + チェックが入っているものに関してマテリアルを選択します。 + +##### 属性情報でのマテリアル分け + +- `属性情報`をマテリアル分けの基準とした場合、設定項目は次のようになります。 + 下図は道路のうち歩道部分を茶色、車道部分をグレー色にする場合の設定です。 + +![](../resources/manual/cityAdjust/windowByAttr.png) + +- `属性情報キー`で分類基準となる属性情報のキーを指定します。 + - この際、`属性情報キーを選択`ボタンを押すことで下図のウィンドウが表示され、選択肢から選んで入力できます。 + ![](../resources/manual/cityAdjust/attrSelectWindow.png) + このウィンドウでは、対象オブジェクトとその子に存在する属性情報を検索して表示します。 + 選択肢から1つ選んで`決定`ボタンを押すことで属性情報キーを選択します。 +- 以下、`検索`ボタン、パターンごとのマテリアル指定、実行は上述の「地物型でのマテリアル分け」と同じです。 +- 処理が完了すると結果は新しいゲームオブジェクトとして配置され、それらがヒエラルキー上で選択状態となります。`主要地物内の同一マテリアル単位`で分割結合した場合は出力されたゲームオブジェクトの名前は"Material-(マテリアルID)"となり、それ以外の場合はオブジェクトが対応する地物のgml:idと同じ文字列で設定されます。 + +## 地形変換/高さ合わせ機能 +![image (3)](https://github.com/user-attachments/assets/d0af1040-c40d-4335-9b3c-4139aeb69a56) + +`地形変換/高さ合わせ`画面では以下を行えます。 +- 地形の平滑化 + - 地形モデルの平滑化・テレインへの変換を行います。 +- 高さ合わせ + - LOD1道路等、高さが付与されていない地物の地形への高さ合わせや、LOD3道路にめり込んでしまっている地形の形状修正を行います。 + +> [!NOTE] +> 高さ合わせ対象となる都市モデルは次のパッケージタイプです。 +> 「道路、災害リスク、土地利用、都市計画決定情報、徒歩道、広場、水部、交通(航路)」 + +> [!NOTE] +> テレインのメリットは、例えば芸術的な目的で高さを変える、テクスチャペイントするなどの操作をUnityの標準機能でできることにあります。詳しくは[こちら](https://docs.unity3d.com/ja/2019.4/Manual/terrain-UsingTerrains.html)のUnityマニュアルをご覧ください。 +> 高さ合わせは、急傾斜の地形では誤差が出ることがあります。 + +### 使い方 + +- `変換対象`には、起伏モデルを含む都市モデルを選択します。 +- `オブジェクト配置`プルダウンを選択します。 + - `新規追加`は元のコンポーネントを非表示にし、そのまま残します。 + - `置き換える`は元のコンポーネントを削除します。 +- `詳細設定`から更に細かい設定が行えます。 +- `実行`ボタンを押すと地形の平滑化が行われ、道路、災害リスク、土地利用等対象の都市モデルが変換した地形に重なるよう自動的に調整されます。 + +地形変換/高さ合わせ処理の成果物について、テレイン化の成果物は名前の先頭に"TERRAIN_"と付与された名前のテレインになります。高さ合わせした地物については、前と同じ名前のゲームオブジェクトが生成されます。 + +### 詳細設定 + +![](../resources/manual/cityAdjust/advancedSettings.png) + +#### 地形変換 +- `地形変換`にチェックを入れると地形の変換(平滑化・テレインへの変換)が有効になり、更に詳細なオプションが表示されます。 + - `解像度`プルダウンから変換時にハイトマップとして利用する画像解像度を選択できます。 + - `ハイトマップ平滑化`にチェックを入れるとハイトマップにぼかしフィルタを適用し、よりスムーズな地形になります。 + - `地形変換`では、地形の起伏を滑らかに変更する処理が入ります。そのため、測量の高さを厳密に使いたいケース、特に測量からの誤差の少なさが重要となる状況ではこの処理はそぐわない場合があります。 + - `余白を端の高さに合わせる`にチェックを入れるとハイトマップの余白を一番端のピクセルで埋めます。チェックが外れていると余白部分の高さは0になります。 + +#### 高さ合わせ機能 +- `高さ合わせ`にチェックを入れると地物の高さ合わせが有効となり、更に詳細なオプションが表示されます。 + - `交通・区域モデルの高さを地形に合わせる`にチェックをいれると道路、災害リスク、土地利用等の都市モデルを変換した地形に重なるよう調整します。 + - `土地をLOD3道路モデルに合わせる`にチェックをいれると地形モデルの形状がLOD3道路モデルに合わせて修正されます。 + - インスペクターで非表示にしていなくても、シーン上で非表示にしたものについては高さ合わせの対象外となります。 -- `選択オブジェクト`には、現在選択中のゲームオブジェクトが表示されます。これが変換対象になります。 - - 選び方は、変換したいゲームオブジェクトの親を1つ選択しても良いですし、変換したい地物を複数選択しても良いです。 -- `単位`では変換後の結合粒度を指定します。 - - `地域単位`: 3Dモデルが1つのゲームオブジェクトにまとまります。 - - `主要地物単位`: 例えば建築物の場合、建物1つごとに1つのゲームオブジェクトになります。 - - `最小地物単位`: 例えば建築物の場合、窓、屋根などのパーツごとに1つのゲームオブジェクトになります。 -- `実行`ボタンで変換を実行します。 -- 実行後、ダイアログが表示され、変換前のゲームオブジェクトを削除するか残すかを選択できます。 \ No newline at end of file +> [!CAUTION] +> 地形変換の機能を利用するためには、都市モデルインポート時に`起伏`を含めてインポートする必要があります。 diff --git a/Documentation~/manual/runtimeAPI.md b/Documentation~/manual/runtimeAPI.md index dfffc0890..35a39f509 100644 --- a/Documentation~/manual/runtimeAPI.md +++ b/Documentation~/manual/runtimeAPI.md @@ -22,6 +22,9 @@ `Assets/Samples/PLATEAU SDK for Unity/(バージョン)/PLATEAU Samples/APISample/RuntimeAPISample.cs` 以下にそのコードを解説します。 + +### ランタイムAPI利用の下準備 + ### インポート ```csharp @@ -115,4 +118,14 @@ public async void GranularityConvert() ここで`conf`は分割結合の設定であり、次のように設定できます。 `new GranularityConvertOptionUnity(new GranularityConvertOption(ここに粒度を入れる, 1), ここに変換対象の配列を入れる, 元のオブジェクトを消すならtrueで残すならfalse);` -なお`new GranularityConvertOption`の2つ目の引数である`1`は、未実装の設定項目のためどの数値をいれても動作に影響しません。 \ No newline at end of file +なお`new GranularityConvertOption`の2つ目の引数である`1`は、未実装の設定項目のためどの数値をいれても動作に影響しません。 + +## Assembly Definition Assetを利用する場合 +Assembly Definition Assetをご利用の場合、 +PLATEAUのAPIを利用するためには次のように設定する必要があります。 + +- ご利用のAssembly Definition Assetのうち、PLATEAUのAPIを利用したいものを選択します。 +- インスペクタからAssembly Definition Referencesに次を追加します。 + - PLATEAU.Runtime + - libplateau +- Applyを押します。 diff --git a/Documentation~/manual/toc.yml b/Documentation~/manual/toc.yml index 7cc65c2e8..ee3d91afe 100644 --- a/Documentation~/manual/toc.yml +++ b/Documentation~/manual/toc.yml @@ -4,13 +4,13 @@ items: - name: インストール href: Installation.md - - name: 都市モデルのインポート + - name: 3D都市モデルのインポート href: ImportCityModels.md - - name: 都市モデルのエクスポート + - name: 3D都市モデルのエクスポート href: ExportCityModels.md - - name: モデル修正 + - name: 3D都市モデルの編集 href: ModelAdjust.md - - name: 都市情報へのアクセス + - name: 属性情報へのアクセス href: AccessCityObject.md - name: SDKのマテリアルについて href: sdkMaterial.md diff --git a/Documentation~/resources/manual/cityAdjust/advancedSettings.png b/Documentation~/resources/manual/cityAdjust/advancedSettings.png new file mode 100644 index 000000000..6f827ac52 Binary files /dev/null and b/Documentation~/resources/manual/cityAdjust/advancedSettings.png differ diff --git a/Documentation~/resources/manual/cityAdjust/attrSelectWindow.png b/Documentation~/resources/manual/cityAdjust/attrSelectWindow.png new file mode 100644 index 000000000..1762938c1 Binary files /dev/null and b/Documentation~/resources/manual/cityAdjust/attrSelectWindow.png differ diff --git a/Documentation~/resources/manual/cityAdjust/materialAdjustWindow.png b/Documentation~/resources/manual/cityAdjust/materialAdjustWindow.png new file mode 100644 index 000000000..2613b25e4 Binary files /dev/null and b/Documentation~/resources/manual/cityAdjust/materialAdjustWindow.png differ diff --git a/Documentation~/resources/manual/cityAdjust/materialByAttr.png b/Documentation~/resources/manual/cityAdjust/materialByAttr.png new file mode 100644 index 000000000..46b7ce59f Binary files /dev/null and b/Documentation~/resources/manual/cityAdjust/materialByAttr.png differ diff --git a/Documentation~/resources/manual/cityAdjust/packageSelectWindow.png b/Documentation~/resources/manual/cityAdjust/packageSelectWindow.png new file mode 100644 index 000000000..eca8f8409 Binary files /dev/null and b/Documentation~/resources/manual/cityAdjust/packageSelectWindow.png differ diff --git a/Documentation~/resources/manual/cityAdjust/saveToAssets.png b/Documentation~/resources/manual/cityAdjust/saveToAssets.png new file mode 100644 index 000000000..9a283c1a9 Binary files /dev/null and b/Documentation~/resources/manual/cityAdjust/saveToAssets.png differ diff --git a/Documentation~/resources/manual/cityAdjust/terrainWindow.png b/Documentation~/resources/manual/cityAdjust/terrainWindow.png new file mode 100644 index 000000000..713a3d168 Binary files /dev/null and b/Documentation~/resources/manual/cityAdjust/terrainWindow.png differ diff --git a/Documentation~/resources/manual/cityAdjust/windowByAttr.png b/Documentation~/resources/manual/cityAdjust/windowByAttr.png new file mode 100644 index 000000000..fc493abcf Binary files /dev/null and b/Documentation~/resources/manual/cityAdjust/windowByAttr.png differ diff --git a/Documentation~/resources/manual/cityAdjust/windowByType.png b/Documentation~/resources/manual/cityAdjust/windowByType.png new file mode 100644 index 000000000..62ea91216 Binary files /dev/null and b/Documentation~/resources/manual/cityAdjust/windowByType.png differ diff --git a/Documentation~/resources/manual/exportCityModels/exportWindow.png b/Documentation~/resources/manual/exportCityModels/exportWindow.png index fb2c20e22..7946e247a 100644 Binary files a/Documentation~/resources/manual/exportCityModels/exportWindow.png and b/Documentation~/resources/manual/exportCityModels/exportWindow.png differ diff --git a/Documentation~/resources/manual/importCityModels/plateauWindowImport.png b/Documentation~/resources/manual/importCityModels/plateauWindowImport.png index 307d24a3f..9552425be 100644 Binary files a/Documentation~/resources/manual/importCityModels/plateauWindowImport.png and b/Documentation~/resources/manual/importCityModels/plateauWindowImport.png differ diff --git a/Editor/CityImport/AreaSelector/AreaSelectorStarter.cs b/Editor/CityImport/AreaSelector/AreaSelectorStarter.cs index a04be5170..92d2855b6 100644 --- a/Editor/CityImport/AreaSelector/AreaSelectorStarter.cs +++ b/Editor/CityImport/AreaSelector/AreaSelectorStarter.cs @@ -1,7 +1,6 @@ using PLATEAU.CityImport.AreaSelector; using PLATEAU.CityImport.Config; -using PLATEAU.Dataset; -using PLATEAU.Editor.EditorWindow.PlateauWindow; +using PLATEAU.Editor.Window.Main; using PLATEAU.Util; using UnityEditor; using UnityEditor.SceneManagement; diff --git a/Editor/CityImport/CityImportConfigGUI.cs b/Editor/CityImport/CityImportConfigGUI.cs index 54330232d..7ab81cba8 100644 --- a/Editor/CityImport/CityImportConfigGUI.cs +++ b/Editor/CityImport/CityImportConfigGUI.cs @@ -3,7 +3,7 @@ using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Editor.CityImport.PackageImportConfigGUIs; using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; namespace PLATEAU.Editor.CityImport { diff --git a/Editor/CityImport/PackageImportConfigGUIs/Components/LodGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Components/LodGUI.cs index 45b89bb6b..49a246a7b 100644 --- a/Editor/CityImport/PackageImportConfigGUIs/Components/LodGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Components/LodGUI.cs @@ -1,7 +1,7 @@ using System; using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components { diff --git a/Editor/CityImport/PackageImportConfigGUIs/Components/MapZoomLevelSelectGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Components/MapZoomLevelSelectGUI.cs index a0c636a9c..a64b21042 100644 --- a/Editor/CityImport/PackageImportConfigGUIs/Components/MapZoomLevelSelectGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Components/MapZoomLevelSelectGUI.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using PLATEAU.CityImport.Config; using PLATEAU.Dataset; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; using PLATEAU.Native; using PLATEAU.Texture; using PLATEAU.Util; diff --git a/Editor/CityImport/PackageImportConfigGUIs/Components/PositionConfGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Components/PositionConfGUI.cs index 3d0200493..79a98202d 100644 --- a/Editor/CityImport/PackageImportConfigGUIs/Components/PositionConfGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Components/PositionConfGUI.cs @@ -1,5 +1,5 @@ using PLATEAU.CityImport.Config; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; using UnityEditor; using UnityEngine; diff --git a/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/TextureIncludeGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/TextureIncludeGUI.cs index e87bdd779..1c3e48f3c 100644 --- a/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/TextureIncludeGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Extendables/Components/TextureIncludeGUI.cs @@ -1,5 +1,5 @@ using PLATEAU.CityImport.Config.PackageImportConfigs; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; using UnityEditor; namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables.Components diff --git a/Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigOverrideGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigOverrideGUI.cs index d7a00ecd5..ea02eb5c0 100644 --- a/Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigOverrideGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/Extendables/PackageImportConfigOverrideGUI.cs @@ -1,7 +1,7 @@ using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables.Components; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; using UnityEditor; namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables diff --git a/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUI.cs index 8cfcada6a..04b5e7307 100644 --- a/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUI.cs @@ -3,7 +3,7 @@ using PLATEAU.Dataset; using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components; using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; using UnityEditor; namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs diff --git a/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIComponent.cs b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIComponent.cs index 6c27dc230..45e65cd3b 100644 --- a/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIComponent.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIComponent.cs @@ -1,5 +1,5 @@ using PLATEAU.CityImport.Config.PackageImportConfigs; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs { diff --git a/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIList.cs b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIList.cs index d900d4368..469dc5d50 100644 --- a/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIList.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/PackageImportConfigGUIList.cs @@ -3,7 +3,7 @@ using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Extendables; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; namespace PLATEAU.Editor.CityImport.PackageImportConfigGUIs { diff --git a/Editor/CityImport/PackageImportConfigGUIs/ReliefImportConfigGUI.cs b/Editor/CityImport/PackageImportConfigGUIs/ReliefImportConfigGUI.cs index 575fe49a5..69c1cc008 100644 --- a/Editor/CityImport/PackageImportConfigGUIs/ReliefImportConfigGUI.cs +++ b/Editor/CityImport/PackageImportConfigGUIs/ReliefImportConfigGUI.cs @@ -3,7 +3,7 @@ using PLATEAU.CityImport.Config.PackageImportConfigs; using PLATEAU.Dataset; using PLATEAU.Editor.CityImport.PackageImportConfigGUIs.Components; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; using UnityEditor; using UnityEngine; diff --git a/Editor/CityInfo/PLATEAUCityObjectGroupEditor.cs b/Editor/CityInfo/PLATEAUCityObjectGroupEditor.cs index ca2f02070..0195b49db 100644 --- a/Editor/CityInfo/PLATEAUCityObjectGroupEditor.cs +++ b/Editor/CityInfo/PLATEAUCityObjectGroupEditor.cs @@ -1,5 +1,5 @@ using PLATEAU.CityInfo; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; using PLATEAU.PolygonMesh; using UnityEditor; using UnityEditorInternal; @@ -10,7 +10,7 @@ namespace PLATEAU.Editor.CityInfo [CustomEditor(typeof(PLATEAUCityObjectGroup))] public class PLATEAUCityObjectGroupEditor : UnityEditor.Editor { - Vector2 scroll; + private readonly ScrollView scrollView = new (GUILayout.MaxHeight(400)); public void OnEnable() { @@ -31,9 +31,10 @@ public override void OnInspectorGUI() PlateauEditorStyle.Heading("属性情報", null); using (PlateauEditorStyle.VerticalScopeLevel1()) { - scroll = EditorGUILayout.BeginScrollView(scroll, GUILayout.MaxHeight(400)); - EditorGUILayout.TextArea(json); - EditorGUILayout.EndScrollView(); + scrollView.Draw(() => + { + EditorGUILayout.TextArea(json); + }); } using (new EditorGUI.DisabledScope(true)) diff --git a/Editor/CityInfo/PLATEAUInstancedCityModelEditor.cs b/Editor/CityInfo/PLATEAUInstancedCityModelEditor.cs index 1dd6f080e..441009edb 100644 --- a/Editor/CityInfo/PLATEAUInstancedCityModelEditor.cs +++ b/Editor/CityInfo/PLATEAUInstancedCityModelEditor.cs @@ -1,5 +1,5 @@ using PLATEAU.CityInfo; -using PLATEAU.Editor.EditorWindow.Common; +using PLATEAU.Editor.Window.Common; using PLATEAU.Geometries; using PLATEAU.Native; using UnityEditor; diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts.meta deleted file mode 100644 index 76c2263c6..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2d077da95f874279873f17d17b5e1a26 -timeCreated: 1671076235 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/DestroyOrPreserveSrcGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/DestroyOrPreserveSrcGUI.cs deleted file mode 100644 index d81ed0549..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/DestroyOrPreserveSrcGUI.cs +++ /dev/null @@ -1,25 +0,0 @@ -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 deleted file mode 100644 index 0d1f0d8b2..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/DestroyOrPreserveSrcGUI.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: dbdc28b6a19b4b528ef309c35e6eecb2 -timeCreated: 1701158349 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/FilterConditionGUI.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/FilterConditionGUI.cs.meta deleted file mode 100644 index 97136923d..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/AdjustGUIParts/FilterConditionGUI.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 7fe237331fcf4f25b4981f01f2283929 -timeCreated: 1671076260 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAddGUI.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAddGUI.cs.meta deleted file mode 100644 index b066476f9..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityAddGUI.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2c329dfd329d441b80d416a2a2955c6e -timeCreated: 1662359510 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityChangeActiveGUI.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityChangeActiveGUI.cs.meta deleted file mode 100644 index 2627560d5..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityChangeActiveGUI.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 38726f9e66b94c529bfe681d51c4db9f -timeCreated: 1662359818 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityExportGUI.cs.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityExportGUI.cs.meta deleted file mode 100644 index 384762be4..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityExportGUI.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 6f856f156697478da650bf9cde1dbbf1 -timeCreated: 1662359853 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityGranularityConvertGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityGranularityConvertGUI.cs deleted file mode 100644 index e949dd7a9..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityGranularityConvertGUI.cs +++ /dev/null @@ -1,106 +0,0 @@ -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; -using UnityEditor; -using UnityEngine; - -namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI -{ - /// - /// PLATEAU SDK ウィンドウで「結合/分離」タブが選択されている時のGUIです。 - /// - internal class CityGranularityConvertGUI : IEditorDrawable - { - private readonly UnityEditor.EditorWindow parentEditorWindow; - private GameObject[] selected = Array.Empty(); - private Vector2 scrollSelected; - private int selectedUnit = 2; - private static readonly string[] UnitOptions = { "最小地物単位(壁面,屋根面等)", "主要地物単位(建築物,道路等)", "地域単位" }; - private readonly DestroyOrPreserveSrcGUI destroyOrPreserveGUI = new(); - - private readonly bool isExecTaskRunning = false; - - public CityGranularityConvertGUI(UnityEditor.EditorWindow parentEditorWindow) - { - this.parentEditorWindow = parentEditorWindow; - Selection.selectionChanged += OnSelectionChanged; - } - - public void Dispose() - { - Selection.selectionChanged -= OnSelectionChanged; - Array.Clear(selected,0, selected.Length); - } - - private void OnSelectionChanged() - { - //選択アイテムのフィルタリング処理 - selected = Selection.gameObjects; - parentEditorWindow.Repaint(); - } - - public void Draw() - { - PlateauEditorStyle.SubTitle("選択したモデルデータの結合・分離を行います。"); - PlateauEditorStyle.Heading("選択オブジェクト", null); - using (PlateauEditorStyle.VerticalScopeLevel2()) - { - scrollSelected = EditorGUILayout.BeginScrollView(scrollSelected, GUILayout.MaxHeight(100)); - foreach (GameObject obj in selected) - { - EditorGUILayout.LabelField(obj.name); - } - EditorGUILayout.EndScrollView(); - } - - PlateauEditorStyle.Heading("設定", null); - - using (PlateauEditorStyle.VerticalScopeWithPadding(16, 0, 8, 16)) - { - EditorGUIUtility.labelWidth = 50; - this.selectedUnit = - PlateauEditorStyle.PopupWithLabelWidth( - "分割・結合単位", this.selectedUnit, UnitOptions, 90); - destroyOrPreserveGUI.Draw(); - } - - // if(selectedUnit == 0 ) - // { - // this.foldOutOption = PlateauEditorStyle.FoldOut(this.foldOutOption, "Option", () => - // { - // using (PlateauEditorStyle.VerticalScopeWithPadding(16, 0, 8, 16)) - // { - // toggleMaxSize = EditorGUILayout.ToggleLeft("メッシュが最大サイズを超える場合はグリッド分割する", toggleMaxSize); - // } - // }, 30); - // } - - PlateauEditorStyle.Separator(0); - - using (new EditorGUI.DisabledScope(isExecTaskRunning)) - { - if (PlateauEditorStyle.MainButton(isExecTaskRunning ? "処理中..." : "実行")) - { - Exec().ContinueWithErrorCatch(); - } - } - } - - private async Task Exec() - { - Debug.Log("変換開始"); - var converter = new CityGranularityConverter(); - 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.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportConfigGUI.cs.meta deleted file mode 100644 index 77907ae40..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityImportConfigGUI.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2764dbcbb4624537af7b238b85fa7cd7 -timeCreated: 1702054079 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityMaterialAdjustGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityMaterialAdjustGUI.cs deleted file mode 100644 index 7280226f7..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityMaterialAdjustGUI.cs +++ /dev/null @@ -1,183 +0,0 @@ -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 -{ - /// - /// PLATEAU SDK ウィンドウで「マテリアル分け」タブが選択されている時のGUIです。 - /// - internal class CityMaterialAdjustGUI : IEditorDrawable - { - private UnityEditor.EditorWindow parentEditorWindow; - private GameObject[] selectedObjs = new GameObject[0]; - private Vector2 scrollSelected; - private int selectedType; - private string[] typeOptions = { "地物型" /*, "属性情報"*/ }; - private string attrKey = ""; - 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(selectedObjs, 0, selectedObjs.Length); - } - - private void OnSelectionChanged() - { - 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 selectedObjs) - { - 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)) - { - EditorGUIUtility.labelWidth = 50; - this.selectedType = EditorGUILayout.Popup("分類", this.selectedType, typeOptions); - } - - ; - } - - private void DisplayCityObjTypeSearchButton() - { - using (PlateauEditorStyle.VerticalScopeWithPadding(0, 0, 15, 0)) - { - PlateauEditorStyle.CenterAlignHorizontal(() => - { - if (adjuster == null) - { - if (PlateauEditorStyle.MiniButton("検索", 150)) - { - 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(); - } - } - }); - } - } - - private void DisplayCityObjectTypeMaterialConfGUI() - { - var conf = adjuster.MaterialAdjustConf; - int displayIndex = 1; - - // 存在する地物型を列挙します - foreach (var (typeNode, typeConf) in conf) - { - using (PlateauEditorStyle.VerticalScopeLevel1()) - { - PlateauEditorStyle.CategoryTitle( - $"地物型{displayIndex} : {typeNode.GetDisplayName()}"); - typeConf.ChangeMaterial = EditorGUILayout.ToggleLeft("マテリアルを変更する", typeConf.ChangeMaterial); - if (typeConf.ChangeMaterial) - { - typeConf.Material = (Material)EditorGUILayout.ObjectField("マテリアル", - typeConf.Material, typeof(Material), false); - } - } - - displayIndex++; - } - } - } -} \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityModificationFrameGUI.cs b/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityModificationFrameGUI.cs deleted file mode 100644 index 21f7b6b73..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityModificationFrameGUI.cs +++ /dev/null @@ -1,39 +0,0 @@ -using PLATEAU.Editor.EditorWindow.Common; - -namespace PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI -{ - /// - /// PLATEAU SDK ウィンドウで「モデル調整」タブが選択されている時のGUIです。 - /// - internal class CityModificationFrameGUI : IEditorDrawable - { - private int tabIndex; - private readonly IEditorDrawable[] tabGUIArray; - private string[] tabNames = { "ゲームオブジェクト\nON/OFF" , "マテリアル分け", "結合/分離" }; - - public CityModificationFrameGUI(UnityEditor.EditorWindow parentEditorWindow) - { - this.tabGUIArray = new IEditorDrawable[] - { - new CityChangeActiveGUI(), - new CityMaterialAdjustGUI(parentEditorWindow), - new CityGranularityConvertGUI(parentEditorWindow) - }; - } - - public void Draw() - { - this.tabIndex = PlateauEditorStyle.TabsForFrame(this.tabIndex, tabNames); - using (PlateauEditorStyle.VerticalLineFrame()) - { - this.tabGUIArray[this.tabIndex].Draw(); - } - } - - public void Dispose() - { - foreach (var gui in tabGUIArray) - gui.Dispose(); - } - } -} diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts.meta deleted file mode 100644 index 733f9ffd4..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ExportGUIParts.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 93734dd8848b42f597e819e7a6dc4a0c -timeCreated: 1677471264 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts.meta b/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts.meta deleted file mode 100644 index 4f3b6ba65..000000000 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/ImportGUIParts.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ee16d2c8b1f9463697e6a27e521a6a92 -timeCreated: 1669712808 \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/PlateauWindow.cs b/Editor/EditorWindow/PlateauWindow/PlateauWindow.cs deleted file mode 100644 index bc585cca9..000000000 --- a/Editor/EditorWindow/PlateauWindow/PlateauWindow.cs +++ /dev/null @@ -1,39 +0,0 @@ -using PLATEAU.Editor.EditorWindow.Common; -using UnityEditor; -using UnityEngine; - -namespace PLATEAU.Editor.EditorWindow.PlateauWindow -{ - /// - /// PLATEAU SDK ウィンドウのエントリーポイントです。 - /// - internal class PlateauWindow : UnityEditor.EditorWindow - { - private Vector2 scrollPosition; - private PlateauWindowGUI gui; - - [MenuItem("PLATEAU/PLATEAU SDK")] - public static void Open() - { - var window = GetWindow("PLATEAU SDK"); - window.Show(); - } - - private void OnGUI() - { - this.gui ??= new PlateauWindowGUI(this); - using var scrollView = new EditorGUILayout.ScrollViewScope(this.scrollPosition); - this.scrollPosition = scrollView.scrollPosition; - PlateauEditorStyle.SetCurrentWindow(this); - this.gui.Draw(); - } - - /// テストからアクセスする用 - internal const string NameOfInnerGuiField = nameof(gui); - - private void OnDestroy() - { - gui.Dispose(); - } - } -} diff --git a/Editor/EditorWindow/PlateauWindow/PlateauWindowGUI.cs b/Editor/EditorWindow/PlateauWindow/PlateauWindowGUI.cs deleted file mode 100644 index d4a5d8c24..000000000 --- a/Editor/EditorWindow/PlateauWindow/PlateauWindowGUI.cs +++ /dev/null @@ -1,53 +0,0 @@ -using PLATEAU.Editor.EditorWindow.Common; -using PLATEAU.Editor.EditorWindow.PlateauWindow.MainTabGUI; -using System; - -namespace PLATEAU.Editor.EditorWindow.PlateauWindow -{ - internal class PlateauWindowGUI : IEditorDrawable - { - public Action OnTabChange; - private int TabIndex { get => this.tabIndex; - set { - if(value != this.tabIndex) - OnTabChange?.Invoke(value); - this.tabIndex = value; - } - } - private int tabIndex; - private readonly IEditorDrawable[] tabGUIArray; - - private readonly string[] tabImages = - { "dark_icon_import.png", "dark_icon_modify.png", "dark_icon_export.png", "dark_icon_information.png" }; - - public PlateauWindowGUI(UnityEditor.EditorWindow parentEditorWindow) - { - this.tabGUIArray = new IEditorDrawable[] - { - new CityAddGUI(parentEditorWindow), - new CityModificationFrameGUI(parentEditorWindow), - new CityExportGUI(), - new CityAttributeGUI(parentEditorWindow, this) - }; - } - - public void Draw() - { - // ウィンドウのメインとなるタブ選択GUIを表示し、選択中のタブGUIクラスに描画処理を委譲します。 - this.TabIndex = PlateauEditorStyle.TabWithImages(this.TabIndex, this.tabImages, 80); - PlateauEditorStyle.MainLogo(); - this.tabGUIArray[this.TabIndex].Draw(); - } - - public void Dispose() - { - foreach (var gui in tabGUIArray) - gui.Dispose(); - } - - /// テストからアクセスする用 - internal const string NameOfTabIndex = nameof(tabIndex); - - internal const string NameOfTabGUIArray = nameof(tabGUIArray); - } -} diff --git a/Editor/EditorWindow/PlateauWindow/PlateauWindowGUI.cs.meta b/Editor/EditorWindow/PlateauWindow/PlateauWindowGUI.cs.meta deleted file mode 100644 index cff4b505b..000000000 --- a/Editor/EditorWindow/PlateauWindow/PlateauWindowGUI.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 3cecd040438c4cd1b34cc358aa945c78 -timeCreated: 1662359310 \ No newline at end of file diff --git a/Editor/RoadNetwork.meta b/Editor/RoadNetwork.meta new file mode 100644 index 000000000..f0b89b2c4 --- /dev/null +++ b/Editor/RoadNetwork.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4b58fc8f6f97fc34283cbc4231322d1f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/RoadNetwork/RnIDDrawer.cs b/Editor/RoadNetwork/RnIDDrawer.cs new file mode 100644 index 000000000..1bc3fffc3 --- /dev/null +++ b/Editor/RoadNetwork/RnIDDrawer.cs @@ -0,0 +1,59 @@ +using PLATEAU.RoadNetwork.Data; +using UnityEditor; +using UnityEngine; + +namespace PLATEAU.Editor.RoadNetwork +{ +#if true + public class RnIDDrawer : PropertyDrawer where T : IPrimitiveData + { + private static readonly string typeName = typeof(T).Name.Replace("RoadNetworkData", ""); + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + var id = property.FindPropertyRelative(RnID.IdFieldName); + var val = id?.intValue ?? -1; + // 編集不可にする + EditorGUI.BeginDisabledGroup(true); + EditorGUI.IntField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), $"{label.text}[{typeName}]", val); + EditorGUI.EndDisabledGroup(); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return EditorGUIUtility.singleLineHeight; + } + } + + [CustomPropertyDrawer(typeof(RnID))] + public class RnTrackIDDrawer : RnIDDrawer { } + + + [CustomPropertyDrawer(typeof(RnID))] + public class RnNodeIDDrawer : RnIDDrawer { } + + + [CustomPropertyDrawer(typeof(RnID))] + public class RnLinkIDDrawer : RnIDDrawer { } + + + [CustomPropertyDrawer(typeof(RnID))] + public class RnLineStringIDDrawer : RnIDDrawer { } + + [CustomPropertyDrawer(typeof(RnID))] + public class RnPointIDDrawer : RnIDDrawer { } + + + [CustomPropertyDrawer(typeof(RnID))] + public class RnBlockIDDrawer : RnIDDrawer { } + + + [CustomPropertyDrawer(typeof(RnID))] + public class RnWayIDDrawer : RnIDDrawer { } + + + [CustomPropertyDrawer(typeof(RnID))] + public class RnLaneIDDrawer : RnIDDrawer { } + +#endif +} \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityGranularityConvertGUI.cs.meta b/Editor/RoadNetwork/RnIDDrawer.cs.meta similarity index 83% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/CityGranularityConvertGUI.cs.meta rename to Editor/RoadNetwork/RnIDDrawer.cs.meta index 98d1280e2..b5ede781c 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityGranularityConvertGUI.cs.meta +++ b/Editor/RoadNetwork/RnIDDrawer.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1bcfc9027b3c8864e8189b73f5af10c3 +guid: 7f5e1af8b3d4deb488a333e002e38960 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/RoadNetwork/RoadNetworkBlockDrawer.cs b/Editor/RoadNetwork/RoadNetworkBlockDrawer.cs new file mode 100644 index 000000000..44d2378f3 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkBlockDrawer.cs @@ -0,0 +1,16 @@ +using PLATEAU.RoadNetwork; +using UnityEditor; +using UnityEngine.UIElements; + +namespace PLATEAU.Editor.RoadNetwork +{ + [CustomPropertyDrawer(typeof(RoadNetworkBlock))] + public class RoadNetworkBlockDrawer : PropertyDrawer + { + public override VisualElement CreatePropertyGUI(SerializedProperty property) + { + + return base.CreatePropertyGUI(property); + } + } +} \ No newline at end of file diff --git a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityModificationFrameGUI.cs.meta b/Editor/RoadNetwork/RoadNetworkBlockDrawer.cs.meta similarity index 83% rename from Editor/EditorWindow/PlateauWindow/MainTabGUI/CityModificationFrameGUI.cs.meta rename to Editor/RoadNetwork/RoadNetworkBlockDrawer.cs.meta index 3e769b767..80dfe1b60 100644 --- a/Editor/EditorWindow/PlateauWindow/MainTabGUI/CityModificationFrameGUI.cs.meta +++ b/Editor/RoadNetwork/RoadNetworkBlockDrawer.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 098664410c1b0304fa2c20ebb9f3e0ff +guid: d60bd9b5cf754ea49822ff28593726d1 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/RoadNetwork/RoadNetworkEditingSystem.cs b/Editor/RoadNetwork/RoadNetworkEditingSystem.cs new file mode 100644 index 000000000..eb6c63c36 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkEditingSystem.cs @@ -0,0 +1,442 @@ +using NUnit.Framework; +using PLATEAU.RoadNetwork; +using PLATEAU.RoadNetwork.Data; +using System; +using System.Linq; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace PLATEAU.Editor.RoadNetwork +{ + /// + /// 内部システムが利用するインターフェイス + /// + public interface IRoadNetworkEditingSystemInterface + { + //public RoadNetworkUIDoc UIDocEditor { get; } + public IRoadNetworkEditOperation NetworkOperator { get; } + public RoadNetworkSceneGUISystem SceneGUISystem { get; } + } + + /// + /// 道路ネットワーク編集システムのインスタンス + /// 管理元 + /// 出来るだけサブシステム同士で連携を取らないようにする + /// + public class RoadNetworkEditingSystem : IRoadNetworkEditingSystemInterface + { + /// + /// システムのインスタンスを管理する機能を提供するインターフェイス + /// + public interface ISystemInstance + { + void RequestReinitialize(); + } + + /// + /// + /// + /// + /// + public RoadNetworkEditingSystem(ISystemInstance editorInstance, VisualElement rootVisualElement) + { + Assert.IsNotNull(editorInstance); + this.systemInstance = new EditorInstance(this, editorInstance); + + Assert.IsNotNull(rootVisualElement); + this.rootVisualElement = rootVisualElement; + system = new EditingSystem(this); + TryInitialize(rootVisualElement); + } + + /// + /// 編集機能を提供するインターフェイス + /// + public IRoadNetworkEditOperation NetworkOperator => editOperation; + + /// + /// シーンのGUIのシステムを提供する + /// UnityEditor.Editorを継承するクラスでのみ使用する + /// 呼び出す箇所は一か所にする + /// + public RoadNetworkSceneGUISystem SceneGUISystem => sceneGUISystem; + + // 道路ネットワークを所持したオブジェクトのデフォルト名 + private readonly string defaultRoadNetworkObjectName = "RoadNetworkTester"; + + private readonly ISystemInstance systemInstance; + private readonly VisualElement rootVisualElement; + + // 選択している道路ネットワークを所持したオブジェクト + private UnityEngine.Object roadNetworkObject; + // 選択している道路ネットワーク + private RoadNetworkModel roadNetworkModel; + // 現在の編集モード + private RoadNetworkEditMode editingMode; + + // 選択中の道路ネットワーク要素 Link,Lane,Block...etc + private System.Object selectedRoadNetworkElement; + + // 選択中の信号制御器のパターン + private TrafficSignalControllerPattern selectedSignalPattern; + // 選択中の信号制御器のパターンのフェーズ + private TrafficSignalControllerPhase selectedSignalPhase; + + // 内部システム同士が連携する時や共通データにアクセスする際に利用する + private readonly IRoadNetworkEditingSystem system; + + private IRoadNetworkEditOperation editOperation; + private RoadNetworkUIDoc uiDocEditor; + private RoadNetworkSceneGUISystem sceneGUISystem; + + // 道路ネットワーク関係のアセットを管理するクラス + private RoadNetworkEditorAssets assets; + + /// + /// 初期化を試みる + /// 多重初期化はしないので複数回呼び出しても問題ない + /// + /// + /// + private bool TryInitialize(VisualElement rootVisualElement) + { + // 初期化の必要性チェック + bool needIniteditOperation = editOperation == null; + bool needInitEditor = uiDocEditor == null; + bool needInitGUISystem = sceneGUISystem == null; + + + // 初期化 Initlaize() + if (needIniteditOperation) + { + editOperation = new RoadNetworkEditorOperation(); + } + + if (needInitEditor) + { + assets = new RoadNetworkEditorAssets(); + + var visualTree = assets.GetAsset(RoadNetworkEditorAssets.EditorAssetName); + var inst = visualTree.Instantiate(); + rootVisualElement.Add(inst); + //visualTree.CloneTree(rootVisualElement); + + uiDocEditor = new RoadNetworkUIDoc(system, rootVisualElement, assets); + uiDocEditor.Initialize(); + + } + + if (needInitGUISystem) + { + sceneGUISystem = new RoadNetworkSceneGUISystem(system); + } + + // 他のシステム連携が必要な初期化 PostInitliaze() + if (needInitEditor) + { + uiDocEditor.PostInitialize(); + } + + // その他 初期化 + + // 道路ネットワークの取得を試みる 自動設定機能 + var roadNetworkObj = GameObject.Find(defaultRoadNetworkObjectName); + if (roadNetworkObj != null) + { + this.roadNetworkObject = roadNetworkObj; + Selection.activeGameObject = roadNetworkObj; + } + return true; + } + + /// + /// 内部システムが利用するインターフェイス + /// 内部システム同士が連携する時や共通データにアクセスする際に利用する + /// + public interface IRoadNetworkEditingSystem + { + /// + /// 編集機能のインスタンス + /// + ISystemInstance EditorInstance { get; } + + /// + /// 道路ネットワークを所持したUnityオブジェクト + /// + UnityEngine.Object RoadNetworkObject { get; set; } + event EventHandler OnChangedRoadNetworkObject; + + /// + /// 道路ネットワーク + /// + RoadNetworkModel RoadNetwork { get; } + + /// + /// 現在の編集モード + /// + RoadNetworkEditMode CurrentEditMode { get; set; } + event EventHandler OnChangedEditMode; + /// + /// 編集機能を提供するインターフェイス + /// + IRoadNetworkEditOperation EditOperation { get; } + + /// + /// 選択中の道路ネットワーク要素 + /// + System.Object SelectedRoadNetworkElement { get; set; } + event EventHandler OnChangedSelectRoadNetworkElement; + + /// + /// 選択中の信号制御器のパターン + /// + TrafficSignalControllerPattern SelectedSignalControllerPattern { get; set; } + event EventHandler OnChangedSignalControllerPattern; + /// + /// 選択中の信号制御器のパターンのフェーズ + /// + TrafficSignalControllerPhase SelectedSignalPhase { get; set; } + event EventHandler OnChangedSignalControllerPhase; + + /// + /// 道路ネットワークを所持したオブジェクトに変更があったことをUnityEditorに伝える + /// + void NotifyChangedRoadNetworkObject2Editor(); + + } + + /// + /// 内部システムが利用するインスタンス + /// 内部システム同士が連携する時や共通データにアクセスする際に利用する + /// + private class EditingSystem : IRoadNetworkEditingSystem + { + public EditingSystem(RoadNetworkEditingSystem system) + { + Assert.IsNotNull(system); + this.system = system; + } + + + private readonly RoadNetworkEditingSystem system; + + + public UnityEngine.Object RoadNetworkObject + { + get => system.roadNetworkObject; + set + { + if (system.roadNetworkObject == value) + return; + + var roadNetworkObj = value as IRoadNetworkObject; + Assert.IsNotNull(roadNetworkObj); + if (roadNetworkObj == null) + return; + var roadNetwork = roadNetworkObj.RoadNetwork; + if (roadNetwork == null) + return; + + system.roadNetworkObject = value; + system.roadNetworkModel = roadNetwork; + OnChangedRoadNetworkObject?.Invoke(this, EventArgs.Empty); + } + + } + public event EventHandler OnChangedRoadNetworkObject; + + public RoadNetworkModel RoadNetwork + { + get => system.roadNetworkModel; + } + + public RoadNetworkEditMode CurrentEditMode + { + get => system.editingMode; + set + { + if (system.editingMode == value) + return; + system.editingMode = value; + OnChangedEditMode?.Invoke(this, EventArgs.Empty); + } + } + public event EventHandler OnChangedEditMode; + public event EventHandler OnChangedSelectRoadNetworkElement; + public event EventHandler OnChangedSignalControllerPattern; + public event EventHandler OnChangedSignalControllerPhase; + + public IRoadNetworkEditOperation EditOperation => system.editOperation; + + public object SelectedRoadNetworkElement + { + get => system.selectedRoadNetworkElement; + set + { + if (system.selectedRoadNetworkElement == value) + return; + system.selectedRoadNetworkElement = value; + OnChangedSelectRoadNetworkElement?.Invoke(this, EventArgs.Empty); + } + } + + public ISystemInstance EditorInstance => system.systemInstance; + + public TrafficSignalControllerPattern SelectedSignalControllerPattern + { + get => system.selectedSignalPattern; + set + { + if (system.selectedSignalPattern == value) + return; + system.selectedSignalPattern = value; + OnChangedSignalControllerPattern?.Invoke(this, EventArgs.Empty); + + system.selectedSignalPhase = null; + } + } + + public TrafficSignalControllerPhase SelectedSignalPhase + { + get => system.selectedSignalPhase; + set + { + if (system.selectedSignalPhase == value) + return; + system.selectedSignalPhase = value; + OnChangedSignalControllerPhase?.Invoke(this, EventArgs.Empty); + } + } + + public void NotifyChangedRoadNetworkObject2Editor() + { + if (system.roadNetworkObject == null) + return; + EditorUtility.SetDirty(system.roadNetworkObject); + + } + } + + /// + /// RoadNetwork編集機能のデータ操作部分の機能を提供するクラス + /// EditingSystemのサブクラスに移動するかも + /// + public class RoadNetworkEditorOperation : IRoadNetworkEditOperation + { + public RoadNetworkEditingResult AddPoint(RoadNetworkWay way, int idx, RoadNetworkPoint point) + { + way.LineString.Points.Insert(idx, point); + + return new RoadNetworkEditingResult(RoadNetworkEditingResultType.Success); + } + + public RoadNetworkEditingResult RemovePoint(RoadNetworkWay way, RoadNetworkPoint point) + { + var isSuc = way.LineString.Points.Remove(point); + if (isSuc) + { + return new RoadNetworkEditingResult(RoadNetworkEditingResultType.Success); + } + else + { + return new RoadNetworkEditingResult(RoadNetworkEditingResultType.InvalidArgs, "Can't found point."); + } + } + + public RoadNetworkEditingResult MovePoint(RoadNetworkPoint point, in Vector3 newPos) + { + if (point.Vertex == newPos) + return new RoadNetworkEditingResult(RoadNetworkEditingResultType.Success); + + point.Vertex = newPos; + return new RoadNetworkEditingResult(RoadNetworkEditingResultType.Success); + } + + public RoadNetworkEditingResult ScaleRoadWidth(RoadNetworkLane lane, float factor) + { + throw new NotImplementedException(); + } + + public RoadNetworkEditingResult ScaleRoadWidth(RoadNetworkLink link, float factor) + { + throw new NotImplementedException(); + } + + public RoadNetworkEditingResult AddMainLane(RoadNetworkLink link, int idx, RoadNetworkLane newLane) + { + throw new NotImplementedException(); + //link.MainLanes.Insert(idx, newLane); + //return new RoadNetworkEditingResult(RoadNetworkEditingResultType.Success); + } + public RoadNetworkEditingResult RemoveLane(RoadNetworkLink link, RoadNetworkLane lane) + { + throw new NotImplementedException(); + + //// MainLane以外も削除出来るようにする + + //bool isSuc = link.MainLanes.Remove(lane); + //if (isSuc) + //{ + // return new RoadNetworkEditingResult(RoadNetworkEditingResultType.Success); + //} + //else + //{ + // return new RoadNetworkEditingResult(RoadNetworkEditingResultType.InvalidArgs, "Can't found lane."); + //} + } + + public RoadNetworkEditingResult RegisterRegulation(RoadNetworkLink link, RoadNetworkRegulationElemet newRegulation) + { + throw new NotImplementedException(); + } + + public RoadNetworkEditingResult RegisterRegulation(RoadNetworkLane lane, RoadNetworkRegulationElemet newRegulation) + { + throw new NotImplementedException(); + } + + public RoadNetworkEditingResult RegisterRegulation(RoadNetworkBlock block, RoadNetworkRegulationElemet newRegulation) + { + throw new NotImplementedException(); + } + + public RoadNetworkEditingResult RegisterRegulation(RoadNetworkTrack track, RoadNetworkRegulationElemet newRegulation) + { + throw new NotImplementedException(); + } + + } + + /// + /// 編集機能のインスタンスを管理する機能を行っているクラス + /// + public class EditorInstance : ISystemInstance + { + public EditorInstance(RoadNetworkEditingSystem system, ISystemInstance editorInstance) + { + this.system = system; + this.editorInstance = editorInstance; + } + + private RoadNetworkEditingSystem system; + private ISystemInstance editorInstance; + + public void RequestReinitialize() + { + //system.rootVisualElement.RemoveFromHierarchy(); + //editorInstance.RequestReinitialize(); + //return; + var children = system.rootVisualElement.Children().ToArray(); + foreach (var item in children) + { + item.RemoveFromHierarchy(); + } + editorInstance.RequestReinitialize(); + + } + } + } + + +} diff --git a/Editor/RoadNetwork/RoadNetworkEditingSystem.cs.meta b/Editor/RoadNetwork/RoadNetworkEditingSystem.cs.meta new file mode 100644 index 000000000..4da893255 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkEditingSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b96cd657c9e52245987a53ebdbf0d4b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/RoadNetwork/RoadNetworkEditorWindow.cs b/Editor/RoadNetwork/RoadNetworkEditorWindow.cs new file mode 100644 index 000000000..ff759f95b --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkEditorWindow.cs @@ -0,0 +1,87 @@ +namespace PLATEAU.Editor.RoadNetwork +{ + /// + /// 道路ネットワーク手動編集機能を提供するエディタウィンドウ + /// 実際の処理を行うRoadNetworkEditorクラスのインスタンス化、インスタンスの管理に専念する + /// + public class RoadNetworkEditorWindow : UnityEditor.EditorWindow + { + public IRoadNetworkEditingSystemInterface EditorInterface { get; private set; } + + private static readonly string WindowName = "PLATEAU RoadNetwork Editor"; + + /// + /// ウィンドウのインスタンスを確認する + /// ラップ関数 + /// + /// + public static bool HasOpenInstances() + { + return HasOpenInstances(); + } + + /// + /// エディタを取得する + /// + /// + public static IRoadNetworkEditingSystemInterface GetEditorInterface() + { + return GetWindow(false).EditorInterface; + } + + // 2024年7月のリリース準備のため、開発中の機能を一時的にメニューから非表示にしています。 + // リリースが終わったら下のコメント行を復活させてください。 + // [MenuItem("PLATEAU_Dev/PLATEAU RoadNetwork Editor")] + public static void ShowWindow() + { + GetWindow(true); + } + + public void Reinitialize() + { + EditorInterface = null; + // 初期化 + Initialize(); + } + + private void Initialize() + { + // 初期化 + if (EditorInterface == null) + { + EditorInterface = new RoadNetworkEditingSystem(new EditorInstance(this), rootVisualElement); + } + } + + private void OnEnable() + { + Initialize(); + } + + /// + /// ウィンドウを取得する、存在しない場合に生成する + /// ラップ関数 + /// + /// + /// + private static RoadNetworkEditorWindow GetWindow(bool focus) + { + return GetWindow(WindowName, focus); + } + + private class EditorInstance : RoadNetworkEditingSystem.ISystemInstance + { + public EditorInstance(RoadNetworkEditorWindow window) + { + this.window = window; + } + RoadNetworkEditorWindow window; + + public void RequestReinitialize() + { + window.Reinitialize(); + } + } + + } +} diff --git a/Editor/RoadNetwork/RoadNetworkEditorWindow.cs.meta b/Editor/RoadNetwork/RoadNetworkEditorWindow.cs.meta new file mode 100644 index 000000000..85cace796 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkEditorWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5fe7aa797ec0dab4f83ec6d534f92004 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/RoadNetwork/RoadNetworkLaneDrawer.cs b/Editor/RoadNetwork/RoadNetworkLaneDrawer.cs new file mode 100644 index 000000000..f9dc2be70 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkLaneDrawer.cs @@ -0,0 +1,21 @@ +using PLATEAU.RoadNetwork; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace PLATEAU.Editor.RoadNetwork +{ + [CustomPropertyDrawer(typeof(RoadNetworkLane))] + public class RoadNetworkLaneDrawer : PropertyDrawer + { + public override VisualElement CreatePropertyGUI(SerializedProperty property) + { + return base.CreatePropertyGUI(property); + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + base.OnGUI(position, property, label); + } + } +} \ No newline at end of file diff --git a/Editor/RoadNetwork/RoadNetworkLaneDrawer.cs.meta b/Editor/RoadNetwork/RoadNetworkLaneDrawer.cs.meta new file mode 100644 index 000000000..e3099c245 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkLaneDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5ccd052f2dadf4241acfc7fb612c5ff1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/RoadNetwork/RoadNetworkLineStringDrawer.cs b/Editor/RoadNetwork/RoadNetworkLineStringDrawer.cs new file mode 100644 index 000000000..26befafb8 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkLineStringDrawer.cs @@ -0,0 +1,16 @@ +using PLATEAU.RoadNetwork; +using UnityEditor; +using UnityEngine.UIElements; + +namespace PLATEAU.Editor.RoadNetwork +{ + [CustomPropertyDrawer(typeof(RoadNetworkLineString))] + public class RoadNetworkLineStringDrawer : PropertyDrawer + { + public override VisualElement CreatePropertyGUI(SerializedProperty property) + { + + return base.CreatePropertyGUI(property); + } + } +} \ No newline at end of file diff --git a/Editor/RoadNetwork/RoadNetworkLineStringDrawer.cs.meta b/Editor/RoadNetwork/RoadNetworkLineStringDrawer.cs.meta new file mode 100644 index 000000000..773d777a7 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkLineStringDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8f6ff438eeab244e8048bb45668bf31 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/RoadNetwork/RoadNetworkLinkDrawer.cs b/Editor/RoadNetwork/RoadNetworkLinkDrawer.cs new file mode 100644 index 000000000..ac8c54208 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkLinkDrawer.cs @@ -0,0 +1,16 @@ +using PLATEAU.RoadNetwork; +using UnityEditor; +using UnityEngine.UIElements; + +namespace PLATEAU.Editor.RoadNetwork +{ + [CustomPropertyDrawer(typeof(RoadNetworkLink))] + public class RoadNetworkLinkDrawer : PropertyDrawer + { + public override VisualElement CreatePropertyGUI(SerializedProperty property) + { + + return base.CreatePropertyGUI(property); + } + } +} \ No newline at end of file diff --git a/Editor/RoadNetwork/RoadNetworkLinkDrawer.cs.meta b/Editor/RoadNetwork/RoadNetworkLinkDrawer.cs.meta new file mode 100644 index 000000000..48460d1f6 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkLinkDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b789e8bef4b3abc4fa5a90fe39c92494 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/RoadNetwork/RoadNetworkModelDrawer.cs b/Editor/RoadNetwork/RoadNetworkModelDrawer.cs new file mode 100644 index 000000000..d5cd4478c --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkModelDrawer.cs @@ -0,0 +1,27 @@ +namespace PLATEAU.Editor.RoadNetwork +{ +#if false + [CustomPropertyDrawer(typeof(RoadNetworkModel))] + public class RoadNetworkModelDrawer : PropertyDrawer + { + + public override VisualElement CreatePropertyGUI(SerializedProperty property) + { + return base.CreatePropertyGUI(property); + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + base.OnGUI(position, property, label); + + //EditorGUI.BeginProperty(position, label, property); + + var linkProperty = property?.FindPropertyRelative(nameof(RoadNetworkModel.Links)); + //var arraySize = linkProperty?.arraySize ?? 0; + //EditorGUI.IntField(position, "LinkSize", arraySize); + + //EditorGUI.EndProperty(); + } + } +#endif +} \ No newline at end of file diff --git a/Editor/RoadNetwork/RoadNetworkModelDrawer.cs.meta b/Editor/RoadNetwork/RoadNetworkModelDrawer.cs.meta new file mode 100644 index 000000000..1392acccc --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkModelDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a4101bafe4eaca4b887513752402fea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/RoadNetwork/RoadNetworkNodeDrawer.cs b/Editor/RoadNetwork/RoadNetworkNodeDrawer.cs new file mode 100644 index 000000000..7f59ad5c6 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkNodeDrawer.cs @@ -0,0 +1,15 @@ +using UnityEditor; +using UnityEngine.UIElements; + +namespace PLATEAU.Editor.RoadNetwork +{ + [CustomPropertyDrawer(typeof(RoadNetworkNodeDrawer))] + public class RoadNetworkNodeDrawer : PropertyDrawer + { + public override VisualElement CreatePropertyGUI(SerializedProperty property) + { + + return base.CreatePropertyGUI(property); + } + } +} \ No newline at end of file diff --git a/Editor/RoadNetwork/RoadNetworkNodeDrawer.cs.meta b/Editor/RoadNetwork/RoadNetworkNodeDrawer.cs.meta new file mode 100644 index 000000000..52511a771 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkNodeDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6b155cc2e14a19e41ae1c85f0ea5c63e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/RoadNetwork/RoadNetworkSceneGUISystem.cs b/Editor/RoadNetwork/RoadNetworkSceneGUISystem.cs new file mode 100644 index 000000000..52dd2664f --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkSceneGUISystem.cs @@ -0,0 +1,604 @@ +using System; +using PLATEAU.RoadNetwork; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEngine.Assertions; +using System.Linq; +using static PLATEAU.Editor.RoadNetwork.RoadNetworkEditingSystem; + +namespace PLATEAU.Editor.RoadNetwork +{ + /// + /// SceneGUIまわりの機能を管理するクラス + /// 記述先のファイルを変更するかも? + /// + public class RoadNetworkSceneGUISystem + { + public RoadNetworkSceneGUISystem(IRoadNetworkEditingSystem editorSystem) + { + Assert.IsNotNull(editorSystem); + this.editorSystem = editorSystem; + } + + private const float pointHndScaleFactor = 0.1f; + private const float laneHndScaleFactor = 0.4f; + private const float linkHndScaleFactor = 0.5f; + private const float signalLightHndScaleFactor = 0.2f; + private const float signalControllerScaleFactor = 0.3f; + private readonly Vector3 selectBtnPosOffset = Vector3.up * 10.0f; + + private IRoadNetworkEditingSystem editorSystem; + + /// + /// OnSceneGUI()内での状態 + /// + private struct SceneGUIState + { + public bool isDirtyTarget; // ターゲットに変更があったか + public Action delayCommand; // 遅延コマンド 要素の追加や削除を行う際に利用する foreach外で利用する + + // cache + public Vector3 linkPos; + public Vector3 lanePos; + + public Vector3 nodePos; + public Vector3 signalControllerPos; + public Vector3 signalLightPos; + + // loop operation + public bool isContinue; + public bool isBreak; + internal Camera currentCamera; + + public void ResetLoopOperationFlags() + { + isContinue = false; + isBreak = false; + } + }; + + /// + /// クラス内の状態 + /// + private struct SceneGUISystemState + { + public void Init(out SceneGUIState state) + { + state = new SceneGUIState + { + isDirtyTarget = false, + delayCommand = null, + }; + } + public void Apply(in SceneGUIState state) + { + + } + }; + private SceneGUISystemState systemState; + + public void OnSceneGUI(UnityEngine.Object target) + { + SetRoadNetworkObject2System(target); + var network = GetRoadNetwork(); + if (network == null) + return; + + // ステイトの初期化 + SceneGUIState state; + systemState.Init(out state); + + var currentCamera = SceneView.currentDrawingSceneView.camera; + state.currentCamera = currentCamera; + + // ハンドルの配置、要素数を変化させない値変更、遅延実行用のコマンド生成を行う + // 遅延実行用のコマンドは1フレームにつき一つまで実行できるとする(要素削除順の管理などが面倒なため) + Update3DHandle(network, ref state); + + // 編集モードの状態表示 + // 2D GUI + var sceneViewPixelRect = currentCamera.pixelRect; + var guiLayoutRect = new Rect(sceneViewPixelRect.position + sceneViewPixelRect.center, sceneViewPixelRect.size / 2.0f); + Handles.BeginGUI(); + GUILayout.BeginArea(guiLayoutRect); + GUILayout.Box("道路ネットワーク編集モード"); + GUILayout.EndArea(); + Handles.EndGUI(); + + // 遅延実行 コレクションの要素数などを変化させる + if (state.delayCommand != null) + state.delayCommand.Invoke(); + + // 変更を通知する + if (state.isDirtyTarget) + { + editorSystem.NotifyChangedRoadNetworkObject2Editor(); + } + + systemState.Apply(state); + } + + + private SceneGUIState Update3DHandle(RoadNetworkModel network, ref SceneGUIState state) + { + + // Node + foreach (var node in network.Nodes) + { + state.ResetLoopOperationFlags(); + ForeachNode(editorSystem, network.Nodes, node, ref state); + if (state.isBreak) break; + if (state.isContinue) continue; + + // SignalController + foreach (var signalController in new TrafficSignalLightController[1] { node.SignalController }) + { + state.ResetLoopOperationFlags(); + ForeachSignalController(editorSystem, signalController, ref state); + if (state.isBreak) break; + if (state.isContinue) continue; + + // signalLight + foreach (var signalLight in signalController.SignalLights) + { + state.ResetLoopOperationFlags(); + ForeachSignalLight(editorSystem, signalController.SignalLights, signalLight, ref state); + + if (state.isBreak) break; + if (state.isContinue) continue; + + } + } + } + + // link + foreach (var link in network.Links) + { + state.ResetLoopOperationFlags(); + ForeachLink(editorSystem, network.Links, link, ref state); + if (state.isBreak) break; + if (state.isContinue) continue; + + state.linkPos = CalcLinkPos(link); + + // lane + foreach (var lane in link.MainLanes) + { + state.ResetLoopOperationFlags(); + ForeachLane(editorSystem, link.MainLanes, lane, ref state); + //ForeachLanes(editorSystem, link.MainLanes, lane, ref state); + if (state.isBreak) break; + if (state.isContinue) continue; + + // way + foreach (var way in lane.BothWays) + { + state.ResetLoopOperationFlags(); + if (state.isBreak) break; + if (state.isContinue) continue; + + // point + foreach (var point in way.Points) + { + state.ResetLoopOperationFlags(); + ForeachPoints(editorSystem, point, ref state); + if (state.isBreak) break; + if (state.isContinue) continue; + } + } + } + } + + return state; + } + + private bool SetRoadNetworkObject2System(UnityEngine.Object target) + { + editorSystem.RoadNetworkObject = target; + return editorSystem.RoadNetworkObject != null; + } + + private RoadNetworkModel GetRoadNetwork() + { + return editorSystem.RoadNetwork; + } + + private void ForeachLane(IRoadNetworkEditingSystem editorSystem, IReadOnlyList mainLanes, RoadNetworkLane lane, ref SceneGUIState state) + { + state.lanePos = CalcLanePos(lane); + + bool isDisplay = false; + if (lane != editorSystem.SelectedRoadNetworkElement as RoadNetworkLane) + { + isDisplay = true; + } + + if (isDisplay) + { + state.isContinue = true; + } + + if (isDisplay) + { + // レーンの選択ボタンの表示 + var lanePos = state.lanePos + selectBtnPosOffset; + var laneSelectBtnSize = HandleUtility.GetHandleSize(lanePos) * laneHndScaleFactor; + var isClicked = Handles.Button(lanePos, Quaternion.identity, laneSelectBtnSize, laneSelectBtnSize, RoadNetworkLaneHandleCap); + if (isClicked) + { + editorSystem.SelectedRoadNetworkElement = lane; + } + + // レーンの構造変更機能が有効である + if (editorSystem.CurrentEditMode == RoadNetworkEditMode.EditLaneStructure) + { + var offset = Vector3.up * signalLightHndScaleFactor; + var scaleHandlePos = state.lanePos + offset; + + var sizeOffset = laneHndScaleFactor; + var size = HandleUtility.GetHandleSize(scaleHandlePos) * sizeOffset; + var isClickedSplit = Handles.Button(scaleHandlePos, Quaternion.identity, size, size, RoadNetworkSplitLaneButtonHandleCap); + if (isClickedSplit) + { + // 車線数を増やす + state.delayCommand += () => + { + //var newLanes = lane.SplitLane(2); // Laneが3つになる + //if (newLanes == null) + // return; + //lanes.AddRange(newLanes); + Debug.Log("車線数を増やすボタンが押された"); + + }; + state.isDirtyTarget = true; + } + + // 仮 車線数を減らす ParentLinkがnullであるためレーンを選択できないので適当なレーンを削除する + var isClickedRemove = Handles.Button(scaleHandlePos + Vector3.right * size * 1.5f, Quaternion.identity, size, size, RoadNetworkRemoveLaneButtonHandleCap); + if (isClickedRemove) + { + state.delayCommand += () => + { + //lanes.Remove(lane); // Link,他のLaneなどとの繋がりを切る処理が必要 + Debug.Log("車線数を減らすボタンが押された"); + }; + state.isDirtyTarget = true; + } + } + + if (editorSystem.CurrentEditMode == RoadNetworkEditMode.EditLaneShape) + { + // 1つのレーンの幅員を増やす + //if (lane.LeftWay.Count > 0) + //{ + // var leftCenterIdx = lane.LeftWay.Count / 2; + // var scaleHandlePos = lane.LeftWay[leftCenterIdx]; + // var dir = Vector3.up; + // if (lane.LeftWay.Count >= 2) + // { + // dir = lane.LeftWay.GetVertexNormal(leftCenterIdx - 1); + // dir.Normalize(); + // } + + // var size = HandleUtility.GetHandleSize(scaleHandlePos); + // EditorGUI.BeginChangeCheck(); + // var scale = Deploy1DScaleHandle(1.0f, scaleHandlePos, dir, Quaternion.identity, size); + // if (EditorGUI.EndChangeCheck()) + // { + // foreach (var way in lane.BothWays) + // { + // int i = 0; + // foreach (var point in way.Points) + // { + // var vertNorm = way.GetVertexNormal(i++); + // point.Vertex = point + (scale - 1) * 0.1f * vertNorm; + // state.isDirtyTarget = true; + // } + // } + // } + //} + } + + } + } + + private void ForeachLink(IRoadNetworkEditingSystem editorSystem, IReadOnlyList links, RoadNetworkLink link, ref SceneGUIState state) + { + state.linkPos = CalcLinkPos(link); + + bool isDisplay = false; + // 自身が選択されていない + if (link != editorSystem.SelectedRoadNetworkElement as RoadNetworkLink) + { + //子の要素が選択されていない + var lane = editorSystem.SelectedRoadNetworkElement as RoadNetworkLane; + if (lane?.ParentLink != link) + { + isDisplay = true; + } + } + + if (isDisplay) + { + state.isContinue = true; + } + + if (isDisplay) + { + // 処理負荷軽減のため適当なレーンを選択して中心位置を計算 + var linkSelectbtnPos = state.linkPos + selectBtnPosOffset; + var linkSelectBtnHandleDefaultSize = linkHndScaleFactor; + var size = HandleUtility.GetHandleSize(linkSelectbtnPos) * linkSelectBtnHandleDefaultSize; + var pickSize = size; + var isClicked = Handles.Button( + linkSelectbtnPos, Quaternion.identity, size, pickSize, RoadNetworkLinkHandleCap); + if (isClicked) + { + editorSystem.SelectedRoadNetworkElement = link; + } + + } + } + + private void ForeachPoints(IRoadNetworkEditingSystem sys, RoadNetworkPoint point, ref SceneGUIState state) + { + if (sys.CurrentEditMode != RoadNetworkEditMode.EditLaneShape) + return; + + var networkOperator = sys.EditOperation; + var size = HandleUtility.GetHandleSize(point) * pointHndScaleFactor; + EditorGUI.BeginChangeCheck(); + //var vertPos = DeployTranslateHandle(point); + var vertPos = DeployFreeMoveHandle(point, size, snap: Vector3.zero); + + if (EditorGUI.EndChangeCheck()) + { + var res = networkOperator.MovePoint(point, vertPos); + state.isDirtyTarget = true; + Debug.Assert(res.IsSuccess); + } + + } + + private void ForeachSignalLight(IRoadNetworkEditingSystem editorSystem, List signalLights, TrafficSignalLight signalLight, ref SceneGUIState state) + { + state.signalLightPos = signalLight.position; + if (editorSystem.CurrentEditMode == RoadNetworkEditMode.EditTrafficRegulation) + { + var size = HandleUtility.GetHandleSize(signalLight.position) * signalLightHndScaleFactor; + bool isClicked = Handles.Button(signalLight.position, Quaternion.identity, size, size, RoadNetworkTrafficSignalLightCap); + if (isClicked) + { + //editorSystem.SelectedRoadNetworkElement = signalLight; + Debug.Log("SignalLight"); + } + } + } + + private void ForeachSignalController(IRoadNetworkEditingSystem editorSystem, TrafficSignalLightController signalController, ref SceneGUIState state) + { + // 存在しないなら飛ばす + if (signalController == null) + { + state.isContinue = true; + return; + } + + state.signalControllerPos = signalController.Position; + + bool isDisplay = false; + if (signalController != editorSystem.SelectedRoadNetworkElement) + { + isDisplay = true; + } + // 表示されているなら子の要素を表示しない + if (isDisplay) + { + state.isContinue = true; + } + + // ハンドルを表示する + if (isDisplay) + { + if (editorSystem.CurrentEditMode == RoadNetworkEditMode.EditTrafficRegulation) + { + var size = HandleUtility.GetHandleSize(signalController.Position) * signalControllerScaleFactor; + bool isClicked = Handles.Button(signalController.Position, Quaternion.identity, size, size, RoadNetworkTrafficSignalLightCap); + if (isClicked) + { + editorSystem.SelectedRoadNetworkElement = signalController; + Debug.Log(signalController.SelfId); + } + } + } + } + + private void ForeachNode(IRoadNetworkEditingSystem editorSystem, IReadOnlyList nodes, RoadNetworkNode node, ref SceneGUIState state) + { + state.nodePos = node.GetCenterPoint(); + + bool isDisplayNode = false; + // 自身が選択されていない + if (editorSystem.SelectedRoadNetworkElement != node) + { + // 子の要素が選択されていない + var trafficLightController = editorSystem.SelectedRoadNetworkElement as TrafficSignalLightController; + if (trafficLightController?.CorrespondingNode != node) + { + isDisplayNode = true; + } + } + + // 要素を表示するなら子の要素を表示しない + if (isDisplayNode) + { + state.isContinue = true; + } + + if (isDisplayNode) + { + var selectbtnPos = state.nodePos + selectBtnPosOffset; + var selectBtnHandleDefaultSize = linkHndScaleFactor; + var size = HandleUtility.GetHandleSize(selectbtnPos) * selectBtnHandleDefaultSize; + var pickSize = size; + var isClicked = Handles.Button( + selectbtnPos, state.currentCamera.transform.rotation, size, pickSize, RoadNetworkNodeHandleCap); + if (isClicked) + { + editorSystem.SelectedRoadNetworkElement = node; + Debug.Log("sele" + editorSystem.SelectedRoadNetworkElement.ToString()); + } + + } + + + } + + private static Vector3 CalcLinkPos(RoadNetworkLink link) + { + var midIdx = link.AllLanes.Count() / 2; + // midIdxのLaneを取得する + var lanesEnum = link.AllLanes.GetEnumerator(); + var cnt = 0; + while (lanesEnum.MoveNext()) + { + if (cnt++ == midIdx) + break; + } + var centerLane = lanesEnum.Current; + + var avePos = CalcLanePos(centerLane); + return avePos; + } + + private static Vector3 CalcLanePos(RoadNetworkLane centerLane) + { + var numVert = centerLane.Vertices.Count(); + var sumVert = Vector3.zero; + foreach (var vert in centerLane.Vertices) + { + sumVert += vert; + } + var avePos = sumVert / (float)numVert; + return avePos; + } + + + + private static void RoadNetworkTrafficSignalLightCap(int controlID, Vector3 position, Quaternion rotation, float size, EventType eventType) + { + switch (eventType) + { + case EventType.MouseMove: + case EventType.Layout: + Handles.CubeHandleCap(controlID, position, rotation, size, eventType); + break; + case EventType.Repaint: + Handles.CubeHandleCap(controlID, position, rotation, size, eventType); + break; + } + } + private static void RoadNetworkNodeHandleCap(int controlID, Vector3 position, Quaternion rotation, float size, EventType eventType) + { + switch (eventType) + { + case EventType.MouseMove: + case EventType.Layout: + Handles.SphereHandleCap(controlID, position, rotation, size, eventType); + break; + case EventType.Repaint: + Handles.SphereHandleCap(controlID, position, rotation, size, eventType); + break; + } + + } + + static void RoadNetworkLinkHandleCap(int controlID, Vector3 position, Quaternion rotation, float size, EventType eventType) + { + switch (eventType) + { + case EventType.MouseMove: + case EventType.Layout: + Handles.CubeHandleCap(controlID, position, rotation, size, eventType); + + break; + case EventType.Repaint: + //Handles.CubeHandleCap(controlID, position, rotation, size, eventType); + Handles.DrawWireCube(position, new Vector3(size, size, size)); + var subCubeSize = size * signalControllerScaleFactor; + Handles.DrawWireCube(position + Vector3.right * subCubeSize, new Vector3(subCubeSize, subCubeSize, subCubeSize)); + Handles.DrawWireCube(position + Vector3.left * subCubeSize, new Vector3(subCubeSize, subCubeSize, subCubeSize)); + Handles.DrawLine(position + Vector3.right * size * linkHndScaleFactor, position + Vector3.left * size * linkHndScaleFactor); + break; + } + + } + + static void RoadNetworkLaneHandleCap(int controlID, Vector3 position, Quaternion rotation, float size, EventType eventType) + { + switch (eventType) + { + case EventType.MouseMove: + case EventType.Layout: + Handles.CubeHandleCap(controlID, position, rotation, size, eventType); + + break; + case EventType.Repaint: + Handles.DrawWireCube(position, new Vector3(size, size, size)); + Handles.DrawWireCube(position, new Vector3(size, size * pointHndScaleFactor, size * signalControllerScaleFactor)); + break; + } + + } + + static void RoadNetworkSplitLaneButtonHandleCap(int controlID, Vector3 position, Quaternion rotation, float size, EventType eventType) + { + switch (eventType) + { + case EventType.MouseMove: + case EventType.Layout: + Handles.CubeHandleCap(controlID, position, rotation, size, eventType); + + break; + case EventType.Repaint: + Handles.DrawWireDisc(position, Vector3.up, size * linkHndScaleFactor); + Handles.DrawWireCube(position + Vector3.forward * 0.07f, new Vector3(size, size * pointHndScaleFactor, size * 0.15f)); + Handles.DrawWireCube(position + Vector3.back * 0.07f, new Vector3(size, size * pointHndScaleFactor, size * 0.15f)); + break; + } + } + + static void RoadNetworkRemoveLaneButtonHandleCap(int controlID, Vector3 position, Quaternion rotation, float size, EventType eventType) + { + switch (eventType) + { + case EventType.MouseMove: + case EventType.Layout: + Handles.CubeHandleCap(controlID, position, rotation, size, eventType); + + break; + case EventType.Repaint: + Handles.DrawWireDisc(position, Vector3.up, size * linkHndScaleFactor); + Handles.DrawWireCube(position + Vector3.forward * 0.07f, new Vector3(size, size * pointHndScaleFactor, size * 0.15f)); + break; + } + } + + private static Vector3 DeployFreeMoveHandle(in Vector3 pos, float size, in Vector3 snap) + { + return Handles.FreeMoveHandle(pos, size, snap, Handles.SphereHandleCap); + } + + //Vector3 static DeployTranslateHandle(in Vector3 pos) + //{ + // return Handles.PositionHandle(pos, Quaternion.identity); + //} + + //float static Deploy1DScaleHandle(float scale, in Vector3 pos, in Vector3 dir, in Quaternion rot, float size, float snap = 0.01f) + //{ + // return Handles.ScaleSlider(scale, pos, dir, rot, size, snap); + //} + + } +} diff --git a/Editor/RoadNetwork/RoadNetworkSceneGUISystem.cs.meta b/Editor/RoadNetwork/RoadNetworkSceneGUISystem.cs.meta new file mode 100644 index 000000000..879513ec4 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkSceneGUISystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9a3a62cebd605546813206e5b77b3a1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/RoadNetwork/RoadNetworkTrackDrawer.cs b/Editor/RoadNetwork/RoadNetworkTrackDrawer.cs new file mode 100644 index 000000000..5ed201b57 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkTrackDrawer.cs @@ -0,0 +1,16 @@ +using PLATEAU.RoadNetwork; +using UnityEditor; +using UnityEngine.UIElements; + +namespace PLATEAU.Editor.RoadNetwork +{ + [CustomPropertyDrawer(typeof(RoadNetworkTrack))] + public class RoadNetworkTrackDrawer : PropertyDrawer + { + public override VisualElement CreatePropertyGUI(SerializedProperty property) + { + + return base.CreatePropertyGUI(property); + } + } +} \ No newline at end of file diff --git a/Editor/RoadNetwork/RoadNetworkTrackDrawer.cs.meta b/Editor/RoadNetwork/RoadNetworkTrackDrawer.cs.meta new file mode 100644 index 000000000..9ab471462 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkTrackDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa247e1c82331914aab1b80be1e0c983 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/RoadNetwork/RoadNetworkUIDoc.cs b/Editor/RoadNetwork/RoadNetworkUIDoc.cs new file mode 100644 index 000000000..f48328e58 --- /dev/null +++ b/Editor/RoadNetwork/RoadNetworkUIDoc.cs @@ -0,0 +1,371 @@ +using NUnit.Framework; +using PLATEAU.RoadNetwork; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + +using static PLATEAU.Editor.RoadNetwork.RoadNetworkEditingSystem; +using GenerateParameterFunc = + System.Action; + + +namespace PLATEAU.Editor.RoadNetwork +{ + public enum RoadNetworkEditingResultType + { + _Undefind = 0xfffffff, + Success = 0x0000000, + InvalidNewValue = 1 << 0, // 適切な変更値ではない + InvalidTarget = 1 << 1, // 適切な変更対象ではない(主に第1引数のLink,Laneなどについて) + CantApplyEditing = 1 << 2, // 適用できない編集。リンクの幅員を小さくしすぎて一部のレーンの幅員が0になるなど + InvalidArgs = 1 << 3, // 適切な引数ではない。(主に第2引数以降 Wayのポイントを削除する際に渡したポイントが存在しないなど) + _UndefindError = 1 << 256, + //Faild // 失敗原因を明確にするために未使用 + } + + public struct RoadNetworkEditingResult + { + public readonly RoadNetworkEditingResultType Result; + public readonly string Msg; + + public bool IsSuccess { get => Result == RoadNetworkEditingResultType.Success; } + public RoadNetworkEditingResult(RoadNetworkEditingResultType result, string msg = "") + { + this.Result = result; + this.Msg = msg; + } + } + + /// + /// 道路ネットワークの交通規制を登録するための構造体ラッパ + /// 削除予定 インターフェイスで引数で利用しているがそれぞれのクラスの引数を用意する + /// + public struct RoadNetworkRegulationElemet + { + // 信号制御器 + // 信号灯器 + // 一時停止線 + // 一時停止標識 + // 工事、事故、その他の規制 + } + + public interface IRoadNetworkEditOperation + { + /// + /// ポイントの追加、削除、移動 + /// + /// + /// + /// + /// + RoadNetworkEditingResult AddPoint(RoadNetworkWay way, int idx, RoadNetworkPoint point); + RoadNetworkEditingResult RemovePoint(RoadNetworkWay way, RoadNetworkPoint point); + RoadNetworkEditingResult MovePoint(RoadNetworkPoint point, in Vector3 newPos); + + /// + /// 幅員のスケーリング + /// + /// + /// + /// + RoadNetworkEditingResult ScaleRoadWidth(RoadNetworkLane lane, float factor); + RoadNetworkEditingResult ScaleRoadWidth(RoadNetworkLink link, float factor); + + /// + /// 射線を増やす、減らす + /// + /// + /// + /// + /// + RoadNetworkEditingResult AddMainLane(RoadNetworkLink link, int idx, RoadNetworkLane newLane); + RoadNetworkEditingResult RemoveLane(RoadNetworkLink link, RoadNetworkLane lane); + + /// + /// 交通規制情報の登録 + /// + /// + /// + /// + RoadNetworkEditingResult RegisterRegulation(RoadNetworkLink link, RoadNetworkRegulationElemet newRegulation); + RoadNetworkEditingResult RegisterRegulation(RoadNetworkLane lane, RoadNetworkRegulationElemet newRegulation); + RoadNetworkEditingResult RegisterRegulation(RoadNetworkBlock block, RoadNetworkRegulationElemet newRegulation); + RoadNetworkEditingResult RegisterRegulation(RoadNetworkTrack track, RoadNetworkRegulationElemet newRegulation); + } + + /// + /// 道路ネットワークの編集モード + /// + public enum RoadNetworkEditMode + { + EditLaneShape, + EditLaneStructure, + EditTrafficRegulation, + } + + /// + /// 道路ネットワークエディタのUIDocumentを扱うクラス + /// インスペクター、エディタ、ランタイムでも利用できるように汎用化する + /// (エディタ専用のUIを使用してるため現状はランタイム使用不可) + /// + /// 未完成のクラス 大きく改装予定 役割は変えない + /// + public class RoadNetworkUIDoc + { + // RoadNetworkUIDoc内に隠したい, 依存部分をこのクラスの下層に配置する? + //public RoadNetworkEditMode CurrentMode { get => (RoadNetworkEditMode)modeSelector.value; } + public RoadNetworkEditMode CurrentMode { + get => system.CurrentEditMode; + set => system.CurrentEditMode = value; + } + + private Button refreshButton; + private EnumField modeSelector; + private ScrollView parameterView; + private ObjectField objSelecter; + private TrafficSignalLightControllerUIDoc trafficSignalLightControllerUIDoc; + + private readonly IRoadNetworkEditingSystem system; + private readonly RoadNetworkEditorAssets assets; + + private readonly Dictionary ParamterLayoutSet = + new Dictionary { + { RoadNetworkEditMode.EditLaneShape, CreateEditLaneShapeLayout }, + { RoadNetworkEditMode.EditLaneStructure, CreateEditLaneStructureLayout }, + { RoadNetworkEditMode.EditTrafficRegulation, CreateTrafficRegulationLayout }, + }; + + private static void CreateDebugNodeLayout(IRoadNetworkEditingSystem system, RoadNetworkEditorAssets assets, VisualElement root) + { + var element = assets.GetAsset(RoadNetworkEditorAssets.Vec3Field).Instantiate(); + element.Q().label = "座標"; + root.Add(element); + } + + private static void CreateDebugLinkLayout(IRoadNetworkEditingSystem system, RoadNetworkEditorAssets assets, VisualElement root) + { + + Func createDataIDField = () => { + var dataID = assets.GetAsset(RoadNetworkEditorAssets.DataIDField).Instantiate().Q(); + dataID.label = ""; + dataID.value = -1; + return dataID; + }; + CreateParamterBox(assets, root, "本線レーン", createDataIDField); + CreateParamterBox(assets, root, "右折レーン", createDataIDField); + CreateParamterBox(assets, root, "左折レーン", createDataIDField); + + var floatFieldAsset = assets.GetAsset(RoadNetworkEditorAssets.FloatFieldAsset); + if (floatFieldAsset.Instantiate() is var linkCap) + { + var slider = linkCap.Q(); + { + slider.label = "リンク容量(pcu/時/車線)"; + slider.highValue = 100.0f; + slider.value = 0.0f; + } + root.Add(linkCap); + } + + if (floatFieldAsset.Instantiate() is var freeSpd) + { + var slider = freeSpd.Q(); + { + slider.label = "自由流速度(km/時)"; + slider.highValue = 300.0f; + slider.value = 60.0f; + } + root.Add(freeSpd); + } + if (floatFieldAsset.Instantiate() is var jamDens) + { + var slider = jamDens.Q(); + { + slider.label = "ジャム密度(pcu/km/車線)"; + slider.highValue = 100.0f; + slider.value = 0.0f; + } + root.Add(jamDens); + } + } + + private static void CreateDebugLaneLayout(IRoadNetworkEditingSystem system, RoadNetworkEditorAssets assets, VisualElement root) + { + Func createVec3Field = () => { + var vecField = assets.GetAsset(RoadNetworkEditorAssets.Vec3Field).Instantiate().Q(); + vecField.label = ""; + return vecField; + }; + CreateParamterBox(assets, root, "道形状の設定(左側Way)", createVec3Field); + CreateParamterBox(assets, root, "道形状の設定(右側Way)", createVec3Field); + + Func createDataIDField = () => { + var dataID = assets.GetAsset(RoadNetworkEditorAssets.DataIDField).Instantiate().Q(); + dataID.label = ""; + dataID.value = -1; + return dataID; + }; + CreateParamterBox(assets, root, "連結元レーン(上流側)", createDataIDField); + CreateParamterBox(assets, root, "連結先レーン(下流側)", createDataIDField); + } + + + private static void CreateParamterBox(RoadNetworkEditorAssets assets, VisualElement root, string labelText, Func createElemetFunc) + { + var parameterBoxAsset = assets.GetAsset(RoadNetworkEditorAssets.ParameterBoxAssetName); + + var parameterBox = parameterBoxAsset.Instantiate(); + + var label = parameterBox.Q