/// <summary> /// Generate the voxels for the given terrain chunk. /// </summary> /// <param name="voxels">The voxels to populate.</param> /// <param name="surfaceHeights">The height of the surface at each x position.</param> /// <param name="chunkIndex">The chunk index.</param> public void Generate(ChunkVoxels voxels, float[] surfaceHeights, Position chunkIndex) { int originY = chunkIndex.Y * Chunk.Height; for (int x = 0; x < Chunk.Width; x++) { float surfaceHeightF = surfaceHeights[x]; int surfaceHeightI = (int)Math.Floor(surfaceHeightF); float deltaHeight = surfaceHeightF - surfaceHeightI; for (int y = 0; y < Chunk.Height; y++) { int height = originY + y; // Create the voxel at this point Voxel voxel; if (height > surfaceHeightI) { // This voxel lies above the surface voxel = Voxel.Air; } else { // Determine the material var material = TerrainMaterial.Dirt; if (height == surfaceHeightI) { // This voxel lies on the surface, so scale the density by the noise value byte density = (byte)(Voxel.DensityMax - (Voxel.DensityMax * deltaHeight)); // The density property stores 2 densities. The 'foreground' density which is that which // can be dug, and the 'background' density which represents the original density // Set the foreground and background densities both density = (byte)((density << 4) | density); voxel = new Voxel(material, density); } else { // The voxel lies under the surface voxel = new Voxel(material, Voxel.DensityMin); } } // Set the voxel voxels[x, y] = voxel; } } }
/// <summary> /// Fill the terrain with the given material below the surface and air above. /// </summary> /// <param name="chunk">The chunk</param> /// <param name="chunkIndex">The chunk index.</param> /// <param name="surfaceHeights">The y value of each surface point.</param> /// <param name="material">The material to fill below surface.</param> private void FillAroundSurface( ChunkVoxels chunk, Position chunkIndex, int[] surfaceHeights, TerrainMaterial material) { for (int chunkX = 0; chunkX < Chunk.Width; chunkX++) { int surfaceHeight = surfaceHeights[chunkX]; for (int chunkY = 0; chunkY < Chunk.Height; chunkY++) { if (chunkY < surfaceHeight) { chunk[chunkX, chunkY] = new Voxel(material, Voxel.DensityMin); } else if (chunkY > surfaceHeight) { chunk[chunkX, chunkY] = new Voxel(TerrainMaterial.Air, Voxel.DensityMax); } } } }