aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs424
-rw-r--r--OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs290
-rw-r--r--OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/NavierStokes.cs612
-rw-r--r--OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs224
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
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Text; 31using System.Text;
32 32
33namespace libTerrain 33namespace 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
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Text; 31using System.Text;
32 32
33namespace libTerrain 33namespace 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
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Text; 31using System.Text;
32 32
33namespace libTerrain 33namespace 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
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Text; 31using System.Text;
32 32
33namespace libTerrain 33namespace 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}