try save a few ns on parcel overlays

0.9.1.0-post-fixes
UbitUmarov 2019-03-19 06:00:36 +00:00
parent c2086e6257
commit 6dde1aaa14
1 changed files with 145 additions and 87 deletions

View File

@ -998,6 +998,39 @@ namespace OpenSim.Region.CoreModules.World.Land
} }
} }
public ILandObject GetLandObjectinLandUnits(int x, int y)
{
if (m_landList.Count == 0 || m_landIDList == null)
return null;
lock (m_landIDList)
{
try
{
return m_landList[m_landIDList[x, y]];
}
catch (IndexOutOfRangeException)
{
return null;
}
}
}
public int GetLandObjectIDinLandUnits(int x, int y)
{
lock (m_landIDList)
{
try
{
return m_landIDList[x, y];
}
catch (IndexOutOfRangeException)
{
return -1;
}
}
}
// Create a 'parcel is here' bitmap for the parcel identified by the passed landID // Create a 'parcel is here' bitmap for the parcel identified by the passed landID
private bool[,] CreateBitmapForID(int landID) private bool[,] CreateBitmapForID(int landID)
{ {
@ -1282,18 +1315,9 @@ namespace OpenSim.Region.CoreModules.World.Land
#region Parcel Updating #region Parcel Updating
/// <summary> /// <summary>
/// Send the parcel overlay blocks to the client. We send the overlay packets /// Send the parcel overlay blocks to the client.
/// around a location and limited by the 'parcelLayerViewDistance'. This number
/// is usually 128 and the code is arranged so it sends all the parcel overlay
/// information for a whole region if the region is legacy sized (256x256). If
/// the region is larger, only the parcel layer information is sent around
/// the point specified. This reduces the problem of parcel layer information
/// blocks increasing exponentially as region size increases.
/// </summary> /// </summary>
/// <param name="remote_client">The object representing the client</param> /// <param name="remote_client">The object representing the client</param>
/// <param name="xPlace">X position in the region to send surrounding parcel layer info</param>
/// <param name="yPlace">y position in the region to send surrounding parcel layer info</param>
/// <param name="layerViewDistance">Distance from x,y position to send parcel layer info</param>
public void SendParcelOverlay(IClientAPI remote_client) public void SendParcelOverlay(IClientAPI remote_client)
{ {
if (remote_client.SceneAgent.PresenceType == PresenceType.Npc) if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
@ -1301,92 +1325,100 @@ namespace OpenSim.Region.CoreModules.World.Land
const int LAND_BLOCKS_PER_PACKET = 1024; const int LAND_BLOCKS_PER_PACKET = 1024;
int curID;
int southID;
byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
int byteArrayCount = 0; int byteArrayCount = 0;
int sequenceID = 0; int sequenceID = 0;
int sx = (int)m_scene.RegionInfo.RegionSizeX / LandUnit;
byte curByte;
byte tmpByte;
// Layer data is in LandUnit (4m) chunks // Layer data is in LandUnit (4m) chunks
for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y += LandUnit) for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / LandUnit; ++y)
{ {
for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x += LandUnit) for (int x = 0; x < sx;)
{ {
byte tempByte = 0; //This represents the byte for the current 4x4 curID = GetLandObjectIDinLandUnits(x,y);
if(curID < 0)
continue;
ILandObject currentParcelBlock = GetLandObject(x, y); ILandObject currentParcel = GetLandObject(curID);
if (currentParcel == null)
continue;
if (currentParcelBlock != null)
{
// types // types
if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) if (currentParcel.LandData.OwnerID == remote_client.AgentId)
{ {
//Owner Flag //Owner Flag
tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_REQUESTER; curByte = LandChannel.LAND_TYPE_OWNED_BY_REQUESTER;
} }
else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID)) else if (currentParcel.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcel.LandData.GroupID))
{ {
tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_GROUP; curByte = LandChannel.LAND_TYPE_OWNED_BY_GROUP;
} }
else if (currentParcelBlock.LandData.SalePrice > 0 && else if (currentParcel.LandData.SalePrice > 0 &&
(currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || (currentParcel.LandData.AuthBuyerID == UUID.Zero ||
currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) currentParcel.LandData.AuthBuyerID == remote_client.AgentId))
{ {
//Sale type //Sale type
tempByte = (byte)LandChannel.LAND_TYPE_IS_FOR_SALE; curByte = LandChannel.LAND_TYPE_IS_FOR_SALE;
} }
else if (currentParcelBlock.LandData.OwnerID == UUID.Zero) else if (currentParcel.LandData.OwnerID == UUID.Zero)
{ {
//Public type //Public type
tempByte = (byte)LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero curByte = LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero
} }
// LAND_TYPE_IS_BEING_AUCTIONED still unsuported // LAND_TYPE_IS_BEING_AUCTIONED still unsuported
else else
{ {
//Other Flag //Other
tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_OTHER; curByte = LandChannel.LAND_TYPE_OWNED_BY_OTHER;
} }
// now flags // now flags
// border control
ILandObject westParcel = null;
ILandObject southParcel = null;
if (x > 0)
{
westParcel = GetLandObject((x - 1), y);
}
if (y > 0)
{
southParcel = GetLandObject(x, (y - 1));
}
if (x == 0)
{
tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
}
else if (westParcel != null && westParcel != currentParcelBlock)
{
tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
}
if (y == 0)
{
tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
}
else if (southParcel != null && southParcel != currentParcelBlock)
{
tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
}
// local sound // local sound
if ((currentParcelBlock.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0) if ((currentParcel.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0)
tempByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND; curByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND;
// hide avatars // hide avatars
if (!currentParcelBlock.LandData.SeeAVs) if (!currentParcel.LandData.SeeAVs)
tempByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS; curByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS;
// border flags for current
if (y == 0)
{
curByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
tmpByte = curByte;
}
else
{
tmpByte = curByte;
southID = GetLandObjectIDinLandUnits(x, (y - 1));
if (southID > 0 && southID != curID)
tmpByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
}
byteArray[byteArrayCount] = tempByte; tmpByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
byteArray[byteArrayCount] = tmpByte;
byteArrayCount++;
if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
{
remote_client.SendLandParcelOverlay(byteArray, sequenceID);
byteArrayCount = 0;
sequenceID++;
byteArray = new byte[LAND_BLOCKS_PER_PACKET];
}
// keep adding while on same parcel, checking south border
if (y == 0)
{
// all have south border and that is already on curByte
while (++x < sx && GetLandObjectIDinLandUnits(x, y) == curID)
{
byteArray[byteArrayCount] = curByte;
byteArrayCount++; byteArrayCount++;
if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
{ {
@ -1397,6 +1429,32 @@ namespace OpenSim.Region.CoreModules.World.Land
} }
} }
} }
else
{
while (++x < sx && GetLandObjectIDinLandUnits(x, y) == curID)
{
// need to check south one by one
southID = GetLandObjectIDinLandUnits(x, (y - 1));
if (southID > 0 && southID != curID)
{
tmpByte = curByte;
tmpByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
byteArray[byteArrayCount] = tmpByte;
}
else
byteArray[byteArrayCount] = curByte;
byteArrayCount++;
if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
{
remote_client.SendLandParcelOverlay(byteArray, sequenceID);
byteArrayCount = 0;
sequenceID++;
byteArray = new byte[LAND_BLOCKS_PER_PACKET];
}
}
}
}
} }
if (byteArrayCount > 0) if (byteArrayCount > 0)