123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using Sirenix.OdinInspector;
- using KairoEngine.Chunks;
- namespace KairoEngine.TerrainEngine
- {
- #if UNITY_EDITOR
- [UnityEditor.InitializeOnLoad]
- #endif
- [HideMonoScript]
- public class ChunkTerrainCullingSystem : MonoBehaviour
- {
- public ChunkTerrainGenerator chunkTerrainGenerator;
- public int maxChunks = 512;
- public float destroyDistanceModifier = 3f;
-
- public List<CullingTarget> targets;
- private void Start()
- {
- chunkTerrainGenerator.DestroyTerrain();
- chunkTerrainGenerator.Initialize();
- for (int i = 0; i < targets.Count; i++) targets[i].lastPosition = new Vector3();
- }
- private void Update()
- {
- CullChunks();
- }
- [ShowInInspector] private bool cullObjectsInEditor = false;
- [Button("Cull Chunks")]
- private void EditorCulling()
- {
- cullObjectsInEditor = !cullObjectsInEditor;
- if(cullObjectsInEditor)
- {
- chunkTerrainGenerator.DestroyTerrain();
- chunkTerrainGenerator.Initialize();
- UnityEditor.EditorApplication.update += CullChunks;
- for (int i = 0; i < targets.Count; i++) targets[i].lastPosition = new Vector3();
- CullChunks();
- }
- else UnityEditor.EditorApplication.update -= CullChunks;
- }
-
- public void CullChunks()
- {
- if(chunkTerrainGenerator == null) return;
- if(!chunkTerrainGenerator.IsInitialized()) return;
- for (int i = 0; i < targets.Count; i++)
- {
- Vector3 chunkPos = chunkTerrainGenerator.chunkSystem.GetChunkGlobalPositionFromGlobalPosition(targets[i].target.position);
- if(!chunkPos.Equals(targets[i].lastPosition))
- {
- chunkTerrainGenerator.ClearChunkDataBuffer();
- targets[i].chunkPositions.Clear();
- targets[i].chunkPositions.InsertRange(0, GetChunkPositions(targets[i].radius, chunkPos));
- for (int a = 0; a < targets[i].chunkPositions.Count; a++)
- {
- chunkTerrainGenerator.GenerateChunk(targets[i].chunkPositions[a]);
- }
-
- }
- targets[i].lastPosition = chunkPos;
- }
- //DestroyChunks();
- #if UNITY_EDITOR
- chunkTerrainGenerator.UpdateEditor ();
- #endif
- }
- private List<Vector3> GetChunkPositions(int radius, Vector3 origin)
- {
- List<Vector2Int> points = new List<Vector2Int>();
- for (int i = 1; i < radius; i++)
- {
- for (int j = 1; j < radius; j++)
- {
- if (i * i + j * j < (radius * radius))
- {
- points.Add(new Vector2Int(i,j));
- points.Add(new Vector2Int(-i,j));
- points.Add(new Vector2Int(i,-j));
- points.Add(new Vector2Int(-i,-j));
- points.Add(new Vector2Int(i, 0));
- points.Add(new Vector2Int(-i, 0));
- points.Add(new Vector2Int(0, j));
- points.Add(new Vector2Int(0, -j));
- }
- }
- }
- //Debug.Log($"Found {points.Count} points");
- List<Vector3> chunkPositions = new List<Vector3>();
- chunkPositions.Add(origin);
- var voxelSize = chunkTerrainGenerator.voxelSize;
- var chunkSize = chunkTerrainGenerator.chunkSize;
- for (int i = 0; i < points.Count; i++)
- {
- for (int j = 0; j < chunkTerrainGenerator.chunkLimit.y; j++)
- {
- Vector3 pos = new Vector3(points[i].x * chunkSize.x * voxelSize.x, j * chunkSize.y * voxelSize.y, points[i].y * chunkSize.z * voxelSize.z);
- pos += origin;
- chunkPositions.Add(pos);
- }
- }
- //Debug.Log($"Found {chunkPositions.Count} chunk positions");
- return chunkPositions;
- }
- public void DestroyChunks()
- {
- int chunkCount = chunkTerrainGenerator.chunkSystem.chunkList.Count;
- if(chunkCount < maxChunks) return;
- int destroyCount = chunkCount - maxChunks;
- Vector3 chunkSize = chunkTerrainGenerator.chunkSize;
- Vector3 voxelSize = chunkTerrainGenerator.voxelSize;
- Vector3 size = new Vector3(chunkSize.x * voxelSize.x, chunkSize.y * voxelSize.y, chunkSize.z * voxelSize.z);
- List<Vector3> destroyList = new List<Vector3>();
- for (int i = 0; i < chunkCount; i++)
- {
- Vector3 chunkPos = chunkTerrainGenerator.chunkSystem.chunkList[i];
- List<bool> values = new List<bool>();
- for (int a = 0; a < targets.Count; a++)
- {
- Vector3 targetPos = targets[a].target.position;
- Vector3 pos = targetPos + (size * targets[a].radius * destroyDistanceModifier);
- pos.y = targetPos.y;
- if(Vector3.Distance(targetPos, chunkPos) > Vector3.Distance(targetPos, pos)) values.Add(true);
- }
- if(values.Count == targets.Count) destroyList.Add(chunkPos);
- if(destroyList.Count >= destroyCount) break;
- }
- for (int i = 0; i < destroyList.Count; i++)
- {
- chunkTerrainGenerator.DestroyChunk(destroyList[i]);
- }
- }
- [System.Serializable]
- public class CullingTarget
- {
- [HorizontalGroup("Target", 0.8f), HideLabel] public Transform target;
- [HorizontalGroup("Target"), HideLabel, Range(0, 16)] public int radius;
- public Vector3 lastPosition;
- public List<Vector3> chunkPositions;
- }
- }
- }
|