Fixed negative chunks invisible

This commit is contained in:
max
2025-12-14 23:54:22 +01:00
parent a1cdd6b5de
commit 35ecc36bdb
7 changed files with 118 additions and 40 deletions

111
World.cs
View File

@@ -8,6 +8,9 @@ namespace Voxel
{
private Dictionary<(int, int), Chunk> _chunks;
private (int x, int z) _lastCenter = (0, 0);
private int _loadDistance = 4;
private static readonly Dictionary<Orientation, (int x, int y)> _neighborOffsets = new()
{
{ Orientation.West, (1, 0) },
@@ -33,6 +36,7 @@ namespace Voxel
UpdateNeighboringChunks(chunk);
chunk.UpdateChunkMesh();
Renderer.MarkBuffersDirty();
}
public void RemoveChunk(int chunkX, int chunkZ)
@@ -52,6 +56,63 @@ namespace Voxel
}
}
public new void UpdateChunkLoading(Vector3 playerPosition)
{
int centerX = (int)Math.Floor(playerPosition.X / Chunk.Size);
int centerZ = (int)Math.Floor(playerPosition.Z / Chunk.Size);
// Quick check - skip if still in same chunk
if (centerX == _lastCenter.x && centerZ == _lastCenter.z)
return;
_lastCenter = (centerX, centerZ);
// Calculate bounds
int minX = centerX - _loadDistance;
int maxX = centerX + _loadDistance;
int minZ = centerZ - _loadDistance;
int maxZ = centerZ + _loadDistance;
// Unload chunks outside range
UnloadDistantChunks(minX, maxX, minZ, maxZ);
// Load chunks inside range
LoadChunksInRange(minX, maxX, minZ, maxZ);
}
private void UnloadDistantChunks(int minX, int maxX, int minZ, int maxZ)
{
var chunksToRemove = new List<(int, int)>();
foreach (var (chunkX, chunkZ) in _chunks.Keys)
{
if (chunkX < minX || chunkX > maxX || chunkZ < minZ || chunkZ > maxZ)
{
chunksToRemove.Add((chunkX, chunkZ));
}
}
foreach (var chunkPos in chunksToRemove)
{
RemoveChunk(chunkPos.Item1, chunkPos.Item2);
}
}
private void LoadChunksInRange(int minX, int maxX, int minZ, int maxZ)
{
for (int x = minX; x <= maxX; x++)
{
for (int z = minZ; z <= maxZ; z++)
{
if (!_chunks.ContainsKey((x, z)))
{
Chunk chunk = new Chunk(x, z);
AddChunk(chunk);
}
}
}
}
public void UpdateNeighboringChunks(Chunk chunk)
{
chunk.Neighbors[Orientation.West] = null;
@@ -87,39 +148,21 @@ namespace Voxel
public Blocks GetBlock(int worldX, int worldY, int worldZ)
{
int chunkX = worldX / Chunk.Size;
int chunkZ = worldZ / Chunk.Size;
var (chunkX, chunkZ, localX, localZ) = WorldToChunkCoords(worldX, worldZ);
Chunk chunk = GetChunk(chunkX, chunkZ);
if (chunk == null) return 0; // air if chunk not loaded
int localX = worldX % Chunk.Size;
int localZ = worldZ % Chunk.Size;
return chunk.GetBlock(localX, worldY, localZ);
}
List<Orientation> GetEdgeOrientations(int localX, int localZ, int size)
{
var orientations = new List<Orientation>();
if (localX == size - 1) orientations.Add(Orientation.West);
if (localX == 0) orientations.Add(Orientation.East);
if (localZ == size - 1) orientations.Add(Orientation.North);
if (localZ == 0) orientations.Add(Orientation.South);
return orientations;
}
public void SetBlock(int worldX, int worldY, int worldZ, Blocks block)
{
int chunkX = worldX / Chunk.Size;
int chunkZ = worldZ / Chunk.Size;
var (chunkX, chunkZ, localX, localZ) = WorldToChunkCoords(worldX, worldZ);
Chunk chunk = GetChunk(chunkX, chunkZ);
if (chunk == null) return;
int localX = worldX % Chunk.Size;
int localZ = worldZ % Chunk.Size;
chunk.SetBlock(localX, worldY, localZ, block);
if (block == Blocks.Air && ((localX == Chunk.Size - 1 || localX == 0) || (localZ == Chunk.Size - 1 || localZ == 0)))
@@ -134,6 +177,30 @@ namespace Voxel
}
}
public static (int chunkX, int chunkZ, int localX, int localZ) WorldToChunkCoords(int worldX, int worldZ)
{
int chunkX = worldX >= 0 ? worldX / Chunk.Size : (worldX + 1) / Chunk.Size - 1;
int chunkZ = worldZ >= 0 ? worldZ / Chunk.Size : (worldZ + 1) / Chunk.Size - 1;
int localX = ((worldX % Chunk.Size) + Chunk.Size) % Chunk.Size;
int localZ = ((worldZ % Chunk.Size) + Chunk.Size) % Chunk.Size;
return (chunkX, chunkZ, localX, localZ);
}
List<Orientation> GetEdgeOrientations(int localX, int localZ, int size)
{
var orientations = new List<Orientation>();
if (localX == size - 1) orientations.Add(Orientation.West);
if (localX == 0) orientations.Add(Orientation.East);
if (localZ == size - 1) orientations.Add(Orientation.North);
if (localZ == 0) orientations.Add(Orientation.South);
return orientations;
}
public IEnumerable<(Orientation orientation, Chunk neighbor)> GetChunkNeighbors(Chunk chunk)
{
int chunkX = chunk.X;