예제 #1
0
 public void textureTerrain(TextureProgressDelegate textureProgressDelegate)
 {
     Terrain ter = (Terrain) GetComponent(typeof(Terrain));
     if (ter == null) {
         return;
     }
     TerrainData terData = ter.terrainData;
     splatPrototypes = terData.splatPrototypes;
     int nTextures = splatPrototypes.Length;
     if (nTextures < 2) {
         Debug.LogError("Error: You must assign at least 2 textures.");
         return;
     }
     textureProgressDelegate("Procedural Terrain Texture", "Generating height and slope maps. Please wait.", 0.1f);
     int Tw = terData.heightmapWidth - 1;
     int Th = terData.heightmapHeight - 1;
     float[,] heightMapData = new float[Tw, Th];
     float[,] slopeMapData = new float[Tw, Th];
     float[,,] splatMapData;
     terData.alphamapResolution = Tw;
     splatMapData = terData.GetAlphamaps(0, 0, Tw, Tw);
     // Angles to difference...
     Vector3 terSize = terData.size;
     float slopeBlendMinimum = ((terSize.x / Tw) * Mathf.Tan(slopeBlendMinAngle * Mathf.Deg2Rad)) / terSize.y;
     float slopeBlendMaximum = ((terSize.x / Tw) * Mathf.Tan(slopeBlendMaxAngle * Mathf.Deg2Rad)) / terSize.y;
     try {
         float greatestHeight = 0.0f;
         int xNeighbours;
         int yNeighbours;
         int xShift;
         int yShift;
         int xIndex;
         int yIndex;
         float[,] heightMap = terData.GetHeights(0, 0, Tw, Th);
         for (int Ty = 0; Ty < Th; Ty++) {
             // y...
             if (Ty == 0) {
                 yNeighbours = 2;
                 yShift = 0;
                 yIndex = 0;
             } else if (Ty == Th - 1) {
                 yNeighbours = 2;
                 yShift = -1;
                 yIndex = 1;
             } else {
                 yNeighbours = 3;
                 yShift = -1;
                 yIndex = 1;
             }
             for (int Tx = 0; Tx < Tw; Tx++) {
                 // x...
                 if (Tx == 0) {
                     xNeighbours = 2;
                     xShift = 0;
                     xIndex = 0;
                 } else if (Tx == Tw - 1) {
                     xNeighbours = 2;
                     xShift = -1;
                     xIndex = 1;
                 } else {
                     xNeighbours = 3;
                     xShift = -1;
                     xIndex = 1;
                 }
                 // Get height...
                 float h = heightMap[Tx + xIndex + xShift, Ty + yIndex + yShift];
                 if (h > greatestHeight) {
                     greatestHeight = h;
                 }
                 // ...and apply to height map...
                 heightMapData[Tx, Ty] = h;
                 // Calculate slope...
                 float tCumulative = 0.0f;
                 float nNeighbours = xNeighbours * yNeighbours - 1;
                 int Ny;
                 int Nx;
                 float t;
                 for (Ny = 0; Ny < yNeighbours; Ny++) {
                     for (Nx = 0; Nx < xNeighbours; Nx++) {
                         // Ignore the index...
                         if (Nx != xIndex || Ny != yIndex) {
                             t = Mathf.Abs(h - heightMap[Tx + Nx + xShift, Ty + Ny + yShift]);
                             tCumulative += t;
                         }
                     }
                 }
                 float tAverage = tCumulative / nNeighbours;
                 // ...and apply to the slope map...
                 slopeMapData[Tx, Ty] = tAverage;
             }
             // Show progress...
             // float completePoints = Ty * Th;
             // float totalPoints = Tw * Th;
             // float percentComplete = (completePoints / totalPoints) * 0.6f;
             // textureProgressDelegate("Procedural Terrain Texture", "Generating height and slope maps. Please wait.", percentComplete);
         }
         // Blend slope...
         float sBlended;
         int Px;
         int Py;
         for (Py = 0; Py < Th; Py++) {
             for (Px = 0; Px < Tw; Px++) {
                 sBlended = slopeMapData[Px, Py];
                 if (sBlended < slopeBlendMinimum) {
                     sBlended = 0;
                 } else if (sBlended < slopeBlendMaximum) {
                     sBlended = (sBlended - slopeBlendMinimum) / (slopeBlendMaximum - slopeBlendMinimum);
                 } else if (sBlended > slopeBlendMaximum) {
                     sBlended = 1;
                 }
                 slopeMapData[Px, Py] = sBlended;
                 splatMapData[Px, Py, 0] = sBlended;
             }
         }
         // Blend height maps...
         for (int i = 1; i < nTextures; i++) {
             for (Py = 0; Py < Th; Py++) {
                 for (Px = 0; Px < Tw; Px++) {
                     float hBlendInMinimum = 0;
                     float hBlendInMaximum = 0;
                     float hBlendOutMinimum = 1;
                     float hBlendOutMaximum = 1;
                     float hValue;
                     float hBlended = 0;
                     if (i > 1) {
                         hBlendInMinimum = (float) heightBlendPoints[i * 2 - 4];
                         hBlendInMaximum = (float) heightBlendPoints[i * 2 - 3];
                     }
                     if (i < nTextures - 1) {
                         hBlendOutMinimum = (float) heightBlendPoints[i * 2 - 2];
                         hBlendOutMaximum = (float) heightBlendPoints[i * 2 - 1];
                     }
                     hValue = heightMapData[Px, Py];
                     if (hValue >= hBlendInMaximum && hValue <= hBlendOutMinimum) {
                         // Full...
                         hBlended = 1;
                     } else if (hValue >= hBlendInMinimum && hValue < hBlendInMaximum) {
                         // Blend in...
                         hBlended = (hValue - hBlendInMinimum) / (hBlendInMaximum - hBlendInMinimum);
                     } else if (hValue > hBlendOutMinimum && hValue <= hBlendOutMaximum) {
                         // Blend out...
                         hBlended = 1 - ((hValue - hBlendOutMinimum) / (hBlendOutMaximum - hBlendOutMinimum));
                     }
                     // Subtract slope...
                     float sValue = slopeMapData[Px, Py];
                     hBlended -= sValue;
                     if (hBlended < 0) {
                         hBlended = 0;
                     }
                     splatMapData[Px, Py, i] = hBlended;
                 }
             }
         }
         // Generate splat maps...
         textureProgressDelegate("Procedural Terrain Texture", "Generating splat map. Please wait.", 0.9f);
         terData.SetAlphamaps(0, 0, splatMapData);
         // Clean up...
         heightMapData = null;
         slopeMapData = null;
         splatMapData = null;
     }
     catch (Exception e) {
         // Clean up...
         heightMapData = null;
         slopeMapData = null;
         splatMapData = null;
         Debug.LogError("An error occurred: "+e);
     }
 }
