diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index a038f73733..3eff96edee 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -464,7 +464,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Name, position, sp.Scene.RegionInfo.RegionName); // Teleport within the same region - if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) + if (!sp.Scene.PositionIsInCurrentRegion(position) || position.Z < 0) { Vector3 emergencyPos = new Vector3(128, 128, 128); @@ -580,7 +580,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer MapBlockData block = new MapBlockData(); block.X = (ushort)regX; block.Y = (ushort)regY; - block.Access = 254; // == not there + block.Access = (byte)SimAccess.Down; List blocks = new List(); blocks.Add(block); @@ -713,10 +713,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - uint newRegionX = (uint)(reg.RegionHandle >> 40); - uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); - uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); - uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); + uint newRegionX, newRegionY, oldRegionX, oldRegionY; + Util.RegionHandleToRegionLoc(reg.RegionHandle, out newRegionX, out newRegionY); + Util.RegionHandleToRegionLoc(sp.Scene.RegionInfo.RegionHandle, out oldRegionX, out oldRegionY); ulong destinationHandle = finalDestination.RegionHandle; @@ -1333,6 +1332,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return region; } + // This returns 'true' if the new region already has a child agent for our + // incoming agent. The implication is that, if 'false', we have to create the + // child and then teleport into the region. protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) { if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) @@ -1357,20 +1359,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); } - protected virtual bool IsOutsideRegion(Scene s, Vector3 pos) - { - if (s.TestBorderCross(pos, Cardinals.N)) - return true; - if (s.TestBorderCross(pos, Cardinals.S)) - return true; - if (s.TestBorderCross(pos, Cardinals.E)) - return true; - if (s.TestBorderCross(pos, Cardinals.W)) - return true; - - return false; - } - #endregion #region Landmark Teleport @@ -2077,7 +2065,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public NotFoundLocationCache() { } - // Add an area to the lost of 'not found' places. The area is the snapped region + // Add an area to the list of 'not found' places. The area is the snapped region // area around the added point. public void Add(double pX, double pY) { @@ -2305,22 +2293,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner) { - Border[] northBorders = Scene.NorthBorders.ToArray(); - Border[] eastBorders = Scene.EastBorders.ToArray(); - Vector2 extent = Vector2.Zero; - for (int i = 0; i < eastBorders.Length; i++) - { - extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X; - } - for (int i = 0; i < northBorders.Length; i++) - { - extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; - } - // Loss of fraction on purpose - extent.X = ((int)extent.X / (int)Constants.RegionSize); - extent.Y = ((int)extent.Y / (int)Constants.RegionSize); + if (m_regionCombinerModule != null) + { + Vector2 megaRegionSize = m_regionCombinerModule.GetSizeOfMegaregion(Scene.RegionInfo.RegionID); + extent.X = (float)Util.WorldToRegionLoc((uint)megaRegionSize.X); + extent.Y = (float)Util.WorldToRegionLoc((uint)megaRegionSize.Y); + } swCorner.X = Scene.RegionInfo.RegionLocX - 1; swCorner.Y = Scene.RegionInfo.RegionLocY - 1; diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs index e03ac5a26f..c6f531edd2 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs @@ -55,5 +55,10 @@ namespace OpenSim.Region.Framework.Interfaces /// Currently, will throw an exception if this does not match a root region. /// Vector2 GetSizeOfMegaregion(UUID regionId); + + /// + /// Tests to see of position (relative to the region) is within the megaregion + /// + bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2f666c032c..682c2aa8c7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -160,11 +160,6 @@ namespace OpenSim.Region.Framework.Scenes /// public SimStatsReporter StatsReporter { get; private set; } - public List NorthBorders = new List(); - public List EastBorders = new List(); - public List SouthBorders = new List(); - public List WestBorders = new List(); - /// /// Controls whether physics can be applied to prims. Even if false, prims still have entries in a /// PhysicsScene in order to perform collision detection @@ -349,7 +344,6 @@ namespace OpenSim.Region.Framework.Scenes // TODO: Possibly stop other classes being able to manipulate this directly. private SceneGraph m_sceneGraph; - private volatile int m_bordersLocked; private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing private volatile bool m_backingup; private Dictionary m_returns = new Dictionary(); @@ -426,18 +420,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_splitRegionID = value; } } - public bool BordersLocked - { - get { return m_bordersLocked == 1; } - set - { - if (value == true) - m_bordersLocked = 1; - else - m_bordersLocked = 0; - } - } - public new float TimeDilation { get { return m_sceneGraph.PhysicsScene.TimeDilation; } @@ -1031,28 +1013,6 @@ namespace OpenSim.Region.Framework.Scenes PeriodicBackup = true; UseBackup = true; - BordersLocked = true; - Border northBorder = new Border(); - northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (float)RegionInfo.RegionSizeY); //<--- - northBorder.CrossDirection = Cardinals.N; - NorthBorders.Add(northBorder); - - Border southBorder = new Border(); - southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //---> - southBorder.CrossDirection = Cardinals.S; - SouthBorders.Add(southBorder); - - Border eastBorder = new Border(); - eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (float)RegionInfo.RegionSizeY); //<--- - eastBorder.CrossDirection = Cardinals.E; - EastBorders.Add(eastBorder); - - Border westBorder = new Border(); - westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //---> - westBorder.CrossDirection = Cardinals.W; - WestBorders.Add(westBorder); - BordersLocked = false; - m_eventManager = new EventManager(); m_permissions = new ScenePermissions(this); @@ -2445,201 +2405,34 @@ namespace OpenSim.Region.Framework.Scenes } // Simple test to see if a position is in the current region. - // Resuming the position is relative to the region so anything outside its bounds. + // This test is mostly used to see if a region crossing is necessary. + // Assuming the position is relative to the region so anything outside its bounds. // Return 'true' if position inside region. public bool PositionIsInCurrentRegion(Vector3 pos) { - bool ret = true; + bool ret = false; int xx = (int)Math.Floor(pos.X); int yy = (int)Math.Floor(pos.Y); - if (xx < 0 - || xx >= RegionInfo.RegionSizeX - || yy < 0 - || yy >= RegionInfo.RegionSizeY) - ret = false; + if (xx < 0 || yy < 0) + return false; + + IRegionCombinerModule regionCombinerModule = RequestModuleInterface(); + if (regionCombinerModule == null) + { + // Regular region. Just check for region size + if (xx < RegionInfo.RegionSizeX || yy < RegionInfo.RegionSizeY ) + ret = true; + } + else + { + // We're in a mega-region so see if we are still in that larger region + ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy); + } + return ret; } - public Border GetCrossedBorder(Vector3 position, Cardinals gridline) - { - if (BordersLocked) - { - switch (gridline) - { - case Cardinals.N: - lock (NorthBorders) - { - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return b; - } - } - break; - case Cardinals.S: - lock (SouthBorders) - { - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return b; - } - } - - break; - case Cardinals.E: - lock (EastBorders) - { - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return b; - } - } - - break; - case Cardinals.W: - - lock (WestBorders) - { - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return b; - } - } - break; - - } - } - else - { - switch (gridline) - { - case Cardinals.N: - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return b; - } - - break; - case Cardinals.S: - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return b; - } - break; - case Cardinals.E: - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return b; - } - - break; - case Cardinals.W: - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return b; - } - break; - - } - } - - return null; - } - - public bool TestBorderCross(Vector3 position, Cardinals border) - { - if (BordersLocked) - { - switch (border) - { - case Cardinals.N: - lock (NorthBorders) - { - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - case Cardinals.E: - lock (EastBorders) - { - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - case Cardinals.S: - lock (SouthBorders) - { - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - case Cardinals.W: - lock (WestBorders) - { - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - } - } - else - { - switch (border) - { - case Cardinals.N: - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return true; - } - break; - case Cardinals.E: - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return true; - } - break; - case Cardinals.S: - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return true; - } - break; - case Cardinals.W: - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return true; - } - break; - } - } - return false; - } - - /// /// Called when objects or attachments cross the border, or teleport, between regions. /// @@ -3874,61 +3667,11 @@ namespace OpenSim.Region.Framework.Scenes { // CleanDroppedAttachments(); - if (TestBorderCross(acd.startpos, Cardinals.E)) - { - Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E); - acd.startpos.X = crossedBorder.BorderLine.Z - 1; - m_log.DebugFormat("{0} NewUserConnection Adjusted border E. startpos={1}", LogHeader, acd.startpos); - } - - if (TestBorderCross(acd.startpos, Cardinals.N)) - { - Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N); - acd.startpos.Y = crossedBorder.BorderLine.Z - 1; - } - - //Mitigate http://opensimulator.org/mantis/view.php?id=3522 - // Check if start position is outside of region - // If it is, check the Z start position also.. if not, leave it alone. - if (BordersLocked) - { - lock (EastBorders) - { - if (acd.startpos.X > EastBorders[0].BorderLine.Z) - { - m_log.Warn("FIX AGENT POSITION"); - acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - } - lock (NorthBorders) - { - if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) - { - m_log.Warn("FIX Agent POSITION"); - acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - } - } else - { - if (acd.startpos.X > EastBorders[0].BorderLine.Z) - { - m_log.Warn("FIX AGENT POSITION"); - acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) - { - m_log.Warn("FIX Agent POSITION"); - acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - } + // Make sure avatar position is in the region (why it wouldn't be is a mystery but do sanity checking) + if (acd.startpos.X < 0) acd.startpos.X = 1f; + if (acd.startpos.X >= RegionInfo.RegionSizeX) acd.startpos.X = RegionInfo.RegionSizeX - 1f; + if (acd.startpos.Y < 0) acd.startpos.Y = 1f; + if (acd.startpos.Y >= RegionInfo.RegionSizeY) acd.startpos.Y = RegionInfo.RegionSizeY - 1f; // m_log.DebugFormat( // "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c6b98ca6f2..0657cbbfad 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -429,7 +429,7 @@ namespace OpenSim.Region.Framework.Scenes /// public bool IsAttachmentCheckFull() { - return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); + return (IsAttachment || (m_rootPart.Shape.PCode == (byte)PCodeEnum.Primitive && m_rootPart.Shape.State != 0)); } private struct avtocrossInfo @@ -451,19 +451,10 @@ namespace OpenSim.Region.Framework.Scenes if (Scene != null) { if ( - // (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) - // || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) - // || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) - // || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) - // Experimental change for better border crossings. - // The commented out original lines above would, it seems, trigger - // a border crossing a little early or late depending on which - // direction the object was moving. - (Scene.TestBorderCross(val, Cardinals.E) - || Scene.TestBorderCross(val, Cardinals.W) - || Scene.TestBorderCross(val, Cardinals.N) - || Scene.TestBorderCross(val, Cardinals.S)) - && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) + !Scene.PositionIsInCurrentRegion(val) + && !IsAttachmentCheckFull() + && (!Scene.LoadingPrims) + ) { IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface(); string version = String.Empty; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 1cf77267e4..db4e285014 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2479,13 +2479,10 @@ namespace OpenSim.Region.Framework.Scenes if (pa != null) { - Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); - - if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) - | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) - | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) - | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) + Vector3 newpos = pa.Position; + if (!ParentGroup.Scene.PositionIsInCurrentRegion(newpos)) { + // Setting position outside current region will start region crossing ParentGroup.AbsolutePosition = newpos; return; } diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 29b39e031a..5fb74b01ea 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 + "If teleport is true then some extra teleport debug information is logged.\n" + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", HandleDebugSceneSetCommand); - - scene.AddCommand( - "Regions", - this, "show borders", "show borders", "Show border information for regions", HandleShowBordersCommand); - } - - private void HandleShowBordersCommand(string module, string[] args) - { - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("Borders for {0}:\n", m_scene.Name); - - ConsoleDisplayTable cdt = new ConsoleDisplayTable(); - cdt.AddColumn("Cross Direction", 15); - cdt.AddColumn("Line", 34); - cdt.AddColumn("Trigger Region", 14); - - foreach (Border b in m_scene.NorthBorders) - cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); - - foreach (Border b in m_scene.EastBorders) - cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); - - foreach (Border b in m_scene.SouthBorders) - cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); - - foreach (Border b in m_scene.WestBorders) - cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); - - cdt.AddToStringBuilder(sb); - - MainConsole.Instance.Output(sb.ToString()); } private void HandleDebugSceneGetCommand(string module, string[] args) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 7127c73c18..a7ffad08c0 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -44,6 +44,7 @@ namespace OpenSim.Region.RegionCombinerModule public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static string LogHeader = "[REGION COMBINER MODULE]"; public string Name { @@ -134,6 +135,49 @@ namespace OpenSim.Region.RegionCombinerModule throw new Exception(string.Format("Region with id {0} not found", regionId)); } + // Test to see if this postiion (relative to the region) is within the area covered + // by this megaregion. + public bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy) + { + bool ret = false; + if (xx < 0 || yy < 0) + return ret; + + foreach (RegionConnections rootRegion in m_regions.Values) + { + if (currentRegion == rootRegion.RegionId) + { + // The caller is in the root region so this is an easy test + if (xx < rootRegion.XEnd && yy < rootRegion.YEnd) + { + ret = true; + } + break; + } + else + { + // Maybe the caller is in one of the sub-regions + foreach (RegionData childRegion in rootRegion.ConnectedRegions) + { + if (currentRegion == childRegion.RegionId) + { + // This is a child. Diddle the offsets and check if in + Vector3 positionInMegaregion = childRegion.Offset; + positionInMegaregion.X += xx; + positionInMegaregion.Y += yy; + if (positionInMegaregion.X < rootRegion.XEnd && positionInMegaregion.Y < rootRegion.YEnd) + { + ret = true; + } + break; + } + } + } + } + + return ret; + } + private void NewPresence(ScenePresence presence) { if (presence.IsChildAgent) @@ -220,27 +264,6 @@ namespace OpenSim.Region.RegionCombinerModule // */ - // Give each region a standard set of non-infinite borders - Border northBorder = new Border(); - northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<--- - northBorder.CrossDirection = Cardinals.N; - scene.NorthBorders[0] = northBorder; - - Border southBorder = new Border(); - southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //---> - southBorder.CrossDirection = Cardinals.S; - scene.SouthBorders[0] = southBorder; - - Border eastBorder = new Border(); - eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<--- - eastBorder.CrossDirection = Cardinals.E; - scene.EastBorders[0] = eastBorder; - - Border westBorder = new Border(); - westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //---> - westBorder.CrossDirection = Cardinals.W; - scene.WestBorders[0] = westBorder; - RegionConnections newConn = new RegionConnections(); newConn.ConnectedRegions = new List(); newConn.RegionScene = scene; @@ -248,8 +271,8 @@ namespace OpenSim.Region.RegionCombinerModule newConn.RegionId = scene.RegionInfo.originRegionID; newConn.X = scene.RegionInfo.RegionLocX; newConn.Y = scene.RegionInfo.RegionLocY; - newConn.XEnd = (int)Constants.RegionSize; - newConn.YEnd = (int)Constants.RegionSize; + newConn.XEnd = scene.RegionInfo.RegionSizeX; + newConn.YEnd = scene.RegionInfo.RegionSizeX; lock (m_regions) { @@ -415,6 +438,11 @@ namespace OpenSim.Region.RegionCombinerModule */ #endregion + + // Check to see if this new region is adjacent to the root region. + // Note that we expect the regions to be combined from the root region outward + // thus the requirement for the ordering in the configuration files. + // If we're one region over +x y (i.e. root region is to the west) //xxx //xxy @@ -431,7 +459,7 @@ namespace OpenSim.Region.RegionCombinerModule //xxx if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) { - connectedYN = DoWorkForOneRegionOverXPlusY(rootConn, newConn, scene); + connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); break; } @@ -441,9 +469,8 @@ namespace OpenSim.Region.RegionCombinerModule //xxx if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) { - connectedYN = DoWorkForOneRegionOverPlusXPlusY(rootConn, newConn, scene); + connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); break; - } } @@ -453,20 +480,20 @@ namespace OpenSim.Region.RegionCombinerModule DoWorkForRootRegion(newConn, scene); } } - - // Set up infinite borders around the entire AABB of the combined ConnectedRegions - AdjustLargeRegionBounds(); } private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { + // Offset (in meters) from the base of this region to the base of the root region. Vector3 offset = Vector3.Zero; offset.X = newConn.PosX - rootConn.PosX; offset.Y = newConn.PosY - rootConn.PosY; + // The new total size of the region (in meters) + // We just extend the X and Y dimensions so the extent might temporarily include areas without regions. Vector3 extents = Vector3.Zero; - extents.Y = rootConn.YEnd; - extents.X = rootConn.XEnd + newConn.XEnd; + extents.X = Math.Max(rootConn.XEnd, offset.X + newConn.RegionScene.RegionInfo.RegionSizeX); + extents.Y = Math.Max(rootConn.YEnd, offset.Y + newConn.RegionScene.RegionInfo.RegionSizeY); rootConn.UpdateExtents(extents); @@ -475,9 +502,6 @@ namespace OpenSim.Region.RegionCombinerModule rootConn.RegionScene.RegionInfo.RegionName, newConn.RegionScene.RegionInfo.RegionName, offset, extents); - scene.BordersLocked = true; - rootConn.RegionScene.BordersLocked = true; - RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; @@ -490,34 +514,10 @@ namespace OpenSim.Region.RegionCombinerModule // Inform Child region that it needs to forward it's terrain to the root region scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); - // Extend the borders as appropriate - lock (rootConn.RegionScene.EastBorders) - rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.NorthBorders) - rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.SouthBorders) - rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (scene.WestBorders) - { - scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West - - // Trigger auto teleport to root region - scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; - scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; - } - // Reset Terrain.. since terrain loads before we get here, we need to load // it again so it loads in the root region - scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); - // Unlock borders - rootConn.RegionScene.BordersLocked = false; - scene.BordersLocked = false; - // Create a client event forwarder and add this region's events to the root region. if (rootConn.ClientEventForwarder != null) rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); @@ -525,6 +525,9 @@ namespace OpenSim.Region.RegionCombinerModule return true; } + /* + * 20140215 radams1: The border stuff was removed and the addition of regions to the mega-regions + * was generalized. These functions are not needed for the generalized solution but left for reference. private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; @@ -536,9 +539,6 @@ namespace OpenSim.Region.RegionCombinerModule extents.X = rootConn.XEnd; rootConn.UpdateExtents(extents); - scene.BordersLocked = true; - rootConn.RegionScene.BordersLocked = true; - RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; @@ -553,30 +553,11 @@ namespace OpenSim.Region.RegionCombinerModule rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); - lock (rootConn.RegionScene.NorthBorders) - rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.EastBorders) - rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.WestBorders) - rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (scene.SouthBorders) - { - scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south - scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; - scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; - } - // Reset Terrain.. since terrain normally loads first. //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); - scene.BordersLocked = false; - rootConn.RegionScene.BordersLocked = false; - if (rootConn.ClientEventForwarder != null) rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); @@ -600,9 +581,6 @@ namespace OpenSim.Region.RegionCombinerModule extents.Y = rootConn.YEnd; extents.X = rootConn.XEnd; - scene.BordersLocked = true; - rootConn.RegionScene.BordersLocked = true; - RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; @@ -618,67 +596,10 @@ namespace OpenSim.Region.RegionCombinerModule rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); - lock (rootConn.RegionScene.NorthBorders) - { - if (rootConn.RegionScene.NorthBorders.Count == 1)// && 2) - { - //compound border - // already locked above - rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.EastBorders) - rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.WestBorders) - rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; - } - } - - lock (scene.SouthBorders) - { - scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south - scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; - scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; - } - - lock (rootConn.RegionScene.EastBorders) - { - if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) - { - rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.NorthBorders) - rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.SouthBorders) - rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - } - } - - lock (scene.WestBorders) - { - scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West - scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; - scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; - } - - /* - else - { - conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; - scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south - } - */ - - // Reset Terrain.. since terrain normally loads first. //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); - scene.BordersLocked = false; - rootConn.RegionScene.BordersLocked = false; if (rootConn.ClientEventForwarder != null) rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); @@ -687,6 +608,7 @@ namespace OpenSim.Region.RegionCombinerModule //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); } + */ private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene) { @@ -885,125 +807,6 @@ namespace OpenSim.Region.RegionCombinerModule // } // } - // Create a set of infinite borders around the whole aabb of the combined island. - private void AdjustLargeRegionBounds() - { - lock (m_regions) - { - foreach (RegionConnections rconn in m_regions.Values) - { - Vector3 offset = Vector3.Zero; - rconn.RegionScene.BordersLocked = true; - foreach (RegionData rdata in rconn.ConnectedRegions) - { - if (rdata.Offset.X > offset.X) offset.X = rdata.Offset.X; - if (rdata.Offset.Y > offset.Y) offset.Y = rdata.Offset.Y; - } - - lock (rconn.RegionScene.NorthBorders) - { - Border northBorder = null; - // If we don't already have an infinite border, create one. - if (!TryGetInfiniteBorder(rconn.RegionScene.NorthBorders, out northBorder)) - { - northBorder = new Border(); - rconn.RegionScene.NorthBorders.Add(northBorder); - } - - northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, - offset.Y + (int) Constants.RegionSize); //<--- - northBorder.CrossDirection = Cardinals.N; - } - - lock (rconn.RegionScene.SouthBorders) - { - Border southBorder = null; - // If we don't already have an infinite border, create one. - if (!TryGetInfiniteBorder(rconn.RegionScene.SouthBorders, out southBorder)) - { - southBorder = new Border(); - rconn.RegionScene.SouthBorders.Add(southBorder); - } - southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //---> - southBorder.CrossDirection = Cardinals.S; - } - - lock (rconn.RegionScene.EastBorders) - { - Border eastBorder = null; - // If we don't already have an infinite border, create one. - if (!TryGetInfiniteBorder(rconn.RegionScene.EastBorders, out eastBorder)) - { - eastBorder = new Border(); - rconn.RegionScene.EastBorders.Add(eastBorder); - } - eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, offset.X + (int)Constants.RegionSize); - //<--- - eastBorder.CrossDirection = Cardinals.E; - } - - lock (rconn.RegionScene.WestBorders) - { - Border westBorder = null; - // If we don't already have an infinite border, create one. - if (!TryGetInfiniteBorder(rconn.RegionScene.WestBorders, out westBorder)) - { - westBorder = new Border(); - rconn.RegionScene.WestBorders.Add(westBorder); - - } - westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //---> - westBorder.CrossDirection = Cardinals.W; - } - - rconn.RegionScene.BordersLocked = false; - } - } - } - - /// - /// Try and get an Infinite border out of a listT of borders - /// - /// - /// - /// - public static bool TryGetInfiniteBorder(List borders, out Border oborder) - { - // Warning! Should be locked before getting here! - foreach (Border b in borders) - { - if (b.BorderLine.X == float.MinValue && b.BorderLine.Y == float.MaxValue) - { - oborder = b; - return true; - } - } - - oborder = null; - return false; - } - - public RegionData GetRegionFromPosition(Vector3 pPosition) - { - pPosition = pPosition/(int) Constants.RegionSize; - int OffsetX = (int) pPosition.X; - int OffsetY = (int) pPosition.Y; - - lock (m_regions) - { - foreach (RegionConnections regConn in m_regions.Values) - { - foreach (RegionData reg in regConn.ConnectedRegions) - { - if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY) - return reg; - } - } - } - - return new RegionData(); - } - public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion) { if (BigRegion.PermissionModule == null)