예제 #1
0
    public void AddTrees(ref WorldData worldData, int seed)
    {
        List <TreeData> treeData = new List <TreeData>();

        System.Random rng  = new System.Random(seed);
        int           size = TerrainGenerator.size * (int)treesPerVoxel;

        float[,] landNoise = Procedural.NoiseMap(seed, TerrainGenerator.size, TerrainGenerator.noiseScale, terrainGenerator.multiplier);
        float[,] treeNoise = Procedural.NoiseMap(seed + 1, size, treeNoiseScale, AnimationCurve.Linear(0f, 0f, 1f, 1f));

        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                Coords voxelCoords   = new Coords(Mathf.FloorToInt(x / treesPerVoxel), Mathf.FloorToInt(y / treesPerVoxel));
                bool   adjacentOcean = Util.AdjacentProperty(Util.CoordsToVoxels(worldData.voxelData, Util.GetAdjacent(voxelCoords, true)), "isOcean");
                bool   adjacentLake  = Util.AdjacentProperty(Util.CoordsToVoxels(worldData.voxelData, Util.GetAdjacent(voxelCoords, true)), "isLake");
                if (worldData.voxelData[voxelCoords.x, voxelCoords.y].isLand && !worldData.voxelData[voxelCoords.x, voxelCoords.y].occupied && !adjacentOcean && (treeNoise[x, y] < treeThreshold || adjacentLake) && rng.Next(0, 1000) / 1000f < treeNoise[x, y] * landNoise[voxelCoords.x, voxelCoords.y] * treeDensity)
                {
                    int      treeType   = rng.Next(0, treeObjects.Length);
                    Coords   treeCoords = new Coords(x, y);
                    float    rotation   = rng.Next(0, 360);
                    TreeData tree       = new TreeData(treeCoords, voxelCoords, treeType, rotation);
                    treeData.Add(tree);
                    worldData.voxelData[voxelCoords.x, voxelCoords.y].occupied = true;
                    worldData.voxelData[voxelCoords.x, voxelCoords.y].hasTrees = true;
                }
            }
        }

        worldData.treeData = treeData;
    }
예제 #2
0
    public void AddRocks(ref WorldData worldData, int seed)
    {
        List <RockData> rockData = new List <RockData>();

        System.Random rng  = new System.Random(seed);
        int           size = TerrainGenerator.size;

        float[,] noiseMap = Procedural.NoiseMap(seed + 2, size, rockNoiseScale, AnimationCurve.Linear(0f, 0f, 1f, 1f));

        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                Coords coords        = new Coords(x, y);
                bool   adjacentOcean = Util.AdjacentProperty(Util.CoordsToVoxels(worldData.voxelData, Util.GetAdjacent(coords, true)), "isOcean");
                if (worldData.voxelData[x, y].isLand && !adjacentOcean && !worldData.voxelData[x, y].occupied && noiseMap[x, y] < rockThreshold)
                {
                    RockData rock = new RockData(coords, rng.Next(0, rockObjects.Length), rng.Next(0, 360));
                    rockData.Add(rock);
                    worldData.voxelData[coords.x, coords.y].occupied  = true;
                    worldData.voxelData[coords.x, coords.y].navigable = false;
                }
            }
        }

        worldData.rockData = rockData;
    }
예제 #3
0
    public VoxelData[,] GenerateVoxelData(int seed)
    {
        System.Random rng = new System.Random(seed);

        VoxelData[,] voxelData = new VoxelData[size, size];

        float[,] landNoise  = Procedural.NoiseMap(seed, size, noiseScale, multiplier);
        float[,] colorNoise = Procedural.NoiseMap(seed + 1, size, ObjectGenerator.treeNoiseScale, AnimationCurve.Linear(0f, 0f, 1f, 1f));
        float[,] falloffMap = Procedural.FalloffMap(size);

        //Determine what is land
        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                landNoise[x, y] = Mathf.Max(0, landNoise[x, y] - falloffMap[x, y]);
            }
        }

        //Set corresponding voxel values for land
        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                voxelData[x, y] = new VoxelData {
                    coords = new Coords(x, y)
                };
                if (landNoise[x, y] > waterThreshold)
                {
                    voxelData[x, y].isLand    = true;
                    voxelData[x, y].navigable = true;
                }
                else
                {
                    voxelData[x, y].isOcean = true;
                }
            }
        }

        //Find and mark lakes
        bool[,] marked = new bool[size, size];
        List <List <Coords> > bodiesOfWater = new List <List <Coords> >();

        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                marked[x, y] = false;
            }
        }
        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                if (!marked[x, y] && voxelData[x, y].isOcean)
                {
                    Stack <Coords> stack = new Stack <Coords>();
                    List <Coords>  list  = new List <Coords>();
                    stack.Push(new Coords(x, y));
                    while (stack.Count > 0)
                    {
                        Coords v = stack.Pop();
                        if (!marked[(int)v.x, (int)v.y])
                        {
                            list.Add(v);
                            marked[(int)v.x, (int)v.y] = true;
                            foreach (Coords adj in Util.GetAdjacent(v, true))
                            {
                                if (voxelData[(int)adj.x, (int)adj.y].isOcean)
                                {
                                    stack.Push(adj);
                                }
                            }
                        }
                    }
                    bodiesOfWater.Add(list);
                }
            }
        }
        foreach (List <Coords> body in bodiesOfWater)
        {
            if (body.Count < 100)
            {
                foreach (Coords v in body)
                {
                    voxelData[v.x, v.y].isOcean = false;
                    voxelData[v.x, v.y].isLake  = true;
                }
            }
        }

        //Set voxel colors
        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                if (voxelData[x, y].isLand)
                {
                    Color baseColor = Color.Lerp(Palette.LandMin, Palette.LandMax, rng.Next(0, 1000) / 1000f);
                    voxelData[x, y].color = SerializableColor.FromColor(Color.Lerp(baseColor, Palette.Chartreuse, Mathf.Pow(colorNoise[x, y] * landNoise[x, y], 2)));
                }
                else
                {
                    voxelData[x, y].color = SerializableColor.FromColor(Palette.Water);
                }
            }
        }

        //Set beaches and coasts
        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                Coords coords = new Coords(x, y);
                if (voxelData[x, y].isLand && Util.AdjacentProperty(Util.CoordsToVoxels(voxelData, Util.GetAdjacent(coords, true)), "isOcean") && colorNoise[x, y] > .5f)
                {
                    voxelData[x, y].color = SerializableColor.FromColor(Color.Lerp(voxelData[x, y].color.ToColor(), Palette.Sand, Mathf.Pow(colorNoise[x, y], 2)));
                }
                else if (voxelData[x, y].isOcean && Util.AdjacentProperty(Util.CoordsToVoxels(voxelData, Util.GetAdjacent(coords, true)), "isLand"))
                {
                    voxelData[x, y].color = SerializableColor.FromColor(Color.Lerp(voxelData[x, y].color.ToColor(), Palette.Coast, .1f));
                }
            }
        }

        return(voxelData);
    }