29 using OpenSim.Region.Framework.Interfaces;
30 using OpenSim.Region.Framework.Scenes;
39 private const double rainHeight = 0.2;
40 private const int rounds = 10;
41 private const NeighbourSystem type = NeighbourSystem.Moore;
42 private const double waterSaturation = 0.30;
44 #region Supporting Functions
46 private static int[] Neighbours(NeighbourSystem neighbourType,
int index)
48 int[] coord =
new int[2];
52 switch (neighbourType)
54 case NeighbourSystem.Moore:
107 case NeighbourSystem.VonNeumann:
144 private enum NeighbourSystem
152 #region ITerrainPaintableEffect Members
155 double strength,
double duration,
int startX,
int endX,
int startY,
int endY)
157 strength = TerrainUtil.MetersToSphericalStrength(strength);
167 for (x = startX; x <= endX; x++)
169 for (y = startY; y <= endY; y++)
172 water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration);
176 for (
int i = 0; i < rounds; i++)
179 for (x = startX; x <= endX; x++)
181 for (y = startY; y <= endY; y++)
185 const double solConst = (1.0 / rounds);
186 double sedDelta = water[x, y] * solConst;
187 map[x, y] -= sedDelta;
188 sediment[x, y] += sedDelta;
194 for (x = startX; x <= endX; x++)
196 for (y = startY; y <= endY; y++)
198 if (water[x, y] <= 0)
204 double altitudeTotal = 0.0;
205 double altitudeMe = map[x, y] + water[x, y];
207 const int NEIGHBOUR_ME = 4;
208 const int NEIGHBOUR_MAX = 9;
210 for (
int j = 0; j < NEIGHBOUR_MAX; j++)
212 if (j != NEIGHBOUR_ME)
214 int[] coords = Neighbours(type, j);
219 if (coords[0] > map.
Width - 1)
221 if (coords[1] > map.
Height - 1)
229 double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]];
232 if (altitudeNeighbour - altitudeMe < 0)
236 altitudeTotal += altitudeNeighbour;
244 double altitudeAvg = altitudeTotal / neighbours;
247 for (
int j = 0; j < NEIGHBOUR_MAX; j++)
249 if (j != NEIGHBOUR_ME)
251 int[] coords = Neighbours(type, j);
256 if (coords[0] > map.
Width - 1)
258 if (coords[1] > map.
Height - 1)
270 double altitudeDelta = altitudeMe - altitudeAvg;
272 if (altitudeDelta < 0)
276 double waterMin = Math.Min(water[x, y], altitudeDelta);
277 double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]])
280 double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]);
282 if (sedimentDelta > 0)
284 sediment[x, y] -= sedimentDelta;
285 sediment[coords[0], coords[1]] += sedimentDelta;
294 for (x = 0; x < water.Width; x++)
296 for (y = 0; y < water.Height; y++)
298 water[x, y] *= 1.0 - (rainHeight / rounds);
300 double waterCapacity = waterSaturation * water[x, y];
302 double sedimentDeposit = sediment[x, y] - waterCapacity;
303 if (sedimentDeposit > 0)
307 sediment[x, y] -= sedimentDeposit;
308 map[x, y] += sedimentDeposit;
316 for (x = 0; x < water.Width; x++)
317 for (y = 0; y < water.Height; y++)
318 if (mask[x, y] && sediment[x, y] > 0)
319 map[x, y] += sediment[x, y];
void PaintEffect(ITerrainChannel map, bool[,] mask, double rx, double ry, double rz, double strength, double duration, int startX, int endX, int startY, int endY)
Interactive OpenSim region server
A new version of the old Channel class, simplified