Beispiel #1
0
        /// <summary>
        /// Adds face data to an internal list.
        /// </summary>
        /// <param name="list">The list of face data.</param>
        /// <param name="center">The center of the current block.</param>
        /// <param name="face">The current block face.</param>
        /// <param name="type">The current block type.</param>
        /// <param name="lighting">The face's lighting information.</param>
        public void AddFaceData( Vector3 center, BlockFace face, BlockType type, BlockFaceLighting lighting )
        {
            // set texture coordinate info
            var texSize = SpriteSheet.Instance.TexCoordSize;
            var typeInfo = BlockTypeInfo.Find( type );
            switch ( face )
            {
                case BlockFace.Back:
                case BlockFace.Front:
                case BlockFace.Left:
                case BlockFace.Right:
                    _tcTL = typeInfo.SideTextureCoordinate;
                    break;
                case BlockFace.Bottom:
                    _tcTL = typeInfo.BottomTextureCoordinate;
                    break;
                case BlockFace.Top:
                    _tcTL = typeInfo.TopTextureCoordinate;
                    break;
            }
            _tcTR.X = _tcTL.X + texSize.X;
            _tcTR.Y = _tcTL.Y;
            _tcBL.X = _tcTL.X;
            _tcBL.Y = _tcTL.Y + texSize.Y;
            _tcBR.X = _tcTL.X + texSize.X;
            _tcBR.Y = _tcTL.Y + texSize.Y;

            // now add to the vertex list
            switch ( face )
            {
                case BlockFace.Front:
                    _vertices.Add( new BlockVertex( center + _vTLF, Vector3.Forward, _tcTL, lighting.UpperLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBLF, Vector3.Forward, _tcBL, lighting.LowerLeft ) );
                    _vertices.Add( new BlockVertex( center + _vTRF, Vector3.Forward, _tcTR, lighting.UpperRight ) );
                    _vertices.Add( new BlockVertex( center + _vBLF, Vector3.Forward, _tcBL, lighting.LowerLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBRF, Vector3.Forward, _tcBR, lighting.LowerRight ) );
                    _vertices.Add( new BlockVertex( center + _vTRF, Vector3.Forward, _tcTR, lighting.UpperRight ) );
                    break;
                case BlockFace.Back:
                    _vertices.Add( new BlockVertex( center + _vTLB, Vector3.Backward, _tcTR, lighting.UpperRight ) );
                    _vertices.Add( new BlockVertex( center + _vTRB, Vector3.Backward, _tcTL, lighting.UpperLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBLB, Vector3.Backward, _tcBR, lighting.LowerRight ) );
                    _vertices.Add( new BlockVertex( center + _vBLB, Vector3.Backward, _tcBR, lighting.LowerRight ) );
                    _vertices.Add( new BlockVertex( center + _vTRB, Vector3.Backward, _tcTL, lighting.UpperLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBRB, Vector3.Backward, _tcBL, lighting.LowerLeft ) );
                    break;
                case BlockFace.Top:
                    _vertices.Add( new BlockVertex( center + _vTLF, Vector3.Up, _tcBL, lighting.LowerLeft ) );
                    _vertices.Add( new BlockVertex( center + _vTRB, Vector3.Up, _tcTR, lighting.UpperRight ) );
                    _vertices.Add( new BlockVertex( center + _vTLB, Vector3.Up, _tcTL, lighting.UpperLeft ) );
                    _vertices.Add( new BlockVertex( center + _vTLF, Vector3.Up, _tcBL, lighting.LowerLeft ) );
                    _vertices.Add( new BlockVertex( center + _vTRF, Vector3.Up, _tcBR, lighting.LowerRight ) );
                    _vertices.Add( new BlockVertex( center + _vTRB, Vector3.Up, _tcTR, lighting.UpperRight ) );
                    break;
                case BlockFace.Bottom:
                    _vertices.Add( new BlockVertex( center + _vBLF, Vector3.Down, _tcTL, lighting.UpperLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBLB, Vector3.Down, _tcBL, lighting.LowerLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBRB, Vector3.Down, _tcBR, lighting.LowerRight ) );
                    _vertices.Add( new BlockVertex( center + _vBLF, Vector3.Down, _tcTL, lighting.UpperLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBRB, Vector3.Down, _tcBR, lighting.LowerRight ) );
                    _vertices.Add( new BlockVertex( center + _vBRF, Vector3.Down, _tcTR, lighting.UpperRight ) );
                    break;
                case BlockFace.Left:
                    _vertices.Add( new BlockVertex( center + _vTLF, Vector3.Left, _tcTR, lighting.UpperRight ) );
                    _vertices.Add( new BlockVertex( center + _vBLB, Vector3.Left, _tcBL, lighting.LowerLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBLF, Vector3.Left, _tcBR, lighting.LowerRight ) );
                    _vertices.Add( new BlockVertex( center + _vTLB, Vector3.Left, _tcTL, lighting.UpperLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBLB, Vector3.Left, _tcBL, lighting.LowerLeft ) );
                    _vertices.Add( new BlockVertex( center + _vTLF, Vector3.Left, _tcTR, lighting.UpperRight ) );
                    break;
                case BlockFace.Right:
                    _vertices.Add( new BlockVertex( center + _vTRF, Vector3.Right, _tcTL, lighting.UpperLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBRF, Vector3.Right, _tcBL, lighting.LowerLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBRB, Vector3.Right, _tcBR, lighting.LowerRight ) );
                    _vertices.Add( new BlockVertex( center + _vTRB, Vector3.Right, _tcTR, lighting.UpperRight ) );
                    _vertices.Add( new BlockVertex( center + _vTRF, Vector3.Right, _tcTL, lighting.UpperLeft ) );
                    _vertices.Add( new BlockVertex( center + _vBRB, Vector3.Right, _tcBR, lighting.LowerRight ) );
                    break;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Adds face data to an internal list.
        /// </summary>
        /// <param name="list">The list of face data.</param>
        /// <param name="center">The center of the current block.</param>
        /// <param name="face">The current block face.</param>
        /// <param name="type">The current block type.</param>
        /// <param name="lighting">The face's lighting information.</param>
        public void AddFaceData(Vector3 center, BlockFace face, BlockType type, BlockFaceLighting lighting)
        {
            // set texture coordinate info
            var texSize  = SpriteSheet.Instance.TexCoordSize;
            var typeInfo = BlockTypeInfo.Find(type);

            switch (face)
            {
            case BlockFace.Back:
            case BlockFace.Front:
            case BlockFace.Left:
            case BlockFace.Right:
                _tcTL = typeInfo.SideTextureCoordinate;
                break;

            case BlockFace.Bottom:
                _tcTL = typeInfo.BottomTextureCoordinate;
                break;

            case BlockFace.Top:
                _tcTL = typeInfo.TopTextureCoordinate;
                break;
            }
            _tcTR.X = _tcTL.X + texSize.X;
            _tcTR.Y = _tcTL.Y;
            _tcBL.X = _tcTL.X;
            _tcBL.Y = _tcTL.Y + texSize.Y;
            _tcBR.X = _tcTL.X + texSize.X;
            _tcBR.Y = _tcTL.Y + texSize.Y;

            // now add to the vertex list
            switch (face)
            {
            case BlockFace.Front:
                _vertices.Add(new BlockVertex(center + _vTLF, Vector3.Forward, _tcTL, lighting.UpperLeft));
                _vertices.Add(new BlockVertex(center + _vBLF, Vector3.Forward, _tcBL, lighting.LowerLeft));
                _vertices.Add(new BlockVertex(center + _vTRF, Vector3.Forward, _tcTR, lighting.UpperRight));
                _vertices.Add(new BlockVertex(center + _vBLF, Vector3.Forward, _tcBL, lighting.LowerLeft));
                _vertices.Add(new BlockVertex(center + _vBRF, Vector3.Forward, _tcBR, lighting.LowerRight));
                _vertices.Add(new BlockVertex(center + _vTRF, Vector3.Forward, _tcTR, lighting.UpperRight));
                break;

            case BlockFace.Back:
                _vertices.Add(new BlockVertex(center + _vTLB, Vector3.Backward, _tcTR, lighting.UpperRight));
                _vertices.Add(new BlockVertex(center + _vTRB, Vector3.Backward, _tcTL, lighting.UpperLeft));
                _vertices.Add(new BlockVertex(center + _vBLB, Vector3.Backward, _tcBR, lighting.LowerRight));
                _vertices.Add(new BlockVertex(center + _vBLB, Vector3.Backward, _tcBR, lighting.LowerRight));
                _vertices.Add(new BlockVertex(center + _vTRB, Vector3.Backward, _tcTL, lighting.UpperLeft));
                _vertices.Add(new BlockVertex(center + _vBRB, Vector3.Backward, _tcBL, lighting.LowerLeft));
                break;

            case BlockFace.Top:
                _vertices.Add(new BlockVertex(center + _vTLF, Vector3.Up, _tcBL, lighting.LowerLeft));
                _vertices.Add(new BlockVertex(center + _vTRB, Vector3.Up, _tcTR, lighting.UpperRight));
                _vertices.Add(new BlockVertex(center + _vTLB, Vector3.Up, _tcTL, lighting.UpperLeft));
                _vertices.Add(new BlockVertex(center + _vTLF, Vector3.Up, _tcBL, lighting.LowerLeft));
                _vertices.Add(new BlockVertex(center + _vTRF, Vector3.Up, _tcBR, lighting.LowerRight));
                _vertices.Add(new BlockVertex(center + _vTRB, Vector3.Up, _tcTR, lighting.UpperRight));
                break;

            case BlockFace.Bottom:
                _vertices.Add(new BlockVertex(center + _vBLF, Vector3.Down, _tcTL, lighting.UpperLeft));
                _vertices.Add(new BlockVertex(center + _vBLB, Vector3.Down, _tcBL, lighting.LowerLeft));
                _vertices.Add(new BlockVertex(center + _vBRB, Vector3.Down, _tcBR, lighting.LowerRight));
                _vertices.Add(new BlockVertex(center + _vBLF, Vector3.Down, _tcTL, lighting.UpperLeft));
                _vertices.Add(new BlockVertex(center + _vBRB, Vector3.Down, _tcBR, lighting.LowerRight));
                _vertices.Add(new BlockVertex(center + _vBRF, Vector3.Down, _tcTR, lighting.UpperRight));
                break;

            case BlockFace.Left:
                _vertices.Add(new BlockVertex(center + _vTLF, Vector3.Left, _tcTR, lighting.UpperRight));
                _vertices.Add(new BlockVertex(center + _vBLB, Vector3.Left, _tcBL, lighting.LowerLeft));
                _vertices.Add(new BlockVertex(center + _vBLF, Vector3.Left, _tcBR, lighting.LowerRight));
                _vertices.Add(new BlockVertex(center + _vTLB, Vector3.Left, _tcTL, lighting.UpperLeft));
                _vertices.Add(new BlockVertex(center + _vBLB, Vector3.Left, _tcBL, lighting.LowerLeft));
                _vertices.Add(new BlockVertex(center + _vTLF, Vector3.Left, _tcTR, lighting.UpperRight));
                break;

            case BlockFace.Right:
                _vertices.Add(new BlockVertex(center + _vTRF, Vector3.Right, _tcTL, lighting.UpperLeft));
                _vertices.Add(new BlockVertex(center + _vBRF, Vector3.Right, _tcBL, lighting.LowerLeft));
                _vertices.Add(new BlockVertex(center + _vBRB, Vector3.Right, _tcBR, lighting.LowerRight));
                _vertices.Add(new BlockVertex(center + _vTRB, Vector3.Right, _tcTR, lighting.UpperRight));
                _vertices.Add(new BlockVertex(center + _vTRF, Vector3.Right, _tcTL, lighting.UpperLeft));
                _vertices.Add(new BlockVertex(center + _vBRB, Vector3.Right, _tcBR, lighting.LowerRight));
                break;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Builds the voxel buffer without locking the chunk data.
        /// </summary>
        /// <param name="needToSetCurrentChunk">True if we need to set this chunk as the current chunk for the terrain, false if not.</param>
        private void BuildVoxelBufferNoLockData( bool needToSetCurrentChunk )
        {
            Profiler.Start( "Voxel Buffer Building" );

            lock ( _chunkBuilder )
            {
                _chunkBuilder.Reset();

                // get the terrain
                var terrain = Terrain.Instance;
                if ( needToSetCurrentChunk )
                {
                    terrain.SetCurrentChunk( this );
                }

                // go through for each terrain block
                var temp = new Block();
                var tempBounds = new BoundingBox();
                var blockCenter = new Vector3();
                var useSmoothLighting = Game.Instance.Settings.SmoothLighting;
                for ( int x = 0; x < ChunkData.SizeXZ; ++x )
                {
                    for ( int z = 0; z < ChunkData.SizeXZ; ++z )
                    {
                        var lighting = new BlockFaceLighting( Block.MaximumLighting );

                        for ( int y = ChunkData.SizeY - 1; y >= 0; --y )
                        {
                            // get block info
                            var block = _data[ x, y, z ];
                            var exposed = false;
                            if ( block.TypeInfo.IsEmpty )
                            {
                                continue;
                            }

                            // get the block's and center
                            Position.LocalToWorld( _data.Index, x, y, z, out blockCenter );

                            // get surrounding block light level
                            // TODO : We don't need to get a lot of these if smooth lighting is disabled
                            var right            = GetLightFromBlock( terrain, x + 1, y,     z     );
                            var rightTop         = GetLightFromBlock( terrain, x + 1, y + 1, z     );
                            var rightBottom      = GetLightFromBlock( terrain, x + 1, y - 1, z     );
                            var left             = GetLightFromBlock( terrain, x - 1, y,     z     );
                            var leftTop          = GetLightFromBlock( terrain, x - 1, y + 1, z     );
                            var leftBottom       = GetLightFromBlock( terrain, x - 1, y - 1, z     );
                            var back             = GetLightFromBlock( terrain, x,     y,     z + 1 );
                            var backLeft         = GetLightFromBlock( terrain, x - 1, y,     z + 1 );
                            var backRight        = GetLightFromBlock( terrain, x + 1, y,     z + 1 );
                            var backTop          = GetLightFromBlock( terrain, x,     y + 1, z + 1 );
                            var backTopLeft      = GetLightFromBlock( terrain, x - 1, y + 1, z + 1 );
                            var backTopRight     = GetLightFromBlock( terrain, x + 1, y + 1, z + 1 );
                            var backBottom       = GetLightFromBlock( terrain, x,     y - 1, z + 1 );
                            var backBottomLeft   = GetLightFromBlock( terrain, x - 1, y - 1, z + 1 );
                            var backBottomRight  = GetLightFromBlock( terrain, x + 1, y - 1, z + 1 );
                            var front            = GetLightFromBlock( terrain, x,     y,     z - 1 );
                            var frontLeft        = GetLightFromBlock( terrain, x - 1, y,     z - 1 );
                            var frontRight       = GetLightFromBlock( terrain, x + 1, y,     z - 1 );
                            var frontTop         = GetLightFromBlock( terrain, x,     y + 1, z - 1 );
                            var frontTopLeft     = GetLightFromBlock( terrain, x - 1, y + 1, z - 1 );
                            var frontTopRight    = GetLightFromBlock( terrain, x + 1, y + 1, z - 1 );
                            var frontBottom      = GetLightFromBlock( terrain, x,     y - 1, z - 1 );
                            var frontBottomLeft  = GetLightFromBlock( terrain, x - 1, y - 1, z - 1 );
                            var frontBottomRight = GetLightFromBlock( terrain, x + 1, y - 1, z - 1 );
                            var top              = GetLightFromBlock( terrain, x,     y + 1, z     );
                            var bottom           = GetLightFromBlock( terrain, x,     y - 1, z     );

                            // check to the right
                            temp.Type = terrain.Query( x + 1, y, z );
                            if ( temp.TypeInfo.IsEmpty )
                            {
                                lighting = new BlockFaceLighting( right );

                                // calculate smooth lighting
                                if ( useSmoothLighting )
                                {
                                    lighting.LowerLeft  = 0.25f * ( right + rightBottom + frontBottomRight + frontRight );
                                    lighting.LowerRight = 0.25f * ( right + rightBottom + backBottomRight  + backRight  );
                                    lighting.UpperRight = 0.25f * ( right + rightTop    + backTopRight     + backRight  );
                                    lighting.UpperLeft  = 0.25f * ( right + rightTop    + frontTopRight    + frontRight );
                                }

                                _chunkBuilder.AddFaceData( blockCenter, BlockFace.Right, block.Type, lighting );
                                exposed = true;
                            }

                            // check to the left
                            temp.Type = terrain.Query( x - 1, y, z );
                            if ( temp.TypeInfo.IsEmpty )
                            {
                                lighting = new BlockFaceLighting( left );

                                // calculate smooth lighting
                                if ( useSmoothLighting )
                                {
                                    lighting.LowerLeft  = 0.25f * ( left + leftBottom + backBottomLeft  + backLeft  );
                                    lighting.LowerRight = 0.25f * ( left + leftBottom + frontBottomLeft + frontLeft );
                                    lighting.UpperRight = 0.25f * ( left + leftTop    + frontTopLeft    + frontLeft );
                                    lighting.UpperLeft  = 0.25f * ( left + leftTop    + backTopLeft     + backLeft  );
                                }

                                _chunkBuilder.AddFaceData( blockCenter, BlockFace.Left, block.Type, lighting );
                                exposed = true;
                            }

                            // check in back
                            temp.Type = terrain.Query( x, y, z + 1 );
                            if ( temp.TypeInfo.IsEmpty )
                            {
                                lighting = new BlockFaceLighting( back );

                                // calculate smooth lighting
                                if ( useSmoothLighting )
                                {
                                    lighting.LowerLeft  = 0.25f * ( back + backBottom + backBottomRight + backRight );
                                    lighting.LowerRight = 0.25f * ( back + backBottom + backBottomLeft  + backLeft  );
                                    lighting.UpperRight = 0.25f * ( back + backTop    + backTopLeft     + backLeft  );
                                    lighting.UpperLeft  = 0.25f * ( back + backTop    + backTopRight    + backRight );
                                }

                                _chunkBuilder.AddFaceData( blockCenter, BlockFace.Back, block.Type, lighting );
                                exposed = true;
                            }

                            // check in front
                            temp.Type = terrain.Query( x, y, z - 1 );
                            if ( temp.TypeInfo.IsEmpty )
                            {
                                lighting = new BlockFaceLighting( front );

                                // calculate smooth lighting
                                if ( useSmoothLighting )
                                {
                                    lighting.LowerLeft  = 0.25f * ( front + frontBottom + frontBottomLeft  + frontLeft  );
                                    lighting.LowerRight = 0.25f * ( front + frontBottom + frontBottomRight + frontRight );
                                    lighting.UpperRight = 0.25f * ( front + frontTop    + frontTopRight    + frontRight );
                                    lighting.UpperLeft  = 0.25f * ( front + frontTop    + frontTopLeft     + frontLeft  );
                                }

                                _chunkBuilder.AddFaceData( blockCenter, BlockFace.Front, block.Type, lighting );
                                exposed = true;
                            }

                            // check above
                            temp.Type = terrain.Query( x, y + 1, z );
                            if ( temp.TypeInfo.IsEmpty )
                            {
                                lighting = new BlockFaceLighting( top );

                                // calculate smooth lighting
                                if ( useSmoothLighting )
                                {
                                    lighting.LowerLeft  = 0.25f * ( top + frontTop + frontTopLeft  + leftTop  );
                                    lighting.LowerRight = 0.25f * ( top + frontTop + frontTopRight + rightTop );
                                    lighting.UpperRight = 0.25f * ( top + backTop  + backTopRight  + rightTop );
                                    lighting.UpperLeft  = 0.25f * ( top + backTop  + backTopLeft   + leftTop  );
                                }

                                _chunkBuilder.AddFaceData( blockCenter, BlockFace.Top, block.Type, lighting );
                                exposed = true;
                            }

                            // check below
                            temp.Type = terrain.Query( x, y - 1, z );
                            if ( temp.TypeInfo.IsEmpty )
                            {
                                lighting = new BlockFaceLighting( bottom );

                                // calculate smooth lighting
                                if ( useSmoothLighting )
                                {
                                    lighting.LowerLeft  = 0.25f * ( bottom + backBottom  + backBottomLeft   + leftBottom  );
                                    lighting.LowerRight = 0.25f * ( bottom + backBottom  + backBottomRight  + rightBottom );
                                    lighting.UpperRight = 0.25f * ( bottom + frontBottom + frontBottomRight + rightBottom );
                                    lighting.UpperLeft  = 0.25f * ( bottom + frontBottom + frontBottomLeft  + leftBottom  );
                                }

                                _chunkBuilder.AddFaceData( blockCenter, BlockFace.Bottom, block.Type, lighting );
                                exposed = true;
                            }

                            // add the block's bounds to the octree if it's exposed
                            if ( exposed )
                            {
                                CreateBlockBounds( x, y, z, ref tempBounds );
                                _octree.Add( tempBounds );
                            }
                        }
                    }
                }

                // now build the terrain
                lock ( _terrain )
                {
                    _chunkBuilder.PopulateBuffer( _terrain );
                }
            }

            Profiler.Stop( "Voxel Buffer Building" );
        }
Beispiel #4
0
        /// <summary>
        /// Builds the voxel buffer without locking the chunk data.
        /// </summary>
        /// <param name="needToSetCurrentChunk">True if we need to set this chunk as the current chunk for the terrain, false if not.</param>
        private void BuildVoxelBufferNoLockData(bool needToSetCurrentChunk)
        {
            Profiler.Start("Voxel Buffer Building");


            lock ( _chunkBuilder )
            {
                _chunkBuilder.Reset();

                // get the terrain
                var terrain = Terrain.Instance;
                if (needToSetCurrentChunk)
                {
                    terrain.SetCurrentChunk(this);
                }

                // go through for each terrain block
                var temp              = new Block();
                var tempBounds        = new BoundingBox();
                var blockCenter       = new Vector3();
                var useSmoothLighting = Game.Instance.Settings.SmoothLighting;
                for (int x = 0; x < ChunkData.SizeXZ; ++x)
                {
                    for (int z = 0; z < ChunkData.SizeXZ; ++z)
                    {
                        var lighting = new BlockFaceLighting(Block.MaximumLighting);

                        for (int y = ChunkData.SizeY - 1; y >= 0; --y)
                        {
                            // get block info
                            var block   = _data[x, y, z];
                            var exposed = false;
                            if (block.TypeInfo.IsEmpty)
                            {
                                continue;
                            }

                            // get the block's and center
                            Position.LocalToWorld(_data.Index, x, y, z, out blockCenter);

                            // get surrounding block light level
                            // TODO : We don't need to get a lot of these if smooth lighting is disabled
                            var right            = GetLightFromBlock(terrain, x + 1, y, z);
                            var rightTop         = GetLightFromBlock(terrain, x + 1, y + 1, z);
                            var rightBottom      = GetLightFromBlock(terrain, x + 1, y - 1, z);
                            var left             = GetLightFromBlock(terrain, x - 1, y, z);
                            var leftTop          = GetLightFromBlock(terrain, x - 1, y + 1, z);
                            var leftBottom       = GetLightFromBlock(terrain, x - 1, y - 1, z);
                            var back             = GetLightFromBlock(terrain, x, y, z + 1);
                            var backLeft         = GetLightFromBlock(terrain, x - 1, y, z + 1);
                            var backRight        = GetLightFromBlock(terrain, x + 1, y, z + 1);
                            var backTop          = GetLightFromBlock(terrain, x, y + 1, z + 1);
                            var backTopLeft      = GetLightFromBlock(terrain, x - 1, y + 1, z + 1);
                            var backTopRight     = GetLightFromBlock(terrain, x + 1, y + 1, z + 1);
                            var backBottom       = GetLightFromBlock(terrain, x, y - 1, z + 1);
                            var backBottomLeft   = GetLightFromBlock(terrain, x - 1, y - 1, z + 1);
                            var backBottomRight  = GetLightFromBlock(terrain, x + 1, y - 1, z + 1);
                            var front            = GetLightFromBlock(terrain, x, y, z - 1);
                            var frontLeft        = GetLightFromBlock(terrain, x - 1, y, z - 1);
                            var frontRight       = GetLightFromBlock(terrain, x + 1, y, z - 1);
                            var frontTop         = GetLightFromBlock(terrain, x, y + 1, z - 1);
                            var frontTopLeft     = GetLightFromBlock(terrain, x - 1, y + 1, z - 1);
                            var frontTopRight    = GetLightFromBlock(terrain, x + 1, y + 1, z - 1);
                            var frontBottom      = GetLightFromBlock(terrain, x, y - 1, z - 1);
                            var frontBottomLeft  = GetLightFromBlock(terrain, x - 1, y - 1, z - 1);
                            var frontBottomRight = GetLightFromBlock(terrain, x + 1, y - 1, z - 1);
                            var top    = GetLightFromBlock(terrain, x, y + 1, z);
                            var bottom = GetLightFromBlock(terrain, x, y - 1, z);



                            // check to the right
                            temp.Type = terrain.Query(x + 1, y, z);
                            if (temp.TypeInfo.IsEmpty)
                            {
                                lighting = new BlockFaceLighting(right);

                                // calculate smooth lighting
                                if (useSmoothLighting)
                                {
                                    lighting.LowerLeft  = 0.25f * (right + rightBottom + frontBottomRight + frontRight);
                                    lighting.LowerRight = 0.25f * (right + rightBottom + backBottomRight + backRight);
                                    lighting.UpperRight = 0.25f * (right + rightTop + backTopRight + backRight);
                                    lighting.UpperLeft  = 0.25f * (right + rightTop + frontTopRight + frontRight);
                                }

                                _chunkBuilder.AddFaceData(blockCenter, BlockFace.Right, block.Type, lighting);
                                exposed = true;
                            }

                            // check to the left
                            temp.Type = terrain.Query(x - 1, y, z);
                            if (temp.TypeInfo.IsEmpty)
                            {
                                lighting = new BlockFaceLighting(left);

                                // calculate smooth lighting
                                if (useSmoothLighting)
                                {
                                    lighting.LowerLeft  = 0.25f * (left + leftBottom + backBottomLeft + backLeft);
                                    lighting.LowerRight = 0.25f * (left + leftBottom + frontBottomLeft + frontLeft);
                                    lighting.UpperRight = 0.25f * (left + leftTop + frontTopLeft + frontLeft);
                                    lighting.UpperLeft  = 0.25f * (left + leftTop + backTopLeft + backLeft);
                                }

                                _chunkBuilder.AddFaceData(blockCenter, BlockFace.Left, block.Type, lighting);
                                exposed = true;
                            }

                            // check in back
                            temp.Type = terrain.Query(x, y, z + 1);
                            if (temp.TypeInfo.IsEmpty)
                            {
                                lighting = new BlockFaceLighting(back);

                                // calculate smooth lighting
                                if (useSmoothLighting)
                                {
                                    lighting.LowerLeft  = 0.25f * (back + backBottom + backBottomRight + backRight);
                                    lighting.LowerRight = 0.25f * (back + backBottom + backBottomLeft + backLeft);
                                    lighting.UpperRight = 0.25f * (back + backTop + backTopLeft + backLeft);
                                    lighting.UpperLeft  = 0.25f * (back + backTop + backTopRight + backRight);
                                }

                                _chunkBuilder.AddFaceData(blockCenter, BlockFace.Back, block.Type, lighting);
                                exposed = true;
                            }

                            // check in front
                            temp.Type = terrain.Query(x, y, z - 1);
                            if (temp.TypeInfo.IsEmpty)
                            {
                                lighting = new BlockFaceLighting(front);

                                // calculate smooth lighting
                                if (useSmoothLighting)
                                {
                                    lighting.LowerLeft  = 0.25f * (front + frontBottom + frontBottomLeft + frontLeft);
                                    lighting.LowerRight = 0.25f * (front + frontBottom + frontBottomRight + frontRight);
                                    lighting.UpperRight = 0.25f * (front + frontTop + frontTopRight + frontRight);
                                    lighting.UpperLeft  = 0.25f * (front + frontTop + frontTopLeft + frontLeft);
                                }

                                _chunkBuilder.AddFaceData(blockCenter, BlockFace.Front, block.Type, lighting);
                                exposed = true;
                            }

                            // check above
                            temp.Type = terrain.Query(x, y + 1, z);
                            if (temp.TypeInfo.IsEmpty)
                            {
                                lighting = new BlockFaceLighting(top);

                                // calculate smooth lighting
                                if (useSmoothLighting)
                                {
                                    lighting.LowerLeft  = 0.25f * (top + frontTop + frontTopLeft + leftTop);
                                    lighting.LowerRight = 0.25f * (top + frontTop + frontTopRight + rightTop);
                                    lighting.UpperRight = 0.25f * (top + backTop + backTopRight + rightTop);
                                    lighting.UpperLeft  = 0.25f * (top + backTop + backTopLeft + leftTop);
                                }

                                _chunkBuilder.AddFaceData(blockCenter, BlockFace.Top, block.Type, lighting);
                                exposed = true;
                            }

                            // check below
                            temp.Type = terrain.Query(x, y - 1, z);
                            if (temp.TypeInfo.IsEmpty)
                            {
                                lighting = new BlockFaceLighting(bottom);

                                // calculate smooth lighting
                                if (useSmoothLighting)
                                {
                                    lighting.LowerLeft  = 0.25f * (bottom + backBottom + backBottomLeft + leftBottom);
                                    lighting.LowerRight = 0.25f * (bottom + backBottom + backBottomRight + rightBottom);
                                    lighting.UpperRight = 0.25f * (bottom + frontBottom + frontBottomRight + rightBottom);
                                    lighting.UpperLeft  = 0.25f * (bottom + frontBottom + frontBottomLeft + leftBottom);
                                }

                                _chunkBuilder.AddFaceData(blockCenter, BlockFace.Bottom, block.Type, lighting);
                                exposed = true;
                            }



                            // add the block's bounds to the octree if it's exposed
                            if (exposed)
                            {
                                CreateBlockBounds(x, y, z, ref tempBounds);
                                _octree.Add(tempBounds);
                            }
                        }
                    }
                }

                // now build the terrain
                lock ( _terrain )
                {
                    _chunkBuilder.PopulateBuffer(_terrain);
                }
            }


            Profiler.Stop("Voxel Buffer Building");
        }