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 int updateCount; // number of patches that need to be sent
|
||||
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)
|
||||
{
|
||||
updated = new bool[terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize];
|
||||
updateCount = 0;
|
||||
Presence = pPresence;
|
||||
Terrain = terrData;
|
||||
// Initially, send all patches to the client
|
||||
SetAll(true);
|
||||
}
|
||||
|
@ -519,6 +521,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
// ITerrainModule.PushTerrain()
|
||||
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)
|
||||
{
|
||||
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);
|
||||
m_perClientPatchUpdates.Add(presence.UUID, pups);
|
||||
}
|
||||
// By setting all to modified, the next update tick will send the patches
|
||||
pups.SetAll(true);
|
||||
}
|
||||
}
|
||||
|
@ -543,7 +547,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
pClient.SendLayerData(new float[10]);
|
||||
}
|
||||
}
|
||||
|
||||
#region Plugin Loading Methods
|
||||
|
||||
private void LoadPlugins()
|
||||
|
@ -991,7 +994,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
else
|
||||
{
|
||||
// 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 = new float[10];
|
||||
m_scene.ForEachClient(
|
||||
|
@ -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
|
||||
// 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.
|
||||
private void CheckSendingPatchesToClients()
|
||||
{
|
||||
|
@ -1043,7 +1048,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
// LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName);
|
||||
// Sort the patches to send by the distance from the presence
|
||||
toSend.Sort();
|
||||
/*
|
||||
/* old way that sent individual patches
|
||||
foreach (PatchesToSend pts in toSend)
|
||||
{
|
||||
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[] yPieces = new int[toSend.Count];
|
||||
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)
|
||||
{
|
||||
List<PatchesToSend> ret = new List<PatchesToSend>();
|
||||
|
@ -1075,43 +1082,60 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
|||
if (presence == null)
|
||||
return ret;
|
||||
|
||||
Vector3 presencePos = presence.AbsolutePosition;
|
||||
|
||||
// Before this distance check, the whole region just showed up. Adding the distance
|
||||
// check causes different things to happen for the current and adjacent regions.
|
||||
// So, to keep legacy views, if the region is legacy sized, don't do distance check.
|
||||
bool isLegacySizedRegion = pups.Terrain.SizeX == Constants.RegionSize && pups.Terrain.SizeY == Constants.RegionSize;
|
||||
bool shouldCheckViewDistance = m_sendTerrainUpdatesByViewDistance && !isLegacySizedRegion;
|
||||
|
||||
int startX = 0;
|
||||
int endX = (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize;
|
||||
int startY = 0;
|
||||
int endY = (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize;
|
||||
|
||||
// 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
|
||||
int startX = (((int)(presence.AbsolutePosition.X - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2;
|
||||
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);
|
||||
int startY = (((int)(presence.AbsolutePosition.Y - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2;
|
||||
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);
|
||||
int endX = (((int)(presence.AbsolutePosition.X + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2;
|
||||
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);
|
||||
int endY = (((int)(presence.AbsolutePosition.Y + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2;
|
||||
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}, start=<{4},{5}>, end=<{6},{7}>",
|
||||
}
|
||||
|
||||
// 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,
|
||||
// presence.DrawDistance, presence.AbsolutePosition,
|
||||
// presence.DrawDistance, presencePos, presence.CameraPosition,
|
||||
// isLegacySizeChildRegion,
|
||||
// startX, startY, endX, endY);
|
||||
for(int x = startX; x < endX; x++)
|
||||
{
|
||||
for(int y = startY; y < endY; y++)
|
||||
{
|
||||
//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);
|
||||
if (pups.GetByPatch(x, y))
|
||||
{
|
||||
//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
|
||||
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))
|
||||
{
|
||||
//They can see it, send it to them
|
||||
pups.SetByPatch(x, y, false);
|
||||
float dist = Vector3.DistanceSquared(presencePos, patchPos);
|
||||
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