private void CheckForTerrainUpdates()
{
List<VoxelUpdate> FineChanges = new List<VoxelUpdate>();
List<ChunkUpdate> ChunkChanges = new List<ChunkUpdate>();
// NumVoxelsPerChunk/4 = Maximum fine changes PER UPDATE allowed.
int MaxFineChangesAllowed = (VoxelChannel.CHUNK_SIZE_X * VoxelChannel.CHUNK_SIZE_Y * VoxelChannel.CHUNK_SIZE_Z) / 4;
int NumFineChanges = 0;
// For each chunk...
for (int cx = 0; cx < (m_channel.Width / VoxelChannel.CHUNK_SIZE_X); cx++)
{
for (int cy = 0; cy < (m_channel.Length / VoxelChannel.CHUNK_SIZE_Y); cy++)
{
// Get voxels in each chunk...
byte[] data_a = m_channel.GetChunkData(cx, cy);
byte[] data_b = m_revert.GetChunkData(cx, cy);
// Compare
for (int x = 0; x < VoxelChannel.CHUNK_SIZE_X; x++)
{
for (int y = 0; y < VoxelChannel.CHUNK_SIZE_Y; y++)
{
for (int z = 0; z < VoxelChannel.CHUNK_SIZE_Z; z++)
{
// Compare newest voxel with revert map voxel
byte a = m_channel.GetChunkBlock(ref data_a, x, y, z);
if (a != m_channel.GetChunkBlock(ref data_b, x, y, z))
{
// Too many fine updates?
NumFineChanges++;
if (NumFineChanges > MaxFineChangesAllowed)
{
// Clear fine updates, reset counter, and add a coarse update.
FineChanges.Clear();
NumFineChanges = 0;
ChunkUpdate cu = new ChunkUpdate();
cu.X = cx;
cu.Y = cy;
cu.Z = 0;
ChunkChanges.Add(cu);
}
else
{
// Otherwise, add a fine update.
VoxelUpdate vu = new VoxelUpdate();
vu.X = x;
vu.Y = y;
vu.Z = z;
vu.Type = a;
FineChanges.Add(vu);
}
}
}
}
}
}
}
m_scene.ForEachClient(delegate(IClientAPI cli)
{
foreach (VoxelUpdate up in FineChanges)
{
cli.SendVoxelUpdate(up.X, up.Y, up.Z, up.Type);
}
foreach (ChunkUpdate up in ChunkChanges)
{
cli.SendChunkUpdate(up.X, up.Y, up.Z);
}
});
}