aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
diff options
context:
space:
mode:
authorRobert Adams2015-06-06 07:09:20 -0700
committerRobert Adams2015-06-06 07:09:20 -0700
commit81ef7b586ee357904d8f3669d838df373fbedb83 (patch)
treebabaed3ec1ade33e5fbf94a6b9f36388377a6e60 /OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
parentTypo Fix (diff)
downloadopensim-SC_OLD-81ef7b586ee357904d8f3669d838df373fbedb83.zip
opensim-SC_OLD-81ef7b586ee357904d8f3669d838df373fbedb83.tar.gz
opensim-SC_OLD-81ef7b586ee357904d8f3669d838df373fbedb83.tar.bz2
opensim-SC_OLD-81ef7b586ee357904d8f3669d838df373fbedb83.tar.xz
Address Mantis 7592 (http://opensimulator.org/mantis/view.php?id=7592) by
disabling terrain patch sending by view distance for legacy sized regions. The problem seems to be that people expect adjacent legacy sized regions to just display like they always have. Limiting displayed terrain is complicated by the camera position not being updated in child regions.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs74
1 files changed, 49 insertions, 25 deletions
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index cec17e2..932652c 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -107,11 +107,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain
107 private bool[,] updated; // for each patch, whether it needs to be sent to this client 107 private bool[,] updated; // for each patch, whether it needs to be sent to this client
108 private int updateCount; // number of patches that need to be sent 108 private int updateCount; // number of patches that need to be sent
109 public ScenePresence Presence; // a reference to the client to send to 109 public ScenePresence Presence; // a reference to the client to send to
110 public TerrainData Terrain; // reference to the underlying terrain
110 public PatchUpdates(TerrainData terrData, ScenePresence pPresence) 111 public PatchUpdates(TerrainData terrData, ScenePresence pPresence)
111 { 112 {
112 updated = new bool[terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize]; 113 updated = new bool[terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize];
113 updateCount = 0; 114 updateCount = 0;
114 Presence = pPresence; 115 Presence = pPresence;
116 Terrain = terrData;
115 // Initially, send all patches to the client 117 // Initially, send all patches to the client
116 SetAll(true); 118 SetAll(true);
117 } 119 }
@@ -519,6 +521,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
519 // ITerrainModule.PushTerrain() 521 // ITerrainModule.PushTerrain()
520 public void PushTerrain(IClientAPI pClient) 522 public void PushTerrain(IClientAPI pClient)
521 { 523 {
524 // If view distance based, set the modified patch bits and the frame event will send the updates
522 if (m_sendTerrainUpdatesByViewDistance) 525 if (m_sendTerrainUpdatesByViewDistance)
523 { 526 {
524 ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId); 527 ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId);
@@ -533,6 +536,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
533 pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence); 536 pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence);
534 m_perClientPatchUpdates.Add(presence.UUID, pups); 537 m_perClientPatchUpdates.Add(presence.UUID, pups);
535 } 538 }
539 // By setting all to modified, the next update tick will send the patches
536 pups.SetAll(true); 540 pups.SetAll(true);
537 } 541 }
538 } 542 }
@@ -543,7 +547,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
543 pClient.SendLayerData(new float[10]); 547 pClient.SendLayerData(new float[10]);
544 } 548 }
545 } 549 }
546
547 #region Plugin Loading Methods 550 #region Plugin Loading Methods
548 551
549 private void LoadPlugins() 552 private void LoadPlugins()
@@ -991,16 +994,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain
991 else 994 else
992 { 995 {
993 // Legacy update sending where the update is sent out as soon as noticed 996 // Legacy update sending where the update is sent out as soon as noticed
994 // We know the actual terrain data passed is ignored. This kludge saves changing IClientAPI. 997 // We know the actual terrain data that is passed is ignored so this passes a dummy heightmap.
995 //float[] heightMap = terrData.GetFloatsSerialized(); 998 //float[] heightMap = terrData.GetFloatsSerialized();
996 float[] heightMap = new float[10]; 999 float[] heightMap = new float[10];
997 m_scene.ForEachClient( 1000 m_scene.ForEachClient(
998 delegate(IClientAPI controller) 1001 delegate(IClientAPI controller)
999 { 1002 {
1000 controller.SendLayerData(x / Constants.TerrainPatchSize, 1003 controller.SendLayerData(x / Constants.TerrainPatchSize,
1001 y / Constants.TerrainPatchSize, 1004 y / Constants.TerrainPatchSize,
1002 heightMap); 1005 heightMap);
1003 } 1006 }
1004 ); 1007 );
1005 } 1008 }
1006 } 1009 }
@@ -1026,6 +1029,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1026 1029
1027 // Called each frame time to see if there are any patches to send to any of the 1030 // Called each frame time to see if there are any patches to send to any of the
1028 // ScenePresences. 1031 // ScenePresences.
1032 // We know this is only called if we are doing view distance patch sending so some
1033 // tests are not made.
1029 // Loop through all the per-client info and send any patches necessary. 1034 // Loop through all the per-client info and send any patches necessary.
1030 private void CheckSendingPatchesToClients() 1035 private void CheckSendingPatchesToClients()
1031 { 1036 {
@@ -1043,7 +1048,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1043 // LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName); 1048 // LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName);
1044 // Sort the patches to send by the distance from the presence 1049 // Sort the patches to send by the distance from the presence
1045 toSend.Sort(); 1050 toSend.Sort();
1046 /* 1051 /* old way that sent individual patches
1047 foreach (PatchesToSend pts in toSend) 1052 foreach (PatchesToSend pts in toSend)
1048 { 1053 {
1049 pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null); 1054 pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null);
@@ -1051,6 +1056,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1051 } 1056 }
1052 */ 1057 */
1053 1058
1059 // new way that sends all patches to the protocol so they can be sent in one block
1054 int[] xPieces = new int[toSend.Count]; 1060 int[] xPieces = new int[toSend.Count];
1055 int[] yPieces = new int[toSend.Count]; 1061 int[] yPieces = new int[toSend.Count];
1056 float[] patchPieces = new float[toSend.Count * 2]; 1062 float[] patchPieces = new float[toSend.Count * 2];
@@ -1067,6 +1073,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1067 } 1073 }
1068 } 1074 }
1069 1075
1076 // Compute a list of modified patches that are within our view distance.
1070 private List<PatchesToSend> GetModifiedPatchesInViewDistance(PatchUpdates pups) 1077 private List<PatchesToSend> GetModifiedPatchesInViewDistance(PatchUpdates pups)
1071 { 1078 {
1072 List<PatchesToSend> ret = new List<PatchesToSend>(); 1079 List<PatchesToSend> ret = new List<PatchesToSend>();
@@ -1075,43 +1082,60 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1075 if (presence == null) 1082 if (presence == null)
1076 return ret; 1083 return ret;
1077 1084
1078 // Compute the area of patches within our draw distance 1085 Vector3 presencePos = presence.AbsolutePosition;
1079 int startX = (((int)(presence.AbsolutePosition.X - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2; 1086
1080 startX = Math.Max(startX, 0); 1087 // Before this distance check, the whole region just showed up. Adding the distance
1081 startX = Math.Min(startX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize); 1088 // check causes different things to happen for the current and adjacent regions.
1082 int startY = (((int)(presence.AbsolutePosition.Y - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2; 1089 // So, to keep legacy views, if the region is legacy sized, don't do distance check.
1083 startY = Math.Max(startY, 0); 1090 bool isLegacySizedRegion = pups.Terrain.SizeX == Constants.RegionSize && pups.Terrain.SizeY == Constants.RegionSize;
1084 startY = Math.Min(startY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize); 1091 bool shouldCheckViewDistance = m_sendTerrainUpdatesByViewDistance && !isLegacySizedRegion;
1085 int endX = (((int)(presence.AbsolutePosition.X + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2; 1092
1086 endX = Math.Max(endX, 0); 1093 int startX = 0;
1087 endX = Math.Min(endX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize); 1094 int endX = (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize;
1088 int endY = (((int)(presence.AbsolutePosition.Y + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2; 1095 int startY = 0;
1089 endY = Math.Max(endY, 0); 1096 int endY = (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize;
1090 endY = Math.Min(endY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize); 1097
1091 // m_log.DebugFormat("{0} GetModifiedPatchesInViewDistance. rName={1}, ddist={2}, apos={3}, start=<{4},{5}>, end=<{6},{7}>", 1098 // The following only reduces the size of area scanned for updates. Only significant for very large varregions.
1099 if (shouldCheckViewDistance)
1100 {
1101 // Compute the area of patches within our draw distance
1102 startX = (((int)(presencePos.X - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2;
1103 startX = Math.Max(startX, 0);
1104 startX = Math.Min(startX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize);
1105 startY = (((int)(presencePos.Y - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2;
1106 startY = Math.Max(startY, 0);
1107 startY = Math.Min(startY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize);
1108 endX = (((int)(presencePos.X + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2;
1109 endX = Math.Max(endX, 0);
1110 endX = Math.Min(endX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize);
1111 endY = (((int)(presencePos.Y + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2;
1112 endY = Math.Max(endY, 0);
1113 endY = Math.Min(endY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize);
1114 }
1115
1116 // m_log.DebugFormat("{0} GetModifiedPatchesInViewDistance. rName={1}, ddist={2}, apos={3}, cpos={4}, isChild={5}, start=<{6},{7}>, end=<{8},{9}>",
1092 // LogHeader, m_scene.RegionInfo.RegionName, 1117 // LogHeader, m_scene.RegionInfo.RegionName,
1093 // presence.DrawDistance, presence.AbsolutePosition, 1118 // presence.DrawDistance, presencePos, presence.CameraPosition,
1119 // isLegacySizeChildRegion,
1094 // startX, startY, endX, endY); 1120 // startX, startY, endX, endY);
1095 for(int x = startX; x < endX; x++) 1121 for(int x = startX; x < endX; x++)
1096 { 1122 {
1097 for(int y = startY; y < endY; y++) 1123 for(int y = startY; y < endY; y++)
1098 { 1124 {
1099 //Need to make sure we don't send the same ones over and over 1125 //Need to make sure we don't send the same ones over and over
1100 Vector3 presencePos = presence.AbsolutePosition;
1101 Vector3 patchPos = new Vector3(x * Constants.TerrainPatchSize, y * Constants.TerrainPatchSize, presencePos.Z); 1126 Vector3 patchPos = new Vector3(x * Constants.TerrainPatchSize, y * Constants.TerrainPatchSize, presencePos.Z);
1102 if (pups.GetByPatch(x, y)) 1127 if (pups.GetByPatch(x, y))
1103 { 1128 {
1104 //Check which has less distance, camera or avatar position, both have to be done. 1129 //Check which has less distance, camera or avatar position, both have to be done.
1105 //Its not a radius, its a diameter and we add 50 so that it doesn't look like it cuts off 1130 //Its not a radius, its a diameter and we add 50 so that it doesn't look like it cuts off
1106 if (Util.DistanceLessThan(presencePos, patchPos, presence.DrawDistance + 50) 1131 if (!shouldCheckViewDistance
1132 || Util.DistanceLessThan(presencePos, patchPos, presence.DrawDistance + 50)
1107 || Util.DistanceLessThan(presence.CameraPosition, patchPos, presence.DrawDistance + 50)) 1133 || Util.DistanceLessThan(presence.CameraPosition, patchPos, presence.DrawDistance + 50))
1108 { 1134 {
1109 //They can see it, send it to them 1135 //They can see it, send it to them
1110 pups.SetByPatch(x, y, false); 1136 pups.SetByPatch(x, y, false);
1111 float dist = Vector3.DistanceSquared(presencePos, patchPos); 1137 float dist = Vector3.DistanceSquared(presencePos, patchPos);
1112 ret.Add(new PatchesToSend(x, y, dist)); 1138 ret.Add(new PatchesToSend(x, y, dist));
1113 //Wait and send them all at once
1114 // pups.client.SendLayerData(x, y, null);
1115 } 1139 }
1116 } 1140 }
1117 } 1141 }