Пример #1
0
 private float[,] generateVoronoi(float[,] heightMap, Vector2 arraySize, GeneratorProgressDelegate generatorProgressDelegate)
 {
     int Tx = (int) arraySize.x;
     int Ty = (int) arraySize.y;
     // Create Voronoi set...
     ArrayList voronoiSet = new ArrayList();
     int i;
     for (i = 0; i < voronoiCells; i++) {
         Peak newPeak = new Peak();
         int xCoord = (int) Mathf.Floor(UnityEngine.Random.value * Tx);
         int yCoord = (int) Mathf.Floor(UnityEngine.Random.value * Ty);
         float pointHeight = UnityEngine.Random.value;
         if (UnityEngine.Random.value > voronoiFeatures) {
             pointHeight = 0.0f;
         }
         newPeak.peakPoint = new Vector2(xCoord, yCoord);
         newPeak.peakHeight = pointHeight;
         voronoiSet.Add(newPeak);
     }
     int Mx;
     int My;
     float highestScore = 0.0f;
     for (My = 0; My < Ty; My++) {
         for (Mx = 0; Mx < Tx; Mx++) {
             ArrayList peakDistances = new ArrayList();
             for (i = 0; i < voronoiCells; i++) {
                 Peak peakI = (Peak) voronoiSet[i];
                 Vector2 peakPoint = peakI.peakPoint;
                 float distanceToPeak = Vector2.Distance(peakPoint, new Vector2(Mx, My));
                 PeakDistance newPeakDistance = new PeakDistance();
                 newPeakDistance.id = i;
                 newPeakDistance.dist = distanceToPeak;
                 peakDistances.Add(newPeakDistance);
             }
             peakDistances.Sort();
             PeakDistance peakDistOne = (PeakDistance) peakDistances[0];
             PeakDistance peakDistTwo = (PeakDistance) peakDistances[1];
             int p1 = peakDistOne.id;
             float d1 = peakDistOne.dist;
             float d2 = peakDistTwo.dist;
             float scale = Mathf.Abs(d1 - d2) / ((Tx + Ty) / Mathf.Sqrt(voronoiCells));
             Peak peakOne = (Peak) voronoiSet[p1];
             float h1 = (float) peakOne.peakHeight;
             float hScore = h1 - Mathf.Abs(d1 / d2) * h1;
             float asRadians;
             switch (voronoiType) {
                 case VoronoiType.Linear:
                 // Nothing...
                 break;
                 case VoronoiType.Sine:
                 asRadians = hScore * Mathf.PI - Mathf.PI / 2;
                 hScore = 0.5f + Mathf.Sin(asRadians) / 2;
                 break;
                 case VoronoiType.Tangent:
                 asRadians = hScore * Mathf.PI / 2;
                 hScore = 0.5f + Mathf.Tan(asRadians) / 2;
                 break;
             }
             hScore = (hScore * scale * voronoiScale) + (hScore * (1.0f - voronoiScale));
             if (hScore < 0.0f) {
                 hScore = 0.0f;
             } else if (hScore > 1.0f) {
                 hScore = 1.0f;
             }
             heightMap[Mx, My] = hScore;
             if (hScore > highestScore) {
                 highestScore = hScore;
             }
         }
         // Show progress...
         float completePoints = My * Ty;
         float totalPoints = Tx * Ty;
         float percentComplete = completePoints / totalPoints;
         generatorProgressDelegate("Voronoi Generator", "Generating height map. Please wait.", percentComplete);
     }
     // Normalise...
     for (My = 0; My < Ty; My++) {
         for (Mx = 0; Mx < Tx; Mx++) {
             float normalisedHeight = heightMap[Mx, My] * (1.0f / highestScore);
             heightMap[Mx, My] = normalisedHeight;
         }
     }
     return heightMap;
 }
    //        voronoiPresets.Add(new voronoiPresetData("Scattered Peaks", VoronoiType.Linear, 16, 8, 0.5f, 1.0f));
    //    voronoiPresets.Add(new voronoiPresetData("Rolling Hills", VoronoiType.Sine, 8, 8, 0.0f, 1.0f));
    //    voronoiPresets.Add(new voronoiPresetData("Jagged Mountains", VoronoiType.Linear, 32, 32, 0.5f, 1.0f));
    private float[,] generateVoronoi(ref float[,] heightMap, Vector2 arraySize, bool regenFlag)
    {
        int Tx = (int)arraySize.x;
        int Ty = (int)arraySize.y;
        // Create Voronoi set...
        ArrayList voronoiSet = new ArrayList();
        int i;
        int inc = 1;
        if (regenFlag)
            inc++;
        for (i = 0; i < voronoiCells; i += inc)
        {
            Peak newPeak = new Peak();
            int xCoord = (int)Mathf.Floor(UnityEngine.Random.value * Tx);
            int yCoord = (int)Mathf.Floor(UnityEngine.Random.value * Ty);
            float pointHeight = UnityEngine.Random.value;
            if (UnityEngine.Random.value > voronoiFeatures)
            {
                pointHeight = 0.0f;
            }
            newPeak.peakPoint = new Vector2(xCoord, yCoord);
            newPeak.peakHeight = pointHeight;
            voronoiSet.Add(newPeak);
        }
        int Mx;
        int My;
        float highestScore = 0.0f;
        for (My = 0; My < Ty; My += inc)
        {
            for (Mx = 0; Mx < Tx; Mx += inc)
            {
                ArrayList peakDistances = new ArrayList();
                try
                {
                    for (i = 0; i < voronoiCells; i += inc)
                    {
                        Peak peakI = (Peak)voronoiSet[i];
                        Vector2 peakPoint = peakI.peakPoint;
                        float distanceToPeak = Vector2.Distance(peakPoint, new Vector2(Mx, My));
                        PeakDistance newPeakDistance = new PeakDistance();
                        newPeakDistance.id = i;
                        newPeakDistance.dist = distanceToPeak;
                        peakDistances.Add(newPeakDistance);
                    }
                }
                catch (Exception) { }
                peakDistances.Sort();
                PeakDistance peakDistOne = (PeakDistance)peakDistances[0];
                PeakDistance peakDistTwo = (PeakDistance)peakDistances[1];
                int p1 = peakDistOne.id;
                float d1 = peakDistOne.dist;
                float d2 = peakDistTwo.dist;
                float scale = Mathf.Abs(d1 - d2) / ((Tx + Ty) / Mathf.Sqrt(voronoiCells));
                Peak peakOne = (Peak)voronoiSet[p1];
                float h1 = (float)peakOne.peakHeight;
                float hScore = h1 - Mathf.Abs(d1 / d2) * h1;
                float asRadians;
                switch (voronoiType)
                {
                    case VoronoiType.Linear:
                        // Nothing...
                        break;
                    case VoronoiType.Sine:
                        asRadians = hScore * Mathf.PI - Mathf.PI / 2;
                        hScore = 0.5f + Mathf.Sin(asRadians) / 2;
                        break;
                    case VoronoiType.Tangent:
                        asRadians = hScore * Mathf.PI / 2;
                        hScore = 0.5f + Mathf.Tan(asRadians) / 2;
                        break;
                }
                hScore = (hScore * scale * voronoiScale) + (hScore * (1.0f - voronoiScale));
                if (hScore < 0.0f)
                {
                    hScore = 0.0f;
                }
                else if (hScore > 1.0f)
                {
                    hScore = 1.0f;
                }
                heightMap[Mx, My] += hScore;
                if (hScore > highestScore)
                {
                    highestScore = hScore;
                }
                heightMap[Mx, My] = hScore + heightMap[Mx, My] < 1? heightMap[Mx, My] : 1;
                heightMap[Mx, My] *= mHeight;
            }

        }

        // Normalise...
        //for (My = 0; My < Ty; My++)
        //{
        //    for (Mx = 0; Mx < Tx; Mx++)
        //    {
        //        float normalisedHeight = heightMap[Mx, My] * (1.0f / highestScore);
        //        heightMap[Mx, My] = normalisedHeight;
        //    }
        //}
        return heightMap;
    }