aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
authorRobert Adams2014-03-10 22:01:55 -0700
committerRobert Adams2014-03-10 22:05:18 -0700
commit742f5054408bbd928ea2422dd9abc04ee57c80dc (patch)
tree03cba6e526914ac7bfefc210afd7179834045c6c /OpenSim/Region/CoreModules
parentDon't start KeyframeMotion timers until all the regions are ready. This preve... (diff)
downloadopensim-SC-742f5054408bbd928ea2422dd9abc04ee57c80dc.zip
opensim-SC-742f5054408bbd928ea2422dd9abc04ee57c80dc.tar.gz
opensim-SC-742f5054408bbd928ea2422dd9abc04ee57c80dc.tar.bz2
opensim-SC-742f5054408bbd928ea2422dd9abc04ee57c80dc.tar.xz
Change terrain update sending to be triggered by frame tick rather
than everytime terrain is changed. The TerrainModule now hooks the frame event and, if terrain has changed, sends terrain updates to the clients. This polling pattern replaces the previous push on change pattern and will make it easier to do per client throttling and per scene presence terrain update ordering.
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs142
1 files changed, 92 insertions, 50 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 {