private List <Color> GetNeighbourColours(int x, int y, float[,] heightMap, float[,] biomeMap) { List <Color> colours = new List <Color>(); for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { if ((x + dx >= 0 && x + dx < heightMap.GetLength(0)) && (y + dy >= 0 && y + dy < heightMap.GetLength(1))) { Biome biome = biomeHelper.GetBiome(biomeMap[x + dx, y + dy]); if (biome != null) { TerrainType terrainType = biomeHelper.GetTerrainType(biome, heightMap[x + dx, y + dy]); if (terrainType != null) { colours.Add(terrainType.colour); } else { Debug.LogError("No Terrain Type found!"); } } else { Debug.LogError("No Biome found!"); } } else { //Debug.LogWarning("Index exists in other chunk"); } } } return(colours); }
public static MeshData GenerateTerrainMesh(Terrain terrain, BiomeHelper biomeHelper, float heightMultiplier, AnimationCurve meshHeightCurve, int levelOfDetail) { AnimationCurve heightCurve = new AnimationCurve(meshHeightCurve.keys); int size = terrain.heightMap.GetLength(0); float topLeftX = (size - 1) / -2f; float topLeftZ = (size - 1) / 2f; int meshSimplificationIncrement = levelOfDetail == 0 ? 1 : levelOfDetail * 2; int verticesPerLine = (size - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine); int vertexIndex = 0; for (int y = 0; y < size; y += meshSimplificationIncrement) { for (int x = 0; x < size; x += meshSimplificationIncrement) { Biome biome = biomeHelper.GetBiome(terrain.biomeMap[x, y]); meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(terrain.heightMap[x, y]) * heightMultiplier * (biome != null ? biome.heightMultiplier : 1), topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)size, y / (float)size); if (x < size - 1 && y < size - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } meshData.SetColours(terrain.colourMap); meshData.ApplyFlatShading(); return(meshData); }
private void TerraForming(byte[] ChunkCubes, ChunkColumnInfo[] columnsInfo, ref Range3I chunkWorldRange, double[,] biomeMap, FastRandom chunkRnd) { int surface, surfaceLayer; int inWaterMaxLevel = 0; Biome currentBiome; ChunkColumnInfo columnInfo; int index = 0; int noise2DIndex = 0; for (int X = 0; X < AbstractChunk.ChunkSize.X; X++) { for (int Z = 0; Z < AbstractChunk.ChunkSize.Z; Z++) { //Get Biomes informations for this Column============================================ bool mustPlacedSnow; double temperature = biomeMap[noise2DIndex, 1]; double moisture = biomeMap[noise2DIndex, 2]; double zoneValue = biomeMap[noise2DIndex, 3]; byte biomeId = _biomeHelper.GetBiome(biomeMap[noise2DIndex, 0], temperature, moisture, zoneValue); //Get this landscape Column Biome value currentBiome = _config.ProcessorParam.Biomes[biomeId]; //Get Temperature and Moisture columnInfo = new ChunkColumnInfo() { Biome = biomeId, Moisture = (byte)(moisture * 255), Temperature = (byte)(temperature * 255), MaxHeight = byte.MaxValue, Zone = (byte)(zoneValue * 255), IsWild = true }; mustPlacedSnow = (temperature <0.2 && moisture> 0.5); //==================================================================================== surface = chunkRnd.Next(currentBiome.UnderSurfaceLayers.Min, currentBiome.UnderSurfaceLayers.Max + 1); inWaterMaxLevel = 0; surfaceLayer = 0; bool solidGroundHitted = false; for (int Y = _worldGeneratedHeight - 1; Y >= 0; Y--) //Y { index = ((Z * AbstractChunk.ChunkSize.X) + X) * AbstractChunk.ChunkSize.Y + Y; byte cubeId = ChunkCubes[index]; //Restart Surface layer if needed if (surfaceLayer > 0 && cubeId == UtopiaProcessorParams.CubeId.Air && Y > (_config.ProcessorParam.WaterLevel - 5)) { surfaceLayer = 1; } if (cubeId == UtopiaProcessorParams.CubeId.Stone) { if (solidGroundHitted == false) { if (columnInfo.MaxHeight < Y || inWaterMaxLevel == 0) { columnInfo.MaxHeight = (byte)Y; } columnInfo.MaxGroundHeight = (byte)Y; solidGroundHitted = true; } cubeId = currentBiome.GroundCube; //Under water soil if (Y < _config.ProcessorParam.WaterLevel && inWaterMaxLevel != 0) { if (cubeId == currentBiome.GroundCube) { ChunkCubes[index] = currentBiome.UnderSurfaceCube; } break; } inWaterMaxLevel = 0; //Surface Layer handling if (surface > surfaceLayer) { if (surfaceLayer == 0) { if (mustPlacedSnow) { //Get cube index above this one //Place a snow block on it ChunkCubes[((Z * AbstractChunk.ChunkSize.X) + X) * AbstractChunk.ChunkSize.Y + (Y + 1)] = UtopiaProcessorParams.CubeId.Snow; mustPlacedSnow = false; } ChunkCubes[index] = currentBiome.SurfaceCube; } else { ChunkCubes[index] = currentBiome.UnderSurfaceCube; } surfaceLayer++; } } else //This block is not Stone (Air, Water, or BedRock) { if (cubeId == UtopiaProcessorParams.CubeId.WaterStill) { if (mustPlacedSnow) { //Get cube index above this one //Place a snow block on it ChunkCubes[index] = UtopiaProcessorParams.CubeId.Ice; } inWaterMaxLevel = Y; columnInfo.MaxHeight = (byte)Y; } else { if (inWaterMaxLevel > 0 && cubeId == UtopiaProcessorParams.CubeId.Air) { ChunkCubes[index] = UtopiaProcessorParams.CubeId.WaterStill; } } } } columnsInfo[noise2DIndex] = columnInfo; noise2DIndex++; } } }