public void SaveShrinkNode(LightShrinkNode node) { lock (_lockObj) { node.index = 0; node.prevLightLevel = 0; node.lightLevel = 0; node.chunk = null; shrinkNodes.Enqueue(node); if (maxShrink < shrinkNodes.Count) { maxShrink = shrinkNodes.Count; } } }
public LightShrinkNode GetShrinkNode(int index, int prevLightLevel, int lightLevel, Chunk chunk) { LightShrinkNode node; lock (_lockObj) { if (shrinkNodes.Count > 0) { node = shrinkNodes.Dequeue(); node.index = index; node.prevLightLevel = prevLightLevel; node.lightLevel = lightLevel; node.chunk = chunk; } else { node = new LightShrinkNode(index, prevLightLevel, lightLevel, chunk); } } return(node); }
private List <Chunk> GetBlockLightChangeChunks(Chunk chunk, int x, int y, int z, Block b, List <Chunk> list) { BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType); int curBlockLightLevel = calculator.LightLevel(b.ExtendId); int blockLightLevel = chunk.GetBlockLight(x, y, z, true); if (curBlockLightLevel > blockLightLevel) { int index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; LightSpreadNode node = NodeCache.Instance.GetSpreadNode(index, curBlockLightLevel, chunk); _blockLightSpread.AddSpreadNode(node); chunk.SetBlockLight(x, y, z, curBlockLightLevel, true); } else if (curBlockLightLevel < blockLightLevel) { int index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; LightShrinkNode node = NodeCache.Instance.GetShrinkNode(index, blockLightLevel, curBlockLightLevel, chunk); _blockLightShrink.AddShrinkNode(node); chunk.SetBlockLight(x, y, z, curBlockLightLevel, true); } List <Chunk> spreadList = _blockLightSpread.SpreadInChunk(chunk); List <Chunk> shrinkList = _blockLightShrink.ShrinkInChunk(chunk); for (int i = 0; i < spreadList.Count; i++) { if (!list.Contains(spreadList[i])) { list.Add(spreadList[i]); } } for (int i = 0; i < shrinkList.Count; i++) { if (!list.Contains(shrinkList[i])) { list.Add(shrinkList[i]); } } return(list); }
public List <Chunk> ShrinkInChunk(Chunk chunk) { int nextX; int nextY; int nextZ; Chunk nextChunk; _changedList.Clear(); while (_lightBfsQueue.Count > 0) { LightShrinkNode node = _lightBfsQueue.Dequeue(); int y = node.index % Chunk.chunkHeight; int temp = node.index / Chunk.chunkHeight; int z = temp % Chunk.chunkDepth; int x = temp / Chunk.chunkDepth; Chunk nodeChunk = node.chunk; int prevLightLevel = node.prevLightLevel; int curLightLevel = node.lightLevel; NodeCache.Instance.SaveShrinkNode(node); //y - 1 nextY = y - 1; if (nextY >= 0) { SpreadInPosDown(x, nextY, z, nodeChunk, prevLightLevel, curLightLevel); } nextX = x - 1; nextChunk = nodeChunk; if (nextX < 0) { nextChunk = _world.GetChunk(nextX + nodeChunk.worldPos.x, y + nodeChunk.worldPos.y, z + nodeChunk.worldPos.z); nextX = Chunk.chunkWidth - 1; } if (nextChunk != null && (nextChunk.isLightDataPrepared || nextChunk.worldPos.EqualOther(chunk.worldPos))) { ShrinkHorizontalInPos(nextX, y, z, nextChunk, prevLightLevel, curLightLevel); } // //x + 1 nextX = x + 1; nextChunk = nodeChunk; if (nextX >= Chunk.chunkWidth) { nextChunk = _world.GetChunk(nextX + nodeChunk.worldPos.x, y + nodeChunk.worldPos.y, z + nodeChunk.worldPos.z); nextX = 0; } if (nextChunk != null && (nextChunk.isLightDataPrepared || nextChunk.worldPos.EqualOther(chunk.worldPos))) { ShrinkHorizontalInPos(nextX, y, z, nextChunk, prevLightLevel, curLightLevel); } //z - 1 nextZ = z - 1; nextChunk = nodeChunk; if (nextZ < 0) { nextChunk = _world.GetChunk(x + nodeChunk.worldPos.x, y + nodeChunk.worldPos.y, nextZ + nodeChunk.worldPos.z); nextZ = Chunk.chunkDepth - 1; } if (nextChunk != null && (nextChunk.isLightDataPrepared || nextChunk.worldPos.EqualOther(chunk.worldPos))) { ShrinkHorizontalInPos(x, y, nextZ, nextChunk, prevLightLevel, curLightLevel); } //z + 1 nextZ = z + 1; nextChunk = nodeChunk; if (nextZ >= Chunk.chunkDepth) { nextChunk = _world.GetChunk(x + nodeChunk.worldPos.x, y + nodeChunk.worldPos.y, nextZ + nodeChunk.worldPos.z); nextZ = 0; } if (nextChunk != null && (nextChunk.isLightDataPrepared || nextChunk.worldPos.EqualOther(chunk.worldPos))) { ShrinkHorizontalInPos(x, y, nextZ, nextChunk, prevLightLevel, curLightLevel); } // y + 1 nextY = y + 1; if (nextY < Chunk.chunkHeight) { ShrinkInPosUp(x, nextY, z, nodeChunk, prevLightLevel, curLightLevel); } } List <Chunk> spreadList = _lightSpread.SpreadInChunk(chunk); for (int i = 0; i < spreadList.Count; i++) { if (!_changedList.Contains(spreadList[i])) { _changedList.Add(spreadList[i]); } } return(_changedList); }
public void AddShrinkNode(LightShrinkNode node) { _lightBfsQueue.Enqueue(node); }
private List <Chunk> GetSunLightChangeChunks(Chunk chunk, int x, int y, int z, Block b, List <Chunk> list) { List <Chunk> spreadList = null; List <Chunk> shrinkList = null; BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType); int lightDamp = calculator.LightDamp(b.ExtendId); int height = chunk.GetHeight(x, z); int lightLevel = chunk.GetSunLight(x, y, z, true); int curLightLevel; if (y >= height - 1) { for (int ty = y; ty >= height; ty--) { Block nextBlock = chunk.GetBlock(x, ty, z); BlockAttributeCalculator nextCalculator = BlockAttributeCalculatorFactory.GetCalculator(nextBlock.BlockType); int nextLightDamp = nextCalculator.LightDamp(nextBlock.ExtendId); if (nextLightDamp > 0) { height = ty + 1; //更新高度 chunk.SetHeight(x, z, height, true); break; } } curLightLevel = WorldConfig.Instance.maxLightLevel - lightDamp; if (curLightLevel < 0) { curLightLevel = 0; } } else { int leftSunLight = chunk.GetSunLight(x - 1, y, z); int rightSunLight = chunk.GetSunLight(x + 1, y, z); int topSunLight = chunk.GetSunLight(x, y + 1, z); int bottomSunLight = chunk.GetSunLight(x, y - 1, z); int frontSunLight = chunk.GetSunLight(x, y, z + 1); int backSunLight = chunk.GetSunLight(x, y, z - 1); int maxSunLight = GetMax(leftSunLight, rightSunLight, topSunLight, bottomSunLight, frontSunLight, backSunLight); curLightLevel = maxSunLight - lightDamp - 1; if (curLightLevel < 0) { curLightLevel = 0; } } if (curLightLevel < lightLevel) { chunk.SetSunLight(x, y, z, curLightLevel, true); int index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; LightShrinkNode node = NodeCache.Instance.GetShrinkNode(index, lightLevel, curLightLevel, chunk); _sunLightShrink.AddShrinkNode(node); shrinkList = _sunLightShrink.ShrinkInChunk(chunk); } else if (curLightLevel > lightLevel) { chunk.SetSunLight(x, y, z, curLightLevel, true); int index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y; LightSpreadNode node = NodeCache.Instance.GetSpreadNode(index, curLightLevel, chunk); _sunLightSpread.AddSpreadNode(node); spreadList = _sunLightSpread.SpreadInChunk(chunk); } if (spreadList != null) { for (int i = 0; i < spreadList.Count; i++) { if (!list.Contains(spreadList[i])) { list.Add(spreadList[i]); } } } if (shrinkList != null) { for (int i = 0; i < shrinkList.Count; i++) { if (!list.Contains(shrinkList[i])) { list.Add(shrinkList[i]); } } } return(list); }