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
|
public class LandManagementModule : INonSharedRegionModule
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
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/";
|
private static readonly string remoteParcelRequestPath = "0009/";
|
||||||
|
|
||||||
|
@ -76,15 +77,11 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
protected IPrimCountModule m_primCountModule;
|
protected IPrimCountModule m_primCountModule;
|
||||||
protected IDialogModule m_Dialog;
|
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>
|
/// <value>
|
||||||
/// Local land ids at specified region co-ordinates (region size / 4)
|
/// Local land ids at specified region co-ordinates (region size / 4)
|
||||||
/// </value>
|
/// </value>
|
||||||
private readonly int[,] m_landIDList = new int[landArrayMax, landArrayMax];
|
private int[,] m_landIDList;
|
||||||
|
private const int landUnit = 4;
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Land objects keyed by local id
|
/// Land objects keyed by local id
|
||||||
|
@ -117,6 +114,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
public void AddRegion(Scene scene)
|
public void AddRegion(Scene scene)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
|
m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
|
||||||
|
|
||||||
m_landIDList.Initialize();
|
m_landIDList.Initialize();
|
||||||
landChannel = new LandChannel(scene, this);
|
landChannel = new LandChannel(scene, this);
|
||||||
|
|
||||||
|
@ -326,6 +325,7 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
{
|
{
|
||||||
m_landList.Clear();
|
m_landList.Clear();
|
||||||
m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
|
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();
|
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);
|
"[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
|
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.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||||
fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
|
fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
|
||||||
|
|
||||||
|
@ -467,8 +468,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
|
|
||||||
public void SendLandUpdate(ScenePresence avatar, bool force)
|
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))),
|
ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
|
||||||
(int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
|
(int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
|
||||||
|
|
||||||
if (over != null)
|
if (over != null)
|
||||||
{
|
{
|
||||||
|
@ -634,20 +635,32 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
new_land.LandData.LocalID = newLandLocalID;
|
new_land.LandData.LocalID = newLandLocalID;
|
||||||
|
|
||||||
bool[,] landBitmap = new_land.GetLandBitmap();
|
bool[,] landBitmap = new_land.GetLandBitmap();
|
||||||
for (int x = 0; x < landArrayMax; x++)
|
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);
|
||||||
|
|
||||||
|
if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
|
||||||
{
|
{
|
||||||
for (int y = 0; y < landArrayMax; y++)
|
// 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])
|
if (landBitmap[x, y])
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
|
// "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}",
|
||||||
// new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
|
// new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
m_landIDList[x, y] = newLandLocalID;
|
m_landIDList[x, y] = newLandLocalID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_landList.Add(newLandLocalID, new_land);
|
m_landList.Add(newLandLocalID, new_land);
|
||||||
}
|
}
|
||||||
|
@ -666,9 +679,9 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
ILandObject land;
|
ILandObject land;
|
||||||
lock (m_landList)
|
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)
|
if (m_landIDList[x, y] == local_id)
|
||||||
{
|
{
|
||||||
|
@ -720,9 +733,9 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
bool[,] landBitmapSlave = slave.GetLandBitmap();
|
bool[,] landBitmapSlave = slave.GetLandBitmap();
|
||||||
lock (m_landList)
|
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])
|
if (landBitmapSlave[x, y])
|
||||||
{
|
{
|
||||||
|
@ -756,23 +769,28 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
/// <returns>Land object at the point supplied</returns>
|
/// <returns>Land object at the point supplied</returns>
|
||||||
public ILandObject GetLandObject(float x_float, float y_float)
|
public ILandObject GetLandObject(float x_float, float y_float)
|
||||||
{
|
{
|
||||||
|
return GetLandObject((int)x_float, (int)y_float);
|
||||||
|
/*
|
||||||
int x;
|
int x;
|
||||||
int y;
|
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;
|
return null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / 4.0));
|
x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit));
|
||||||
y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / 4.0));
|
y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit));
|
||||||
}
|
}
|
||||||
catch (OverflowException)
|
catch (OverflowException)
|
||||||
{
|
{
|
||||||
return null;
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -789,37 +807,111 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
|
// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
|
||||||
// x, y, m_scene.RegionInfo.RegionName);
|
// x, y, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
if (m_landList.ContainsKey(m_landIDList[x, y]))
|
if (m_landList.ContainsKey(m_landIDList[x, y]))
|
||||||
return m_landList[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;
|
return null;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given a region position, return the parcel land object for that location
|
||||||
public ILandObject GetLandObject(int x, int y)
|
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
|
// These exceptions here will cause a lot of complaints from the users specifically because
|
||||||
// they happen every time at border crossings
|
// 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)
|
lock (m_landIDList)
|
||||||
{
|
{
|
||||||
try
|
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)
|
catch (IndexOutOfRangeException)
|
||||||
{
|
{
|
||||||
// m_log.WarnFormat(
|
m_log.ErrorFormat(
|
||||||
// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}",
|
"{0} GetLandObject: Tried to retrieve land object from out of bounds co-ordinate ({1},{2}) in {3}. landListSize=({4},{5})",
|
||||||
// x, y, m_scene.RegionInfo.RegionName);
|
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 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
|
#endregion
|
||||||
|
@ -1082,17 +1174,34 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
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 blockmeters = 4 * (int) Constants.RegionSize/(int)Constants.TerrainPatchSize;
|
|
||||||
|
|
||||||
|
// Layer data is in landUnit (4m) chunks
|
||||||
for (int y = 0; y < blockmeters; y++)
|
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++)
|
||||||
|
{
|
||||||
|
byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * landUnit, y * landUnit), x, y, remote_client);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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
|
byte tempByte = 0; //This represents the byte for the current 4x4
|
||||||
|
|
||||||
ILandObject currentParcelBlock = GetLandObject(x * 4, y * 4);
|
|
||||||
|
|
||||||
if (currentParcelBlock != null)
|
if (currentParcelBlock != null)
|
||||||
{
|
{
|
||||||
if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
|
if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
|
||||||
|
@ -1124,11 +1233,11 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
ILandObject southParcel = null;
|
ILandObject southParcel = null;
|
||||||
if (x > 0)
|
if (x > 0)
|
||||||
{
|
{
|
||||||
westParcel = GetLandObject((x - 1) * 4, y * 4);
|
westParcel = GetLandObject((x - 1) * landUnit, y * landUnit);
|
||||||
}
|
}
|
||||||
if (y > 0)
|
if (y > 0)
|
||||||
{
|
{
|
||||||
southParcel = GetLandObject(x * 4, (y - 1) * 4);
|
southParcel = GetLandObject(x * landUnit, (y - 1) * landUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
|
@ -1149,18 +1258,9 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH);
|
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return tempByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
|
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
|
#region Member Variables
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
#pragma warning disable 0429
|
private static readonly string LogHeader = "[LAND OBJECT]";
|
||||||
private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64;
|
|
||||||
#pragma warning restore 0429
|
private bool[,] m_landBitmap;
|
||||||
private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax];
|
private readonly int landUnit = 4;
|
||||||
|
|
||||||
private int m_lastSeqId = 0;
|
private int m_lastSeqId = 0;
|
||||||
|
|
||||||
|
@ -93,12 +93,12 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
{
|
{
|
||||||
get
|
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])
|
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
|
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])
|
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)
|
public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
|
m_landBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
|
||||||
|
|
||||||
LandData.OwnerID = owner_id;
|
LandData.OwnerID = owner_id;
|
||||||
if (is_group_owned)
|
if (is_group_owned)
|
||||||
LandData.GroupID = owner_id;
|
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>
|
/// <returns>Returns true if the piece of land contains the specified point</returns>
|
||||||
public bool ContainsPoint(int x, int y)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -194,7 +196,7 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Normal Calculations
|
// 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.ObjectCapacity
|
||||||
* (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
|
* (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!
|
// 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
|
else
|
||||||
{
|
{
|
||||||
//Normal Calculations
|
//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);
|
* (float)m_scene.RegionInfo.ObjectCapacity);
|
||||||
return simMax;
|
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)
|
public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
|
||||||
{
|
{
|
||||||
IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
|
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)
|
if (estateModule != null)
|
||||||
regionFlags = estateModule.GetRegionFlags();
|
regionFlags = estateModule.GetRegionFlags();
|
||||||
|
|
||||||
|
@ -546,8 +553,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
over =
|
over =
|
||||||
m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 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)Constants.RegionSize - 1)));
|
Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1)));
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
@ -694,15 +701,15 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateAABBAndAreaValues()
|
private void UpdateAABBAndAreaValues()
|
||||||
{
|
{
|
||||||
int min_x = 64;
|
int min_x = 10000;
|
||||||
int min_y = 64;
|
int min_y = 10000;
|
||||||
int max_x = 0;
|
int max_x = 0;
|
||||||
int max_y = 0;
|
int max_y = 0;
|
||||||
int tempArea = 0;
|
int tempArea = 0;
|
||||||
int x, y;
|
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)
|
if (LandBitmap[x, y] == true)
|
||||||
{
|
{
|
||||||
|
@ -710,31 +717,31 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
if (min_y > y) min_y = y;
|
if (min_y > y) min_y = y;
|
||||||
if (max_x < x) max_x = x;
|
if (max_x < x) max_x = x;
|
||||||
if (max_y < y) max_y = y;
|
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;
|
int tx = min_x * landUnit;
|
||||||
if (tx > ((int)Constants.RegionSize - 1))
|
if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
|
||||||
tx = ((int)Constants.RegionSize - 1);
|
tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
|
||||||
int ty = min_y * 4;
|
int ty = min_y * landUnit;
|
||||||
if (ty > ((int)Constants.RegionSize - 1))
|
if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
|
||||||
ty = ((int)Constants.RegionSize - 1);
|
ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
|
||||||
|
|
||||||
LandData.AABBMin =
|
LandData.AABBMin =
|
||||||
new Vector3(
|
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;
|
tx = max_x * landUnit;
|
||||||
if (tx > ((int)Constants.RegionSize - 1))
|
if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
|
||||||
tx = ((int)Constants.RegionSize - 1);
|
tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
|
||||||
ty = max_y * 4;
|
ty = max_y * landUnit;
|
||||||
if (ty > ((int)Constants.RegionSize - 1))
|
if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1))
|
||||||
ty = ((int)Constants.RegionSize - 1);
|
ty = ((int)m_scene.RegionInfo.RegionSizeY - 1);
|
||||||
|
|
||||||
LandData.AABBMax
|
LandData.AABBMax
|
||||||
= new Vector3(
|
= 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;
|
LandData.Area = tempArea;
|
||||||
}
|
}
|
||||||
|
@ -746,21 +753,12 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the land's bitmap manually
|
/// Sets the land's bitmap manually
|
||||||
/// </summary>
|
/// </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)
|
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;
|
LandBitmap = bitmap;
|
||||||
ForceUpdateLandInfo();
|
ForceUpdateLandInfo();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the land's bitmap manually
|
/// Gets the land's bitmap manually
|
||||||
|
@ -773,12 +771,12 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
|
|
||||||
public bool[,] BasicFullRegionLandBitmap()
|
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)
|
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.Initialize();
|
||||||
|
|
||||||
tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
|
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,
|
public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
|
||||||
bool set_value)
|
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;
|
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
|
if (x >= start_x / landUnit && x < end_x / landUnit
|
||||||
&& y >= start_y / 4 && y < end_y / 4)
|
&& y >= start_y / landUnit && y < end_y / landUnit)
|
||||||
{
|
{
|
||||||
land_bitmap[x, y] = set_value;
|
land_bitmap[x, y] = set_value;
|
||||||
}
|
}
|
||||||
|
@ -827,21 +819,21 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
|
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(
|
||||||
throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
|
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))
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int x, y;
|
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])
|
if (bitmap_add[x, y])
|
||||||
{
|
{
|
||||||
|
@ -858,13 +850,13 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private byte[] ConvertLandBitmapToBytes()
|
private byte[] ConvertLandBitmapToBytes()
|
||||||
{
|
{
|
||||||
byte[] tempConvertArr = new byte[512];
|
byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8];
|
||||||
byte tempByte = 0;
|
byte tempByte = 0;
|
||||||
int x, y, i, byteNum = 0;
|
int byteNum = 0;
|
||||||
i = 0;
|
int 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++)
|
||||||
{
|
{
|
||||||
tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
|
tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
|
||||||
if (i % 8 == 0)
|
if (i % 8 == 0)
|
||||||
|
@ -881,25 +873,45 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
|
|
||||||
private bool[,] ConvertBytesToLandBitmap()
|
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();
|
tempConvertMap.Initialize();
|
||||||
byte tempByte = 0;
|
byte tempByte = 0;
|
||||||
int x = 0, y = 0, i = 0, bitNum = 0;
|
// Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap.
|
||||||
for (i = 0; i < 512; i++)
|
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];
|
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);
|
bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
|
||||||
|
try
|
||||||
|
{
|
||||||
tempConvertMap[x, y] = bit;
|
tempConvertMap[x, y] = bit;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("{0} ConvertBytestoLandBitmap: i={1}, x={2}, y={3}", LogHeader, i, x, y);
|
||||||
|
}
|
||||||
x++;
|
x++;
|
||||||
if (x > 63)
|
if (x >= xLen)
|
||||||
{
|
{
|
||||||
x = 0;
|
x = 0;
|
||||||
y++;
|
y++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tempConvertMap;
|
return tempConvertMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue