try to make SOG crossings full async. Simplify some borders checking....
parent
fd79f75ba6
commit
4571e5bc3e
|
@ -3865,7 +3865,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
SceneObjectPart part = (SceneObjectPart)update.Entity;
|
SceneObjectPart part = (SceneObjectPart)update.Entity;
|
||||||
|
|
||||||
if (part.ParentGroup.IsDeleted)
|
if (part.ParentGroup.IsDeleted || part.ParentGroup.inTransit)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (part.ParentGroup.IsAttachment)
|
if (part.ParentGroup.IsAttachment)
|
||||||
|
|
|
@ -1385,13 +1385,61 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
|
|
||||||
#region Agent Crossings
|
#region Agent Crossings
|
||||||
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
|
|
||||||
|
public bool checkAgentAccessToRegion(ScenePresence agent, GridRegion destiny, Vector3 position, out string version, out string reason)
|
||||||
{
|
{
|
||||||
string r = String.Empty;
|
reason = String.Empty;
|
||||||
return GetDestination(scene, agentID, pos, out xDest, out yDest, out version, out newpos, out r);
|
version = String.Empty;
|
||||||
|
|
||||||
|
UUID agentID = agent.UUID;
|
||||||
|
ulong destinyHandle = destiny.RegionHandle;
|
||||||
|
|
||||||
|
ExpiringCache<ulong, DateTime> r;
|
||||||
|
DateTime banUntil;
|
||||||
|
if (m_bannedRegions.TryGetValue(agentID, out r))
|
||||||
|
{
|
||||||
|
if (r.TryGetValue(destinyHandle, out banUntil))
|
||||||
|
{
|
||||||
|
if (DateTime.Now < banUntil)
|
||||||
|
{
|
||||||
|
reason = "Cannot connect to region";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
r.Remove(destinyHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene ascene = agent.Scene;
|
||||||
|
|
||||||
|
if (!ascene.SimulationService.QueryAccess(destiny, agentID, position, out version, out reason))
|
||||||
|
{
|
||||||
|
if (r == null)
|
||||||
|
{
|
||||||
|
r = new ExpiringCache<ulong, DateTime>();
|
||||||
|
r.Add(destinyHandle, DateTime.Now + TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
|
||||||
|
|
||||||
|
m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(30));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r.Add(destinyHandle, DateTime.Now + TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos, out string reason)
|
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos)
|
||||||
|
{
|
||||||
|
string r = String.Empty;
|
||||||
|
return GetDestination(scene, agentID, pos, out version, out newpos, out r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos, out string reason)
|
||||||
{
|
{
|
||||||
version = String.Empty;
|
version = String.Empty;
|
||||||
reason = String.Empty;
|
reason = String.Empty;
|
||||||
|
@ -1400,9 +1448,13 @@ 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);
|
||||||
|
|
||||||
uint neighbourx = scene.RegionInfo.RegionLocX;
|
RegionInfo regInfo = scene.RegionInfo;
|
||||||
uint neighboury = scene.RegionInfo.RegionLocY;
|
|
||||||
|
uint neighbourx = regInfo.RegionLocX;
|
||||||
|
uint neighboury = regInfo.RegionLocY;
|
||||||
const float boundaryDistance = 0.7f;
|
const float boundaryDistance = 0.7f;
|
||||||
|
|
||||||
|
/*
|
||||||
Vector3 northCross = new Vector3(0, boundaryDistance, 0);
|
Vector3 northCross = new Vector3(0, boundaryDistance, 0);
|
||||||
Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0);
|
Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0);
|
||||||
Vector3 eastCross = new Vector3(boundaryDistance, 0, 0);
|
Vector3 eastCross = new Vector3(boundaryDistance, 0, 0);
|
||||||
|
@ -1463,11 +1515,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
newpos.X = Util.Clamp(newpos.X, enterDistance, maxX);
|
newpos.X = Util.Clamp(newpos.X, enterDistance, maxX);
|
||||||
newpos.Y = Util.Clamp(newpos.Y, enterDistance, maxY);
|
newpos.Y = Util.Clamp(newpos.Y, enterDistance, maxY);
|
||||||
|
*/
|
||||||
|
float regionSizeX = regInfo.RegionSizeX;
|
||||||
|
float regionSizeY = regInfo.RegionSizeY;
|
||||||
|
|
||||||
xDest = neighbourx;
|
if (pos.X < boundaryDistance)
|
||||||
yDest = neighboury;
|
neighbourx--;
|
||||||
|
else if (pos.X > regionSizeX - boundaryDistance)
|
||||||
|
neighbourx += (uint)(regionSizeX / Constants.RegionSize);
|
||||||
|
|
||||||
int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
|
if (pos.Y < boundaryDistance)
|
||||||
|
neighboury--;
|
||||||
|
else if (pos.Y > regionSizeY - boundaryDistance)
|
||||||
|
neighboury += (uint)(regionSizeY / Constants.RegionSize);
|
||||||
|
|
||||||
|
int x = (int)(neighbourx * Constants.RegionSize);
|
||||||
|
int y = (int)(neighboury * Constants.RegionSize);
|
||||||
|
|
||||||
ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
|
ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
|
||||||
|
|
||||||
|
@ -1489,6 +1552,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
|
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
|
||||||
|
if (neighbourRegion == null)
|
||||||
|
{
|
||||||
|
reason = "";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
float newRegionSizeX = neighbourRegion.RegionSizeX;
|
||||||
|
float newRegionSizeY = neighbourRegion.RegionSizeY;
|
||||||
|
|
||||||
|
if (pos.X < boundaryDistance)
|
||||||
|
newpos.X += newRegionSizeX;
|
||||||
|
else if (pos.X > regionSizeX - boundaryDistance)
|
||||||
|
newpos.X -= regionSizeX;
|
||||||
|
|
||||||
|
if (pos.Y < boundaryDistance)
|
||||||
|
newpos.Y += newRegionSizeY;
|
||||||
|
else if (pos.Y > regionSizeY - boundaryDistance)
|
||||||
|
newpos.Y -= regionSizeY;
|
||||||
|
|
||||||
|
const float enterDistance = 0.5f;
|
||||||
|
newpos.X = Util.Clamp(newpos.X, enterDistance, newRegionSizeX - enterDistance);
|
||||||
|
newpos.Y = Util.Clamp(newpos.Y, enterDistance, newRegionSizeY - enterDistance);
|
||||||
|
|
||||||
if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
|
if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
|
||||||
{
|
{
|
||||||
|
@ -1543,13 +1628,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
Vector3 pos = agent.AbsolutePosition + agent.Velocity;
|
Vector3 pos = agent.AbsolutePosition + agent.Velocity;
|
||||||
|
|
||||||
GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos, out x, out y, out version, out newpos, out reason);
|
GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos, out version, out newpos, out reason);
|
||||||
if (neighbourRegion == null)
|
if (neighbourRegion == null)
|
||||||
{
|
{
|
||||||
if (reason == String.Empty)
|
if (reason != String.Empty)
|
||||||
agent.ControllingClient.SendAlertMessage("Cannot cross to region");
|
agent.ControllingClient.SendAlertMessage("Cannot cross to region");
|
||||||
else
|
|
||||||
agent.ControllingClient.SendAlertMessage("Cannot cross to region: " + reason);
|
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2346,6 +2429,62 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
#region Object Transfers
|
#region Object Transfers
|
||||||
|
|
||||||
|
public GridRegion GetObjectDestination(SceneObjectGroup grp, Vector3 targetPosition,out Vector3 newpos)
|
||||||
|
{
|
||||||
|
newpos = targetPosition;
|
||||||
|
|
||||||
|
Scene scene = grp.Scene;
|
||||||
|
if (scene == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
RegionInfo srcRegionInfo = scene.RegionInfo;
|
||||||
|
int neighbourx = (int)srcRegionInfo.RegionLocX;
|
||||||
|
int neighboury = (int)srcRegionInfo.RegionLocY;
|
||||||
|
float regionSizeX = srcRegionInfo.RegionSizeX;
|
||||||
|
float regionSizeY = srcRegionInfo.RegionSizeY;
|
||||||
|
|
||||||
|
float edgeJitter = 0.2f;
|
||||||
|
|
||||||
|
if (targetPosition.X < edgeJitter)
|
||||||
|
neighbourx--;
|
||||||
|
else if (targetPosition.X > regionSizeX - edgeJitter)
|
||||||
|
neighbourx += (int)(regionSizeX / Constants.RegionSize);
|
||||||
|
|
||||||
|
if (targetPosition.Y < edgeJitter)
|
||||||
|
neighboury--;
|
||||||
|
else if (targetPosition.Y > regionSizeY - edgeJitter)
|
||||||
|
neighboury += (int)(regionSizeY / Constants.RegionSize);
|
||||||
|
|
||||||
|
int x = neighbourx * (int)Constants.RegionSize;
|
||||||
|
int y = neighboury * (int)Constants.RegionSize;
|
||||||
|
|
||||||
|
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
|
||||||
|
if (neighbourRegion == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
float newRegionSizeX = neighbourRegion.RegionSizeX;
|
||||||
|
float newRegionSizeY = neighbourRegion.RegionSizeY;
|
||||||
|
|
||||||
|
if (targetPosition.X < edgeJitter)
|
||||||
|
newpos.X += newRegionSizeX;
|
||||||
|
else if (targetPosition.X > regionSizeX - edgeJitter)
|
||||||
|
newpos.X -= regionSizeX;
|
||||||
|
|
||||||
|
if (targetPosition.Y < edgeJitter)
|
||||||
|
newpos.Y += newRegionSizeY;
|
||||||
|
else if (targetPosition.Y > regionSizeY - edgeJitter)
|
||||||
|
newpos.Y -= regionSizeY;
|
||||||
|
|
||||||
|
const float enterDistance = 0.2f;
|
||||||
|
newpos.X = Util.Clamp(newpos.X, enterDistance, newRegionSizeX - enterDistance);
|
||||||
|
newpos.Y = Util.Clamp(newpos.Y, enterDistance, newRegionSizeY - enterDistance);
|
||||||
|
|
||||||
|
return neighbourRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 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.
|
||||||
|
@ -2365,23 +2504,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
if (scene == null)
|
if (scene == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// http://wiki.secondlife.com/wiki/STATUS_DIE_AT_EDGE
|
|
||||||
// DieAtEdge does NOT mean that objects can't cross regions.
|
|
||||||
// It just means they die when they go off world, unless
|
|
||||||
// RETURN_AT_EDGE is set.
|
|
||||||
// if (grp.RootPart.DIE_AT_EDGE)
|
|
||||||
// {
|
|
||||||
// // We remove the object here
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// scene.DeleteSceneObject(grp, false);
|
|
||||||
// }
|
|
||||||
// catch (Exception)
|
|
||||||
// {
|
|
||||||
// m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
|
|
||||||
// }
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
int thisx = (int)scene.RegionInfo.RegionLocX;
|
int thisx = (int)scene.RegionInfo.RegionLocX;
|
||||||
int thisy = (int)scene.RegionInfo.RegionLocY;
|
int thisy = (int)scene.RegionInfo.RegionLocY;
|
||||||
|
@ -2594,7 +2716,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
/// true if the crossing itself was successful, false on failure
|
/// true if the crossing itself was successful, false on failure
|
||||||
/// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
|
/// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
|
||||||
/// </returns>
|
/// </returns>
|
||||||
protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent)
|
public bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent)
|
||||||
{
|
{
|
||||||
//m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
|
//m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
|
||||||
|
|
||||||
|
|
|
@ -93,9 +93,11 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
|
|
||||||
void EnableChildAgent(ScenePresence agent, GridRegion region);
|
void EnableChildAgent(ScenePresence agent, GridRegion region);
|
||||||
|
|
||||||
GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos);
|
GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos);
|
||||||
|
GridRegion GetObjectDestination(SceneObjectGroup grp, Vector3 targetPosition, out Vector3 newpos);
|
||||||
|
bool checkAgentAccessToRegion(ScenePresence agent, GridRegion destiny, Vector3 position, out string version, out string reason);
|
||||||
void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
|
void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
|
||||||
|
bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent);
|
||||||
|
|
||||||
ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
|
ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
|
||||||
|
|
||||||
|
|
|
@ -516,6 +516,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public uint ParentID;
|
public uint ParentID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool inTransit = false;
|
||||||
|
public delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The absolute position of this scene object in the scene
|
/// The absolute position of this scene object in the scene
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -525,8 +529,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Vector3 val = value;
|
Vector3 val = value;
|
||||||
|
|
||||||
if (Scene != null)
|
if (Scene != null && !inTransit)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
// (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E)
|
// (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E)
|
||||||
|
@ -543,130 +547,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|| Scene.TestBorderCross(val, Cardinals.S))
|
|| Scene.TestBorderCross(val, Cardinals.S))
|
||||||
&& !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
|
&& !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
|
||||||
{
|
{
|
||||||
IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
|
inTransit = true;
|
||||||
uint x = 0;
|
SOGCrossDelegate d = CrossAsync;
|
||||||
uint y = 0;
|
d.BeginInvoke(this, val, CrossAsyncCompleted, d);
|
||||||
string version = String.Empty;
|
return;
|
||||||
Vector3 newpos = Vector3.Zero;
|
|
||||||
OpenSim.Services.Interfaces.GridRegion destination = null;
|
|
||||||
|
|
||||||
if (m_rootPart.DIE_AT_EDGE || m_rootPart.RETURN_AT_EDGE)
|
|
||||||
{
|
|
||||||
// this should delete the grp in this case
|
|
||||||
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
|
|
||||||
// actually assume this sog was removed from simulation
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_rootPart.KeyframeMotion != null)
|
|
||||||
m_rootPart.KeyframeMotion.StartCrossingCheck();
|
|
||||||
|
|
||||||
bool canCross = true;
|
|
||||||
|
|
||||||
foreach (ScenePresence av in m_linkedAvatars)
|
|
||||||
{
|
|
||||||
// We need to cross these agents. First, let's find
|
|
||||||
// out if any of them can't cross for some reason.
|
|
||||||
// We have to deny the crossing entirely if any
|
|
||||||
// of them are banned. Alternatively, we could
|
|
||||||
// unsit banned agents....
|
|
||||||
|
|
||||||
|
|
||||||
// We set the avatar position as being the object
|
|
||||||
// position to get the region to send to
|
|
||||||
if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null)
|
|
||||||
{
|
|
||||||
canCross = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canCross)
|
|
||||||
{
|
|
||||||
// We unparent the SP quietly so that it won't
|
|
||||||
// be made to stand up
|
|
||||||
|
|
||||||
List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
|
|
||||||
|
|
||||||
foreach (ScenePresence av in m_linkedAvatars)
|
|
||||||
{
|
|
||||||
avtocrossInfo avinfo = new avtocrossInfo();
|
|
||||||
SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
|
|
||||||
if (parentPart != null)
|
|
||||||
av.ParentUUID = parentPart.UUID;
|
|
||||||
|
|
||||||
avinfo.av = av;
|
|
||||||
avinfo.ParentID = av.ParentID;
|
|
||||||
avsToCross.Add(avinfo);
|
|
||||||
|
|
||||||
av.PrevSitOffset = av.OffsetPosition;
|
|
||||||
av.ParentID = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// m_linkedAvatars.Clear();
|
|
||||||
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
|
|
||||||
|
|
||||||
// Normalize
|
|
||||||
if (val.X >= Constants.RegionSize)
|
|
||||||
val.X -= Constants.RegionSize;
|
|
||||||
if (val.Y >= Constants.RegionSize)
|
|
||||||
val.Y -= Constants.RegionSize;
|
|
||||||
if (val.X < 0)
|
|
||||||
val.X += Constants.RegionSize;
|
|
||||||
if (val.Y < 0)
|
|
||||||
val.Y += Constants.RegionSize;
|
|
||||||
|
|
||||||
// If it's deleted, crossing was successful
|
|
||||||
if (IsDeleted)
|
|
||||||
{
|
|
||||||
// foreach (ScenePresence av in m_linkedAvatars)
|
|
||||||
foreach (avtocrossInfo avinfo in avsToCross)
|
|
||||||
{
|
|
||||||
ScenePresence av = avinfo.av;
|
|
||||||
if (!av.IsInTransit) // just in case...
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
|
|
||||||
|
|
||||||
av.IsInTransit = true;
|
|
||||||
|
|
||||||
CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
|
|
||||||
d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val);
|
|
||||||
}
|
|
||||||
avsToCross.Clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else // cross failed, put avas back ??
|
|
||||||
{
|
|
||||||
foreach (avtocrossInfo avinfo in avsToCross)
|
|
||||||
{
|
|
||||||
ScenePresence av = avinfo.av;
|
|
||||||
av.ParentUUID = UUID.Zero;
|
|
||||||
av.ParentID = avinfo.ParentID;
|
|
||||||
// m_linkedAvatars.Add(av);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
avsToCross.Clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m_rootPart.KeyframeMotion != null)
|
|
||||||
m_rootPart.KeyframeMotion.CrossingFailure();
|
|
||||||
|
|
||||||
if (RootPart.PhysActor != null)
|
|
||||||
{
|
|
||||||
RootPart.PhysActor.CrossingFailure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vector3 oldp = AbsolutePosition;
|
|
||||||
val.X = Util.Clamp<float>(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f);
|
|
||||||
val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
|
|
||||||
// dont crash land StarShips
|
|
||||||
// val.Z = Util.Clamp<float>(oldp.Z, 0.5f, 4096.0f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,46 +598,197 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
part.TriggerScriptChangedEvent(Changed.POSITION);
|
part.TriggerScriptChangedEvent(Changed.POSITION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
Scene.EventManager.TriggerParcelPrimCountTainted();
|
||||||
This seems not needed and should not be needed:
|
|
||||||
sp absolute position depends on sit part absolute position fixed above.
|
|
||||||
sp ParentPosition is not used anywhere.
|
|
||||||
Since presence is sitting, viewer considers it 'linked' to root prim, so it will move/rotate it
|
|
||||||
Sending a extra packet with avatar position is not only bandwidth waste, but may cause jitter in viewers due to UPD nature.
|
|
||||||
|
|
||||||
if (!m_dupeInProgress)
|
|
||||||
{
|
|
||||||
foreach (ScenePresence av in m_linkedAvatars)
|
|
||||||
{
|
|
||||||
SceneObjectPart p = m_scene.GetSceneObjectPart(av.ParentID);
|
|
||||||
if (p != null && m_parts.TryGetValue(p.UUID, out p))
|
|
||||||
{
|
|
||||||
Vector3 offset = p.GetWorldPosition() - av.ParentPosition;
|
|
||||||
av.AbsolutePosition += offset;
|
|
||||||
// av.ParentPosition = p.GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition
|
|
||||||
av.SendAvatarDataToAllAgents();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//if (m_rootPart.PhysActor != null)
|
|
||||||
//{
|
|
||||||
//m_rootPart.PhysActor.Position =
|
|
||||||
//new PhysicsVector(m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y,
|
|
||||||
//m_rootPart.GroupPosition.Z);
|
|
||||||
//m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (Scene != null)
|
|
||||||
Scene.EventManager.TriggerParcelPrimCountTainted();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Vector3 Velocity
|
public SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val)
|
||||||
{
|
{
|
||||||
get { return RootPart.Velocity; }
|
Scene sogScene = sog.m_scene;
|
||||||
set { RootPart.Velocity = value; }
|
IEntityTransferModule entityTransfer = sogScene.RequestModuleInterface<IEntityTransferModule>();
|
||||||
|
|
||||||
|
Vector3 newpos = Vector3.Zero;
|
||||||
|
OpenSim.Services.Interfaces.GridRegion destination = null;
|
||||||
|
|
||||||
|
if (sog.RootPart.DIE_AT_EDGE)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sogScene.DeleteSceneObject(sog, false);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border.");
|
||||||
|
}
|
||||||
|
return sog;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sog.RootPart.RETURN_AT_EDGE)
|
||||||
|
{
|
||||||
|
// We remove the object here
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<uint> localIDs = new List<uint>();
|
||||||
|
localIDs.Add(sog.RootPart.LocalId);
|
||||||
|
sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition,
|
||||||
|
"Returned at region cross");
|
||||||
|
sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border.");
|
||||||
|
}
|
||||||
|
return sog;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sog.m_rootPart.KeyframeMotion != null)
|
||||||
|
sog.m_rootPart.KeyframeMotion.StartCrossingCheck();
|
||||||
|
|
||||||
|
if (entityTransfer == null)
|
||||||
|
return sog;
|
||||||
|
|
||||||
|
destination = entityTransfer.GetObjectDestination(sog, val, out newpos);
|
||||||
|
if (destination == null)
|
||||||
|
return sog;
|
||||||
|
|
||||||
|
if (sog.m_linkedAvatars.Count == 0)
|
||||||
|
{
|
||||||
|
entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true);
|
||||||
|
return sog;
|
||||||
|
}
|
||||||
|
|
||||||
|
string reason = String.Empty;
|
||||||
|
string version = String.Empty;
|
||||||
|
|
||||||
|
foreach (ScenePresence av in sog.m_linkedAvatars)
|
||||||
|
{
|
||||||
|
// We need to cross these agents. First, let's find
|
||||||
|
// out if any of them can't cross for some reason.
|
||||||
|
// We have to deny the crossing entirely if any
|
||||||
|
// of them are banned. Alternatively, we could
|
||||||
|
// unsit banned agents....
|
||||||
|
|
||||||
|
// We set the avatar position as being the object
|
||||||
|
// position to get the region to send to
|
||||||
|
if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, out version, out reason))
|
||||||
|
{
|
||||||
|
return sog;
|
||||||
|
}
|
||||||
|
m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We unparent the SP quietly so that it won't
|
||||||
|
// be made to stand up
|
||||||
|
|
||||||
|
List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
|
||||||
|
|
||||||
|
foreach (ScenePresence av in sog.m_linkedAvatars)
|
||||||
|
{
|
||||||
|
avtocrossInfo avinfo = new avtocrossInfo();
|
||||||
|
SceneObjectPart parentPart = sogScene.GetSceneObjectPart(av.ParentID);
|
||||||
|
if (parentPart != null)
|
||||||
|
av.ParentUUID = parentPart.UUID;
|
||||||
|
|
||||||
|
avinfo.av = av;
|
||||||
|
avinfo.ParentID = av.ParentID;
|
||||||
|
avsToCross.Add(avinfo);
|
||||||
|
|
||||||
|
av.PrevSitOffset = av.OffsetPosition;
|
||||||
|
av.ParentID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true))
|
||||||
|
{
|
||||||
|
foreach (avtocrossInfo avinfo in avsToCross)
|
||||||
|
{
|
||||||
|
ScenePresence av = avinfo.av;
|
||||||
|
if (!av.IsInTransit) // just in case...
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
|
||||||
|
|
||||||
|
av.IsInTransit = true;
|
||||||
|
|
||||||
|
// CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
|
||||||
|
// d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
|
||||||
|
entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, av.Flying, version);
|
||||||
|
if(av.IsChildAgent)
|
||||||
|
{
|
||||||
|
if (av.ParentUUID != UUID.Zero)
|
||||||
|
{
|
||||||
|
av.ClearControls();
|
||||||
|
av.ParentPart = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
av.ParentUUID = UUID.Zero;
|
||||||
|
// In any case
|
||||||
|
av.IsInTransit = false;
|
||||||
|
|
||||||
|
m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar already in transit {0} to {1}", av.Name, val);
|
||||||
|
}
|
||||||
|
avsToCross.Clear();
|
||||||
|
return sog;
|
||||||
|
}
|
||||||
|
else // cross failed, put avas back ??
|
||||||
|
{
|
||||||
|
foreach (avtocrossInfo avinfo in avsToCross)
|
||||||
|
{
|
||||||
|
ScenePresence av = avinfo.av;
|
||||||
|
av.ParentUUID = UUID.Zero;
|
||||||
|
av.ParentID = avinfo.ParentID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
avsToCross.Clear();
|
||||||
|
|
||||||
|
return sog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CrossAsyncCompleted(IAsyncResult iar)
|
||||||
|
{
|
||||||
|
SOGCrossDelegate icon = (SOGCrossDelegate)iar.AsyncState;
|
||||||
|
SceneObjectGroup sog = icon.EndInvoke(iar);
|
||||||
|
|
||||||
|
if (sog.IsDeleted)
|
||||||
|
{
|
||||||
|
sog.inTransit = false; // just in case...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SceneObjectPart rootp = sog.m_rootPart;
|
||||||
|
Vector3 oldp = rootp.GroupPosition;
|
||||||
|
oldp.X = Util.Clamp<float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f);
|
||||||
|
oldp.Y = Util.Clamp<float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f);
|
||||||
|
rootp.GroupPosition = oldp;
|
||||||
|
|
||||||
|
SceneObjectPart[] parts = sog.m_parts.GetArray();
|
||||||
|
|
||||||
|
foreach (SceneObjectPart part in parts)
|
||||||
|
{
|
||||||
|
if (part != rootp)
|
||||||
|
part.GroupPosition = oldp;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ScenePresence av in sog.m_linkedAvatars)
|
||||||
|
{
|
||||||
|
av.sitSOGmoved();
|
||||||
|
}
|
||||||
|
|
||||||
|
sog.Velocity = Vector3.Zero;
|
||||||
|
|
||||||
|
if (sog.m_rootPart.KeyframeMotion != null)
|
||||||
|
sog.m_rootPart.KeyframeMotion.CrossingFailure();
|
||||||
|
|
||||||
|
if (sog.RootPart.PhysActor != null)
|
||||||
|
{
|
||||||
|
sog.RootPart.PhysActor.CrossingFailure();
|
||||||
|
}
|
||||||
|
|
||||||
|
sog.inTransit = false;
|
||||||
|
sog.ScheduleGroupForFullUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
|
private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
|
||||||
|
@ -784,6 +819,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
|
m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Vector3 Velocity
|
||||||
|
{
|
||||||
|
get { return RootPart.Velocity; }
|
||||||
|
set { RootPart.Velocity = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public override uint LocalId
|
public override uint LocalId
|
||||||
{
|
{
|
||||||
get { return m_rootPart.LocalId; }
|
get { return m_rootPart.LocalId; }
|
||||||
|
@ -2620,7 +2661,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// an object has been deleted from a scene before update was processed.
|
// an object has been deleted from a scene before update was processed.
|
||||||
// A more fundamental overhaul of the update mechanism is required to eliminate all
|
// A more fundamental overhaul of the update mechanism is required to eliminate all
|
||||||
// the race conditions.
|
// the race conditions.
|
||||||
if (IsDeleted)
|
if (IsDeleted || inTransit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Even temporary objects take part in physics (e.g. temp-on-rez bullets)
|
// Even temporary objects take part in physics (e.g. temp-on-rez bullets)
|
||||||
|
@ -2736,7 +2777,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendGroupRootTerseUpdate()
|
public void SendGroupRootTerseUpdate()
|
||||||
{
|
{
|
||||||
if (IsDeleted)
|
if (IsDeleted || inTransit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RootPart.SendTerseUpdateToAllClients();
|
RootPart.SendTerseUpdateToAllClients();
|
||||||
|
@ -2755,7 +2796,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendGroupTerseUpdate()
|
public void SendGroupTerseUpdate()
|
||||||
{
|
{
|
||||||
if (IsDeleted)
|
if (IsDeleted || inTransit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (IsAttachment)
|
if (IsAttachment)
|
||||||
|
|
|
@ -1123,6 +1123,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (part == null)
|
if (part == null)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
|
m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
|
||||||
|
ParentID = 0;
|
||||||
|
ParentPart = null;
|
||||||
|
PrevSitOffset = Vector3.Zero;
|
||||||
|
ClearControls();
|
||||||
|
IsLoggingIn = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1216,13 +1221,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
else
|
else
|
||||||
AddToPhysicalScene(isFlying);
|
AddToPhysicalScene(isFlying);
|
||||||
|
|
||||||
// XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
|
|
||||||
// location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
|
|
||||||
// since it requires a physics actor to be present. If it is left any later, then physics appears to reset
|
|
||||||
// the value to a negative position which does not trigger the border cross.
|
|
||||||
// This may not be the best location for this.
|
|
||||||
CheckForBorderCrossing();
|
|
||||||
|
|
||||||
if (ForceFly)
|
if (ForceFly)
|
||||||
{
|
{
|
||||||
Flying = true;
|
Flying = true;
|
||||||
|
@ -1231,12 +1229,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
Flying = false;
|
Flying = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
|
|
||||||
// avatar to return to the standing position in mid-air. On login it looks like this is being sent
|
|
||||||
// elsewhere anyway
|
|
||||||
// Animator.SendAnimPack();
|
|
||||||
|
|
||||||
|
// XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
|
||||||
|
// location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
|
||||||
|
// since it requires a physics actor to be present. If it is left any later, then physics appears to reset
|
||||||
|
// the value to a negative position which does not trigger the border cross.
|
||||||
|
// This may not be the best location for this.
|
||||||
|
|
||||||
|
|
||||||
|
// its not
|
||||||
|
// CheckForBorderCrossing();
|
||||||
|
}
|
||||||
|
|
||||||
m_log.DebugFormat("[MakeRootAgent] position and physical: {0}ms", Util.EnvironmentTickCountSubtract(ts));
|
m_log.DebugFormat("[MakeRootAgent] position and physical: {0}ms", Util.EnvironmentTickCountSubtract(ts));
|
||||||
m_scene.SwapRootAgentCount(false);
|
m_scene.SwapRootAgentCount(false);
|
||||||
|
|
||||||
|
@ -2734,7 +2738,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ParentID = 0;
|
ParentID = 0;
|
||||||
ParentPart = null;
|
ParentPart = null;
|
||||||
|
|
||||||
|
|
||||||
if (part.SitTargetAvatar == UUID)
|
if (part.SitTargetAvatar == UUID)
|
||||||
standRotation = standRotation * part.SitTargetOrientation;
|
standRotation = standRotation * part.SitTargetOrientation;
|
||||||
else
|
else
|
||||||
|
@ -2761,12 +2764,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
Vector3 standPos = sitPartWorldPosition + adjustmentForSitPose;
|
Vector3 standPos = sitPartWorldPosition + adjustmentForSitPose;
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[SCENE PRESENCE]: Setting stand to pos {0}, (adjustmentForSitPosition {1}, adjustmentForSitPose {2}) rotation {3} for {4} in {5}",
|
|
||||||
// standPos, adjustmentForSitPosition, adjustmentForSitPose, standRotation, Name, Scene.Name);
|
|
||||||
|
|
||||||
standPos.X = Util.Clamp<float>(standPos.X, 0.5f, (float)Constants.RegionSize - 0.5f);
|
|
||||||
standPos.Y = Util.Clamp<float>(standPos.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
|
|
||||||
m_pos = standPos;
|
m_pos = standPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3308,6 +3305,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (IsChildAgent == false)
|
if (IsChildAgent == false)
|
||||||
{
|
{
|
||||||
|
CheckForBorderCrossing();
|
||||||
|
|
||||||
if (IsInTransit)
|
if (IsInTransit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3329,8 +3328,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_lastVelocity = Velocity;
|
m_lastVelocity = Velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckForBorderCrossing();
|
|
||||||
|
|
||||||
CheckForSignificantMovement(); // sends update to the modules.
|
CheckForSignificantMovement(); // sends update to the modules.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3847,7 +3844,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
protected void CheckForBorderCrossing()
|
protected void CheckForBorderCrossing()
|
||||||
{
|
{
|
||||||
// Check that we we are not a child
|
// Check that we we are not a child
|
||||||
if (IsChildAgent)
|
if (IsChildAgent || IsInTransit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If we don't have a PhysActor, we can't cross anyway
|
// If we don't have a PhysActor, we can't cross anyway
|
||||||
|
@ -3857,25 +3854,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
|
if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (IsInTransit)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Vector3 pos2 = AbsolutePosition;
|
Vector3 pos2 = AbsolutePosition;
|
||||||
Vector3 vel = Velocity;
|
Vector3 vel = Velocity;
|
||||||
int neighbor = 0;
|
|
||||||
int[] fix = new int[2];
|
|
||||||
|
|
||||||
float timeStep = 0.1f;
|
float timeStep = 0.1f;
|
||||||
pos2.X = pos2.X + (vel.X * timeStep);
|
pos2.X += vel.X * timeStep;
|
||||||
pos2.Y = pos2.Y + (vel.Y * timeStep);
|
pos2.Y += vel.Y * timeStep;
|
||||||
pos2.Z = pos2.Z + (vel.Z * timeStep);
|
pos2.Z += vel.Z * timeStep;
|
||||||
|
|
||||||
|
|
||||||
// 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);
|
||||||
|
/*
|
||||||
// Checks if where it's headed exists a region
|
// Checks if where it's headed exists a region
|
||||||
|
int neighbor = 0;
|
||||||
|
int[] fix = new int[2];
|
||||||
|
|
||||||
bool needsTransit = false;
|
bool needsTransit = false;
|
||||||
if (m_scene.TestBorderCross(pos2, Cardinals.W))
|
if (m_scene.TestBorderCross(pos2, Cardinals.W))
|
||||||
{
|
{
|
||||||
|
@ -3925,59 +3919,55 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Makes sure avatar does not end up outside region
|
// Makes sure avatar does not end up outside region
|
||||||
|
|
||||||
if (neighbor <= 0)
|
if (neighbor <= 0)
|
||||||
{
|
{
|
||||||
if (needsTransit)
|
if (needsTransit)
|
||||||
{
|
{
|
||||||
if (m_requestedSitTargetUUID == UUID.Zero)
|
CrossToNewRegionFail();
|
||||||
{
|
|
||||||
bool isFlying = Flying;
|
|
||||||
RemoveFromPhysicalScene();
|
|
||||||
|
|
||||||
Vector3 pos = AbsolutePosition;
|
|
||||||
if (AbsolutePosition.X < 0)
|
|
||||||
pos.X += Velocity.X * 2;
|
|
||||||
else if (AbsolutePosition.X > Constants.RegionSize)
|
|
||||||
pos.X -= Velocity.X * 2;
|
|
||||||
if (AbsolutePosition.Y < 0)
|
|
||||||
pos.Y += Velocity.Y * 2;
|
|
||||||
else if (AbsolutePosition.Y > Constants.RegionSize)
|
|
||||||
pos.Y -= Velocity.Y * 2;
|
|
||||||
Velocity = Vector3.Zero;
|
|
||||||
AbsolutePosition = pos;
|
|
||||||
|
|
||||||
// m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition);
|
|
||||||
|
|
||||||
AddToPhysicalScene(isFlying);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (neighbor > 0)
|
else if (neighbor > 0)
|
||||||
{
|
{
|
||||||
if (!CrossToNewRegion())
|
if (!CrossToNewRegion())
|
||||||
{
|
{
|
||||||
if (m_requestedSitTargetUUID == UUID.Zero)
|
CrossToNewRegionFail();
|
||||||
{
|
|
||||||
bool isFlying = Flying;
|
|
||||||
RemoveFromPhysicalScene();
|
|
||||||
|
|
||||||
Vector3 pos = AbsolutePosition;
|
|
||||||
if (AbsolutePosition.X < 0)
|
|
||||||
pos.X += Velocity.X * 2;
|
|
||||||
else if (AbsolutePosition.X > Constants.RegionSize)
|
|
||||||
pos.X -= Velocity.X * 2;
|
|
||||||
if (AbsolutePosition.Y < 0)
|
|
||||||
pos.Y += Velocity.Y * 2;
|
|
||||||
else if (AbsolutePosition.Y > Constants.RegionSize)
|
|
||||||
pos.Y -= Velocity.Y * 2;
|
|
||||||
Velocity = Vector3.Zero;
|
|
||||||
AbsolutePosition = pos;
|
|
||||||
|
|
||||||
AddToPhysicalScene(isFlying);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
bool needsTransit = false;
|
||||||
|
|
||||||
|
if (pos2.X < 0)
|
||||||
|
needsTransit = true;
|
||||||
|
else if (pos2.X > m_scene.RegionInfo.RegionSizeX)
|
||||||
|
needsTransit = true;
|
||||||
|
else if (pos2.Y < 0)
|
||||||
|
needsTransit = true;
|
||||||
|
else if (pos2.Y > m_scene.RegionInfo.RegionSizeY)
|
||||||
|
needsTransit = true;
|
||||||
|
|
||||||
|
if (needsTransit)
|
||||||
|
{
|
||||||
|
if (!CrossToNewRegion() && m_requestedSitTargetUUID == UUID.Zero)
|
||||||
|
{
|
||||||
|
// we don't have entity transfer module
|
||||||
|
Vector3 pos = AbsolutePosition;
|
||||||
|
float px = pos.X;
|
||||||
|
if (px < 0)
|
||||||
|
pos.X += Velocity.X * 2;
|
||||||
|
else if (px > m_scene.RegionInfo.RegionSizeX)
|
||||||
|
pos.X -= Velocity.X * 2;
|
||||||
|
|
||||||
|
float py = pos.Y;
|
||||||
|
if (py < 0)
|
||||||
|
pos.Y += Velocity.Y * 2;
|
||||||
|
else if (py > m_scene.RegionInfo.RegionSizeY)
|
||||||
|
pos.Y -= Velocity.Y * 2;
|
||||||
|
|
||||||
|
Velocity = Vector3.Zero;
|
||||||
|
AbsolutePosition = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CrossToNewRegionFail()
|
public void CrossToNewRegionFail()
|
||||||
|
@ -3988,14 +3978,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
RemoveFromPhysicalScene();
|
RemoveFromPhysicalScene();
|
||||||
|
|
||||||
Vector3 pos = AbsolutePosition;
|
Vector3 pos = AbsolutePosition;
|
||||||
if (AbsolutePosition.X < 0)
|
float px = pos.X;
|
||||||
|
if (px < 0)
|
||||||
pos.X += Velocity.X * 2;
|
pos.X += Velocity.X * 2;
|
||||||
else if (AbsolutePosition.X > Constants.RegionSize)
|
else if (px > m_scene.RegionInfo.RegionSizeX)
|
||||||
pos.X -= Velocity.X * 2;
|
pos.X -= Velocity.X * 2;
|
||||||
if (AbsolutePosition.Y < 0)
|
|
||||||
|
float py = pos.Y;
|
||||||
|
if (py < 0)
|
||||||
pos.Y += Velocity.Y * 2;
|
pos.Y += Velocity.Y * 2;
|
||||||
else if (AbsolutePosition.Y > Constants.RegionSize)
|
else if (py > m_scene.RegionInfo.RegionSizeY)
|
||||||
pos.Y -= Velocity.Y * 2;
|
pos.Y -= Velocity.Y * 2;
|
||||||
|
|
||||||
Velocity = Vector3.Zero;
|
Velocity = Vector3.Zero;
|
||||||
AbsolutePosition = pos;
|
AbsolutePosition = pos;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue