예제 #1
0
        private static void FluidFillSunLight(Chunk chunk)
        {
            for (byte x = 0; x < Chunk.WidthInBlocks; x++)
            {
                for (byte z = 0; z < Chunk.LengthInBlocks; z++)
                {
                    int offset = BlockStorage.BlockIndexByRelativePosition(chunk, x, z);

                    for (byte y = Chunk.MaxHeightIndexInBlocks; y > 0; y--)
                    {
                        var blockIndex = offset + y;

                        if (BlockStorage.Blocks[blockIndex].Type != BlockType.None) // solid blocks can't propagate light.
                        {
                            continue;
                        }

                        var blockLight = BlockStorage.Blocks[blockIndex].Sun;
                        if (blockLight <= 1) // if block's light value is too low (dark),
                        {
                            continue;        // just skip it.
                        }
                        var propagatedLight = (byte)((blockLight * 9) / 10);

                        PropagateSunLight(blockIndex + BlockStorage.XStep, propagatedLight); // propagate light to block in east.
                        PropagateSunLight(blockIndex - BlockStorage.XStep, propagatedLight); // propagate light to block in west.
                        PropagateSunLight(blockIndex + BlockStorage.ZStep, propagatedLight); // propagate light to block in north.
                        PropagateSunLight(blockIndex - BlockStorage.ZStep, propagatedLight); // propagate light to block in south.
                        // DO NOT repropagete to upper block which we don't need to do so and may cause loops!
                        PropagateSunLight(blockIndex - 1, propagatedLight);                  // propagate light to block down.
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Clears all lighting and then applies sun-lighting.
        /// </summary>
        /// <param name="chunk"></param>
        private static void SetInitialLighting(Chunk chunk)
        {
            byte sunValue = Chunk.MaxSunValue;

            for (byte x = 0; x < Chunk.WidthInBlocks; x++)
            {
                for (byte z = 0; z < Chunk.LengthInBlocks; z++)
                {
                    int  offset  = BlockStorage.BlockIndexByRelativePosition(chunk, x, z);
                    bool inShade = false; // if we get direct sunlight, inShade will be set to false.

                    for (byte y = Chunk.MaxHeightIndexInBlocks; y > 0; y--)
                    {
                        if (!inShade && BlockStorage.Blocks[offset + y].Type != BlockType.None) // if we're under direct sunlight and just hit a solid block.
                        {
                            inShade = true;                                                     // set inShade to true;
                        }
                        BlockStorage.Blocks[offset + y].Sun = inShade ? (byte)0 : sunValue;
                        BlockStorage.Blocks[offset + y].R   = 0;
                        BlockStorage.Blocks[offset + y].G   = 0;
                        BlockStorage.Blocks[offset + y].B   = 0;
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Builds vertex list for chunk.
        /// </summary>
        /// <param name="chunk"></param>
        private void BuildVertexList(Chunk chunk)
        {
            if (chunk.Disposed)
            {
                return;
            }

            Clear(chunk);

            for (byte x = 0; x < Chunk.WidthInBlocks; x++)
            {
                for (byte z = 0; z < Chunk.LenghtInBlocks; z++)
                {
                    int offset = BlockStorage.BlockIndexByRelativePosition(chunk, x, z);

                    for (byte y = chunk.LowestEmptyBlockOffset; y < chunk.HighestSolidBlockOffset; y++)
                    {
                        var blockIndex = offset + y;

                        var block = BlockStorage.Blocks[blockIndex];

                        if (block.Type == BlockType.None)
                        {
                            continue;
                        }

                        var position = new Vector3Int(chunk.WorldPosition.X + x, y, chunk.WorldPosition.Z + z);
                        this.BuildBlockVertices(chunk, blockIndex, position);
                    }
                }
            }

            var vertices = chunk.VertexList.ToArray();
            var indices  = chunk.IndexList.ToArray();

            if (vertices.Length == 0 || indices.Length == 0)
            {
                return;
            }

            chunk.VertexBuffer = new VertexBuffer(this.Game.GraphicsDevice, typeof(BlockVertex), vertices.Length, BufferUsage.WriteOnly);
            chunk.VertexBuffer.SetData(vertices);

            chunk.IndexBuffer = new IndexBuffer(this.Game.GraphicsDevice, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly);
            chunk.IndexBuffer.SetData(indices);
        }