From c42a23d6face33a6a5a55cbe60ce4be10c35a9fd Mon Sep 17 00:00:00 2001 From: max Date: Wed, 28 Jun 2023 01:07:27 +0200 Subject: [PATCH] Simple grid generation and loading - Grid generation - Grid loading - GridIds - Still having issues with serialization of the grid data structure --- Editor/ScenePartitionEditorWindow.cs | 24 ++++++++++++++ Editor/ScenePartitionSO.cs | 47 +++++++++++++++++++++++++++- Editor/ScenePartitionSOEditor.cs | 33 +++++++++++++++++++ Editor/ScenePartitionSS.cs | 7 ++++- Runtime/SceneGrid.cs | 34 ++++++++++++++------ Runtime/SerializedStructures.cs | 3 +- 6 files changed, 135 insertions(+), 13 deletions(-) diff --git a/Editor/ScenePartitionEditorWindow.cs b/Editor/ScenePartitionEditorWindow.cs index bc25f74..366210f 100644 --- a/Editor/ScenePartitionEditorWindow.cs +++ b/Editor/ScenePartitionEditorWindow.cs @@ -17,6 +17,11 @@ public static void ShowExample() private void OnGUI() { + if (GUILayout.Button("Save")) + { + ScenePartitionSS.Save(); + } + DrawSceneDataCache(); } @@ -55,6 +60,25 @@ private void DrawSceneDataCache() EditorGUILayout.IntField((int)scenePartition.Value.id); } } + + if (sceneData.Value.SceneGrid != null) + { + EditorGUILayout.LabelField($"generatedSceneGrid"); + + foreach (KeyValuePair> item in sceneData.Value.SceneGrid.Grid) + { + EditorGUILayout.IntField("gridId", item.Key); + + EditorGUI.indentLevel++; + + foreach (uint id in item.Value) + { + EditorGUILayout.IntField((int)id); + } + + EditorGUI.indentLevel--; + } + } } } } diff --git a/Editor/ScenePartitionSO.cs b/Editor/ScenePartitionSO.cs index 249ee47..618a000 100644 --- a/Editor/ScenePartitionSO.cs +++ b/Editor/ScenePartitionSO.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Text.RegularExpressions; using UnityEditor; using UnityEditor.SceneManagement; @@ -58,7 +59,7 @@ public void LoadAll() } /// - /// Load already/previously loaded partitions. + /// Discard changes and reload loaded partitions. /// public void Reload() { @@ -204,5 +205,49 @@ public void LoadPartitions(uint[] ids) LoadScenePartitions(partitionIds); } + + public void GenerateSceneGridData() + { + if (!Data.HasCreatedPartitions) return; + + LoadAll(); + + Scene scene = EditorSceneManager.OpenScene(ScenePartitionUtils.GetScenePath(this), OpenSceneMode.Single); + + GameObject[] rootGameObjects = scene.GetRootGameObjects(); + + Data.SceneGrid.Grid.Clear(); + + // Maybe later switch to getting the data from disk instead of loading the scene and then unloading it again. + foreach (GameObject gameObject in rootGameObjects) + { + // https://forum.unity.com/threads/how-to-get-the-local-identifier-in-file-for-scene-objects.265686/ + PropertyInfo inspectorModeInfo = typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance); + SerializedObject serializedObject = new SerializedObject(gameObject.transform); + inspectorModeInfo.SetValue(serializedObject, InspectorMode.Debug, null); + SerializedProperty localIdProp = serializedObject.FindProperty("m_LocalIdentfierInFile"); + + uint localId = (uint)localIdProp.intValue; + + if (Data.ScenePartitions.ContainsKey(localId)) + { + Data.SceneGrid.Insert(localId, gameObject.transform.position); + } + else + { + Debug.LogWarning($"Could not find LocalIdentfierInFile for {gameObject.transform} {gameObject.name} {gameObject.transform.GetInstanceID()}"); + } + } + + Unload(); + } + + public void LoadCell(int gridId) + { + if (Data.SceneGrid.Grid.TryGetValue(gridId, out List ids)) + { + LoadPartitions(ids.ToArray()); + } + } } } \ No newline at end of file diff --git a/Editor/ScenePartitionSOEditor.cs b/Editor/ScenePartitionSOEditor.cs index 521647b..9ee3ae7 100644 --- a/Editor/ScenePartitionSOEditor.cs +++ b/Editor/ScenePartitionSOEditor.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using UnityEditor; using UnityEngine; @@ -7,6 +8,7 @@ namespace VertexColor.ScenePartition.Editor public class ScenePartitionSOEditor : UnityEditor.Editor { private int id = 0; + private int gridId = 0; public override void OnInspectorGUI() { @@ -64,6 +66,37 @@ public override void OnInspectorGUI() { scenePartitionSO.LoadPartitions(new uint[1] { (uint)id }); } + + if (GUILayout.Button("GenerateSceneGrid")) + { + scenePartitionSO.GenerateSceneGridData(); + } + + gridId = EditorGUILayout.IntField("gridId", gridId); + + if (GUILayout.Button("LoadSceneGrid")) + { + scenePartitionSO.LoadCell(gridId); + } + + if (scenePartitionSO.Data.SceneGrid != null) + { + EditorGUILayout.LabelField($"generatedSceneGrid"); + + foreach (KeyValuePair> item in scenePartitionSO.Data.SceneGrid.Grid) + { + EditorGUILayout.IntField("gridId", item.Key); + + EditorGUI.indentLevel++; + + foreach (uint id in item.Value) + { + EditorGUILayout.IntField((int)id); + } + + EditorGUI.indentLevel--; + } + } } } } diff --git a/Editor/ScenePartitionSS.cs b/Editor/ScenePartitionSS.cs index 989a63e..2d3169c 100644 --- a/Editor/ScenePartitionSS.cs +++ b/Editor/ScenePartitionSS.cs @@ -29,7 +29,12 @@ public ScenePartitionData GetScenePartitionData(ScenePartitionSO scenePartitionS private void OnDisable() { - Save(true); + Save(); + } + + public static void Save() + { + instance.Save(true); } } diff --git a/Runtime/SceneGrid.cs b/Runtime/SceneGrid.cs index 84c5a97..c0152e4 100644 --- a/Runtime/SceneGrid.cs +++ b/Runtime/SceneGrid.cs @@ -1,10 +1,9 @@ -using System; using System.Collections.Generic; using UnityEngine; namespace VertexColor.ScenePartition.Editor { - [Serializable] + [System.Serializable] public class SceneGrid { [SerializeField] @@ -13,25 +12,42 @@ public class SceneGrid [SerializeField] private SceneGridDictionary grid = new SceneGridDictionary(); - public void Insert(uint id, Vector2 point) + public SceneGridDictionary Grid => grid; + + public void Insert(uint id, Vector3 point) { - Vector2 gridPos = CalculateGridPosition(point); - if (grid.TryGetValue(gridPos, out List ids)) + int gridId = CalculateGridPosition(point); + if (grid.TryGetValue(gridId, out List ids)) { ids.Add(id); } else { - grid.Add(gridPos, new List { id }); + grid.Add(gridId, new List { id }); } } - public Vector2 CalculateGridPosition(Vector2 point) + public int CalculateGridPosition(Vector3 point) { int x = Mathf.FloorToInt(point.x / cellSize); - int y = Mathf.FloorToInt(point.y / cellSize); + int z = Mathf.FloorToInt(point.z / cellSize); - return new Vector2(x, y); + return IntPairToInt(x, z); + } + + public static int IntPairToInt(int x, int y) + { + // Combine x and y components into a single int + return (x << 16) | (ushort)y; + } + + public static (int, int) IntToIntPair(int value) + { + // Extract x and y components from the combined int + int x = value >> 16; + int y = (short)value; + + return (x, y); } } } diff --git a/Runtime/SerializedStructures.cs b/Runtime/SerializedStructures.cs index 42245bd..e14a0c9 100644 --- a/Runtime/SerializedStructures.cs +++ b/Runtime/SerializedStructures.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using UnityEngine; namespace VertexColor.ScenePartition { @@ -10,5 +9,5 @@ public class ScenePartitionSortedList : SerializableSortedList { } [System.Serializable] - public class SceneGridDictionary : SerializableDictionary> { } + public class SceneGridDictionary : SerializableDictionary> { } } \ No newline at end of file