예제 #2
0
 public void TextureTerrain(float[] slopeStops, float[] heightStops, Texture2D[] textures)
 {
     if (slopeStops.Length != 2) {
         Debug.LogError("Error: slopeStops must have 2 values");
         return;
     }
     if (heightStops.Length > 8) {
         Debug.LogError("Error: heightStops must have no more than 8 values");
         return;
     }
     if (heightStops.Length % 2 != 0) {
         Debug.LogError("Error: heightStops must have an even number of values");
         return;
     }
     int numTextures = textures.Length;
     int numTexturesByStops = (heightStops.Length / 2) + 2;
     if (numTextures != numTexturesByStops) {
         Debug.LogError("Error: heightStops contains an incorrect number of values");
         return;
     }
     foreach (float stop in slopeStops) {
         if (stop < 0 || stop > 90) {
             Debug.LogError("Error: The value of all slopeStops must be in the range 0.0 to 90.0");
             return;
         }
     }
     foreach (float stop in heightStops) {
         if (stop < 0 || stop > 1) {
             Debug.LogError("Error: The value of all heightStops must be in the range 0.0 to 1.0");
             return;
         }
     }
     Terrain ter = (Terrain) GetComponent(typeof(Terrain));
     TerrainData terData = ter.terrainData;
     splatPrototypes = terData.splatPrototypes;
     deleteAllSplatPrototypes();
     int n = 0;
     foreach (Texture2D tex in textures) {
         addSplatPrototype(tex, n);
         n++;
     }
     slopeBlendMinAngle = slopeStops[0];
     slopeBlendMaxAngle = slopeStops[1];
     n = 0;
     foreach (float stop in heightStops) {
         heightBlendPoints[n] = stop;
         n++;
     }
     terData.splatPrototypes = splatPrototypes;
     TextureProgressDelegate textureProgressDelegate = new TextureProgressDelegate(dummyTextureProgress);
     textureTerrain(textureProgressDelegate);
 }