/// <summary> /// Generic function to generate the chunk's voxels and voxel features. /// This does not bake the voxel features into the chunk /// </summary> /// <returns></returns> public virtual void generateVoxelsFor(Chunk chunk) { int solidVoxelCount = 0; byte[] voxels = new byte[Chunk.Diameter * Chunk.Diameter * Chunk.Diameter]; List <ITerrainFeature> features = new List <ITerrainFeature>(); Coordinate chunkWorldLocation = Chunk.IDToWorldLocation(chunk.id); /// For each XZ location in the chunk: chunkWorldLocation.xz.until((chunkWorldLocation + Chunk.Diameter).xz, currentWorldXZLocation => { currentWorldXZLocation.until(currentWorldXZLocation.replaceY(Chunk.Diameter), currentVoxelWorldLocation => { XZMapData xzData = getMapDataForXZLocation(currentWorldXZLocation); byte voxelValue = generateVoxelAt(currentVoxelWorldLocation, out ITerrainFeature potentialFeature, xzData); // if the voxel isn't empty, we add it to the generated data and count it. if (voxelValue != Voxel.Types.Empty.Id) { Coordinate localChunkVoxelLocation = currentVoxelWorldLocation - chunkWorldLocation; voxels[localChunkVoxelLocation.flatten(Chunk.Diameter)] = voxelValue; solidVoxelCount++; } // add a feature to the list. We don't bake them until after the terrain is generated. if (potentialFeature != null) { features.Add(potentialFeature); } }); });
/// <summary> /// Generate the voxels at the given chunk /// </summary> /// <param name="worldLocation"></param> /// <param name="feature"></param> /// <returns></returns> public override byte generateVoxelAt(Coordinate worldLocation, out ITerrainFeature feature, XZMapData xzData) { feature = null; if (worldLocation.y == xzData.surfaceHeight) { if (worldLocation.x + worldLocation.y % 12 == 0) { // make a new feature at the local chunk location feature = potentialFeatures[0].make(worldLocation - (Chunk.IDFromWorldLocation(worldLocation) * Chunk.Diameter)); } return(TerrainBlock.Types.Grass.Id); } else if (worldLocation.y < xzData.surfaceHeight) { return(TerrainBlock.Types.Dirt.Id); } else { return(TerrainBlock.Types.Air.Id); } }