aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Constants.cs4
-rw-r--r--OpenSim/Framework/RegionInfo.cs11
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs218
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs17
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs48
6 files changed, 235 insertions, 66 deletions
diff --git a/OpenSim/Framework/Constants.cs b/OpenSim/Framework/Constants.cs
index d18b32e..d80808c 100644
--- a/OpenSim/Framework/Constants.cs
+++ b/OpenSim/Framework/Constants.cs
@@ -30,11 +30,13 @@ namespace OpenSim.Framework
30{ 30{
31 public class Constants 31 public class Constants
32 { 32 {
33 // 'RegionSize' captures the legacy region size. 33 // 'RegionSize' is the legacy region size.
34 // DO NOT USE THIS FOR ANY NEW CODE. Use Scene.RegionSize[XYZ] as a region might not 34 // DO NOT USE THIS FOR ANY NEW CODE. Use Scene.RegionSize[XYZ] as a region might not
35 // be the legacy region size. 35 // be the legacy region size.
36 public const uint RegionSize = 256; 36 public const uint RegionSize = 256;
37 public const uint RegionHeight = 4096; 37 public const uint RegionHeight = 4096;
38 // This could be a parameters but, really, a region of greater than this is pretty unmanageable
39 public const uint MaximumRegionSize = 8192;
38 40
39 // Since terrain is stored in 16x16 heights, regions must be a multiple of this number and that is the minimum 41 // Since terrain is stored in 16x16 heights, regions must be a multiple of this number and that is the minimum
40 public const int MinRegionSize = 16; 42 public const int MinRegionSize = 16;
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index cf909cd..63b3d89 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -788,7 +788,16 @@ namespace OpenSim.Framework
788 RegionSizeX = minSize; 788 RegionSizeX = minSize;
789 RegionSizeY = minSize; 789 RegionSizeY = minSize;
790 m_log.ErrorFormat("{0} Regions must be square until viewers are updated. Forcing region {1} size to <{2},{3}>", 790 m_log.ErrorFormat("{0} Regions must be square until viewers are updated. Forcing region {1} size to <{2},{3}>",
791 LogHeader, m_regionName, RegionSizeX, RegionSizeY); 791 LogHeader, m_regionName, RegionSizeX, RegionSizeY);
792 }
793
794 // There is a practical limit to region size.
795 if (RegionSizeX > Constants.MaximumRegionSize || RegionSizeY > Constants.MaximumRegionSize)
796 {
797 RegionSizeX = Util.Clamp<uint>(RegionSizeX, Constants.RegionSize, Constants.MaximumRegionSize);
798 RegionSizeY = Util.Clamp<uint>(RegionSizeY, Constants.RegionSize, Constants.MaximumRegionSize);
799 m_log.ErrorFormat("{0} Region dimensions must be less than {1}. Clamping {2}'s size to <{3},{4}>",
800 LogHeader, Constants.MaximumRegionSize, m_regionName, RegionSizeX, RegionSizeY);
792 } 801 }
793 802
794 m_log.InfoFormat("{0} Region {1} size set to <{2},{3}>", LogHeader, m_regionName, RegionSizeX, RegionSizeY); 803 m_log.InfoFormat("{0} Region {1} size set to <{2},{3}>", LogHeader, m_regionName, RegionSizeX, RegionSizeY);
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index eb1b271..c3d0765 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule 52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]";
55 56
56 public const int DefaultMaxTransferDistance = 4095; 57 public const int DefaultMaxTransferDistance = 4095;
57 public const bool WaitForAgentArrivedAtDestinationDefault = true; 58 public const bool WaitForAgentArrivedAtDestinationDefault = true;
@@ -433,10 +434,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
433 float posZLimit = 22; 434 float posZLimit = 22;
434 435
435 // TODO: Check other Scene HeightField 436 // TODO: Check other Scene HeightField
436 if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) 437 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
437 {
438 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
439 }
440 438
441 float newPosZ = posZLimit + localAVHeight; 439 float newPosZ = posZLimit + localAVHeight;
442 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 440 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
@@ -485,9 +483,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
485 483
486 if (finalDestination == null) 484 if (finalDestination == null)
487 { 485 {
488 m_log.WarnFormat( 486 m_log.WarnFormat( "{0} Final destination is having problems. Unable to teleport {1} {2}",
489 "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}", 487 LogHeader, sp.Name, sp.UUID);
490 sp.Name, sp.UUID);
491 488
492 sp.ControllingClient.SendTeleportFailed("Problem at destination"); 489 sp.ControllingClient.SendTeleportFailed("Problem at destination");
493 return; 490 return;
@@ -528,11 +525,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
528 525
529 // and set the map-tile to '(Offline)' 526 // and set the map-tile to '(Offline)'
530 uint regX, regY; 527 uint regX, regY;
531 Utils.LongToUInts(regionHandle, out regX, out regY); 528 Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY);
532 529
533 MapBlockData block = new MapBlockData(); 530 MapBlockData block = new MapBlockData();
534 block.X = (ushort)(regX / Constants.RegionSize); 531 block.X = (ushort)Util.WorldToRegionLoc(regX);
535 block.Y = (ushort)(regY / Constants.RegionSize); 532 block.Y = (ushort)Util.WorldToRegionLoc(regY);
536 block.Access = 254; // == not there 533 block.Access = 254; // == not there
537 534
538 List<MapBlockData> blocks = new List<MapBlockData>(); 535 List<MapBlockData> blocks = new List<MapBlockData>();
@@ -1372,6 +1369,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1372 1369
1373// m_log.DebugFormat( 1370// m_log.DebugFormat(
1374// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1371// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1372 /*
1375 1373
1376 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1374 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1377 uint neighbourx = scene.RegionInfo.LegacyRegionLocX; 1375 uint neighbourx = scene.RegionInfo.LegacyRegionLocX;
@@ -1506,6 +1504,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1506 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); 1504 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1507 newpos.Y = enterDistance; 1505 newpos.Y = enterDistance;
1508 } 1506 }
1507 */
1509 1508
1510 /* 1509 /*
1511 1510
@@ -1532,52 +1531,71 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1532 } 1531 }
1533 */ 1532 */
1534 1533
1535 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1534 double presenceWorldX = (double)scene.RegionInfo.RegionLocX + pos.X;
1536 1535 double presenceWorldY = (double)scene.RegionInfo.RegionLocY + pos.Y;
1537 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1538 1536
1539 ExpiringCache<ulong, DateTime> r; 1537 // Call the grid service to lookup the region containing the new position.
1540 DateTime banUntil; 1538 GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
1539 presenceWorldX, presenceWorldY);
1541 1540
1542 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 1541 if (neighbourRegion != null)
1543 {
1544 if (r.TryGetValue(neighbourHandle, out banUntil))
1545 {
1546 if (DateTime.Now < banUntil)
1547 return false;
1548 r.Remove(neighbourHandle);
1549 }
1550 }
1551 else
1552 { 1542 {
1553 r = null; 1543 Vector3 newRegionRelativeObjectPosition = new Vector3(
1554 } 1544 (float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
1545 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
1546 pos.Z);
1547 agent.ControllingClient.SendAgentAlertMessage(
1548 String.Format("Moving you to region {0},{1}", neighbourRegion.RegionCoordX, neighbourRegion.RegionCoordY), false);
1549 InformClientToInitiateTeleportToLocation(agent, (uint)neighbourRegion.RegionCoordX, (uint)neighbourRegion.RegionCoordY,
1550 newRegionRelativeObjectPosition, scene);
1555 1551
1556 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1552 ExpiringCache<ulong, DateTime> r;
1553 DateTime banUntil;
1557 1554
1558 string reason; 1555 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r))
1559 string version;
1560 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1561 {
1562 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1563 if (r == null)
1564 { 1556 {
1565 r = new ExpiringCache<ulong, DateTime>(); 1557 if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil))
1566 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1558 {
1567 1559 if (DateTime.Now < banUntil)
1568 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 1560 return false;
1561 r.Remove(neighbourRegion.RegionHandle);
1562 }
1569 } 1563 }
1570 else 1564 else
1571 { 1565 {
1572 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1566 r = null;
1573 } 1567 }
1574 return false;
1575 }
1576 1568
1577 agent.IsInTransit = true; 1569 string reason;
1570 string version;
1571 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newRegionRelativeObjectPosition, out version, out reason))
1572 {
1573 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1574 if (r == null)
1575 {
1576 r = new ExpiringCache<ulong, DateTime>();
1577 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1578
1579 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45));
1580 }
1581 else
1582 {
1583 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1584 }
1585 return false;
1586 }
1578 1587
1579 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1588 agent.IsInTransit = true;
1580 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1589
1590 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1591 d.BeginInvoke(agent, newRegionRelativeObjectPosition,
1592 (uint)neighbourRegion.RegionLocX, (uint)neighbourRegion.RegionLocY,
1593 neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1594 }
1595 else
1596 {
1597 m_log.ErrorFormat("{0} Cross(sp). Did not find target region. SP.AbsolutePosition={1}", LogHeader, pos);
1598 }
1581 1599
1582 return true; 1600 return true;
1583 } 1601 }
@@ -2055,8 +2073,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2055 } 2073 }
2056 } 2074 }
2057 2075
2076 // Computes the difference between two region bases.
2077 // Returns a vector of world coordinates (meters) from base of first region to the second.
2078 // The first region is the home region of the passed scene presence.
2058 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) 2079 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour)
2059 { 2080 {
2081 /*
2060 int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX; 2082 int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX;
2061 int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY; 2083 int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY;
2062 int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize; 2084 int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize;
@@ -2064,6 +2086,67 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2064 int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize; 2086 int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize;
2065 int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize; 2087 int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize;
2066 return new Vector3(shiftx, shifty, 0f); 2088 return new Vector3(shiftx, shifty, 0f);
2089 */
2090 return new Vector3(sp.Scene.RegionInfo.RegionLocX - neighbour.RegionLocX,
2091 sp.Scene.RegionInfo.RegionLocY - neighbour.RegionLocY,
2092 0f);
2093 }
2094
2095 // Given a world position (fractional meter coordinate), get the GridRegion info for
2096 // the region containing that point.
2097 // Return 'null' if no such region exists.
2098 private GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
2099 {
2100 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py);
2101 GridRegion ret = null;
2102
2103 // As an optimization, since most regions will be legacy sized regions (256x256), first try to get
2104 // the region at the appropriate legacy region location.
2105 uint possibleX = (uint)Math.Floor(px);
2106 possibleX -= possibleX % Constants.RegionSize;
2107 uint possibleY = (uint)Math.Floor(py);
2108 possibleY -= possibleY % Constants.RegionSize;
2109 ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY);
2110 if (ret != null)
2111 {
2112 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
2113 LogHeader, possibleX, possibleY, ret.RegionName);
2114 }
2115
2116 if (ret == null)
2117 {
2118 // If the simple lookup failed, search the larger area for a region that contains this point
2119 double range = (double)Constants.RegionSize + 2;
2120 while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize))
2121 {
2122 // Get from the grid service a list of regions that might contain this point
2123 List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID,
2124 (int)(px - range), (int)(px + range),
2125 (int)(py - range), (int)(py + range));
2126 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
2127 LogHeader, possibleRegions.Count, range);
2128 if (possibleRegions != null && possibleRegions.Count > 0)
2129 {
2130 // If we found some regions, check to see if the point is within
2131 foreach (GridRegion gr in possibleRegions)
2132 {
2133 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>",
2134 LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY);
2135 if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
2136 && py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY))
2137 {
2138 // Found a region that contains the point
2139 ret = gr;
2140 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
2141 break;
2142 }
2143 }
2144 }
2145 // Larger search area for next time around if not found
2146 range *= 2;
2147 }
2148 }
2149 return ret;
2067 } 2150 }
2068 2151
2069 private void InformClientOfNeighbourCompleted(IAsyncResult iar) 2152 private void InformClientOfNeighbourCompleted(IAsyncResult iar)
@@ -2272,10 +2355,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2272 /// Move the given scene object into a new region depending on which region its absolute position has moved 2355 /// Move the given scene object into a new region depending on which region its absolute position has moved
2273 /// into. 2356 /// into.
2274 /// 2357 ///
2275 /// This method locates the new region handle and offsets the prim position for the new region 2358 /// Using the objects new world location, ask the grid service for a the new region and adjust the prim
2359 /// position to be relative to the new region.
2276 /// </summary> 2360 /// </summary>
2277 /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
2278 /// <param name="grp">the scene object that we're crossing</param> 2361 /// <param name="grp">the scene object that we're crossing</param>
2362 /// <param name="attemptedPosition">the attempted out of region position of the scene object. This position is
2363 /// relative to the region the object currently is in.</param>
2364 /// <param name="silent">if 'true', the deletion of the client from the region is not broadcast to the clients</param>
2279 public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent) 2365 public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
2280 { 2366 {
2281 if (grp == null) 2367 if (grp == null)
@@ -2301,6 +2387,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2301 return; 2387 return;
2302 } 2388 }
2303 2389
2390 /*
2304 int thisx = (int)scene.RegionInfo.LegacyRegionLocX; 2391 int thisx = (int)scene.RegionInfo.LegacyRegionLocX;
2305 int thisy = (int)scene.RegionInfo.LegacyRegionLocY; 2392 int thisy = (int)scene.RegionInfo.LegacyRegionLocY;
2306 Vector3 EastCross = new Vector3(0.1f, 0, 0); 2393 Vector3 EastCross = new Vector3(0.1f, 0, 0);
@@ -2309,10 +2396,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2309 Vector3 SouthCross = new Vector3(0, -0.1f, 0); 2396 Vector3 SouthCross = new Vector3(0, -0.1f, 0);
2310 2397
2311 2398
2312 // use this if no borders were crossed! 2399 // use this default if no borders were crossed (handle of the current region)
2313 ulong newRegionHandle 2400 ulong newRegionHandle = Util.RegionWorldLocToHandle(scene.RegionInfo.RegionWorldLocX, scene.RegionInfo.RegionWorldLocY);
2314 = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
2315 (uint)((thisy) * Constants.RegionSize));
2316 2401
2317 Vector3 pos = attemptedPosition; 2402 Vector3 pos = attemptedPosition;
2318 2403
@@ -2469,30 +2554,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2469 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize)); 2554 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
2470 // y + 1 2555 // y + 1
2471 } 2556 }
2557 */
2472 2558
2473 // Offset the positions for the new region across the border 2559 // Remember the old group position in case the region lookup fails so position can be restored.
2474 Vector3 oldGroupPosition = grp.RootPart.GroupPosition; 2560 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
2475 2561
2476 // If we fail to cross the border, then reset the position of the scene object on that border. 2562 // Compute the absolute position of the object.
2477 uint x = 0, y = 0; 2563 double objectWorldLocX = (double)scene.RegionInfo.RegionWorldLocX + attemptedPosition.X;
2478 Utils.LongToUInts(newRegionHandle, out x, out y); 2564 double objectWorldLocY = (double)scene.RegionInfo.RegionWorldLocY + attemptedPosition.Y;
2479 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 2565
2566 // Ask the grid service for the region that contains the passed address
2567 GridRegion destination = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, objectWorldLocX, objectWorldLocY);
2568
2569 Vector3 pos = Vector3.Zero;
2570 if (destination != null)
2571 {
2572 // Adjust the object's relative position from the old region (attemptedPosition)
2573 // to be relative to the new region (pos).
2574 pos = new Vector3( (float)(objectWorldLocX - (double)destination.RegionLocX),
2575 (float)(objectWorldLocY - (double)destination.RegionLocY),
2576 attemptedPosition.Z);
2577 }
2480 2578
2481 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2579 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2482 { 2580 {
2483 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 2581 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID);
2484 2582
2485 // We are going to move the object back to the old position so long as the old position 2583 // We are going to move the object back to the old position so long as the old position
2486 // is in the region 2584 // is in the region
2487 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 2585 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
2488 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 2586 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
2489 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f); 2587 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
2490 2588
2491 grp.RootPart.GroupPosition = oldGroupPosition; 2589 grp.RootPart.GroupPosition = oldGroupPosition;
2492 2590
2493 // Need to turn off the physics flags, otherwise the object will continue to attempt to 2591 // Need to turn off the physics flags, otherwise the object will continue to attempt to
2494 // move out of the region creating an infinite loop of failed attempts to cross 2592 // move out of the region creating an infinite loop of failed attempts to cross
2495 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false); 2593 grp.UpdatePrimFlags(grp.RootPart.LocalId, false, grp.IsTemporary, grp.IsPhantom, false);
2496 2594
2497 if (grp.RootPart.KeyframeMotion != null) 2595 if (grp.RootPart.KeyframeMotion != null)
2498 grp.RootPart.KeyframeMotion.CrossingFailure(); 2596 grp.RootPart.KeyframeMotion.CrossingFailure();
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
index 598351e..277293a 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
@@ -197,6 +197,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
197 // be the base coordinate of the region. 197 // be the base coordinate of the region.
198 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) 198 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
199 { 199 {
200 m_log.DebugFormat("{0} GetRegionByPosition. pos=<{1},{2}>", "[LOCAL GRID SERVICE CONNECTOR", x, y);
200 GridRegion region = null; 201 GridRegion region = null;
201 202
202 // First see if it's a neighbour, even if it isn't on this sim. 203 // 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
209 region = rcache.GetRegionByPosition(x, y); 210 region = rcache.GetRegionByPosition(x, y);
210 if (region != null) 211 if (region != null)
211 { 212 {
213 m_log.DebugFormat("{0} GetRegionByPosition. Found region {1}. Pos=<{2},{3}>",
214 "[LOCAL GRID SERVICE CONNECTOR", region.RegionName, x, y);
212 return region; 215 return region;
213 } 216 }
214 } 217 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 99c7079..be8aed1 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2483,6 +2483,23 @@ namespace OpenSim.Region.Framework.Scenes
2483 EntityTransferModule.Cross(grp, attemptedPosition, silent); 2483 EntityTransferModule.Cross(grp, attemptedPosition, silent);
2484 } 2484 }
2485 2485
2486 // Simple test to see if a position is in the current region.
2487 // Resuming the position is relative to the region so anything outside its bounds.
2488 // Return 'true' if position inside region.
2489 public bool PositionIsInCurrentRegion(Vector3 pos)
2490 {
2491 bool ret = true;
2492 int xx = (int)Math.Floor(pos.X);
2493 int yy = (int)Math.Floor(pos.Y);
2494 if (xx < 0
2495 || xx > RegionInfo.RegionSizeX
2496 || yy < 0
2497 || yy > RegionInfo.RegionSizeY)
2498 ret = false;
2499 return ret;
2500
2501 }
2502
2486 public Border GetCrossedBorder(Vector3 position, Cardinals gridline) 2503 public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
2487 { 2504 {
2488 if (BordersLocked) 2505 if (BordersLocked)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 2c64c85..e827229 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -3123,6 +3123,9 @@ namespace OpenSim.Region.Framework.Scenes
3123 int neighbor = 0; 3123 int neighbor = 0;
3124 int[] fix = new int[2]; 3124 int[] fix = new int[2];
3125 3125
3126 // Compute the avatar position in the next physics tick.
3127 // If the avatar will be crossing, we force the crossing to happen now
3128 // in the hope that this will make the avatar movement smoother when crossing.
3126 float timeStep = 0.1f; 3129 float timeStep = 0.1f;
3127 pos2.X = pos2.X + (vel.X * timeStep); 3130 pos2.X = pos2.X + (vel.X * timeStep);
3128 pos2.Y = pos2.Y + (vel.Y * timeStep); 3131 pos2.Y = pos2.Y + (vel.Y * timeStep);
@@ -3130,12 +3133,48 @@ namespace OpenSim.Region.Framework.Scenes
3130 3133
3131 if (!IsInTransit) 3134 if (!IsInTransit)
3132 { 3135 {
3133// m_log.DebugFormat( 3136 m_log.DebugFormat(
3134// "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}", 3137 "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}",
3135// pos2, Name, Scene.Name); 3138 pos2, Name, Scene.Name);
3139
3140 if (!m_scene.PositionIsInCurrentRegion(pos2))
3141 {
3142 // Disconnect from the current region
3143 bool isFlying = Flying;
3144 RemoveFromPhysicalScene();
3145 // pos2 is the forcasted position so make that the 'current' position so the crossing
3146 // code will move us into the newly addressed region.
3147 m_pos = pos2;
3148 if (CrossToNewRegion())
3149 {
3150 AddToPhysicalScene(isFlying);
3151 }
3152 else
3153 {
3154 // Tried to make crossing happen but it failed.
3155 if (m_requestedSitTargetUUID == UUID.Zero)
3156 {
3157
3158 Vector3 pos = AbsolutePosition;
3159 if (AbsolutePosition.X < 0)
3160 pos.X += Velocity.X * 2;
3161 else if (AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX)
3162 pos.X -= Velocity.X * 2;
3163 if (AbsolutePosition.Y < 0)
3164 pos.Y += Velocity.Y * 2;
3165 else if (AbsolutePosition.Y > m_scene.RegionInfo.RegionSizeY)
3166 pos.Y -= Velocity.Y * 2;
3167 Velocity = Vector3.Zero;
3168 AbsolutePosition = pos;
3169
3170 AddToPhysicalScene(isFlying);
3171 }
3172 }
3173
3174 }
3136 3175
3176 /*
3137 // Checks if where it's headed exists a region 3177 // Checks if where it's headed exists a region
3138 bool needsTransit = false;
3139 if (m_scene.TestBorderCross(pos2, Cardinals.W)) 3178 if (m_scene.TestBorderCross(pos2, Cardinals.W))
3140 { 3179 {
3141 if (m_scene.TestBorderCross(pos2, Cardinals.S)) 3180 if (m_scene.TestBorderCross(pos2, Cardinals.S))
@@ -3236,6 +3275,7 @@ namespace OpenSim.Region.Framework.Scenes
3236 } 3275 }
3237 } 3276 }
3238 } 3277 }
3278 */
3239 } 3279 }
3240 else 3280 else
3241 { 3281 {