recover opensim m_sendTerrainUpdatesByViewDistance. if false do as opensim (slower since it depended on sending terrain as TASK). if true send by view range and also all terrain at arrival
parent
abd6640453
commit
7276a89ddd
|
@ -1242,14 +1242,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Send LayerData in typerwriter pattern
|
// Send LayerData in typerwriter pattern
|
||||||
|
//for (int y = 0; y < 16; y++)
|
||||||
|
//{
|
||||||
|
// for (int x = 0; x < 16; x++)
|
||||||
|
// {
|
||||||
|
// SendLayerData(x, y, map);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
for (int y = 0; y < 16; y++)
|
// Send LayerData in a spiral pattern. Fun!
|
||||||
{
|
SendLayerTopRight(map, 0, 0, map.SizeX / Constants.TerrainPatchSize - 1, map.SizeY / Constants.TerrainPatchSize - 1);
|
||||||
for (int x = 0; x < 16; x++)
|
|
||||||
{
|
|
||||||
SendLayerData(x, y, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -1257,6 +1259,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SendLayerTopRight(TerrainData map, int x1, int y1, int x2, int y2)
|
||||||
|
{
|
||||||
|
// Row
|
||||||
|
for (int i = x1; i <= x2; i++)
|
||||||
|
SendLayerData(i, y1, map);
|
||||||
|
|
||||||
|
// Column
|
||||||
|
for (int j = y1 + 1; j <= y2; j++)
|
||||||
|
SendLayerData(x2, j, map);
|
||||||
|
|
||||||
|
if (x2 - x1 > 0 && y2 - y1 > 0)
|
||||||
|
SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendLayerBottomLeft(TerrainData map, int x1, int y1, int x2, int y2)
|
||||||
|
{
|
||||||
|
// Row in reverse
|
||||||
|
for (int i = x2; i >= x1; i--)
|
||||||
|
SendLayerData(i, y2, map);
|
||||||
|
|
||||||
|
// Column in reverse
|
||||||
|
for (int j = y2 - 1; j >= y1; j--)
|
||||||
|
SendLayerData(x1, j, map);
|
||||||
|
|
||||||
|
if (x2 - x1 > 0 && y2 - y1 > 0)
|
||||||
|
SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Legacy form of invocation that passes around a bare data array.
|
// Legacy form of invocation that passes around a bare data array.
|
||||||
// Just ignore what was passed and use the real terrain info that is part of the scene.
|
// Just ignore what was passed and use the real terrain info that is part of the scene.
|
||||||
// As a HORRIBLE kludge in an attempt to not change the definition of IClientAPI,
|
// As a HORRIBLE kludge in an attempt to not change the definition of IClientAPI,
|
||||||
|
@ -1359,7 +1390,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
private void SendTheLayerPacket(LayerDataPacket layerpack)
|
private void SendTheLayerPacket(LayerDataPacket layerpack)
|
||||||
{
|
{
|
||||||
OutPacket(layerpack, ThrottleOutPacketType.Land);
|
OutPacket(layerpack, ThrottleOutPacketType.Land);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -107,6 +107,10 @@ 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 bool sendAll;
|
||||||
|
public int sendAllcurrentX;
|
||||||
|
public int sendAllcurrentY;
|
||||||
|
|
||||||
|
|
||||||
public PatchUpdates(TerrainData terrData, ScenePresence pPresence)
|
public PatchUpdates(TerrainData terrData, ScenePresence pPresence)
|
||||||
{
|
{
|
||||||
|
@ -150,6 +154,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||||
updated[xx, yy] = state;
|
updated[xx, yy] = state;
|
||||||
if (state)
|
if (state)
|
||||||
updateCount = updated.GetLength(0) * updated.GetLength(1);
|
updateCount = updated.GetLength(0) * updated.GetLength(1);
|
||||||
|
sendAllcurrentX = 0;
|
||||||
|
sendAllcurrentY = 0;
|
||||||
|
sendAll = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logically OR's the terrain data's patch taint map into this client's update map.
|
// Logically OR's the terrain data's patch taint map into this client's update map.
|
||||||
|
@ -211,7 +218,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||||
if (terrainConfig != null)
|
if (terrainConfig != null)
|
||||||
{
|
{
|
||||||
m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
|
m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
|
||||||
m_sendTerrainUpdatesByViewDistance = terrainConfig.GetBoolean("SendTerrainUpdatesByViewDistance", m_sendTerrainUpdatesByViewDistance);
|
m_sendTerrainUpdatesByViewDistance =
|
||||||
|
terrainConfig.GetBoolean(
|
||||||
|
"SendTerrainUpdatesByViewDistance",m_sendTerrainUpdatesByViewDistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,21 +533,29 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||||
// ITerrainModule.PushTerrain()
|
// ITerrainModule.PushTerrain()
|
||||||
public void PushTerrain(IClientAPI pClient)
|
public void PushTerrain(IClientAPI pClient)
|
||||||
{
|
{
|
||||||
ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId);
|
if (m_sendTerrainUpdatesByViewDistance)
|
||||||
if (presence != null)
|
|
||||||
{
|
{
|
||||||
lock (m_perClientPatchUpdates)
|
ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId);
|
||||||
|
if (presence != null)
|
||||||
{
|
{
|
||||||
PatchUpdates pups;
|
lock (m_perClientPatchUpdates)
|
||||||
if (!m_perClientPatchUpdates.TryGetValue(pClient.AgentId, out pups))
|
|
||||||
{
|
{
|
||||||
// There is a ScenePresence without a send patch map. Create one.
|
PatchUpdates pups;
|
||||||
pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence);
|
if (!m_perClientPatchUpdates.TryGetValue(pClient.AgentId, out pups))
|
||||||
m_perClientPatchUpdates.Add(presence.UUID, pups);
|
{
|
||||||
|
// There is a ScenePresence without a send patch map. Create one.
|
||||||
|
pups = new PatchUpdates(m_scene.Heightmap.GetTerrainData(), presence);
|
||||||
|
m_perClientPatchUpdates.Add(presence.UUID, pups);
|
||||||
|
}
|
||||||
|
pups.SetAll(true);
|
||||||
}
|
}
|
||||||
pups.SetAll(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The traditional way is to call into the protocol stack to send them all.
|
||||||
|
pClient.SendLayerData(new float[10]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Plugin Loading Methods
|
#region Plugin Loading Methods
|
||||||
|
@ -949,19 +966,37 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||||
/// <param name="y">The patch corner to send</param>
|
/// <param name="y">The patch corner to send</param>
|
||||||
private void SendToClients(TerrainData terrData, int x, int y)
|
private void SendToClients(TerrainData terrData, int x, int y)
|
||||||
{
|
{
|
||||||
// Add that this patch needs to be sent to the accounting for each client.
|
if (m_sendTerrainUpdatesByViewDistance)
|
||||||
lock (m_perClientPatchUpdates)
|
|
||||||
{
|
{
|
||||||
m_scene.ForEachScenePresence(presence =>
|
// Add that this patch needs to be sent to the accounting for each client.
|
||||||
{
|
lock (m_perClientPatchUpdates)
|
||||||
PatchUpdates thisClientUpdates;
|
{
|
||||||
if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out thisClientUpdates))
|
m_scene.ForEachScenePresence(presence =>
|
||||||
{
|
{
|
||||||
// There is a ScenePresence without a send patch map. Create one.
|
PatchUpdates thisClientUpdates;
|
||||||
thisClientUpdates = new PatchUpdates(terrData, presence);
|
if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out thisClientUpdates))
|
||||||
m_perClientPatchUpdates.Add(presence.UUID, thisClientUpdates);
|
{
|
||||||
|
// There is a ScenePresence without a send patch map. Create one.
|
||||||
|
thisClientUpdates = new PatchUpdates(terrData, presence);
|
||||||
|
m_perClientPatchUpdates.Add(presence.UUID, thisClientUpdates);
|
||||||
|
}
|
||||||
|
thisClientUpdates.SetByXY(x, y, true);
|
||||||
}
|
}
|
||||||
thisClientUpdates.SetByXY(x, y, true);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Legacy update sending where the update is sent out as soon as noticed
|
||||||
|
// 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(
|
||||||
|
delegate (IClientAPI controller)
|
||||||
|
{
|
||||||
|
controller.SendLayerData(x / Constants.TerrainPatchSize,
|
||||||
|
y / Constants.TerrainPatchSize,
|
||||||
|
heightMap);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -993,46 +1028,113 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||||
{
|
{
|
||||||
foreach (PatchUpdates pups in m_perClientPatchUpdates.Values)
|
foreach (PatchUpdates pups in m_perClientPatchUpdates.Values)
|
||||||
{
|
{
|
||||||
if (!Monitor.TryEnter(pups))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// throught acording to land queue free to send bytes
|
// throught acording to land queue free to send bytes
|
||||||
if (!pups.Presence.ControllingClient.CanSendLayerData())
|
if (!pups.Presence.ControllingClient.CanSendLayerData())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (pups.HasUpdates())
|
if (pups.HasUpdates())
|
||||||
{
|
{
|
||||||
|
if (m_sendTerrainUpdatesByViewDistance)
|
||||||
// There is something that could be sent to this client.
|
|
||||||
List<PatchesToSend> toSend = GetModifiedPatchesInViewDistance(pups);
|
|
||||||
if (toSend.Count > 0)
|
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0} CheckSendingPatchesToClient: sending {1} patches to {2} in region {3}",
|
// There is something that could be sent to this client.
|
||||||
// LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName);
|
List<PatchesToSend> toSend = GetModifiedPatchesInViewDistance(pups);
|
||||||
// Sort the patches to send by the distance from the presence
|
if (toSend.Count > 0)
|
||||||
toSend.Sort();
|
|
||||||
/*
|
|
||||||
foreach (PatchesToSend pts in toSend)
|
|
||||||
{
|
{
|
||||||
pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null);
|
// m_log.DebugFormat("{0} CheckSendingPatchesToClient: sending {1} patches to {2} in region {3}",
|
||||||
// presence.ControllingClient.SendLayerData(xs.ToArray(), ys.ToArray(), null, TerrainPatch.LayerType.Land);
|
// LogHeader, toSend.Count, pups.Presence.Name, m_scene.RegionInfo.RegionName);
|
||||||
}
|
// Sort the patches to send by the distance from the presence
|
||||||
*/
|
toSend.Sort();
|
||||||
|
/*
|
||||||
|
foreach (PatchesToSend pts in toSend)
|
||||||
|
{
|
||||||
|
pups.Presence.ControllingClient.SendLayerData(pts.PatchX, pts.PatchY, null);
|
||||||
|
// presence.ControllingClient.SendLayerData(xs.ToArray(), ys.ToArray(), null, TerrainPatch.LayerType.Land);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
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];
|
||||||
int pieceIndex = 0;
|
int pieceIndex = 0;
|
||||||
foreach (PatchesToSend pts in toSend)
|
foreach (PatchesToSend pts in toSend)
|
||||||
{
|
{
|
||||||
patchPieces[pieceIndex++] = pts.PatchX;
|
patchPieces[pieceIndex++] = pts.PatchX;
|
||||||
patchPieces[pieceIndex++] = pts.PatchY;
|
patchPieces[pieceIndex++] = pts.PatchY;
|
||||||
|
}
|
||||||
|
pups.Presence.ControllingClient.SendLayerData(-toSend.Count, 0, patchPieces);
|
||||||
}
|
}
|
||||||
pups.Presence.ControllingClient.SendLayerData(-toSend.Count, 0, patchPieces);
|
if (pups.sendAll && toSend.Count < 1024)
|
||||||
|
SendAllModifiedPatchs(pups);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SendAllModifiedPatchs(pups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void SendAllModifiedPatchs(PatchUpdates pups)
|
||||||
|
{
|
||||||
|
if (!pups.sendAll) // sanity
|
||||||
|
return;
|
||||||
|
|
||||||
|
int limitX = (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize;
|
||||||
|
int limitY = (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize;
|
||||||
|
|
||||||
|
if (pups.sendAllcurrentX > limitX || pups.sendAllcurrentY > limitY)
|
||||||
|
{
|
||||||
|
pups.sendAll = false;
|
||||||
|
pups.sendAllcurrentX = 0;
|
||||||
|
pups.sendAllcurrentY = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int npatchs = 0;
|
||||||
|
List<PatchesToSend> patchs = new List<PatchesToSend>();
|
||||||
|
int x = pups.sendAllcurrentX;
|
||||||
|
int y = pups.sendAllcurrentY;
|
||||||
|
// send it in the order viewer draws it
|
||||||
|
// even if not best for memory scan
|
||||||
|
for (; y < limitY; y++)
|
||||||
|
{
|
||||||
|
for (; x < limitX; x++)
|
||||||
|
{
|
||||||
|
if (pups.GetByPatch(x, y))
|
||||||
|
{
|
||||||
|
pups.SetByPatch(x, y, false);
|
||||||
|
patchs.Add(new PatchesToSend(x, y, 0));
|
||||||
|
if (++npatchs >= 512)
|
||||||
|
{
|
||||||
|
pups.sendAllcurrentX = x + 1;
|
||||||
|
pups.sendAllcurrentY = y;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Monitor.Exit(pups);
|
|
||||||
}
|
}
|
||||||
|
if (npatchs >= 512)
|
||||||
|
break;
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x >= limitX && y >= limitY)
|
||||||
|
{
|
||||||
|
pups.sendAll = false;
|
||||||
|
pups.sendAllcurrentX = 0;
|
||||||
|
pups.sendAllcurrentY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
npatchs = patchs.Count;
|
||||||
|
if (npatchs > 0)
|
||||||
|
{
|
||||||
|
int[] xPieces = new int[npatchs];
|
||||||
|
int[] yPieces = new int[npatchs];
|
||||||
|
float[] patchPieces = new float[npatchs * 2];
|
||||||
|
int pieceIndex = 0;
|
||||||
|
foreach (PatchesToSend pts in patchs)
|
||||||
|
{
|
||||||
|
patchPieces[pieceIndex++] = pts.PatchX;
|
||||||
|
patchPieces[pieceIndex++] = pts.PatchY;
|
||||||
|
}
|
||||||
|
pups.Presence.ControllingClient.SendLayerData(-npatchs, 0, patchPieces);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1119,7 +1221,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||||
{
|
{
|
||||||
pups.SetByPatch(x, y, false);
|
pups.SetByPatch(x, y, false);
|
||||||
ret.Add(new PatchesToSend(x, y, (float)distsq));
|
ret.Add(new PatchesToSend(x, y, (float)distsq));
|
||||||
if (npatchs++ > 65536)
|
if (npatchs++ > 1024)
|
||||||
{
|
{
|
||||||
y = endY;
|
y = endY;
|
||||||
x = endX;
|
x = endX;
|
||||||
|
|
Loading…
Reference in New Issue