aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework')
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs497
2 files changed, 171 insertions, 330 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 6545a99..13cc99a 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -269,9 +269,7 @@ namespace OpenSim.Region.CoreModules.Framework
269 foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID]) 269 foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID])
270 { 270 {
271 uint x, y; 271 uint x, y;
272 Utils.LongToUInts(kvp.Key, out x, out y); 272 Util.RegionHandleToRegionLoc(kvp.Key, out x, out y);
273 x = x / Constants.RegionSize;
274 y = y / Constants.RegionSize;
275 m_log.Info(" >> "+x+", "+y+": "+kvp.Value); 273 m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
276 } 274 }
277 } 275 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index ef5239a..4954cd9 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)))
@@ -489,9 +487,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
489 487
490 if (finalDestination == null) 488 if (finalDestination == null)
491 { 489 {
492 m_log.WarnFormat( 490 m_log.WarnFormat( "{0} Final destination is having problems. Unable to teleport {1} {2}",
493 "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}", 491 LogHeader, sp.Name, sp.UUID);
494 sp.Name, sp.UUID);
495 492
496 sp.ControllingClient.SendTeleportFailed("Problem at destination"); 493 sp.ControllingClient.SendTeleportFailed("Problem at destination");
497 return; 494 return;
@@ -532,11 +529,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
532 529
533 // and set the map-tile to '(Offline)' 530 // and set the map-tile to '(Offline)'
534 uint regX, regY; 531 uint regX, regY;
535 Utils.LongToUInts(regionHandle, out regX, out regY); 532 Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY);
536 533
537 MapBlockData block = new MapBlockData(); 534 MapBlockData block = new MapBlockData();
538 block.X = (ushort)(regX / Constants.RegionSize); 535 block.X = (ushort)Util.WorldToRegionLoc(regX);
539 block.Y = (ushort)(regY / Constants.RegionSize); 536 block.Y = (ushort)Util.WorldToRegionLoc(regY);
540 block.Access = 254; // == not there 537 block.Access = 254; // == not there
541 538
542 List<MapBlockData> blocks = new List<MapBlockData>(); 539 List<MapBlockData> blocks = new List<MapBlockData>();
@@ -1342,6 +1339,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1342 if (uinfo.HomeRegionID == UUID.Zero) 1339 if (uinfo.HomeRegionID == UUID.Zero)
1343 { 1340 {
1344 // can't find the Home region: Tell viewer and abort 1341 // can't find the Home region: Tell viewer and abort
1342 m_log.ErrorFormat("{0} No grid user info found for {1} {2}. Cannot send home.",
1343 LogHeader, client.Name, client.AgentId);
1345 client.SendTeleportFailed("You don't have a home position set."); 1344 client.SendTeleportFailed("You don't have a home position set.");
1346 return false; 1345 return false;
1347 } 1346 }
@@ -1375,7 +1374,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1375 1374
1376 #region Agent Crossings 1375 #region Agent Crossings
1377 1376
1378 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) 1377 // Given a position relative to the current region (which has previously been tested to
1378 // see that it is actually outside the current region), find the new region that the
1379 // point is actually in.
1380 // Returns the coordinates and information of the new region or 'null' of it doesn't exist.
1381 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos)
1379 { 1382 {
1380 version = String.Empty; 1383 version = String.Empty;
1381 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1384 newpos = new Vector3(pos.X, pos.Y, pos.Z);
@@ -1383,130 +1386,59 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1383// m_log.DebugFormat( 1386// m_log.DebugFormat(
1384// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1387// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1385 1388
1386 uint neighbourx = scene.RegionInfo.RegionLocX; 1389 // Compute world location of the object's position
1387 uint neighboury = scene.RegionInfo.RegionLocY; 1390 double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X;
1388 const float boundaryDistance = 1.7f; 1391 double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y;
1389 Vector3 northCross = new Vector3(0, boundaryDistance, 0); 1392
1390 Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0); 1393 // Call the grid service to lookup the region containing the new position.
1391 Vector3 eastCross = new Vector3(boundaryDistance, 0, 0); 1394 GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
1392 Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0); 1395 presenceWorldX, presenceWorldY);
1393 1396
1394 // distance into new region to place avatar 1397 if (neighbourRegion != null)
1395 const float enterDistance = 0.5f; 1398 {
1396 1399 // Compute the entity's position relative to the new region
1397 if (scene.TestBorderCross(pos + westCross, Cardinals.W)) 1400 newpos = new Vector3( (float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
1398 { 1401 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
1399 if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1402 pos.Z);
1400 { 1403
1401 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); 1404 // Check if banned from destination region.
1402 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); 1405 ExpiringCache<ulong, DateTime> r;
1406 DateTime banUntil;
1407 if (m_bannedRegions.TryGetValue(agentID, out r))
1408 {
1409 if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil))
1410 {
1411 if (DateTime.Now < banUntil)
1412 {
1413 // If we're banned from the destination, we just can't go there.
1414 neighbourRegion = null;
1415 }
1416 r.Remove(neighbourRegion.RegionHandle);
1417 }
1418 }
1419 else
1420 {
1421 r = null;
1403 } 1422 }
1404 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1405 {
1406 neighboury--;
1407 newpos.Y = Constants.RegionSize - enterDistance;
1408 }
1409
1410 neighbourx--;
1411 newpos.X = Constants.RegionSize - enterDistance;
1412 }
1413 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1414 {
1415 Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E);
1416 neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1417 newpos.X = enterDistance;
1418 1423
1419 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1424 // Check to see if we have access to the target region.
1425 string reason;
1426 if (neighbourRegion != null
1427 && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1420 { 1428 {
1421 neighboury--; 1429 if (r == null)
1422 newpos.Y = Constants.RegionSize - enterDistance; 1430 {
1423 } 1431 r = new ExpiringCache<ulong, DateTime>();
1424 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1432 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1425 {
1426 Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1427 neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
1428 newpos.Y = enterDistance;
1429 }
1430 }
1431 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1432 {
1433 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1434 neighboury--;
1435 newpos.Y = Constants.RegionSize - enterDistance;
1436 }
1437 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1438 {
1439 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1440 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1441 newpos.Y = enterDistance;
1442 }
1443
1444 /*
1445
1446 if (pos.X < boundaryDistance) //West
1447 {
1448 neighbourx--;
1449 newpos.X = Constants.RegionSize - enterDistance;
1450 }
1451 else if (pos.X > Constants.RegionSize - boundaryDistance) // East
1452 {
1453 neighbourx++;
1454 newpos.X = enterDistance;
1455 }
1456
1457 if (pos.Y < boundaryDistance) // South
1458 {
1459 neighboury--;
1460 newpos.Y = Constants.RegionSize - enterDistance;
1461 }
1462 else if (pos.Y > Constants.RegionSize - boundaryDistance) // North
1463 {
1464 neighboury++;
1465 newpos.Y = enterDistance;
1466 }
1467 */
1468
1469 xDest = neighbourx;
1470 yDest = neighboury;
1471
1472 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1473
1474 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
1475
1476 ExpiringCache<ulong, DateTime> r;
1477 DateTime banUntil;
1478
1479 if (m_bannedRegions.TryGetValue(agentID, out r))
1480 {
1481 if (r.TryGetValue(neighbourHandle, out banUntil))
1482 {
1483 if (DateTime.Now < banUntil)
1484 return null;
1485 r.Remove(neighbourHandle);
1486 }
1487 }
1488 else
1489 {
1490 r = null;
1491 }
1492
1493 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1494
1495 string reason;
1496 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1497 {
1498 if (r == null)
1499 {
1500 r = new ExpiringCache<ulong, DateTime>();
1501 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1502 1433
1503 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); 1434 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1504 } 1435 }
1505 else 1436 else
1506 { 1437 {
1507 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1438 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1508 } 1439 }
1509 return null; 1440 neighbourRegion = null;
1441 }
1510 } 1442 }
1511 1443
1512 return neighbourRegion; 1444 return neighbourRegion;
@@ -1519,7 +1451,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1519 Vector3 newpos; 1451 Vector3 newpos;
1520 string version; 1452 string version;
1521 1453
1522 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos); 1454 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out version, out newpos);
1523 if (neighbourRegion == null) 1455 if (neighbourRegion == null)
1524 { 1456 {
1525 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); 1457 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
@@ -2028,15 +1960,80 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2028 } 1960 }
2029 } 1961 }
2030 1962
1963 // Computes the difference between two region bases.
1964 // Returns a vector of world coordinates (meters) from base of first region to the second.
1965 // The first region is the home region of the passed scene presence.
2031 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) 1966 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour)
2032 { 1967 {
2033 int rRegionX = (int)sp.Scene.RegionInfo.RegionLocX; 1968 /*
2034 int rRegionY = (int)sp.Scene.RegionInfo.RegionLocY; 1969 int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX;
1970 int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY;
2035 int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize; 1971 int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize;
2036 int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize; 1972 int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize;
2037 int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize; 1973 int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize;
2038 int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize; 1974 int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize;
2039 return new Vector3(shiftx, shifty, 0f); 1975 return new Vector3(shiftx, shifty, 0f);
1976 */
1977 return new Vector3(sp.Scene.RegionInfo.RegionLocX - neighbour.RegionLocX,
1978 sp.Scene.RegionInfo.RegionLocY - neighbour.RegionLocY,
1979 0f);
1980 }
1981
1982 // Given a world position (fractional meter coordinate), get the GridRegion info for
1983 // the region containing that point.
1984 // Return 'null' if no such region exists.
1985 private GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
1986 {
1987 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py);
1988 GridRegion ret = null;
1989
1990 // As an optimization, since most regions will be legacy sized regions (256x256), first try to get
1991 // the region at the appropriate legacy region location.
1992 uint possibleX = (uint)Math.Floor(px);
1993 possibleX -= possibleX % Constants.RegionSize;
1994 uint possibleY = (uint)Math.Floor(py);
1995 possibleY -= possibleY % Constants.RegionSize;
1996 ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY);
1997 if (ret != null)
1998 {
1999 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
2000 LogHeader, possibleX, possibleY, ret.RegionName);
2001 }
2002
2003 if (ret == null)
2004 {
2005 // If the simple lookup failed, search the larger area for a region that contains this point
2006 double range = (double)Constants.RegionSize * 2 + 2;
2007 while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize))
2008 {
2009 // Get from the grid service a list of regions that might contain this point
2010 List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID,
2011 (int)(px - range), (int)(px + range),
2012 (int)(py - range), (int)(py + range));
2013 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
2014 LogHeader, possibleRegions.Count, range);
2015 if (possibleRegions != null && possibleRegions.Count > 0)
2016 {
2017 // If we found some regions, check to see if the point is within
2018 foreach (GridRegion gr in possibleRegions)
2019 {
2020 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>",
2021 LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY);
2022 if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
2023 && py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY))
2024 {
2025 // Found a region that contains the point
2026 ret = gr;
2027 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
2028 break;
2029 }
2030 }
2031 }
2032 // Larger search area for next time around if not found
2033 range *= 2;
2034 }
2035 }
2036 return ret;
2040 } 2037 }
2041 2038
2042 private void InformClientOfNeighbourCompleted(IAsyncResult iar) 2039 private void InformClientOfNeighbourCompleted(IAsyncResult iar)
@@ -2245,10 +2242,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2245 /// Move the given scene object into a new region depending on which region its absolute position has moved 2242 /// Move the given scene object into a new region depending on which region its absolute position has moved
2246 /// into. 2243 /// into.
2247 /// 2244 ///
2248 /// This method locates the new region handle and offsets the prim position for the new region 2245 /// Using the objects new world location, ask the grid service for a the new region and adjust the prim
2246 /// position to be relative to the new region.
2249 /// </summary> 2247 /// </summary>
2250 /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
2251 /// <param name="grp">the scene object that we're crossing</param> 2248 /// <param name="grp">the scene object that we're crossing</param>
2249 /// <param name="attemptedPosition">the attempted out of region position of the scene object. This position is
2250 /// relative to the region the object currently is in.</param>
2251 /// <param name="silent">if 'true', the deletion of the client from the region is not broadcast to the clients</param>
2252 public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent) 2252 public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
2253 { 2253 {
2254 if (grp == null) 2254 if (grp == null)
@@ -2274,208 +2274,51 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2274 return; 2274 return;
2275 } 2275 }
2276 2276
2277 int thisx = (int)scene.RegionInfo.RegionLocX; 2277 // Remember the old group position in case the region lookup fails so position can be restored.
2278 int thisy = (int)scene.RegionInfo.RegionLocY; 2278 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
2279 Vector3 EastCross = new Vector3(0.1f, 0, 0);
2280 Vector3 WestCross = new Vector3(-0.1f, 0, 0);
2281 Vector3 NorthCross = new Vector3(0, 0.1f, 0);
2282 Vector3 SouthCross = new Vector3(0, -0.1f, 0);
2283
2284
2285 // use this if no borders were crossed!
2286 ulong newRegionHandle
2287 = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
2288 (uint)((thisy) * Constants.RegionSize));
2289
2290 Vector3 pos = attemptedPosition;
2291
2292 int changeX = 1;
2293 int changeY = 1;
2294
2295 if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
2296 {
2297 if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
2298 {
2299
2300 Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2301
2302 if (crossedBorderx.BorderLine.Z > 0)
2303 {
2304 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2305 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2306 }
2307 else
2308 pos.X = ((pos.X + Constants.RegionSize));
2309
2310 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2311 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2312
2313 if (crossedBordery.BorderLine.Z > 0)
2314 {
2315 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2316 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2317 }
2318 else
2319 pos.Y = ((pos.Y + Constants.RegionSize));
2320
2321
2322
2323 newRegionHandle
2324 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
2325 (uint)((thisy - changeY) * Constants.RegionSize));
2326 // x - 1
2327 // y - 1
2328 }
2329 else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2330 {
2331 Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2332
2333 if (crossedBorderx.BorderLine.Z > 0)
2334 {
2335 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2336 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2337 }
2338 else
2339 pos.X = ((pos.X + Constants.RegionSize));
2340
2341
2342 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2343 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2344
2345 if (crossedBordery.BorderLine.Z > 0)
2346 {
2347 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2348 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2349 }
2350 else
2351 pos.Y = ((pos.Y + Constants.RegionSize));
2352 2279
2353 newRegionHandle 2280 // Compute the absolute position of the object.
2354 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), 2281 double objectWorldLocX = (double)scene.RegionInfo.WorldLocX + attemptedPosition.X;
2355 (uint)((thisy + changeY) * Constants.RegionSize)); 2282 double objectWorldLocY = (double)scene.RegionInfo.WorldLocY + attemptedPosition.Y;
2356 // x - 1
2357 // y + 1
2358 }
2359 else
2360 {
2361 Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2362 2283
2363 if (crossedBorderx.BorderLine.Z > 0) 2284 // Ask the grid service for the region that contains the passed address
2364 { 2285 GridRegion destination = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, objectWorldLocX, objectWorldLocY);
2365 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2366 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2367 }
2368 else
2369 pos.X = ((pos.X + Constants.RegionSize));
2370 2286
2371 newRegionHandle 2287 Vector3 pos = Vector3.Zero;
2372 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), 2288 if (destination != null)
2373 (uint)(thisy * Constants.RegionSize));
2374 // x - 1
2375 }
2376 }
2377 else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
2378 { 2289 {
2379 if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) 2290 // Adjust the object's relative position from the old region (attemptedPosition)
2380 { 2291 // to be relative to the new region (pos).
2381 2292 pos = new Vector3( (float)(objectWorldLocX - (double)destination.RegionLocX),
2382 pos.X = ((pos.X - Constants.RegionSize)); 2293 (float)(objectWorldLocY - (double)destination.RegionLocY),
2383 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); 2294 attemptedPosition.Z);
2384 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2385
2386 if (crossedBordery.BorderLine.Z > 0)
2387 {
2388 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2389 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2390 }
2391 else
2392 pos.Y = ((pos.Y + Constants.RegionSize));
2393
2394
2395 newRegionHandle
2396 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2397 (uint)((thisy - changeY) * Constants.RegionSize));
2398 // x + 1
2399 // y - 1
2400 }
2401 else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2402 {
2403 pos.X = ((pos.X - Constants.RegionSize));
2404 pos.Y = ((pos.Y - Constants.RegionSize));
2405 newRegionHandle
2406 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2407 (uint)((thisy + changeY) * Constants.RegionSize));
2408 // x + 1
2409 // y + 1
2410 }
2411 else
2412 {
2413 pos.X = ((pos.X - Constants.RegionSize));
2414 newRegionHandle
2415 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2416 (uint)(thisy * Constants.RegionSize));
2417 // x + 1
2418 }
2419 } 2295 }
2420 else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
2421 {
2422 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2423 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2424 2296
2425 if (crossedBordery.BorderLine.Z > 0) 2297 if (destination != null)
2298 {
2299 if (!CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2426 { 2300 {
2427 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); 2301 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID);
2428 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); 2302
2303 // We are going to move the object back to the old position so long as the old position
2304 // is in the region
2305 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
2306 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
2307 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
2308
2309 grp.AbsolutePosition = oldGroupPosition;
2310 grp.Velocity = Vector3.Zero;
2311 if (grp.RootPart.PhysActor != null)
2312 grp.RootPart.PhysActor.CrossingFailure();
2313
2314 if (grp.RootPart.KeyframeMotion != null)
2315 grp.RootPart.KeyframeMotion.CrossingFailure();
2316
2317 grp.ScheduleGroupForFullUpdate();
2429 } 2318 }
2430 else
2431 pos.Y = ((pos.Y + Constants.RegionSize));
2432
2433 newRegionHandle
2434 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
2435 // y - 1
2436 } 2319 }
2437 else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2438 {
2439
2440 pos.Y = ((pos.Y - Constants.RegionSize));
2441 newRegionHandle
2442 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
2443 // y + 1
2444 }
2445
2446 // Offset the positions for the new region across the border
2447 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
2448
2449 // If we fail to cross the border, then reset the position of the scene object on that border.
2450 uint x = 0, y = 0;
2451 Utils.LongToUInts(newRegionHandle, out x, out y);
2452 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
2453
2454 if (destination != null)
2455 {
2456 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2457 return; // we did it
2458 }
2459
2460 // no one or failed lets go back and tell physics to go on
2461 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
2462 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
2463 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
2464
2465 grp.AbsolutePosition = oldGroupPosition;
2466 grp.Velocity = Vector3.Zero;
2467
2468 if (grp.RootPart.PhysActor != null)
2469 grp.RootPart.PhysActor.CrossingFailure();
2470
2471 if (grp.RootPart.KeyframeMotion != null)
2472 grp.RootPart.KeyframeMotion.CrossingFailure();
2473
2474 grp.ScheduleGroupForFullUpdate();
2475 } 2320 }
2476 2321
2477
2478
2479 /// <summary> 2322 /// <summary>
2480 /// Move the given scene object into a new region 2323 /// Move the given scene object into a new region
2481 /// </summary> 2324 /// </summary>