Ejemplo n.º 1
0
        void GetRequiredBlocks(BlockPosition worldBlockPosition)
        {
            // We're putting in some work here to try to avoid loading the same blocks
            // multiple times for various faces of the block we're working on. This
            // is only useful for blocks where we're drawing multiple faces, which isn't
            // many of them relatively speaking. It's just barely worth the complexity.

            // TODO: depending on how things work out, it might be better to just do a
            // marching load of blocks along the z axis. That would be 9 blocks loaded
            // per tessellation, and we're currently doing ~7, but that could change as
            // we mess with the terrain and algorithms.

            // TODO: We can save a little time by getting the world
            // positions by relative arithmetic rather than direction chains.

            upBlock = world.GetBlockAt(worldBlockPosition.Up);
            if (upBlock.CanBeSeenThrough)
            {
                upFrontBlock = world.GetBlockAt(worldBlockPosition.Up.Front);
                upBackBlock = world.GetBlockAt(worldBlockPosition.Up.Back);
                upLeftFrontBlock = world.GetBlockAt(worldBlockPosition.Up.Left.Front);
                upLeftBlock = world.GetBlockAt(worldBlockPosition.Up.Left);
                upLeftBackBlock = world.GetBlockAt(worldBlockPosition.Up.Left.Back);
                upRightFrontBlock = world.GetBlockAt(worldBlockPosition.Up.Right.Front);
                upRightBlock = world.GetBlockAt(worldBlockPosition.Up.Right);
                upRightBackBlock = world.GetBlockAt(worldBlockPosition.Up.Right.Back);
            }
            else
            {
                upLeftBlock = null;
                upBackBlock = null;
                upLeftBackBlock = null;
                upRightBlock = null;
                upRightBackBlock = null;
                upFrontBlock = null;
                upRightFrontBlock = null;
                upLeftFrontBlock = null;
            }

            leftBlock = world.GetBlockAt(worldBlockPosition.Left);
            if (leftBlock.CanBeSeenThrough)
            {
                leftFrontBlock = world.GetBlockAt(worldBlockPosition.Left.Front);
                leftBackBlock = world.GetBlockAt(worldBlockPosition.Left.Back);
                leftUpFrontBlock = upLeftFrontBlock ?? world.GetBlockAt(worldBlockPosition.Left.Up.Front);
                leftUpBlock = upLeftBlock ?? world.GetBlockAt(worldBlockPosition.Left.Up);
                leftUpBackBlock = upLeftBackBlock ?? world.GetBlockAt(worldBlockPosition.Left.Up.Back);
                leftDownFrontBlock = world.GetBlockAt(worldBlockPosition.Left.Down.Front);
                leftDownBlock = world.GetBlockAt(worldBlockPosition.Left.Down);
                leftDownBackBlock = world.GetBlockAt(worldBlockPosition.Left.Down.Back);
            }
            else
            {
                leftUpBlock = null;
                leftBackBlock = null;
                leftUpBackBlock = null;
                leftFrontBlock = null;
                leftUpFrontBlock = null;
                leftDownBlock = null;
                leftDownFrontBlock = null;
                leftDownBackBlock = null;
            }

            rightBlock = world.GetBlockAt(worldBlockPosition.Right);
            if (rightBlock.CanBeSeenThrough)
            {
                rightFrontBlock = world.GetBlockAt(worldBlockPosition.Right.Front);
                rightBackBlock = world.GetBlockAt(worldBlockPosition.Right.Back);
                rightUpFrontBlock = upRightFrontBlock ?? world.GetBlockAt(worldBlockPosition.Right.Up.Front);
                rightUpBlock = upRightBlock ?? world.GetBlockAt(worldBlockPosition.Right.Up);
                rightUpBackBlock = upRightBackBlock ?? world.GetBlockAt(worldBlockPosition.Right.Up.Back);
                rightDownFrontBlock = world.GetBlockAt(worldBlockPosition.Right.Down.Front);
                rightDownBlock = world.GetBlockAt(worldBlockPosition.Right.Down);
                rightDownBackBlock = world.GetBlockAt(worldBlockPosition.Right.Down.Back);
            }
            else
            {
                rightUpBlock = null;
                rightFrontBlock = null;
                rightUpFrontBlock = null;
                rightBackBlock = null;
                rightUpBackBlock = null;
                rightDownBlock = null;
                rightDownBackBlock = null;
                rightDownFrontBlock = null;
            }

            backBlock = world.GetBlockAt(worldBlockPosition.Back);
            if (backBlock.CanBeSeenThrough)
            {
                backLeftBlock = leftBackBlock ?? world.GetBlockAt(worldBlockPosition.Back.Left);
                backRightBlock = rightBackBlock ?? world.GetBlockAt(worldBlockPosition.Back.Right);
                backUpLeftBlock = upLeftBackBlock ?? leftUpBackBlock ?? world.GetBlockAt(worldBlockPosition.Back.Up.Left);
                backUpBlock = upBackBlock ?? world.GetBlockAt(worldBlockPosition.Back.Up);
                backUpRightBlock = upRightBackBlock ?? rightUpBackBlock ?? world.GetBlockAt(worldBlockPosition.Back.Up.Right);
                backDownLeftBlock = leftDownBackBlock ?? world.GetBlockAt(worldBlockPosition.Back.Down.Left);
                backDownBlock = world.GetBlockAt(worldBlockPosition.Back.Down);
                backDownRightBlock = rightDownBackBlock ?? world.GetBlockAt(worldBlockPosition.Back.Down.Right);
            }
            else
            {
                backUpBlock = null;
                backRightBlock = null;
                backUpRightBlock = null;
                backLeftBlock = null;
                backUpLeftBlock = null;
                backDownBlock = null;
                backDownLeftBlock = null;
                backDownRightBlock = null;
            }

            frontBlock = world.GetBlockAt(worldBlockPosition.Front);
            if (frontBlock.CanBeSeenThrough)
            {
                frontLeftBlock = leftFrontBlock ?? world.GetBlockAt(worldBlockPosition.Front.Left);
                frontRightBlock = rightFrontBlock ?? world.GetBlockAt(worldBlockPosition.Front.Right);
                frontUpLeftBlock = upLeftFrontBlock ?? leftUpFrontBlock ?? world.GetBlockAt(worldBlockPosition.Front.Up.Left);
                frontUpBlock = upFrontBlock ?? world.GetBlockAt(worldBlockPosition.Front.Up);
                frontUpRightBlock = upRightFrontBlock ?? rightUpFrontBlock ?? world.GetBlockAt(worldBlockPosition.Front.Up.Right);
                frontDownLeftBlock = leftDownFrontBlock ?? world.GetBlockAt(worldBlockPosition.Front.Down.Left);
                frontDownBlock = world.GetBlockAt(worldBlockPosition.Front.Down);
                frontDownRightBlock = rightDownFrontBlock ?? world.GetBlockAt(worldBlockPosition.Front.Down.Right);
            }
            else
            {
                frontUpBlock = null;
                frontLeftBlock = null;
                frontUpLeftBlock = null;
                frontRightBlock = null;
                frontUpRightBlock = null;
                frontDownBlock = null;
                frontDownRightBlock = null;
                frontDownLeftBlock = null;
            }

            downBlock = world.GetBlockAt(worldBlockPosition.Down);
            if (downBlock.CanBeSeenThrough)
            {
                downFrontBlock = frontDownBlock ?? world.GetBlockAt(worldBlockPosition.Down.Front);
                downBackBlock = backDownBlock ?? world.GetBlockAt(worldBlockPosition.Down.Back);
                downLeftFrontBlock = leftDownFrontBlock ?? frontDownLeftBlock ?? world.GetBlockAt(worldBlockPosition.Down.Left.Front);
                downLeftBlock = leftDownBlock ?? world.GetBlockAt(worldBlockPosition.Down.Left);
                downLeftBackBlock = leftDownBackBlock ?? backDownLeftBlock ?? world.GetBlockAt(worldBlockPosition.Down.Left.Back);
                downRightFrontBlock = rightDownFrontBlock ?? frontDownRightBlock ?? world.GetBlockAt(worldBlockPosition.Down.Right.Front);
                downRightBlock = rightDownBlock ?? world.GetBlockAt(worldBlockPosition.Down.Right);
                downRightBackBlock = rightDownBackBlock ?? backDownRightBlock ?? world.GetBlockAt(worldBlockPosition.Down.Right.Back);
            }
            // Don't need to null these out because they're not used anywhere else
        }
Ejemplo n.º 2
0
        Vector3 AverageLightingOver(Block adjacent, Block edge1, Block edge2, Block diagonal, float limit)
        {
            // For each vertex we examine four voxels grouped around the vertex in the plane of the face that the vertex belongs to.
            // The voxels we're interested in for a particular vertex are:
            //   The voxel adjacent to the face we're calculating
            //   One voxel along the edge of the face we're calculating
            //   The other voxel along the edge of the face we're calculating
            //   The voxel diagonal to the face we're calculating

            float average;
            if (!edge1.CanPropagateLight && !edge2.CanPropagateLight)
            {
                // If the two edge voxels are not transparent then light can't get from the diagonal to the vertex we're calculating
                // so we don't include it in the average
                average = (adjacent.LightLevel + edge1.LightLevel + edge2.LightLevel) / 3f;
            }
            else
            {
                average = (adjacent.LightLevel + edge1.LightLevel + edge2.LightLevel + diagonal.LightLevel) / 4f;
            }

            var percentage = Math.Min(average / World.MaximumLightLevel, limit);

            return new Vector3(percentage);
        }