Fixed negative chunks invisible
This commit is contained in:
111
World.cs
111
World.cs
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user