using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace KairoEngine.Chunks { [Serializable] public class ChunkSystem { public Vector3Int chunkSize = new Vector3Int(16, 16, 16); public Vector3 voxelSize = new Vector3(1f, 1f, 1f); public Dictionary> chunks; public List chunkList = new List(); public ChunkSystem(Vector3Int chunkSize, Vector3 voxelSize, bool debug = false) { this.chunkSize = chunkSize; this.voxelSize = voxelSize; this.chunks = new Dictionary>(); } public void CreateChunk(Vector3 globalPosition, Vector3Int position, Func, Vector3Int, TChunkBlock> createChunkBlock) { Chunk chunk = new Chunk(chunkSize, globalPosition, position, createChunkBlock); chunks.Add(position, chunk); chunkList.Add(globalPosition); } public void DestroyChunk(Vector3 globalPosition) { Vector3Int chunkPos = GetChunkPositionFromGlobalPosition(globalPosition); chunks.Remove(chunkPos); chunkList.Remove(globalPosition); } public Vector3Int GetVoxelFromGlobalPosition(Vector3 position) { Vector3 voxelPos = new Vector3(); Vector3 chunkPos = GetChunkGlobalPositionFromGlobalPosition(position); voxelPos = position - chunkPos; // voxelPos.x = position.x - (Mathf.Floor(position.x / chunkSize.x * voxelSize.x) * chunkSize.x * voxelSize.x); // voxelPos.y = position.y - (Mathf.Floor(position.y / chunkSize.y * voxelSize.y) * chunkSize.y * voxelSize.y); // voxelPos.z = position.z - (Mathf.Floor(position.z / chunkSize.z * voxelSize.z) * chunkSize.z * voxelSize.z); voxelPos = new Vector3(voxelPos.x / voxelSize.x, voxelPos.y / voxelSize.y, voxelPos.z / voxelSize.z); //voxelPos = new Vector3(voxelPos.x + 0.1f, voxelPos.y + 0.1f, voxelPos.z + 0.1f); Vector3Int pos = new Vector3Int(Mathf.FloorToInt(voxelPos.x), Mathf.FloorToInt(voxelPos.y), Mathf.FloorToInt(voxelPos.z)); if(pos.x >= chunkSize.x || pos.y >= chunkSize.y || pos.z >= chunkSize.z) Debug.LogError($"Position is out of chunk bounds ({pos} | {position} | {chunkPos})"); pos = new Vector3Int(Mathf.Clamp(pos.x, 0, chunkSize.x - 1), Mathf.Clamp(pos.y, 0, chunkSize.y - 1), Mathf.Clamp(pos.z, 0, chunkSize.z - 1)); return pos; } public Vector3Int GetChunkPositionFromGlobalPosition(Vector3 position) { Vector3 pos = new Vector3(position.x / voxelSize.x, position.y / voxelSize.y, position.z / voxelSize.z); Vector3Int chunkPos = new Vector3Int(); chunkPos.x = Mathf.FloorToInt(pos.x / chunkSize.x ) * chunkSize.x; chunkPos.y = Mathf.FloorToInt(pos.y / chunkSize.y ) * chunkSize.y; chunkPos.z = Mathf.FloorToInt(pos.z / chunkSize.z ) * chunkSize.z; return chunkPos; } public Vector3 GetChunkGlobalPositionFromGlobalPosition(Vector3 position) { Vector3Int chunkPos = GetChunkPositionFromGlobalPosition(position); Vector3 pos = new Vector3(chunkPos.x * voxelSize.x, chunkPos.y * voxelSize.y, chunkPos.z * voxelSize.z); return pos; } public TChunkBlock GetBlock(Vector3 position) { Chunk chunk = GetChunk(position); if(!chunk.isInitialized()) return default(TChunkBlock); return chunk.GetBlock(GetVoxelFromGlobalPosition(position)); } public void SetBlock(Vector3 position, TChunkBlock data) { Chunk chunk = GetChunk(position); if(!chunk.isInitialized()) return; Vector3Int pos = GetVoxelFromGlobalPosition(position); if(pos.x >= chunkSize.x || pos.y >= chunkSize.y || pos.z >= chunkSize.z) return; chunk.SetBlock(pos, data); } public Chunk GetChunk(Vector3 position) { Vector3Int chunkPos = GetChunkPositionFromGlobalPosition(position); Chunk chunk; //if(!chunks.TryGetValue(chunkPos, out chunk)) Debug.LogWarning($"Chunk not found for position {chunkPos}"); chunks.TryGetValue(chunkPos, out chunk); return chunk; } public bool ChunkExists(Vector3 position) { Vector3Int chunkPos = GetChunkPositionFromGlobalPosition(position); Chunk chunk; bool value = chunks.TryGetValue(chunkPos, out chunk); return value; } } }