private void PullTransparencyCacheFromAdjacentBlocks(ChunkSubspacePosition position) { PullTransparencyCacheFromAdjacentBlock(position, -1, -1, -1); PullTransparencyCacheFromAdjacentBlock(position, 0, -1, -1); PullTransparencyCacheFromAdjacentBlock(position, 1, -1, -1); PullTransparencyCacheFromAdjacentBlock(position, -1, 0, -1); PullTransparencyCacheFromAdjacentBlock(position, 0, 0, -1); PullTransparencyCacheFromAdjacentBlock(position, 1, 0, -1); PullTransparencyCacheFromAdjacentBlock(position, -1, 1, -1); PullTransparencyCacheFromAdjacentBlock(position, 0, 1, -1); PullTransparencyCacheFromAdjacentBlock(position, 1, 1, -1); PullTransparencyCacheFromAdjacentBlock(position, -1, -1, 0); PullTransparencyCacheFromAdjacentBlock(position, 0, -1, 0); PullTransparencyCacheFromAdjacentBlock(position, 1, -1, 0); PullTransparencyCacheFromAdjacentBlock(position, -1, 0, 0); PullTransparencyCacheFromAdjacentBlock(position, 1, 0, 0); PullTransparencyCacheFromAdjacentBlock(position, -1, 1, 0); PullTransparencyCacheFromAdjacentBlock(position, 0, 1, 0); PullTransparencyCacheFromAdjacentBlock(position, 1, 1, 0); PullTransparencyCacheFromAdjacentBlock(position, -1, -1, 1); PullTransparencyCacheFromAdjacentBlock(position, 0, -1, 1); PullTransparencyCacheFromAdjacentBlock(position, 1, -1, 1); PullTransparencyCacheFromAdjacentBlock(position, -1, 0, 1); PullTransparencyCacheFromAdjacentBlock(position, 0, 0, 1); PullTransparencyCacheFromAdjacentBlock(position, 1, 0, 1); PullTransparencyCacheFromAdjacentBlock(position, -1, 1, 1); PullTransparencyCacheFromAdjacentBlock(position, 0, 1, 1); PullTransparencyCacheFromAdjacentBlock(position, 1, 1, 1); }
private void PullTransparencyCacheFromAdjacentBlock(ChunkSubspacePosition position, int xOffset, int yOffset, int zOffset) { ChunkSubspacePosition checkPosition; checkPosition = position; checkPosition.x += xOffset; checkPosition.y += yOffset; checkPosition.z += zOffset; if (checkPosition.x >= 0 && checkPosition.x < SIZE && checkPosition.y >= 0 && checkPosition.y < SIZE && checkPosition.z >= 0 && checkPosition.z < SIZE) { SetAdjacentBlockTransparentFlag(position, xOffset, yOffset, zOffset, GetBlock(checkPosition).IsTransparent()); } else { BlockSpacePosition blockPosition = checkPosition.GetBlockSpacePosition(this); Chunk otherChunk = ChunkRepository.GetChunkAtPosition(blockPosition); if (otherChunk != null) { ChunkSubspacePosition otherChunkPosition = blockPosition.GetChunkSubspacePosition(otherChunk); SetAdjacentBlockTransparentFlag(position, xOffset, yOffset, zOffset, otherChunk.GetBlock(otherChunkPosition).IsTransparent()); } } }
private void PushTransparencyCacheToAdjacentBlocks(ChunkSubspacePosition position, bool transparent) { PushTransparencyCacheToAdjacentBlock(position, -1, -1, -1, transparent); PushTransparencyCacheToAdjacentBlock(position, 0, -1, -1, transparent); PushTransparencyCacheToAdjacentBlock(position, 1, -1, -1, transparent); PushTransparencyCacheToAdjacentBlock(position, -1, 0, -1, transparent); PushTransparencyCacheToAdjacentBlock(position, 0, 0, -1, transparent); PushTransparencyCacheToAdjacentBlock(position, 1, 0, -1, transparent); PushTransparencyCacheToAdjacentBlock(position, -1, 1, -1, transparent); PushTransparencyCacheToAdjacentBlock(position, 0, 1, -1, transparent); PushTransparencyCacheToAdjacentBlock(position, 1, 1, -1, transparent); PushTransparencyCacheToAdjacentBlock(position, -1, -1, 0, transparent); PushTransparencyCacheToAdjacentBlock(position, 0, -1, 0, transparent); PushTransparencyCacheToAdjacentBlock(position, 1, -1, 0, transparent); PushTransparencyCacheToAdjacentBlock(position, -1, 0, 0, transparent); PushTransparencyCacheToAdjacentBlock(position, 1, 0, 0, transparent); PushTransparencyCacheToAdjacentBlock(position, -1, 1, 0, transparent); PushTransparencyCacheToAdjacentBlock(position, 0, 1, 0, transparent); PushTransparencyCacheToAdjacentBlock(position, 1, 1, 0, transparent); PushTransparencyCacheToAdjacentBlock(position, -1, -1, 1, transparent); PushTransparencyCacheToAdjacentBlock(position, 0, -1, 1, transparent); PushTransparencyCacheToAdjacentBlock(position, 1, -1, 1, transparent); PushTransparencyCacheToAdjacentBlock(position, -1, 0, 1, transparent); PushTransparencyCacheToAdjacentBlock(position, 0, 0, 1, transparent); PushTransparencyCacheToAdjacentBlock(position, 1, 0, 1, transparent); PushTransparencyCacheToAdjacentBlock(position, -1, 1, 1, transparent); PushTransparencyCacheToAdjacentBlock(position, 0, 1, 1, transparent); PushTransparencyCacheToAdjacentBlock(position, 1, 1, 1, transparent); }
private void PushTransparencyCacheToAdjacentBlock(ChunkSubspacePosition position, int xOffset, int yOffset, int zOffset, bool transparent) { position.x += xOffset; position.y += yOffset; position.z += zOffset; if (position.x >= 0 && position.x < SIZE && position.y >= 0 && position.y < SIZE && position.z >= 0 && position.z < SIZE) { SetAdjacentBlockTransparentFlag(position, -xOffset, -yOffset, -zOffset, transparent); } else { BlockSpacePosition blockPosition = position.GetBlockSpacePosition(this); Chunk otherChunk = ChunkRepository.GetChunkAtPosition(blockPosition); if (otherChunk != null) { ChunkSubspacePosition otherChunkPosition = blockPosition.GetChunkSubspacePosition(otherChunk); otherChunk.SetAdjacentBlockTransparentFlag(otherChunkPosition, -xOffset, -yOffset, -zOffset, transparent); } } }
public void RemoveBlockAtPosition(BlockSpacePosition position, RemoveBlockCallback callback) { ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(this); if (subspacePosition.x < 0 || subspacePosition.y < 0 || subspacePosition.z < 0 || subspacePosition.x >= SIZE || subspacePosition.y >= SIZE || subspacePosition.z >= SIZE) { return; } Block block = GetBlock(subspacePosition); if (block.IsBedrock()) { // Bedrock is a special case - it can't be removed return; } if (callback != null) { callback(position, block); } SetBlock(subspacePosition, BlockType.Air, true); }
public ChunkBlockPair GetBlockAtPosition(BlockSpacePosition position, Chunk hintChunk) { if (hintChunk == null) { return(GetBlockAtPosition(position)); } ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(hintChunk); if (subspacePosition.x < 0 || subspacePosition.y < 0 || subspacePosition.z < 0 || subspacePosition.x >= Chunk.SIZE || subspacePosition.y >= Chunk.SIZE || subspacePosition.z >= Chunk.SIZE) { return(GetBlockAtPosition(position)); } ChunkBlockPair returnPair; returnPair.block = hintChunk.GetBlock(subspacePosition); returnPair.chunk = hintChunk; return(returnPair); }
public void SetBlockAtPosition(BlockSpacePosition position, BlockType type, bool triggerLightingUpdate) { if (type == BlockType.Air) { throw new Exception("Can not use SetBlockAtPosition to set a block to air. Rather, use " + "RemoveBlockAtPosition for this purpose."); } ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(this); SetBlock(subspacePosition, type, triggerLightingUpdate); }
public void QueueAdjacentBlockTransparencyModification(ChunkSubspacePosition position, int xOffset, int yOffset, int zOffset, bool transparent) { AdjacentTransparencyModification modification; modification.position = position; modification.xOffset = xOffset; modification.yOffset = yOffset; modification.zOffset = zOffset; modification.transparent = transparent; lock (adjacentTransparencyModificationList) { adjacentTransparencyModificationList.Enqueue(modification); } }
private void FlushBlockRemoval(ChunkSubspacePosition position, BlockDefinition definition, BlockDefinition prevDefinition) { PushTransparencyCacheToAdjacentBlocks(position, definition.IsTransparent()); if (prevDefinition.IsLightEmitter()) { BlockLight light; light.chunk = this; light.chunkPosition = position; light.blockDefinition = prevDefinition; lights.Remove(light); } needsMeshUpdate = true; }
public Block GetBlock(ChunkSubspacePosition position) { #if DEBUG if (position.x < 0) { UnityEngine.Debug.LogWarning(String.Format("Chunk.GetBlock - X is below 0: {0}", position.x)); } else if (position.x >= SIZE) { UnityEngine.Debug.LogWarning(String.Format("Chunk.GetBlock - X is above max: {0}", position.x)); } if (position.y < 0) { UnityEngine.Debug.LogWarning("Chunk.GetBlock - Y is below 0."); } else if (position.y >= SIZE) { UnityEngine.Debug.LogWarning("Chunk.GetBlock - Y is above max."); } if (position.z < 0) { UnityEngine.Debug.LogWarning(String.Format("Chunk.GetBlock - Z is below 0: {0}", position.z)); } else if (position.z >= SIZE) { UnityEngine.Debug.LogWarning(String.Format("Chunk.GetBlock - Z is above max: {0}", position.z)); } #endif Block returnBlock; lock (padlock) { if (position.x < 0 || position.x >= SIZE || position.y < 0 || position.y >= SIZE || position.z < 0 || position.z >= SIZE) { return(Block.EmptyBlock()); } returnBlock = blocks[position.x, position.y, position.z]; } return(returnBlock); }
private void FlushBlockSet(ChunkSubspacePosition position, BlockDefinition definition, BlockDefinition prevDefinition) { if (prevDefinition.IsTransparent() != definition.IsTransparent()) { PushTransparencyCacheToAdjacentBlocks(position, definition.IsTransparent()); } MarkForMeshUpdate(); if (definition.IsLightEmitter()) { BlockLight light; light.chunk = this; light.chunkPosition = position; light.blockDefinition = definition; lights.Add(light); } }
private void SetBlock(ChunkSubspacePosition position, BlockDefinition definition, bool triggerLightingUpdate) { lock (padlock) { if (position.x < 0 || position.x >= SIZE || position.y < 0 || position.y >= SIZE || position.z < 0 || position.z >= SIZE) { return; } if (triggerLightingUpdate) { BlockSpacePosition blockPosition = position.GetBlockSpacePosition(this); RenderService.MarkChunksWithinMaxLightRadiusForMeshUpdate(blockPosition); } else { PutInChunkProcessingList(); } dirty = true; if (MeshGenerationIsInProgress()) { BlockModification modification; modification.position = position; modification.definition = definition; modificationList.Enqueue(modification); } else { BlockDefinition prevDefinition; prevDefinition = blocks[position.x, position.y, position.z].GetDefinition(); blocks[position.x, position.y, position.z].Set(definition); if (definition.IsActive() == false) { FlushBlockRemoval(position, definition, prevDefinition); } else { FlushBlockSet(position, definition, prevDefinition); } } } }
private void SetAdjacentBlockTransparentFlag(ChunkSubspacePosition position, int xOffset, int yOffset, int zOffset, bool transparent) { if (position.x < 0 || position.x >= SIZE || position.y < 0 || position.y >= SIZE || position.z < 0 || position.z >= SIZE) { return; } PutInChunkProcessingList(); if (Monitor.TryEnter(padlock)) { blocks[position.x, position.y, position.z] .SetAdjacentBlockTransparentFlag(xOffset, yOffset, zOffset, transparent); Monitor.Exit(padlock); } else { // Else, could not get the lock - queue to try again later QueueAdjacentBlockTransparencyModification(position, xOffset, yOffset, zOffset, transparent); } }
void GenerateBlocksThread(object chunkInstance) { Chunk chunk = chunkInstance as Chunk; ChunkSubspacePosition position; BlockSpacePosition checkPosition; for (position.x = 0; position.x < SIZE; position.x++) { checkPosition.x = worldPosition.x * SIZE + position.x; for (position.z = 0; position.z < SIZE; position.z++) { checkPosition.z = worldPosition.z * SIZE + position.z; isShorelineCache[position.x, position.z] = true; for (position.y = worldPosition.y * SIZE + SIZE; position.y < Configuration.HEIGHT; position.y++) { checkPosition.y = position.y; Block checkBlock = ChunkRepository.GetBlockAtPosition(checkPosition); if (checkBlock.IsActive() && checkBlock.IsNotTransparent()) { isShorelineCache[position.x, position.z] = false; break; } } } } BlockType[,,] blockTypes = worldGenerator.GenerateBlocks(chunk); for (position.x = 0; position.x < SIZE; position.x++) { for (position.y = 0; position.y < SIZE; position.y++) { for (position.z = 0; position.z < SIZE; position.z++) { BlockDefinition blockDefinition = BlockDefinition.DefinitionOfType(blockTypes[position.x, position.y, position.z]); chunk.SetBlock(position, blockDefinition, false); if (blockDefinition.IsActive() && blockDefinition.IsNotTransparent() && blockDefinition.GetBlockType() != BlockType.Sand) { isShorelineCache[position.x, position.z] = false; } if (blockDefinition.IsLightEmitter()) { BlockLight light; light.chunk = this; light.chunkPosition = position; light.blockDefinition = blockDefinition; lock (chunk.padlock) { chunk.lights.Add(light); } } } } } // Generate and apply the models from this and all nearby chunks List <Model> generatedModels = worldGenerator.GenerateModels(chunk); lock (generatingModelsLock) { for (int i = 0; i < generatedModels.Count; i++) { AddModel(generatedModels[i]); } } List <Chunk> lockedChunks = LockNearbyChunkModels(); ApplyModels(); UnlockChunkModels(lockedChunks); // Cleanup pass for (position.x = 0; position.x < SIZE; position.x++) { for (position.z = 0; position.z < SIZE; position.z++) { for (position.y = SIZE - 1; position.y >= 0; position.y--) { chunk.GetBlock(position); // If the block is water, make sure it's surrounded on the bottom and sides if (chunk.GetBlock(position).IsWater()) { for (int i = 0; i < 5; i++) { ChunkSubspacePosition solidCheckPosition = position; if (i == 0) { solidCheckPosition.y -= 1; } else if (i == 1) { solidCheckPosition.x -= 1; } else if (i == 2) { solidCheckPosition.x += 1; } else if (i == 3) { solidCheckPosition.z -= 1; } else if (i == 4) { solidCheckPosition.z += 1; } if (solidCheckPosition.x >= 0 && solidCheckPosition.x < SIZE && solidCheckPosition.y >= 0 && solidCheckPosition.y < SIZE && solidCheckPosition.z >= 0 && solidCheckPosition.z < SIZE) { if (chunk.GetBlock(solidCheckPosition).IsNotActive()) { chunk.SetBlock(solidCheckPosition, BlockType.Stone, false); } } else { BlockSpacePosition checkWorldPosition = solidCheckPosition.GetBlockSpacePosition(chunk); if (ChunkRepository.GetBlockAtPosition(checkWorldPosition).IsNotActive()) { ChunkRepository.SetBlockAtPosition(checkWorldPosition, BlockType.Stone, false); } } } } } } } LoadTransparencyCache(); chunk.SetLoadState(ChunkLoadState.BlockGenerationComplete); }
private void SetBlock(ChunkSubspacePosition position, BlockType type, bool triggerLightingUpdate) { SetBlock(position, BlockDefinition.DefinitionOfType(type), triggerLightingUpdate); }
public Block GetBlockAtPosition(BlockSpacePosition position) { ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(this); return(GetBlock(subspacePosition)); }