aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs145
1 files changed, 144 insertions, 1 deletions
diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs
index 0cec05d..e3463c1 100644
--- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs
+++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs
@@ -1 +1,144 @@
1/* Needs BSD rewrite */ \ No newline at end of file 1/*
2* Copyright (c) Contributors, http://www.openmetaverse.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30using System.Collections.Generic;
31using System.Text;
32
33namespace libTerrain
34{
35 partial class Channel
36 {
37 public void hydraulicErosion(Channel rain, double evaporation, double solubility, int frequency, int rounds)
38 {
39 Channel water = new Channel(w, h);
40 Channel sediment = new Channel(w, h);
41 Channel terrain = this;
42 Channel waterFlow = new Channel(w, h);
43
44 NEIGHBOURS type = NEIGHBOURS.NEIGHBOUR_MOORE;
45 int NEIGHBOUR_ME = 4;
46
47 int NEIGHBOUR_MAX = type == NEIGHBOURS.NEIGHBOUR_MOORE ? 9 : 5;
48
49 for (int i = 0; i < rounds; i++)
50 {
51 water += rain;
52
53 sediment = terrain * water;
54 terrain -= sediment;
55
56 for (int x = 1; x < w - 1; x++)
57 {
58 for (int y = 1; y < h - 1; y++)
59 {
60 double[] heights = new double[NEIGHBOUR_MAX];
61 double[] diffs = new double[NEIGHBOUR_MAX];
62
63 double heightCenter = map[x, y];
64
65 for (int j = 0; j < NEIGHBOUR_MAX; j++)
66 {
67 if (j != NEIGHBOUR_ME)
68 {
69 int[] coords = neighbours(type, j);
70 coords[0] += x;
71 coords[1] += y;
72
73 heights[j] = map[coords[0], coords[1]] + water.map[coords[0], coords[1]] + sediment.map[coords[0], coords[1]];
74 diffs[j] = heightCenter - heights[j];
75 }
76 }
77
78 double totalHeight = 0;
79 double totalHeightDiff = 0;
80 int totalCellsCounted = 1;
81
82 for (int j = 0; j < NEIGHBOUR_MAX; j++)
83 {
84 if (j != NEIGHBOUR_ME)
85 {
86 if (diffs[j] > 0)
87 {
88 totalHeight += heights[j];
89 totalHeightDiff += diffs[j];
90 totalCellsCounted++;
91 }
92 }
93 }
94
95 if (totalCellsCounted == 1)
96 continue;
97
98 double averageHeight = totalHeight / totalCellsCounted;
99 double waterAmount = Math.Min(water.map[x, y], heightCenter - averageHeight);
100
101 // TODO: Check this.
102 waterFlow.map[x, y] += waterFlow.map[x, y] - waterAmount;
103
104 double totalInverseDiff = waterAmount / totalHeightDiff;
105
106 for (int j = 0; j < NEIGHBOUR_MAX; j++)
107 {
108 if (j != NEIGHBOUR_ME)
109 {
110 int[] coords = neighbours(type, j);
111 coords[0] += x;
112 coords[1] += y;
113
114 if (diffs[j] > 0)
115 {
116 waterFlow.setWrap(coords[0], coords[1], waterFlow.map[coords[0], coords[1]] + diffs[j] * totalInverseDiff);
117 }
118 }
119 }
120 }
121 }
122
123 water += waterFlow;
124 waterFlow.fill(0);
125
126 water *= evaporation;
127
128 for (int x = 0; x < w; x++)
129 {
130 for (int y = 0; y < h; y++)
131 {
132 double deposition = sediment.map[x, y] - water.map[x, y] * solubility;
133 if (deposition > 0)
134 {
135 sediment.map[x, y] -= deposition;
136 terrain.map[x, y] += deposition;
137 }
138 }
139 }
140
141 }
142 }
143 }
144} \ No newline at end of file