private void Weather(int width, int height, float T, Vector2[] neighbs, float[,] buffer) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { buffer[x, y] = Overworld.Map.Map[x, y].Height * Overworld.Map.Map[x, y].Faults; } } int weatheringIters = 10; for (int iter = 0; iter < weatheringIters; iter++) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Vector2 p = new Vector2(x, y); Vector2 maxDiffNeigh = Vector2.Zero; float maxDiff = 0; float totalDiff = 0; float h = OverworldImageOperations.GetHeight(buffer, p); float lowestNeighbor = 0.0f; for (int i = 0; i < 4; i++) { float nh = OverworldImageOperations.GetHeight(buffer, p + neighbs[i]); float diff = h - nh; totalDiff += diff; if (diff > maxDiff) { maxDiffNeigh = neighbs[i]; maxDiff = diff; lowestNeighbor = nh; } } if (maxDiff > T) { OverworldImageOperations.AddValue(Overworld.Map.Map, p + maxDiffNeigh, OverworldField.Weathering, (float)(maxDiff * 0.4f)); OverworldImageOperations.AddValue(Overworld.Map.Map, p, OverworldField.Weathering, (float)(-maxDiff * 0.4f)); } } } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Vector2 p = new Vector2(x, y); float w = OverworldImageOperations.GetValue(Overworld.Map.Map, p, OverworldField.Weathering); OverworldImageOperations.AddHeight(buffer, p, w); Overworld.Map.Map[x, y].Weathering = 0.0f; } } } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Overworld.Map.Map[x, y].Weathering = buffer[x, y] - Overworld.Map.Map[x, y].Height * Overworld.Map.Map[x, y].Faults; } } }
private void Erode(int width, int height, float seaLevel, OverworldCell[,] heightMap, int numRains, int rainLength, int numRainSamples, float[,] buffer) { float remaining = 1.0f - Progress - 0.2f; float orig = Progress; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { buffer[x, y] = heightMap[x, y].Height; } } for (int i = 0; i < numRains; i++) { Progress = orig + remaining * ((float)i / (float)numRains); Vector2 currentPos = new Vector2(0, 0); Vector2 bestPos = currentPos; float bestHeight = 0.0f; for (int k = 0; k < numRainSamples; k++) { int randX = Random.Next(1, width - 1); int randY = Random.Next(1, height - 1); currentPos = new Vector2(randX, randY); float h = OverworldImageOperations.GetHeight(buffer, currentPos); if (h > bestHeight) { bestHeight = h; bestPos = currentPos; } } currentPos = bestPos; const float erosionRate = 0.9f; Vector2 velocity = Vector2.Zero; for (int j = 0; j < rainLength; j++) { Vector2 g = OverworldImageOperations.GetMinNeighbor(buffer, currentPos); float h = OverworldImageOperations.GetHeight(buffer, currentPos); if (h < seaLevel || g.LengthSquared() < 1e-12) { break; } OverworldImageOperations.MinBlend(Overworld.Map.Map, currentPos, erosionRate * OverworldImageOperations.GetValue(Overworld.Map.Map, currentPos, OverworldField.Erosion), OverworldField.Erosion); velocity = 0.1f * g + 0.7f * velocity + 0.2f * MathFunctions.RandVector2Circle(); currentPos += velocity; } } }