diff options
Start of the OpenSim library , for now only contains a few textures.
Diffstat (limited to 'OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators')
4 files changed, 775 insertions, 775 deletions
diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs index 589d360..5d2b4d4 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs | |||
@@ -1,213 +1,213 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://www.openmetaverse.org/ | 2 | * Copyright (c) Contributors, http://www.openmetaverse.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Text; | 31 | using System.Text; |
32 | 32 | ||
33 | namespace libTerrain | 33 | namespace libTerrain |
34 | { | 34 | { |
35 | partial class Channel | 35 | partial class Channel |
36 | { | 36 | { |
37 | // Ideas for Aerobic erosion | 37 | // Ideas for Aerobic erosion |
38 | // | 38 | // |
39 | // Unlike thermal (gravity) and hydraulic (water suspension) | 39 | // Unlike thermal (gravity) and hydraulic (water suspension) |
40 | // aerobic erosion should displace mass by moving sediment | 40 | // aerobic erosion should displace mass by moving sediment |
41 | // in "hops". The length of the hop being dictated by the | 41 | // in "hops". The length of the hop being dictated by the |
42 | // presence of sharp cliffs and wind speed. | 42 | // presence of sharp cliffs and wind speed. |
43 | 43 | ||
44 | // The ability to pickup sediment is defined by the total | 44 | // The ability to pickup sediment is defined by the total |
45 | // surface area, such that: | 45 | // surface area, such that: |
46 | // 0 0 0 | 46 | // 0 0 0 |
47 | // 0 1 0 | 47 | // 0 1 0 |
48 | // 0 0 0 | 48 | // 0 0 0 |
49 | // Would be the best possible value for sediment to be | 49 | // Would be the best possible value for sediment to be |
50 | // picked up (total difference = 8) and flatter land | 50 | // picked up (total difference = 8) and flatter land |
51 | // will erode less quickly. | 51 | // will erode less quickly. |
52 | 52 | ||
53 | // Suspended particles assist the erosion process by hitting | 53 | // Suspended particles assist the erosion process by hitting |
54 | // the surface and chiselling additional particles off faster | 54 | // the surface and chiselling additional particles off faster |
55 | // than alone. | 55 | // than alone. |
56 | 56 | ||
57 | // Particles are deposited when one of two conditions is met | 57 | // Particles are deposited when one of two conditions is met |
58 | // First: | 58 | // First: |
59 | // When particles hit a wall - such that the | 59 | // When particles hit a wall - such that the |
60 | // wind direction points at a difference >= the | 60 | // wind direction points at a difference >= the |
61 | // deposition mininum talus. | 61 | // deposition mininum talus. |
62 | // Second: | 62 | // Second: |
63 | // When wind speed is lowered to below the minimum | 63 | // When wind speed is lowered to below the minimum |
64 | // required for transit. An idea for this is to | 64 | // required for transit. An idea for this is to |
65 | // use the navier-stokes algorithms for simulating | 65 | // use the navier-stokes algorithms for simulating |
66 | // pressure across the terrain. | 66 | // pressure across the terrain. |
67 | 67 | ||
68 | /// <summary> | 68 | /// <summary> |
69 | /// An experimental erosion algorithm developed by Adam. Moves sediment by factoring the surface area of each height point. | 69 | /// An experimental erosion algorithm developed by Adam. Moves sediment by factoring the surface area of each height point. |
70 | /// </summary> | 70 | /// </summary> |
71 | /// <param name="windspeed">0..1 The speed of the wind</param> | 71 | /// <param name="windspeed">0..1 The speed of the wind</param> |
72 | /// <param name="pickup_talus_minimum">The minimum angle at which rock is eroded 0..1 (recommended: <= 0.30)</param> | 72 | /// <param name="pickup_talus_minimum">The minimum angle at which rock is eroded 0..1 (recommended: <= 0.30)</param> |
73 | /// <param name="drop_talus_minimum">The minimum angle at which rock is dropped 0..1 (recommended: >= 0.00)</param> | 73 | /// <param name="drop_talus_minimum">The minimum angle at which rock is dropped 0..1 (recommended: >= 0.00)</param> |
74 | /// <param name="carry">The percentage of rock which can be picked up to pickup 0..1</param> | 74 | /// <param name="carry">The percentage of rock which can be picked up to pickup 0..1</param> |
75 | /// <param name="rounds">The number of erosion rounds (recommended: 25+)</param> | 75 | /// <param name="rounds">The number of erosion rounds (recommended: 25+)</param> |
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 = false; | 79 | bool debugImages = false; |
80 | 80 | ||
81 | Channel wind = new Channel(w, h) ; | 81 | Channel wind = new Channel(w, h) ; |
82 | Channel sediment = new Channel(w, h); | 82 | Channel sediment = new Channel(w, h); |
83 | int x, y, i, j; | 83 | int x, y, i, j; |
84 | 84 | ||
85 | this.Normalise(); | 85 | this.Normalise(); |
86 | 86 | ||
87 | wind = this.Copy(); | 87 | wind = this.Copy(); |
88 | wind.Noise(); | 88 | wind.Noise(); |
89 | 89 | ||
90 | if (debugImages) | 90 | if (debugImages) |
91 | wind.SaveImage("testimg/wind_start.png"); | 91 | wind.SaveImage("testimg/wind_start.png"); |
92 | 92 | ||
93 | if (usingFluidDynamics) | 93 | if (usingFluidDynamics) |
94 | { | 94 | { |
95 | wind.navierStokes(20, 0.1, 0.0, 0.0); | 95 | wind.navierStokes(20, 0.1, 0.0, 0.0); |
96 | } | 96 | } |
97 | else | 97 | else |
98 | { | 98 | { |
99 | wind.Pertubation(30); | 99 | wind.Pertubation(30); |
100 | } | 100 | } |
101 | 101 | ||
102 | if (debugImages) | 102 | if (debugImages) |
103 | wind.SaveImage("testimg/wind_begin.png"); | 103 | wind.SaveImage("testimg/wind_begin.png"); |
104 | 104 | ||
105 | for (i = 0; i < rounds; i++) | 105 | for (i = 0; i < rounds; i++) |
106 | { | 106 | { |
107 | // Convert some rocks to sand | 107 | // Convert some rocks to sand |
108 | for (x = 1; x < w - 1; x++) | 108 | for (x = 1; x < w - 1; x++) |
109 | { | 109 | { |
110 | for (y = 1; y < h - 1; y++) | 110 | for (y = 1; y < h - 1; y++) |
111 | { | 111 | { |
112 | double me = Get(x, y); | 112 | double me = Get(x, y); |
113 | double surfacearea = 0.3; // Everything will erode even if it's flat. Just slower. | 113 | double surfacearea = 0.3; // Everything will erode even if it's flat. Just slower. |
114 | 114 | ||
115 | for (j = 0; j < 9; j++) | 115 | for (j = 0; j < 9; j++) |
116 | { | 116 | { |
117 | int[] coords = Neighbours(NeighbourSystem.Moore, j); | 117 | int[] coords = Neighbours(NeighbourSystem.Moore, j); |
118 | double target = Get(x + coords[0], y + coords[1]); | 118 | double target = Get(x + coords[0], y + coords[1]); |
119 | 119 | ||
120 | surfacearea += Math.Abs(target - me); | 120 | surfacearea += Math.Abs(target - me); |
121 | } | 121 | } |
122 | 122 | ||
123 | double amount = surfacearea * wind.map[x, y] * carry; | 123 | double amount = surfacearea * wind.map[x, y] * carry; |
124 | 124 | ||
125 | if (amount < 0) | 125 | if (amount < 0) |
126 | amount = 0; | 126 | amount = 0; |
127 | 127 | ||
128 | if (surfacearea > pickupTalusMinimum) | 128 | if (surfacearea > pickupTalusMinimum) |
129 | { | 129 | { |
130 | Set(x, y, map[x, y] - amount); | 130 | Set(x, y, map[x, y] - amount); |
131 | sediment.map[x, y] += amount; | 131 | sediment.map[x, y] += amount; |
132 | } | 132 | } |
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | if (usingFluidDynamics) | 136 | if (usingFluidDynamics) |
137 | { | 137 | { |
138 | sediment.navierStokes(7, 0.1, 0.0, 0.1); | 138 | sediment.navierStokes(7, 0.1, 0.0, 0.1); |
139 | 139 | ||
140 | Channel noiseChan = new Channel(w, h); | 140 | Channel noiseChan = new Channel(w, h); |
141 | noiseChan.Noise(); | 141 | noiseChan.Noise(); |
142 | wind.Blend(noiseChan, 0.01); | 142 | wind.Blend(noiseChan, 0.01); |
143 | 143 | ||
144 | wind.navierStokes(10, 0.1, 0.01, 0.01); | 144 | wind.navierStokes(10, 0.1, 0.01, 0.01); |
145 | 145 | ||
146 | sediment.Distort(wind, windspeed); | 146 | sediment.Distort(wind, windspeed); |
147 | } | 147 | } |
148 | else | 148 | else |
149 | { | 149 | { |
150 | wind.Pertubation(15); // Can do better later | 150 | wind.Pertubation(15); // Can do better later |
151 | wind.seed++; | 151 | wind.seed++; |
152 | sediment.Pertubation(10); // Sediment is blown around a bit | 152 | sediment.Pertubation(10); // Sediment is blown around a bit |
153 | sediment.seed++; | 153 | sediment.seed++; |
154 | } | 154 | } |
155 | 155 | ||
156 | if (debugImages) | 156 | if (debugImages) |
157 | wind.SaveImage("testimg/wind_" + i.ToString() + ".png"); | 157 | wind.SaveImage("testimg/wind_" + i.ToString() + ".png"); |
158 | 158 | ||
159 | // Convert some sand to rock | 159 | // Convert some sand to rock |
160 | for (x = 1; x < w - 1; x++) | 160 | for (x = 1; x < w - 1; x++) |
161 | { | 161 | { |
162 | for (y = 1; y < h - 1; y++) | 162 | for (y = 1; y < h - 1; y++) |
163 | { | 163 | { |
164 | double me = Get(x, y); | 164 | double me = Get(x, y); |
165 | double surfacearea = 0.01; // Flat land does not get deposition | 165 | double surfacearea = 0.01; // Flat land does not get deposition |
166 | double min = double.MaxValue; | 166 | double min = double.MaxValue; |
167 | int[] minside = new int[2]; | 167 | int[] minside = new int[2]; |
168 | 168 | ||
169 | for (j = 0; j < 9; j++) | 169 | for (j = 0; j < 9; j++) |
170 | { | 170 | { |
171 | int[] coords = Neighbours(NeighbourSystem.Moore, j); | 171 | int[] coords = Neighbours(NeighbourSystem.Moore, j); |
172 | double target = Get(x + coords[0], y + coords[1]); | 172 | double target = Get(x + coords[0], y + coords[1]); |
173 | 173 | ||
174 | surfacearea += Math.Abs(target - me); | 174 | surfacearea += Math.Abs(target - me); |
175 | 175 | ||
176 | if (target < min && lowest) | 176 | if (target < min && lowest) |
177 | { | 177 | { |
178 | minside = (int[])coords.Clone(); | 178 | minside = (int[])coords.Clone(); |
179 | min = target; | 179 | min = target; |
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | double amount = surfacearea * (1.0 - wind.map[x, y]) * carry; | 183 | double amount = surfacearea * (1.0 - wind.map[x, y]) * carry; |
184 | 184 | ||
185 | if (amount < 0) | 185 | if (amount < 0) |
186 | amount = 0; | 186 | amount = 0; |
187 | 187 | ||
188 | if (surfacearea > dropTalusMinimum) | 188 | if (surfacearea > dropTalusMinimum) |
189 | { | 189 | { |
190 | Set(x + minside[0], y + minside[1], map[x + minside[0], y + minside[1]] + amount); | 190 | Set(x + minside[0], y + minside[1], map[x + minside[0], y + minside[1]] + amount); |
191 | sediment.map[x, y] -= amount; | 191 | sediment.map[x, y] -= amount; |
192 | } | 192 | } |
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
196 | if (debugImages) | 196 | if (debugImages) |
197 | sediment.SaveImage("testimg/sediment_" + i.ToString() + ".png"); | 197 | sediment.SaveImage("testimg/sediment_" + i.ToString() + ".png"); |
198 | 198 | ||
199 | wind.Normalise(); | 199 | wind.Normalise(); |
200 | wind *= windspeed; | 200 | wind *= windspeed; |
201 | 201 | ||
202 | this.Normalise(); | 202 | this.Normalise(); |
203 | } | 203 | } |
204 | 204 | ||
205 | Channel myself = this; | 205 | Channel myself = this; |
206 | myself += sediment; | 206 | myself += sediment; |
207 | myself.Normalise(); | 207 | myself.Normalise(); |
208 | 208 | ||
209 | if (debugImages) | 209 | if (debugImages) |
210 | this.SaveImage("testimg/output.png"); | 210 | this.SaveImage("testimg/output.png"); |
211 | } | 211 | } |
212 | } | 212 | } |
213 | } \ No newline at end of file | 213 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs index 36da77c..fb9e21e 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs | |||
@@ -1,146 +1,146 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://www.openmetaverse.org/ | 2 | * Copyright (c) Contributors, http://www.openmetaverse.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Text; | 31 | using System.Text; |
32 | 32 | ||
33 | namespace libTerrain | 33 | namespace libTerrain |
34 | { | 34 | { |
35 | partial class Channel | 35 | partial class Channel |
36 | { | 36 | { |
37 | public void HydraulicErosion(Channel rain, double evaporation, double solubility, int frequency, int rounds) | 37 | public void HydraulicErosion(Channel rain, double evaporation, double solubility, int frequency, int rounds) |
38 | { | 38 | { |
39 | SetDiff(); | 39 | SetDiff(); |
40 | 40 | ||
41 | Channel water = new Channel(w, h); | 41 | Channel water = new Channel(w, h); |
42 | Channel sediment = new Channel(w, h); | 42 | Channel sediment = new Channel(w, h); |
43 | Channel terrain = this; | 43 | Channel terrain = this; |
44 | Channel waterFlow = new Channel(w, h); | 44 | Channel waterFlow = new Channel(w, h); |
45 | 45 | ||
46 | NeighbourSystem type = NeighbourSystem.Moore; | 46 | NeighbourSystem type = NeighbourSystem.Moore; |
47 | int NEIGHBOUR_ME = 4; | 47 | int NEIGHBOUR_ME = 4; |
48 | 48 | ||
49 | int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; | 49 | int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; |
50 | 50 | ||
51 | for (int i = 0; i < rounds; i++) | 51 | for (int i = 0; i < rounds; i++) |
52 | { | 52 | { |
53 | water += rain; | 53 | water += rain; |
54 | 54 | ||
55 | sediment = terrain * water; | 55 | sediment = terrain * water; |
56 | terrain -= sediment; | 56 | terrain -= sediment; |
57 | 57 | ||
58 | for (int x = 1; x < w - 1; x++) | 58 | for (int x = 1; x < w - 1; x++) |
59 | { | 59 | { |
60 | for (int y = 1; y < h - 1; y++) | 60 | for (int y = 1; y < h - 1; y++) |
61 | { | 61 | { |
62 | double[] heights = new double[NEIGHBOUR_MAX]; | 62 | double[] heights = new double[NEIGHBOUR_MAX]; |
63 | double[] diffs = new double[NEIGHBOUR_MAX]; | 63 | double[] diffs = new double[NEIGHBOUR_MAX]; |
64 | 64 | ||
65 | double heightCenter = map[x, y]; | 65 | double heightCenter = map[x, y]; |
66 | 66 | ||
67 | for (int j = 0; j < NEIGHBOUR_MAX; j++) | 67 | for (int j = 0; j < NEIGHBOUR_MAX; j++) |
68 | { | 68 | { |
69 | if (j != NEIGHBOUR_ME) | 69 | if (j != NEIGHBOUR_ME) |
70 | { | 70 | { |
71 | int[] coords = Neighbours(type, j); | 71 | int[] coords = Neighbours(type, j); |
72 | coords[0] += x; | 72 | coords[0] += x; |
73 | coords[1] += y; | 73 | coords[1] += y; |
74 | 74 | ||
75 | heights[j] = map[coords[0], coords[1]] + water.map[coords[0], coords[1]] + sediment.map[coords[0], coords[1]]; | 75 | heights[j] = map[coords[0], coords[1]] + water.map[coords[0], coords[1]] + sediment.map[coords[0], coords[1]]; |
76 | diffs[j] = heightCenter - heights[j]; | 76 | diffs[j] = heightCenter - heights[j]; |
77 | } | 77 | } |
78 | } | 78 | } |
79 | 79 | ||
80 | double totalHeight = 0; | 80 | double totalHeight = 0; |
81 | double totalHeightDiff = 0; | 81 | double totalHeightDiff = 0; |
82 | int totalCellsCounted = 1; | 82 | int totalCellsCounted = 1; |
83 | 83 | ||
84 | for (int j = 0; j < NEIGHBOUR_MAX; j++) | 84 | for (int j = 0; j < NEIGHBOUR_MAX; j++) |
85 | { | 85 | { |
86 | if (j != NEIGHBOUR_ME) | 86 | if (j != NEIGHBOUR_ME) |
87 | { | 87 | { |
88 | if (diffs[j] > 0) | 88 | if (diffs[j] > 0) |
89 | { | 89 | { |
90 | totalHeight += heights[j]; | 90 | totalHeight += heights[j]; |
91 | totalHeightDiff += diffs[j]; | 91 | totalHeightDiff += diffs[j]; |
92 | totalCellsCounted++; | 92 | totalCellsCounted++; |
93 | } | 93 | } |
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | if (totalCellsCounted == 1) | 97 | if (totalCellsCounted == 1) |
98 | continue; | 98 | continue; |
99 | 99 | ||
100 | double averageHeight = totalHeight / totalCellsCounted; | 100 | double averageHeight = totalHeight / totalCellsCounted; |
101 | double waterAmount = Math.Min(water.map[x, y], heightCenter - averageHeight); | 101 | double waterAmount = Math.Min(water.map[x, y], heightCenter - averageHeight); |
102 | 102 | ||
103 | // TODO: Check this. | 103 | // TODO: Check this. |
104 | waterFlow.map[x, y] += waterFlow.map[x, y] - waterAmount; | 104 | waterFlow.map[x, y] += waterFlow.map[x, y] - waterAmount; |
105 | 105 | ||
106 | double totalInverseDiff = waterAmount / totalHeightDiff; | 106 | double totalInverseDiff = waterAmount / totalHeightDiff; |
107 | 107 | ||
108 | for (int j = 0; j < NEIGHBOUR_MAX; j++) | 108 | for (int j = 0; j < NEIGHBOUR_MAX; j++) |
109 | { | 109 | { |
110 | if (j != NEIGHBOUR_ME) | 110 | if (j != NEIGHBOUR_ME) |
111 | { | 111 | { |
112 | int[] coords = Neighbours(type, j); | 112 | int[] coords = Neighbours(type, j); |
113 | coords[0] += x; | 113 | coords[0] += x; |
114 | coords[1] += y; | 114 | coords[1] += y; |
115 | 115 | ||
116 | if (diffs[j] > 0) | 116 | if (diffs[j] > 0) |
117 | { | 117 | { |
118 | waterFlow.SetWrap(coords[0], coords[1], waterFlow.map[coords[0], coords[1]] + diffs[j] * totalInverseDiff); | 118 | waterFlow.SetWrap(coords[0], coords[1], waterFlow.map[coords[0], coords[1]] + diffs[j] * totalInverseDiff); |
119 | } | 119 | } |
120 | } | 120 | } |
121 | } | 121 | } |
122 | } | 122 | } |
123 | } | 123 | } |
124 | 124 | ||
125 | water += waterFlow; | 125 | water += waterFlow; |
126 | waterFlow.Fill(0); | 126 | waterFlow.Fill(0); |
127 | 127 | ||
128 | water *= evaporation; | 128 | water *= evaporation; |
129 | 129 | ||
130 | for (int x = 0; x < w; x++) | 130 | for (int x = 0; x < w; x++) |
131 | { | 131 | { |
132 | for (int y = 0; y < h; y++) | 132 | for (int y = 0; y < h; y++) |
133 | { | 133 | { |
134 | double deposition = sediment.map[x, y] - water.map[x, y] * solubility; | 134 | double deposition = sediment.map[x, y] - water.map[x, y] * solubility; |
135 | if (deposition > 0) | 135 | if (deposition > 0) |
136 | { | 136 | { |
137 | sediment.map[x, y] -= deposition; | 137 | sediment.map[x, y] -= deposition; |
138 | terrain.map[x, y] += deposition; | 138 | terrain.map[x, y] += deposition; |
139 | } | 139 | } |
140 | } | 140 | } |
141 | } | 141 | } |
142 | 142 | ||
143 | } | 143 | } |
144 | } | 144 | } |
145 | } | 145 | } |
146 | } \ No newline at end of file | 146 | } \ 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 8a111ed..1cd213b 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/NavierStokes.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/NavierStokes.cs | |||
@@ -1,307 +1,307 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://www.openmetaverse.org/ | 2 | * Copyright (c) Contributors, http://www.openmetaverse.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Text; | 31 | using System.Text; |
32 | 32 | ||
33 | namespace libTerrain | 33 | namespace libTerrain |
34 | { | 34 | { |
35 | partial class Channel | 35 | partial class Channel |
36 | { | 36 | { |
37 | // Navier Stokes Algorithms ported from | 37 | // Navier Stokes Algorithms ported from |
38 | // "Real-Time Fluid Dynamics for Games" by Jos Stam. | 38 | // "Real-Time Fluid Dynamics for Games" by Jos Stam. |
39 | // presented at GDC 2003. | 39 | // presented at GDC 2003. |
40 | 40 | ||
41 | // Poorly ported from C++. (I gave up making it properly native somewhere after nsSetBnd) | 41 | // Poorly ported from C++. (I gave up making it properly native somewhere after nsSetBnd) |
42 | 42 | ||
43 | private static int nsIX(int i, int j, int N) | 43 | private static int nsIX(int i, int j, int N) |
44 | { | 44 | { |
45 | return ((i) + (N + 2) * (j)); | 45 | return ((i) + (N + 2) * (j)); |
46 | } | 46 | } |
47 | 47 | ||
48 | private static void nsSwap(ref double x0, ref double x) | 48 | private static void nsSwap(ref double x0, ref double x) |
49 | { | 49 | { |
50 | double tmp = x0; | 50 | double tmp = x0; |
51 | x0 = x; | 51 | x0 = x; |
52 | x = tmp; | 52 | x = tmp; |
53 | } | 53 | } |
54 | 54 | ||
55 | private static void nsSwap(ref double[] x0, ref double[] x) | 55 | private static void nsSwap(ref double[] x0, ref double[] x) |
56 | { | 56 | { |
57 | double[] tmp = x0; | 57 | double[] tmp = x0; |
58 | x0 = x; | 58 | x0 = x; |
59 | x = tmp; | 59 | x = tmp; |
60 | } | 60 | } |
61 | 61 | ||
62 | private void nsAddSource(int N, ref double[] x, ref double[] s, double dt) | 62 | private void nsAddSource(int N, ref double[] x, ref double[] s, double dt) |
63 | { | 63 | { |
64 | int i; | 64 | int i; |
65 | int size = (N + 2) * (N + 2); | 65 | int size = (N + 2) * (N + 2); |
66 | for (i = 0; i < size; i++) | 66 | for (i = 0; i < size; i++) |
67 | { | 67 | { |
68 | x[i] += dt * s[i]; | 68 | x[i] += dt * s[i]; |
69 | } | 69 | } |
70 | } | 70 | } |
71 | 71 | ||
72 | private void nsSetBnd(int N, int b, ref double[] x) | 72 | private void nsSetBnd(int N, int b, ref double[] x) |
73 | { | 73 | { |
74 | int i; | 74 | int i; |
75 | for (i = 0; i <= N; i++) | 75 | for (i = 0; i <= N; i++) |
76 | { | 76 | { |
77 | x[nsIX(0, i, N)] = b == 1 ? -x[nsIX(1, i, N)] : x[nsIX(1, i, N)]; | 77 | x[nsIX(0, i, N)] = b == 1 ? -x[nsIX(1, i, N)] : x[nsIX(1, i, N)]; |
78 | x[nsIX(0, N + 1, N)] = b == 1 ? -x[nsIX(N, i, N)] : x[nsIX(N, i, N)]; | 78 | x[nsIX(0, N + 1, N)] = b == 1 ? -x[nsIX(N, i, N)] : x[nsIX(N, i, N)]; |
79 | x[nsIX(i, 0, N)] = b == 2 ? -x[nsIX(i, 1, N)] : x[nsIX(i, 1, N)]; | 79 | x[nsIX(i, 0, N)] = b == 2 ? -x[nsIX(i, 1, N)] : x[nsIX(i, 1, N)]; |
80 | x[nsIX(i, N + 1, N)] = b == 2 ? -x[nsIX(i, N, N)] : x[nsIX(i, N, N)]; | 80 | x[nsIX(i, N + 1, N)] = b == 2 ? -x[nsIX(i, N, N)] : x[nsIX(i, N, N)]; |
81 | } | 81 | } |
82 | x[nsIX(0, 0, N)] = 0.5f * (x[nsIX(1, 0, N)] + x[nsIX(0, 1, N)]); | 82 | x[nsIX(0, 0, N)] = 0.5f * (x[nsIX(1, 0, N)] + x[nsIX(0, 1, N)]); |
83 | x[nsIX(0, N + 1, N)] = 0.5f * (x[nsIX(1, N + 1, N)] + x[nsIX(0, N, N)]); | 83 | x[nsIX(0, N + 1, N)] = 0.5f * (x[nsIX(1, N + 1, N)] + x[nsIX(0, N, N)]); |
84 | x[nsIX(N + 1, 0, N)] = 0.5f * (x[nsIX(N, 0, N)] + x[nsIX(N + 1, 1, N)]); | 84 | x[nsIX(N + 1, 0, N)] = 0.5f * (x[nsIX(N, 0, N)] + x[nsIX(N + 1, 1, N)]); |
85 | x[nsIX(N + 1, N + 1, N)] = 0.5f * (x[nsIX(N, N + 1, N)] + x[nsIX(N + 1, N, N)]); | 85 | x[nsIX(N + 1, N + 1, N)] = 0.5f * (x[nsIX(N, N + 1, N)] + x[nsIX(N + 1, N, N)]); |
86 | } | 86 | } |
87 | 87 | ||
88 | private void nsLinSolve(int N, int b, ref double[] x, ref double[] x0, double a, double c) | 88 | private void nsLinSolve(int N, int b, ref double[] x, ref double[] x0, double a, double c) |
89 | { | 89 | { |
90 | int i, j; | 90 | int i, j; |
91 | for (i = 1; i <= N; i++) | 91 | for (i = 1; i <= N; i++) |
92 | { | 92 | { |
93 | for (j = 1; j <= N; j++) | 93 | for (j = 1; j <= N; j++) |
94 | { | 94 | { |
95 | x[nsIX(i, j, N)] = (x0[nsIX(i, j, N)] + a * | 95 | x[nsIX(i, j, N)] = (x0[nsIX(i, j, N)] + a * |
96 | (x[nsIX(i - 1, j, N)] + | 96 | (x[nsIX(i - 1, j, N)] + |
97 | x[nsIX(i + 1, j, N)] + | 97 | x[nsIX(i + 1, j, N)] + |
98 | x[nsIX(i, j - 1, N)] + x[nsIX(i, j + 1, N)]) | 98 | x[nsIX(i, j - 1, N)] + x[nsIX(i, j + 1, N)]) |
99 | ) / c; | 99 | ) / c; |
100 | } | 100 | } |
101 | } | 101 | } |
102 | 102 | ||
103 | nsSetBnd(N, b, ref x); | 103 | nsSetBnd(N, b, ref x); |
104 | } | 104 | } |
105 | 105 | ||
106 | private void nsDiffuse(int N, int b, ref double[] x, ref double[] x0, double diff, double dt) | 106 | private void nsDiffuse(int N, int b, ref double[] x, ref double[] x0, double diff, double dt) |
107 | { | 107 | { |
108 | double a = dt * diff * N * N; | 108 | double a = dt * diff * N * N; |
109 | nsLinSolve(N, b, ref x, ref x0, a, 1 + 4 * a); | 109 | nsLinSolve(N, b, ref x, ref x0, a, 1 + 4 * a); |
110 | } | 110 | } |
111 | 111 | ||
112 | private void nsAdvect(int N, int b, ref double[] d, ref double[] d0, ref double[] u, ref double[] v, double dt) | 112 | private void nsAdvect(int N, int b, ref double[] d, ref double[] d0, ref double[] u, ref double[] v, double dt) |
113 | { | 113 | { |
114 | int i, j, i0, j0, i1, j1; | 114 | int i, j, i0, j0, i1, j1; |
115 | double x, y, s0, t0, s1, t1, dt0; | 115 | double x, y, s0, t0, s1, t1, dt0; |
116 | 116 | ||
117 | dt0 = dt * N; | 117 | dt0 = dt * N; |
118 | 118 | ||
119 | for (i = 1; i <= N; i++) | 119 | for (i = 1; i <= N; i++) |
120 | { | 120 | { |
121 | for (j = 1; j <= N; j++) | 121 | for (j = 1; j <= N; j++) |
122 | { | 122 | { |
123 | x = i - dt0 * u[nsIX(i, j, N)]; | 123 | x = i - dt0 * u[nsIX(i, j, N)]; |
124 | y = j - dt0 * v[nsIX(i, j, N)]; | 124 | y = j - dt0 * v[nsIX(i, j, N)]; |
125 | 125 | ||
126 | if (x < 0.5) | 126 | if (x < 0.5) |
127 | x = 0.5; | 127 | x = 0.5; |
128 | if (x > N + 0.5) | 128 | if (x > N + 0.5) |
129 | x = N + 0.5; | 129 | x = N + 0.5; |
130 | i0 = (int)x; | 130 | i0 = (int)x; |
131 | i1 = i0 + 1; | 131 | i1 = i0 + 1; |
132 | 132 | ||
133 | if (y < 0.5) | 133 | if (y < 0.5) |
134 | y = 0.5; | 134 | y = 0.5; |
135 | if (y > N + 0.5) | 135 | if (y > N + 0.5) |
136 | y = N + 0.5; | 136 | y = N + 0.5; |
137 | j0 = (int)y; | 137 | j0 = (int)y; |
138 | j1 = j0 + 1; | 138 | j1 = j0 + 1; |
139 | 139 | ||
140 | s1 = x - i0; | 140 | s1 = x - i0; |
141 | s0 = 1 - s1; | 141 | s0 = 1 - s1; |
142 | t1 = y - j0; | 142 | t1 = y - j0; |
143 | t0 = 1 - t1; | 143 | t0 = 1 - t1; |
144 | 144 | ||
145 | d[nsIX(i, j, N)] = s0 * (t0 * d0[nsIX(i0, j0, N)] + t1 * d0[nsIX(i0, j1, N)]) + | 145 | d[nsIX(i, j, N)] = s0 * (t0 * d0[nsIX(i0, j0, N)] + t1 * d0[nsIX(i0, j1, N)]) + |
146 | s1 * (t0 * d0[nsIX(i1, j0, N)] + t1 * d0[nsIX(i1, j1, N)]); | 146 | s1 * (t0 * d0[nsIX(i1, j0, N)] + t1 * d0[nsIX(i1, j1, N)]); |
147 | } | 147 | } |
148 | } | 148 | } |
149 | 149 | ||
150 | nsSetBnd(N, b, ref d); | 150 | nsSetBnd(N, b, ref d); |
151 | } | 151 | } |
152 | 152 | ||
153 | public void nsProject(int N, ref double[] u, ref double[] v, ref double[] p, ref double[] div) | 153 | public void nsProject(int N, ref double[] u, ref double[] v, ref double[] p, ref double[] div) |
154 | { | 154 | { |
155 | int i, j; | 155 | int i, j; |
156 | 156 | ||
157 | for (i = 1; i <= N; i++) | 157 | for (i = 1; i <= N; i++) |
158 | { | 158 | { |
159 | for (j = 1; j <= N; j++) | 159 | for (j = 1; j <= N; j++) |
160 | { | 160 | { |
161 | div[nsIX(i, j, N)] = -0.5 * (u[nsIX(i + 1, j, N)] - u[nsIX(i - 1, j, N)] + v[nsIX(i, j + 1, N)] - v[nsIX(i, j - 1, N)]) / N; | 161 | div[nsIX(i, j, N)] = -0.5 * (u[nsIX(i + 1, j, N)] - u[nsIX(i - 1, j, N)] + v[nsIX(i, j + 1, N)] - v[nsIX(i, j - 1, N)]) / N; |
162 | p[nsIX(i, j, N)] = 0; | 162 | p[nsIX(i, j, N)] = 0; |
163 | } | 163 | } |
164 | } | 164 | } |
165 | 165 | ||
166 | nsSetBnd(N, 0, ref div); | 166 | nsSetBnd(N, 0, ref div); |
167 | nsSetBnd(N, 0, ref p); | 167 | nsSetBnd(N, 0, ref p); |
168 | 168 | ||
169 | nsLinSolve(N, 0, ref p, ref div, 1, 4); | 169 | nsLinSolve(N, 0, ref p, ref div, 1, 4); |
170 | 170 | ||
171 | for (i = 1; i <= N; i++) | 171 | for (i = 1; i <= N; i++) |
172 | { | 172 | { |
173 | for (j = 1; j <= N; j++) | 173 | for (j = 1; j <= N; j++) |
174 | { | 174 | { |
175 | u[nsIX(i, j, N)] -= 0.5 * N * (p[nsIX(i + 1, j, N)] - p[nsIX(i - 1, j, N)]); | 175 | u[nsIX(i, j, N)] -= 0.5 * N * (p[nsIX(i + 1, j, N)] - p[nsIX(i - 1, j, N)]); |
176 | v[nsIX(i, j, N)] -= 0.5 * N * (p[nsIX(i, j + 1, N)] - p[nsIX(i, j - 1, N)]); | 176 | v[nsIX(i, j, N)] -= 0.5 * N * (p[nsIX(i, j + 1, N)] - p[nsIX(i, j - 1, N)]); |
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | nsSetBnd(N, 1, ref u); | 180 | nsSetBnd(N, 1, ref u); |
181 | nsSetBnd(N, 2, ref v); | 181 | nsSetBnd(N, 2, ref v); |
182 | } | 182 | } |
183 | 183 | ||
184 | private void nsDensStep(int N, ref double[] x, ref double[] x0, ref double[] u, ref double[] v, double diff, double dt) | 184 | private void nsDensStep(int N, ref double[] x, ref double[] x0, ref double[] u, ref double[] v, double diff, double dt) |
185 | { | 185 | { |
186 | nsAddSource(N, ref x, ref x0, dt); | 186 | nsAddSource(N, ref x, ref x0, dt); |
187 | nsSwap(ref x0, ref x); | 187 | nsSwap(ref x0, ref x); |
188 | nsDiffuse(N, 0, ref x, ref x0, diff, dt); | 188 | nsDiffuse(N, 0, ref x, ref x0, diff, dt); |
189 | nsSwap(ref x0, ref x); | 189 | nsSwap(ref x0, ref x); |
190 | nsAdvect(N, 0, ref x, ref x0, ref u, ref v, dt); | 190 | nsAdvect(N, 0, ref x, ref x0, ref u, ref v, dt); |
191 | } | 191 | } |
192 | 192 | ||
193 | private void nsVelStep(int N, ref double[] u, ref double[] v, ref double[] u0, ref double[] v0, double visc, double dt) | 193 | private void nsVelStep(int N, ref double[] u, ref double[] v, ref double[] u0, ref double[] v0, double visc, double dt) |
194 | { | 194 | { |
195 | nsAddSource(N, ref u, ref u0, dt); | 195 | nsAddSource(N, ref u, ref u0, dt); |
196 | nsAddSource(N, ref v, ref v0, dt); | 196 | nsAddSource(N, ref v, ref v0, dt); |
197 | nsSwap(ref u0, ref u); | 197 | nsSwap(ref u0, ref u); |
198 | nsDiffuse(N, 1, ref u, ref u0, visc, dt); | 198 | nsDiffuse(N, 1, ref u, ref u0, visc, dt); |
199 | nsSwap(ref v0, ref v); | 199 | nsSwap(ref v0, ref v); |
200 | nsDiffuse(N, 2, ref v, ref v0, visc, dt); | 200 | nsDiffuse(N, 2, ref v, ref v0, visc, dt); |
201 | nsProject(N, ref u, ref v, ref u0, ref v0); | 201 | nsProject(N, ref u, ref v, ref u0, ref v0); |
202 | nsSwap(ref u0, ref u); | 202 | nsSwap(ref u0, ref u); |
203 | nsSwap(ref v0, ref v); | 203 | nsSwap(ref v0, ref v); |
204 | nsAdvect(N, 1, ref u, ref u0, ref u0, ref v0, dt); | 204 | nsAdvect(N, 1, ref u, ref u0, ref u0, ref v0, dt); |
205 | nsAdvect(N, 2, ref v, ref v0, ref u0, ref v0, dt); | 205 | nsAdvect(N, 2, ref v, ref v0, ref u0, ref v0, dt); |
206 | nsProject(N, ref u, ref v, ref u0, ref v0); | 206 | nsProject(N, ref u, ref v, ref u0, ref v0); |
207 | } | 207 | } |
208 | 208 | ||
209 | private void nsBufferToDoubles(ref double[] dens, int N, ref double[,] doubles) | 209 | private void nsBufferToDoubles(ref double[] dens, int N, ref double[,] doubles) |
210 | { | 210 | { |
211 | int i; | 211 | int i; |
212 | int j; | 212 | int j; |
213 | 213 | ||
214 | for (i = 1; i <= N; i++) | 214 | for (i = 1; i <= N; i++) |
215 | { | 215 | { |
216 | for (j = 1; j <= N; j++) | 216 | for (j = 1; j <= N; j++) |
217 | { | 217 | { |
218 | doubles[i - 1, j - 1] = dens[nsIX(i, j, N)]; | 218 | doubles[i - 1, j - 1] = dens[nsIX(i, j, N)]; |
219 | } | 219 | } |
220 | } | 220 | } |
221 | } | 221 | } |
222 | 222 | ||
223 | private void nsDoublesToBuffer(double[,] doubles, int N, ref double[] dens) | 223 | private void nsDoublesToBuffer(double[,] doubles, int N, ref double[] dens) |
224 | { | 224 | { |
225 | int i; | 225 | int i; |
226 | int j; | 226 | int j; |
227 | 227 | ||
228 | for (i = 1; i <= N; i++) | 228 | for (i = 1; i <= N; i++) |
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 - 1, j - 1]; | 232 | dens[nsIX(i, j, N)] = doubles[i - 1, j - 1]; |
233 | } | 233 | } |
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
237 | private void nsSimulate(int N, int rounds, double dt, double diff, double visc) | 237 | private void nsSimulate(int N, int rounds, double dt, double diff, double visc) |
238 | { | 238 | { |
239 | int size = (N * 2) * (N * 2); | 239 | int size = (N * 2) * (N * 2); |
240 | 240 | ||
241 | double[] u = new double[size]; // Force, X axis | 241 | double[] u = new double[size]; // Force, X axis |
242 | double[] v = new double[size]; // Force, Y axis | 242 | double[] v = new double[size]; // Force, Y axis |
243 | double[] u_prev = new double[size]; | 243 | double[] u_prev = new double[size]; |
244 | double[] v_prev = new double[size]; | 244 | double[] v_prev = new double[size]; |
245 | double[] dens = new double[size]; | 245 | double[] dens = new double[size]; |
246 | double[] dens_prev = new double[size]; | 246 | double[] dens_prev = new double[size]; |
247 | 247 | ||
248 | nsDoublesToBuffer(this.map, N, ref dens); | 248 | nsDoublesToBuffer(this.map, N, ref dens); |
249 | nsDoublesToBuffer(this.map, N, ref dens_prev); | 249 | nsDoublesToBuffer(this.map, N, ref dens_prev); |
250 | 250 | ||
251 | for (int i = 0; i < rounds; i++) | 251 | for (int i = 0; i < rounds; i++) |
252 | { | 252 | { |
253 | u_prev = u; | 253 | u_prev = u; |
254 | v_prev = v; | 254 | v_prev = v; |
255 | dens_prev = dens; | 255 | dens_prev = dens; |
256 | 256 | ||
257 | nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt); | 257 | nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt); |
258 | nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt); | 258 | nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt); |
259 | } | 259 | } |
260 | 260 | ||
261 | nsBufferToDoubles(ref dens, N, ref this.map); | 261 | nsBufferToDoubles(ref dens, N, ref this.map); |
262 | } | 262 | } |
263 | 263 | ||
264 | /// <summary> | 264 | /// <summary> |
265 | /// Performs computational fluid dynamics on a channel | 265 | /// Performs computational fluid dynamics on a channel |
266 | /// </summary> | 266 | /// </summary> |
267 | /// <param name="rounds">The number of steps to perform (Recommended: 20)</param> | 267 | /// <param name="rounds">The number of steps to perform (Recommended: 20)</param> |
268 | /// <param name="dt">Delta Time - The time between steps (Recommended: 0.1)</param> | 268 | /// <param name="dt">Delta Time - The time between steps (Recommended: 0.1)</param> |
269 | /// <param name="diff">Fluid diffusion rate (Recommended: 0.0)</param> | 269 | /// <param name="diff">Fluid diffusion rate (Recommended: 0.0)</param> |
270 | /// <param name="visc">Fluid viscosity (Recommended: 0.0)</param> | 270 | /// <param name="visc">Fluid viscosity (Recommended: 0.0)</param> |
271 | public void navierStokes(int rounds, double dt, double diff, double visc) | 271 | public void navierStokes(int rounds, double dt, double diff, double visc) |
272 | { | 272 | { |
273 | nsSimulate(this.h, rounds, dt, diff, visc); | 273 | nsSimulate(this.h, rounds, dt, diff, visc); |
274 | } | 274 | } |
275 | 275 | ||
276 | public void navierStokes(int rounds, double dt, double diff, double visc, ref double[,] uret, ref double[,] vret) | 276 | public void navierStokes(int rounds, double dt, double diff, double visc, ref double[,] uret, ref double[,] vret) |
277 | { | 277 | { |
278 | int N = this.h; | 278 | int N = this.h; |
279 | 279 | ||
280 | int size = (N * 2) * (N * 2); | 280 | int size = (N * 2) * (N * 2); |
281 | 281 | ||
282 | double[] u = new double[size]; // Force, X axis | 282 | double[] u = new double[size]; // Force, X axis |
283 | double[] v = new double[size]; // Force, Y axis | 283 | double[] v = new double[size]; // Force, Y axis |
284 | double[] u_prev = new double[size]; | 284 | double[] u_prev = new double[size]; |
285 | double[] v_prev = new double[size]; | 285 | double[] v_prev = new double[size]; |
286 | double[] dens = new double[size]; | 286 | double[] dens = new double[size]; |
287 | double[] dens_prev = new double[size]; | 287 | double[] dens_prev = new double[size]; |
288 | 288 | ||
289 | nsDoublesToBuffer(this.map, N, ref dens); | 289 | nsDoublesToBuffer(this.map, N, ref dens); |
290 | nsDoublesToBuffer(this.map, N, ref dens_prev); | 290 | nsDoublesToBuffer(this.map, N, ref dens_prev); |
291 | 291 | ||
292 | for (int i = 0; i < rounds; i++) | 292 | for (int i = 0; i < rounds; i++) |
293 | { | 293 | { |
294 | u_prev = u; | 294 | u_prev = u; |
295 | v_prev = v; | 295 | v_prev = v; |
296 | dens_prev = dens; | 296 | dens_prev = dens; |
297 | 297 | ||
298 | nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt); | 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); | 299 | nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt); |
300 | } | 300 | } |
301 | 301 | ||
302 | nsBufferToDoubles(ref u, N, ref uret); | 302 | nsBufferToDoubles(ref u, N, ref uret); |
303 | nsBufferToDoubles(ref v, N, ref vret); | 303 | nsBufferToDoubles(ref v, N, ref vret); |
304 | nsBufferToDoubles(ref dens, N, ref this.map); | 304 | nsBufferToDoubles(ref dens, N, ref this.map); |
305 | } | 305 | } |
306 | } | 306 | } |
307 | } \ No newline at end of file | 307 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs index 07c7d66..695d501 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs | |||
@@ -1,112 +1,112 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://www.openmetaverse.org/ | 2 | * Copyright (c) Contributors, http://www.openmetaverse.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Text; | 31 | using System.Text; |
32 | 32 | ||
33 | namespace libTerrain | 33 | namespace libTerrain |
34 | { | 34 | { |
35 | partial class Channel | 35 | partial class Channel |
36 | { | 36 | { |
37 | /// <summary> | 37 | /// <summary> |
38 | /// A thermal weathering implementation based on Musgrave's original 1989 algorithm. This is Adam's custom implementation which may differ slightly from the original. | 38 | /// A thermal weathering implementation based on Musgrave's original 1989 algorithm. This is Adam's custom implementation which may differ slightly from the original. |
39 | /// </summary> | 39 | /// </summary> |
40 | /// <param name="talus">The rock angle (represented as a dy/dx ratio) at which point it will be succeptible to breakage</param> | 40 | /// <param name="talus">The rock angle (represented as a dy/dx ratio) at which point it will be succeptible to breakage</param> |
41 | /// <param name="rounds">The number of erosion rounds</param> | 41 | /// <param name="rounds">The number of erosion rounds</param> |
42 | /// <param name="c">The amount of rock to carry each round</param> | 42 | /// <param name="c">The amount of rock to carry each round</param> |
43 | public Channel ThermalWeathering(double talus, int rounds, double c) | 43 | public Channel ThermalWeathering(double talus, int rounds, double c) |
44 | { | 44 | { |
45 | SetDiff(); | 45 | SetDiff(); |
46 | 46 | ||
47 | double[,] lastFrame; | 47 | double[,] lastFrame; |
48 | double[,] thisFrame; | 48 | double[,] thisFrame; |
49 | 49 | ||
50 | lastFrame = (double[,])map.Clone(); | 50 | lastFrame = (double[,])map.Clone(); |
51 | thisFrame = (double[,])map.Clone(); | 51 | thisFrame = (double[,])map.Clone(); |
52 | 52 | ||
53 | NeighbourSystem type = NeighbourSystem.Moore; // Using moore neighbourhood (twice as computationally expensive) | 53 | NeighbourSystem type = NeighbourSystem.Moore; // Using moore neighbourhood (twice as computationally expensive) |
54 | int NEIGHBOUR_ME = 4; // I am always 4 in both systems. | 54 | int NEIGHBOUR_ME = 4; // I am always 4 in both systems. |
55 | 55 | ||
56 | int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; | 56 | int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; |
57 | 57 | ||
58 | int frames = rounds; // Number of thermal erosion iterations to run | 58 | int frames = rounds; // Number of thermal erosion iterations to run |
59 | int i, j; | 59 | int i, j; |
60 | int x, y; | 60 | int x, y; |
61 | 61 | ||
62 | for (i = 0; i < frames; i++) | 62 | for (i = 0; i < frames; i++) |
63 | { | 63 | { |
64 | for (x = 0; x < w; x++) | 64 | for (x = 0; x < w; x++) |
65 | { | 65 | { |
66 | for (y = 0; y < h; y++) | 66 | for (y = 0; y < h; y++) |
67 | { | 67 | { |
68 | for (j = 0; j < NEIGHBOUR_MAX; j++) | 68 | for (j = 0; j < NEIGHBOUR_MAX; j++) |
69 | { | 69 | { |
70 | if (j != NEIGHBOUR_ME) | 70 | if (j != NEIGHBOUR_ME) |
71 | { | 71 | { |
72 | int[] coords = Neighbours(type, j); | 72 | int[] coords = Neighbours(type, j); |
73 | 73 | ||
74 | coords[0] += x; | 74 | coords[0] += x; |
75 | coords[1] += y; | 75 | coords[1] += y; |
76 | 76 | ||
77 | if (coords[0] > w - 1) | 77 | if (coords[0] > w - 1) |
78 | coords[0] = w - 1; | 78 | coords[0] = w - 1; |
79 | if (coords[1] > h - 1) | 79 | if (coords[1] > h - 1) |
80 | coords[1] = h - 1; | 80 | coords[1] = h - 1; |
81 | if (coords[0] < 0) | 81 | if (coords[0] < 0) |
82 | coords[0] = 0; | 82 | coords[0] = 0; |
83 | if (coords[1] < 0) | 83 | if (coords[1] < 0) |
84 | coords[1] = 0; | 84 | coords[1] = 0; |
85 | 85 | ||
86 | double heightF = thisFrame[x, y]; | 86 | double heightF = thisFrame[x, y]; |
87 | double target = thisFrame[coords[0], coords[1]]; | 87 | double target = thisFrame[coords[0], coords[1]]; |
88 | 88 | ||
89 | if (target > heightF + talus) | 89 | if (target > heightF + talus) |
90 | { | 90 | { |
91 | double calc = c * ((target - heightF) - talus); | 91 | double calc = c * ((target - heightF) - talus); |
92 | heightF += calc; | 92 | heightF += calc; |
93 | target -= calc; | 93 | target -= calc; |
94 | } | 94 | } |
95 | 95 | ||
96 | thisFrame[x, y] = heightF; | 96 | thisFrame[x, y] = heightF; |
97 | thisFrame[coords[0], coords[1]] = target; | 97 | thisFrame[coords[0], coords[1]] = target; |
98 | 98 | ||
99 | } | 99 | } |
100 | } | 100 | } |
101 | } | 101 | } |
102 | } | 102 | } |
103 | lastFrame = (double[,])thisFrame.Clone(); | 103 | lastFrame = (double[,])thisFrame.Clone(); |
104 | } | 104 | } |
105 | 105 | ||
106 | map = thisFrame; | 106 | map = thisFrame; |
107 | 107 | ||
108 | Normalise(); // Just to guaruntee a smooth 0..1 value | 108 | Normalise(); // Just to guaruntee a smooth 0..1 value |
109 | return this; | 109 | return this; |
110 | } | 110 | } |
111 | } | 111 | } |
112 | } | 112 | } |