public void erodeAllTerrain(ErosionProgressDelegate erosionProgressDelegate) { erosionMode = ErosionMode.Filter; // Check enum vars... convertIntVarsToEnums(); // Error checking... Terrain ter = (Terrain) GetComponent(typeof(Terrain)); if (ter == null) { return; } try { TerrainData terData = ter.terrainData; int Tw = terData.heightmapWidth; int Th = terData.heightmapHeight; float[,] heightMap = terData.GetHeights(0, 0, Tw, Th); // Set the number of iterations and pass the height array to the appropriate erosion script... int iterations; switch (erosionType) { case ErosionType.Thermal: iterations = thermalIterations; heightMap = fastErosion(heightMap, new Vector2(Tw, Th), iterations, erosionProgressDelegate); break; case ErosionType.Hydraulic: iterations = hydraulicIterations; switch (hydraulicType) { case HydraulicType.Fast: heightMap = fastErosion(heightMap, new Vector2(Tw, Th), iterations, erosionProgressDelegate); break; case HydraulicType.Full: heightMap = fullHydraulicErosion(heightMap, new Vector2(Tw, Th), iterations, erosionProgressDelegate); break; case HydraulicType.Velocity: heightMap = velocityHydraulicErosion(heightMap, new Vector2(Tw, Th), iterations, erosionProgressDelegate); break; } break; case ErosionType.Tidal: Vector3 terSize = terData.size; if (tidalSeaLevel >= transform.position.y && tidalSeaLevel <= transform.position.y + terSize.y) { iterations = tidalIterations; heightMap = fastErosion(heightMap, new Vector2(Tw, Th), iterations, erosionProgressDelegate); } else { Debug.LogError("Sea level does not intersect terrain object. Erosion operation failed."); } break; case ErosionType.Wind: iterations = windIterations; heightMap = windErosion(heightMap, new Vector2(Tw, Th), iterations, erosionProgressDelegate); break; default: return; } // Apply it to the terrain object terData.SetHeights(0, 0, heightMap); } catch (Exception e) { Debug.LogError("An error occurred: "+e); } }
private void erodeTerrainWithBrush() { erosionMode = ErosionMode.Brush; // Error checking... Terrain ter = (Terrain) GetComponent(typeof(Terrain)); if (ter == null) { return; } int Px = 0; int Py = 0; try { TerrainData terData = ter.terrainData; int Tw = terData.heightmapWidth; int Th = terData.heightmapHeight; Vector3 Ts = terData.size; int Sx = (int) Mathf.Floor((Tw / Ts.x) * brushSize); int Sy = (int) Mathf.Floor((Th / Ts.z) * brushSize); Vector3 localBrushPosition = transform.InverseTransformPoint(brushPosition); Px = (int) Mathf.Round((localBrushPosition.x / Ts.x) * Tw - (Sx / 2)); Py = (int) Mathf.Round((localBrushPosition.z / Ts.z) * Th - (Sy / 2)); if (Px < 0) { Sx = Sx + Px; Px = 0; } if (Py < 0) { Sy = Sy + Py; Py = 0; } if (Px + Sx > Tw) { Sx = Tw - Px; } if (Py + Sy > Th) { Sy = Th - Py; } float[,] heightMap = terData.GetHeights(Px, Py, Sx, Sy); Sx = heightMap.GetLength(1); Sy = heightMap.GetLength(0); // Pass the height array to the erosion script... float[,] erodedheightMap = (float[,]) heightMap.Clone(); ErosionProgressDelegate erosionProgressDelegate = new ErosionProgressDelegate(dummyErosionProgress); erodedheightMap = fastErosion(erodedheightMap, new Vector2(Sx, Sy), 1, erosionProgressDelegate); // Apply it to the terrain object float sampleRadius = Sx / 2.0f; for (int Ty = 0; Ty < Sx; Ty++) { for (int Tx = 0; Tx < Sy; Tx++) { float oldHeightAtPoint = heightMap[Tx, Ty]; float newHeightAtPoint = erodedheightMap[Tx, Ty]; float distancefromOrigin = Vector2.Distance(new Vector2(Tx, Ty), new Vector2(sampleRadius, sampleRadius)); float weightAtPoint = 1.0f - ((distancefromOrigin - (sampleRadius - (sampleRadius * brushSoftness))) / (sampleRadius * brushSoftness)); if (weightAtPoint < 0.0f) { weightAtPoint = 0.0f; } else if (weightAtPoint > 1.0f) { weightAtPoint = 1.0f; } weightAtPoint *= brushOpacity; float blendedHeightAtPoint = (newHeightAtPoint * weightAtPoint) + (oldHeightAtPoint * (1.0f - weightAtPoint)); heightMap[Tx, Ty] = blendedHeightAtPoint; } } terData.SetHeights(Px, Py, heightMap); } catch (Exception e) { Debug.LogError("A brush error occurred: "+e); } }