diff options
Diffstat (limited to '')
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 | { |