using OpenTK.Mathematics; namespace RubyDung; public class World { private Shader shader; // private Chunk chunk; // private Chunk[,,] chunks; private Dictionary chunks = new Dictionary(); // private byte[,,] blocks; private Dictionary blocks = new Dictionary(); private int chunkSize = 16; public Vector3i worldSize = new Vector3i(256, 256, 16); private int xChunks; private int yChunks; private int zChunks; private int viewDistance = 1; public World(Shader shader) { this.shader = shader; viewDistance *= chunkSize; // blocks = new byte[worldSize.X, worldSize.Y, worldSize.Z]; for (int x = -viewDistance; x < viewDistance; x++) { for (int y = -viewDistance; y < viewDistance; y++) { for (int z = 0; z < worldSize.Z; z++) { // blocks[x, y, z] = 1; blocks[new Vector3(x, y, z)] = 1; } } } // chunk = new Chunk(shader, this, 0, 0, 0, 16, 16, 16); xChunks = viewDistance / chunkSize; yChunks = viewDistance / chunkSize; zChunks = worldSize.Z / chunkSize; // chunks = new Chunk[xChunks, yChunks, zChunks]; //* for (int x = -xChunks; x < xChunks; x++) { for (int y = -yChunks; y < yChunks; y++) { for (int z = 0; z < zChunks; z++) { int x0 = x * chunkSize; int y0 = y * chunkSize; int z0 = z * chunkSize; int x1 = (x + 1) * chunkSize; int y1 = (y + 1) * chunkSize; int z1 = (z + 1) * chunkSize; // chunks[x, y, z] = new Chunk(shader, this, x0, y0, z0, x1, y1, z1); chunks[new Vector3(x, y, z)] = new Chunk(shader, this, x0, y0, z0, x1, y1, z1); } } } //*/ } public void OnLoad() { //* // foreach (Chunk chunk in chunks) foreach (Chunk chunk in chunks.Values) { chunk.OnLoad(); } //*/ } public void OnUpdateFrame(Camera camera) { // Calcular qual chunk o jogador está int posX = (int)Math.Floor(camera.cameraPos.X / chunkSize); int posY = (int)Math.Floor(camera.cameraPos.Y / chunkSize); // int blockGenerated = 0; for (int x = posX - viewDistance; x < posX + viewDistance; x++) { for (int y = posY - viewDistance; y < posY + viewDistance; y++) { for (int z = 0; z < worldSize.Z; z++) { if (!blocks.ContainsKey(new Vector3(x, y, z))) { blocks[new Vector3(x, y, z)] = 1; // blockGenerated++; } } } } // Debug.Log($"Blocos gerados: {blockGenerated}"); // Debug.Log($"Position: {posX}, {posY}; Chunk: {xChunks}, {yChunks}"); //* for (int x = posX - xChunks; x < posX + xChunks; x++) { for (int y = posY - yChunks; y < posY + yChunks; y++) { for (int z = 0; z < zChunks; z++) { if (!chunks.ContainsKey(new Vector3(x, y, z))) { // Debug.Log($"Novo chunk criado em: {x}, {y}, {z}"); int x0 = x * chunkSize; int y0 = y * chunkSize; int z0 = z * chunkSize; int x1 = (x + 1) * chunkSize; int y1 = (y + 1) * chunkSize; int z1 = (z + 1) * chunkSize; chunks[new Vector3(x, y, z)] = new Chunk(shader, this, x0, y0, z0, x1, y1, z1); chunks[new Vector3(x, y, z)].OnLoad(); } } } } //*/ // Debug.Log($"Renderizando {chunks.Count} chunks"); // foreach (Chunk chunk in chunks) foreach (Chunk chunk in chunks.Values) { chunk.OnUpdateFrame(); } } public void OnRenderFrame() { // foreach (Chunk chunk in chunks) foreach (Chunk chunk in chunks.Values) { chunk.OnRenderFrame(); } } public bool IsTile(int x, int y, int z) { if (x >= -viewDistance && x < viewDistance) { if (y >= -viewDistance && y < viewDistance) { if (z >= 0 && z < worldSize.Z) { // return blocks[x, y, z] == 1; return blocks.ContainsKey(new Vector3(x, y, z)); } } } return false; } public bool IsSolidTile(int x, int y, int z) { return IsTile(x, y, z); } public List GetCubes(AABB other) { List cubes = new List(); int x0 = (int)other.x0 - 1; int y0 = (int)other.y0 - 1; int z0 = (int)other.z0 - 1; int x1 = (int)other.x1 + 1; int y1 = (int)other.y1 + 1; int z1 = (int)other.z1 + 1; /* // Arredonda para baixo os limites mínimos int x0 = (int)Math.Floor(other.x0); int y0 = (int)Math.Floor(other.y0); int z0 = (int)Math.Floor(other.z0); // Arredonda para cima os limites máximos int x1 = (int)Math.Ceiling(other.x1); int y1 = (int)Math.Ceiling(other.y1); int z1 = (int)Math.Ceiling(other.z1); */ //* if (x0 < -viewDistance) { x0 = -viewDistance; } if (y0 < -viewDistance) { y0 = -viewDistance; } if (z0 < 0) { z0 = 0; } if (x1 > viewDistance) { x1 = viewDistance; } if (y1 > viewDistance) { y1 = viewDistance; } if (z1 > worldSize.Z) { z1 = worldSize.Z; } //*/ // Limita as coordenadas aos limites do mundo /* x0 = Math.Max(x0, -viewDistance); y0 = Math.Max(y0, -viewDistance); z0 = Math.Max(z0, 0); x1 = Math.Min(x1, viewDistance); y1 = Math.Min(y1, viewDistance); z1 = Math.Min(z1, worldSize.Z); */ for (int x = x0; x < x1; x++) { for (int y = y0; y < y1; y++) { for (int z = z0; z < z1; z++) { if (IsSolidTile(x, y, z)) { cubes.Add(new AABB( (float)x, (float)y, (float)z, (float)x + 1.0f, (float)y + 1.0f, (float)z + 1.0f )); } } } } return cubes; } }