示例#1
0
        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);
        }
示例#2
0
        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());
                }
            }
        }
示例#3
0
        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);
        }
示例#4
0
        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);
                }
            }
        }
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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);
            }
        }
示例#9
0
        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;
        }
示例#10
0
        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);
        }
示例#11
0
        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);
            }
        }
示例#12
0
        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);
                    }
                }
            }
        }
示例#13
0
        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);
            }
        }
示例#14
0
        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);
        }
示例#15
0
 private void SetBlock(ChunkSubspacePosition position, BlockType type, bool triggerLightingUpdate)
 {
     SetBlock(position, BlockDefinition.DefinitionOfType(type), triggerLightingUpdate);
 }
示例#16
0
        public Block GetBlockAtPosition(BlockSpacePosition position)
        {
            ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(this);

            return(GetBlock(subspacePosition));
        }