aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/TerrainChannel.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainChannel.cs72
1 files changed, 72 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
index b4b1823..24709dc 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
@@ -36,6 +36,8 @@ using OpenSim.Data;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
38 38
39using OpenMetaverse;
40
39using log4net; 41using log4net;
40 42
41namespace OpenSim.Region.Framework.Scenes 43namespace OpenSim.Region.Framework.Scenes
@@ -212,6 +214,76 @@ namespace OpenSim.Region.Framework.Scenes
212 sr.Close(); 214 sr.Close();
213 } 215 }
214 216
217 // ITerrainChannel.Merge
218 public void Merge(ITerrainChannel newTerrain, Vector3 displacement, float radianRotation, Vector2 rotationDisplacement)
219 {
220 for (int xx = 0; xx < newTerrain.Width; xx++)
221 {
222 for (int yy = 0; yy < newTerrain.Height; yy++)
223 {
224 int dispX = (int)displacement.X;
225 int dispY = (int)displacement.Y;
226 float newHeight = (float)newTerrain[xx, yy] + displacement.Z;
227 if (radianRotation == 0)
228 {
229 // If no rotation, place the new height in the specified location
230 dispX += xx;
231 dispY += yy;
232 if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY)
233 {
234 m_terrainData[dispX, dispY] = newHeight;
235 }
236 }
237 else
238 {
239 // If rotating, we have to smooth the result because the conversion
240 // to ints will mean heightmap entries will not get changed
241 // First compute the rotation location for the new height.
242 dispX += (int)(rotationDisplacement.X
243 + ((float)xx - rotationDisplacement.X) * Math.Cos(radianRotation)
244 - ((float)yy - rotationDisplacement.Y) * Math.Sin(radianRotation) );
245
246 dispY += (int)(rotationDisplacement.Y
247 + ((float)xx - rotationDisplacement.X) * Math.Sin(radianRotation)
248 + ((float)yy - rotationDisplacement.Y) * Math.Cos(radianRotation) );
249
250 if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY)
251 {
252 float oldHeight = m_terrainData[dispX, dispY];
253 // Smooth the heights around this location if the old height is far from this one
254 for (int sxx = dispX - 2; sxx < dispX + 2; sxx++)
255 {
256 for (int syy = dispY - 2; syy < dispY + 2; syy++)
257 {
258 if (sxx >= 0 && sxx < m_terrainData.SizeX && syy >= 0 && syy < m_terrainData.SizeY)
259 {
260 if (sxx == dispX && syy == dispY)
261 {
262 // Set height for the exact rotated point
263 m_terrainData[dispX, dispY] = newHeight;
264 }
265 else
266 {
267 if (Math.Abs(m_terrainData[sxx, syy] - newHeight) > 1f)
268 {
269 // If the adjacent height is far off, force it to this height
270 m_terrainData[sxx, syy] = newHeight;
271 }
272 }
273 }
274 }
275 }
276 }
277
278 if (dispX >= 0 && dispX < m_terrainData.SizeX && dispY >= 0 && dispY < m_terrainData.SizeY)
279 {
280 m_terrainData[dispX, dispY] = (float)newTerrain[xx, yy];
281 }
282 }
283 }
284 }
285 }
286
215 #endregion 287 #endregion
216 288
217 public TerrainChannel Copy() 289 public TerrainChannel Copy()