collision refactor
This commit is contained in:
81
World.cs
81
World.cs
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user