varregion: Add MaxRegionSize constant and enforce in RegionInfo.
Intermediate checkin of changing border cross computation from checking boundry limits to requests to GridService. Not totally functional.varregion
parent
109136c074
commit
6cd0d7a62b
OpenSim
Framework
Region
CoreModules
Framework/EntityTransfer
ServiceConnectorsOut/Grid
Framework/Scenes
|
@ -30,11 +30,13 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public class Constants
|
public class Constants
|
||||||
{
|
{
|
||||||
// 'RegionSize' captures the legacy region size.
|
// 'RegionSize' is the legacy region size.
|
||||||
// DO NOT USE THIS FOR ANY NEW CODE. Use Scene.RegionSize[XYZ] as a region might not
|
// DO NOT USE THIS FOR ANY NEW CODE. Use Scene.RegionSize[XYZ] as a region might not
|
||||||
// be the legacy region size.
|
// be the legacy region size.
|
||||||
public const uint RegionSize = 256;
|
public const uint RegionSize = 256;
|
||||||
public const uint RegionHeight = 4096;
|
public const uint RegionHeight = 4096;
|
||||||
|
// This could be a parameters but, really, a region of greater than this is pretty unmanageable
|
||||||
|
public const uint MaximumRegionSize = 8192;
|
||||||
|
|
||||||
// Since terrain is stored in 16x16 heights, regions must be a multiple of this number and that is the minimum
|
// Since terrain is stored in 16x16 heights, regions must be a multiple of this number and that is the minimum
|
||||||
public const int MinRegionSize = 16;
|
public const int MinRegionSize = 16;
|
||||||
|
|
|
@ -791,6 +791,15 @@ namespace OpenSim.Framework
|
||||||
LogHeader, m_regionName, RegionSizeX, RegionSizeY);
|
LogHeader, m_regionName, RegionSizeX, RegionSizeY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There is a practical limit to region size.
|
||||||
|
if (RegionSizeX > Constants.MaximumRegionSize || RegionSizeY > Constants.MaximumRegionSize)
|
||||||
|
{
|
||||||
|
RegionSizeX = Util.Clamp<uint>(RegionSizeX, Constants.RegionSize, Constants.MaximumRegionSize);
|
||||||
|
RegionSizeY = Util.Clamp<uint>(RegionSizeY, Constants.RegionSize, Constants.MaximumRegionSize);
|
||||||
|
m_log.ErrorFormat("{0} Region dimensions must be less than {1}. Clamping {2}'s size to <{3},{4}>",
|
||||||
|
LogHeader, Constants.MaximumRegionSize, m_regionName, RegionSizeX, RegionSizeY);
|
||||||
|
}
|
||||||
|
|
||||||
m_log.InfoFormat("{0} Region {1} size set to <{2},{3}>", LogHeader, m_regionName, RegionSizeX, RegionSizeY);
|
m_log.InfoFormat("{0} Region {1} size set to <{2},{3}>", LogHeader, m_regionName, RegionSizeX, RegionSizeY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
|
public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
|
||||||
{
|
{
|
||||||
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 = "[ENTITY TRANSFER MODULE]";
|
||||||
|
|
||||||
public const int DefaultMaxTransferDistance = 4095;
|
public const int DefaultMaxTransferDistance = 4095;
|
||||||
public const bool WaitForAgentArrivedAtDestinationDefault = true;
|
public const bool WaitForAgentArrivedAtDestinationDefault = true;
|
||||||
|
@ -433,10 +434,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
float posZLimit = 22;
|
float posZLimit = 22;
|
||||||
|
|
||||||
// TODO: Check other Scene HeightField
|
// TODO: Check other Scene HeightField
|
||||||
if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize)
|
|
||||||
{
|
|
||||||
posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
|
posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
|
||||||
}
|
|
||||||
|
|
||||||
float newPosZ = posZLimit + localAVHeight;
|
float newPosZ = posZLimit + localAVHeight;
|
||||||
if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
|
if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
|
||||||
|
@ -485,9 +483,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
if (finalDestination == null)
|
if (finalDestination == null)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat( "{0} Final destination is having problems. Unable to teleport {1} {2}",
|
||||||
"[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}",
|
LogHeader, sp.Name, sp.UUID);
|
||||||
sp.Name, sp.UUID);
|
|
||||||
|
|
||||||
sp.ControllingClient.SendTeleportFailed("Problem at destination");
|
sp.ControllingClient.SendTeleportFailed("Problem at destination");
|
||||||
return;
|
return;
|
||||||
|
@ -528,11 +525,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
// and set the map-tile to '(Offline)'
|
// and set the map-tile to '(Offline)'
|
||||||
uint regX, regY;
|
uint regX, regY;
|
||||||
Utils.LongToUInts(regionHandle, out regX, out regY);
|
Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY);
|
||||||
|
|
||||||
MapBlockData block = new MapBlockData();
|
MapBlockData block = new MapBlockData();
|
||||||
block.X = (ushort)(regX / Constants.RegionSize);
|
block.X = (ushort)Util.WorldToRegionLoc(regX);
|
||||||
block.Y = (ushort)(regY / Constants.RegionSize);
|
block.Y = (ushort)Util.WorldToRegionLoc(regY);
|
||||||
block.Access = 254; // == not there
|
block.Access = 254; // == not there
|
||||||
|
|
||||||
List<MapBlockData> blocks = new List<MapBlockData>();
|
List<MapBlockData> blocks = new List<MapBlockData>();
|
||||||
|
@ -1372,6 +1369,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
|
// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
|
||||||
|
/*
|
||||||
|
|
||||||
Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
|
Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
|
||||||
uint neighbourx = scene.RegionInfo.LegacyRegionLocX;
|
uint neighbourx = scene.RegionInfo.LegacyRegionLocX;
|
||||||
|
@ -1506,6 +1504,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
|
neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
|
||||||
newpos.Y = enterDistance;
|
newpos.Y = enterDistance;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -1532,20 +1531,34 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
|
double presenceWorldX = (double)scene.RegionInfo.RegionLocX + pos.X;
|
||||||
|
double presenceWorldY = (double)scene.RegionInfo.RegionLocY + pos.Y;
|
||||||
|
|
||||||
int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
|
// Call the grid service to lookup the region containing the new position.
|
||||||
|
GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
|
||||||
|
presenceWorldX, presenceWorldY);
|
||||||
|
|
||||||
|
if (neighbourRegion != null)
|
||||||
|
{
|
||||||
|
Vector3 newRegionRelativeObjectPosition = new Vector3(
|
||||||
|
(float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
|
||||||
|
(float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
|
||||||
|
pos.Z);
|
||||||
|
agent.ControllingClient.SendAgentAlertMessage(
|
||||||
|
String.Format("Moving you to region {0},{1}", neighbourRegion.RegionCoordX, neighbourRegion.RegionCoordY), false);
|
||||||
|
InformClientToInitiateTeleportToLocation(agent, (uint)neighbourRegion.RegionCoordX, (uint)neighbourRegion.RegionCoordY,
|
||||||
|
newRegionRelativeObjectPosition, scene);
|
||||||
|
|
||||||
ExpiringCache<ulong, DateTime> r;
|
ExpiringCache<ulong, DateTime> r;
|
||||||
DateTime banUntil;
|
DateTime banUntil;
|
||||||
|
|
||||||
if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r))
|
if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r))
|
||||||
{
|
{
|
||||||
if (r.TryGetValue(neighbourHandle, out banUntil))
|
if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil))
|
||||||
{
|
{
|
||||||
if (DateTime.Now < banUntil)
|
if (DateTime.Now < banUntil)
|
||||||
return false;
|
return false;
|
||||||
r.Remove(neighbourHandle);
|
r.Remove(neighbourRegion.RegionHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1553,23 +1566,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
r = null;
|
r = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
|
|
||||||
|
|
||||||
string reason;
|
string reason;
|
||||||
string version;
|
string version;
|
||||||
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
|
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newRegionRelativeObjectPosition, out version, out reason))
|
||||||
{
|
{
|
||||||
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
|
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
|
||||||
if (r == null)
|
if (r == null)
|
||||||
{
|
{
|
||||||
r = new ExpiringCache<ulong, DateTime>();
|
r = new ExpiringCache<ulong, DateTime>();
|
||||||
r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
|
r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
|
||||||
|
|
||||||
m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45));
|
m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
|
r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1577,7 +1588,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
agent.IsInTransit = true;
|
agent.IsInTransit = true;
|
||||||
|
|
||||||
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
|
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
|
||||||
d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
|
d.BeginInvoke(agent, newRegionRelativeObjectPosition,
|
||||||
|
(uint)neighbourRegion.RegionLocX, (uint)neighbourRegion.RegionLocY,
|
||||||
|
neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("{0} Cross(sp). Did not find target region. SP.AbsolutePosition={1}", LogHeader, pos);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2055,8 +2073,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Computes the difference between two region bases.
|
||||||
|
// Returns a vector of world coordinates (meters) from base of first region to the second.
|
||||||
|
// The first region is the home region of the passed scene presence.
|
||||||
Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour)
|
Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX;
|
int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX;
|
||||||
int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY;
|
int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY;
|
||||||
int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize;
|
int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize;
|
||||||
|
@ -2064,6 +2086,67 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize;
|
int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize;
|
||||||
int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize;
|
int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize;
|
||||||
return new Vector3(shiftx, shifty, 0f);
|
return new Vector3(shiftx, shifty, 0f);
|
||||||
|
*/
|
||||||
|
return new Vector3(sp.Scene.RegionInfo.RegionLocX - neighbour.RegionLocX,
|
||||||
|
sp.Scene.RegionInfo.RegionLocY - neighbour.RegionLocY,
|
||||||
|
0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a world position (fractional meter coordinate), get the GridRegion info for
|
||||||
|
// the region containing that point.
|
||||||
|
// Return 'null' if no such region exists.
|
||||||
|
private GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py);
|
||||||
|
GridRegion ret = null;
|
||||||
|
|
||||||
|
// As an optimization, since most regions will be legacy sized regions (256x256), first try to get
|
||||||
|
// the region at the appropriate legacy region location.
|
||||||
|
uint possibleX = (uint)Math.Floor(px);
|
||||||
|
possibleX -= possibleX % Constants.RegionSize;
|
||||||
|
uint possibleY = (uint)Math.Floor(py);
|
||||||
|
possibleY -= possibleY % Constants.RegionSize;
|
||||||
|
ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY);
|
||||||
|
if (ret != null)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
|
||||||
|
LogHeader, possibleX, possibleY, ret.RegionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == null)
|
||||||
|
{
|
||||||
|
// If the simple lookup failed, search the larger area for a region that contains this point
|
||||||
|
double range = (double)Constants.RegionSize + 2;
|
||||||
|
while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize))
|
||||||
|
{
|
||||||
|
// Get from the grid service a list of regions that might contain this point
|
||||||
|
List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID,
|
||||||
|
(int)(px - range), (int)(px + range),
|
||||||
|
(int)(py - range), (int)(py + range));
|
||||||
|
m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
|
||||||
|
LogHeader, possibleRegions.Count, range);
|
||||||
|
if (possibleRegions != null && possibleRegions.Count > 0)
|
||||||
|
{
|
||||||
|
// If we found some regions, check to see if the point is within
|
||||||
|
foreach (GridRegion gr in possibleRegions)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>",
|
||||||
|
LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY);
|
||||||
|
if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
|
||||||
|
&& py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY))
|
||||||
|
{
|
||||||
|
// Found a region that contains the point
|
||||||
|
ret = gr;
|
||||||
|
m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Larger search area for next time around if not found
|
||||||
|
range *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InformClientOfNeighbourCompleted(IAsyncResult iar)
|
private void InformClientOfNeighbourCompleted(IAsyncResult iar)
|
||||||
|
@ -2272,10 +2355,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
/// Move the given scene object into a new region depending on which region its absolute position has moved
|
/// Move the given scene object into a new region depending on which region its absolute position has moved
|
||||||
/// into.
|
/// into.
|
||||||
///
|
///
|
||||||
/// This method locates the new region handle and offsets the prim position for the new region
|
/// Using the objects new world location, ask the grid service for a the new region and adjust the prim
|
||||||
|
/// position to be relative to the new region.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
|
|
||||||
/// <param name="grp">the scene object that we're crossing</param>
|
/// <param name="grp">the scene object that we're crossing</param>
|
||||||
|
/// <param name="attemptedPosition">the attempted out of region position of the scene object. This position is
|
||||||
|
/// relative to the region the object currently is in.</param>
|
||||||
|
/// <param name="silent">if 'true', the deletion of the client from the region is not broadcast to the clients</param>
|
||||||
public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
|
public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
|
||||||
{
|
{
|
||||||
if (grp == null)
|
if (grp == null)
|
||||||
|
@ -2301,6 +2387,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
int thisx = (int)scene.RegionInfo.LegacyRegionLocX;
|
int thisx = (int)scene.RegionInfo.LegacyRegionLocX;
|
||||||
int thisy = (int)scene.RegionInfo.LegacyRegionLocY;
|
int thisy = (int)scene.RegionInfo.LegacyRegionLocY;
|
||||||
Vector3 EastCross = new Vector3(0.1f, 0, 0);
|
Vector3 EastCross = new Vector3(0.1f, 0, 0);
|
||||||
|
@ -2309,10 +2396,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
Vector3 SouthCross = new Vector3(0, -0.1f, 0);
|
Vector3 SouthCross = new Vector3(0, -0.1f, 0);
|
||||||
|
|
||||||
|
|
||||||
// use this if no borders were crossed!
|
// use this default if no borders were crossed (handle of the current region)
|
||||||
ulong newRegionHandle
|
ulong newRegionHandle = Util.RegionWorldLocToHandle(scene.RegionInfo.RegionWorldLocX, scene.RegionInfo.RegionWorldLocY);
|
||||||
= Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
|
|
||||||
(uint)((thisy) * Constants.RegionSize));
|
|
||||||
|
|
||||||
Vector3 pos = attemptedPosition;
|
Vector3 pos = attemptedPosition;
|
||||||
|
|
||||||
|
@ -2469,30 +2554,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
= Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
|
= Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
|
||||||
// y + 1
|
// y + 1
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Offset the positions for the new region across the border
|
// Remember the old group position in case the region lookup fails so position can be restored.
|
||||||
Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
|
Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
|
||||||
|
|
||||||
// If we fail to cross the border, then reset the position of the scene object on that border.
|
// Compute the absolute position of the object.
|
||||||
uint x = 0, y = 0;
|
double objectWorldLocX = (double)scene.RegionInfo.RegionWorldLocX + attemptedPosition.X;
|
||||||
Utils.LongToUInts(newRegionHandle, out x, out y);
|
double objectWorldLocY = (double)scene.RegionInfo.RegionWorldLocY + attemptedPosition.Y;
|
||||||
GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
|
|
||||||
|
// Ask the grid service for the region that contains the passed address
|
||||||
|
GridRegion destination = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, objectWorldLocX, objectWorldLocY);
|
||||||
|
|
||||||
|
Vector3 pos = Vector3.Zero;
|
||||||
|
if (destination != null)
|
||||||
|
{
|
||||||
|
// Adjust the object's relative position from the old region (attemptedPosition)
|
||||||
|
// to be relative to the new region (pos).
|
||||||
|
pos = new Vector3( (float)(objectWorldLocX - (double)destination.RegionLocX),
|
||||||
|
(float)(objectWorldLocY - (double)destination.RegionLocY),
|
||||||
|
attemptedPosition.Z);
|
||||||
|
}
|
||||||
|
|
||||||
if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
|
if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID);
|
m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID);
|
||||||
|
|
||||||
// We are going to move the object back to the old position so long as the old position
|
// We are going to move the object back to the old position so long as the old position
|
||||||
// is in the region
|
// is in the region
|
||||||
oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1);
|
oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
|
||||||
oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1);
|
oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
|
||||||
oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
|
oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
|
||||||
|
|
||||||
grp.RootPart.GroupPosition = oldGroupPosition;
|
grp.RootPart.GroupPosition = oldGroupPosition;
|
||||||
|
|
||||||
// Need to turn off the physics flags, otherwise the object will continue to attempt to
|
// Need to turn off the physics flags, otherwise the object will continue to attempt to
|
||||||
// move out of the region creating an infinite loop of failed attempts to cross
|
// move out of the region creating an infinite loop of failed attempts to cross
|
||||||
grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
|
grp.UpdatePrimFlags(grp.RootPart.LocalId, false, grp.IsTemporary, grp.IsPhantom, false);
|
||||||
|
|
||||||
if (grp.RootPart.KeyframeMotion != null)
|
if (grp.RootPart.KeyframeMotion != null)
|
||||||
grp.RootPart.KeyframeMotion.CrossingFailure();
|
grp.RootPart.KeyframeMotion.CrossingFailure();
|
||||||
|
|
|
@ -197,6 +197,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
// be the base coordinate of the region.
|
// be the base coordinate of the region.
|
||||||
public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
|
public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
|
||||||
{
|
{
|
||||||
|
m_log.DebugFormat("{0} GetRegionByPosition. pos=<{1},{2}>", "[LOCAL GRID SERVICE CONNECTOR", x, y);
|
||||||
GridRegion region = null;
|
GridRegion region = null;
|
||||||
|
|
||||||
// First see if it's a neighbour, even if it isn't on this sim.
|
// First see if it's a neighbour, even if it isn't on this sim.
|
||||||
|
@ -209,6 +210,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
region = rcache.GetRegionByPosition(x, y);
|
region = rcache.GetRegionByPosition(x, y);
|
||||||
if (region != null)
|
if (region != null)
|
||||||
{
|
{
|
||||||
|
m_log.DebugFormat("{0} GetRegionByPosition. Found region {1}. Pos=<{2},{3}>",
|
||||||
|
"[LOCAL GRID SERVICE CONNECTOR", region.RegionName, x, y);
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2483,6 +2483,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
EntityTransferModule.Cross(grp, attemptedPosition, silent);
|
EntityTransferModule.Cross(grp, attemptedPosition, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simple test to see if a position is in the current region.
|
||||||
|
// Resuming the position is relative to the region so anything outside its bounds.
|
||||||
|
// Return 'true' if position inside region.
|
||||||
|
public bool PositionIsInCurrentRegion(Vector3 pos)
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
int xx = (int)Math.Floor(pos.X);
|
||||||
|
int yy = (int)Math.Floor(pos.Y);
|
||||||
|
if (xx < 0
|
||||||
|
|| xx > RegionInfo.RegionSizeX
|
||||||
|
|| yy < 0
|
||||||
|
|| yy > RegionInfo.RegionSizeY)
|
||||||
|
ret = false;
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
|
public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
|
||||||
{
|
{
|
||||||
if (BordersLocked)
|
if (BordersLocked)
|
||||||
|
|
|
@ -3123,6 +3123,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
int neighbor = 0;
|
int neighbor = 0;
|
||||||
int[] fix = new int[2];
|
int[] fix = new int[2];
|
||||||
|
|
||||||
|
// Compute the avatar position in the next physics tick.
|
||||||
|
// If the avatar will be crossing, we force the crossing to happen now
|
||||||
|
// in the hope that this will make the avatar movement smoother when crossing.
|
||||||
float timeStep = 0.1f;
|
float timeStep = 0.1f;
|
||||||
pos2.X = pos2.X + (vel.X * timeStep);
|
pos2.X = pos2.X + (vel.X * timeStep);
|
||||||
pos2.Y = pos2.Y + (vel.Y * timeStep);
|
pos2.Y = pos2.Y + (vel.Y * timeStep);
|
||||||
|
@ -3130,12 +3133,48 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (!IsInTransit)
|
if (!IsInTransit)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
// "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}",
|
"[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}",
|
||||||
// pos2, Name, Scene.Name);
|
pos2, Name, Scene.Name);
|
||||||
|
|
||||||
|
if (!m_scene.PositionIsInCurrentRegion(pos2))
|
||||||
|
{
|
||||||
|
// Disconnect from the current region
|
||||||
|
bool isFlying = Flying;
|
||||||
|
RemoveFromPhysicalScene();
|
||||||
|
// pos2 is the forcasted position so make that the 'current' position so the crossing
|
||||||
|
// code will move us into the newly addressed region.
|
||||||
|
m_pos = pos2;
|
||||||
|
if (CrossToNewRegion())
|
||||||
|
{
|
||||||
|
AddToPhysicalScene(isFlying);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Tried to make crossing happen but it failed.
|
||||||
|
if (m_requestedSitTargetUUID == UUID.Zero)
|
||||||
|
{
|
||||||
|
|
||||||
|
Vector3 pos = AbsolutePosition;
|
||||||
|
if (AbsolutePosition.X < 0)
|
||||||
|
pos.X += Velocity.X * 2;
|
||||||
|
else if (AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX)
|
||||||
|
pos.X -= Velocity.X * 2;
|
||||||
|
if (AbsolutePosition.Y < 0)
|
||||||
|
pos.Y += Velocity.Y * 2;
|
||||||
|
else if (AbsolutePosition.Y > m_scene.RegionInfo.RegionSizeY)
|
||||||
|
pos.Y -= Velocity.Y * 2;
|
||||||
|
Velocity = Vector3.Zero;
|
||||||
|
AbsolutePosition = pos;
|
||||||
|
|
||||||
|
AddToPhysicalScene(isFlying);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// Checks if where it's headed exists a region
|
// Checks if where it's headed exists a region
|
||||||
bool needsTransit = false;
|
|
||||||
if (m_scene.TestBorderCross(pos2, Cardinals.W))
|
if (m_scene.TestBorderCross(pos2, Cardinals.W))
|
||||||
{
|
{
|
||||||
if (m_scene.TestBorderCross(pos2, Cardinals.S))
|
if (m_scene.TestBorderCross(pos2, Cardinals.S))
|
||||||
|
@ -3236,6 +3275,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue