aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs101
1 files changed, 70 insertions, 31 deletions
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index fd30c46..7bc5e88 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -30,10 +30,14 @@ using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Reflection; 31using System.Reflection;
32using System.Net; 32using System.Net;
33
33using log4net; 34using log4net;
34using Nini.Config; 35using Nini.Config;
36
35using OpenMetaverse; 37using OpenMetaverse;
36using Mono.Addins; 38using Mono.Addins;
39
40using OpenSim.Data;
37using OpenSim.Framework; 41using OpenSim.Framework;
38using OpenSim.Region.CoreModules.Framework.InterfaceCommander; 42using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
39using OpenSim.Region.CoreModules.World.Terrain.FileLoaders; 43using OpenSim.Region.CoreModules.World.Terrain.FileLoaders;
@@ -70,6 +74,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
70 #endregion 74 #endregion
71 75
72 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 private static readonly string LogHeader = "[TERRAIN MODULE]";
73 78
74 private readonly Commander m_commander = new Commander("terrain"); 79 private readonly Commander m_commander = new Commander("terrain");
75 80
@@ -130,15 +135,15 @@ namespace OpenSim.Region.CoreModules.World.Terrain
130 { 135 {
131 if (m_scene.Heightmap == null) 136 if (m_scene.Heightmap == null)
132 { 137 {
133 m_channel = new TerrainChannel(m_InitialTerrain); 138 m_channel = new TerrainChannel(m_InitialTerrain, (int)m_scene.RegionInfo.RegionSizeX,
139 (int)m_scene.RegionInfo.RegionSizeY,
140 (int)m_scene.RegionInfo.RegionSizeZ);
134 m_scene.Heightmap = m_channel; 141 m_scene.Heightmap = m_channel;
135 m_revert = new TerrainChannel();
136 UpdateRevertMap(); 142 UpdateRevertMap();
137 } 143 }
138 else 144 else
139 { 145 {
140 m_channel = m_scene.Heightmap; 146 m_channel = m_scene.Heightmap;
141 m_revert = new TerrainChannel();
142 UpdateRevertMap(); 147 UpdateRevertMap();
143 } 148 }
144 149
@@ -230,11 +235,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain
230 try 235 try
231 { 236 {
232 ITerrainChannel channel = loader.Value.LoadFile(filename); 237 ITerrainChannel channel = loader.Value.LoadFile(filename);
233 if (channel.Width != Constants.RegionSize || channel.Height != Constants.RegionSize) 238 if (channel.Width != m_scene.RegionInfo.RegionSizeX || channel.Height != m_scene.RegionInfo.RegionSizeY)
234 { 239 {
235 // TerrainChannel expects a RegionSize x RegionSize map, currently 240 // TerrainChannel expects a RegionSize x RegionSize map, currently
236 throw new ArgumentException(String.Format("wrong size, use a file with size {0} x {1}", 241 throw new ArgumentException(String.Format("wrong size, use a file with size {0} x {1}",
237 Constants.RegionSize, Constants.RegionSize)); 242 m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY));
238 } 243 }
239 m_log.DebugFormat("[TERRAIN]: Loaded terrain, wd/ht: {0}/{1}", channel.Width, channel.Height); 244 m_log.DebugFormat("[TERRAIN]: Loaded terrain, wd/ht: {0}/{1}", channel.Width, channel.Height);
240 m_scene.Heightmap = channel; 245 m_scene.Heightmap = channel;
@@ -309,12 +314,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain
309 LoadFromStream(filename, URIFetch(pathToTerrainHeightmap)); 314 LoadFromStream(filename, URIFetch(pathToTerrainHeightmap));
310 } 315 }
311 316
317 public void LoadFromStream(string filename, Stream stream)
318 {
319 Vector2 defaultDisplacement = new Vector2(0f, 0f);
320 LoadFromStream(filename, defaultDisplacement, stream);
321 }
322
312 /// <summary> 323 /// <summary>
313 /// Loads a terrain file from a stream and installs it in the scene. 324 /// Loads a terrain file from a stream and installs it in the scene.
314 /// </summary> 325 /// </summary>
315 /// <param name="filename">Filename to terrain file. Type is determined by extension.</param> 326 /// <param name="filename">Filename to terrain file. Type is determined by extension.</param>
316 /// <param name="stream"></param> 327 /// <param name="stream"></param>
317 public void LoadFromStream(string filename, Stream stream) 328 public void LoadFromStream(string filename, Vector2 displacement, Stream stream)
318 { 329 {
319 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 330 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
320 { 331 {
@@ -325,8 +336,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
325 try 336 try
326 { 337 {
327 ITerrainChannel channel = loader.Value.LoadStream(stream); 338 ITerrainChannel channel = loader.Value.LoadStream(stream);
328 m_scene.Heightmap = channel; 339 MergeTerrainIntoExisting(channel, displacement);
329 m_channel = channel;
330 UpdateRevertMap(); 340 UpdateRevertMap();
331 } 341 }
332 catch (NotImplementedException) 342 catch (NotImplementedException)
@@ -346,6 +356,33 @@ namespace OpenSim.Region.CoreModules.World.Terrain
346 throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename)); 356 throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename));
347 } 357 }
348 358
359 private void MergeTerrainIntoExisting(ITerrainChannel channel, Vector2 displacement)
360 {
361 if (displacement == Vector2.Zero)
362 {
363 // If there is no displacement, just use this channel as the new heightmap
364 m_scene.Heightmap = channel;
365 m_channel = channel;
366 }
367 else
368 {
369 // If there is a displacement, we copy the loaded heightmap into the overall region
370 for (int xx = 0; xx < channel.Width; xx++)
371 {
372 for (int yy = 0; yy < channel.Height; yy++)
373 {
374 int dispX = xx + (int)displacement.X;
375 int dispY = yy + (int)displacement.Y;
376 if (dispX >= 0 && dispX < m_channel.Width
377 && dispY >= 0 && dispY < m_channel.Height)
378 {
379 m_channel[dispX, dispY] = channel[xx, yy];
380 }
381 }
382 }
383 }
384 }
385
349 private static Stream URIFetch(Uri uri) 386 private static Stream URIFetch(Uri uri)
350 { 387 {
351 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); 388 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
@@ -532,6 +569,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
532 /// </summary> 569 /// </summary>
533 public void UpdateRevertMap() 570 public void UpdateRevertMap()
534 { 571 {
572 /*
535 int x; 573 int x;
536 for (x = 0; x < m_channel.Width; x++) 574 for (x = 0; x < m_channel.Width; x++)
537 { 575 {
@@ -541,6 +579,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
541 m_revert[x, y] = m_channel[x, y]; 579 m_revert[x, y] = m_channel[x, y];
542 } 580 }
543 } 581 }
582 */
583 m_revert = m_channel.MakeCopy();
544 } 584 }
545 585
546 /// <summary> 586 /// <summary>
@@ -567,8 +607,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
567 { 607 {
568 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, 608 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY,
569 fileWidth, fileHeight, 609 fileWidth, fileHeight,
570 (int) Constants.RegionSize, 610 (int) m_scene.RegionInfo.RegionSizeX,
571 (int) Constants.RegionSize); 611 (int) m_scene.RegionInfo.RegionSizeY);
572 m_scene.Heightmap = channel; 612 m_scene.Heightmap = channel;
573 m_channel = channel; 613 m_channel = channel;
574 UpdateRevertMap(); 614 UpdateRevertMap();
@@ -615,8 +655,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
615 { 655 {
616 loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, 656 loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
617 fileWidth, fileHeight, 657 fileWidth, fileHeight,
618 (int)Constants.RegionSize, 658 (int)m_scene.RegionInfo.RegionSizeX,
619 (int)Constants.RegionSize); 659 (int)m_scene.RegionInfo.RegionSizeY);
620 660
621 MainConsole.Instance.OutputFormat( 661 MainConsole.Instance.OutputFormat(
622 "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}", 662 "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}",
@@ -705,7 +745,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
705 private void CheckForTerrainUpdates(bool respectEstateSettings) 745 private void CheckForTerrainUpdates(bool respectEstateSettings)
706 { 746 {
707 bool shouldTaint = false; 747 bool shouldTaint = false;
708 float[] serialised = m_channel.GetFloatsSerialised(); 748 float[] terrHeights = m_channel.GetFloatsSerialised();
709 int x; 749 int x;
710 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize) 750 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize)
711 { 751 {
@@ -714,16 +754,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain
714 { 754 {
715 if (m_channel.Tainted(x, y)) 755 if (m_channel.Tainted(x, y))
716 { 756 {
717 // if we should respect the estate settings then 757 // If we should respect the estate settings then
718 // fixup and height deltas that don't respect them 758 // fixup and height deltas that don't respect them.
759 // Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values.
719 if (respectEstateSettings && LimitChannelChanges(x, y)) 760 if (respectEstateSettings && LimitChannelChanges(x, y))
720 { 761 {
721 // this has been vetoed, so update 762 // Terrain heights were modified. Refetch the terrain info.
722 // what we are going to send to the client 763 terrHeights = m_channel.GetFloatsSerialised();
723 serialised = m_channel.GetFloatsSerialised();
724 } 764 }
725 765
726 SendToClients(serialised, x, y); 766 // m_log.DebugFormat("{0} Patch modified. Sending (x,y) = ({1},{2})", LogHeader, x, y);
767 SendToClients(terrHeights, x, y);
727 shouldTaint = true; 768 shouldTaint = true;
728 } 769 }
729 } 770 }
@@ -792,13 +833,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain
792 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param> 833 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param>
793 /// <param name="x">The patch corner to send</param> 834 /// <param name="x">The patch corner to send</param>
794 /// <param name="y">The patch corner to send</param> 835 /// <param name="y">The patch corner to send</param>
795 private void SendToClients(float[] serialised, int x, int y) 836 private void SendToClients(float[] heightMap, int x, int y)
796 { 837 {
797 m_scene.ForEachClient( 838 m_scene.ForEachClient(
798 delegate(IClientAPI controller) 839 delegate(IClientAPI controller)
799 { controller.SendLayerData( 840 { controller.SendLayerData( x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, heightMap); }
800 x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised);
801 }
802 ); 841 );
803 } 842 }
804 843
@@ -984,28 +1023,28 @@ namespace OpenSim.Region.CoreModules.World.Terrain
984 1023
985 if (direction.ToLower().StartsWith("y")) 1024 if (direction.ToLower().StartsWith("y"))
986 { 1025 {
987 for (int x = 0; x < Constants.RegionSize; x++) 1026 for (int x = 0; x < m_channel.Width; x++)
988 { 1027 {
989 for (int y = 0; y < Constants.RegionSize / 2; y++) 1028 for (int y = 0; y < m_channel.Height / 2; y++)
990 { 1029 {
991 double height = m_channel[x, y]; 1030 double height = m_channel[x, y];
992 double flippedHeight = m_channel[x, (int)Constants.RegionSize - 1 - y]; 1031 double flippedHeight = m_channel[x, (int)m_channel.Height - 1 - y];
993 m_channel[x, y] = flippedHeight; 1032 m_channel[x, y] = flippedHeight;
994 m_channel[x, (int)Constants.RegionSize - 1 - y] = height; 1033 m_channel[x, (int)m_channel.Height - 1 - y] = height;
995 1034
996 } 1035 }
997 } 1036 }
998 } 1037 }
999 else if (direction.ToLower().StartsWith("x")) 1038 else if (direction.ToLower().StartsWith("x"))
1000 { 1039 {
1001 for (int y = 0; y < Constants.RegionSize; y++) 1040 for (int y = 0; y < m_channel.Height; y++)
1002 { 1041 {
1003 for (int x = 0; x < Constants.RegionSize / 2; x++) 1042 for (int x = 0; x < m_channel.Width / 2; x++)
1004 { 1043 {
1005 double height = m_channel[x, y]; 1044 double height = m_channel[x, y];
1006 double flippedHeight = m_channel[(int)Constants.RegionSize - 1 - x, y]; 1045 double flippedHeight = m_channel[(int)m_channel.Width - 1 - x, y];
1007 m_channel[x, y] = flippedHeight; 1046 m_channel[x, y] = flippedHeight;
1008 m_channel[(int)Constants.RegionSize - 1 - x, y] = height; 1047 m_channel[(int)m_channel.Width - 1 - x, y] = height;
1009 1048
1010 } 1049 }
1011 } 1050 }