From 5cf96daaf29209e065b852a0eefeb7f5dbd88b48 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Tue, 22 Jan 2008 08:52:51 +0000 Subject: * Enabled dead region tracking for ChildAgentDataUpdates ** If the region fails 3 times, then ChildAgentDataUpdates no longer get sent to that region * Enabled Child_Get_Tasks in grid mode. * When Child_Get_Tasks is enabled on neighbor regions, the neighbor region uses the client's draw distance to send out prim. This is a lot less likely to flood the client now since the ChildAgentDataUpdate contains both the throttle settings and the draw distance. This means that with this enabled, you can see prim in other regions in grid mode. Very experimental. --- OpenSim/Region/Environment/Scenes/InnerScene.cs | 30 ++++++----- OpenSim/Region/Environment/Scenes/Scene.cs | 19 +++++-- .../Scenes/SceneCommunicationService.cs | 33 ++++++------ OpenSim/Region/Environment/Scenes/ScenePresence.cs | 58 ++++++++++++++++++++-- 4 files changed, 105 insertions(+), 35 deletions(-) (limited to 'OpenSim/Region/Environment') diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 9aa3f20..6c0ed28 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs @@ -537,20 +537,24 @@ namespace OpenSim.Region.Environment.Scenes // the initial update for and what we'll use to limit the // space we check for new objects on movement. - if (presence.IsChildAgent) + if (presence.IsChildAgent && m_parentScene.m_sendTasksToChild) { - //Vector3 avPosition = new Vector3(presence.AbsolutePosition.X,presence.AbsolutePosition.Y,presence.AbsolutePosition.Z); - //LLVector3 oLoc = ((SceneObjectGroup)ent).AbsolutePosition; - //Vector3 objPosition = new Vector3(oLoc.X,oLoc.Y,oLoc.Z); - //float distResult = Vector3Distance(avPosition, objPosition); - //if (distResult > 512) - //{ - //int x = 0; - //} - //if (distResult < presence.DrawDistance) - //{ - ((SceneObjectGroup) ent).ScheduleFullUpdateToAvatar(presence); - //} + LLVector3 oLoc = ((SceneObjectGroup)ent).AbsolutePosition; + float distResult = (float)Util.GetDistanceTo(presence.AbsolutePosition,oLoc); + + //MainLog.Instance.Verbose("DISTANCE", distResult.ToString()); + + if (distResult > 60) + { + int x = 0; + } + if (distResult < presence.DrawDistance) + { + // Send Only if we don't already know about it. + // KnownPrim also makes the prim known when called. + if (!presence.KnownPrim(((SceneObjectGroup) ent).UUID)) + ((SceneObjectGroup) ent).ScheduleFullUpdateToAvatar(presence); + } } else { diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 64b9abb..f32de2e 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1391,6 +1391,8 @@ namespace OpenSim.Region.Environment.Scenes m_sceneGridService.OnCloseAgentConnection += CloseConnection; m_sceneGridService.OnRegionUp += OtherRegionUp; m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; + + @@ -1492,19 +1494,25 @@ namespace OpenSim.Region.Environment.Scenes public virtual bool IncomingChildAgentDataUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) { ScenePresence childAgentUpdate = GetScenePresence(new LLUUID(cAgentData.AgentID)); - if (!(childAgentUpdate.Equals(null))) + if (childAgentUpdate != null) { // I can't imagine *yet* why we would get an update if the agent is a root agent.. // however to avoid a race condition crossing borders.. if (childAgentUpdate.IsChildAgent) { + uint rRegionX = (uint)(cAgentData.regionHandle >> 40); + uint rRegionY = (((uint)(cAgentData.regionHandle)) >> 8); + uint tRegionX = RegionInfo.RegionLocX; + uint tRegionY = RegionInfo.RegionLocY; //Send Data to ScenePresence - childAgentUpdate.ChildAgentDataUpdate(cAgentData); + childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); // Not Implemented: //TODO: Do we need to pass the message on to one of our neighbors? + } + return true; } - return true; + return false; } /// @@ -1614,6 +1622,11 @@ namespace OpenSim.Region.Environment.Scenes return m_sceneGridService.CrossToNeighbouringRegion(regionHandle, agentID, position, isFlying); } + public void SendOutChildAgentUpdates(ChildAgentDataUpdate cadu, ScenePresence presence) + { + m_sceneGridService.SendChildAgentDataUpdate(cadu, presence); + } + #endregion #region Module Methods diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index a9c2c2f..805b44c 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -332,7 +332,7 @@ namespace OpenSim.Region.Environment.Scenes //bool val = m_commsProvider.InterRegion.RegionUp(new SearializableRegionInfo(region)); } - public delegate void SendChildAgentDataUpdateDelegate(ulong regionHandle, ChildAgentDataUpdate cAgentData); + public delegate void SendChildAgentDataUpdateDelegate(ChildAgentDataUpdate cAgentData, ScenePresence presence); /// /// This informs all neighboring regions about the settings of it's child agent. @@ -341,18 +341,22 @@ namespace OpenSim.Region.Environment.Scenes /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. /// /// - private void SendChildAgentDataUpdateAsync(ulong regionHandle, ChildAgentDataUpdate cAgentData) + private void SendChildAgentDataUpdateAsync(ChildAgentDataUpdate cAgentData, ScenePresence presence) { - MainLog.Instance.Notice("INTERGRID", "Informing a neighbor about my agent."); - bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); + //MainLog.Instance.Notice("INTERGRID", "Informing neighbors about my agent."); - if (regionAccepted) - { - MainLog.Instance.Notice("INTERGRID", "Completed sending a neighbor an update about my agent"); - } - else + foreach (ulong regionHandle in presence.KnownChildRegions) { - MainLog.Instance.Notice("INTERGRID", "Failed sending a neighbor an update about my agent"); + bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); + + if (regionAccepted) + { + //MainLog.Instance.Notice("INTERGRID", "Completed sending a neighbor an update about my agent"); + } + else + { + //MainLog.Instance.Notice("INTERGRID", "Failed sending a neighbor an update about my agent"); + } } } @@ -362,11 +366,11 @@ namespace OpenSim.Region.Environment.Scenes icon.EndInvoke(iar); } - public void SendChildAgentDataUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) + public void SendChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, ScenePresence presence) { // This assumes that we know what our neighbors are. SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; - d.BeginInvoke(regionHandle, cAgentData, + d.BeginInvoke(cAgentData,presence, SendChildAgentDataUpdateCompleted, d); } @@ -374,11 +378,8 @@ namespace OpenSim.Region.Environment.Scenes public delegate void SendCloseChildAgentDelegate( ScenePresence presence); /// - /// This informs all neighboring regions about the settings of it's child agent. + /// This Closes child agents on neighboring regions /// Calls an asynchronous method to do so.. so it doesn't lag the sim. - /// - /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. - /// /// private void SendCloseChildAgentAsync(ScenePresence presence) { diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index c8310e4..f37b38b 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -55,6 +55,7 @@ namespace OpenSim.Region.Environment.Scenes private LLVector3 m_requestedSitOffset = new LLVector3(); private float m_sitAvatarHeight = 2.0f; private float m_godlevel = 0; + private LLVector3 m_LastChildAgentUpdatePosition = new LLVector3(); private int m_perfMonMS = 0; @@ -90,6 +91,8 @@ namespace OpenSim.Region.Environment.Scenes private LLQuaternion m_headrotation = new LLQuaternion(); private byte m_state = (byte) 0; + private List m_knownPrimUUID = new List(); + // Agent's Draw distance. protected float m_DrawDistance = 0f; @@ -136,6 +139,17 @@ namespace OpenSim.Region.Environment.Scenes get { return m_physicsActor; } } + public bool KnownPrim(LLUUID primID) + { + if (m_knownPrimUUID.Contains(primID)) + { + return true; + } + m_knownPrimUUID.Add(primID); + return false; + } + + public bool Updated { set { m_updateflag = value; } @@ -499,7 +513,7 @@ namespace OpenSim.Region.Environment.Scenes m_scene.CommsManager.UserProfileCacheService.UpdateUserInventory(m_uuid); //if (!m_gotAllObjectsInScene) //{ - //m_scene.SendAllSceneObjectsToClient(this); + m_scene.SendAllSceneObjectsToClient(this); //m_gotAllObjectsInScene = true; //} } @@ -1408,6 +1422,29 @@ namespace OpenSim.Region.Environment.Scenes m_scene.NotifyMyCoarseLocationChange(); } } + + // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m + if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32) + { + ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); + cadu.ActiveGroupID=LLUUID.Zero.UUID; + cadu.AgentID = UUID.UUID; + cadu.alwaysrun = m_setAlwaysRun; + cadu.AVHeight = m_avHeight; + LLVector3 tempCameraCenter = new LLVector3(m_CameraCenter.x, m_CameraCenter.y, m_CameraCenter.z); + cadu.cameraPosition = new sLLVector3(tempCameraCenter); + cadu.drawdistance = m_DrawDistance; + cadu.godlevel = m_godlevel; + cadu.GroupAccess = 0; + cadu.Position = new sLLVector3(AbsolutePosition); + cadu.regionHandle = m_scene.RegionInfo.RegionHandle; + cadu.throttles = ControllingClient.GetThrottlesPacked(1f); + cadu.Velocity = new sLLVector3(Velocity); + m_scene.SendOutChildAgentUpdates(cadu,this); + m_LastChildAgentUpdatePosition.X = AbsolutePosition.X; + m_LastChildAgentUpdatePosition.Y = AbsolutePosition.Y; + m_LastChildAgentUpdatePosition.Z = AbsolutePosition.Z; + } } #endregion @@ -1532,15 +1569,30 @@ namespace OpenSim.Region.Environment.Scenes /// This updates important decision making data about a child agent /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region /// - public void ChildAgentDataUpdate(ChildAgentDataUpdate cAgentData) + public void ChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) { // + int shiftx = ((int)rRegionX - (int)tRegionX) * 256; + int shifty = ((int)rRegionY - (int)tRegionY) * 256; + m_DrawDistance = cAgentData.drawdistance; - m_pos = new LLVector3(cAgentData.Position.x, cAgentData.Position.y, cAgentData.Position.z); + m_pos = new LLVector3(cAgentData.Position.x + shiftx, cAgentData.Position.y + shifty, cAgentData.Position.z); + + // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region m_CameraCenter = new Vector3(cAgentData.cameraPosition.x, cAgentData.cameraPosition.y, cAgentData.cameraPosition.z); + + m_godlevel = cAgentData.godlevel; + SetHeight(cAgentData.AVHeight); + ControllingClient.SetChildAgentThrottle(cAgentData.throttles); + + + + // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. + if (m_scene.m_sendTasksToChild) + m_scene.SendAllSceneObjectsToClient(this); //cAgentData.AVHeight; //cAgentData.regionHandle; //m_velocity = cAgentData.Velocity; -- cgit v1.1