Browse Source

Added OnChunkGenerated and OnTerrainGenerated Generic Events

James Peret 1 year ago
parent
commit
301106c437
2 changed files with 35 additions and 10 deletions
  1. 1 0
      ChangeLog.md
  2. 34 10
      Runtime/ChunkTerrainGenerator.cs

+ 1 - 0
ChangeLog.md

@@ -2,6 +2,7 @@
 
 ### v0.0.2
 
+- Added OnChunkGenerated and OnTerrainGenerated Generic Events
 - Added support for building Navigation Meshes after the terrain is generated
 - Added terrain generation on start or on Generic Event
 - Added ability to change the generated terrain mesh GameObject tag

+ 34 - 10
Runtime/ChunkTerrainGenerator.cs

@@ -24,7 +24,12 @@ namespace KairoEngine.TerrainEngine
         [BoxGroup("Configurations")] public int parallelMeshJobs = 4;
         [HorizontalGroup("Configurations/NavMesh")] public bool processNavMesh = false;
         [HorizontalGroup("Configurations/NavMesh"), ShowIf("@processNavMesh"), HideLabel] public NavMeshSurface navMeshSurface;
+        [HorizontalGroup("Configurations/OnChunkGeneratedEvent")] public bool triggerOnChunkGeneratedEvent = true;
+        [HorizontalGroup("Configurations/OnChunkGeneratedEvent"), ShowIf("@triggerOnChunkGeneratedEvent"), HideLabel] public string onChunkGeneratedEvent;
+        [HorizontalGroup("Configurations/OnTerrainGeneratedEvent")] public bool triggerOnTerrainGeneratedEvent = true;
+        [HorizontalGroup("Configurations/OnTerrainGeneratedEvent"), ShowIf("@triggerOnTerrainGeneratedEvent"), HideLabel] public string onTerrainGeneratedEvent;
         [BoxGroup("Configurations")] public bool showChunkData = false;
+        [BoxGroup("Configurations")] public bool showDebug = false;
         
         [InlineProperty, HideLabel, BoxGroup("Marching Cubes")] public MarchingCubes4 marchingCubes = new();
         [BoxGroup("Map Data Generator"), InlineProperty, HideLabel, SerializeReference] public IMapDataGenerator mapDataGenerator;
@@ -33,10 +38,12 @@ namespace KairoEngine.TerrainEngine
         
         public Dictionary<Vector3, GameObject> terrainMeshes = new Dictionary<Vector3, GameObject>();
 
-        private List<Vector3> chunkDataBuffer = new List<Vector3>(); // Store list of chunks for populating with data
-        private List<Vector3> chunkMeshBuffer = new List<Vector3>(); // Store list of chunks for generating the mesh
+        [ShowInInspector] private List<Vector3> chunkDataBuffer = new List<Vector3>(); // Store list of chunks for populating with data
+        [ShowInInspector] private List<Vector3> chunkMeshBuffer = new List<Vector3>(); // Store list of chunks for generating the mesh
+        [ShowInInspector] private List<Vector3> chunkMeshProcessBuffer = new List<Vector3>(); // Store list of chunks that are waiting for their meshes
 
         private bool initialized = false;
+        private bool buildingNavmesh = false;
 
         public class VoxelUpdateData
         {
@@ -178,9 +185,13 @@ namespace KairoEngine.TerrainEngine
         public void GenerateTerrainMesh(Vector3 position, bool overwrite = false)
         {
             bool meshExists = terrainMeshes.TryGetValue(position, out GameObject obj);
-            if(meshExists && !overwrite) return;
+            if(meshExists && !overwrite && obj != null) return;
             if(!overwrite) terrainMeshes.Add(position, null);
-            if(marchingCubes != null) marchingCubes.Generate(chunkSystem, this, position);
+            if(marchingCubes != null) 
+            {
+                chunkMeshProcessBuffer.Add(position);
+                marchingCubes.Generate(chunkSystem, this, position);
+            }
         }
 
         public void UpdateGenerator()
@@ -252,7 +263,6 @@ namespace KairoEngine.TerrainEngine
 
         private void ProcessChunkMeshBuffer()
         {
-            bool terrainChanged = false;
             marchingCubes.UpdateFinishedJobs();
             int limit = marchingCubes.GetJobCount() < parallelMeshJobs ? parallelMeshJobs - marchingCubes.GetJobCount() : 0;
             limit = limit < chunkMeshBuffer.Count ? limit : chunkMeshBuffer.Count;
@@ -260,11 +270,7 @@ namespace KairoEngine.TerrainEngine
             {
                 GenerateTerrainMesh(chunkMeshBuffer[i]);
             }
-            if(chunkMeshBuffer.Count > 0) terrainChanged = true;
             chunkMeshBuffer.RemoveRange(0, limit);
-            if(!processNavMesh) return;
-            if(terrainChanged && chunkMeshBuffer.Count == 0 && chunkDataBuffer.Count == 0 && navMeshSurface != null)
-                Timer.ExecuteRealTime(50, () => navMeshSurface.BuildNavMesh());
         }
 
         public void DestroyChunk(Vector3 position)
@@ -297,7 +303,7 @@ namespace KairoEngine.TerrainEngine
         public void DestroyTerrain()
         {
             var childTransforms = this.gameObject.transform.GetComponentsInChildren<Transform>();
-            if(childTransforms.Length > 0) Debug.Log($"Destroying {childTransforms.Length - 1} terrain objects");
+            if(childTransforms.Length > 0) Debug.Log($"Destroying {childTransforms.Length} terrain objects");
             for (int i = 0; i < childTransforms.Length; i++)
             {
                 if(childTransforms[i] == this.transform) continue;
@@ -406,6 +412,7 @@ namespace KairoEngine.TerrainEngine
 
         public void AddGeneratedTerrainMesh(Vector3 chunkPosition, GameObject meshObj)
         {
+            chunkMeshProcessBuffer.Remove(chunkPosition);
             bool meshExists = terrainMeshes.TryGetValue(chunkPosition, out GameObject currentMesh);
             if(currentMesh != null)
             {
@@ -419,6 +426,23 @@ namespace KairoEngine.TerrainEngine
                 //terrainMeshes.Add(chunkPosition, meshObj);
                 terrainMeshes[chunkPosition] = meshObj;
             }
+            if(triggerOnChunkGeneratedEvent) GenericEvents.Trigger(onChunkGeneratedEvent, chunkPosition);
+            if(!buildingNavmesh && chunkMeshProcessBuffer.Count == 0 && chunkMeshBuffer.Count == 0 && chunkDataBuffer.Count == 0)
+            {
+                buildingNavmesh = true;
+                Timer.ExecuteRealTime(50, () => {
+                    if(processNavMesh && navMeshSurface != null) 
+                    {
+                        var cron = new Cronometer();
+                        navMeshSurface.BuildNavMesh();
+                        //navMeshSurface.UpdateNavMesh(navMeshSurface.navMeshData);
+                        cron.Stop();
+                        if(showDebug) Debug.Log($"Generated Navmesh in {cron.Print()}");
+                        buildingNavmesh = false;
+                    }
+                    if(triggerOnTerrainGeneratedEvent) GenericEvents.Trigger(onTerrainGeneratedEvent);
+                });
+            }
         }
 
         [Button("Save"), ButtonGroup("Buttons")]