diff options
Diffstat (limited to 'OpenSim')
9 files changed, 526 insertions, 1103 deletions
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index ae2ff63..90188d2 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs | |||
@@ -149,11 +149,32 @@ namespace OpenSim.Framework | |||
149 | public uint WorldLocX = 0; | 149 | public uint WorldLocX = 0; |
150 | public uint WorldLocY = 0; | 150 | public uint WorldLocY = 0; |
151 | public uint WorldLocZ = 0; | 151 | public uint WorldLocZ = 0; |
152 | |||
153 | /// <summary> | ||
154 | /// X dimension of the region. | ||
155 | /// </summary> | ||
156 | /// <remarks> | ||
157 | /// If this is a varregion then the default size set here will be replaced when we load the region config. | ||
158 | /// </remarks> | ||
152 | public uint RegionSizeX = Constants.RegionSize; | 159 | public uint RegionSizeX = Constants.RegionSize; |
160 | |||
161 | /// <summary> | ||
162 | /// X dimension of the region. | ||
163 | /// </summary> | ||
164 | /// <remarks> | ||
165 | /// If this is a varregion then the default size set here will be replaced when we load the region config. | ||
166 | /// </remarks> | ||
153 | public uint RegionSizeY = Constants.RegionSize; | 167 | public uint RegionSizeY = Constants.RegionSize; |
168 | |||
169 | /// <summary> | ||
170 | /// Z dimension of the region. | ||
171 | /// </summary> | ||
172 | /// <remarks> | ||
173 | /// XXX: Unknown if this accounts for regions with negative Z. | ||
174 | /// </remarks> | ||
154 | public uint RegionSizeZ = Constants.RegionHeight; | 175 | public uint RegionSizeZ = Constants.RegionHeight; |
155 | 176 | ||
156 | private Dictionary<String, String> m_otherSettings = new Dictionary<string, string>(); | 177 | private Dictionary<String, String> m_extraSettings = new Dictionary<string, string>(); |
157 | 178 | ||
158 | // Apparently, we're applying the same estatesettings regardless of whether it's local or remote. | 179 | // Apparently, we're applying the same estatesettings regardless of whether it's local or remote. |
159 | 180 | ||
@@ -506,16 +527,16 @@ namespace OpenSim.Framework | |||
506 | { | 527 | { |
507 | string val; | 528 | string val; |
508 | string keylower = key.ToLower(); | 529 | string keylower = key.ToLower(); |
509 | if (m_otherSettings.TryGetValue(keylower, out val)) | 530 | if (m_extraSettings.TryGetValue(keylower, out val)) |
510 | return val; | 531 | return val; |
511 | m_log.DebugFormat("[RegionInfo] Could not locate value for parameter {0}", key); | 532 | m_log.DebugFormat("[RegionInfo] Could not locate value for parameter {0}", key); |
512 | return null; | 533 | return null; |
513 | } | 534 | } |
514 | 535 | ||
515 | public void SetOtherSetting(string key, string value) | 536 | public void SetExtraSetting(string key, string value) |
516 | { | 537 | { |
517 | string keylower = key.ToLower(); | 538 | string keylower = key.ToLower(); |
518 | m_otherSettings[keylower] = value; | 539 | m_extraSettings[keylower] = value; |
519 | } | 540 | } |
520 | 541 | ||
521 | private void ReadNiniConfig(IConfigSource source, string name) | 542 | private void ReadNiniConfig(IConfigSource source, string name) |
@@ -733,7 +754,7 @@ namespace OpenSim.Framework | |||
733 | 754 | ||
734 | foreach (String s in allKeys) | 755 | foreach (String s in allKeys) |
735 | { | 756 | { |
736 | SetOtherSetting(s, config.GetString(s)); | 757 | SetExtraSetting(s, config.GetString(s)); |
737 | } | 758 | } |
738 | } | 759 | } |
739 | 760 | ||
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index b32a169..0f6c507 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -121,8 +121,53 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
121 | /// </summary> | 121 | /// </summary> |
122 | private EntityTransferStateMachine m_entityTransferStateMachine; | 122 | private EntityTransferStateMachine m_entityTransferStateMachine; |
123 | 123 | ||
124 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = | 124 | // For performance, we keed a cached of banned regions so we don't keep going |
125 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); | 125 | // to the grid service. |
126 | private class BannedRegionCache | ||
127 | { | ||
128 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = | ||
129 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); | ||
130 | ExpiringCache<ulong, DateTime> m_idCache; | ||
131 | DateTime m_banUntil; | ||
132 | public BannedRegionCache() | ||
133 | { | ||
134 | } | ||
135 | // Return 'true' if there is a valid ban entry for this agent in this region | ||
136 | public bool IfBanned(ulong pRegionHandle, UUID pAgentID) | ||
137 | { | ||
138 | bool ret = false; | ||
139 | if (m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) | ||
140 | { | ||
141 | if (m_idCache.TryGetValue(pRegionHandle, out m_banUntil)) | ||
142 | { | ||
143 | if (DateTime.Now < m_banUntil) | ||
144 | { | ||
145 | ret = true; | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | return ret; | ||
150 | } | ||
151 | // Add this agent in this region as a banned person | ||
152 | public void Add(ulong pRegionHandle, UUID pAgentID) | ||
153 | { | ||
154 | if (!m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) | ||
155 | { | ||
156 | m_idCache = new ExpiringCache<ulong, DateTime>(); | ||
157 | m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(45)); | ||
158 | } | ||
159 | m_idCache.Add(pRegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | ||
160 | } | ||
161 | // Remove the agent from the region's banned list | ||
162 | public void Remove(ulong pRegionHandle, UUID pAgentID) | ||
163 | { | ||
164 | if (m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) | ||
165 | { | ||
166 | m_idCache.Remove(pRegionHandle); | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | private BannedRegionCache m_bannedRegionCache = new BannedRegionCache(); | ||
126 | 171 | ||
127 | private IEventQueue m_eqModule; | 172 | private IEventQueue m_eqModule; |
128 | private IRegionCombinerModule m_regionCombinerModule; | 173 | private IRegionCombinerModule m_regionCombinerModule; |
@@ -337,6 +382,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
337 | "[ENTITY TRANSFER MODULE]: Received teleport cancel request from {0} in {1}", client.Name, Scene.Name); | 382 | "[ENTITY TRANSFER MODULE]: Received teleport cancel request from {0} in {1}", client.Name, Scene.Name); |
338 | } | 383 | } |
339 | 384 | ||
385 | // Attempt to teleport the ScenePresence to the specified position in the specified region (spec'ed by its handle). | ||
340 | public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) | 386 | public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) |
341 | { | 387 | { |
342 | if (sp.Scene.Permissions.IsGridGod(sp.UUID)) | 388 | if (sp.Scene.Permissions.IsGridGod(sp.UUID)) |
@@ -418,7 +464,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
418 | sp.Name, position, sp.Scene.RegionInfo.RegionName); | 464 | sp.Name, position, sp.Scene.RegionInfo.RegionName); |
419 | 465 | ||
420 | // Teleport within the same region | 466 | // Teleport within the same region |
421 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) | 467 | if (!sp.Scene.PositionIsInCurrentRegion(position) || position.Z < 0) |
422 | { | 468 | { |
423 | Vector3 emergencyPos = new Vector3(128, 128, 128); | 469 | Vector3 emergencyPos = new Vector3(128, 128, 128); |
424 | 470 | ||
@@ -437,10 +483,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
437 | float posZLimit = 22; | 483 | float posZLimit = 22; |
438 | 484 | ||
439 | // TODO: Check other Scene HeightField | 485 | // TODO: Check other Scene HeightField |
440 | if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) | 486 | posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; |
441 | { | ||
442 | posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; | ||
443 | } | ||
444 | 487 | ||
445 | posZLimit += localHalfAVHeight + 0.1f; | 488 | posZLimit += localHalfAVHeight + 0.1f; |
446 | 489 | ||
@@ -484,9 +527,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
484 | ScenePresence sp, ulong regionHandle, Vector3 position, | 527 | ScenePresence sp, ulong regionHandle, Vector3 position, |
485 | Vector3 lookAt, uint teleportFlags, out GridRegion finalDestination) | 528 | Vector3 lookAt, uint teleportFlags, out GridRegion finalDestination) |
486 | { | 529 | { |
487 | uint x = 0, y = 0; | 530 | // Get destination region taking into account that the address could be an offset |
488 | Utils.LongToUInts(regionHandle, out x, out y); | 531 | // region inside a varregion. |
489 | GridRegion reg = Scene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); | 532 | GridRegion reg = GetTeleportDestinationRegion(sp.Scene.GridService, sp.Scene.RegionInfo.ScopeID, regionHandle, ref position); |
490 | 533 | ||
491 | if (reg != null) | 534 | if (reg != null) |
492 | { | 535 | { |
@@ -537,12 +580,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
537 | 580 | ||
538 | // and set the map-tile to '(Offline)' | 581 | // and set the map-tile to '(Offline)' |
539 | uint regX, regY; | 582 | uint regX, regY; |
540 | Utils.LongToUInts(regionHandle, out regX, out regY); | 583 | Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY); |
541 | 584 | ||
542 | MapBlockData block = new MapBlockData(); | 585 | MapBlockData block = new MapBlockData(); |
543 | block.X = (ushort)(regX / Constants.RegionSize); | 586 | block.X = (ushort)(regX / Constants.RegionSize); |
544 | block.Y = (ushort)(regY / Constants.RegionSize); | 587 | block.Y = (ushort)(regY / Constants.RegionSize); |
545 | block.Access = 254; // == not there | 588 | block.Access = (byte)SimAccess.Down; // == not there |
546 | 589 | ||
547 | List<MapBlockData> blocks = new List<MapBlockData>(); | 590 | List<MapBlockData> blocks = new List<MapBlockData>(); |
548 | blocks.Add(block); | 591 | blocks.Add(block); |
@@ -550,6 +593,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
550 | } | 593 | } |
551 | } | 594 | } |
552 | 595 | ||
596 | // The teleport address could be an address in a subregion of a larger varregion. | ||
597 | // Find the real base region and adjust the teleport location to account for the | ||
598 | // larger region. | ||
599 | private GridRegion GetTeleportDestinationRegion(IGridService gridService, UUID scope, ulong regionHandle, ref Vector3 position) | ||
600 | { | ||
601 | uint x = 0, y = 0; | ||
602 | Util.RegionHandleToWorldLoc(regionHandle, out x, out y); | ||
603 | |||
604 | // Compute the world location we're teleporting to | ||
605 | double worldX = (double)x + position.X; | ||
606 | double worldY = (double)y + position.Y; | ||
607 | |||
608 | // Find the region that contains the position | ||
609 | GridRegion reg = GetRegionContainingWorldLocation(gridService, scope, worldX, worldY); | ||
610 | |||
611 | if (reg != null) | ||
612 | { | ||
613 | // modify the position for the offset into the actual region returned | ||
614 | position.X += x - reg.RegionLocX; | ||
615 | position.Y += y - reg.RegionLocY; | ||
616 | } | ||
617 | |||
618 | return reg; | ||
619 | } | ||
620 | |||
553 | // Nothing to validate here | 621 | // Nothing to validate here |
554 | protected virtual bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) | 622 | protected virtual bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) |
555 | { | 623 | { |
@@ -650,10 +718,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
650 | return; | 718 | return; |
651 | } | 719 | } |
652 | 720 | ||
653 | uint newRegionX = (uint)(reg.RegionHandle >> 40); | 721 | uint newRegionX, newRegionY, oldRegionX, oldRegionY; |
654 | uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); | 722 | Util.RegionHandleToRegionLoc(reg.RegionHandle, out newRegionX, out newRegionY); |
655 | uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); | 723 | Util.RegionHandleToRegionLoc(sp.Scene.RegionInfo.RegionHandle, out oldRegionX, out oldRegionY); |
656 | uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); | ||
657 | 724 | ||
658 | ulong destinationHandle = finalDestination.RegionHandle; | 725 | ulong destinationHandle = finalDestination.RegionHandle; |
659 | 726 | ||
@@ -675,8 +742,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
675 | 742 | ||
676 | string reason; | 743 | string reason; |
677 | string version; | 744 | string version; |
745 | string myversion = string.Format("{0}/{1}", OutgoingTransferVersionName, MaxOutgoingTransferVersion); | ||
678 | if (!Scene.SimulationService.QueryAccess( | 746 | if (!Scene.SimulationService.QueryAccess( |
679 | finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) | 747 | finalDestination, sp.ControllingClient.AgentId, position, out version, out reason)) |
680 | { | 748 | { |
681 | sp.ControllingClient.SendTeleportFailed(reason); | 749 | sp.ControllingClient.SendTeleportFailed(reason); |
682 | 750 | ||
@@ -1274,6 +1342,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1274 | return region; | 1342 | return region; |
1275 | } | 1343 | } |
1276 | 1344 | ||
1345 | // This returns 'true' if the new region already has a child agent for our | ||
1346 | // incoming agent. The implication is that, if 'false', we have to create the | ||
1347 | // child and then teleport into the region. | ||
1277 | protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) | 1348 | protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) |
1278 | { | 1349 | { |
1279 | if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) | 1350 | if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) |
@@ -1298,20 +1369,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1298 | return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); | 1369 | return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); |
1299 | } | 1370 | } |
1300 | 1371 | ||
1301 | protected virtual bool IsOutsideRegion(Scene s, Vector3 pos) | ||
1302 | { | ||
1303 | if (s.TestBorderCross(pos, Cardinals.N)) | ||
1304 | return true; | ||
1305 | if (s.TestBorderCross(pos, Cardinals.S)) | ||
1306 | return true; | ||
1307 | if (s.TestBorderCross(pos, Cardinals.E)) | ||
1308 | return true; | ||
1309 | if (s.TestBorderCross(pos, Cardinals.W)) | ||
1310 | return true; | ||
1311 | |||
1312 | return false; | ||
1313 | } | ||
1314 | |||
1315 | #endregion | 1372 | #endregion |
1316 | 1373 | ||
1317 | #region Landmark Teleport | 1374 | #region Landmark Teleport |
@@ -1390,214 +1447,80 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1390 | 1447 | ||
1391 | #region Agent Crossings | 1448 | #region Agent Crossings |
1392 | 1449 | ||
1393 | public bool checkAgentAccessToRegion(ScenePresence agent, GridRegion destiny, Vector3 position, out string version, out string reason) | ||
1394 | { | ||
1395 | reason = String.Empty; | ||
1396 | version = String.Empty; | ||
1397 | |||
1398 | UUID agentID = agent.UUID; | ||
1399 | ulong destinyHandle = destiny.RegionHandle; | ||
1400 | |||
1401 | ExpiringCache<ulong, DateTime> r; | ||
1402 | DateTime banUntil; | ||
1403 | if (m_bannedRegions.TryGetValue(agentID, out r)) | ||
1404 | { | ||
1405 | if (r.TryGetValue(destinyHandle, out banUntil)) | ||
1406 | { | ||
1407 | if (DateTime.Now < banUntil) | ||
1408 | { | ||
1409 | reason = "Cannot connect to region"; | ||
1410 | return false; | ||
1411 | } | ||
1412 | r.Remove(destinyHandle); | ||
1413 | } | ||
1414 | } | ||
1415 | else | ||
1416 | { | ||
1417 | r = null; | ||
1418 | } | ||
1419 | |||
1420 | Scene ascene = agent.Scene; | ||
1421 | |||
1422 | if (!ascene.SimulationService.QueryAccess(destiny, agentID, position, out version, out reason)) | ||
1423 | { | ||
1424 | if (r == null) | ||
1425 | { | ||
1426 | r = new ExpiringCache<ulong, DateTime>(); | ||
1427 | r.Add(destinyHandle, DateTime.Now + TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30)); | ||
1428 | |||
1429 | m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(30)); | ||
1430 | } | ||
1431 | else | ||
1432 | { | ||
1433 | r.Add(destinyHandle, DateTime.Now + TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30)); | ||
1434 | } | ||
1435 | return false; | ||
1436 | } | ||
1437 | return true; | ||
1438 | } | ||
1439 | |||
1440 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos) | 1450 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos) |
1441 | { | 1451 | { |
1442 | string r = String.Empty; | 1452 | string r = String.Empty; |
1443 | return GetDestination(scene, agentID, pos, out version, out newpos, out r); | 1453 | return GetDestination(scene, agentID, pos, out version, out newpos, out r); |
1444 | } | 1454 | } |
1445 | 1455 | ||
1446 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos, out string reason) | 1456 | // Given a position relative to the current region (which has previously been tested to |
1457 | // see that it is actually outside the current region), find the new region that the | ||
1458 | // point is actually in. | ||
1459 | // Returns the coordinates and information of the new region or 'null' of it doesn't exist. | ||
1460 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, | ||
1461 | out string version, out Vector3 newpos, out string failureReason) | ||
1447 | { | 1462 | { |
1448 | version = String.Empty; | 1463 | version = String.Empty; |
1449 | reason = String.Empty; | ||
1450 | newpos = pos; | 1464 | newpos = pos; |
1465 | failureReason = string.Empty; | ||
1451 | 1466 | ||
1452 | // m_log.DebugFormat( | 1467 | // m_log.DebugFormat( |
1453 | // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); | 1468 | // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); |
1454 | 1469 | ||
1455 | RegionInfo regInfo = scene.RegionInfo; | 1470 | // Compute world location of the object's position |
1471 | double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X; | ||
1472 | double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y; | ||
1456 | 1473 | ||
1457 | uint neighbourx = regInfo.RegionLocX; | 1474 | // Call the grid service to lookup the region containing the new position. |
1458 | uint neighboury = regInfo.RegionLocY; | 1475 | GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, |
1459 | const float boundaryDistance = 0.7f; | 1476 | presenceWorldX, presenceWorldY, |
1460 | 1477 | Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY)); | |
1461 | /* | ||
1462 | Vector3 northCross = new Vector3(0, boundaryDistance, 0); | ||
1463 | Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0); | ||
1464 | Vector3 eastCross = new Vector3(boundaryDistance, 0, 0); | ||
1465 | Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0); | ||
1466 | 1478 | ||
1467 | // distance into new region to place avatar | 1479 | if (neighbourRegion != null) |
1468 | const float enterDistance = 0.5f; | ||
1469 | const float maxX = Constants.RegionSize - enterDistance; | ||
1470 | const float maxY = Constants.RegionSize - enterDistance; | ||
1471 | |||
1472 | if (scene.TestBorderCross(pos + westCross, Cardinals.W)) | ||
1473 | { | 1480 | { |
1474 | if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | 1481 | // Compute the entity's position relative to the new region |
1475 | { | 1482 | newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX), |
1476 | Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); | 1483 | (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), |
1477 | neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); | 1484 | pos.Z); |
1478 | newpos.Y -= Constants.RegionSize; | ||
1479 | } | ||
1480 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | ||
1481 | { | ||
1482 | neighboury--; | ||
1483 | newpos.Y += Constants.RegionSize; | ||
1484 | } | ||
1485 | |||
1486 | neighbourx--; | ||
1487 | newpos.X += Constants.RegionSize; | ||
1488 | } | ||
1489 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) | ||
1490 | { | ||
1491 | Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E); | ||
1492 | neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); | ||
1493 | newpos.X -= Constants.RegionSize; | ||
1494 | 1485 | ||
1495 | if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 1486 | if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) |
1496 | { | 1487 | { |
1497 | neighboury--; | 1488 | failureReason = "Cannot region cross into banned parcel"; |
1498 | newpos.Y += Constants.RegionSize; | 1489 | neighbourRegion = null; |
1499 | } | 1490 | } |
1500 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | 1491 | else |
1501 | { | 1492 | { |
1502 | Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N); | 1493 | // If not banned, make sure this agent is not in the list. |
1503 | neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); | 1494 | m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID); |
1504 | newpos.Y -= Constants.RegionSize; | ||
1505 | } | 1495 | } |
1506 | } | ||
1507 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | ||
1508 | { | ||
1509 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | ||
1510 | neighboury--; | ||
1511 | newpos.Y += Constants.RegionSize; | ||
1512 | } | ||
1513 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | ||
1514 | { | ||
1515 | Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); | ||
1516 | neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); | ||
1517 | newpos.Y -= Constants.RegionSize; | ||
1518 | } | ||
1519 | 1496 | ||
1520 | newpos.X = Util.Clamp(newpos.X, enterDistance, maxX); | 1497 | // Check to see if we have access to the target region. |
1521 | newpos.Y = Util.Clamp(newpos.Y, enterDistance, maxY); | 1498 | string myversion = string.Format("{0}/{1}", OutgoingTransferVersionName, MaxOutgoingTransferVersion); |
1522 | */ | 1499 | if (neighbourRegion != null |
1523 | float regionSizeX = regInfo.RegionSizeX; | 1500 | && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out failureReason)) |
1524 | float regionSizeY = regInfo.RegionSizeY; | ||
1525 | |||
1526 | if (pos.X < boundaryDistance) | ||
1527 | neighbourx--; | ||
1528 | else if (pos.X > regionSizeX - boundaryDistance) | ||
1529 | neighbourx += (uint)(regionSizeX / Constants.RegionSize); | ||
1530 | |||
1531 | if (pos.Y < boundaryDistance) | ||
1532 | neighboury--; | ||
1533 | else if (pos.Y > regionSizeY - boundaryDistance) | ||
1534 | neighboury += (uint)(regionSizeY / Constants.RegionSize); | ||
1535 | |||
1536 | int x = (int)(neighbourx * Constants.RegionSize); | ||
1537 | int y = (int)(neighboury * Constants.RegionSize); | ||
1538 | |||
1539 | ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y); | ||
1540 | |||
1541 | ExpiringCache<ulong, DateTime> r; | ||
1542 | DateTime banUntil; | ||
1543 | |||
1544 | if (m_bannedRegions.TryGetValue(agentID, out r)) | ||
1545 | { | ||
1546 | if (r.TryGetValue(neighbourHandle, out banUntil)) | ||
1547 | { | 1501 | { |
1548 | if (DateTime.Now < banUntil) | 1502 | // remember banned |
1549 | return null; | 1503 | m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); |
1550 | r.Remove(neighbourHandle); | 1504 | neighbourRegion = null; |
1551 | } | 1505 | } |
1552 | } | 1506 | } |
1553 | else | 1507 | else |
1554 | { | 1508 | { |
1555 | r = null; | 1509 | // The destination region just doesn't exist |
1510 | failureReason = "Cannot cross into non-existent region"; | ||
1556 | } | 1511 | } |
1557 | 1512 | ||
1558 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); | ||
1559 | if (neighbourRegion == null) | 1513 | if (neighbourRegion == null) |
1560 | { | 1514 | m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}", |
1561 | reason = ""; | 1515 | LogHeader, scene.RegionInfo.RegionName, |
1562 | return null; | 1516 | scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, |
1563 | } | 1517 | scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, |
1564 | 1518 | pos); | |
1565 | float newRegionSizeX = neighbourRegion.RegionSizeX; | 1519 | else |
1566 | float newRegionSizeY = neighbourRegion.RegionSizeY; | 1520 | m_log.DebugFormat("{0} GetDestination: new region={1} at <{2},{3}> of size <{4},{5}>, newpos=<{6},{7}>", |
1567 | if (newRegionSizeX == 0) | 1521 | LogHeader, neighbourRegion.RegionName, |
1568 | newRegionSizeX = Constants.RegionSize; | 1522 | neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY, |
1569 | if (newRegionSizeY == 0) | 1523 | newpos.X, newpos.Y); |
1570 | newRegionSizeY = Constants.RegionSize; | ||
1571 | |||
1572 | if (pos.X < boundaryDistance) | ||
1573 | newpos.X += newRegionSizeX; | ||
1574 | else if (pos.X > regionSizeX - boundaryDistance) | ||
1575 | newpos.X -= regionSizeX; | ||
1576 | |||
1577 | if (pos.Y < boundaryDistance) | ||
1578 | newpos.Y += newRegionSizeY; | ||
1579 | else if (pos.Y > regionSizeY - boundaryDistance) | ||
1580 | newpos.Y -= regionSizeY; | ||
1581 | |||
1582 | const float enterDistance = 0.5f; | ||
1583 | newpos.X = Util.Clamp(newpos.X, enterDistance, newRegionSizeX - enterDistance); | ||
1584 | newpos.Y = Util.Clamp(newpos.Y, enterDistance, newRegionSizeY - enterDistance); | ||
1585 | |||
1586 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) | ||
1587 | { | ||
1588 | if (r == null) | ||
1589 | { | ||
1590 | r = new ExpiringCache<ulong, DateTime>(); | ||
1591 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | ||
1592 | |||
1593 | m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); | ||
1594 | } | ||
1595 | else | ||
1596 | { | ||
1597 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | ||
1598 | } | ||
1599 | return null; | ||
1600 | } | ||
1601 | 1524 | ||
1602 | return neighbourRegion; | 1525 | return neighbourRegion; |
1603 | } | 1526 | } |
@@ -1632,15 +1555,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1632 | uint y; | 1555 | uint y; |
1633 | Vector3 newpos; | 1556 | Vector3 newpos; |
1634 | string version; | 1557 | string version; |
1635 | string reason; | 1558 | string failureReason; |
1636 | 1559 | ||
1637 | Vector3 pos = agent.AbsolutePosition + agent.Velocity; | 1560 | Vector3 pos = agent.AbsolutePosition + agent.Velocity; |
1638 | 1561 | ||
1639 | GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos, out version, out newpos, out reason); | 1562 | GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos, |
1563 | out version, out newpos, out failureReason); | ||
1640 | if (neighbourRegion == null) | 1564 | if (neighbourRegion == null) |
1641 | { | 1565 | { |
1642 | if (reason != String.Empty) | 1566 | if (failureReason != String.Empty) |
1643 | agent.ControllingClient.SendAlertMessage("Cannot cross to region"); | 1567 | agent.ControllingClient.SendAlertMessage(failureReason); |
1644 | return agent; | 1568 | return agent; |
1645 | } | 1569 | } |
1646 | 1570 | ||
@@ -1678,7 +1602,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1678 | 1602 | ||
1679 | agent.Scene.RequestTeleportLocation( | 1603 | agent.Scene.RequestTeleportLocation( |
1680 | agent.ControllingClient, | 1604 | agent.ControllingClient, |
1681 | Utils.UIntsToLong(regionX * (uint)Constants.RegionSize, regionY * (uint)Constants.RegionSize), | 1605 | Util.RegionLocToHandle(regionX, regionY), |
1682 | position, | 1606 | position, |
1683 | agent.Lookat, | 1607 | agent.Lookat, |
1684 | (uint)Constants.TeleportFlags.ViaLocation); | 1608 | (uint)Constants.TeleportFlags.ViaLocation); |
@@ -1688,11 +1612,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1688 | if (im != null) | 1612 | if (im != null) |
1689 | { | 1613 | { |
1690 | UUID gotoLocation = Util.BuildFakeParcelID( | 1614 | UUID gotoLocation = Util.BuildFakeParcelID( |
1691 | Util.UIntsToLong( | 1615 | Util.RegionLocToHandle(regionX, regionY), |
1692 | (regionX * | ||
1693 | (uint)Constants.RegionSize), | ||
1694 | (regionY * | ||
1695 | (uint)Constants.RegionSize)), | ||
1696 | (uint)(int)position.X, | 1616 | (uint)(int)position.X, |
1697 | (uint)(int)position.Y, | 1617 | (uint)(int)position.Y, |
1698 | (uint)(int)position.Z); | 1618 | (uint)(int)position.Z); |
@@ -1745,8 +1665,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1745 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 1665 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
1746 | /// </summary> | 1666 | /// </summary> |
1747 | public ScenePresence CrossAgentToNewRegionAsync( | 1667 | public ScenePresence CrossAgentToNewRegionAsync( |
1748 | ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, | 1668 | ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, |
1749 | bool isFlying, string version) | 1669 | bool isFlying, string version) |
1750 | { | 1670 | { |
1751 | if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) | 1671 | if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) |
1752 | { | 1672 | { |
@@ -1893,11 +1813,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1893 | // Next, let's close the child agent connections that are too far away. | 1813 | // Next, let's close the child agent connections that are too far away. |
1894 | uint neighbourx; | 1814 | uint neighbourx; |
1895 | uint neighboury; | 1815 | uint neighboury; |
1896 | 1816 | Util.RegionHandleToRegionLoc(neighbourRegion.RegionHandle, out neighbourx, out neighboury); | |
1897 | Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury); | ||
1898 | |||
1899 | neighbourx /= Constants.RegionSize; | ||
1900 | neighboury /= Constants.RegionSize; | ||
1901 | 1817 | ||
1902 | agent.CloseChildAgents(neighbourx, neighboury); | 1818 | agent.CloseChildAgents(neighbourx, neighboury); |
1903 | 1819 | ||
@@ -2059,7 +1975,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2059 | 1975 | ||
2060 | if (m_regionInfo != null) | 1976 | if (m_regionInfo != null) |
2061 | { | 1977 | { |
2062 | neighbours = RequestNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); | 1978 | neighbours = GetNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); |
2063 | } | 1979 | } |
2064 | else | 1980 | else |
2065 | { | 1981 | { |
@@ -2216,15 +2132,195 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2216 | } | 2132 | } |
2217 | } | 2133 | } |
2218 | 2134 | ||
2135 | // Computes the difference between two region bases. | ||
2136 | // Returns a vector of world coordinates (meters) from base of first region to the second. | ||
2137 | // The first region is the home region of the passed scene presence. | ||
2219 | Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) | 2138 | Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) |
2220 | { | 2139 | { |
2221 | int rRegionX = (int)sp.Scene.RegionInfo.RegionLocX; | 2140 | /* |
2222 | int rRegionY = (int)sp.Scene.RegionInfo.RegionLocY; | 2141 | int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX; |
2142 | int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY; | ||
2223 | int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize; | 2143 | int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize; |
2224 | int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize; | 2144 | int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize; |
2225 | int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize; | 2145 | int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize; |
2226 | int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize; | 2146 | int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize; |
2227 | return new Vector3(shiftx, shifty, 0f); | 2147 | return new Vector3(shiftx, shifty, 0f); |
2148 | */ | ||
2149 | return new Vector3( sp.Scene.RegionInfo.WorldLocX - neighbour.RegionLocX, | ||
2150 | sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY, | ||
2151 | 0f); | ||
2152 | } | ||
2153 | |||
2154 | public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py) | ||
2155 | { | ||
2156 | // Since we don't know how big the regions could be, we have to search a very large area | ||
2157 | // to find possible regions. | ||
2158 | return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize); | ||
2159 | } | ||
2160 | |||
2161 | #region NotFoundLocationCache class | ||
2162 | // A collection of not found locations to make future lookups 'not found' lookups quick. | ||
2163 | // A simple expiring cache that keeps not found locations for some number of seconds. | ||
2164 | // A 'not found' location is presumed to be anywhere in the minimum sized region that | ||
2165 | // contains that point. A conservitive estimate. | ||
2166 | private class NotFoundLocationCache | ||
2167 | { | ||
2168 | private struct NotFoundLocation | ||
2169 | { | ||
2170 | public double minX, maxX, minY, maxY; | ||
2171 | public DateTime expireTime; | ||
2172 | } | ||
2173 | private List<NotFoundLocation> m_notFoundLocations = new List<NotFoundLocation>(); | ||
2174 | public NotFoundLocationCache() | ||
2175 | { | ||
2176 | } | ||
2177 | // Add an area to the list of 'not found' places. The area is the snapped region | ||
2178 | // area around the added point. | ||
2179 | public void Add(double pX, double pY) | ||
2180 | { | ||
2181 | lock (m_notFoundLocations) | ||
2182 | { | ||
2183 | if (!LockedContains(pX, pY)) | ||
2184 | { | ||
2185 | NotFoundLocation nfl = new NotFoundLocation(); | ||
2186 | // A not found location is not found for at least a whole region sized area | ||
2187 | nfl.minX = pX - (pX % (double)Constants.RegionSize); | ||
2188 | nfl.minY = pY - (pY % (double)Constants.RegionSize); | ||
2189 | nfl.maxX = nfl.minX + (double)Constants.RegionSize; | ||
2190 | nfl.maxY = nfl.minY + (double)Constants.RegionSize; | ||
2191 | nfl.expireTime = DateTime.Now + TimeSpan.FromSeconds(30); | ||
2192 | m_notFoundLocations.Add(nfl); | ||
2193 | } | ||
2194 | } | ||
2195 | |||
2196 | } | ||
2197 | // Test to see of this point is in any of the 'not found' areas. | ||
2198 | // Return 'true' if the point is found inside the 'not found' areas. | ||
2199 | public bool Contains(double pX, double pY) | ||
2200 | { | ||
2201 | bool ret = false; | ||
2202 | lock (m_notFoundLocations) | ||
2203 | ret = LockedContains(pX, pY); | ||
2204 | return ret; | ||
2205 | } | ||
2206 | private bool LockedContains(double pX, double pY) | ||
2207 | { | ||
2208 | bool ret = false; | ||
2209 | this.DoExpiration(); | ||
2210 | foreach (NotFoundLocation nfl in m_notFoundLocations) | ||
2211 | { | ||
2212 | if (pX >= nfl.minX && pX < nfl.maxX && pY >= nfl.minY && pY < nfl.maxY) | ||
2213 | { | ||
2214 | ret = true; | ||
2215 | break; | ||
2216 | } | ||
2217 | } | ||
2218 | return ret; | ||
2219 | } | ||
2220 | private void DoExpiration() | ||
2221 | { | ||
2222 | List<NotFoundLocation> m_toRemove = null; | ||
2223 | DateTime now = DateTime.Now; | ||
2224 | foreach (NotFoundLocation nfl in m_notFoundLocations) | ||
2225 | { | ||
2226 | if (nfl.expireTime < now) | ||
2227 | { | ||
2228 | if (m_toRemove == null) | ||
2229 | m_toRemove = new List<NotFoundLocation>(); | ||
2230 | m_toRemove.Add(nfl); | ||
2231 | } | ||
2232 | } | ||
2233 | if (m_toRemove != null) | ||
2234 | { | ||
2235 | foreach (NotFoundLocation nfl in m_toRemove) | ||
2236 | m_notFoundLocations.Remove(nfl); | ||
2237 | m_toRemove.Clear(); | ||
2238 | } | ||
2239 | } | ||
2240 | } | ||
2241 | #endregion // NotFoundLocationCache class | ||
2242 | private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache(); | ||
2243 | |||
2244 | // Given a world position (fractional meter coordinate), get the GridRegion info for | ||
2245 | // the region containing that point. | ||
2246 | // Someday this should be a method on GridService. | ||
2247 | // 'pSizeHint' is the size of the source region but since the destination point can be anywhere | ||
2248 | // the size of the target region is unknown thus the search area might have to be very large. | ||
2249 | // Return 'null' if no such region exists. | ||
2250 | public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, | ||
2251 | double px, double py, uint pSizeHint) | ||
2252 | { | ||
2253 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py); | ||
2254 | GridRegion ret = null; | ||
2255 | const double fudge = 2.0; | ||
2256 | |||
2257 | // One problem with this routine is negative results. That is, this can be called lots of times | ||
2258 | // for regions that don't exist. m_notFoundLocationCache remembers 'not found' results so they | ||
2259 | // will be quick 'not found's next time. | ||
2260 | // NotFoundLocationCache is an expiring cache so it will eventually forget about 'not found' and | ||
2261 | // thus re-ask the GridService about the location. | ||
2262 | if (m_notFoundLocationCache.Contains(px, py)) | ||
2263 | { | ||
2264 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py); | ||
2265 | return null; | ||
2266 | } | ||
2267 | |||
2268 | // As an optimization, since most regions will be legacy sized regions (256x256), first try to get | ||
2269 | // the region at the appropriate legacy region location. | ||
2270 | uint possibleX = (uint)Math.Floor(px); | ||
2271 | possibleX -= possibleX % Constants.RegionSize; | ||
2272 | uint possibleY = (uint)Math.Floor(py); | ||
2273 | possibleY -= possibleY % Constants.RegionSize; | ||
2274 | ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY); | ||
2275 | if (ret != null) | ||
2276 | { | ||
2277 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}", | ||
2278 | LogHeader, possibleX, possibleY, ret.RegionName); | ||
2279 | } | ||
2280 | |||
2281 | if (ret == null) | ||
2282 | { | ||
2283 | // If the simple lookup failed, search the larger area for a region that contains this point | ||
2284 | double range = (double)pSizeHint + fudge; | ||
2285 | while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize)) | ||
2286 | { | ||
2287 | // Get from the grid service a list of regions that might contain this point. | ||
2288 | // The region origin will be in the zero direction so only subtract the range. | ||
2289 | List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID, | ||
2290 | (int)(px - range), (int)(px), | ||
2291 | (int)(py - range), (int)(py)); | ||
2292 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}", | ||
2293 | LogHeader, possibleRegions.Count, range); | ||
2294 | if (possibleRegions != null && possibleRegions.Count > 0) | ||
2295 | { | ||
2296 | // If we found some regions, check to see if the point is within | ||
2297 | foreach (GridRegion gr in possibleRegions) | ||
2298 | { | ||
2299 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>", | ||
2300 | LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY); | ||
2301 | if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX) | ||
2302 | && py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY)) | ||
2303 | { | ||
2304 | // Found a region that contains the point | ||
2305 | ret = gr; | ||
2306 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName); | ||
2307 | break; | ||
2308 | } | ||
2309 | } | ||
2310 | } | ||
2311 | // Larger search area for next time around if not found | ||
2312 | range *= 2; | ||
2313 | } | ||
2314 | } | ||
2315 | |||
2316 | if (ret == null) | ||
2317 | { | ||
2318 | // remember this location was not found so we can quickly not find it next time | ||
2319 | m_notFoundLocationCache.Add(px, py); | ||
2320 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py); | ||
2321 | } | ||
2322 | |||
2323 | return ret; | ||
2228 | } | 2324 | } |
2229 | 2325 | ||
2230 | private void InformClientOfNeighbourCompleted(IAsyncResult iar) | 2326 | private void InformClientOfNeighbourCompleted(IAsyncResult iar) |
@@ -2310,22 +2406,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2310 | /// <param name='neCorner'></param> | 2406 | /// <param name='neCorner'></param> |
2311 | private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner) | 2407 | private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner) |
2312 | { | 2408 | { |
2313 | Border[] northBorders = Scene.NorthBorders.ToArray(); | ||
2314 | Border[] eastBorders = Scene.EastBorders.ToArray(); | ||
2315 | |||
2316 | Vector2 extent = Vector2.Zero; | 2409 | Vector2 extent = Vector2.Zero; |
2317 | for (int i = 0; i < eastBorders.Length; i++) | 2410 | |
2318 | { | 2411 | if (m_regionCombinerModule != null) |
2319 | extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X; | ||
2320 | } | ||
2321 | for (int i = 0; i < northBorders.Length; i++) | ||
2322 | { | 2412 | { |
2323 | extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; | 2413 | Vector2 megaRegionSize = m_regionCombinerModule.GetSizeOfMegaregion(Scene.RegionInfo.RegionID); |
2414 | extent.X = (float)Util.WorldToRegionLoc((uint)megaRegionSize.X); | ||
2415 | extent.Y = (float)Util.WorldToRegionLoc((uint)megaRegionSize.Y); | ||
2324 | } | 2416 | } |
2325 | 2417 | ||
2326 | // Loss of fraction on purpose | ||
2327 | extent.X = ((int)extent.X / (int)Constants.RegionSize); | ||
2328 | extent.Y = ((int)extent.Y / (int)Constants.RegionSize); | ||
2329 | 2418 | ||
2330 | swCorner.X = Scene.RegionInfo.RegionLocX - 1; | 2419 | swCorner.X = Scene.RegionInfo.RegionLocX - 1; |
2331 | swCorner.Y = Scene.RegionInfo.RegionLocY - 1; | 2420 | swCorner.Y = Scene.RegionInfo.RegionLocY - 1; |
@@ -2340,56 +2429,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2340 | /// <param name="pRegionLocX"></param> | 2429 | /// <param name="pRegionLocX"></param> |
2341 | /// <param name="pRegionLocY"></param> | 2430 | /// <param name="pRegionLocY"></param> |
2342 | /// <returns></returns> | 2431 | /// <returns></returns> |
2343 | protected List<GridRegion> RequestNeighbours(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY) | 2432 | protected List<GridRegion> GetNeighbours(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY) |
2344 | { | 2433 | { |
2345 | Scene pScene = avatar.Scene; | 2434 | Scene pScene = avatar.Scene; |
2346 | RegionInfo m_regionInfo = pScene.RegionInfo; | 2435 | RegionInfo m_regionInfo = pScene.RegionInfo; |
2436 | List<GridRegion> neighbours; | ||
2347 | 2437 | ||
2348 | // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't | 2438 | // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't |
2349 | // clear what should be done with a "far view" given that megaregions already extended the | 2439 | // clear what should be done with a "far view" given that megaregions already extended the |
2350 | // view to include everything in the megaregion | 2440 | // view to include everything in the megaregion |
2351 | if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) | 2441 | if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) |
2352 | { | 2442 | { |
2353 | int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance; | 2443 | // The area to check is as big as the current region. |
2444 | // We presume all adjacent regions are the same size as this region. | ||
2445 | uint dd = Math.Max((uint)avatar.Scene.DefaultDrawDistance, | ||
2446 | Math.Max(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY)); | ||
2354 | 2447 | ||
2355 | dd--; | 2448 | uint startX = Util.RegionToWorldLoc(pRegionLocX) - dd + Constants.RegionSize/2; |
2449 | uint startY = Util.RegionToWorldLoc(pRegionLocY) - dd + Constants.RegionSize/2; | ||
2356 | 2450 | ||
2357 | // region center | 2451 | uint endX = Util.RegionToWorldLoc(pRegionLocX) + dd + Constants.RegionSize/2; |
2358 | int endX = (int)pRegionLocX * (int)Constants.RegionSize + (int)(Constants.RegionSize / 2); | 2452 | uint endY = Util.RegionToWorldLoc(pRegionLocY) + dd + Constants.RegionSize/2; |
2359 | int endY = (int)pRegionLocY * (int)Constants.RegionSize + (int)(Constants.RegionSize / 2); | ||
2360 | |||
2361 | int startX = endX - dd; | ||
2362 | int startY = endY - dd; | ||
2363 | |||
2364 | endX += dd; | ||
2365 | endY += dd; | ||
2366 | 2453 | ||
2367 | if (startX < 0) startX = 0; | 2454 | neighbours |
2368 | if (startY < 0) startY = 0; | 2455 | = avatar.Scene.GridService.GetRegionRange( |
2456 | m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY); | ||
2369 | 2457 | ||
2370 | List<GridRegion> neighbours = | ||
2371 | avatar.Scene.GridService.GetRegionRange(m_regionInfo.ScopeID, startX, endX, startY, endY); | ||
2372 | |||
2373 | neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); | ||
2374 | return neighbours; | ||
2375 | } | 2458 | } |
2376 | else | 2459 | else |
2377 | { | 2460 | { |
2378 | Vector2 swCorner, neCorner; | 2461 | Vector2 swCorner, neCorner; |
2379 | GetMegaregionViewRange(out swCorner, out neCorner); | 2462 | GetMegaregionViewRange(out swCorner, out neCorner); |
2380 | 2463 | ||
2381 | List<GridRegion> neighbours | 2464 | neighbours |
2382 | = pScene.GridService.GetRegionRange( | 2465 | = pScene.GridService.GetRegionRange( |
2383 | m_regionInfo.ScopeID, | 2466 | m_regionInfo.ScopeID, |
2384 | (int)swCorner.X * (int)Constants.RegionSize, | 2467 | (int)Util.RegionToWorldLoc((uint)swCorner.X), (int)Util.RegionToWorldLoc((uint)neCorner.X), |
2385 | (int)neCorner.X * (int)Constants.RegionSize, | 2468 | (int)Util.RegionToWorldLoc((uint)swCorner.Y), (int)Util.RegionToWorldLoc((uint)neCorner.Y)); |
2386 | (int)swCorner.Y * (int)Constants.RegionSize, | 2469 | } |
2387 | (int)neCorner.Y * (int)Constants.RegionSize); | ||
2388 | 2470 | ||
2389 | neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); | 2471 | // The r.RegionFlags == null check only needs to be made for simulators before 2015-01-14 (pre 0.8.1). |
2472 | neighbours.RemoveAll( r => r.RegionID == m_regionInfo.RegionID ); | ||
2390 | 2473 | ||
2391 | return neighbours; | 2474 | return neighbours; |
2392 | } | ||
2393 | } | 2475 | } |
2394 | /* not in use | 2476 | /* not in use |
2395 | private List<ulong> NewNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours) | 2477 | private List<ulong> NewNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours) |
@@ -2509,8 +2591,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2509 | /// | 2591 | /// |
2510 | /// This method locates the new region handle and offsets the prim position for the new region | 2592 | /// This method locates the new region handle and offsets the prim position for the new region |
2511 | /// </summary> | 2593 | /// </summary> |
2512 | /// <param name="attemptedPosition">the attempted out of region position of the scene object</param> | ||
2513 | /// <param name="grp">the scene object that we're crossing</param> | 2594 | /// <param name="grp">the scene object that we're crossing</param> |
2595 | /// <param name="attemptedPosition">the attempted out of region position of the scene object. This position is | ||
2596 | /// relative to the region the object currently is in.</param> | ||
2597 | /// <param name="silent">if 'true', the deletion of the client from the region is not broadcast to the clients</param> | ||
2514 | public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent) | 2598 | public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent) |
2515 | { | 2599 | { |
2516 | if (grp == null) | 2600 | if (grp == null) |
@@ -2522,209 +2606,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2522 | if (scene == null) | 2606 | if (scene == null) |
2523 | return; | 2607 | return; |
2524 | 2608 | ||
2609 | // Remember the old group position in case the region lookup fails so position can be restored. | ||
2610 | Vector3 oldGroupPosition = grp.RootPart.GroupPosition; | ||
2525 | 2611 | ||
2526 | int thisx = (int)scene.RegionInfo.RegionLocX; | 2612 | // Compute the absolute position of the object. |
2527 | int thisy = (int)scene.RegionInfo.RegionLocY; | 2613 | double objectWorldLocX = (double)scene.RegionInfo.WorldLocX + attemptedPosition.X; |
2528 | Vector3 EastCross = new Vector3(0.1f, 0, 0); | 2614 | double objectWorldLocY = (double)scene.RegionInfo.WorldLocY + attemptedPosition.Y; |
2529 | Vector3 WestCross = new Vector3(-0.1f, 0, 0); | ||
2530 | Vector3 NorthCross = new Vector3(0, 0.1f, 0); | ||
2531 | Vector3 SouthCross = new Vector3(0, -0.1f, 0); | ||
2532 | |||
2533 | |||
2534 | // use this if no borders were crossed! | ||
2535 | ulong newRegionHandle | ||
2536 | = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize), | ||
2537 | (uint)((thisy) * Constants.RegionSize)); | ||
2538 | |||
2539 | Vector3 pos = attemptedPosition; | ||
2540 | |||
2541 | int changeX = 1; | ||
2542 | int changeY = 1; | ||
2543 | |||
2544 | if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W)) | ||
2545 | { | ||
2546 | if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) | ||
2547 | { | ||
2548 | |||
2549 | Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); | ||
2550 | |||
2551 | if (crossedBorderx.BorderLine.Z > 0) | ||
2552 | { | ||
2553 | pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); | ||
2554 | changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); | ||
2555 | } | ||
2556 | else | ||
2557 | pos.X = ((pos.X + Constants.RegionSize)); | ||
2558 | |||
2559 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
2560 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
2561 | |||
2562 | if (crossedBordery.BorderLine.Z > 0) | ||
2563 | { | ||
2564 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
2565 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
2566 | } | ||
2567 | else | ||
2568 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
2569 | |||
2570 | |||
2571 | |||
2572 | newRegionHandle | ||
2573 | = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), | ||
2574 | (uint)((thisy - changeY) * Constants.RegionSize)); | ||
2575 | // x - 1 | ||
2576 | // y - 1 | ||
2577 | } | ||
2578 | else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) | ||
2579 | { | ||
2580 | Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); | ||
2581 | |||
2582 | if (crossedBorderx.BorderLine.Z > 0) | ||
2583 | { | ||
2584 | pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); | ||
2585 | changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); | ||
2586 | } | ||
2587 | else | ||
2588 | pos.X = ((pos.X + Constants.RegionSize)); | ||
2589 | |||
2590 | |||
2591 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
2592 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
2593 | |||
2594 | if (crossedBordery.BorderLine.Z > 0) | ||
2595 | { | ||
2596 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
2597 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
2598 | } | ||
2599 | else | ||
2600 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
2601 | |||
2602 | newRegionHandle | ||
2603 | = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), | ||
2604 | (uint)((thisy + changeY) * Constants.RegionSize)); | ||
2605 | // x - 1 | ||
2606 | // y + 1 | ||
2607 | } | ||
2608 | else | ||
2609 | { | ||
2610 | Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); | ||
2611 | 2615 | ||
2612 | if (crossedBorderx.BorderLine.Z > 0) | 2616 | // Ask the grid service for the region that contains the passed address |
2613 | { | 2617 | GridRegion destination = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, |
2614 | pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); | 2618 | objectWorldLocX, objectWorldLocY); |
2615 | changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); | ||
2616 | } | ||
2617 | else | ||
2618 | pos.X = ((pos.X + Constants.RegionSize)); | ||
2619 | 2619 | ||
2620 | newRegionHandle | 2620 | Vector3 pos = Vector3.Zero; |
2621 | = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), | 2621 | if (destination != null) |
2622 | (uint)(thisy * Constants.RegionSize)); | ||
2623 | // x - 1 | ||
2624 | } | ||
2625 | } | ||
2626 | else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E)) | ||
2627 | { | 2622 | { |
2628 | if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) | 2623 | // Adjust the object's relative position from the old region (attemptedPosition) |
2629 | { | 2624 | // to be relative to the new region (pos). |
2630 | 2625 | pos = new Vector3( (float)(objectWorldLocX - (double)destination.RegionLocX), | |
2631 | pos.X = ((pos.X - Constants.RegionSize)); | 2626 | (float)(objectWorldLocY - (double)destination.RegionLocY), |
2632 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | 2627 | attemptedPosition.Z); |
2633 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
2634 | |||
2635 | if (crossedBordery.BorderLine.Z > 0) | ||
2636 | { | ||
2637 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
2638 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
2639 | } | ||
2640 | else | ||
2641 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
2642 | |||
2643 | |||
2644 | newRegionHandle | ||
2645 | = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), | ||
2646 | (uint)((thisy - changeY) * Constants.RegionSize)); | ||
2647 | // x + 1 | ||
2648 | // y - 1 | ||
2649 | } | ||
2650 | else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) | ||
2651 | { | ||
2652 | pos.X = ((pos.X - Constants.RegionSize)); | ||
2653 | pos.Y = ((pos.Y - Constants.RegionSize)); | ||
2654 | newRegionHandle | ||
2655 | = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), | ||
2656 | (uint)((thisy + changeY) * Constants.RegionSize)); | ||
2657 | // x + 1 | ||
2658 | // y + 1 | ||
2659 | } | ||
2660 | else | ||
2661 | { | ||
2662 | pos.X = ((pos.X - Constants.RegionSize)); | ||
2663 | newRegionHandle | ||
2664 | = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), | ||
2665 | (uint)(thisy * Constants.RegionSize)); | ||
2666 | // x + 1 | ||
2667 | } | ||
2668 | } | 2628 | } |
2669 | else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) | ||
2670 | { | ||
2671 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
2672 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
2673 | 2629 | ||
2674 | if (crossedBordery.BorderLine.Z > 0) | 2630 | if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) |
2675 | { | ||
2676 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
2677 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
2678 | } | ||
2679 | else | ||
2680 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
2681 | |||
2682 | newRegionHandle | ||
2683 | = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize)); | ||
2684 | // y - 1 | ||
2685 | } | ||
2686 | else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) | ||
2687 | { | 2631 | { |
2632 | m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID); | ||
2688 | 2633 | ||
2689 | pos.Y = ((pos.Y - Constants.RegionSize)); | 2634 | // We are going to move the object back to the old position so long as the old position |
2690 | newRegionHandle | 2635 | // is in the region |
2691 | = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize)); | 2636 | oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1)); |
2692 | // y + 1 | 2637 | oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1)); |
2693 | } | 2638 | oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight); |
2694 | 2639 | ||
2695 | // Offset the positions for the new region across the border | 2640 | grp.AbsolutePosition = oldGroupPosition; |
2696 | Vector3 oldGroupPosition = grp.RootPart.GroupPosition; | 2641 | grp.Velocity = Vector3.Zero; |
2642 | if (grp.RootPart.PhysActor != null) | ||
2643 | grp.RootPart.PhysActor.CrossingFailure(); | ||
2697 | 2644 | ||
2698 | // If we fail to cross the border, then reset the position of the scene object on that border. | 2645 | if (grp.RootPart.KeyframeMotion != null) |
2699 | uint x = 0, y = 0; | 2646 | grp.RootPart.KeyframeMotion.CrossingFailure(); |
2700 | Utils.LongToUInts(newRegionHandle, out x, out y); | ||
2701 | GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); | ||
2702 | 2647 | ||
2703 | if (destination != null) | 2648 | grp.ScheduleGroupForFullUpdate(); |
2704 | { | ||
2705 | if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) | ||
2706 | return; // we did it | ||
2707 | } | 2649 | } |
2708 | |||
2709 | // no one or failed lets go back and tell physics to go on | ||
2710 | oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f); | ||
2711 | oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f); | ||
2712 | // oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f); | ||
2713 | |||
2714 | grp.AbsolutePosition = oldGroupPosition; | ||
2715 | grp.Velocity = Vector3.Zero; | ||
2716 | |||
2717 | if (grp.RootPart.PhysActor != null) | ||
2718 | grp.RootPart.PhysActor.CrossingFailure(); | ||
2719 | |||
2720 | if (grp.RootPart.KeyframeMotion != null) | ||
2721 | grp.RootPart.KeyframeMotion.CrossingFailure(); | ||
2722 | |||
2723 | grp.ScheduleGroupForFullUpdate(); | ||
2724 | } | 2650 | } |
2725 | 2651 | ||
2726 | |||
2727 | |||
2728 | /// <summary> | 2652 | /// <summary> |
2729 | /// Move the given scene object into a new region | 2653 | /// Move the given scene object into a new region |
2730 | /// </summary> | 2654 | /// </summary> |
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs index e03ac5a..c6f531e 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs | |||
@@ -55,5 +55,10 @@ namespace OpenSim.Region.Framework.Interfaces | |||
55 | /// Currently, will throw an exception if this does not match a root region. | 55 | /// Currently, will throw an exception if this does not match a root region. |
56 | /// </param> | 56 | /// </param> |
57 | Vector2 GetSizeOfMegaregion(UUID regionId); | 57 | Vector2 GetSizeOfMegaregion(UUID regionId); |
58 | |||
59 | /// <summary> | ||
60 | /// Tests to see of position (relative to the region) is within the megaregion | ||
61 | /// </summary> | ||
62 | bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy); | ||
58 | } | 63 | } |
59 | } \ No newline at end of file | 64 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index eb34f55..03270d7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -160,11 +160,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
160 | /// </summary> | 160 | /// </summary> |
161 | public SimStatsReporter StatsReporter { get; private set; } | 161 | public SimStatsReporter StatsReporter { get; private set; } |
162 | 162 | ||
163 | public List<Border> NorthBorders = new List<Border>(); | ||
164 | public List<Border> EastBorders = new List<Border>(); | ||
165 | public List<Border> SouthBorders = new List<Border>(); | ||
166 | public List<Border> WestBorders = new List<Border>(); | ||
167 | |||
168 | /// <summary> | 163 | /// <summary> |
169 | /// Controls whether physics can be applied to prims. Even if false, prims still have entries in a | 164 | /// Controls whether physics can be applied to prims. Even if false, prims still have entries in a |
170 | /// PhysicsScene in order to perform collision detection | 165 | /// PhysicsScene in order to perform collision detection |
@@ -364,7 +359,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
364 | 359 | ||
365 | // TODO: Possibly stop other classes being able to manipulate this directly. | 360 | // TODO: Possibly stop other classes being able to manipulate this directly. |
366 | private SceneGraph m_sceneGraph; | 361 | private SceneGraph m_sceneGraph; |
367 | private volatile int m_bordersLocked; | ||
368 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing | 362 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing |
369 | private volatile bool m_backingup; | 363 | private volatile bool m_backingup; |
370 | private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); | 364 | private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); |
@@ -446,18 +440,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
446 | set { m_splitRegionID = value; } | 440 | set { m_splitRegionID = value; } |
447 | } | 441 | } |
448 | 442 | ||
449 | public bool BordersLocked | ||
450 | { | ||
451 | get { return m_bordersLocked == 1; } | ||
452 | set | ||
453 | { | ||
454 | if (value == true) | ||
455 | m_bordersLocked = 1; | ||
456 | else | ||
457 | m_bordersLocked = 0; | ||
458 | } | ||
459 | } | ||
460 | |||
461 | public new float TimeDilation | 443 | public new float TimeDilation |
462 | { | 444 | { |
463 | get { return m_sceneGraph.PhysicsScene.TimeDilation; } | 445 | get { return m_sceneGraph.PhysicsScene.TimeDilation; } |
@@ -1075,28 +1057,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1075 | PeriodicBackup = true; | 1057 | PeriodicBackup = true; |
1076 | UseBackup = true; | 1058 | UseBackup = true; |
1077 | 1059 | ||
1078 | BordersLocked = true; | ||
1079 | Border northBorder = new Border(); | ||
1080 | northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, RegionInfo.RegionSizeY); //<--- | ||
1081 | northBorder.CrossDirection = Cardinals.N; | ||
1082 | NorthBorders.Add(northBorder); | ||
1083 | |||
1084 | Border southBorder = new Border(); | ||
1085 | southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //---> | ||
1086 | southBorder.CrossDirection = Cardinals.S; | ||
1087 | SouthBorders.Add(southBorder); | ||
1088 | |||
1089 | Border eastBorder = new Border(); | ||
1090 | eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, RegionInfo.RegionSizeX); //<--- | ||
1091 | eastBorder.CrossDirection = Cardinals.E; | ||
1092 | EastBorders.Add(eastBorder); | ||
1093 | |||
1094 | Border westBorder = new Border(); | ||
1095 | westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //---> | ||
1096 | westBorder.CrossDirection = Cardinals.W; | ||
1097 | WestBorders.Add(westBorder); | ||
1098 | BordersLocked = false; | ||
1099 | |||
1100 | m_eventManager = new EventManager(); | 1060 | m_eventManager = new EventManager(); |
1101 | 1061 | ||
1102 | m_permissions = new ScenePermissions(this); | 1062 | m_permissions = new ScenePermissions(this); |
@@ -2611,185 +2571,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
2611 | EntityTransferModule.Cross(grp, attemptedPosition, silent); | 2571 | EntityTransferModule.Cross(grp, attemptedPosition, silent); |
2612 | } | 2572 | } |
2613 | 2573 | ||
2614 | public Border GetCrossedBorder(Vector3 position, Cardinals gridline) | 2574 | // Simple test to see if a position is in the current region. |
2575 | // This test is mostly used to see if a region crossing is necessary. | ||
2576 | // Assuming the position is relative to the region so anything outside its bounds. | ||
2577 | // Return 'true' if position inside region. | ||
2578 | public bool PositionIsInCurrentRegion(Vector3 pos) | ||
2615 | { | 2579 | { |
2616 | if (BordersLocked) | 2580 | bool ret = false; |
2617 | { | 2581 | int xx = (int)Math.Floor(pos.X); |
2618 | switch (gridline) | 2582 | int yy = (int)Math.Floor(pos.Y); |
2619 | { | 2583 | if (xx < 0 || yy < 0) |
2620 | case Cardinals.N: | 2584 | return false; |
2621 | lock (NorthBorders) | ||
2622 | { | ||
2623 | foreach (Border b in NorthBorders) | ||
2624 | { | ||
2625 | if (b.TestCross(position)) | ||
2626 | return b; | ||
2627 | } | ||
2628 | } | ||
2629 | break; | ||
2630 | case Cardinals.S: | ||
2631 | lock (SouthBorders) | ||
2632 | { | ||
2633 | foreach (Border b in SouthBorders) | ||
2634 | { | ||
2635 | if (b.TestCross(position)) | ||
2636 | return b; | ||
2637 | } | ||
2638 | } | ||
2639 | |||
2640 | break; | ||
2641 | case Cardinals.E: | ||
2642 | lock (EastBorders) | ||
2643 | { | ||
2644 | foreach (Border b in EastBorders) | ||
2645 | { | ||
2646 | if (b.TestCross(position)) | ||
2647 | return b; | ||
2648 | } | ||
2649 | } | ||
2650 | |||
2651 | break; | ||
2652 | case Cardinals.W: | ||
2653 | |||
2654 | lock (WestBorders) | ||
2655 | { | ||
2656 | foreach (Border b in WestBorders) | ||
2657 | { | ||
2658 | if (b.TestCross(position)) | ||
2659 | return b; | ||
2660 | } | ||
2661 | } | ||
2662 | break; | ||
2663 | 2585 | ||
2664 | } | 2586 | IRegionCombinerModule regionCombinerModule = RequestModuleInterface<IRegionCombinerModule>(); |
2587 | if (regionCombinerModule == null) | ||
2588 | { | ||
2589 | // Regular region. Just check for region size | ||
2590 | if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY ) | ||
2591 | ret = true; | ||
2665 | } | 2592 | } |
2666 | else | 2593 | else |
2667 | { | 2594 | { |
2668 | switch (gridline) | 2595 | // We're in a mega-region so see if we are still in that larger region |
2669 | { | 2596 | ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy); |
2670 | case Cardinals.N: | ||
2671 | foreach (Border b in NorthBorders) | ||
2672 | { | ||
2673 | if (b.TestCross(position)) | ||
2674 | return b; | ||
2675 | } | ||
2676 | |||
2677 | break; | ||
2678 | case Cardinals.S: | ||
2679 | foreach (Border b in SouthBorders) | ||
2680 | { | ||
2681 | if (b.TestCross(position)) | ||
2682 | return b; | ||
2683 | } | ||
2684 | break; | ||
2685 | case Cardinals.E: | ||
2686 | foreach (Border b in EastBorders) | ||
2687 | { | ||
2688 | if (b.TestCross(position)) | ||
2689 | return b; | ||
2690 | } | ||
2691 | |||
2692 | break; | ||
2693 | case Cardinals.W: | ||
2694 | foreach (Border b in WestBorders) | ||
2695 | { | ||
2696 | if (b.TestCross(position)) | ||
2697 | return b; | ||
2698 | } | ||
2699 | break; | ||
2700 | |||
2701 | } | ||
2702 | } | 2597 | } |
2703 | 2598 | ||
2704 | return null; | 2599 | return ret; |
2705 | } | ||
2706 | 2600 | ||
2707 | public bool TestBorderCross(Vector3 position, Cardinals border) | ||
2708 | { | ||
2709 | if (BordersLocked) | ||
2710 | { | ||
2711 | switch (border) | ||
2712 | { | ||
2713 | case Cardinals.N: | ||
2714 | lock (NorthBorders) | ||
2715 | { | ||
2716 | foreach (Border b in NorthBorders) | ||
2717 | { | ||
2718 | if (b.TestCross(position)) | ||
2719 | return true; | ||
2720 | } | ||
2721 | } | ||
2722 | break; | ||
2723 | case Cardinals.E: | ||
2724 | lock (EastBorders) | ||
2725 | { | ||
2726 | foreach (Border b in EastBorders) | ||
2727 | { | ||
2728 | if (b.TestCross(position)) | ||
2729 | return true; | ||
2730 | } | ||
2731 | } | ||
2732 | break; | ||
2733 | case Cardinals.S: | ||
2734 | lock (SouthBorders) | ||
2735 | { | ||
2736 | foreach (Border b in SouthBorders) | ||
2737 | { | ||
2738 | if (b.TestCross(position)) | ||
2739 | return true; | ||
2740 | } | ||
2741 | } | ||
2742 | break; | ||
2743 | case Cardinals.W: | ||
2744 | lock (WestBorders) | ||
2745 | { | ||
2746 | foreach (Border b in WestBorders) | ||
2747 | { | ||
2748 | if (b.TestCross(position)) | ||
2749 | return true; | ||
2750 | } | ||
2751 | } | ||
2752 | break; | ||
2753 | } | ||
2754 | } | ||
2755 | else | ||
2756 | { | ||
2757 | switch (border) | ||
2758 | { | ||
2759 | case Cardinals.N: | ||
2760 | foreach (Border b in NorthBorders) | ||
2761 | { | ||
2762 | if (b.TestCross(position)) | ||
2763 | return true; | ||
2764 | } | ||
2765 | break; | ||
2766 | case Cardinals.E: | ||
2767 | foreach (Border b in EastBorders) | ||
2768 | { | ||
2769 | if (b.TestCross(position)) | ||
2770 | return true; | ||
2771 | } | ||
2772 | break; | ||
2773 | case Cardinals.S: | ||
2774 | foreach (Border b in SouthBorders) | ||
2775 | { | ||
2776 | if (b.TestCross(position)) | ||
2777 | return true; | ||
2778 | } | ||
2779 | break; | ||
2780 | case Cardinals.W: | ||
2781 | foreach (Border b in WestBorders) | ||
2782 | { | ||
2783 | if (b.TestCross(position)) | ||
2784 | return true; | ||
2785 | } | ||
2786 | break; | ||
2787 | } | ||
2788 | } | ||
2789 | return false; | ||
2790 | } | 2601 | } |
2791 | 2602 | ||
2792 | |||
2793 | /// <summary> | 2603 | /// <summary> |
2794 | /// Called when objects or attachments cross the border, or teleport, between regions. | 2604 | /// Called when objects or attachments cross the border, or teleport, between regions. |
2795 | /// </summary> | 2605 | /// </summary> |
@@ -4116,60 +3926,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
4116 | { | 3926 | { |
4117 | // CleanDroppedAttachments(); | 3927 | // CleanDroppedAttachments(); |
4118 | 3928 | ||
4119 | if (TestBorderCross(acd.startpos, Cardinals.E)) | 3929 | // Make sure avatar position is in the region (why it wouldn't be is a mystery but do sanity checking) |
4120 | { | 3930 | if (acd.startpos.X < 0) acd.startpos.X = 1f; |
4121 | Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E); | 3931 | if (acd.startpos.X >= RegionInfo.RegionSizeX) acd.startpos.X = RegionInfo.RegionSizeX - 1f; |
4122 | acd.startpos.X = crossedBorder.BorderLine.Z - 1; | 3932 | if (acd.startpos.Y < 0) acd.startpos.Y = 1f; |
4123 | } | 3933 | if (acd.startpos.Y >= RegionInfo.RegionSizeY) acd.startpos.Y = RegionInfo.RegionSizeY - 1f; |
4124 | |||
4125 | if (TestBorderCross(acd.startpos, Cardinals.N)) | ||
4126 | { | ||
4127 | Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N); | ||
4128 | acd.startpos.Y = crossedBorder.BorderLine.Z - 1; | ||
4129 | } | ||
4130 | |||
4131 | //Mitigate http://opensimulator.org/mantis/view.php?id=3522 | ||
4132 | // Check if start position is outside of region | ||
4133 | // If it is, check the Z start position also.. if not, leave it alone. | ||
4134 | if (BordersLocked) | ||
4135 | { | ||
4136 | lock (EastBorders) | ||
4137 | { | ||
4138 | if (acd.startpos.X > EastBorders[0].BorderLine.Z) | ||
4139 | { | ||
4140 | m_log.Warn("FIX AGENT POSITION"); | ||
4141 | acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; | ||
4142 | if (acd.startpos.Z > 720) | ||
4143 | acd.startpos.Z = 720; | ||
4144 | } | ||
4145 | } | ||
4146 | lock (NorthBorders) | ||
4147 | { | ||
4148 | if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) | ||
4149 | { | ||
4150 | m_log.Warn("FIX Agent POSITION"); | ||
4151 | acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; | ||
4152 | if (acd.startpos.Z > 720) | ||
4153 | acd.startpos.Z = 720; | ||
4154 | } | ||
4155 | } | ||
4156 | } else | ||
4157 | { | ||
4158 | if (acd.startpos.X > EastBorders[0].BorderLine.Z) | ||
4159 | { | ||
4160 | m_log.Warn("FIX AGENT POSITION"); | ||
4161 | acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; | ||
4162 | if (acd.startpos.Z > 720) | ||
4163 | acd.startpos.Z = 720; | ||
4164 | } | ||
4165 | if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) | ||
4166 | { | ||
4167 | m_log.Warn("FIX Agent POSITION"); | ||
4168 | acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; | ||
4169 | if (acd.startpos.Z > 720) | ||
4170 | acd.startpos.Z = 720; | ||
4171 | } | ||
4172 | } | ||
4173 | 3934 | ||
4174 | // m_log.DebugFormat( | 3935 | // m_log.DebugFormat( |
4175 | // "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", | 3936 | // "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", |
@@ -4883,44 +4644,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
4883 | ScenePresence sp = GetScenePresence(remoteClient.AgentId); | 4644 | ScenePresence sp = GetScenePresence(remoteClient.AgentId); |
4884 | if (sp != null) | 4645 | if (sp != null) |
4885 | { | 4646 | { |
4886 | uint regionX = RegionInfo.RegionLocX; | ||
4887 | uint regionY = RegionInfo.RegionLocY; | ||
4888 | |||
4889 | Utils.LongToUInts(regionHandle, out regionX, out regionY); | ||
4890 | |||
4891 | int shiftx = (int) regionX - (int) RegionInfo.RegionLocX * (int)Constants.RegionSize; | ||
4892 | int shifty = (int) regionY - (int) RegionInfo.RegionLocY * (int)Constants.RegionSize; | ||
4893 | |||
4894 | position.X += shiftx; | ||
4895 | position.Y += shifty; | ||
4896 | |||
4897 | bool result = false; | ||
4898 | |||
4899 | if (TestBorderCross(position,Cardinals.N)) | ||
4900 | result = true; | ||
4901 | |||
4902 | if (TestBorderCross(position, Cardinals.S)) | ||
4903 | result = true; | ||
4904 | |||
4905 | if (TestBorderCross(position, Cardinals.E)) | ||
4906 | result = true; | ||
4907 | |||
4908 | if (TestBorderCross(position, Cardinals.W)) | ||
4909 | result = true; | ||
4910 | |||
4911 | // bordercross if position is outside of region | ||
4912 | |||
4913 | if (!result) | ||
4914 | { | ||
4915 | regionHandle = RegionInfo.RegionHandle; | ||
4916 | } | ||
4917 | else | ||
4918 | { | ||
4919 | // not in this region, undo the shift! | ||
4920 | position.X -= shiftx; | ||
4921 | position.Y -= shifty; | ||
4922 | } | ||
4923 | |||
4924 | if (EntityTransferModule != null) | 4647 | if (EntityTransferModule != null) |
4925 | { | 4648 | { |
4926 | EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); | 4649 | EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 89c7a1a..a99e469 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -529,12 +529,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
529 | set | 529 | set |
530 | { | 530 | { |
531 | Vector3 val = value; | 531 | Vector3 val = value; |
532 | if (Scene != null && !IsAttachmentCheckFull() | 532 | if (Scene != null |
533 | && !Scene.LoadingPrims && | 533 | && Scene.PositionIsInCurrentRegion(val) |
534 | (Scene.TestBorderCross(val, Cardinals.E) || | 534 | && !IsAttachmentCheckFull() |
535 | Scene.TestBorderCross(val, Cardinals.W) || | 535 | && !Scene.LoadingPrims |
536 | Scene.TestBorderCross(val, Cardinals.N) || | ||
537 | Scene.TestBorderCross(val, Cardinals.S)) | ||
538 | ) | 536 | ) |
539 | { | 537 | { |
540 | if (!inTransit) | 538 | if (!inTransit) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 91293c4..8979659 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -2979,10 +2979,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2979 | { | 2979 | { |
2980 | Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); | 2980 | Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); |
2981 | 2981 | ||
2982 | if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | 2982 | if (!ParentGroup.Scene.PositionIsInCurrentRegion(newpos)) |
2983 | || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | ||
2984 | || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | ||
2985 | || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) | ||
2986 | { | 2983 | { |
2987 | ParentGroup.AbsolutePosition = newpos; | 2984 | ParentGroup.AbsolutePosition = newpos; |
2988 | return; | 2985 | return; |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cd9dcf5..2965903 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1170,18 +1170,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1170 | 1170 | ||
1171 | if (ParentID == 0) | 1171 | if (ParentID == 0) |
1172 | { | 1172 | { |
1173 | if (m_scene.TestBorderCross(pos, Cardinals.E)) | ||
1174 | { | ||
1175 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); | ||
1176 | pos.X = crossedBorder.BorderLine.Z - 1; | ||
1177 | } | ||
1178 | |||
1179 | if (m_scene.TestBorderCross(pos, Cardinals.N)) | ||
1180 | { | ||
1181 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); | ||
1182 | pos.Y = crossedBorder.BorderLine.Z - 1; | ||
1183 | } | ||
1184 | |||
1185 | CheckAndAdjustLandingPoint(ref pos); | 1173 | CheckAndAdjustLandingPoint(ref pos); |
1186 | 1174 | ||
1187 | if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) | 1175 | if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) |
@@ -3867,32 +3855,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
3867 | // m_log.DebugFormat( | 3855 | // m_log.DebugFormat( |
3868 | // "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}", | 3856 | // "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}", |
3869 | // pos2, Name, Scene.Name); | 3857 | // pos2, Name, Scene.Name); |
3870 | 3858 | ||
3871 | if( Scene.TestBorderCross(pos2, Cardinals.E) || | 3859 | if (Scene.PositionIsInCurrentRegion(pos2)) |
3872 | Scene.TestBorderCross(pos2, Cardinals.W) || | 3860 | return; |
3873 | Scene.TestBorderCross(pos2, Cardinals.N) || | 3861 | |
3874 | Scene.TestBorderCross(pos2, Cardinals.S) | 3862 | if (!CrossToNewRegion() && m_requestedSitTargetUUID == UUID.Zero) |
3875 | ) | 3863 | { |
3876 | { | 3864 | // we don't have entity transfer module |
3877 | if (!CrossToNewRegion() && m_requestedSitTargetUUID == UUID.Zero) | 3865 | Vector3 pos = AbsolutePosition; |
3878 | { | 3866 | float px = pos.X; |
3879 | // we don't have entity transfer module | 3867 | if (px < 0) |
3880 | Vector3 pos = AbsolutePosition; | 3868 | pos.X += Velocity.X * 2; |
3881 | float px = pos.X; | 3869 | else if (px > m_scene.RegionInfo.RegionSizeX) |
3882 | if (px < 0) | 3870 | pos.X -= Velocity.X * 2; |
3883 | pos.X += Velocity.X * 2; | 3871 | |
3884 | else if (px > m_scene.RegionInfo.RegionSizeX) | 3872 | float py = pos.Y; |
3885 | pos.X -= Velocity.X * 2; | 3873 | if (py < 0) |
3886 | 3874 | pos.Y += Velocity.Y * 2; | |
3887 | float py = pos.Y; | 3875 | else if (py > m_scene.RegionInfo.RegionSizeY) |
3888 | if (py < 0) | 3876 | pos.Y -= Velocity.Y * 2; |
3889 | pos.Y += Velocity.Y * 2; | 3877 | |
3890 | else if (py > m_scene.RegionInfo.RegionSizeY) | 3878 | Velocity = Vector3.Zero; |
3891 | pos.Y -= Velocity.Y * 2; | 3879 | AbsolutePosition = pos; |
3892 | |||
3893 | Velocity = Vector3.Zero; | ||
3894 | AbsolutePosition = pos; | ||
3895 | } | ||
3896 | } | 3880 | } |
3897 | } | 3881 | } |
3898 | 3882 | ||
diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 29b39e0..6cbccc0 100644 --- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs | |||
@@ -116,37 +116,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | |||
116 | + "If teleport is true then some extra teleport debug information is logged.\n" | 116 | + "If teleport is true then some extra teleport debug information is logged.\n" |
117 | + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", | 117 | + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", |
118 | HandleDebugSceneSetCommand); | 118 | HandleDebugSceneSetCommand); |
119 | |||
120 | scene.AddCommand( | ||
121 | "Regions", | ||
122 | this, "show borders", "show borders", "Show border information for regions", HandleShowBordersCommand); | ||
123 | } | ||
124 | |||
125 | private void HandleShowBordersCommand(string module, string[] args) | ||
126 | { | ||
127 | StringBuilder sb = new StringBuilder(); | ||
128 | sb.AppendFormat("Borders for {0}:\n", m_scene.Name); | ||
129 | |||
130 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
131 | cdt.AddColumn("Cross Direction", 15); | ||
132 | cdt.AddColumn("Line", 34); | ||
133 | cdt.AddColumn("Trigger Region", 14); | ||
134 | |||
135 | foreach (Border b in m_scene.NorthBorders) | ||
136 | cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); | ||
137 | |||
138 | foreach (Border b in m_scene.EastBorders) | ||
139 | cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); | ||
140 | |||
141 | foreach (Border b in m_scene.SouthBorders) | ||
142 | cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); | ||
143 | |||
144 | foreach (Border b in m_scene.WestBorders) | ||
145 | cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); | ||
146 | |||
147 | cdt.AddToStringBuilder(sb); | ||
148 | |||
149 | MainConsole.Instance.Output(sb.ToString()); | ||
150 | } | 119 | } |
151 | 120 | ||
152 | private void HandleDebugSceneGetCommand(string module, string[] args) | 121 | private void HandleDebugSceneGetCommand(string module, string[] args) |
@@ -263,4 +232,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments | |||
263 | } | 232 | } |
264 | } | 233 | } |
265 | } | 234 | } |
266 | } \ No newline at end of file | 235 | } |
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 7127c73..341c8f8 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs | |||
@@ -134,6 +134,49 @@ namespace OpenSim.Region.RegionCombinerModule | |||
134 | throw new Exception(string.Format("Region with id {0} not found", regionId)); | 134 | throw new Exception(string.Format("Region with id {0} not found", regionId)); |
135 | } | 135 | } |
136 | 136 | ||
137 | // Test to see if this postiion (relative to the region) is within the area covered | ||
138 | // by this megaregion. | ||
139 | public bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy) | ||
140 | { | ||
141 | bool ret = false; | ||
142 | if (xx < 0 || yy < 0) | ||
143 | return ret; | ||
144 | |||
145 | foreach (RegionConnections rootRegion in m_regions.Values) | ||
146 | { | ||
147 | if (currentRegion == rootRegion.RegionId) | ||
148 | { | ||
149 | // The caller is in the root region so this is an easy test | ||
150 | if (xx < rootRegion.XEnd && yy < rootRegion.YEnd) | ||
151 | { | ||
152 | ret = true; | ||
153 | } | ||
154 | break; | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | // Maybe the caller is in one of the sub-regions | ||
159 | foreach (RegionData childRegion in rootRegion.ConnectedRegions) | ||
160 | { | ||
161 | if (currentRegion == childRegion.RegionId) | ||
162 | { | ||
163 | // This is a child. Diddle the offsets and check if in | ||
164 | Vector3 positionInMegaregion = childRegion.Offset; | ||
165 | positionInMegaregion.X += xx; | ||
166 | positionInMegaregion.Y += yy; | ||
167 | if (positionInMegaregion.X < rootRegion.XEnd && positionInMegaregion.Y < rootRegion.YEnd) | ||
168 | { | ||
169 | ret = true; | ||
170 | } | ||
171 | break; | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | return ret; | ||
178 | } | ||
179 | |||
137 | private void NewPresence(ScenePresence presence) | 180 | private void NewPresence(ScenePresence presence) |
138 | { | 181 | { |
139 | if (presence.IsChildAgent) | 182 | if (presence.IsChildAgent) |
@@ -220,27 +263,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
220 | // | 263 | // |
221 | */ | 264 | */ |
222 | 265 | ||
223 | // Give each region a standard set of non-infinite borders | ||
224 | Border northBorder = new Border(); | ||
225 | northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<--- | ||
226 | northBorder.CrossDirection = Cardinals.N; | ||
227 | scene.NorthBorders[0] = northBorder; | ||
228 | |||
229 | Border southBorder = new Border(); | ||
230 | southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //---> | ||
231 | southBorder.CrossDirection = Cardinals.S; | ||
232 | scene.SouthBorders[0] = southBorder; | ||
233 | |||
234 | Border eastBorder = new Border(); | ||
235 | eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<--- | ||
236 | eastBorder.CrossDirection = Cardinals.E; | ||
237 | scene.EastBorders[0] = eastBorder; | ||
238 | |||
239 | Border westBorder = new Border(); | ||
240 | westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //---> | ||
241 | westBorder.CrossDirection = Cardinals.W; | ||
242 | scene.WestBorders[0] = westBorder; | ||
243 | |||
244 | RegionConnections newConn = new RegionConnections(); | 266 | RegionConnections newConn = new RegionConnections(); |
245 | newConn.ConnectedRegions = new List<RegionData>(); | 267 | newConn.ConnectedRegions = new List<RegionData>(); |
246 | newConn.RegionScene = scene; | 268 | newConn.RegionScene = scene; |
@@ -248,8 +270,8 @@ namespace OpenSim.Region.RegionCombinerModule | |||
248 | newConn.RegionId = scene.RegionInfo.originRegionID; | 270 | newConn.RegionId = scene.RegionInfo.originRegionID; |
249 | newConn.X = scene.RegionInfo.RegionLocX; | 271 | newConn.X = scene.RegionInfo.RegionLocX; |
250 | newConn.Y = scene.RegionInfo.RegionLocY; | 272 | newConn.Y = scene.RegionInfo.RegionLocY; |
251 | newConn.XEnd = (int)Constants.RegionSize; | 273 | newConn.XEnd = scene.RegionInfo.RegionSizeX; |
252 | newConn.YEnd = (int)Constants.RegionSize; | 274 | newConn.YEnd = scene.RegionInfo.RegionSizeX; |
253 | 275 | ||
254 | lock (m_regions) | 276 | lock (m_regions) |
255 | { | 277 | { |
@@ -415,6 +437,11 @@ namespace OpenSim.Region.RegionCombinerModule | |||
415 | */ | 437 | */ |
416 | #endregion | 438 | #endregion |
417 | 439 | ||
440 | |||
441 | // Check to see if this new region is adjacent to the root region. | ||
442 | // Note that we expect the regions to be combined from the root region outward | ||
443 | // thus the requirement for the ordering in the configuration files. | ||
444 | |||
418 | // If we're one region over +x y (i.e. root region is to the west) | 445 | // If we're one region over +x y (i.e. root region is to the west) |
419 | //xxx | 446 | //xxx |
420 | //xxy | 447 | //xxy |
@@ -431,7 +458,7 @@ namespace OpenSim.Region.RegionCombinerModule | |||
431 | //xxx | 458 | //xxx |
432 | if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) | 459 | if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) |
433 | { | 460 | { |
434 | connectedYN = DoWorkForOneRegionOverXPlusY(rootConn, newConn, scene); | 461 | connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); |
435 | break; | 462 | break; |
436 | } | 463 | } |
437 | 464 | ||
@@ -441,9 +468,8 @@ namespace OpenSim.Region.RegionCombinerModule | |||
441 | //xxx | 468 | //xxx |
442 | if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) | 469 | if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) |
443 | { | 470 | { |
444 | connectedYN = DoWorkForOneRegionOverPlusXPlusY(rootConn, newConn, scene); | 471 | connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); |
445 | break; | 472 | break; |
446 | |||
447 | } | 473 | } |
448 | } | 474 | } |
449 | 475 | ||
@@ -453,20 +479,20 @@ namespace OpenSim.Region.RegionCombinerModule | |||
453 | DoWorkForRootRegion(newConn, scene); | 479 | DoWorkForRootRegion(newConn, scene); |
454 | } | 480 | } |
455 | } | 481 | } |
456 | |||
457 | // Set up infinite borders around the entire AABB of the combined ConnectedRegions | ||
458 | AdjustLargeRegionBounds(); | ||
459 | } | 482 | } |
460 | 483 | ||
461 | private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) | 484 | private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) |
462 | { | 485 | { |
486 | // Offset (in meters) from the base of this region to the base of the root region. | ||
463 | Vector3 offset = Vector3.Zero; | 487 | Vector3 offset = Vector3.Zero; |
464 | offset.X = newConn.PosX - rootConn.PosX; | 488 | offset.X = newConn.PosX - rootConn.PosX; |
465 | offset.Y = newConn.PosY - rootConn.PosY; | 489 | offset.Y = newConn.PosY - rootConn.PosY; |
466 | 490 | ||
491 | // The new total size of the region (in meters) | ||
492 | // We just extend the X and Y dimensions so the extent might temporarily include areas without regions. | ||
467 | Vector3 extents = Vector3.Zero; | 493 | Vector3 extents = Vector3.Zero; |
468 | extents.Y = rootConn.YEnd; | 494 | extents.X = Math.Max(rootConn.XEnd, offset.X + newConn.RegionScene.RegionInfo.RegionSizeX); |
469 | extents.X = rootConn.XEnd + newConn.XEnd; | 495 | extents.Y = Math.Max(rootConn.YEnd, offset.Y + newConn.RegionScene.RegionInfo.RegionSizeY); |
470 | 496 | ||
471 | rootConn.UpdateExtents(extents); | 497 | rootConn.UpdateExtents(extents); |
472 | 498 | ||
@@ -475,9 +501,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
475 | rootConn.RegionScene.RegionInfo.RegionName, | 501 | rootConn.RegionScene.RegionInfo.RegionName, |
476 | newConn.RegionScene.RegionInfo.RegionName, offset, extents); | 502 | newConn.RegionScene.RegionInfo.RegionName, offset, extents); |
477 | 503 | ||
478 | scene.BordersLocked = true; | ||
479 | rootConn.RegionScene.BordersLocked = true; | ||
480 | |||
481 | RegionData ConnectedRegion = new RegionData(); | 504 | RegionData ConnectedRegion = new RegionData(); |
482 | ConnectedRegion.Offset = offset; | 505 | ConnectedRegion.Offset = offset; |
483 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; | 506 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; |
@@ -490,34 +513,10 @@ namespace OpenSim.Region.RegionCombinerModule | |||
490 | // Inform Child region that it needs to forward it's terrain to the root region | 513 | // Inform Child region that it needs to forward it's terrain to the root region |
491 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); | 514 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); |
492 | 515 | ||
493 | // Extend the borders as appropriate | ||
494 | lock (rootConn.RegionScene.EastBorders) | ||
495 | rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; | ||
496 | |||
497 | lock (rootConn.RegionScene.NorthBorders) | ||
498 | rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
499 | |||
500 | lock (rootConn.RegionScene.SouthBorders) | ||
501 | rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
502 | |||
503 | lock (scene.WestBorders) | ||
504 | { | ||
505 | scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West | ||
506 | |||
507 | // Trigger auto teleport to root region | ||
508 | scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; | ||
509 | scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; | ||
510 | } | ||
511 | |||
512 | // Reset Terrain.. since terrain loads before we get here, we need to load | 516 | // Reset Terrain.. since terrain loads before we get here, we need to load |
513 | // it again so it loads in the root region | 517 | // it again so it loads in the root region |
514 | |||
515 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); | 518 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); |
516 | 519 | ||
517 | // Unlock borders | ||
518 | rootConn.RegionScene.BordersLocked = false; | ||
519 | scene.BordersLocked = false; | ||
520 | |||
521 | // Create a client event forwarder and add this region's events to the root region. | 520 | // Create a client event forwarder and add this region's events to the root region. |
522 | if (rootConn.ClientEventForwarder != null) | 521 | if (rootConn.ClientEventForwarder != null) |
523 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); | 522 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); |
@@ -525,6 +524,9 @@ namespace OpenSim.Region.RegionCombinerModule | |||
525 | return true; | 524 | return true; |
526 | } | 525 | } |
527 | 526 | ||
527 | /* | ||
528 | * 20140215 radams1: The border stuff was removed and the addition of regions to the mega-regions | ||
529 | * was generalized. These functions are not needed for the generalized solution but left for reference. | ||
528 | private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) | 530 | private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) |
529 | { | 531 | { |
530 | Vector3 offset = Vector3.Zero; | 532 | Vector3 offset = Vector3.Zero; |
@@ -536,9 +538,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
536 | extents.X = rootConn.XEnd; | 538 | extents.X = rootConn.XEnd; |
537 | rootConn.UpdateExtents(extents); | 539 | rootConn.UpdateExtents(extents); |
538 | 540 | ||
539 | scene.BordersLocked = true; | ||
540 | rootConn.RegionScene.BordersLocked = true; | ||
541 | |||
542 | RegionData ConnectedRegion = new RegionData(); | 541 | RegionData ConnectedRegion = new RegionData(); |
543 | ConnectedRegion.Offset = offset; | 542 | ConnectedRegion.Offset = offset; |
544 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; | 543 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; |
@@ -553,30 +552,11 @@ namespace OpenSim.Region.RegionCombinerModule | |||
553 | rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); | 552 | rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); |
554 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); | 553 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); |
555 | 554 | ||
556 | lock (rootConn.RegionScene.NorthBorders) | ||
557 | rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; | ||
558 | |||
559 | lock (rootConn.RegionScene.EastBorders) | ||
560 | rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
561 | |||
562 | lock (rootConn.RegionScene.WestBorders) | ||
563 | rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
564 | |||
565 | lock (scene.SouthBorders) | ||
566 | { | ||
567 | scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south | ||
568 | scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; | ||
569 | scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; | ||
570 | } | ||
571 | |||
572 | // Reset Terrain.. since terrain normally loads first. | 555 | // Reset Terrain.. since terrain normally loads first. |
573 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); | 556 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); |
574 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); | 557 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); |
575 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); | 558 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); |
576 | 559 | ||
577 | scene.BordersLocked = false; | ||
578 | rootConn.RegionScene.BordersLocked = false; | ||
579 | |||
580 | if (rootConn.ClientEventForwarder != null) | 560 | if (rootConn.ClientEventForwarder != null) |
581 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); | 561 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); |
582 | 562 | ||
@@ -600,9 +580,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
600 | extents.Y = rootConn.YEnd; | 580 | extents.Y = rootConn.YEnd; |
601 | extents.X = rootConn.XEnd; | 581 | extents.X = rootConn.XEnd; |
602 | 582 | ||
603 | scene.BordersLocked = true; | ||
604 | rootConn.RegionScene.BordersLocked = true; | ||
605 | |||
606 | RegionData ConnectedRegion = new RegionData(); | 583 | RegionData ConnectedRegion = new RegionData(); |
607 | ConnectedRegion.Offset = offset; | 584 | ConnectedRegion.Offset = offset; |
608 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; | 585 | ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; |
@@ -618,67 +595,10 @@ namespace OpenSim.Region.RegionCombinerModule | |||
618 | rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); | 595 | rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); |
619 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); | 596 | scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); |
620 | 597 | ||
621 | lock (rootConn.RegionScene.NorthBorders) | ||
622 | { | ||
623 | if (rootConn.RegionScene.NorthBorders.Count == 1)// && 2) | ||
624 | { | ||
625 | //compound border | ||
626 | // already locked above | ||
627 | rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; | ||
628 | |||
629 | lock (rootConn.RegionScene.EastBorders) | ||
630 | rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
631 | |||
632 | lock (rootConn.RegionScene.WestBorders) | ||
633 | rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
634 | } | ||
635 | } | ||
636 | |||
637 | lock (scene.SouthBorders) | ||
638 | { | ||
639 | scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south | ||
640 | scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; | ||
641 | scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; | ||
642 | } | ||
643 | |||
644 | lock (rootConn.RegionScene.EastBorders) | ||
645 | { | ||
646 | if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) | ||
647 | { | ||
648 | rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; | ||
649 | |||
650 | lock (rootConn.RegionScene.NorthBorders) | ||
651 | rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
652 | |||
653 | lock (rootConn.RegionScene.SouthBorders) | ||
654 | rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
655 | } | ||
656 | } | ||
657 | |||
658 | lock (scene.WestBorders) | ||
659 | { | ||
660 | scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West | ||
661 | scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; | ||
662 | scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; | ||
663 | } | ||
664 | |||
665 | /* | ||
666 | else | ||
667 | { | ||
668 | conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; | ||
669 | conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
670 | conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; | ||
671 | scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south | ||
672 | } | ||
673 | */ | ||
674 | |||
675 | |||
676 | // Reset Terrain.. since terrain normally loads first. | 598 | // Reset Terrain.. since terrain normally loads first. |
677 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); | 599 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); |
678 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); | 600 | scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); |
679 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); | 601 | //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); |
680 | scene.BordersLocked = false; | ||
681 | rootConn.RegionScene.BordersLocked = false; | ||
682 | 602 | ||
683 | if (rootConn.ClientEventForwarder != null) | 603 | if (rootConn.ClientEventForwarder != null) |
684 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); | 604 | rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); |
@@ -687,6 +607,7 @@ namespace OpenSim.Region.RegionCombinerModule | |||
687 | 607 | ||
688 | //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); | 608 | //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); |
689 | } | 609 | } |
610 | */ | ||
690 | 611 | ||
691 | private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene) | 612 | private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene) |
692 | { | 613 | { |
@@ -885,125 +806,6 @@ namespace OpenSim.Region.RegionCombinerModule | |||
885 | // } | 806 | // } |
886 | // } | 807 | // } |
887 | 808 | ||
888 | // Create a set of infinite borders around the whole aabb of the combined island. | ||
889 | private void AdjustLargeRegionBounds() | ||
890 | { | ||
891 | lock (m_regions) | ||
892 | { | ||
893 | foreach (RegionConnections rconn in m_regions.Values) | ||
894 | { | ||
895 | Vector3 offset = Vector3.Zero; | ||
896 | rconn.RegionScene.BordersLocked = true; | ||
897 | foreach (RegionData rdata in rconn.ConnectedRegions) | ||
898 | { | ||
899 | if (rdata.Offset.X > offset.X) offset.X = rdata.Offset.X; | ||
900 | if (rdata.Offset.Y > offset.Y) offset.Y = rdata.Offset.Y; | ||
901 | } | ||
902 | |||
903 | lock (rconn.RegionScene.NorthBorders) | ||
904 | { | ||
905 | Border northBorder = null; | ||
906 | // If we don't already have an infinite border, create one. | ||
907 | if (!TryGetInfiniteBorder(rconn.RegionScene.NorthBorders, out northBorder)) | ||
908 | { | ||
909 | northBorder = new Border(); | ||
910 | rconn.RegionScene.NorthBorders.Add(northBorder); | ||
911 | } | ||
912 | |||
913 | northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, | ||
914 | offset.Y + (int) Constants.RegionSize); //<--- | ||
915 | northBorder.CrossDirection = Cardinals.N; | ||
916 | } | ||
917 | |||
918 | lock (rconn.RegionScene.SouthBorders) | ||
919 | { | ||
920 | Border southBorder = null; | ||
921 | // If we don't already have an infinite border, create one. | ||
922 | if (!TryGetInfiniteBorder(rconn.RegionScene.SouthBorders, out southBorder)) | ||
923 | { | ||
924 | southBorder = new Border(); | ||
925 | rconn.RegionScene.SouthBorders.Add(southBorder); | ||
926 | } | ||
927 | southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //---> | ||
928 | southBorder.CrossDirection = Cardinals.S; | ||
929 | } | ||
930 | |||
931 | lock (rconn.RegionScene.EastBorders) | ||
932 | { | ||
933 | Border eastBorder = null; | ||
934 | // If we don't already have an infinite border, create one. | ||
935 | if (!TryGetInfiniteBorder(rconn.RegionScene.EastBorders, out eastBorder)) | ||
936 | { | ||
937 | eastBorder = new Border(); | ||
938 | rconn.RegionScene.EastBorders.Add(eastBorder); | ||
939 | } | ||
940 | eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, offset.X + (int)Constants.RegionSize); | ||
941 | //<--- | ||
942 | eastBorder.CrossDirection = Cardinals.E; | ||
943 | } | ||
944 | |||
945 | lock (rconn.RegionScene.WestBorders) | ||
946 | { | ||
947 | Border westBorder = null; | ||
948 | // If we don't already have an infinite border, create one. | ||
949 | if (!TryGetInfiniteBorder(rconn.RegionScene.WestBorders, out westBorder)) | ||
950 | { | ||
951 | westBorder = new Border(); | ||
952 | rconn.RegionScene.WestBorders.Add(westBorder); | ||
953 | |||
954 | } | ||
955 | westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //---> | ||
956 | westBorder.CrossDirection = Cardinals.W; | ||
957 | } | ||
958 | |||
959 | rconn.RegionScene.BordersLocked = false; | ||
960 | } | ||
961 | } | ||
962 | } | ||
963 | |||
964 | /// <summary> | ||
965 | /// Try and get an Infinite border out of a listT of borders | ||
966 | /// </summary> | ||
967 | /// <param name="borders"></param> | ||
968 | /// <param name="oborder"></param> | ||
969 | /// <returns></returns> | ||
970 | public static bool TryGetInfiniteBorder(List<Border> borders, out Border oborder) | ||
971 | { | ||
972 | // Warning! Should be locked before getting here! | ||
973 | foreach (Border b in borders) | ||
974 | { | ||
975 | if (b.BorderLine.X == float.MinValue && b.BorderLine.Y == float.MaxValue) | ||
976 | { | ||
977 | oborder = b; | ||
978 | return true; | ||
979 | } | ||
980 | } | ||
981 | |||
982 | oborder = null; | ||
983 | return false; | ||
984 | } | ||
985 | |||
986 | public RegionData GetRegionFromPosition(Vector3 pPosition) | ||
987 | { | ||
988 | pPosition = pPosition/(int) Constants.RegionSize; | ||
989 | int OffsetX = (int) pPosition.X; | ||
990 | int OffsetY = (int) pPosition.Y; | ||
991 | |||
992 | lock (m_regions) | ||
993 | { | ||
994 | foreach (RegionConnections regConn in m_regions.Values) | ||
995 | { | ||
996 | foreach (RegionData reg in regConn.ConnectedRegions) | ||
997 | { | ||
998 | if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY) | ||
999 | return reg; | ||
1000 | } | ||
1001 | } | ||
1002 | } | ||
1003 | |||
1004 | return new RegionData(); | ||
1005 | } | ||
1006 | |||
1007 | public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion) | 809 | public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion) |
1008 | { | 810 | { |
1009 | if (BigRegion.PermissionModule == null) | 811 | if (BigRegion.PermissionModule == null) |