diff options
author | Diva Canto | 2014-06-01 10:06:59 -0700 |
---|---|---|
committer | Diva Canto | 2014-06-01 10:06:59 -0700 |
commit | 0eaca7aafb0365fb21b6d1ce8e1590845a6b5125 (patch) | |
tree | 1120139228e2c934de544f3288b306699018bb50 | |
parent | Fixed a few things pertaining to interfacing with the estate service. Specifi... (diff) | |
parent | Move the generation of the multi-resolution map tiles off the main (diff) | |
download | opensim-SC-0eaca7aafb0365fb21b6d1ce8e1590845a6b5125.zip opensim-SC-0eaca7aafb0365fb21b6d1ce8e1590845a6b5125.tar.gz opensim-SC-0eaca7aafb0365fb21b6d1ce8e1590845a6b5125.tar.bz2 opensim-SC-0eaca7aafb0365fb21b6d1ce8e1590845a6b5125.tar.xz |
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to '')
9 files changed, 379 insertions, 79 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index e583590..70b0e0a 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -820,7 +820,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
820 | agentCircuit.Id0 = currentAgentCircuit.Id0; | 820 | agentCircuit.Id0 = currentAgentCircuit.Id0; |
821 | } | 821 | } |
822 | 822 | ||
823 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 823 | // if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) |
824 | if (NeedsNewAgent(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
824 | { | 825 | { |
825 | // brand new agent, let's create a new caps seed | 826 | // brand new agent, let's create a new caps seed |
826 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | 827 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); |
@@ -894,7 +895,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
894 | 895 | ||
895 | IClientIPEndpoint ipepClient; | 896 | IClientIPEndpoint ipepClient; |
896 | string capsPath = String.Empty; | 897 | string capsPath = String.Empty; |
897 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 898 | if (NeedsNewAgent(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) |
898 | { | 899 | { |
899 | m_log.DebugFormat( | 900 | m_log.DebugFormat( |
900 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", | 901 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", |
@@ -1070,7 +1071,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1070 | 1071 | ||
1071 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 1072 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
1072 | 1073 | ||
1073 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 1074 | if (NeedsClosing(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
1074 | { | 1075 | { |
1075 | if (!sp.Scene.IncomingPreCloseClient(sp)) | 1076 | if (!sp.Scene.IncomingPreCloseClient(sp)) |
1076 | return; | 1077 | return; |
@@ -1140,7 +1141,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1140 | 1141 | ||
1141 | IClientIPEndpoint ipepClient; | 1142 | IClientIPEndpoint ipepClient; |
1142 | string capsPath = String.Empty; | 1143 | string capsPath = String.Empty; |
1143 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 1144 | if (NeedsNewAgent(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) |
1144 | { | 1145 | { |
1145 | m_log.DebugFormat( | 1146 | m_log.DebugFormat( |
1146 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}", | 1147 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}", |
@@ -1236,7 +1237,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1236 | sp.MakeChildAgent(); | 1237 | sp.MakeChildAgent(); |
1237 | 1238 | ||
1238 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 1239 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
1239 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 1240 | if (NeedsClosing(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
1240 | { | 1241 | { |
1241 | if (!sp.Scene.IncomingPreCloseClient(sp)) | 1242 | if (!sp.Scene.IncomingPreCloseClient(sp)) |
1242 | return; | 1243 | return; |
@@ -2366,7 +2367,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2366 | { | 2367 | { |
2367 | // The area to check is as big as the current region. | 2368 | // The area to check is as big as the current region. |
2368 | // We presume all adjacent regions are the same size as this region. | 2369 | // We presume all adjacent regions are the same size as this region. |
2369 | uint dd = Math.Max((uint)avatar.DrawDistance, | 2370 | uint dd = Math.Max((uint)avatar.Scene.DefaultDrawDistance, |
2370 | Math.Max(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY)); | 2371 | Math.Max(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY)); |
2371 | 2372 | ||
2372 | uint startX = Util.RegionToWorldLoc(pRegionLocX) - dd + Constants.RegionSize/2; | 2373 | uint startX = Util.RegionToWorldLoc(pRegionLocX) - dd + Constants.RegionSize/2; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 3b38c71..d5fca71 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs | |||
@@ -199,6 +199,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
199 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) | 199 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) |
200 | { | 200 | { |
201 | GridRegion region = null; | 201 | GridRegion region = null; |
202 | uint regionX = Util.WorldToRegionLoc((uint)x); | ||
203 | uint regionY = Util.WorldToRegionLoc((uint)y); | ||
202 | 204 | ||
203 | // First see if it's a neighbour, even if it isn't on this sim. | 205 | // First see if it's a neighbour, even if it isn't on this sim. |
204 | // Neighbour data is cached in memory, so this is fast | 206 | // Neighbour data is cached in memory, so this is fast |
@@ -222,11 +224,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
222 | { | 224 | { |
223 | region = m_GridService.GetRegionByPosition(scopeID, x, y); | 225 | region = m_GridService.GetRegionByPosition(scopeID, x, y); |
224 | if (region == null) | 226 | if (region == null) |
227 | { | ||
225 | m_log.DebugFormat("{0} GetRegionByPosition. Region not found by grid service. Pos=<{1},{2}>", | 228 | m_log.DebugFormat("{0} GetRegionByPosition. Region not found by grid service. Pos=<{1},{2}>", |
226 | LogHeader, x, y); | 229 | LogHeader, regionX, regionY); |
230 | } | ||
227 | else | 231 | else |
232 | { | ||
228 | m_log.DebugFormat("{0} GetRegionByPosition. Requested region {1} from grid service. Pos=<{2},{3}>", | 233 | m_log.DebugFormat("{0} GetRegionByPosition. Requested region {1} from grid service. Pos=<{2},{3}>", |
229 | LogHeader, region.RegionName, x, y); | 234 | LogHeader, region.RegionName, regionX, regionY); |
235 | } | ||
230 | } | 236 | } |
231 | return region; | 237 | return region; |
232 | } | 238 | } |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 6e1e8d6..c22c5b6 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | |||
@@ -96,9 +96,88 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
96 | private Scene m_scene; | 96 | private Scene m_scene; |
97 | private volatile bool m_tainted; | 97 | private volatile bool m_tainted; |
98 | private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5); | 98 | private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5); |
99 | 99 | ||
100 | private String m_InitialTerrain = "pinhead-island"; | 100 | private String m_InitialTerrain = "pinhead-island"; |
101 | 101 | ||
102 | // If true, send terrain patch updates to clients based on their view distance | ||
103 | private bool m_sendTerrainUpdatesByViewDistance = false; | ||
104 | |||
105 | // Class to keep the per client collection of terrain patches that must be sent. | ||
106 | // A patch is set to 'true' meaning it should be sent to the client. Once the | ||
107 | // patch packet is queued to the client, the bit for that patch is set to 'false'. | ||
108 | private class PatchUpdates | ||
109 | { | ||
110 | private bool[,] updated; // for each patch, whether it needs to be sent to this client | ||
111 | private int updateCount; // number of patches that need to be sent | ||
112 | public ScenePresence Presence; // a reference to the client to send to | ||
113 | public PatchUpdates(TerrainData terrData, ScenePresence pPresence) | ||
114 | { | ||
115 | updated = new bool[terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize]; | ||
116 | updateCount = 0; | ||
117 | Presence = pPresence; | ||
118 | // Initially, send all patches to the client | ||
119 | SetAll(true); | ||
120 | } | ||
121 | // Returns 'true' if there are any patches marked for sending | ||
122 | public bool HasUpdates() | ||
123 | { | ||
124 | return (updateCount > 0); | ||
125 | } | ||
126 | public void SetByXY(int x, int y, bool state) | ||
127 | { | ||
128 | this.SetByPatch(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, state); | ||
129 | } | ||
130 | public bool GetByPatch(int patchX, int patchY) | ||
131 | { | ||
132 | return updated[patchX, patchY]; | ||
133 | } | ||
134 | public void SetByPatch(int patchX, int patchY, bool state) | ||
135 | { | ||
136 | bool prevState = updated[patchX, patchY]; | ||
137 | if (!prevState && state) | ||
138 | updateCount++; | ||
139 | if (prevState && !state) | ||
140 | updateCount--; | ||
141 | updated[patchX, patchY] = state; | ||
142 | } | ||
143 | public void SetAll(bool state) | ||
144 | { | ||
145 | updateCount = 0; | ||
146 | for (int xx = 0; xx < updated.GetLength(0); xx++) | ||
147 | for (int yy = 0; yy < updated.GetLength(1); yy++) | ||
148 | updated[xx, yy] = state; | ||
149 | if (state) | ||
150 | updateCount = updated.GetLength(0) * updated.GetLength(1); | ||
151 | } | ||
152 | // Logically OR's the terrain data's patch taint map into this client's update map. | ||
153 | public void SetAll(TerrainData terrData) | ||
154 | { | ||
155 | if (updated.GetLength(0) != (terrData.SizeX / Constants.TerrainPatchSize) | ||
156 | || updated.GetLength(1) != (terrData.SizeY / Constants.TerrainPatchSize)) | ||
157 | { | ||
158 | throw new Exception( | ||
159 | String.Format("{0} PatchUpdates.SetAll: patch array not same size as terrain. arr=<{1},{2}>, terr=<{3},{4}>", | ||
160 | LogHeader, updated.GetLength(0), updated.GetLength(1), | ||
161 | terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize) | ||
162 | ); | ||
163 | } | ||
164 | for (int xx = 0; xx < terrData.SizeX; xx += Constants.TerrainPatchSize) | ||
165 | { | ||
166 | for (int yy = 0; yy < terrData.SizeY; yy += Constants.TerrainPatchSize) | ||
167 | { | ||
168 | // Only set tainted. The patch bit may be set if the patch was to be sent later. | ||
169 | if (terrData.IsTaintedAt(xx, yy, false)) | ||
170 | { | ||
171 | this.SetByXY(xx, yy, true); | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | |||
178 | // The flags of which terrain patches to send for each of the ScenePresence's | ||
179 | private Dictionary<UUID, PatchUpdates> m_perClientPatchUpdates = new Dictionary<UUID, PatchUpdates>(); | ||
180 | |||
102 | /// <summary> | 181 | /// <summary> |
103 | /// Human readable list of terrain file extensions that are supported. | 182 | /// Human readable list of terrain file extensions that are supported. |
104 | /// </summary> | 183 | /// </summary> |
@@ -127,7 +206,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
127 | { | 206 | { |
128 | IConfig terrainConfig = config.Configs["Terrain"]; | 207 | IConfig terrainConfig = config.Configs["Terrain"]; |
129 | if (terrainConfig != null) | 208 | if (terrainConfig != null) |
209 | { | ||
130 | m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); | 210 | m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); |
211 | m_sendTerrainUpdatesByViewDistance = terrainConfig.GetBoolean("SendTerrainUpdatesByViewDistance", m_sendTerrainUpdatesByViewDistance); | ||
212 | } | ||
131 | } | 213 | } |
132 | 214 | ||
133 | public void AddRegion(Scene scene) | 215 | public void AddRegion(Scene scene) |
@@ -422,9 +504,46 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
422 | } | 504 | } |
423 | } | 505 | } |
424 | 506 | ||
507 | // Someone diddled terrain outside the normal code paths. Set the taintedness for all clients. | ||
508 | // ITerrainModule.TaintTerrain() | ||
425 | public void TaintTerrain () | 509 | public void TaintTerrain () |
426 | { | 510 | { |
427 | m_channel.GetTerrainData().TaintAllTerrain(); | 511 | lock (m_perClientPatchUpdates) |
512 | { | ||
513 | // Set the flags for all clients so the tainted patches will be sent out | ||
514 | foreach (PatchUpdates pups in m_perClientPatchUpdates.Values) | ||
515 | { | ||
516 | pups.SetAll(m_scene.Heightmap.GetTerrainData()); | ||
517 | } | ||
518 | } | ||
519 | } | ||
520 | |||
521 | // ITerrainModule.PushTerrain() | ||
522 | public void PushTerrain(IClientAPI pClient) | ||
523 | { | ||
524 | if (m_sendTerrainUpdatesByViewDistance) | ||
525 | { | ||
526 | ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId); | ||
527 | if (presence != null) | ||
528 | { | ||
529 | lock (m_perClientPatchUpdates) | ||
530 | { | ||
531 | PatchUpdates pups; | ||
532 | if (!m_perClientPatchUpdates.TryGetValue(pClient.AgentId, out pups)) | ||
533 | { | ||
534 | // There is a ScenePresence without a send patch map. Create one. | ||
535 | pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence); | ||
536 | m_perClientPatchUpdates.Add(presence.UUID, pups); | ||
537 | } | ||
538 | pups.SetAll(true); | ||
539 | } | ||
540 | } | ||
541 | } | ||
542 | else | ||
543 | { | ||
544 | // The traditional way is to call into the protocol stack to send them all. | ||
545 | pClient.SendLayerData(new float[10]); | ||
546 | } | ||
428 | } | 547 | } |
429 | 548 | ||
430 | #region Plugin Loading Methods | 549 | #region Plugin Loading Methods |
@@ -676,6 +795,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
676 | } | 795 | } |
677 | } | 796 | } |
678 | } | 797 | } |
798 | |||
799 | // This event also causes changes to be sent to the clients | ||
800 | CheckSendingPatchesToClients(); | ||
801 | |||
802 | // If things changes, generate some events | ||
679 | if (shouldTaint) | 803 | if (shouldTaint) |
680 | { | 804 | { |
681 | m_scene.EventManager.TriggerTerrainTainted(); | 805 | m_scene.EventManager.TriggerTerrainTainted(); |
@@ -749,31 +873,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
749 | presence.ControllingClient.OnLandUndo -= client_OnLandUndo; | 873 | presence.ControllingClient.OnLandUndo -= client_OnLandUndo; |
750 | presence.ControllingClient.OnUnackedTerrain -= client_OnUnackedTerrain; | 874 | presence.ControllingClient.OnUnackedTerrain -= client_OnUnackedTerrain; |
751 | } | 875 | } |
876 | if (m_perClientPatchUpdates.ContainsKey(client)) | ||
877 | { | ||
878 | m_perClientPatchUpdates.Remove(client); | ||
879 | } | ||
752 | } | 880 | } |
753 | 881 | ||
754 | /// <summary> | 882 | /// <summary> |
755 | /// Checks to see if the terrain has been modified since last check | ||
756 | /// but won't attempt to limit those changes to the limits specified in the estate settings | ||
757 | /// currently invoked by the command line operations in the region server only | ||
758 | /// </summary> | ||
759 | private void CheckForTerrainUpdates() | ||
760 | { | ||
761 | CheckForTerrainUpdates(false); | ||
762 | } | ||
763 | |||
764 | /// <summary> | ||
765 | /// Checks to see if the terrain has been modified since last check. | ||
766 | /// If it has been modified, every all the terrain patches are sent to the client. | ||
767 | /// If the call is asked to respect the estate settings for terrain_raise_limit and | ||
768 | /// terrain_lower_limit, it will clamp terrain updates between these values | ||
769 | /// currently invoked by client_OnModifyTerrain only and not the Commander interfaces | ||
770 | /// <param name="respectEstateSettings">should height map deltas be limited to the estate settings limits</param> | ||
771 | /// </summary> | ||
772 | private void CheckForTerrainUpdates(bool respectEstateSettings) | ||
773 | { | ||
774 | } | ||
775 | |||
776 | /// <summary> | ||
777 | /// Scan over changes in the terrain and limit height changes. This enforces the | 883 | /// Scan over changes in the terrain and limit height changes. This enforces the |
778 | /// non-estate owner limits on rate of terrain editting. | 884 | /// non-estate owner limits on rate of terrain editting. |
779 | /// Returns 'true' if any heights were limited. | 885 | /// Returns 'true' if any heights were limited. |
@@ -857,17 +963,140 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
857 | /// <param name="y">The patch corner to send</param> | 963 | /// <param name="y">The patch corner to send</param> |
858 | private void SendToClients(TerrainData terrData, int x, int y) | 964 | private void SendToClients(TerrainData terrData, int x, int y) |
859 | { | 965 | { |
860 | // We know the actual terrain data passed is ignored. This kludge saves changing IClientAPI. | 966 | if (m_sendTerrainUpdatesByViewDistance) |
861 | //float[] heightMap = terrData.GetFloatsSerialized(); | 967 | { |
862 | float[] heightMap = new float[10]; | 968 | // Add that this patch needs to be sent to the accounting for each client. |
863 | m_scene.ForEachClient( | 969 | lock (m_perClientPatchUpdates) |
864 | delegate(IClientAPI controller) | 970 | { |
971 | m_scene.ForEachScenePresence(presence => | ||
972 | { | ||
973 | PatchUpdates thisClientUpdates; | ||
974 | if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out thisClientUpdates)) | ||
975 | { | ||
976 | // There is a ScenePresence without a send patch map. Create one. | ||
977 | thisClientUpdates = new PatchUpdates(terrData, presence); | ||
978 | m_perClientPatchUpdates.Add(presence.UUID, thisClientUpdates); | ||
979 | } | ||
980 | thisClientUpdates.SetByXY(x, y, true); | ||
981 | } | ||
982 | ); | ||
983 | } | ||
984 | } | ||
985 | else | ||
986 | { | ||
987 | // Legacy update sending where the update is sent out as soon as noticed | ||
988 | // We know the actual terrain data passed is ignored. This kludge saves changing IClientAPI. | ||
989 | //float[] heightMap = terrData.GetFloatsSerialized(); | ||
990 | float[] heightMap = new float[10]; | ||
991 | m_scene.ForEachClient( | ||
992 | delegate(IClientAPI controller) | ||
865 | { | 993 | { |
866 | controller.SendLayerData( x / Constants.TerrainPatchSize, | 994 | controller.SendLayerData(x / Constants.TerrainPatchSize, |
867 | y / Constants.TerrainPatchSize, | 995 | y / Constants.TerrainPatchSize, |
868 | heightMap); | 996 | heightMap); |
869 | } | 997 | } |
870 | ); | 998 | ); |
999 | } | ||
1000 | } | ||
1001 | |||
1002 | private class PatchesToSend : IComparable<PatchesToSend> | ||
1003 | { | ||
1004 | public int PatchX; | ||
1005 | public int PatchY; | ||
1006 | public float Dist; | ||
1007 | public PatchesToSend(int pX, int pY, float pDist) | ||
1008 | { | ||
1009 | PatchX = pX; | ||
1010 | PatchY = pY; | ||
1011 | Dist = pDist; | ||
1012 | } | ||
1013 | public int CompareTo(PatchesToSend other) | ||
1014 | { | ||
1015 | return Dist.CompareTo(other.Dist); | ||
1016 | } | ||
1017 | } | ||
1018 | |||
1019 | // Called each frame time to see if there are any patches to send to any of the | ||
1020 | // ScenePresences. | ||
1021 | // Loop through all the per-client info and send any patches necessary. | ||
1022 | private void CheckSendingPatchesToClients() | ||
1023 | { | ||
1024 | lock (m_perClientPatchUpdates) | ||
1025 | { | ||
1026 | foreach (PatchUpdates pups in m_perClientPatchUpdates.Values) | ||
1027 | { | ||
1028 | if (pups.HasUpdates()) | ||
1029 | { | ||
1030 | // There is something that could be sent to this client. | ||
1031 | List<PatchesToSend> toSend = GetModifiedPatchesInViewDistance(pups); | ||
1032 | if (toSend.Count > 0) | ||
1033 | { | ||
1034 | // m_log.DebugFormat("{0} CheckSendingPatchesToClient: sending {1} patches to {2} in region {3}", | ||
1035 | // LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName); | ||
1036 | // Sort the patches to send by the distance from the presence | ||
1037 | toSend.Sort(); | ||
1038 | foreach (PatchesToSend pts in toSend) | ||
1039 | { | ||
1040 | // TODO: one can send multiple patches in a packet. Do that. | ||
1041 | pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null); | ||
1042 | // presence.ControllingClient.SendLayerData(xs.ToArray(), ys.ToArray(), null, TerrainPatch.LayerType.Land); | ||
1043 | } | ||
1044 | } | ||
1045 | } | ||
1046 | } | ||
1047 | } | ||
1048 | } | ||
1049 | |||
1050 | private List<PatchesToSend> GetModifiedPatchesInViewDistance(PatchUpdates pups) | ||
1051 | { | ||
1052 | List<PatchesToSend> ret = new List<PatchesToSend>(); | ||
1053 | |||
1054 | ScenePresence presence = pups.Presence; | ||
1055 | if (presence == null) | ||
1056 | return ret; | ||
1057 | |||
1058 | // Compute the area of patches within our draw distance | ||
1059 | int startX = (((int) (presence.AbsolutePosition.X - presence.DrawDistance))/Constants.TerrainPatchSize) - 2; | ||
1060 | startX = Math.Max(startX, 0); | ||
1061 | startX = Math.Min(startX, (int)m_scene.RegionInfo.RegionSizeX/Constants.TerrainPatchSize); | ||
1062 | int startY = (((int) (presence.AbsolutePosition.Y - presence.DrawDistance))/Constants.TerrainPatchSize) - 2; | ||
1063 | startY = Math.Max(startY, 0); | ||
1064 | startY = Math.Min(startY, (int)m_scene.RegionInfo.RegionSizeY/Constants.TerrainPatchSize); | ||
1065 | int endX = (((int) (presence.AbsolutePosition.X + presence.DrawDistance))/Constants.TerrainPatchSize) + 2; | ||
1066 | endX = Math.Max(endX, 0); | ||
1067 | endX = Math.Min(endX, (int)m_scene.RegionInfo.RegionSizeX/Constants.TerrainPatchSize); | ||
1068 | int endY = (((int) (presence.AbsolutePosition.Y + presence.DrawDistance))/Constants.TerrainPatchSize) + 2; | ||
1069 | endY = Math.Max(endY, 0); | ||
1070 | endY = Math.Min(endY, (int)m_scene.RegionInfo.RegionSizeY/Constants.TerrainPatchSize); | ||
1071 | // m_log.DebugFormat("{0} GetModifiedPatchesInViewDistance. rName={1}, ddist={2}, apos={3}, start=<{4},{5}>, end=<{6},{7}>", | ||
1072 | // LogHeader, m_scene.RegionInfo.RegionName, | ||
1073 | // presence.DrawDistance, presence.AbsolutePosition, | ||
1074 | // startX, startY, endX, endY); | ||
1075 | for (int x = startX; x < endX; x++) | ||
1076 | { | ||
1077 | for (int y = startY; y < endY; y++) | ||
1078 | { | ||
1079 | //Need to make sure we don't send the same ones over and over | ||
1080 | Vector3 presencePos = presence.AbsolutePosition; | ||
1081 | Vector3 patchPos = new Vector3(x * Constants.TerrainPatchSize, y * Constants.TerrainPatchSize, presencePos.Z); | ||
1082 | if (pups.GetByPatch(x, y)) | ||
1083 | { | ||
1084 | //Check which has less distance, camera or avatar position, both have to be done. | ||
1085 | //Its not a radius, its a diameter and we add 50 so that it doesn't look like it cuts off | ||
1086 | if (Util.DistanceLessThan(presencePos, patchPos, presence.DrawDistance + 50) | ||
1087 | || Util.DistanceLessThan(presence.CameraPosition, patchPos, presence.DrawDistance + 50)) | ||
1088 | { | ||
1089 | //They can see it, send it to them | ||
1090 | pups.SetByPatch(x, y, false); | ||
1091 | float dist = Vector3.DistanceSquared(presencePos, patchPos); | ||
1092 | ret.Add(new PatchesToSend(x, y, dist)); | ||
1093 | //Wait and send them all at once | ||
1094 | // pups.client.SendLayerData(x, y, null); | ||
1095 | } | ||
1096 | } | ||
1097 | } | ||
1098 | } | ||
1099 | return ret; | ||
871 | } | 1100 | } |
872 | 1101 | ||
873 | private void client_OnModifyTerrain(UUID user, float height, float seconds, byte size, byte action, | 1102 | private void client_OnModifyTerrain(UUID user, float height, float seconds, byte size, byte action, |
diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs index a6f5d98..28f797a 100644 --- a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs | |||
@@ -24,9 +24,10 @@ | |||
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 | using System.IO; | ||
27 | 28 | ||
29 | using OpenSim.Framework; | ||
28 | 30 | ||
29 | using System.IO; | ||
30 | using OpenMetaverse; | 31 | using OpenMetaverse; |
31 | 32 | ||
32 | namespace OpenSim.Region.Framework.Interfaces | 33 | namespace OpenSim.Region.Framework.Interfaces |
@@ -44,6 +45,12 @@ namespace OpenSim.Region.Framework.Interfaces | |||
44 | void TaintTerrain(); | 45 | void TaintTerrain(); |
45 | 46 | ||
46 | /// <summary> | 47 | /// <summary> |
48 | /// When a client initially connects, all the terrain must be pushed to the viewer. | ||
49 | /// This call causes all the terrain patches to be sent to the client. | ||
50 | /// </summary> | ||
51 | void PushTerrain(IClientAPI pClient); | ||
52 | |||
53 | /// <summary> | ||
47 | /// Load a terrain from a stream. | 54 | /// Load a terrain from a stream. |
48 | /// </summary> | 55 | /// </summary> |
49 | /// <param name="filename"> | 56 | /// <param name="filename"> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 4208669..0445268 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs | |||
@@ -213,7 +213,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
213 | /// <param name="RemoteClient">Client to send to</param> | 213 | /// <param name="RemoteClient">Client to send to</param> |
214 | public virtual void SendLayerData(IClientAPI RemoteClient) | 214 | public virtual void SendLayerData(IClientAPI RemoteClient) |
215 | { | 215 | { |
216 | RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); | 216 | // RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); |
217 | ITerrainModule terrModule = RequestModuleInterface<ITerrainModule>(); | ||
218 | if (terrModule != null) | ||
219 | { | ||
220 | terrModule.PushTerrain(RemoteClient); | ||
221 | } | ||
217 | } | 222 | } |
218 | 223 | ||
219 | #endregion | 224 | #endregion |
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index c873e40..45c3348 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | |||
@@ -52,6 +52,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
52 | public class SceneCommunicationService //one instance per region | 52 | public class SceneCommunicationService //one instance per region |
53 | { | 53 | { |
54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
55 | private static string LogHeader = "[SCENE COMMUNIATION SERVICE]"; | ||
55 | 56 | ||
56 | protected RegionInfo m_regionInfo; | 57 | protected RegionInfo m_regionInfo; |
57 | protected Scene m_scene; | 58 | protected Scene m_scene; |
@@ -84,15 +85,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
84 | if (neighbourService != null) | 85 | if (neighbourService != null) |
85 | neighbour = neighbourService.HelloNeighbour(regionhandle, region); | 86 | neighbour = neighbourService.HelloNeighbour(regionhandle, region); |
86 | else | 87 | else |
87 | m_log.DebugFormat( | 88 | m_log.DebugFormat( "{0} neighbour service provided for region {0} to inform neigbhours of status", LogHeader, m_scene.Name); |
88 | "[SCENE COMMUNICATION SERVICE]: No neighbour service provided for region {0} to inform neigbhours of status", | ||
89 | m_scene.Name); | ||
90 | 89 | ||
91 | if (neighbour != null) | 90 | if (neighbour != null) |
92 | { | 91 | { |
93 | m_log.DebugFormat( | 92 | m_log.DebugFormat( "{0} Region {1} successfully informed neighbour {2} at {3}-{4} that it is up", |
94 | "[SCENE COMMUNICATION SERVICE]: Region {0} successfully informed neighbour {1} at {2}-{3} that it is up", | 93 | LogHeader, m_scene.Name, neighbour.RegionName, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y)); |
95 | m_scene.Name, neighbour.RegionName, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y)); | ||
96 | 94 | ||
97 | m_scene.EventManager.TriggerOnRegionUp(neighbour); | 95 | m_scene.EventManager.TriggerOnRegionUp(neighbour); |
98 | } | 96 | } |
@@ -111,9 +109,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
111 | List<GridRegion> neighbours | 109 | List<GridRegion> neighbours |
112 | = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID); | 110 | = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID); |
113 | 111 | ||
114 | m_log.DebugFormat( | 112 | m_log.DebugFormat("{0} Informing {1} neighbours that region {2} is up", LogHeader, neighbours.Count, m_scene.Name); |
115 | "[SCENE COMMUNICATION SERVICE]: Informing {0} neighbours that region {1} is up", | ||
116 | neighbours.Count, m_scene.Name); | ||
117 | 113 | ||
118 | foreach (GridRegion n in neighbours) | 114 | foreach (GridRegion n in neighbours) |
119 | { | 115 | { |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 37353c1..063ac73 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -873,7 +873,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
873 | m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; | 873 | m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; |
874 | Animator = new ScenePresenceAnimator(this); | 874 | Animator = new ScenePresenceAnimator(this); |
875 | PresenceType = type; | 875 | PresenceType = type; |
876 | DrawDistance = world.DefaultDrawDistance; | 876 | // DrawDistance = world.DefaultDrawDistance; |
877 | DrawDistance = Constants.RegionSize; | ||
877 | RegionHandle = world.RegionInfo.RegionHandle; | 878 | RegionHandle = world.RegionInfo.RegionHandle; |
878 | ControllingClient = client; | 879 | ControllingClient = client; |
879 | Firstname = ControllingClient.FirstName; | 880 | Firstname = ControllingClient.FirstName; |
@@ -1918,8 +1919,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1918 | // When we get to the point of re-computing neighbors everytime this | 1919 | // When we get to the point of re-computing neighbors everytime this |
1919 | // changes, then start using the agent's drawdistance rather than the | 1920 | // changes, then start using the agent's drawdistance rather than the |
1920 | // region's draw distance. | 1921 | // region's draw distance. |
1921 | // DrawDistance = agentData.Far; | 1922 | DrawDistance = agentData.Far; |
1922 | DrawDistance = Scene.DefaultDrawDistance; | 1923 | // DrawDistance = Scene.DefaultDrawDistance; |
1923 | 1924 | ||
1924 | m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; | 1925 | m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; |
1925 | m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; | 1926 | m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; |
@@ -2277,8 +2278,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2277 | // When we get to the point of re-computing neighbors everytime this | 2278 | // When we get to the point of re-computing neighbors everytime this |
2278 | // changes, then start using the agent's drawdistance rather than the | 2279 | // changes, then start using the agent's drawdistance rather than the |
2279 | // region's draw distance. | 2280 | // region's draw distance. |
2280 | // DrawDistance = agentData.Far; | 2281 | DrawDistance = agentData.Far; |
2281 | DrawDistance = Scene.DefaultDrawDistance; | 2282 | // DrawDistance = Scene.DefaultDrawDistance; |
2282 | 2283 | ||
2283 | // Check if Client has camera in 'follow cam' or 'build' mode. | 2284 | // Check if Client has camera in 'follow cam' or 'build' mode. |
2284 | Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation); | 2285 | Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation); |
@@ -3824,8 +3825,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3824 | // When we get to the point of re-computing neighbors everytime this | 3825 | // When we get to the point of re-computing neighbors everytime this |
3825 | // changes, then start using the agent's drawdistance rather than the | 3826 | // changes, then start using the agent's drawdistance rather than the |
3826 | // region's draw distance. | 3827 | // region's draw distance. |
3827 | // DrawDistance = cAgentData.Far; | 3828 | DrawDistance = cAgentData.Far; |
3828 | DrawDistance = Scene.DefaultDrawDistance; | 3829 | // DrawDistance = Scene.DefaultDrawDistance; |
3829 | 3830 | ||
3830 | if (cAgentData.Position != marker) // UGH!! | 3831 | if (cAgentData.Position != marker) // UGH!! |
3831 | m_pos = cAgentData.Position + offset; | 3832 | m_pos = cAgentData.Position + offset; |
@@ -3935,8 +3936,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3935 | // When we get to the point of re-computing neighbors everytime this | 3936 | // When we get to the point of re-computing neighbors everytime this |
3936 | // changes, then start using the agent's drawdistance rather than the | 3937 | // changes, then start using the agent's drawdistance rather than the |
3937 | // region's draw distance. | 3938 | // region's draw distance. |
3938 | // DrawDistance = cAgent.Far; | 3939 | DrawDistance = cAgent.Far; |
3939 | DrawDistance = Scene.DefaultDrawDistance; | 3940 | // DrawDistance = Scene.DefaultDrawDistance; |
3940 | 3941 | ||
3941 | if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) | 3942 | if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) |
3942 | ControllingClient.SetChildAgentThrottle(cAgent.Throttles); | 3943 | ControllingClient.SetChildAgentThrottle(cAgent.Throttles); |
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 8198592..36957a7 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs | |||
@@ -46,6 +46,7 @@ namespace OpenSim.Services.GridService | |||
46 | private static readonly ILog m_log = | 46 | private static readonly ILog m_log = |
47 | LogManager.GetLogger( | 47 | LogManager.GetLogger( |
48 | MethodBase.GetCurrentMethod().DeclaringType); | 48 | MethodBase.GetCurrentMethod().DeclaringType); |
49 | private string LogHeader = "[GRID SERVICE]"; | ||
49 | 50 | ||
50 | private bool m_DeleteOnUnregister = true; | 51 | private bool m_DeleteOnUnregister = true; |
51 | private static GridService m_RootInstance = null; | 52 | private static GridService m_RootInstance = null; |
@@ -328,7 +329,11 @@ namespace OpenSim.Services.GridService | |||
328 | } | 329 | } |
329 | } | 330 | } |
330 | 331 | ||
331 | // m_log.DebugFormat("[GRID SERVICE]: region {0} has {1} neighbours", region.RegionName, rinfos.Count); | 332 | // string rNames = ""; |
333 | // foreach (GridRegion gr in rinfos) | ||
334 | // rNames += gr.RegionName + ","; | ||
335 | // m_log.DebugFormat("{0} region {1} has {2} neighbours ({3})", | ||
336 | // LogHeader, region.RegionName, rinfos.Count, rNames); | ||
332 | } | 337 | } |
333 | else | 338 | else |
334 | { | 339 | { |
@@ -657,7 +662,7 @@ namespace OpenSim.Services.GridService | |||
657 | return; | 662 | return; |
658 | } | 663 | } |
659 | 664 | ||
660 | RegionData region = m_Database.Get((int)Util.RegionToWorldLoc(x), (int)Util.RegionToWorldLoc(y), UUID.Zero); | 665 | RegionData region = m_Database.Get((int)Util.RegionToWorldLoc(x), (int)Util.RegionToWorldLoc(y), UUID.Zero); |
661 | if (region == null) | 666 | if (region == null) |
662 | { | 667 | { |
663 | MainConsole.Instance.OutputFormat("No region found at {0},{1}", x, y); | 668 | MainConsole.Instance.OutputFormat("No region found at {0},{1}", x, y); |
diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs index 31e147b..0e425f8 100644 --- a/OpenSim/Services/MapImageService/MapImageService.cs +++ b/OpenSim/Services/MapImageService/MapImageService.cs | |||
@@ -36,6 +36,7 @@ using System.Drawing.Imaging; | |||
36 | using System.IO; | 36 | using System.IO; |
37 | using System.Net; | 37 | using System.Net; |
38 | using System.Reflection; | 38 | using System.Reflection; |
39 | using System.Threading; | ||
39 | 40 | ||
40 | using Nini.Config; | 41 | using Nini.Config; |
41 | using log4net; | 42 | using log4net; |
@@ -53,6 +54,7 @@ namespace OpenSim.Services.MapImageService | |||
53 | private static readonly ILog m_log = | 54 | private static readonly ILog m_log = |
54 | LogManager.GetLogger( | 55 | LogManager.GetLogger( |
55 | MethodBase.GetCurrentMethod().DeclaringType); | 56 | MethodBase.GetCurrentMethod().DeclaringType); |
57 | private string LogHeader = "[MAP IMAGE SERVICE]"; | ||
56 | 58 | ||
57 | private const int ZOOM_LEVELS = 8; | 59 | private const int ZOOM_LEVELS = 8; |
58 | private const int IMAGE_WIDTH = 256; | 60 | private const int IMAGE_WIDTH = 256; |
@@ -114,7 +116,7 @@ namespace OpenSim.Services.MapImageService | |||
114 | } | 116 | } |
115 | } | 117 | } |
116 | 118 | ||
117 | return UpdateMultiResolutionFiles(x, y, out reason); | 119 | return UpdateMultiResolutionFilesAsync(x, y, out reason); |
118 | } | 120 | } |
119 | 121 | ||
120 | public bool RemoveMapTile(int x, int y, out string reason) | 122 | public bool RemoveMapTile(int x, int y, out string reason) |
@@ -136,33 +138,81 @@ namespace OpenSim.Services.MapImageService | |||
136 | } | 138 | } |
137 | } | 139 | } |
138 | 140 | ||
139 | return UpdateMultiResolutionFiles(x, y, out reason); | 141 | return UpdateMultiResolutionFilesAsync(x, y, out reason); |
140 | } | 142 | } |
141 | 143 | ||
142 | private bool UpdateMultiResolutionFiles(int x, int y, out string reason) | 144 | // When large varregions start up, they can send piles of new map tiles. This causes |
145 | // this multi-resolution routine to be called a zillion times an causes much CPU | ||
146 | // time to be spent creating multi-resolution tiles that will be replaced when | ||
147 | // the next maptile arrives. | ||
148 | private class mapToMultiRez | ||
149 | { | ||
150 | public int xx; | ||
151 | public int yy; | ||
152 | public mapToMultiRez(int pX, int pY) | ||
153 | { | ||
154 | xx = pX; | ||
155 | yy = pY; | ||
156 | } | ||
157 | }; | ||
158 | private Queue<mapToMultiRez> multiRezToBuild = new Queue<mapToMultiRez>(); | ||
159 | private bool UpdateMultiResolutionFilesAsync(int x, int y, out string reason) | ||
143 | { | 160 | { |
144 | reason = String.Empty; | 161 | reason = String.Empty; |
145 | lock (m_Sync) | 162 | lock (multiRezToBuild) |
146 | { | 163 | { |
147 | // Stitch seven more aggregate tiles together | 164 | // m_log.DebugFormat("{0} UpdateMultiResolutionFilesAsync: scheduling update for <{1},{2}>", LogHeader, x, y); |
148 | for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++) | 165 | multiRezToBuild.Enqueue(new mapToMultiRez(x, y)); |
166 | if (multiRezToBuild.Count == 1) | ||
167 | Util.FireAndForget(DoUpdateMultiResolutionFilesAsync); | ||
168 | } | ||
169 | |||
170 | return true; | ||
171 | } | ||
172 | |||
173 | private void DoUpdateMultiResolutionFilesAsync(object o) | ||
174 | { | ||
175 | // This sleep causes the FireAndForget thread to be different than the invocation thread. | ||
176 | // It also allows other tiles to be uploaded so the multi-rez images are more likely | ||
177 | // to be correct. | ||
178 | Thread.Sleep(1 * 1000); | ||
179 | |||
180 | while (multiRezToBuild.Count > 0) | ||
181 | { | ||
182 | mapToMultiRez toMultiRez = null; | ||
183 | lock (multiRezToBuild) | ||
149 | { | 184 | { |
150 | // Calculate the width (in full resolution tiles) and bottom-left | 185 | if (multiRezToBuild.Count > 0) |
151 | // corner of the current zoom level | 186 | toMultiRez = multiRezToBuild.Dequeue(); |
152 | int width = (int)Math.Pow(2, (double)(zoomLevel - 1)); | 187 | } |
153 | int x1 = x - (x % width); | 188 | if (toMultiRez != null) |
154 | int y1 = y - (y % width); | 189 | { |
190 | int x = toMultiRez.xx; | ||
191 | int y = toMultiRez.yy; | ||
192 | // m_log.DebugFormat("{0} DoUpdateMultiResolutionFilesAsync: doing build for <{1},{2}>", LogHeader, x, y); | ||
155 | 193 | ||
156 | if (!CreateTile(zoomLevel, x1, y1)) | 194 | // Stitch seven more aggregate tiles together |
195 | for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++) | ||
157 | { | 196 | { |
158 | m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0},{1} at zoom level {1}", x, y, zoomLevel); | 197 | // Calculate the width (in full resolution tiles) and bottom-left |
159 | reason = string.Format("Map tile at zoom level {0} failed", zoomLevel); | 198 | // corner of the current zoom level |
160 | return false; | 199 | int width = (int)Math.Pow(2, (double)(zoomLevel - 1)); |
200 | int x1 = x - (x % width); | ||
201 | int y1 = y - (y % width); | ||
202 | |||
203 | lock (m_Sync) // must lock the reading and writing of the maptile files | ||
204 | { | ||
205 | if (!CreateTile(zoomLevel, x1, y1)) | ||
206 | { | ||
207 | m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0},{1} at zoom level {1}", x, y, zoomLevel); | ||
208 | return; | ||
209 | } | ||
210 | } | ||
161 | } | 211 | } |
162 | } | 212 | } |
163 | } | 213 | } |
164 | 214 | ||
165 | return true; | 215 | return; |
166 | } | 216 | } |
167 | 217 | ||
168 | public byte[] GetMapTile(string fileName, out string format) | 218 | public byte[] GetMapTile(string fileName, out string format) |