collision refactor

This commit is contained in:
maxwes08
2026-03-24 00:14:17 +01:00
parent 9ffda6f5af
commit 24ca4288af
4 changed files with 242 additions and 140 deletions

View File

@@ -47,7 +47,7 @@ namespace Voxel
var neighbors = GetChunkNeighbors(chunk).ToList();
_chunks.Remove((chunkX, chunkZ));
// 3. For each neighbor, remove reference to this chunk
// update neighbor references to this chunk
foreach (var (orientation, neighbor) in neighbors)
{
var opposite = GetOppositeOrientation(orientation);
@@ -159,16 +159,26 @@ namespace Voxel
return chunk.GetBlock(localX, worldY, localZ);
}
public void SetBlock(int worldX, int worldY, int worldZ, Blocks block)
public void SetBlock(int worldX, int worldY, int worldZ, Blocks block, bool updateMesh = true)
{
var (chunkX, chunkZ, localX, localZ) = WorldToChunkCoords(worldX, worldZ);
Chunk chunk = GetChunk(chunkX, chunkZ);
if (chunk == null) return;
chunk.SetBlock(localX, worldY, localZ, block);
chunk.SetBlock(localX, worldY, localZ, block, updateMesh: updateMesh);
if (block == Blocks.Air && ((localX == Chunk.Size - 1 || localX == 0) || (localZ == Chunk.Size - 1 || localZ == 0)))
// temporary tnt functionality
if (block == Blocks.TNT)
{
int radius = 4;
Explode(worldX, worldY, worldZ, 4);
}
if (updateMesh == false) return;
if (block == Blocks.Air && IsOnChunkBorder(worldX, worldZ))
{
foreach (var orientation in GetEdgeOrientations(localX, localZ, Chunk.Size))
{
@@ -180,6 +190,69 @@ namespace Voxel
}
}
public bool IsOnChunkBorder(int worldX, int worldZ)
{
var (chunkX, chunkZ, localX, localZ) = WorldToChunkCoords(worldX, worldZ);
return (localX == Chunk.Size - 1 || localX == 0) || (localZ == Chunk.Size - 1 || localZ == 0);
}
// temporary tnt functionality
public void Explode(int centerX, int centerY, int centerZ, int radius)
{
int radiusSq = radius * radius;
var affectedChunks = new HashSet<Chunk>(); // store chunks that will change
// bounding box
int minX = centerX - radius;
int maxX = centerX + radius;
int minY = centerY - radius;
int maxY = centerY + radius;
int minZ = centerZ - radius;
int maxZ = centerZ + radius;
for (int x = minX; x <= maxX; x++)
{
for (int y = minY; y <= maxY; y++)
{
for (int z = minZ; z <= maxZ; z++)
{
int dx = x - centerX;
int dy = y - centerY;
int dz = z - centerZ;
if (dx * dx + dy * dy + dz * dz <= radiusSq)
{
// no update
SetBlock(x, y, z, Blocks.Air, updateMesh: false);
// add chunk to update list
var (chunkX, chunkZ, localX, localZ) = WorldToChunkCoords(x, z);
Chunk chunk = GetChunk(chunkX, chunkZ);
if (chunk != null)
affectedChunks.Add(chunk);
if (IsOnChunkBorder(x, z))
{
foreach (var orientation in GetEdgeOrientations(localX, localZ, Chunk.Size))
{
if (chunk.Neighbors.TryGetValue(orientation, out var neighbor) && neighbor != null)
{
affectedChunks.Add(neighbor);
}
}
}
}
}
}
}
// Now rebuild meshes for all affected chunks
foreach (var chunk in affectedChunks)
{
chunk.UpdateChunkMesh();
}
}
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;