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.fsassets
parent
0c5facbd75
commit
81ef7b586e
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue