diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 533e53abd5..5a5046e547 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -459,10 +459,17 @@ namespace OpenSim.Framework /// Old region y-coord /// New region y-coord /// - public static bool IsOutsideView(uint oldx, uint newx, uint oldy, uint newy) + public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy) { - // Eventually this will be a function of the draw distance / camera position too. - return (((int)Math.Abs((int)(oldx - newx)) > 1) || ((int)Math.Abs((int)(oldy - newy)) > 1)); + int dd = (int)((drawdist + Constants.RegionSize - 1) / Constants.RegionSize); + + int startX = (int)oldx - dd; + int startY = (int)oldy - dd; + + int endX = (int)oldx + dd; + int endY = (int)oldy + dd; + + return (newx < startX || endX < newx || newy < startY || endY < newy); } public static string FieldToString(byte[] bytes) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 98aa563a4f..95c771e60f 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -318,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agentCircuit.Id0 = currentAgentCircuit.Id0; } - if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) + if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) { // brand new agent, let's create a new caps seed agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); @@ -336,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // OK, it got this agent. Let's close some child agents sp.CloseChildAgents(newRegionX, newRegionY); IClientIPEndpoint ipepClient; - if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) + if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) { //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); #region IP Translation for NAT @@ -447,7 +447,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) + if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) { Thread.Sleep(5000); sp.Close(); @@ -521,14 +521,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return region; } - protected virtual bool NeedsNewAgent(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) + protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) { - return Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY); + return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); } - protected virtual bool NeedsClosing(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) + protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) { - return Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY); + return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); } protected virtual bool IsOutsideRegion(Scene s, Vector3 pos) @@ -1045,7 +1045,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_regionInfo != null) { - neighbours = RequestNeighbours(sp.Scene, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); + neighbours = RequestNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); } else { @@ -1272,8 +1272,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// - protected List RequestNeighbours(Scene pScene, uint pRegionLocX, uint pRegionLocY) + protected List RequestNeighbours(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY) { + Scene pScene = avatar.Scene; RegionInfo m_regionInfo = pScene.RegionInfo; Border[] northBorders = pScene.NorthBorders.ToArray(); @@ -1281,10 +1282,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Border[] eastBorders = pScene.EastBorders.ToArray(); Border[] westBorders = pScene.WestBorders.ToArray(); - // Legacy one region. Provided for simplicity while testing the all inclusive method in the else statement. + // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't + // clear what should be done with a "far view" given that megaregions already extended the + // view to include everything in the megaregion if (northBorders.Length <= 1 && southBorders.Length <= 1 && eastBorders.Length <= 1 && westBorders.Length <= 1) { - return pScene.GridService.GetNeighbours(m_regionInfo.ScopeID, m_regionInfo.RegionID); + int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance; + + int startX = (int)pRegionLocX * (int)Constants.RegionSize - dd + (int)(Constants.RegionSize/2); + int startY = (int)pRegionLocY * (int)Constants.RegionSize - dd + (int)(Constants.RegionSize/2); + + int endX = (int)pRegionLocX * (int)Constants.RegionSize + dd + (int)(Constants.RegionSize/2); + int endY = (int)pRegionLocY * (int)Constants.RegionSize + dd + (int)(Constants.RegionSize/2); + + List neighbours = + avatar.Scene.GridService.GetRegionRange(m_regionInfo.ScopeID, startX, endX, startY, endY); + + neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); + return neighbours; } else { diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 35dcd95aa0..79e76b4cbf 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -130,9 +130,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return region; } - protected override bool NeedsClosing(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) + protected override bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) { - if (base.NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) + if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) return true; int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ee1e0beee4..7def7e9ca3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -83,6 +83,13 @@ namespace OpenSim.Region.Framework.Scenes public bool m_useFlySlow; public bool m_usePreJump; public bool m_seeIntoRegionFromNeighbor; + + protected float m_defaultDrawDistance = 255.0f; + public float DefaultDrawDistance + { + get { return m_defaultDrawDistance; } + } + // TODO: need to figure out how allow client agents but deny // root agents when ACL denies access to root agent public bool m_strictAccessControl = true; @@ -627,6 +634,8 @@ namespace OpenSim.Region.Framework.Scenes // IConfig startupConfig = m_config.Configs["Startup"]; + m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance); + //Animation states m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); // TODO: Change default to true once the feature is supported diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 51b8dcc004..9e9481e815 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -626,7 +626,7 @@ namespace OpenSim.Region.Framework.Scenes Utils.LongToUInts(handle, out x, out y); x = x / Constants.RegionSize; y = y / Constants.RegionSize; - if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) + if (Util.IsOutsideView(DrawDistance, x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) { old.Add(handle); } @@ -700,6 +700,7 @@ namespace OpenSim.Region.Framework.Scenes private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() { + m_DrawDistance = world.DefaultDrawDistance; m_rootRegionHandle = reginfo.RegionHandle; m_controllingClient = client; m_firstname = m_controllingClient.FirstName; @@ -1279,7 +1280,11 @@ namespace OpenSim.Region.Framework.Scenes m_CameraUpAxis = agentData.CameraUpAxis; // The Agent's Draw distance setting - m_DrawDistance = agentData.Far; + // When we get to the point of re-computing neighbors everytime this + // changes, then start using the agent's drawdistance rather than the + // region's draw distance. + // m_DrawDistance = agentData.Far; + m_DrawDistance = Scene.DefaultDrawDistance; // Check if Client has camera in 'follow cam' or 'build' mode. Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); @@ -2913,7 +2918,7 @@ namespace OpenSim.Region.Framework.Scenes //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); - if (Util.IsOutsideView(x, newRegionX, y, newRegionY)) + if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) { byebyeRegions.Add(handle); } @@ -2989,7 +2994,12 @@ namespace OpenSim.Region.Framework.Scenes Vector3 offset = new Vector3(shiftx, shifty, 0f); - m_DrawDistance = cAgentData.Far; + // When we get to the point of re-computing neighbors everytime this + // changes, then start using the agent's drawdistance rather than the + // region's draw distance. + // m_DrawDistance = cAgentData.Far; + m_DrawDistance = Scene.DefaultDrawDistance; + if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!! m_pos = cAgentData.Position + offset; @@ -3139,7 +3149,11 @@ namespace OpenSim.Region.Framework.Scenes m_CameraLeftAxis = cAgent.LeftAxis; m_CameraUpAxis = cAgent.UpAxis; - m_DrawDistance = cAgent.Far; + // When we get to the point of re-computing neighbors everytime this + // changes, then start using the agent's drawdistance rather than the + // region's draw distance. + // m_DrawDistance = cAgent.Far; + m_DrawDistance = Scene.DefaultDrawDistance; if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) ControllingClient.SetChildAgentThrottle(cAgent.Throttles); diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 475d4a0c53..96ffb7ea6b 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -94,6 +94,13 @@ ; Warning! Don't use this with regions that have existing content!, This will likely break them CombineContiguousRegions = false + ; Extend the region's draw distance; 255m is the default which includes + ; one neighbor on each side of the current region, 767m would go three + ; neighbors on each side for a total of 49 regions in view. Warning, unless + ; all the regions have the same drawdistance, you will end up with strange + ; effects because the agents that get closed may be inconsistent. + ; DefaultDrawDistance = 255.0 + ; If you have only one region in an instance, or to avoid the many bugs ; that you can trigger in modules by restarting a region, set this to ; true to make the entire instance exit instead of restarting the region.