예제 #1
0
    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);
    }
예제 #2
0
    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);
    }
예제 #3
0
        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++;
                }
            }
        }