public void UpdateHeightMap(int lx, int ly, int lz) { BlockInfo info = _blockset.GetInfo(lx, ly, lz); int h = Math.Min(ly + 1, _ydim - 1); int height = _blockset.GetHeight(lx, lz); if (h < height) { return; } if (h == height && !info.ObscuresLight) { for (int i = ly - 1; i >= 0; i--) { BlockInfo info2 = _blockset.GetInfo(lx, i, lz); if (info2.ObscuresLight) { _blockset.SetHeight(lx, lz, Math.Min(i + 1, _ydim - 1)); break; } } UpdateBlockSkyLight(lx, h, lz); } else if (h > height && info.ObscuresLight) { _blockset.SetHeight(lx, lz, h); UpdateBlockSkyLight(lx, h, lz); } }
private int NeighborHeight(int x, int z) { IBoundedLitBlockCollection src = LocalChunk(x, 0, z); if (src == null) { return(_ydim - 1); } x = (x + _xdim * 2) % _xdim; z = (z + _zdim * 2) % _zdim; return(src.GetHeight(x, z)); }
private void UpdateBlockSkyLight() { IBoundedLitBlockCollection[,] chunkMap = LocalBlockLightMap(); int xdim = _xdim; int ydim = _ydim; int zdim = _zdim; while (_update.Count > 0) { BlockKey k = _update.Dequeue(); int index = LightBitmapIndex(k); _lightbit[index] = false; int xi = k.x + xdim; int zi = k.z + zdim; IBoundedLitBlockCollection cc = chunkMap[xi / xdim, zi / zdim]; if (cc == null) { continue; } int x = xi % xdim; int y = k.y; int z = zi % zdim; int lightval = cc.GetSkyLight(x, y, z); BlockInfo info = cc.GetInfo(x, y, z); int light = BlockInfo.MIN_LUMINANCE; if (cc.GetHeight(x, z) <= y) { light = BlockInfo.MAX_LUMINANCE; } else { int lle = NeighborSkyLight(chunkMap, k.x, k.y, k.z - 1); int lln = NeighborSkyLight(chunkMap, k.x - 1, k.y, k.z); int lls = NeighborSkyLight(chunkMap, k.x, k.y, k.z + 1); int llw = NeighborSkyLight(chunkMap, k.x + 1, k.y, k.z); int lld = NeighborSkyLight(chunkMap, k.x, k.y - 1, k.z); int llu = NeighborSkyLight(chunkMap, k.x, k.y + 1, k.z); light = Math.Max(light, lle); light = Math.Max(light, lln); light = Math.Max(light, lls); light = Math.Max(light, llw); light = Math.Max(light, lld); light = Math.Max(light, llu); } light = Math.Max(light - info.Opacity, 0); if (light != lightval) { //Console.WriteLine("Block SkyLight: ({0},{1},{2}) " + lightval + " -> " + light, k.x, k.y, k.z); cc.SetSkyLight(x, y, z, light); if (info.TransmitsLight) { if (k.y > 0) { QueueRelight(new BlockKey(k.x, k.y - 1, k.z)); } if (k.y < ydim - 1) { QueueRelight(new BlockKey(k.x, k.y + 1, k.z)); } QueueRelight(new BlockKey(k.x - 1, k.y, k.z)); QueueRelight(new BlockKey(k.x + 1, k.y, k.z)); QueueRelight(new BlockKey(k.x, k.y, k.z - 1)); QueueRelight(new BlockKey(k.x, k.y, k.z + 1)); } } } }