varregion: update LandManagementModule and LandObject for variable sized regions.

avinationmerge
Robert Adams 2015-03-29 16:45:00 -07:00
parent 07dead7dcb
commit df14b40e88
2 changed files with 133 additions and 106 deletions

View File

@ -64,6 +64,12 @@ namespace OpenSim.Region.CoreModules.World.Land
public class LandManagementModule : INonSharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[LAND MANAGEMENT MODULE]";
/// <summary>
/// Minimum land unit size in region co-ordinates.
/// </summary>
public const int landUnit = 4;
private static readonly string remoteParcelRequestPath = "0009/";
@ -74,15 +80,10 @@ namespace OpenSim.Region.CoreModules.World.Land
protected IPrimCountModule m_primCountModule;
protected IDialogModule m_Dialog;
// Minimum for parcels to work is 64m even if we don't actually use them.
#pragma warning disable 0429
private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64;
#pragma warning restore 0429
/// <value>
/// Local land ids at specified region co-ordinates (region size / 4)
/// </value>
private readonly int[,] m_landIDList = new int[landArrayMax, landArrayMax];
private int[,] m_landIDList;
/// <value>
/// Land objects keyed by local id
@ -123,7 +124,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void AddRegion(Scene scene)
{
m_scene = scene;
m_landIDList.Initialize();
m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
landChannel = new LandChannel(scene, this);
parcelInfoCache = new Cache();
@ -264,7 +265,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{
m_landList.Clear();
m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
m_landIDList.Initialize();
m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
}
}
@ -274,11 +275,11 @@ namespace OpenSim.Region.CoreModules.World.Land
/// <returns>The parcel created.</returns>
protected ILandObject CreateDefaultParcel()
{
m_log.DebugFormat(
"[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
m_log.DebugFormat("{0} Creating default parcel for region {1}", LogHeader, m_scene.RegionInfo.RegionName);
ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0,
(int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY));
fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
@ -569,9 +570,9 @@ namespace OpenSim.Region.CoreModules.World.Land
new_land.LandData.LocalID = newLandLocalID;
bool[,] landBitmap = new_land.GetLandBitmap();
for (int x = 0; x < landArrayMax; x++)
for (int x = 0; x < landBitmap.GetLength(0); x++)
{
for (int y = 0; y < landArrayMax; y++)
for (int y = 0; y < landBitmap.GetLength(1); y++)
{
if (landBitmap[x, y])
{
@ -601,9 +602,9 @@ namespace OpenSim.Region.CoreModules.World.Land
ILandObject land;
lock (m_landList)
{
for (int x = 0; x < 64; x++)
for (int x = 0; x < m_landIDList.GetLength(0); x++)
{
for (int y = 0; y < 64; y++)
for (int y = 0; y < m_landIDList.GetLength(1); y++)
{
if (m_landIDList[x, y] == local_id)
{
@ -656,9 +657,9 @@ namespace OpenSim.Region.CoreModules.World.Land
bool[,] landBitmapSlave = slave.GetLandBitmap();
lock (m_landList)
{
for (int x = 0; x < 64; x++)
for (int x = 0; x < landBitmapSlave.GetLength(0); x++)
{
for (int y = 0; y < 64; y++)
for (int y = 0; y < landBitmapSlave.GetLength(1); y++)
{
if (landBitmapSlave[x, y])
{
@ -695,20 +696,23 @@ namespace OpenSim.Region.CoreModules.World.Land
int x;
int y;
if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0)
if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0)
return null;
try
{
x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / 4.0));
y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / 4.0));
x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit));
y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit));
}
catch (OverflowException)
{
return null;
}
if (x >= 64 || y >= 64 || x < 0 || y < 0)
if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit)
|| y >= (m_scene.RegionInfo.RegionSizeY / landUnit)
|| x < 0
|| y < 0)
{
return null;
}
@ -740,20 +744,20 @@ namespace OpenSim.Region.CoreModules.World.Land
int avx = (int)x;
if (avx < 0)
avx = 0;
else if (avx >= (int)Constants.RegionSize)
else if (avx >= m_scene.RegionInfo.RegionSizeX)
avx = (int)Constants.RegionSize - 1;
int avy = (int)y;
if (avy < 0)
avy = 0;
else if (avy >= (int)Constants.RegionSize)
else if (avy >= m_scene.RegionInfo.RegionSizeY)
avy = (int)Constants.RegionSize - 1;
lock (m_landIDList)
{
try
{
return m_landList[m_landIDList[avx / 4, avy / 4]];
return m_landList[m_landIDList[avx / landUnit, avy / landUnit]];
}
catch (IndexOutOfRangeException)
{
@ -764,7 +768,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public ILandObject GetLandObject(int x, int y)
{
if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0)
if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
{
// These exceptions here will cause a lot of complaints from the users specifically because
// they happen every time at border crossings
@ -1057,9 +1061,10 @@ namespace OpenSim.Region.CoreModules.World.Land
int byteArrayCount = 0;
int sequenceID = 0;
for (int y = 0; y < Constants.RegionSize; y += 4)
// Layer data is in landUnit (4m) chunks
for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y += landUnit)
{
for (int x = 0; x < Constants.RegionSize; x += 4)
for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x += landUnit)
{
byte tempByte = 0; //This represents the byte for the current 4x4
@ -1769,7 +1774,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{
// most likely still cached from building the extLandData entry
uint x = 0, y = 0;
Utils.LongToUInts(data.RegionHandle, out x, out y);
Util.RegionHandleToWorldLoc(data.RegionHandle, out x, out y);
info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y);
}
// we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark.

View File

@ -45,15 +45,13 @@ namespace OpenSim.Region.CoreModules.World.Land
#region Member Variables
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#pragma warning disable 0429
private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64;
#pragma warning restore 0429
private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax];
private static readonly string LogHeader = "[LAND OBJECT]";
private readonly int landUnit = 4;
private int m_lastSeqId = 0;
private int m_expiryCounter = 0;
protected LandData m_landData = new LandData();
protected Scene m_scene;
protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
@ -61,6 +59,7 @@ namespace OpenSim.Region.CoreModules.World.Land
protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>();
protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds
private bool[,] m_landBitmap;
public bool[,] LandBitmap
{
get { return m_landBitmap; }
@ -76,6 +75,7 @@ namespace OpenSim.Region.CoreModules.World.Land
return free;
}
protected LandData m_landData;
public LandData LandData
{
get { return m_landData; }
@ -94,12 +94,12 @@ namespace OpenSim.Region.CoreModules.World.Land
{
get
{
for (int y = 0; y < landArrayMax; y++)
for (int y = 0; y < LandBitmap.GetLength(1); y++)
{
for (int x = 0; x < landArrayMax; x++)
for (int x = 0; x < LandBitmap.GetLength(0); x++)
{
if (LandBitmap[x, y])
return new Vector3(x * 4, y * 4, 0);
return new Vector3(x * landUnit, y * landUnit, 0);
}
}
@ -111,13 +111,13 @@ namespace OpenSim.Region.CoreModules.World.Land
{
get
{
for (int y = landArrayMax - 1; y >= 0; y--)
for (int y = LandBitmap.GetLength(1) - 1; y >= 0; y--)
{
for (int x = landArrayMax - 1; x >= 0; x--)
for (int x = LandBitmap.GetLength(0) - 1; x >= 0; x--)
{
if (LandBitmap[x, y])
{
return new Vector3(x * 4 + 4, y * 4 + 4, 0);
return new Vector3(x * landUnit + landUnit, y * landUnit + landUnit, 0);
}
}
}
@ -128,9 +128,21 @@ namespace OpenSim.Region.CoreModules.World.Land
#region Constructors
public LandObject(LandData landData, Scene scene)
{
LandData = landData.Copy();
m_scene = scene;
}
public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
{
m_scene = scene;
if (m_scene == null)
LandBitmap = new bool[Constants.RegionSize / landUnit, Constants.RegionSize / landUnit];
else
LandBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
LandData = new LandData();
LandData.OwnerID = owner_id;
if (is_group_owned)
LandData.GroupID = owner_id;
@ -155,9 +167,9 @@ namespace OpenSim.Region.CoreModules.World.Land
/// <returns>Returns true if the piece of land contains the specified point</returns>
public bool ContainsPoint(int x, int y)
{
if (x >= 0 && y >= 0 && x < Constants.RegionSize && y < Constants.RegionSize)
if (x >= 0 && y >= 0 && x < m_scene.RegionInfo.RegionSizeX && y < m_scene.RegionInfo.RegionSizeY)
{
return (LandBitmap[x / 4, y / 4] == true);
return LandBitmap[x / landUnit, y / landUnit];
}
else
{
@ -197,10 +209,10 @@ namespace OpenSim.Region.CoreModules.World.Land
else
{
// Normal Calculations
int parcelMax = (int)((long)LandData.Area
int parcelMax = (int)( (long)LandData.Area
* (long)m_scene.RegionInfo.ObjectCapacity
* (long)m_scene.RegionInfo.RegionSettings.ObjectBonus
/ 65536L);
/ (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) );
//m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax);
return parcelMax;
}
@ -231,8 +243,9 @@ namespace OpenSim.Region.CoreModules.World.Land
else
{
//Normal Calculations
int simMax = (int)((long)LandData.SimwideArea
* (long)m_scene.RegionInfo.ObjectCapacity / 65536L);
int simMax = (int)( (long)LandData.SimwideArea
* (long)m_scene.RegionInfo.ObjectCapacity
/ (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) );
// m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}", LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax);
return simMax;
}
@ -597,8 +610,8 @@ namespace OpenSim.Region.CoreModules.World.Land
try
{
over =
m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)),
Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1)));
m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)m_scene.RegionInfo.RegionSizeX - 1)),
Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1)));
}
catch (Exception)
{
@ -752,9 +765,9 @@ namespace OpenSim.Region.CoreModules.World.Land
int max_y = Int32.MinValue;
int tempArea = 0;
int x, y;
for (x = 0; x < 64; x++)
for (x = 0; x < LandBitmap.GetLength(0); x++)
{
for (y = 0; y < 64; y++)
for (y = 0; y < LandBitmap.GetLength(1); y++)
{
if (LandBitmap[x, y] == true)
{
@ -766,23 +779,25 @@ namespace OpenSim.Region.CoreModules.World.Land
max_x = x;
if (max_y < y)
max_y = y;
tempArea += 16; //16sqm peice of land
tempArea += landUnit * landUnit; //16sqm peice of land
}
}
}
int tx = min_x * landUnit;
if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
int tx = min_x * 4;
int htx;
if (tx == ((int)Constants.RegionSize))
htx = tx - 1;
if (tx >= ((int)m_scene.RegionInfo.RegionSizeX))
htx = (int)m_scene.RegionInfo.RegionSizeX - 1;
else
htx = tx;
int ty = min_y * 4;
int ty = min_y * landUnit;
int hty;
if (ty == ((int)Constants.RegionSize))
hty = ty - 1;
if (ty >= ((int)m_scene.RegionInfo.RegionSizeY))
hty = (int)m_scene.RegionInfo.RegionSizeY - 1;
else
hty = ty;
@ -791,17 +806,17 @@ namespace OpenSim.Region.CoreModules.World.Land
(float)(tx), (float)(ty), m_scene != null ? (float)m_scene.Heightmap[htx, hty] : 0);
max_x++;
tx = max_x * 4;
if (tx == ((int)Constants.RegionSize))
htx = tx - 1;
tx = max_x * landUnit;
if (tx >= ((int)m_scene.RegionInfo.RegionSizeX))
htx = (int)m_scene.RegionInfo.RegionSizeX - 1;
else
htx = tx;
max_y++;
ty = max_y * 4;
if (ty == ((int)Constants.RegionSize))
hty = ty - 1;
if (ty >= ((int)m_scene.RegionInfo.RegionSizeY))
hty = (int)m_scene.RegionInfo.RegionSizeY - 1;
else
hty = ty;
@ -819,21 +834,12 @@ namespace OpenSim.Region.CoreModules.World.Land
/// <summary>
/// Sets the land's bitmap manually
/// </summary>
/// <param name="bitmap">64x64 block representing where this land is on a map</param>
/// <param name="bitmap">block representing where this land is on a map mapped in a 4x4 meter grid</param>
public void SetLandBitmap(bool[,] bitmap)
{
if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
{
//Throw an exception - The bitmap is not 64x64
//throw new Exception("Error: Invalid Parcel Bitmap");
}
else
{
//Valid: Lets set it
LandBitmap = bitmap;
ForceUpdateLandInfo();
}
}
/// <summary>
/// Gets the land's bitmap manually
@ -846,14 +852,16 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool[,] BasicFullRegionLandBitmap()
{
return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize);
return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY);
}
public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
{
bool[,] tempBitmap = new bool[64,64];
// Empty bitmap for the whole region
bool[,] tempBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
tempBitmap.Initialize();
// Fill the bitmap square area specified by state and end
tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
return tempBitmap;
}
@ -871,19 +879,13 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
bool set_value)
{
if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
{
//Throw an exception - The bitmap is not 64x64
//throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
}
int x, y;
for (y = 0; y < 64; y++)
for (y = 0; y < land_bitmap.GetLength(1); y++)
{
for (x = 0; x < 64; x++)
for (x = 0; x < land_bitmap.GetLength(0); x++)
{
if (x >= start_x / 4 && x < end_x / 4
&& y >= start_y / 4 && y < end_y / 4)
if (x >= start_x / landUnit && x < end_x / landUnit
&& y >= start_y / landUnit && y < end_y / landUnit)
{
land_bitmap[x, y] = set_value;
}
@ -900,21 +902,21 @@ namespace OpenSim.Region.CoreModules.World.Land
/// <returns></returns>
public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
{
if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
if (bitmap_base.GetLength(0) != bitmap_add.GetLength(0)
|| bitmap_base.GetLength(1) != bitmap_add.GetLength(1)
|| bitmap_add.Rank != 2
|| bitmap_base.Rank != 2)
{
//Throw an exception - The bitmap is not 64x64
throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
}
if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
{
//Throw an exception - The bitmap is not 64x64
throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
throw new Exception(
String.Format("{0} MergeLandBitmaps. merging maps not same size. baseSizeXY=<{1},{2}>, addSizeXY=<{3},{4}>",
LogHeader, bitmap_base.GetLength(0), bitmap_base.GetLength(1), bitmap_add.GetLength(0), bitmap_add.GetLength(1))
);
}
int x, y;
for (y = 0; y < 64; y++)
for (y = 0; y < bitmap_base.GetLength(1); y++)
{
for (x = 0; x < 64; x++)
for (x = 0; x < bitmap_add.GetLength(0); x++)
{
if (bitmap_add[x, y])
{
@ -931,14 +933,14 @@ namespace OpenSim.Region.CoreModules.World.Land
/// <returns></returns>
private byte[] ConvertLandBitmapToBytes()
{
byte[] tempConvertArr = new byte[512];
byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8];
int tempByte = 0;
int x, y, i, byteNum = 0;
int i, byteNum = 0;
int mask = 1;
i = 0;
for (y = 0; y < 64; y++)
for (int y = 0; y < LandBitmap.GetLength(1); y++)
{
for (x = 0; x < 64; x++)
for (int x = 0; x < LandBitmap.GetLength(0); x++)
{
if (LandBitmap[x, y])
tempByte |= mask;
@ -971,25 +973,45 @@ namespace OpenSim.Region.CoreModules.World.Land
private bool[,] ConvertBytesToLandBitmap()
{
bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax];
bool[,] tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
tempConvertMap.Initialize();
byte tempByte = 0;
int x = 0, y = 0, i = 0, bitNum = 0;
for (i = 0; i < 512; i++)
// Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap.
int bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8);
int xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit);
if (bitmapLen == 512)
{
// Legacy bitmap being passed in. Use the legacy region size
// and only set the lower area of the larger region.
xLen = (int)(Constants.RegionSize / landUnit);
}
// m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen);
int x = 0, y = 0;
for (int i = 0; i < bitmapLen; i++)
{
tempByte = LandData.Bitmap[i];
for (bitNum = 0; bitNum < 8; bitNum++)
for (int bitNum = 0; bitNum < 8; bitNum++)
{
bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
try
{
tempConvertMap[x, y] = bit;
}
catch (Exception)
{
m_log.DebugFormat("{0} ConvertBytestoLandBitmap: i={1}, x={2}, y={3}", LogHeader, i, x, y);
}
x++;
if (x > 63)
if (x >= xLen)
{
x = 0;
y++;
}
}
}
return tempConvertMap;
}