aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs142
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainChannel.cs12
2 files changed, 93 insertions, 61 deletions
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 08891d9..daf9901 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -149,8 +149,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
149 149
150 m_scene.RegisterModuleInterface<ITerrainModule>(this); 150 m_scene.RegisterModuleInterface<ITerrainModule>(this);
151 m_scene.EventManager.OnNewClient += EventManager_OnNewClient; 151 m_scene.EventManager.OnNewClient += EventManager_OnNewClient;
152 m_scene.EventManager.OnClientClosed += EventManager_OnClientClosed;
152 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; 153 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
153 m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick; 154 m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick;
155 m_scene.EventManager.OnFrame += EventManager_OnFrame;
154 } 156 }
155 157
156 InstallDefaultEffects(); 158 InstallDefaultEffects();
@@ -189,8 +191,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
189 // remove the commands 191 // remove the commands
190 m_scene.UnregisterModuleCommander(m_commander.Name); 192 m_scene.UnregisterModuleCommander(m_commander.Name);
191 // remove the event-handlers 193 // remove the event-handlers
194 m_scene.EventManager.OnFrame -= EventManager_OnFrame;
192 m_scene.EventManager.OnTerrainTick -= EventManager_OnTerrainTick; 195 m_scene.EventManager.OnTerrainTick -= EventManager_OnTerrainTick;
193 m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole; 196 m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole;
197 m_scene.EventManager.OnClientClosed -= EventManager_OnClientClosed;
194 m_scene.EventManager.OnNewClient -= EventManager_OnNewClient; 198 m_scene.EventManager.OnNewClient -= EventManager_OnNewClient;
195 // remove the interface 199 // remove the interface
196 m_scene.UnregisterModuleInterface<ITerrainModule>(this); 200 m_scene.UnregisterModuleInterface<ITerrainModule>(this);
@@ -266,7 +270,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
266 String.Format("Unable to load heightmap: {0}", e.Message)); 270 String.Format("Unable to load heightmap: {0}", e.Message));
267 } 271 }
268 } 272 }
269 CheckForTerrainUpdates();
270 m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); 273 m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
271 return; 274 return;
272 } 275 }
@@ -347,7 +350,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
347 } 350 }
348 } 351 }
349 352
350 CheckForTerrainUpdates();
351 m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); 353 m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
352 return; 354 return;
353 } 355 }
@@ -418,7 +420,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
418 420
419 public void TaintTerrain () 421 public void TaintTerrain ()
420 { 422 {
421 CheckForTerrainUpdates(); 423 m_channel.GetTerrainData().TaintAllTerrain();
422 } 424 }
423 425
424 #region Plugin Loading Methods 426 #region Plugin Loading Methods
@@ -647,7 +649,39 @@ namespace OpenSim.Region.CoreModules.World.Terrain
647 } 649 }
648 650
649 /// <summary> 651 /// <summary>
652 /// Called before processing of every simulation frame.
653 /// This is used to check to see of any of the terrain is tainted and, if so, schedule
654 /// updates for all the presences.
655 /// This also checks to see if there are updates that need to be sent for each presence.
656 /// This is where the logic is to send terrain updates to clients.
657 /// </summary>
658 private void EventManager_OnFrame()
659 {
660 TerrainData terrData = m_channel.GetTerrainData();
661
662 bool shouldTaint = false;
663 for (int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize)
664 {
665 for (int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize)
666 {
667 if (terrData.IsTaintedAt(x, y))
668 {
669 // Found a patch that was modified. Push this flag into the clients.
670 SendToClients(terrData, x, y);
671 shouldTaint = true;
672 }
673 }
674 }
675 if (shouldTaint)
676 {
677 m_scene.EventManager.TriggerTerrainTainted();
678 m_tainted = true;
679 }
680 }
681
682 /// <summary>
650 /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections 683 /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections
684 /// Called infrequently (like every 5 seconds or so). Best used for storing terrain.
651 /// </summary> 685 /// </summary>
652 private void EventManager_OnTerrainTick() 686 private void EventManager_OnTerrainTick()
653 { 687 {
@@ -698,6 +732,22 @@ namespace OpenSim.Region.CoreModules.World.Terrain
698 } 732 }
699 733
700 /// <summary> 734 /// <summary>
735 /// Installs terrain brush hook to IClientAPI
736 /// </summary>
737 /// <param name="client"></param>
738 private void EventManager_OnClientClosed(UUID client, Scene scene)
739 {
740 ScenePresence presence = scene.GetScenePresence(client);
741 if (presence != null)
742 {
743 presence.ControllingClient.OnModifyTerrain -= client_OnModifyTerrain;
744 presence.ControllingClient.OnBakeTerrain -= client_OnBakeTerrain;
745 presence.ControllingClient.OnLandUndo -= client_OnLandUndo;
746 presence.ControllingClient.OnUnackedTerrain -= client_OnUnackedTerrain;
747 }
748 }
749
750 /// <summary>
701 /// Checks to see if the terrain has been modified since last check 751 /// Checks to see if the terrain has been modified since last check
702 /// but won't attempt to limit those changes to the limits specified in the estate settings 752 /// but won't attempt to limit those changes to the limits specified in the estate settings
703 /// currently invoked by the command line operations in the region server only 753 /// currently invoked by the command line operations in the region server only
@@ -717,36 +767,32 @@ namespace OpenSim.Region.CoreModules.World.Terrain
717 /// </summary> 767 /// </summary>
718 private void CheckForTerrainUpdates(bool respectEstateSettings) 768 private void CheckForTerrainUpdates(bool respectEstateSettings)
719 { 769 {
720 bool shouldTaint = false; 770 }
721 float[] terrHeights = m_channel.GetFloatsSerialised(); 771
722 int x; 772 /// <summary>
723 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize) 773 /// Scan over changes in the terrain and limit height changes. This enforces the
774 /// non-estate owner limits on rate of terrain editting.
775 /// Returns 'true' if any heights were limited.
776 /// </summary>
777 private bool EnforceEstateLimits()
778 {
779 TerrainData terrData = m_channel.GetTerrainData();
780
781 bool wasLimited = false;
782 for (int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize)
724 { 783 {
725 int y; 784 for (int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize)
726 for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize)
727 { 785 {
728 if (m_channel.Tainted(x, y)) 786 if (terrData.IsTaintedAt(x, y, false /* clearOnTest */))
729 { 787 {
730 // If we should respect the estate settings then 788 // If we should respect the estate settings then
731 // fixup and height deltas that don't respect them. 789 // fixup and height deltas that don't respect them.
732 // Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values. 790 // Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values.
733 if (respectEstateSettings && LimitChannelChanges(x, y)) 791 wasLimited |= LimitChannelChanges(terrData, x, y);
734 {
735 // Terrain heights were modified. Refetch the terrain info.
736 terrHeights = m_channel.GetFloatsSerialised();
737 }
738
739 // m_log.DebugFormat("{0} Patch modified. Sending (x,y) = ({1},{2})", LogHeader, x, y);
740 SendToClients(terrHeights, x, y);
741 shouldTaint = true;
742 } 792 }
743 } 793 }
744 } 794 }
745 if (shouldTaint) 795 return wasLimited;
746 {
747 m_scene.EventManager.TriggerTerrainTainted();
748 m_tainted = true;
749 }
750 } 796 }
751 797
752 /// <summary> 798 /// <summary>
@@ -754,11 +800,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain
754 /// are all within the current estate limits 800 /// are all within the current estate limits
755 /// <returns>true if changes were limited, false otherwise</returns> 801 /// <returns>true if changes were limited, false otherwise</returns>
756 /// </summary> 802 /// </summary>
757 private bool LimitChannelChanges(int xStart, int yStart) 803 private bool LimitChannelChanges(TerrainData terrData, int xStart, int yStart)
758 { 804 {
759 bool changesLimited = false; 805 bool changesLimited = false;
760 double minDelta = m_scene.RegionInfo.RegionSettings.TerrainLowerLimit; 806 float minDelta = (float)m_scene.RegionInfo.RegionSettings.TerrainLowerLimit;
761 double maxDelta = m_scene.RegionInfo.RegionSettings.TerrainRaiseLimit; 807 float maxDelta = (float)m_scene.RegionInfo.RegionSettings.TerrainRaiseLimit;
762 808
763 // loop through the height map for this patch and compare it against 809 // loop through the height map for this patch and compare it against
764 // the revert map 810 // the revert map
@@ -766,19 +812,18 @@ namespace OpenSim.Region.CoreModules.World.Terrain
766 { 812 {
767 for (int y = yStart; y < yStart + Constants.TerrainPatchSize; y++) 813 for (int y = yStart; y < yStart + Constants.TerrainPatchSize; y++)
768 { 814 {
769 815 float requestedHeight = terrData[x, y];
770 double requestedHeight = m_channel[x, y]; 816 float bakedHeight = (float)m_revert[x, y];
771 double bakedHeight = m_revert[x, y]; 817 float requestedDelta = requestedHeight - bakedHeight;
772 double requestedDelta = requestedHeight - bakedHeight;
773 818
774 if (requestedDelta > maxDelta) 819 if (requestedDelta > maxDelta)
775 { 820 {
776 m_channel[x, y] = bakedHeight + maxDelta; 821 terrData[x, y] = bakedHeight + maxDelta;
777 changesLimited = true; 822 changesLimited = true;
778 } 823 }
779 else if (requestedDelta < minDelta) 824 else if (requestedDelta < minDelta)
780 { 825 {
781 m_channel[x, y] = bakedHeight + minDelta; //as lower is a -ve delta 826 terrData[x, y] = bakedHeight + minDelta; //as lower is a -ve delta
782 changesLimited = true; 827 changesLimited = true;
783 } 828 }
784 } 829 }
@@ -806,11 +851,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain
806 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param> 851 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param>
807 /// <param name="x">The patch corner to send</param> 852 /// <param name="x">The patch corner to send</param>
808 /// <param name="y">The patch corner to send</param> 853 /// <param name="y">The patch corner to send</param>
809 private void SendToClients(float[] heightMap, int x, int y) 854 private void SendToClients(TerrainData terrData, int x, int y)
810 { 855 {
856 float[] heightMap = terrData.GetFloatsSerialized();
811 m_scene.ForEachClient( 857 m_scene.ForEachClient(
812 delegate(IClientAPI controller) 858 delegate(IClientAPI controller)
813 { controller.SendLayerData( x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, heightMap); } 859 {
860 controller.SendLayerData( x / Constants.TerrainPatchSize,
861 y / Constants.TerrainPatchSize,
862 heightMap);
863 }
814 ); 864 );
815 } 865 }
816 866
@@ -856,7 +906,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
856 m_painteffects[(StandardTerrainEffects) action].PaintEffect( 906 m_painteffects[(StandardTerrainEffects) action].PaintEffect(
857 m_channel, allowMask, west, south, height, size, seconds); 907 m_channel, allowMask, west, south, height, size, seconds);
858 908
859 CheckForTerrainUpdates(!god); //revert changes outside estate limits 909 //revert changes outside estate limits
910 if (!god)
911 EnforceEstateLimits();
860 } 912 }
861 } 913 }
862 else 914 else
@@ -897,7 +949,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
897 m_floodeffects[(StandardTerrainEffects) action].FloodEffect( 949 m_floodeffects[(StandardTerrainEffects) action].FloodEffect(
898 m_channel, fillArea, size); 950 m_channel, fillArea, size);
899 951
900 CheckForTerrainUpdates(!god); //revert changes outside estate limits 952 //revert changes outside estate limits
953 if (!god)
954 EnforceEstateLimits();
901 } 955 }
902 } 956 }
903 else 957 else
@@ -948,7 +1002,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
948 private void InterfaceLoadFile(Object[] args) 1002 private void InterfaceLoadFile(Object[] args)
949 { 1003 {
950 LoadFromFile((string) args[0]); 1004 LoadFromFile((string) args[0]);
951 CheckForTerrainUpdates();
952 } 1005 }
953 1006
954 private void InterfaceLoadTileFile(Object[] args) 1007 private void InterfaceLoadTileFile(Object[] args)
@@ -958,7 +1011,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
958 (int) args[2], 1011 (int) args[2],
959 (int) args[3], 1012 (int) args[3],
960 (int) args[4]); 1013 (int) args[4]);
961 CheckForTerrainUpdates();
962 } 1014 }
963 1015
964 private void InterfaceSaveFile(Object[] args) 1016 private void InterfaceSaveFile(Object[] args)
@@ -987,7 +1039,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
987 for (y = 0; y < m_channel.Height; y++) 1039 for (y = 0; y < m_channel.Height; y++)
988 m_channel[x, y] = m_revert[x, y]; 1040 m_channel[x, y] = m_revert[x, y];
989 1041
990 CheckForTerrainUpdates();
991 } 1042 }
992 1043
993 private void InterfaceFlipTerrain(Object[] args) 1044 private void InterfaceFlipTerrain(Object[] args)
@@ -1028,7 +1079,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1028 } 1079 }
1029 1080
1030 1081
1031 CheckForTerrainUpdates();
1032 } 1082 }
1033 1083
1034 private void InterfaceRescaleTerrain(Object[] args) 1084 private void InterfaceRescaleTerrain(Object[] args)
@@ -1086,7 +1136,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1086 } 1136 }
1087 } 1137 }
1088 1138
1089 CheckForTerrainUpdates();
1090 } 1139 }
1091 1140
1092 } 1141 }
@@ -1097,7 +1146,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1097 for (x = 0; x < m_channel.Width; x++) 1146 for (x = 0; x < m_channel.Width; x++)
1098 for (y = 0; y < m_channel.Height; y++) 1147 for (y = 0; y < m_channel.Height; y++)
1099 m_channel[x, y] += (double) args[0]; 1148 m_channel[x, y] += (double) args[0];
1100 CheckForTerrainUpdates();
1101 } 1149 }
1102 1150
1103 private void InterfaceMultiplyTerrain(Object[] args) 1151 private void InterfaceMultiplyTerrain(Object[] args)
@@ -1106,7 +1154,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1106 for (x = 0; x < m_channel.Width; x++) 1154 for (x = 0; x < m_channel.Width; x++)
1107 for (y = 0; y < m_channel.Height; y++) 1155 for (y = 0; y < m_channel.Height; y++)
1108 m_channel[x, y] *= (double) args[0]; 1156 m_channel[x, y] *= (double) args[0];
1109 CheckForTerrainUpdates();
1110 } 1157 }
1111 1158
1112 private void InterfaceLowerTerrain(Object[] args) 1159 private void InterfaceLowerTerrain(Object[] args)
@@ -1115,7 +1162,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1115 for (x = 0; x < m_channel.Width; x++) 1162 for (x = 0; x < m_channel.Width; x++)
1116 for (y = 0; y < m_channel.Height; y++) 1163 for (y = 0; y < m_channel.Height; y++)
1117 m_channel[x, y] -= (double) args[0]; 1164 m_channel[x, y] -= (double) args[0];
1118 CheckForTerrainUpdates();
1119 } 1165 }
1120 1166
1121 private void InterfaceFillTerrain(Object[] args) 1167 private void InterfaceFillTerrain(Object[] args)
@@ -1125,7 +1171,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1125 for (x = 0; x < m_channel.Width; x++) 1171 for (x = 0; x < m_channel.Width; x++)
1126 for (y = 0; y < m_channel.Height; y++) 1172 for (y = 0; y < m_channel.Height; y++)
1127 m_channel[x, y] = (double) args[0]; 1173 m_channel[x, y] = (double) args[0];
1128 CheckForTerrainUpdates();
1129 } 1174 }
1130 1175
1131 private void InterfaceMinTerrain(Object[] args) 1176 private void InterfaceMinTerrain(Object[] args)
@@ -1138,7 +1183,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1138 m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]); 1183 m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]);
1139 } 1184 }
1140 } 1185 }
1141 CheckForTerrainUpdates();
1142 } 1186 }
1143 1187
1144 private void InterfaceMaxTerrain(Object[] args) 1188 private void InterfaceMaxTerrain(Object[] args)
@@ -1151,7 +1195,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1151 m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]); 1195 m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]);
1152 } 1196 }
1153 } 1197 }
1154 CheckForTerrainUpdates();
1155 } 1198 }
1156 1199
1157 private void InterfaceShowDebugStats(Object[] args) 1200 private void InterfaceShowDebugStats(Object[] args)
@@ -1214,7 +1257,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1214 if (m_plugineffects.ContainsKey(firstArg)) 1257 if (m_plugineffects.ContainsKey(firstArg))
1215 { 1258 {
1216 m_plugineffects[firstArg].RunEffect(m_channel); 1259 m_plugineffects[firstArg].RunEffect(m_channel);
1217 CheckForTerrainUpdates();
1218 } 1260 }
1219 else 1261 else
1220 { 1262 {
diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
index 60dc6c9..cc040a6 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
@@ -124,17 +124,7 @@ namespace OpenSim.Region.Framework.Scenes
124 // and the caller will probably do the wrong thing if the terrain is not the legacy 256x256. 124 // and the caller will probably do the wrong thing if the terrain is not the legacy 256x256.
125 public float[] GetFloatsSerialised() 125 public float[] GetFloatsSerialised()
126 { 126 {
127 int points = Width * Height; 127 return m_terrainData.GetFloatsSerialized();
128 float[] heights = new float[points];
129
130 int idx = 0;
131 for (int jj = 0; jj < Height; jj++)
132 for (int ii = 0; ii < Width; ii++)
133 {
134 heights[idx++] = m_terrainData[ii, jj];
135 }
136
137 return heights;
138 } 128 }
139 129
140 // ITerrainChannel.GetDoubles() 130 // ITerrainChannel.GetDoubles()