Пример #1
0
    //	Get biome layer topology and smooth between layers at edges using Perlin or Simplex noise
    private Topology GetBiomeTopology(int x, int z, Column column, TerrainLibrary.Biome biome)
    {
        //	Global voxel column coordinates
        int gx = (int)(x + column.position.x);
        int gz = (int)(z + column.position.z);

        //	Base noise to map biome layers and base height
        float baseNoise = biome.BaseNoise(gx, gz);

        TerrainLibrary.BiomeLayer layer = biome.GetLayer(baseNoise);

        //	Do not overwrite data for this block when getting adjacent biome topology
        if (column.biomeLayers[x, z] == null)
        {
            column.biomeLayers[x, z] = layer;
        }

        //	Make sure gradient margins don't overlap
        float margin = (layer.max - layer.min) / 2;

        //	Clamp margin at max
        margin = margin > layer.maxMargin ? layer.maxMargin : margin;

        //	Layer height data for current layer
        Topology currentTopology = new Topology(layer.Noise(gx, gz),
                                                layer.maxHeight,
                                                baseNoise);

        //	Closeness to top and bottom of baseNoise range defining this biome layer
        float bottomGradient = EdgeGradient(baseNoise, layer.min, margin);
        float topGradient    = EdgeGradient(baseNoise, layer.max, margin);

        TerrainLibrary.BiomeLayer adjacentLayer = null;
        float interpValue;

        //	Smooth to above layer
        if (bottomGradient != 2 && layer.min != 0)
        {
            adjacentLayer = biome.layers[layer.index - 1];
            interpValue   = bottomGradient;
        }
        //	Smooth to below layer
        else if (topGradient != 2 && layer.max != 1)
        {
            adjacentLayer = biome.layers[layer.index + 1];
            interpValue   = topGradient;
        }
        //	Not within margin distance of another layer
        else
        {
            //	No smoothing required
            return(new Topology(currentTopology.noise, currentTopology.height, baseNoise));
        }

        //	Layer height data for adjacent layer
        Topology adjacentTopology = new Topology(adjacentLayer.Noise(gx, gz),
                                                 adjacentLayer.maxHeight,
                                                 baseNoise);

        //	Return smoothed topology
        return(SmoothTopologys(currentTopology, adjacentTopology, interpValue));
    }
Пример #2
0
    //	Get biome topology and smooth between biomes if necessary
    //	using Cellular value and distance-to-edge noise respectively
    public void GetTopologyData(Column column)
    {
        int chunkSize = World.chunkSize;

        column.heightMap = new int[chunkSize, chunkSize];


        //	Iterate over height map
        for (int x = 0; x < chunkSize; x++)
        {
            for (int z = 0; z < chunkSize; z++)
            {
                //	Global voxel column coordinates
                int gx = (int)(x + column.position.x);
                int gz = (int)(z + column.position.z);

                //	Get cellular noise data
                FastNoise.EdgeData edgeData = column.edgeMap[x, z];

                //	Get current biome type
                TerrainLibrary.Biome currentBiome = worldBiomes.GetBiome(edgeData.currentCellValue);

                //	Get adjacent biome type
                TerrainLibrary.Biome adjacentBiome = worldBiomes.GetBiome(edgeData.adjacentCellValue);

                //	Get topology for this pixel
                Topology currentTolopogy = GetBiomeTopology(x, z, column, currentBiome);

                Topology finalTopology;

                //	Within smoothing radius and adjacent biome is different
                if (edgeData.distance2Edge < worldBiomes.smoothRadius && currentBiome != adjacentBiome)
                {
                    if (!column.biomeBoundary)
                    {
                        column.biomeBoundary = true;
                    }

                    float InterpValue = Mathf.InverseLerp(0, worldBiomes.smoothRadius, edgeData.distance2Edge);

                    //	Get topology for this pixel if adjacent biome type
                    Topology adjacentTopology = GetBiomeTopology(x, z, column, adjacentBiome);

                    //	Smooth between topologys
                    finalTopology = SmoothTopologys(currentTolopogy, adjacentTopology, InterpValue);
                }
                else
                {
                    finalTopology = currentTolopogy;
                }

                int POIheight = 0;

                //	Where points of interest exist, flatten terrain
                if (column.POIHeightGradient != null && column.POIHeightGradient[x, z] != 0)
                {
                    float    interpValue = (float)column.POIHeightGradient[x, z] / chunkSize;
                    Topology POITopology = new Topology(0.5f, finalTopology.height, 0.5f);
                    finalTopology = SmoothToPOI(POITopology, finalTopology, interpValue);

                    //	Adjust heighest point
                    POIheight = column.POIType.wallHeight;
                }

                //	Generate final height value for chunk data
                column.heightMap[x, z] = (int)Mathf.Lerp(0, finalTopology.height, finalTopology.baseNoise * finalTopology.noise);

                //	Update highest and lowest block in chunk column
                column.CheckHighest(column.heightMap[x, z] + POIheight);
                column.CheckLowest(column.heightMap[x, z]);
            }
        }
    }