/// <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; } }
/// <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; } }
/// <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" ); }
/// <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"); }