varregion: Massive work to LandManagementModule and LandObject to
handle variable sized regions. Many changes for both the region and parcels. Most of the constant "4" (for the 4x4 parcel units) have been replaced with symbols and math.varregion
parent
f7bd0da026
commit
a7a837550e
|
@ -65,6 +65,7 @@ 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]";
|
||||
|
||||
private static readonly string remoteParcelRequestPath = "0009/";
|
||||
|
||||
|
@ -76,15 +77,11 @@ 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;
|
||||
private const int landUnit = 4;
|
||||
|
||||
/// <value>
|
||||
/// Land objects keyed by local id
|
||||
|
@ -117,6 +114,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
public void AddRegion(Scene scene)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
|
||||
|
||||
m_landIDList.Initialize();
|
||||
landChannel = new LandChannel(scene, this);
|
||||
|
||||
|
@ -326,6 +325,7 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
{
|
||||
m_landList.Clear();
|
||||
m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
|
||||
m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
|
||||
m_landIDList.Initialize();
|
||||
}
|
||||
}
|
||||
|
@ -340,7 +340,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
"[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", 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();
|
||||
|
||||
|
@ -467,8 +468,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
|
||||
public void SendLandUpdate(ScenePresence avatar, bool force)
|
||||
{
|
||||
ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
|
||||
(int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
|
||||
ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
|
||||
(int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
|
||||
|
||||
if (over != null)
|
||||
{
|
||||
|
@ -634,17 +635,29 @@ 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 y = 0; y < landArrayMax; y++)
|
||||
{
|
||||
if (landBitmap[x, y])
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
|
||||
// new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
|
||||
m_log.DebugFormat("{0} AddLandObject. new_land.bitmapSize=({1},{2}). bitmap[600/4,600/4]={3}, newLocalID={4}",
|
||||
LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), landBitmap[600/4, 600/4], newLandLocalID);
|
||||
|
||||
m_landIDList[x, y] = newLandLocalID;
|
||||
if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
|
||||
{
|
||||
// Going to variable sized regions can cause mismatches
|
||||
m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})",
|
||||
LogHeader, landBitmap.GetLength(0), m_landIDList.GetLength(1), landBitmap.GetLength(0), m_landIDList.GetLength(1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = 0; x < landBitmap.GetLength(0); x++)
|
||||
{
|
||||
for (int y = 0; y < landBitmap.GetLength(1); y++)
|
||||
{
|
||||
if (landBitmap[x, y])
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
|
||||
// new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
|
||||
|
||||
m_landIDList[x, y] = newLandLocalID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -666,9 +679,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)
|
||||
{
|
||||
|
@ -720,9 +733,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])
|
||||
{
|
||||
|
@ -756,23 +769,28 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
/// <returns>Land object at the point supplied</returns>
|
||||
public ILandObject GetLandObject(float x_float, float y_float)
|
||||
{
|
||||
return GetLandObject((int)x_float, (int)y_float);
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
@ -789,37 +807,111 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
|
||||
// x, y, m_scene.RegionInfo.RegionName);
|
||||
|
||||
if (m_landList.ContainsKey(m_landIDList[x, y]))
|
||||
return m_landList[m_landIDList[x, y]];
|
||||
try
|
||||
{
|
||||
if (m_landList.ContainsKey(m_landIDList[x, y]))
|
||||
return m_landList[m_landIDList[x, y]];
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})",
|
||||
LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Given a region position, return the parcel land object for that location
|
||||
public ILandObject GetLandObject(int x, int y)
|
||||
{
|
||||
if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0)
|
||||
ILandObject ret = null;
|
||||
|
||||
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
|
||||
throw new Exception("Error: Parcel not found at point " + x + ", " + y);
|
||||
throw new Exception(
|
||||
String.Format("{0} GetLandObject for non-existant position. Region={1}, pos=<{2},{3}",
|
||||
LogHeader, m_scene.RegionInfo.RegionName, x, y)
|
||||
);
|
||||
}
|
||||
|
||||
lock (m_landIDList)
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_landList[m_landIDList[x / 4, y / 4]];
|
||||
int landID = m_landIDList[x / landUnit, y / landUnit];
|
||||
if (landID == 0)
|
||||
{
|
||||
// Zero is the uninitialized value saying there is no parcel for this location.
|
||||
// This sometimes happens when terrain is resized.
|
||||
if (m_landList.Count == 1)
|
||||
{
|
||||
int onlyParcelID = 0;
|
||||
ILandObject onlyLandObject = null;
|
||||
foreach (KeyValuePair<int, ILandObject> kvp in m_landList)
|
||||
{
|
||||
onlyParcelID = kvp.Key;
|
||||
onlyLandObject = kvp.Value;
|
||||
break;
|
||||
}
|
||||
|
||||
// There is only one parcel. Grow it to fill all the unallocated spaces.
|
||||
for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
|
||||
for (int yy = 0; yy < m_landIDList.GetLength(1); yy++)
|
||||
if (m_landIDList[xx, yy] == 0)
|
||||
m_landIDList[xx, yy] = onlyParcelID;
|
||||
|
||||
onlyLandObject.LandBitmap = CreateBitmapForID(onlyParcelID);
|
||||
landID = onlyParcelID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// There are several other parcels so we must create a new one for the unassigned space
|
||||
ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
|
||||
// Claim all the unclaimed "0" ids
|
||||
newLand.SetLandBitmap(CreateBitmapForID(0));
|
||||
newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||
newLand.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
|
||||
AddLandObject(newLand);
|
||||
landID = m_lastLandLocalID;
|
||||
}
|
||||
}
|
||||
|
||||
ret = m_landList[landID];
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
// m_log.WarnFormat(
|
||||
// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}",
|
||||
// x, y, m_scene.RegionInfo.RegionName);
|
||||
|
||||
m_log.ErrorFormat(
|
||||
"{0} GetLandObject: Tried to retrieve land object from out of bounds co-ordinate ({1},{2}) in {3}. landListSize=({4},{5})",
|
||||
LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"{0} GetLandObject: LandID not in landlist. XY=<{1},{2}> in {3}. landID[x,y]={4}",
|
||||
LogHeader, x, y, m_scene.RegionInfo.RegionName, m_landIDList[x/landUnit, y/landUnit]);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Create a 'parcel is here' bitmap for the parcel identified by the passed landID
|
||||
private bool[,] CreateBitmapForID(int landID)
|
||||
{
|
||||
bool[,] ret = new bool[m_landIDList.GetLength(0), m_landIDList.GetLength(1)];
|
||||
ret.Initialize();
|
||||
|
||||
for (int xx = 0; xx < m_landIDList.GetLength(0); xx++)
|
||||
for (int yy = 0; yy < m_landIDList.GetLength(0); yy++)
|
||||
if (m_landIDList[xx, yy] == landID)
|
||||
ret[xx, yy] = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -1082,85 +1174,93 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
|
||||
int byteArrayCount = 0;
|
||||
int sequenceID = 0;
|
||||
int blockmeters = 4 * (int) Constants.RegionSize/(int)Constants.TerrainPatchSize;
|
||||
|
||||
|
||||
for (int y = 0; y < blockmeters; y++)
|
||||
// Layer data is in landUnit (4m) chunks
|
||||
for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); y++)
|
||||
{
|
||||
for (int x = 0; x < blockmeters; x++)
|
||||
for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / landUnit); x++)
|
||||
{
|
||||
byte tempByte = 0; //This represents the byte for the current 4x4
|
||||
|
||||
ILandObject currentParcelBlock = GetLandObject(x * 4, y * 4);
|
||||
|
||||
if (currentParcelBlock != null)
|
||||
byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * landUnit, y * landUnit), x, y, remote_client);
|
||||
byteArrayCount++;
|
||||
if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
|
||||
{
|
||||
if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
|
||||
{
|
||||
//Owner Flag
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
|
||||
}
|
||||
else if (currentParcelBlock.LandData.SalePrice > 0 &&
|
||||
(currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
|
||||
currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
|
||||
{
|
||||
//Sale Flag
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
|
||||
}
|
||||
else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
|
||||
{
|
||||
//Public Flag
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Other Flag
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
|
||||
}
|
||||
|
||||
//Now for border control
|
||||
|
||||
ILandObject westParcel = null;
|
||||
ILandObject southParcel = null;
|
||||
if (x > 0)
|
||||
{
|
||||
westParcel = GetLandObject((x - 1) * 4, y * 4);
|
||||
}
|
||||
if (y > 0)
|
||||
{
|
||||
southParcel = GetLandObject(x * 4, (y - 1) * 4);
|
||||
}
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
|
||||
}
|
||||
else if (westParcel != null && westParcel != currentParcelBlock)
|
||||
{
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
|
||||
}
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
|
||||
}
|
||||
else if (southParcel != null && southParcel != currentParcelBlock)
|
||||
{
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
remote_client.SendLandParcelOverlay(byteArray, sequenceID);
|
||||
byteArrayCount = 0;
|
||||
sequenceID++;
|
||||
byteArray = new byte[LAND_BLOCKS_PER_PACKET];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (byteArrayCount != 0)
|
||||
{
|
||||
remote_client.SendLandParcelOverlay(byteArray, sequenceID);
|
||||
}
|
||||
}
|
||||
|
||||
private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client)
|
||||
{
|
||||
byte tempByte = 0; //This represents the byte for the current 4x4
|
||||
|
||||
if (currentParcelBlock != null)
|
||||
{
|
||||
if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
|
||||
{
|
||||
//Owner Flag
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
|
||||
}
|
||||
else if (currentParcelBlock.LandData.SalePrice > 0 &&
|
||||
(currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
|
||||
currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
|
||||
{
|
||||
//Sale Flag
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE);
|
||||
}
|
||||
else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
|
||||
{
|
||||
//Public Flag
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Other Flag
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER);
|
||||
}
|
||||
|
||||
//Now for border control
|
||||
|
||||
ILandObject westParcel = null;
|
||||
ILandObject southParcel = null;
|
||||
if (x > 0)
|
||||
{
|
||||
westParcel = GetLandObject((x - 1) * landUnit, y * landUnit);
|
||||
}
|
||||
if (y > 0)
|
||||
{
|
||||
southParcel = GetLandObject(x * landUnit, (y - 1) * landUnit);
|
||||
}
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
|
||||
}
|
||||
else if (westParcel != null && westParcel != currentParcelBlock)
|
||||
{
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST);
|
||||
}
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
|
||||
}
|
||||
else if (southParcel != null && southParcel != currentParcelBlock)
|
||||
{
|
||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return tempByte;
|
||||
}
|
||||
|
||||
public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
|
||||
|
|
|
@ -45,10 +45,10 @@ 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 bool[,] m_landBitmap;
|
||||
private readonly int landUnit = 4;
|
||||
|
||||
private int m_lastSeqId = 0;
|
||||
|
||||
|
@ -93,12 +93,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,13 +110,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,6 +130,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_landBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
|
||||
|
||||
LandData.OwnerID = owner_id;
|
||||
if (is_group_owned)
|
||||
LandData.GroupID = owner_id;
|
||||
|
@ -152,9 +154,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] == true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -194,7 +196,7 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
else
|
||||
{
|
||||
// Normal Calculations
|
||||
int parcelMax = (int)(((float)LandData.Area / 65536.0f)
|
||||
int parcelMax = (int)(((float)LandData.Area / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY))
|
||||
* (float)m_scene.RegionInfo.ObjectCapacity
|
||||
* (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
|
||||
// TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL!
|
||||
|
@ -211,7 +213,7 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
else
|
||||
{
|
||||
//Normal Calculations
|
||||
int simMax = (int)(((float)LandData.SimwideArea / 65536.0f)
|
||||
int simMax = (int)(((float)LandData.SimwideArea / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY))
|
||||
* (float)m_scene.RegionInfo.ObjectCapacity);
|
||||
return simMax;
|
||||
}
|
||||
|
@ -224,7 +226,12 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
|
||||
{
|
||||
IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
|
||||
uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
|
||||
// uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
|
||||
uint regionFlags = (uint)(RegionFlags.PublicAllowed
|
||||
| RegionFlags.AllowDirectTeleport
|
||||
| RegionFlags.AllowParcelChanges
|
||||
| RegionFlags.AllowVoice );
|
||||
|
||||
if (estateModule != null)
|
||||
regionFlags = estateModule.GetRegionFlags();
|
||||
|
||||
|
@ -546,8 +553,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)
|
||||
{
|
||||
|
@ -694,15 +701,15 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
/// </summary>
|
||||
private void UpdateAABBAndAreaValues()
|
||||
{
|
||||
int min_x = 64;
|
||||
int min_y = 64;
|
||||
int min_x = 10000;
|
||||
int min_y = 10000;
|
||||
int max_x = 0;
|
||||
int max_y = 0;
|
||||
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)
|
||||
{
|
||||
|
@ -710,31 +717,31 @@ namespace OpenSim.Region.CoreModules.World.Land
|
|||
if (min_y > y) min_y = y;
|
||||
if (max_x < x) 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 * 4;
|
||||
if (tx > ((int)Constants.RegionSize - 1))
|
||||
tx = ((int)Constants.RegionSize - 1);
|
||||
int ty = min_y * 4;
|
||||
if (ty > ((int)Constants.RegionSize - 1))
|
||||
ty = ((int)Constants.RegionSize - 1);
|
||||
int tx = min_x * landUnit;
|
||||
if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
|
||||
tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
|
||||
int ty = min_y * landUnit;
|
||||
if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
|
||||
ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
|
||||
|
||||
LandData.AABBMin =
|
||||
new Vector3(
|
||||
(float)(min_x * 4), (float)(min_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
|
||||
(float)(min_x * landUnit), (float)(min_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
|
||||
|
||||
tx = max_x * 4;
|
||||
if (tx > ((int)Constants.RegionSize - 1))
|
||||
tx = ((int)Constants.RegionSize - 1);
|
||||
ty = max_y * 4;
|
||||
if (ty > ((int)Constants.RegionSize - 1))
|
||||
ty = ((int)Constants.RegionSize - 1);
|
||||
tx = max_x * landUnit;
|
||||
if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
|
||||
tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
|
||||
ty = max_y * landUnit;
|
||||
if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
|
||||
ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
|
||||
|
||||
LandData.AABBMax
|
||||
= new Vector3(
|
||||
(float)(max_x * 4), (float)(max_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
|
||||
(float)(max_x * landUnit), (float)(max_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0);
|
||||
|
||||
LandData.Area = tempArea;
|
||||
}
|
||||
|
@ -746,20 +753,11 @@ 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();
|
||||
}
|
||||
LandBitmap = bitmap;
|
||||
ForceUpdateLandInfo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -773,12 +771,12 @@ 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];
|
||||
bool[,] tempBitmap = new bool[(end_x-start_x)/landUnit,(end_y-start_y)/landUnit];
|
||||
tempBitmap.Initialize();
|
||||
|
||||
tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
|
||||
|
@ -798,19 +796,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;
|
||||
}
|
||||
|
@ -827,21 +819,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])
|
||||
{
|
||||
|
@ -858,13 +850,13 @@ 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];
|
||||
byte tempByte = 0;
|
||||
int x, y, i, byteNum = 0;
|
||||
i = 0;
|
||||
for (y = 0; y < 64; y++)
|
||||
int byteNum = 0;
|
||||
int i = 0;
|
||||
for (int y = 0; y < LandBitmap.GetLength(1); y++)
|
||||
{
|
||||
for (x = 0; x < 64; x++)
|
||||
for (int x = 0; x < LandBitmap.GetLength(0); x++)
|
||||
{
|
||||
tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
|
||||
if (i % 8 == 0)
|
||||
|
@ -881,25 +873,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);
|
||||
tempConvertMap[x, y] = bit;
|
||||
try
|
||||
{
|
||||
tempConvertMap[x, y] = bit;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue