Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

fsassets
Diva Canto 2015-06-09 13:22:24 -07:00
commit a83d2247d4
1 changed files with 49 additions and 25 deletions

View File

@ -107,11 +107,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain
private bool[,] updated; // for each patch, whether it needs to be sent to this client private bool[,] updated; // for each patch, whether it needs to be sent to this client
private int updateCount; // number of patches that need to be sent private int updateCount; // number of patches that need to be sent
public ScenePresence Presence; // a reference to the client to send to public ScenePresence Presence; // a reference to the client to send to
public TerrainData Terrain; // reference to the underlying terrain
public PatchUpdates(TerrainData terrData, ScenePresence pPresence) public PatchUpdates(TerrainData terrData, ScenePresence pPresence)
{ {
updated = new bool[terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize]; updated = new bool[terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize];
updateCount = 0; updateCount = 0;
Presence = pPresence; Presence = pPresence;
Terrain = terrData;
// Initially, send all patches to the client // Initially, send all patches to the client
SetAll(true); SetAll(true);
} }
@ -519,6 +521,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
// ITerrainModule.PushTerrain() // ITerrainModule.PushTerrain()
public void PushTerrain(IClientAPI pClient) public void PushTerrain(IClientAPI pClient)
{ {
// If view distance based, set the modified patch bits and the frame event will send the updates
if (m_sendTerrainUpdatesByViewDistance) if (m_sendTerrainUpdatesByViewDistance)
{ {
ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId); ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId);
@ -533,6 +536,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence); pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence);
m_perClientPatchUpdates.Add(presence.UUID, pups); m_perClientPatchUpdates.Add(presence.UUID, pups);
} }
// By setting all to modified, the next update tick will send the patches
pups.SetAll(true); pups.SetAll(true);
} }
} }
@ -543,7 +547,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
pClient.SendLayerData(new float[10]); pClient.SendLayerData(new float[10]);
} }
} }
#region Plugin Loading Methods #region Plugin Loading Methods
private void LoadPlugins() private void LoadPlugins()
@ -991,16 +994,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain
else else
{ {
// Legacy update sending where the update is sent out as soon as noticed // Legacy update sending where the update is sent out as soon as noticed
// We know the actual terrain data passed is ignored. This kludge saves changing IClientAPI. // We know the actual terrain data that is passed is ignored so this passes a dummy heightmap.
//float[] heightMap = terrData.GetFloatsSerialized(); //float[] heightMap = terrData.GetFloatsSerialized();
float[] heightMap = new float[10]; float[] heightMap = new float[10];
m_scene.ForEachClient( m_scene.ForEachClient(
delegate(IClientAPI controller) delegate(IClientAPI controller)
{ {
controller.SendLayerData(x / Constants.TerrainPatchSize, controller.SendLayerData(x / Constants.TerrainPatchSize,
y / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize,
heightMap); heightMap);
} }
); );
} }
} }
@ -1026,6 +1029,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
// Called each frame time to see if there are any patches to send to any of the // Called each frame time to see if there are any patches to send to any of the
// ScenePresences. // ScenePresences.
// We know this is only called if we are doing view distance patch sending so some
// tests are not made.
// Loop through all the per-client info and send any patches necessary. // Loop through all the per-client info and send any patches necessary.
private void CheckSendingPatchesToClients() private void CheckSendingPatchesToClients()
{ {
@ -1043,7 +1048,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
// LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName); // LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName);
// Sort the patches to send by the distance from the presence // Sort the patches to send by the distance from the presence
toSend.Sort(); toSend.Sort();
/* /* old way that sent individual patches
foreach (PatchesToSend pts in toSend) foreach (PatchesToSend pts in toSend)
{ {
pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null); pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null);
@ -1051,6 +1056,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
} }
*/ */
// new way that sends all patches to the protocol so they can be sent in one block
int[] xPieces = new int[toSend.Count]; int[] xPieces = new int[toSend.Count];
int[] yPieces = new int[toSend.Count]; int[] yPieces = new int[toSend.Count];
float[] patchPieces = new float[toSend.Count * 2]; float[] patchPieces = new float[toSend.Count * 2];
@ -1067,6 +1073,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
} }
} }
// Compute a list of modified patches that are within our view distance.
private List<PatchesToSend> GetModifiedPatchesInViewDistance(PatchUpdates pups) private List<PatchesToSend> GetModifiedPatchesInViewDistance(PatchUpdates pups)
{ {
List<PatchesToSend> ret = new List<PatchesToSend>(); List<PatchesToSend> ret = new List<PatchesToSend>();
@ -1075,43 +1082,60 @@ namespace OpenSim.Region.CoreModules.World.Terrain
if (presence == null) if (presence == null)
return ret; return ret;
// Compute the area of patches within our draw distance Vector3 presencePos = presence.AbsolutePosition;
int startX = (((int)(presence.AbsolutePosition.X - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2;
startX = Math.Max(startX, 0); // Before this distance check, the whole region just showed up. Adding the distance
startX = Math.Min(startX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize); // check causes different things to happen for the current and adjacent regions.
int startY = (((int)(presence.AbsolutePosition.Y - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2; // So, to keep legacy views, if the region is legacy sized, don't do distance check.
startY = Math.Max(startY, 0); bool isLegacySizedRegion = pups.Terrain.SizeX == Constants.RegionSize && pups.Terrain.SizeY == Constants.RegionSize;
startY = Math.Min(startY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize); bool shouldCheckViewDistance = m_sendTerrainUpdatesByViewDistance && !isLegacySizedRegion;
int endX = (((int)(presence.AbsolutePosition.X + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2;
endX = Math.Max(endX, 0); int startX = 0;
endX = Math.Min(endX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize); int endX = (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize;
int endY = (((int)(presence.AbsolutePosition.Y + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2; int startY = 0;
endY = Math.Max(endY, 0); int endY = (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize;
endY = Math.Min(endY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize);
// m_log.DebugFormat("{0} GetModifiedPatchesInViewDistance. rName={1}, ddist={2}, apos={3}, start=<{4},{5}>, end=<{6},{7}>", // The following only reduces the size of area scanned for updates. Only significant for very large varregions.
if (shouldCheckViewDistance)
{
// Compute the area of patches within our draw distance
startX = (((int)(presencePos.X - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2;
startX = Math.Max(startX, 0);
startX = Math.Min(startX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize);
startY = (((int)(presencePos.Y - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2;
startY = Math.Max(startY, 0);
startY = Math.Min(startY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize);
endX = (((int)(presencePos.X + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2;
endX = Math.Max(endX, 0);
endX = Math.Min(endX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize);
endY = (((int)(presencePos.Y + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2;
endY = Math.Max(endY, 0);
endY = Math.Min(endY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize);
}
// m_log.DebugFormat("{0} GetModifiedPatchesInViewDistance. rName={1}, ddist={2}, apos={3}, cpos={4}, isChild={5}, start=<{6},{7}>, end=<{8},{9}>",
// LogHeader, m_scene.RegionInfo.RegionName, // LogHeader, m_scene.RegionInfo.RegionName,
// presence.DrawDistance, presence.AbsolutePosition, // presence.DrawDistance, presencePos, presence.CameraPosition,
// isLegacySizeChildRegion,
// startX, startY, endX, endY); // startX, startY, endX, endY);
for(int x = startX; x < endX; x++) for(int x = startX; x < endX; x++)
{ {
for(int y = startY; y < endY; y++) for(int y = startY; y < endY; y++)
{ {
//Need to make sure we don't send the same ones over and over //Need to make sure we don't send the same ones over and over
Vector3 presencePos = presence.AbsolutePosition;
Vector3 patchPos = new Vector3(x * Constants.TerrainPatchSize, y * Constants.TerrainPatchSize, presencePos.Z); Vector3 patchPos = new Vector3(x * Constants.TerrainPatchSize, y * Constants.TerrainPatchSize, presencePos.Z);
if (pups.GetByPatch(x, y)) if (pups.GetByPatch(x, y))
{ {
//Check which has less distance, camera or avatar position, both have to be done. //Check which has less distance, camera or avatar position, both have to be done.
//Its not a radius, its a diameter and we add 50 so that it doesn't look like it cuts off //Its not a radius, its a diameter and we add 50 so that it doesn't look like it cuts off
if (Util.DistanceLessThan(presencePos, patchPos, presence.DrawDistance + 50) if (!shouldCheckViewDistance
|| Util.DistanceLessThan(presencePos, patchPos, presence.DrawDistance + 50)
|| Util.DistanceLessThan(presence.CameraPosition, patchPos, presence.DrawDistance + 50)) || Util.DistanceLessThan(presence.CameraPosition, patchPos, presence.DrawDistance + 50))
{ {
//They can see it, send it to them //They can see it, send it to them
pups.SetByPatch(x, y, false); pups.SetByPatch(x, y, false);
float dist = Vector3.DistanceSquared(presencePos, patchPos); float dist = Vector3.DistanceSquared(presencePos, patchPos);
ret.Add(new PatchesToSend(x, y, dist)); ret.Add(new PatchesToSend(x, y, dist));
//Wait and send them all at once
// pups.client.SendLayerData(x, y, null);
} }
} }
} }