diff options
author | Robert Adams | 2015-03-22 21:53:02 -0700 |
---|---|---|
committer | Robert Adams | 2015-03-22 21:53:02 -0700 |
commit | 9f18e3ba80a6469b7ff03c7cca595a0a3b999592 (patch) | |
tree | c2ace74c3ffc6eab80b94bfbe4e6a2d37197eb28 | |
parent | Allow setting the size of the wearables array from config, for core compatibi... (diff) | |
download | opensim-SC_OLD-9f18e3ba80a6469b7ff03c7cca595a0a3b999592.zip opensim-SC_OLD-9f18e3ba80a6469b7ff03c7cca595a0a3b999592.tar.gz opensim-SC_OLD-9f18e3ba80a6469b7ff03c7cca595a0a3b999592.tar.bz2 opensim-SC_OLD-9f18e3ba80a6469b7ff03c7cca595a0a3b999592.tar.xz |
Varregion: first cut at removing Border class checks for region crossings.
Added Scene.PositionIsInCurrentRegion(pos) to sense when new position needs some crossing work.
Many changes made to EntityTransferModule to accomodate new crossing sense logic.
Diffstat (limited to '')
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) |