From 66bd79646cbedd923a2ee9253267bf4d9e946ced Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Thu, 14 Apr 2011 02:30:40 +0000 Subject: [PATCH] Replaced the blocklight resetting code, which was buggy. The new method is faster anyway and takes advantage of the fact that light is only being added, not removed or impeded in any way. --- Substrate/SubstrateCS/Source/Chunk.cs | 28 +++++ Substrate/SubstrateCS/Source/ChunkRef.cs | 127 +++++++++++++++++------ 2 files changed, 124 insertions(+), 31 deletions(-) diff --git a/Substrate/SubstrateCS/Source/Chunk.cs b/Substrate/SubstrateCS/Source/Chunk.cs index aac26bb..d5bc7b2 100644 --- a/Substrate/SubstrateCS/Source/Chunk.cs +++ b/Substrate/SubstrateCS/Source/Chunk.cs @@ -734,6 +734,34 @@ namespace Substrate #endregion + public void ResetBlockLight () + { + for (int i = 0; i < _blocks.Length; i++) { + //BlockInfo info = BlockInfo.BlockTable[_blocks[i]]; + _blockLight[i] = 0; // Math.Max(info.Luminance - info.Opacity, 0); + } + } + + public void ResetSkyLight () + { + for (int x = 0; x < XDim; x++) { + for (int z = 0; z < ZDim; z++) { + int height = GetHeight(x, z); + int ystride = x << 11 | z << 7; + for (int y = 0; y < YDim; y++ ) { + int index = ystride + y; + + if (y >= height) { + _skyLight[index] = BlockInfo.MIN_LUMINANCE; + } + else { + _skyLight[index] = BlockInfo.MIN_LUMINANCE; + } + } + } + } + } + private int Timestamp () { DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0); diff --git a/Substrate/SubstrateCS/Source/ChunkRef.cs b/Substrate/SubstrateCS/Source/ChunkRef.cs index bbd571e..5d326aa 100644 --- a/Substrate/SubstrateCS/Source/ChunkRef.cs +++ b/Substrate/SubstrateCS/Source/ChunkRef.cs @@ -438,48 +438,116 @@ namespace Substrate private BitArray _lightbit; private Queue _update; + public void ResetBlockLight () + { + GetChunk().ResetBlockLight(); + MarkDirty(); + } + + public void ResetSkyLight () + { + GetChunk().ResetSkyLight(); + MarkDirty(); + } + public void RebuildBlockLight () { + GetChunk(); + for (int x = 0; x < XDim; x++) { for (int z = 0; z < ZDim; z++) { for (int y = 0; y < YDim; y++) { BlockInfo info = GetBlockInfo(x, y, z); - if (info == null || info.Luminance == 0) { - SetBlockLight(x, y, z, 0); - } - else { - SetBlockLight(x, y, z, Math.Max(info.Luminance - info.Opacity, 0)); - QueueRelight(new BlockKey(x, y, z)); + if (info.Luminance > 0) { + SpreadBlockLight(x, y, z); } } } } - - UpdateBlockLight(); } public void RebuildSkyLight () { + GetChunk(); + for (int x = 0; x < XDim; x++) { for (int z = 0; z < ZDim; z++) { - int height = GetHeight(x, z); - for (int y = 0; y < YDim; y++) { - if (y > height) { - SetBlockLight(x, y, z, BlockInfo.MAX_LUMINANCE); - } - else if (y < height) { - SetBlockLight(x, y, z, 0); - } - else { - QueueRelight(new BlockKey(x, y, z)); - } - } + QueueRelight(new BlockKey(x, YDim - 1, z)); } } + MarkDirty(); UpdateSkyLight(); } + private struct LightRecord + { + public int x; + public int y; + public int z; + public int str; + + public LightRecord (int _x, int _y, int _z, int s) + { + x = _x; + y = _y; + z = _z; + str = s; + } + } + + private void SpreadBlockLight (int lx, int ly, int lz) + { + BlockInfo primary = GetBlockInfo(lx, ly, lz); + int primaryLight = GetBlockLight(lx, ly, lz); + int priLum = Math.Max(primary.Luminance - primary.Opacity, 0); + + if (primaryLight < priLum) { + SetBlockLight(lx, ly, lz, priLum); + } + + if (primaryLight > primary.Luminance - 1) { + return; + } + + Queue spread = new Queue(); + spread.Enqueue(new LightRecord(lx - 1, ly, lz, primary.Luminance - 1)); + spread.Enqueue(new LightRecord(lx + 1, ly, lz, primary.Luminance - 1)); + spread.Enqueue(new LightRecord(lx, ly - 1, lz, primary.Luminance - 1)); + spread.Enqueue(new LightRecord(lx, ly + 1, lz, primary.Luminance - 1)); + spread.Enqueue(new LightRecord(lx, ly, lz - 1, primary.Luminance - 1)); + spread.Enqueue(new LightRecord(lx, ly, lz + 1, primary.Luminance - 1)); + + while (spread.Count > 0) { + LightRecord rec = spread.Dequeue(); + + ChunkRef cc = LocalChunk(rec.x, rec.y, rec.z); + if (cc == null) { + continue; + } + + int x = (rec.x + XDim) % XDim; + int y = rec.y; + int z = (rec.z + ZDim) % ZDim; + + BlockInfo info = cc.GetBlockInfo(x, y, z); + int light = cc.GetBlockLight(x, y, z); + + int dimStr = Math.Max(rec.str - info.Opacity, 0); + + if (dimStr > light) { + cc.SetBlockLight(x, y, z, dimStr); + + spread.Enqueue(new LightRecord(rec.x - 1, rec.y, rec.z, dimStr - 1)); + spread.Enqueue(new LightRecord(rec.x + 1, rec.y, rec.z, dimStr - 1)); + spread.Enqueue(new LightRecord(rec.x, rec.y - 1, rec.z, dimStr - 1)); + spread.Enqueue(new LightRecord(rec.x, rec.y + 1, rec.z, dimStr - 1)); + spread.Enqueue(new LightRecord(rec.x, rec.y, rec.z - 1, dimStr - 1)); + spread.Enqueue(new LightRecord(rec.x, rec.y, rec.z + 1, dimStr - 1)); + } + } + } + private void UpdateBlockLight (int lx, int ly, int lz) { BlockKey primary = new BlockKey(lx, ly, lz); @@ -492,11 +560,6 @@ namespace Substrate QueueRelight(new BlockKey(lx, ly, lz - 1)); QueueRelight(new BlockKey(lx, ly, lz + 1)); - UpdateBlockLight(); - } - - private void UpdateBlockLight () - { while (_update.Count > 0) { BlockKey k = _update.Dequeue(); int index = LightBitmapIndex(k); @@ -514,9 +577,9 @@ namespace Substrate int lld = NeighborLight(k.x, k.y - 1, k.z); int llu = NeighborLight(k.x, k.y + 1, k.z); - int x = (k.x + XDim) % XDim; + int x = (k.x + XDim * 2) % XDim; int y = k.y; - int z = (k.z + ZDim) % ZDim; + int z = (k.z + ZDim * 2) % ZDim; int lightval = cc.GetBlockLight(x, y, z); BlockInfo info = cc.GetBlockInfo(x, y, z); @@ -535,6 +598,7 @@ namespace Substrate //Console.WriteLine("Block Light: ({0},{1},{2}) " + lightval + " -> " + light, k.x, k.y, k.z); cc.SetBlockLight(x, y, z, light); + cc.MarkDirty(); QueueRelight(new BlockKey(k.x - 1, k.y, k.z)); QueueRelight(new BlockKey(k.x + 1, k.y, k.z)); @@ -592,6 +656,7 @@ namespace Substrate //Console.WriteLine("Block SkyLight: ({0},{1},{2}) " + lightval + " -> " + light, k.x, k.y, k.z); cc.SetBlockSkyLight(x, y, z, light); + cc.MarkDirty(); QueueRelight(new BlockKey(k.x - 1, k.y, k.z)); QueueRelight(new BlockKey(k.x + 1, k.y, k.z)); @@ -675,8 +740,8 @@ namespace Substrate return 0; } - x = (x + XDim) % XDim; - z = (z + ZDim) % ZDim; + x = (x + XDim * 2) % XDim; + z = (z + ZDim * 2) % ZDim; BlockInfo info = src.GetBlockInfo(x, y, z); int light = src.GetBlockLight(x, y, z); @@ -695,8 +760,8 @@ namespace Substrate return 0; } - x = (x + XDim) % XDim; - z = (z + ZDim) % ZDim; + x = (x + XDim * 2) % XDim; + z = (z + ZDim * 2) % ZDim; int light = src.GetBlockSkyLight(x, y, z);