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,99 +1325,133 @@ 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
if (currentParcel.LandData.OwnerID == remote_client.AgentId)
{ {
// types //Owner Flag
if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) curByte = LandChannel.LAND_TYPE_OWNED_BY_REQUESTER;
{ }
//Owner Flag else if (currentParcel.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcel.LandData.GroupID))
tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_REQUESTER; {
} curByte = LandChannel.LAND_TYPE_OWNED_BY_GROUP;
else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID)) }
{ else if (currentParcel.LandData.SalePrice > 0 &&
tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_GROUP; (currentParcel.LandData.AuthBuyerID == UUID.Zero ||
} currentParcel.LandData.AuthBuyerID == remote_client.AgentId))
else if (currentParcelBlock.LandData.SalePrice > 0 && {
(currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || //Sale type
currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) curByte = LandChannel.LAND_TYPE_IS_FOR_SALE;
{ }
//Sale type else if (currentParcel.LandData.OwnerID == UUID.Zero)
tempByte = (byte)LandChannel.LAND_TYPE_IS_FOR_SALE; {
} //Public type
else if (currentParcelBlock.LandData.OwnerID == UUID.Zero) curByte = LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero
{ }
//Public type // LAND_TYPE_IS_BEING_AUCTIONED still unsuported
tempByte = (byte)LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero else
} {
// LAND_TYPE_IS_BEING_AUCTIONED still unsuported //Other
else curByte = LandChannel.LAND_TYPE_OWNED_BY_OTHER;
{ }
//Other Flag
tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_OTHER;
}
// now flags // now flags
// border control // local sound
if ((currentParcel.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0)
curByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND;
ILandObject westParcel = null; // hide avatars
ILandObject southParcel = null; if (!currentParcel.LandData.SeeAVs)
if (x > 0) 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;
}
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)
{ {
westParcel = GetLandObject((x - 1), y); 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 (y > 0) }
else
{
while (++x < sx && GetLandObjectIDinLandUnits(x, y) == curID)
{ {
southParcel = GetLandObject(x, (y - 1)); // 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;
if (x == 0) byteArrayCount++;
{ if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST; {
} remote_client.SendLandParcelOverlay(byteArray, sequenceID);
else if (westParcel != null && westParcel != currentParcelBlock) byteArrayCount = 0;
{ sequenceID++;
tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST; byteArray = new byte[LAND_BLOCKS_PER_PACKET];
} }
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
if ((currentParcelBlock.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0)
tempByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND;
// hide avatars
if (!currentParcelBlock.LandData.SeeAVs)
tempByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS;
byteArray[byteArrayCount] = tempByte;
byteArrayCount++;
if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
{
remote_client.SendLandParcelOverlay(byteArray, sequenceID);
byteArrayCount = 0;
sequenceID++;
byteArray = new byte[LAND_BLOCKS_PER_PACKET];
} }
} }
} }