diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 270 |
1 files changed, 217 insertions, 53 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7004d23..183d8d1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -29,7 +29,9 @@ using System; | |||
29 | using System.Xml; | 29 | using System.Xml; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Threading; | ||
32 | using System.Timers; | 33 | using System.Timers; |
34 | using Timer = System.Timers.Timer; | ||
33 | using OpenMetaverse; | 35 | using OpenMetaverse; |
34 | using log4net; | 36 | using log4net; |
35 | using Nini.Config; | 37 | using Nini.Config; |
@@ -73,21 +75,40 @@ namespace OpenSim.Region.Framework.Scenes | |||
73 | 75 | ||
74 | public class ScenePresence : EntityBase, IScenePresence | 76 | public class ScenePresence : EntityBase, IScenePresence |
75 | { | 77 | { |
78 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
79 | |||
76 | // ~ScenePresence() | 80 | // ~ScenePresence() |
77 | // { | 81 | // { |
78 | // m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name); | 82 | // m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name); |
79 | // } | 83 | // } |
80 | 84 | ||
81 | private void TriggerScenePresenceUpdated() | 85 | public void TriggerScenePresenceUpdated() |
82 | { | 86 | { |
83 | if (m_scene != null) | 87 | if (m_scene != null) |
84 | m_scene.EventManager.TriggerScenePresenceUpdated(this); | 88 | m_scene.EventManager.TriggerScenePresenceUpdated(this); |
85 | } | 89 | } |
86 | 90 | ||
87 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
88 | |||
89 | public PresenceType PresenceType { get; private set; } | 91 | public PresenceType PresenceType { get; private set; } |
90 | 92 | ||
93 | private ScenePresenceStateMachine m_stateMachine; | ||
94 | |||
95 | /// <summary> | ||
96 | /// The current state of this presence. Governs only the existence lifecycle. See ScenePresenceStateMachine | ||
97 | /// for more details. | ||
98 | /// </summary> | ||
99 | public ScenePresenceState LifecycleState | ||
100 | { | ||
101 | get | ||
102 | { | ||
103 | return m_stateMachine.GetState(); | ||
104 | } | ||
105 | |||
106 | set | ||
107 | { | ||
108 | m_stateMachine.SetState(value); | ||
109 | } | ||
110 | } | ||
111 | |||
91 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); | 112 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); |
92 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); | 113 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); |
93 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); | 114 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); |
@@ -142,6 +163,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
142 | private Vector3 m_lastVelocity; | 163 | private Vector3 m_lastVelocity; |
143 | private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); | 164 | private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); |
144 | 165 | ||
166 | private bool m_followCamAuto = false; | ||
167 | |||
145 | 168 | ||
146 | private Vector3? m_forceToApply; | 169 | private Vector3? m_forceToApply; |
147 | private int m_userFlags; | 170 | private int m_userFlags; |
@@ -200,7 +223,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
200 | private float m_sitAvatarHeight = 2.0f; | 223 | private float m_sitAvatarHeight = 2.0f; |
201 | 224 | ||
202 | private Vector3 m_lastChildAgentUpdatePosition; | 225 | private Vector3 m_lastChildAgentUpdatePosition; |
203 | private Vector3 m_lastChildAgentUpdateCamPosition; | 226 | // private Vector3 m_lastChildAgentUpdateCamPosition; |
204 | 227 | ||
205 | private const int LAND_VELOCITYMAG_MAX = 12; | 228 | private const int LAND_VELOCITYMAG_MAX = 12; |
206 | 229 | ||
@@ -290,9 +313,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
290 | /// </summary> | 313 | /// </summary> |
291 | private Vector3 posLastSignificantMove; | 314 | private Vector3 posLastSignificantMove; |
292 | 315 | ||
293 | // For teleports and crossings callbacks | 316 | #region For teleports and crossings callbacks |
294 | string m_callbackURI; | 317 | |
295 | UUID m_originRegionID; | 318 | /// <summary> |
319 | /// In the V1 teleport protocol, the destination simulator sends ReleaseAgent to this address. | ||
320 | /// </summary> | ||
321 | private string m_callbackURI; | ||
322 | |||
323 | public UUID m_originRegionID; | ||
324 | |||
325 | /// <summary> | ||
326 | /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent | ||
327 | /// teleport is reusing the connection. | ||
328 | /// </summary> | ||
329 | /// <remarks>May be refactored or move somewhere else soon.</remarks> | ||
330 | public bool DoNotCloseAfterTeleport { get; set; } | ||
331 | |||
332 | #endregion | ||
296 | 333 | ||
297 | /// <value> | 334 | /// <value> |
298 | /// Script engines present in the scene | 335 | /// Script engines present in the scene |
@@ -795,7 +832,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
795 | 832 | ||
796 | public ScenePresence( | 833 | public ScenePresence( |
797 | IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) | 834 | IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) |
798 | { | 835 | { |
799 | AttachmentsSyncLock = new Object(); | 836 | AttachmentsSyncLock = new Object(); |
800 | AllowMovement = true; | 837 | AllowMovement = true; |
801 | IsChildAgent = true; | 838 | IsChildAgent = true; |
@@ -841,6 +878,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
841 | SetDirectionVectors(); | 878 | SetDirectionVectors(); |
842 | 879 | ||
843 | Appearance = appearance; | 880 | Appearance = appearance; |
881 | |||
882 | m_stateMachine = new ScenePresenceStateMachine(this); | ||
844 | } | 883 | } |
845 | 884 | ||
846 | private void RegionHeartbeatEnd(Scene scene) | 885 | private void RegionHeartbeatEnd(Scene scene) |
@@ -874,6 +913,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
874 | { | 913 | { |
875 | ControllingClient.OnCompleteMovementToRegion += CompleteMovement; | 914 | ControllingClient.OnCompleteMovementToRegion += CompleteMovement; |
876 | ControllingClient.OnAgentUpdate += HandleAgentUpdate; | 915 | ControllingClient.OnAgentUpdate += HandleAgentUpdate; |
916 | ControllingClient.OnAgentCameraUpdate += HandleAgentCamerasUpdate; | ||
877 | ControllingClient.OnAgentRequestSit += HandleAgentRequestSit; | 917 | ControllingClient.OnAgentRequestSit += HandleAgentRequestSit; |
878 | ControllingClient.OnAgentSit += HandleAgentSit; | 918 | ControllingClient.OnAgentSit += HandleAgentSit; |
879 | ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; | 919 | ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; |
@@ -937,7 +977,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
937 | /// </summary> | 977 | /// </summary> |
938 | public void MakeRootAgent(Vector3 pos, bool isFlying) | 978 | public void MakeRootAgent(Vector3 pos, bool isFlying) |
939 | { | 979 | { |
940 | m_log.DebugFormat( | 980 | m_log.InfoFormat( |
941 | "[SCENE]: Upgrading child to root agent for {0} in {1}", | 981 | "[SCENE]: Upgrading child to root agent for {0} in {1}", |
942 | Name, m_scene.RegionInfo.RegionName); | 982 | Name, m_scene.RegionInfo.RegionName); |
943 | 983 | ||
@@ -977,6 +1017,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
977 | 1017 | ||
978 | IsChildAgent = false; | 1018 | IsChildAgent = false; |
979 | 1019 | ||
1020 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag | ||
1021 | // set and prevent the close of the connection on a subsequent re-teleport. | ||
1022 | // Should not be needed if we are not trying to tell this region to close | ||
1023 | // DoNotCloseAfterTeleport = false; | ||
1024 | |||
980 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); | 1025 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); |
981 | if (gm != null) | 1026 | if (gm != null) |
982 | Grouptitle = gm.GetGroupTitle(m_uuid); | 1027 | Grouptitle = gm.GetGroupTitle(m_uuid); |
@@ -1153,7 +1198,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1153 | 1198 | ||
1154 | m_scene.EventManager.TriggerOnMakeRootAgent(this); | 1199 | m_scene.EventManager.TriggerOnMakeRootAgent(this); |
1155 | 1200 | ||
1156 | m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd; | ||
1157 | } | 1201 | } |
1158 | 1202 | ||
1159 | public int GetStateSource() | 1203 | public int GetStateSource() |
@@ -1306,7 +1350,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
1306 | 1350 | ||
1307 | public void StopFlying() | 1351 | public void StopFlying() |
1308 | { | 1352 | { |
1309 | ControllingClient.StopFlying(this); | 1353 | Vector3 pos = AbsolutePosition; |
1354 | if (Appearance.AvatarHeight != 127.0f) | ||
1355 | pos += new Vector3(0f, 0f, (Appearance.AvatarHeight / 6f)); | ||
1356 | else | ||
1357 | pos += new Vector3(0f, 0f, (1.56f / 6f)); | ||
1358 | |||
1359 | AbsolutePosition = pos; | ||
1360 | |||
1361 | // attach a suitable collision plane regardless of the actual situation to force the LLClient to land. | ||
1362 | // Collision plane below the avatar's position a 6th of the avatar's height is suitable. | ||
1363 | // Mind you, that this method doesn't get called if the avatar's velocity magnitude is greater then a | ||
1364 | // certain amount.. because the LLClient wouldn't land in that situation anyway. | ||
1365 | |||
1366 | // why are we still testing for this really old height value default??? | ||
1367 | if (Appearance.AvatarHeight != 127.0f) | ||
1368 | CollisionPlane = new Vector4(0, 0, 0, pos.Z - Appearance.AvatarHeight / 6f); | ||
1369 | else | ||
1370 | CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f / 6f)); | ||
1371 | |||
1372 | ControllingClient.SendAgentTerseUpdate(this); | ||
1310 | } | 1373 | } |
1311 | 1374 | ||
1312 | /// <summary> | 1375 | /// <summary> |
@@ -1480,6 +1543,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
1480 | 1543 | ||
1481 | } | 1544 | } |
1482 | 1545 | ||
1546 | private bool WaitForUpdateAgent(IClientAPI client) | ||
1547 | { | ||
1548 | // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero | ||
1549 | int count = 50; | ||
1550 | while (m_originRegionID.Equals(UUID.Zero) && count-- > 0) | ||
1551 | { | ||
1552 | m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); | ||
1553 | Thread.Sleep(200); | ||
1554 | } | ||
1555 | |||
1556 | if (m_originRegionID.Equals(UUID.Zero)) | ||
1557 | { | ||
1558 | // Movement into region will fail | ||
1559 | m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name); | ||
1560 | return false; | ||
1561 | } | ||
1562 | |||
1563 | return true; | ||
1564 | } | ||
1565 | |||
1483 | /// <summary> | 1566 | /// <summary> |
1484 | /// Complete Avatar's movement into the region. | 1567 | /// Complete Avatar's movement into the region. |
1485 | /// </summary> | 1568 | /// </summary> |
@@ -1497,6 +1580,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1497 | "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", | 1580 | "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", |
1498 | client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); | 1581 | client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); |
1499 | 1582 | ||
1583 | // Make sure it's not a login agent. We don't want to wait for updates during login | ||
1584 | if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) | ||
1585 | { | ||
1586 | // Let's wait until UpdateAgent (called by departing region) is done | ||
1587 | if (!WaitForUpdateAgent(client)) | ||
1588 | // The sending region never sent the UpdateAgent data, we have to refuse | ||
1589 | return; | ||
1590 | } | ||
1591 | |||
1500 | Vector3 look = Velocity; | 1592 | Vector3 look = Velocity; |
1501 | 1593 | ||
1502 | // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) | 1594 | // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) |
@@ -1518,11 +1610,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1518 | 1610 | ||
1519 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1611 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1520 | MakeRootAgent(AbsolutePosition, flying); | 1612 | MakeRootAgent(AbsolutePosition, flying); |
1613 | |||
1614 | // Tell the client that we're totally ready | ||
1521 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); | 1615 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); |
1522 | 1616 | ||
1617 | // Remember in HandleUseCircuitCode, we delayed this to here | ||
1618 | if (m_teleportFlags > 0) | ||
1619 | SendInitialDataToMe(); | ||
1620 | |||
1523 | // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); | 1621 | // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); |
1524 | 1622 | ||
1525 | if ((m_callbackURI != null) && !m_callbackURI.Equals("")) | 1623 | if (!string.IsNullOrEmpty(m_callbackURI)) |
1526 | { | 1624 | { |
1527 | // We cannot sleep here since this would hold up the inbound packet processing thread, as | 1625 | // We cannot sleep here since this would hold up the inbound packet processing thread, as |
1528 | // CompleteMovement() is executed synchronously. However, it might be better to delay the release | 1626 | // CompleteMovement() is executed synchronously. However, it might be better to delay the release |
@@ -1550,7 +1648,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1550 | // Create child agents in neighbouring regions | 1648 | // Create child agents in neighbouring regions |
1551 | if (openChildAgents && !IsChildAgent) | 1649 | if (openChildAgents && !IsChildAgent) |
1552 | { | 1650 | { |
1553 | |||
1554 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | 1651 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); |
1555 | if (m_agentTransfer != null) | 1652 | if (m_agentTransfer != null) |
1556 | m_agentTransfer.EnableChildAgents(this); | 1653 | m_agentTransfer.EnableChildAgents(this); |
@@ -1573,6 +1670,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1573 | // m_log.DebugFormat( | 1670 | // m_log.DebugFormat( |
1574 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", | 1671 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", |
1575 | // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); | 1672 | // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); |
1673 | |||
1576 | } | 1674 | } |
1577 | 1675 | ||
1578 | /// <summary> | 1676 | /// <summary> |
@@ -1653,9 +1751,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1653 | /// </summary> | 1751 | /// </summary> |
1654 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | 1752 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) |
1655 | { | 1753 | { |
1656 | // m_log.DebugFormat( | 1754 | //m_log.DebugFormat( |
1657 | // "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", | 1755 | // "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", |
1658 | // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); | 1756 | // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); |
1659 | 1757 | ||
1660 | if (IsChildAgent) | 1758 | if (IsChildAgent) |
1661 | { | 1759 | { |
@@ -1663,10 +1761,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1663 | return; | 1761 | return; |
1664 | } | 1762 | } |
1665 | 1763 | ||
1666 | ++m_movementUpdateCount; | ||
1667 | if (m_movementUpdateCount < 1) | ||
1668 | m_movementUpdateCount = 1; | ||
1669 | |||
1670 | #region Sanity Checking | 1764 | #region Sanity Checking |
1671 | 1765 | ||
1672 | // This is irritating. Really. | 1766 | // This is irritating. Really. |
@@ -1697,21 +1791,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1697 | 1791 | ||
1698 | AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; | 1792 | AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; |
1699 | 1793 | ||
1700 | // Camera location in world. We'll need to raytrace | ||
1701 | // from this location from time to time. | ||
1702 | CameraPosition = agentData.CameraCenter; | ||
1703 | if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance) | ||
1704 | { | ||
1705 | ReprioritizeUpdates(); | ||
1706 | m_lastCameraPosition = CameraPosition; | ||
1707 | } | ||
1708 | |||
1709 | // Use these three vectors to figure out what the agent is looking at | ||
1710 | // Convert it to a Matrix and/or Quaternion | ||
1711 | CameraAtAxis = agentData.CameraAtAxis; | ||
1712 | CameraLeftAxis = agentData.CameraLeftAxis; | ||
1713 | CameraUpAxis = agentData.CameraUpAxis; | ||
1714 | |||
1715 | // The Agent's Draw distance setting | 1794 | // The Agent's Draw distance setting |
1716 | // When we get to the point of re-computing neighbors everytime this | 1795 | // When we get to the point of re-computing neighbors everytime this |
1717 | // changes, then start using the agent's drawdistance rather than the | 1796 | // changes, then start using the agent's drawdistance rather than the |
@@ -1783,8 +1862,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1783 | // Here's where you get them. | 1862 | // Here's where you get them. |
1784 | m_AgentControlFlags = flags; | 1863 | m_AgentControlFlags = flags; |
1785 | m_headrotation = agentData.HeadRotation; | 1864 | m_headrotation = agentData.HeadRotation; |
1865 | byte oldState = State; | ||
1786 | State = agentData.State; | 1866 | State = agentData.State; |
1787 | 1867 | ||
1868 | // We need to send this back to the client in order to stop the edit beams | ||
1869 | if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None) | ||
1870 | ControllingClient.SendAgentTerseUpdate(this); | ||
1871 | |||
1872 | |||
1788 | PhysicsActor actor = PhysicsActor; | 1873 | PhysicsActor actor = PhysicsActor; |
1789 | if (actor == null) | 1874 | if (actor == null) |
1790 | { | 1875 | { |
@@ -1996,10 +2081,78 @@ namespace OpenSim.Region.Framework.Scenes | |||
1996 | SendControlsToScripts(flagsForScripts); | 2081 | SendControlsToScripts(flagsForScripts); |
1997 | } | 2082 | } |
1998 | 2083 | ||
2084 | // We need to send this back to the client in order to see the edit beams | ||
2085 | if ((State & (uint)AgentState.Editing) != 0) | ||
2086 | ControllingClient.SendAgentTerseUpdate(this); | ||
2087 | |||
1999 | m_scene.EventManager.TriggerOnClientMovement(this); | 2088 | m_scene.EventManager.TriggerOnClientMovement(this); |
2000 | TriggerScenePresenceUpdated(); | ||
2001 | } | 2089 | } |
2002 | 2090 | ||
2091 | |||
2092 | /// <summary> | ||
2093 | /// This is the event handler for client cameras. If a client is moving, or moving the camera, this event is triggering. | ||
2094 | /// </summary> | ||
2095 | private void HandleAgentCamerasUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | ||
2096 | { | ||
2097 | //m_log.DebugFormat( | ||
2098 | // "[SCENE PRESENCE]: In {0} received agent camera update from {1}, flags {2}", | ||
2099 | // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); | ||
2100 | |||
2101 | if (IsChildAgent) | ||
2102 | { | ||
2103 | // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); | ||
2104 | return; | ||
2105 | } | ||
2106 | |||
2107 | ++m_movementUpdateCount; | ||
2108 | if (m_movementUpdateCount < 1) | ||
2109 | m_movementUpdateCount = 1; | ||
2110 | |||
2111 | // AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; | ||
2112 | |||
2113 | // Camera location in world. We'll need to raytrace | ||
2114 | // from this location from time to time. | ||
2115 | CameraPosition = agentData.CameraCenter; | ||
2116 | if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance) | ||
2117 | { | ||
2118 | ReprioritizeUpdates(); | ||
2119 | m_lastCameraPosition = CameraPosition; | ||
2120 | } | ||
2121 | |||
2122 | // Use these three vectors to figure out what the agent is looking at | ||
2123 | // Convert it to a Matrix and/or Quaternion | ||
2124 | CameraAtAxis = agentData.CameraAtAxis; | ||
2125 | CameraLeftAxis = agentData.CameraLeftAxis; | ||
2126 | CameraUpAxis = agentData.CameraUpAxis; | ||
2127 | |||
2128 | // The Agent's Draw distance setting | ||
2129 | // When we get to the point of re-computing neighbors everytime this | ||
2130 | // changes, then start using the agent's drawdistance rather than the | ||
2131 | // region's draw distance. | ||
2132 | // DrawDistance = agentData.Far; | ||
2133 | DrawDistance = Scene.DefaultDrawDistance; | ||
2134 | |||
2135 | // Check if Client has camera in 'follow cam' or 'build' mode. | ||
2136 | Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation); | ||
2137 | |||
2138 | m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f) | ||
2139 | && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; | ||
2140 | |||
2141 | |||
2142 | //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); | ||
2143 | // Raycast from the avatar's head to the camera to see if there's anything blocking the view | ||
2144 | if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) | ||
2145 | { | ||
2146 | if (m_followCamAuto) | ||
2147 | { | ||
2148 | Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; | ||
2149 | m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback); | ||
2150 | } | ||
2151 | } | ||
2152 | |||
2153 | TriggerScenePresenceUpdated(); | ||
2154 | } | ||
2155 | |||
2003 | /// <summary> | 2156 | /// <summary> |
2004 | /// Calculate an update to move the presence to the set target. | 2157 | /// Calculate an update to move the presence to the set target. |
2005 | /// </summary> | 2158 | /// </summary> |
@@ -2309,6 +2462,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2309 | AddToPhysicalScene(false); | 2462 | AddToPhysicalScene(false); |
2310 | 2463 | ||
2311 | Animator.TrySetMovementAnimation("STAND"); | 2464 | Animator.TrySetMovementAnimation("STAND"); |
2465 | TriggerScenePresenceUpdated(); | ||
2312 | } | 2466 | } |
2313 | 2467 | ||
2314 | private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) | 2468 | private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) |
@@ -2407,7 +2561,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2407 | ControllingClient.SendSitResponse( | 2561 | ControllingClient.SendSitResponse( |
2408 | part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); | 2562 | part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); |
2409 | 2563 | ||
2410 | m_requestedSitTargetUUID = targetID; | 2564 | m_requestedSitTargetUUID = part.UUID; |
2411 | 2565 | ||
2412 | HandleAgentSit(ControllingClient, UUID); | 2566 | HandleAgentSit(ControllingClient, UUID); |
2413 | 2567 | ||
@@ -2435,7 +2589,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2435 | if (part != null) | 2589 | if (part != null) |
2436 | { | 2590 | { |
2437 | m_requestedSitTargetID = part.LocalId; | 2591 | m_requestedSitTargetID = part.LocalId; |
2438 | m_requestedSitTargetUUID = targetID; | 2592 | m_requestedSitTargetUUID = part.UUID; |
2439 | 2593 | ||
2440 | } | 2594 | } |
2441 | else | 2595 | else |
@@ -2554,6 +2708,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2554 | 2708 | ||
2555 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) | 2709 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) |
2556 | { | 2710 | { |
2711 | if (IsChildAgent) | ||
2712 | return; | ||
2713 | |||
2557 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); | 2714 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); |
2558 | 2715 | ||
2559 | if (part != null) | 2716 | if (part != null) |
@@ -2634,14 +2791,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2634 | } | 2791 | } |
2635 | Animator.TrySetMovementAnimation(sitAnimation); | 2792 | Animator.TrySetMovementAnimation(sitAnimation); |
2636 | SendAvatarDataToAllAgents(); | 2793 | SendAvatarDataToAllAgents(); |
2794 | TriggerScenePresenceUpdated(); | ||
2637 | } | 2795 | } |
2638 | } | 2796 | } |
2639 | 2797 | ||
2640 | public void HandleAgentSitOnGround() | 2798 | public void HandleAgentSitOnGround() |
2641 | { | 2799 | { |
2800 | if (IsChildAgent) | ||
2801 | return; | ||
2802 | |||
2642 | // m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. | 2803 | // m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. |
2643 | m_AngularVelocity = Vector3.Zero; | 2804 | m_AngularVelocity = Vector3.Zero; |
2644 | Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); | 2805 | Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); |
2806 | TriggerScenePresenceUpdated(); | ||
2645 | SitGround = true; | 2807 | SitGround = true; |
2646 | RemoveFromPhysicalScene(); | 2808 | RemoveFromPhysicalScene(); |
2647 | } | 2809 | } |
@@ -2658,11 +2820,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2658 | public void HandleStartAnim(IClientAPI remoteClient, UUID animID) | 2820 | public void HandleStartAnim(IClientAPI remoteClient, UUID animID) |
2659 | { | 2821 | { |
2660 | Animator.AddAnimation(animID, UUID.Zero); | 2822 | Animator.AddAnimation(animID, UUID.Zero); |
2823 | TriggerScenePresenceUpdated(); | ||
2661 | } | 2824 | } |
2662 | 2825 | ||
2663 | public void HandleStopAnim(IClientAPI remoteClient, UUID animID) | 2826 | public void HandleStopAnim(IClientAPI remoteClient, UUID animID) |
2664 | { | 2827 | { |
2665 | Animator.RemoveAnimation(animID, false); | 2828 | Animator.RemoveAnimation(animID, false); |
2829 | TriggerScenePresenceUpdated(); | ||
2666 | } | 2830 | } |
2667 | 2831 | ||
2668 | public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack) | 2832 | public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack) |
@@ -2880,11 +3044,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2880 | SendOtherAgentsAppearanceToMe(); | 3044 | SendOtherAgentsAppearanceToMe(); |
2881 | 3045 | ||
2882 | EntityBase[] entities = Scene.Entities.GetEntities(); | 3046 | EntityBase[] entities = Scene.Entities.GetEntities(); |
2883 | foreach(EntityBase e in entities) | 3047 | foreach (EntityBase e in entities) |
2884 | { | 3048 | { |
2885 | if (e != null && e is SceneObjectGroup) | 3049 | if (e != null && e is SceneObjectGroup) |
2886 | ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); | 3050 | ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); |
2887 | } | 3051 | } |
3052 | |||
2888 | }); | 3053 | }); |
2889 | } | 3054 | } |
2890 | 3055 | ||
@@ -3079,11 +3244,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3079 | } | 3244 | } |
3080 | 3245 | ||
3081 | // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m | 3246 | // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m |
3082 | if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || | 3247 | if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) |
3083 | Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) | ||
3084 | { | 3248 | { |
3085 | m_lastChildAgentUpdatePosition = AbsolutePosition; | 3249 | m_lastChildAgentUpdatePosition = AbsolutePosition; |
3086 | m_lastChildAgentUpdateCamPosition = CameraPosition; | 3250 | // m_lastChildAgentUpdateCamPosition = CameraPosition; |
3087 | 3251 | ||
3088 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); | 3252 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); |
3089 | cadu.ActiveGroupID = UUID.Zero.Guid; | 3253 | cadu.ActiveGroupID = UUID.Zero.Guid; |
@@ -3110,7 +3274,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3110 | cadu.Velocity = Velocity; | 3274 | cadu.Velocity = Velocity; |
3111 | 3275 | ||
3112 | AgentPosition agentpos = new AgentPosition(); | 3276 | AgentPosition agentpos = new AgentPosition(); |
3113 | agentpos.CopyFrom(cadu); | 3277 | agentpos.CopyFrom(cadu, ControllingClient.SessionId); |
3114 | 3278 | ||
3115 | // Let's get this out of the update loop | 3279 | // Let's get this out of the update loop |
3116 | Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); | 3280 | Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); |
@@ -3294,11 +3458,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3294 | } | 3458 | } |
3295 | } | 3459 | } |
3296 | 3460 | ||
3297 | public void RestoreInCurrentScene() | ||
3298 | { | ||
3299 | AddToPhysicalScene(false); // not exactly false | ||
3300 | } | ||
3301 | |||
3302 | public void Reset() | 3461 | public void Reset() |
3303 | { | 3462 | { |
3304 | // m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName); | 3463 | // m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName); |
@@ -3348,10 +3507,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3348 | if (byebyeRegions.Count > 0) | 3507 | if (byebyeRegions.Count > 0) |
3349 | { | 3508 | { |
3350 | m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); | 3509 | m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); |
3351 | Util.FireAndForget(delegate | 3510 | |
3352 | { | 3511 | AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID); |
3353 | m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, byebyeRegions); | 3512 | string auth = string.Empty; |
3354 | }); | 3513 | if (acd != null) |
3514 | auth = acd.SessionID.ToString(); | ||
3515 | m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions); | ||
3355 | } | 3516 | } |
3356 | 3517 | ||
3357 | foreach (ulong handle in byebyeRegions) | 3518 | foreach (ulong handle in byebyeRegions) |
@@ -3452,6 +3613,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3452 | 3613 | ||
3453 | cAgent.AgentID = UUID; | 3614 | cAgent.AgentID = UUID; |
3454 | cAgent.RegionID = Scene.RegionInfo.RegionID; | 3615 | cAgent.RegionID = Scene.RegionInfo.RegionID; |
3616 | cAgent.SessionID = ControllingClient.SessionId; | ||
3455 | 3617 | ||
3456 | cAgent.Position = AbsolutePosition; | 3618 | cAgent.Position = AbsolutePosition; |
3457 | cAgent.Velocity = m_velocity; | 3619 | cAgent.Velocity = m_velocity; |
@@ -3694,7 +3856,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3694 | 3856 | ||
3695 | // if (m_updateCount > 0) | 3857 | // if (m_updateCount > 0) |
3696 | // { | 3858 | // { |
3697 | Animator.UpdateMovementAnimations(); | 3859 | if (Animator.UpdateMovementAnimations()) |
3860 | TriggerScenePresenceUpdated(); | ||
3698 | // m_updateCount--; | 3861 | // m_updateCount--; |
3699 | // } | 3862 | // } |
3700 | 3863 | ||
@@ -3858,6 +4021,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3858 | // Animator.Close(); | 4021 | // Animator.Close(); |
3859 | Animator = null; | 4022 | Animator = null; |
3860 | 4023 | ||
4024 | LifecycleState = ScenePresenceState.Removed; | ||
3861 | } | 4025 | } |
3862 | 4026 | ||
3863 | public void AddAttachment(SceneObjectGroup gobj) | 4027 | public void AddAttachment(SceneObjectGroup gobj) |