diff options
6 files changed, 176 insertions, 14 deletions
diff --git a/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs b/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs index a609623..f52d25a 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs | |||
@@ -277,7 +277,7 @@ namespace OpenSim.Region.Terrain | |||
277 | resultText += "terrain save grdmap <filename> <gradient map> - creates a PNG snapshot of the region using a named gradient map\n"; | 277 | resultText += "terrain save grdmap <filename> <gradient map> - creates a PNG snapshot of the region using a named gradient map\n"; |
278 | resultText += "terrain rescale <min> <max> - rescales a terrain to be between <min> and <max> meters high\n"; | 278 | resultText += "terrain rescale <min> <max> - rescales a terrain to be between <min> and <max> meters high\n"; |
279 | resultText += "terrain fill <val> - fills a terrain at the specified height\n"; | 279 | resultText += "terrain fill <val> - fills a terrain at the specified height\n"; |
280 | resultText += "terrain erode aerobic <windspeed> <pickupmin> <dropmin> <carry> <rounds> <lowest>\n"; | 280 | resultText += "terrain erode aerobic <windspeed> <pickupmin> <dropmin> <carry> <rounds> <lowest t/f> <fluid dynamics t/f>\n"; |
281 | resultText += "terrain erode thermal <talus> <rounds> <carry>\n"; | 281 | resultText += "terrain erode thermal <talus> <rounds> <carry>\n"; |
282 | resultText += "terrain erode hydraulic <rain> <evaporation> <solubility> <frequency> <rounds>\n"; | 282 | resultText += "terrain erode hydraulic <rain> <evaporation> <solubility> <frequency> <rounds>\n"; |
283 | resultText += "terrain multiply <val> - multiplies a terrain by <val>\n"; | 283 | resultText += "terrain multiply <val> - multiplies a terrain by <val>\n"; |
@@ -426,11 +426,14 @@ namespace OpenSim.Region.Terrain | |||
426 | 426 | ||
427 | private bool ConsoleErosion(string[] args, ref string resultText) | 427 | private bool ConsoleErosion(string[] args, ref string resultText) |
428 | { | 428 | { |
429 | double min = heightmap.FindMin(); | ||
430 | double max = heightmap.FindMax(); | ||
431 | |||
429 | switch (args[1].ToLower()) | 432 | switch (args[1].ToLower()) |
430 | { | 433 | { |
431 | case "aerobic": | 434 | case "aerobic": |
432 | // WindSpeed, PickupMinimum,DropMinimum,Carry,Rounds,Lowest | 435 | // WindSpeed, PickupMinimum,DropMinimum,Carry,Rounds,Lowest |
433 | heightmap.AerobicErosion(Convert.ToDouble(args[2]), Convert.ToDouble(args[3]), Convert.ToDouble(args[4]), Convert.ToDouble(args[5]), Convert.ToInt32(args[6]), Convert.ToBoolean(args[7]), true); | 436 | heightmap.AerobicErosion(Convert.ToDouble(args[2]), Convert.ToDouble(args[3]), Convert.ToDouble(args[4]), Convert.ToDouble(args[5]), Convert.ToInt32(args[6]), Convert.ToBoolean(args[7]), Convert.ToBoolean(args[8])); |
434 | break; | 437 | break; |
435 | case "thermal": | 438 | case "thermal": |
436 | heightmap.ThermalWeathering(Convert.ToDouble(args[2]), Convert.ToInt32(args[3]), Convert.ToDouble(args[4])); | 439 | heightmap.ThermalWeathering(Convert.ToDouble(args[2]), Convert.ToInt32(args[3]), Convert.ToDouble(args[4])); |
@@ -444,6 +447,9 @@ namespace OpenSim.Region.Terrain | |||
444 | resultText = "Unknown erosion type"; | 447 | resultText = "Unknown erosion type"; |
445 | return false; | 448 | return false; |
446 | } | 449 | } |
450 | |||
451 | heightmap.Normalise(min, max); | ||
452 | |||
447 | tainted++; | 453 | tainted++; |
448 | return true; | 454 | return true; |
449 | } | 455 | } |
diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs index e6e5a9a..1750418 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs | |||
@@ -257,5 +257,21 @@ namespace libTerrain | |||
257 | { | 257 | { |
258 | return Sum() / (w * h); | 258 | return Sum() / (w * h); |
259 | } | 259 | } |
260 | |||
261 | public bool ContainsNaN() | ||
262 | { | ||
263 | int x, y; | ||
264 | for (x = 0; x < w; x++) | ||
265 | { | ||
266 | for (y = 0; y < h; y++) | ||
267 | { | ||
268 | double elm = map[x, y]; | ||
269 | |||
270 | if (Double.IsNaN(elm)) | ||
271 | return true; | ||
272 | } | ||
273 | } | ||
274 | return false; | ||
275 | } | ||
260 | } | 276 | } |
261 | } | 277 | } |
diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs index b147004..c0173c0 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs | |||
@@ -57,13 +57,16 @@ namespace libTerrain | |||
57 | 57 | ||
58 | public void SaveImage(string filename) | 58 | public void SaveImage(string filename) |
59 | { | 59 | { |
60 | Channel outmap = this.Copy(); | ||
61 | outmap.Normalise(); | ||
62 | |||
60 | Bitmap bit = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb); | 63 | Bitmap bit = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb); |
61 | int x, y; | 64 | int x, y; |
62 | for (x = 0; x < w; x++) | 65 | for (x = 0; x < w; x++) |
63 | { | 66 | { |
64 | for (y = 0; y < h; y++) | 67 | for (y = 0; y < h; y++) |
65 | { | 68 | { |
66 | int val = Math.Min(255, (int)(map[x,y] * 255)); | 69 | int val = Math.Min(255, (int)(outmap.map[x,y] * 255)); |
67 | Color col = Color.FromArgb(val,val,val); | 70 | Color col = Color.FromArgb(val,val,val); |
68 | bit.SetPixel(x, y, col); | 71 | bit.SetPixel(x, y, col); |
69 | } | 72 | } |
diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs index a39db50..e6b18f4 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs | |||
@@ -43,13 +43,20 @@ namespace libTerrain | |||
43 | 43 | ||
44 | int x, y; | 44 | int x, y; |
45 | 45 | ||
46 | for (x = 0; x < w; x++) | 46 | if (max != min) |
47 | { | 47 | { |
48 | for (y = 0; y < h; y++) | 48 | for (x = 0; x < w; x++) |
49 | { | 49 | { |
50 | map[x, y] = (map[x, y] - min) * (1.0 / (max - min)); | 50 | for (y = 0; y < h; y++) |
51 | { | ||
52 | map[x, y] = (map[x, y] - min) * (1.0 / (max - min)); | ||
53 | } | ||
51 | } | 54 | } |
52 | } | 55 | } |
56 | else | ||
57 | { | ||
58 | this.Fill(0.5); | ||
59 | } | ||
53 | 60 | ||
54 | return this; | 61 | return this; |
55 | } | 62 | } |
@@ -244,6 +251,76 @@ namespace libTerrain | |||
244 | map = manipulated; | 251 | map = manipulated; |
245 | } | 252 | } |
246 | 253 | ||
254 | public void Distort(Channel mask, double str) | ||
255 | { | ||
256 | // Simple pertubation filter | ||
257 | double[,] manipulated = new double[w, h]; | ||
258 | |||
259 | double amount; | ||
260 | |||
261 | int x, y; | ||
262 | for (x = 0; x < w; x++) | ||
263 | { | ||
264 | for (y = 0; y < h; y++) | ||
265 | { | ||
266 | amount = mask.map[x, y]; | ||
267 | double offset_x = (double)x + (amount * str) - (0.5 * str); | ||
268 | double offset_y = (double)y + (amount * str) - (0.5 * str); | ||
269 | |||
270 | if (offset_x > w) | ||
271 | offset_x = w - 1; | ||
272 | if (offset_y > h) | ||
273 | offset_y = h - 1; | ||
274 | if (offset_y < 0) | ||
275 | offset_y = 0; | ||
276 | if (offset_x < 0) | ||
277 | offset_x = 0; | ||
278 | |||
279 | double p = GetBilinearInterpolate(offset_x, offset_y); | ||
280 | manipulated[x, y] = p; | ||
281 | SetDiff(x, y); | ||
282 | } | ||
283 | } | ||
284 | map = manipulated; | ||
285 | |||
286 | } | ||
287 | |||
288 | public void Distort(Channel mask, Channel mask2, double str) | ||
289 | { | ||
290 | // Simple pertubation filter | ||
291 | double[,] manipulated = new double[w, h]; | ||
292 | |||
293 | double amountX; | ||
294 | double amountY; | ||
295 | |||
296 | int x, y; | ||
297 | for (x = 0; x < w; x++) | ||
298 | { | ||
299 | for (y = 0; y < h; y++) | ||
300 | { | ||
301 | amountX = mask.map[x, y]; | ||
302 | amountY = mask2.map[x, y]; | ||
303 | double offset_x = (double)x + (amountX * str) - (0.5 * str); | ||
304 | double offset_y = (double)y + (amountY * str) - (0.5 * str); | ||
305 | |||
306 | if (offset_x > w) | ||
307 | offset_x = w - 1; | ||
308 | if (offset_y > h) | ||
309 | offset_y = h - 1; | ||
310 | if (offset_y < 0) | ||
311 | offset_y = 0; | ||
312 | if (offset_x < 0) | ||
313 | offset_x = 0; | ||
314 | |||
315 | double p = GetBilinearInterpolate(offset_x, offset_y); | ||
316 | manipulated[x, y] = p; | ||
317 | SetDiff(x, y); | ||
318 | } | ||
319 | } | ||
320 | map = manipulated; | ||
321 | |||
322 | } | ||
323 | |||
247 | public Channel Blend(Channel other, double amount) | 324 | public Channel Blend(Channel other, double amount) |
248 | { | 325 | { |
249 | int x, y; | 326 | int x, y; |
diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs index f4dfe1d..fecb748 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs | |||
@@ -76,13 +76,19 @@ namespace libTerrain | |||
76 | /// <param name="lowest">Drop sediment at the lowest point?</param> | 76 | /// <param name="lowest">Drop sediment at the lowest point?</param> |
77 | public void AerobicErosion(double windspeed, double pickupTalusMinimum, double dropTalusMinimum, double carry, int rounds, bool lowest, bool usingFluidDynamics) | 77 | public void AerobicErosion(double windspeed, double pickupTalusMinimum, double dropTalusMinimum, double carry, int rounds, bool lowest, bool usingFluidDynamics) |
78 | { | 78 | { |
79 | bool debugImages = true; | ||
80 | |||
79 | Channel wind = new Channel(w, h) ; | 81 | Channel wind = new Channel(w, h) ; |
80 | Channel sediment = new Channel(w, h); | 82 | Channel sediment = new Channel(w, h); |
81 | int x, y, i, j; | 83 | int x, y, i, j; |
82 | 84 | ||
85 | this.Normalise(); | ||
86 | |||
83 | wind = this.Copy(); | 87 | wind = this.Copy(); |
84 | wind.Normalise(); // Cheap wind calculations | 88 | wind.Noise(); |
85 | wind *= windspeed; | 89 | |
90 | if (debugImages) | ||
91 | wind.SaveImage("testimg/wind_start.png"); | ||
86 | 92 | ||
87 | if (usingFluidDynamics) | 93 | if (usingFluidDynamics) |
88 | { | 94 | { |
@@ -90,9 +96,12 @@ namespace libTerrain | |||
90 | } | 96 | } |
91 | else | 97 | else |
92 | { | 98 | { |
93 | wind.Pertubation(30); // Can do better later | 99 | wind.Pertubation(30); |
94 | } | 100 | } |
95 | 101 | ||
102 | if (debugImages) | ||
103 | wind.SaveImage("testimg/wind_begin.png"); | ||
104 | |||
96 | for (i = 0; i < rounds; i++) | 105 | for (i = 0; i < rounds; i++) |
97 | { | 106 | { |
98 | // Convert some rocks to sand | 107 | // Convert some rocks to sand |
@@ -127,7 +136,14 @@ namespace libTerrain | |||
127 | if (usingFluidDynamics) | 136 | if (usingFluidDynamics) |
128 | { | 137 | { |
129 | sediment.navierStokes(7, 0.1, 0.0, 0.1); | 138 | sediment.navierStokes(7, 0.1, 0.0, 0.1); |
130 | wind.navierStokes(10, 0.1, 0.0, 0.0); | 139 | |
140 | Channel noiseChan = new Channel(w, h); | ||
141 | noiseChan.Noise(); | ||
142 | wind.Blend(noiseChan, 0.01); | ||
143 | |||
144 | wind.navierStokes(10, 0.1, 0.01, 0.01); | ||
145 | |||
146 | sediment.Distort(wind, windspeed); | ||
131 | } | 147 | } |
132 | else | 148 | else |
133 | { | 149 | { |
@@ -137,6 +153,9 @@ namespace libTerrain | |||
137 | sediment.seed++; | 153 | sediment.seed++; |
138 | } | 154 | } |
139 | 155 | ||
156 | if (debugImages) | ||
157 | wind.SaveImage("testimg/wind_" + i.ToString() + ".png"); | ||
158 | |||
140 | // Convert some sand to rock | 159 | // Convert some sand to rock |
141 | for (x = 1; x < w - 1; x++) | 160 | for (x = 1; x < w - 1; x++) |
142 | { | 161 | { |
@@ -174,11 +193,21 @@ namespace libTerrain | |||
174 | } | 193 | } |
175 | } | 194 | } |
176 | 195 | ||
196 | if (debugImages) | ||
197 | sediment.SaveImage("testimg/sediment_" + i.ToString() + ".png"); | ||
198 | |||
199 | wind.Normalise(); | ||
200 | wind *= windspeed; | ||
201 | |||
202 | this.Normalise(); | ||
177 | } | 203 | } |
178 | 204 | ||
179 | Channel myself = this; | 205 | Channel myself = this; |
180 | myself += sediment; | 206 | myself += sediment; |
181 | myself.Normalise(); | 207 | myself.Normalise(); |
208 | |||
209 | if (debugImages) | ||
210 | this.SaveImage("testimg/output.png"); | ||
182 | } | 211 | } |
183 | } | 212 | } |
184 | } \ No newline at end of file | 213 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/NavierStokes.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/NavierStokes.cs index a035098..8a111ed 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/NavierStokes.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/NavierStokes.cs | |||
@@ -211,11 +211,11 @@ namespace libTerrain | |||
211 | int i; | 211 | int i; |
212 | int j; | 212 | int j; |
213 | 213 | ||
214 | for (i = 0; i <= N; i++) | 214 | for (i = 1; i <= N; i++) |
215 | { | 215 | { |
216 | for (j = 0; j <= N; j++) | 216 | for (j = 1; j <= N; j++) |
217 | { | 217 | { |
218 | doubles[i, j] = dens[nsIX(i, j, N)]; | 218 | doubles[i - 1, j - 1] = dens[nsIX(i, j, N)]; |
219 | } | 219 | } |
220 | } | 220 | } |
221 | } | 221 | } |
@@ -229,7 +229,7 @@ namespace libTerrain | |||
229 | { | 229 | { |
230 | for (j = 1; j <= N; j++) | 230 | for (j = 1; j <= N; j++) |
231 | { | 231 | { |
232 | dens[nsIX(i, j, N)] = doubles[i, j]; | 232 | dens[nsIX(i, j, N)] = doubles[i - 1, j - 1]; |
233 | } | 233 | } |
234 | } | 234 | } |
235 | } | 235 | } |
@@ -272,5 +272,36 @@ namespace libTerrain | |||
272 | { | 272 | { |
273 | nsSimulate(this.h, rounds, dt, diff, visc); | 273 | nsSimulate(this.h, rounds, dt, diff, visc); |
274 | } | 274 | } |
275 | |||
276 | public void navierStokes(int rounds, double dt, double diff, double visc, ref double[,] uret, ref double[,] vret) | ||
277 | { | ||
278 | int N = this.h; | ||
279 | |||
280 | int size = (N * 2) * (N * 2); | ||
281 | |||
282 | double[] u = new double[size]; // Force, X axis | ||
283 | double[] v = new double[size]; // Force, Y axis | ||
284 | double[] u_prev = new double[size]; | ||
285 | double[] v_prev = new double[size]; | ||
286 | double[] dens = new double[size]; | ||
287 | double[] dens_prev = new double[size]; | ||
288 | |||
289 | nsDoublesToBuffer(this.map, N, ref dens); | ||
290 | nsDoublesToBuffer(this.map, N, ref dens_prev); | ||
291 | |||
292 | for (int i = 0; i < rounds; i++) | ||
293 | { | ||
294 | u_prev = u; | ||
295 | v_prev = v; | ||
296 | dens_prev = dens; | ||
297 | |||
298 | nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt); | ||
299 | nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt); | ||
300 | } | ||
301 | |||
302 | nsBufferToDoubles(ref u, N, ref uret); | ||
303 | nsBufferToDoubles(ref v, N, ref vret); | ||
304 | nsBufferToDoubles(ref dens, N, ref this.map); | ||
305 | } | ||
275 | } | 306 | } |
276 | } \ No newline at end of file | 307 | } \ No newline at end of file |