aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs738
1 files changed, 533 insertions, 205 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 7004d23..f57d4fe 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -29,7 +29,9 @@ using System;
29using System.Xml; 29using System.Xml;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection; 31using System.Reflection;
32using System.Threading;
32using System.Timers; 33using System.Timers;
34using Timer = System.Timers.Timer;
33using OpenMetaverse; 35using OpenMetaverse;
34using log4net; 36using log4net;
35using Nini.Config; 37using Nini.Config;
@@ -73,21 +75,50 @@ 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
112 /// <summary>
113 /// This exists to prevent race conditions between two CompleteMovement threads if the simulator is slow and
114 /// the viewer fires these in quick succession.
115 /// </summary>
116 /// <remarks>
117 /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement
118 /// regulation done there.
119 /// </remarks>
120 private object m_completeMovementLock = new object();
121
91// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 122// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
92 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); 123 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); 124 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
@@ -142,6 +173,8 @@ namespace OpenSim.Region.Framework.Scenes
142 private Vector3 m_lastVelocity; 173 private Vector3 m_lastVelocity;
143 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); 174 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
144 175
176 private bool m_followCamAuto = false;
177
145 178
146 private Vector3? m_forceToApply; 179 private Vector3? m_forceToApply;
147 private int m_userFlags; 180 private int m_userFlags;
@@ -200,7 +233,7 @@ namespace OpenSim.Region.Framework.Scenes
200 private float m_sitAvatarHeight = 2.0f; 233 private float m_sitAvatarHeight = 2.0f;
201 234
202 private Vector3 m_lastChildAgentUpdatePosition; 235 private Vector3 m_lastChildAgentUpdatePosition;
203 private Vector3 m_lastChildAgentUpdateCamPosition; 236// private Vector3 m_lastChildAgentUpdateCamPosition;
204 237
205 private const int LAND_VELOCITYMAG_MAX = 12; 238 private const int LAND_VELOCITYMAG_MAX = 12;
206 239
@@ -290,9 +323,37 @@ namespace OpenSim.Region.Framework.Scenes
290 /// </summary> 323 /// </summary>
291 private Vector3 posLastSignificantMove; 324 private Vector3 posLastSignificantMove;
292 325
293 // For teleports and crossings callbacks 326 #region For teleports and crossings callbacks
294 string m_callbackURI; 327
295 UUID m_originRegionID; 328 /// <summary>
329 /// In the V1 teleport protocol, the destination simulator sends ReleaseAgent to this address.
330 /// </summary>
331 private string m_callbackURI;
332
333 /// <summary>
334 /// Records the region from which this presence originated, if not from login.
335 /// </summary>
336 /// <remarks>
337 /// Also acts as a signal in the teleport V2 process to release UpdateAgent after a viewer has triggered
338 /// CompleteMovement and made the previous child agent a root agent.
339 /// </remarks>
340 private UUID m_originRegionID;
341
342 /// <summary>
343 /// This object is used as a lock before accessing m_originRegionID to make sure that every thread is seeing
344 /// the very latest value and not using some cached version. Cannot make m_originRegionID itself volatite as
345 /// it is a value type.
346 /// </summary>
347 private object m_originRegionIDAccessLock = new object();
348
349 /// <summary>
350 /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
351 /// teleport is reusing the connection.
352 /// </summary>
353 /// <remarks>May be refactored or move somewhere else soon.</remarks>
354 public bool DoNotCloseAfterTeleport { get; set; }
355
356 #endregion
296 357
297 /// <value> 358 /// <value>
298 /// Script engines present in the scene 359 /// Script engines present in the scene
@@ -309,15 +370,12 @@ namespace OpenSim.Region.Framework.Scenes
309 /// <summary> 370 /// <summary>
310 /// Record user movement inputs. 371 /// Record user movement inputs.
311 /// </summary> 372 /// </summary>
312 public byte MovementFlag { get; private set; } 373 public uint MovementFlag { get; private set; }
313 374
314 private bool m_updateflag; 375 /// <summary>
315 376 /// Is the agent stop control flag currently active?
316 public bool Updated 377 /// </summary>
317 { 378 public bool AgentControlStopActive { get; private set; }
318 set { m_updateflag = value; }
319 get { return m_updateflag; }
320 }
321 379
322 private bool m_invulnerable = true; 380 private bool m_invulnerable = true;
323 381
@@ -462,6 +520,7 @@ namespace OpenSim.Region.Framework.Scenes
462 } 520 }
463 else 521 else
464 { 522 {
523// m_log.DebugFormat("[SCENE PRESENCE]: Fetching abs pos where PhysicsActor == null and parent part {0} for {1}", Name, Scene.Name);
465 // Obtain the correct position of a seated avatar. 524 // Obtain the correct position of a seated avatar.
466 // In addition to providing the correct position while 525 // In addition to providing the correct position while
467 // the avatar is seated, this value will also 526 // the avatar is seated, this value will also
@@ -485,7 +544,7 @@ namespace OpenSim.Region.Framework.Scenes
485 } 544 }
486 set 545 set
487 { 546 {
488// m_log.DebugFormat("[SCENE PRESENCE]: Setting position of {0} in {1} to {2}", Name, Scene.Name, value); 547// m_log.DebugFormat("[SCENE PRESENCE]: Setting position of {0} to {1} in {2}", Name, value, Scene.Name);
489// Util.PrintCallStack(); 548// Util.PrintCallStack();
490 549
491 if (PhysicsActor != null) 550 if (PhysicsActor != null)
@@ -502,10 +561,7 @@ namespace OpenSim.Region.Framework.Scenes
502 561
503 // Don't update while sitting. The PhysicsActor above is null whilst sitting. 562 // Don't update while sitting. The PhysicsActor above is null whilst sitting.
504 if (ParentID == 0) 563 if (ParentID == 0)
505 {
506 m_pos = value; 564 m_pos = value;
507// ParentPosition = Vector3.Zero;
508 }
509 565
510 //m_log.DebugFormat( 566 //m_log.DebugFormat(
511 // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 567 // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
@@ -768,6 +824,14 @@ namespace OpenSim.Region.Framework.Scenes
768 set { m_speedModifier = value; } 824 set { m_speedModifier = value; }
769 } 825 }
770 826
827 /// <summary>
828 /// Modifier for agent movement if we get an AGENT_CONTROL_STOP whilst walking or running
829 /// </summary>
830 /// <remarks>
831 /// AGENT_CONTRL_STOP comes about if user holds down space key on viewers.
832 /// </remarks>
833 private float AgentControlStopSlowWhilstMoving = 0.5f;
834
771 private bool m_forceFly; 835 private bool m_forceFly;
772 836
773 public bool ForceFly 837 public bool ForceFly
@@ -795,7 +859,7 @@ namespace OpenSim.Region.Framework.Scenes
795 859
796 public ScenePresence( 860 public ScenePresence(
797 IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) 861 IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type)
798 { 862 {
799 AttachmentsSyncLock = new Object(); 863 AttachmentsSyncLock = new Object();
800 AllowMovement = true; 864 AllowMovement = true;
801 IsChildAgent = true; 865 IsChildAgent = true;
@@ -841,6 +905,8 @@ namespace OpenSim.Region.Framework.Scenes
841 SetDirectionVectors(); 905 SetDirectionVectors();
842 906
843 Appearance = appearance; 907 Appearance = appearance;
908
909 m_stateMachine = new ScenePresenceStateMachine(this);
844 } 910 }
845 911
846 private void RegionHeartbeatEnd(Scene scene) 912 private void RegionHeartbeatEnd(Scene scene)
@@ -874,6 +940,7 @@ namespace OpenSim.Region.Framework.Scenes
874 { 940 {
875 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 941 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
876 ControllingClient.OnAgentUpdate += HandleAgentUpdate; 942 ControllingClient.OnAgentUpdate += HandleAgentUpdate;
943 ControllingClient.OnAgentCameraUpdate += HandleAgentCamerasUpdate;
877 ControllingClient.OnAgentRequestSit += HandleAgentRequestSit; 944 ControllingClient.OnAgentRequestSit += HandleAgentRequestSit;
878 ControllingClient.OnAgentSit += HandleAgentSit; 945 ControllingClient.OnAgentSit += HandleAgentSit;
879 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 946 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
@@ -927,6 +994,7 @@ namespace OpenSim.Region.Framework.Scenes
927 /// <summary> 994 /// <summary>
928 /// Turns a child agent into a root agent. 995 /// Turns a child agent into a root agent.
929 /// </summary> 996 /// </summary>
997 /// <remarks>
930 /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the 998 /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the
931 /// avatar is actual in the sim. They can perform all actions. 999 /// avatar is actual in the sim. They can perform all actions.
932 /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, 1000 /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim,
@@ -934,48 +1002,56 @@ namespace OpenSim.Region.Framework.Scenes
934 /// 1002 ///
935 /// This method is on the critical path for transferring an avatar from one region to another. Delay here 1003 /// This method is on the critical path for transferring an avatar from one region to another. Delay here
936 /// delays that crossing. 1004 /// delays that crossing.
937 /// </summary> 1005 /// </remarks>
938 public void MakeRootAgent(Vector3 pos, bool isFlying) 1006 private bool MakeRootAgent(Vector3 pos, bool isFlying)
939 { 1007 {
940 m_log.DebugFormat( 1008 lock (m_completeMovementLock)
941 "[SCENE]: Upgrading child to root agent for {0} in {1}",
942 Name, m_scene.RegionInfo.RegionName);
943
944 if (ParentUUID != UUID.Zero)
945 { 1009 {
946 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); 1010 if (!IsChildAgent)
947 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); 1011 return false;
948 if (part == null) 1012
1013 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
1014
1015 // m_log.InfoFormat(
1016 // "[SCENE]: Upgrading child to root agent for {0} in {1}",
1017 // Name, m_scene.RegionInfo.RegionName);
1018
1019 if (ParentUUID != UUID.Zero)
949 { 1020 {
950 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); 1021 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1022 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1023 if (part == null)
1024 {
1025 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1026 }
1027 else
1028 {
1029 part.ParentGroup.AddAvatar(UUID);
1030 if (part.SitTargetPosition != Vector3.Zero)
1031 part.SitTargetAvatar = UUID;
1032 // ParentPosition = part.GetWorldPosition();
1033 ParentID = part.LocalId;
1034 ParentPart = part;
1035 m_pos = PrevSitOffset;
1036 // pos = ParentPosition;
1037 pos = part.GetWorldPosition();
1038 }
1039 ParentUUID = UUID.Zero;
1040
1041 // Animator.TrySetMovementAnimation("SIT");
951 } 1042 }
952 else 1043 else
953 { 1044 {
954 part.ParentGroup.AddAvatar(UUID); 1045 IsLoggingIn = false;
955 if (part.SitTargetPosition != Vector3.Zero)
956 part.SitTargetAvatar = UUID;
957// ParentPosition = part.GetWorldPosition();
958 ParentID = part.LocalId;
959 ParentPart = part;
960 m_pos = PrevSitOffset;
961// pos = ParentPosition;
962 pos = part.GetWorldPosition();
963 } 1046 }
964 ParentUUID = UUID.Zero;
965 1047
966 IsChildAgent = false; 1048 IsChildAgent = false;
967
968// Animator.TrySetMovementAnimation("SIT");
969 } 1049 }
970 else
971 {
972 IsChildAgent = false;
973 IsLoggingIn = false;
974 }
975
976 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
977 1050
978 IsChildAgent = false; 1051 // Must reset this here so that a teleport to a region next to an existing region does not keep the flag
1052 // set and prevent the close of the connection on a subsequent re-teleport.
1053 // Should not be needed if we are not trying to tell this region to close
1054// DoNotCloseAfterTeleport = false;
979 1055
980 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); 1056 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
981 if (gm != null) 1057 if (gm != null)
@@ -1116,22 +1192,36 @@ namespace OpenSim.Region.Framework.Scenes
1116 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1192 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1117 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1193 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1118 // not transporting the required data. 1194 // not transporting the required data.
1119 lock (m_attachments) 1195 //
1196 // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
1197 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1198 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1199 // not transporting the required data.
1200 //
1201 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1202 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1203 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
1204 //
1205 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
1206 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1207 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1208 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1209 //
1210 // One cannot simply iterate over attachments in a fire and forget thread because this would no longer
1211 // be locked, allowing race conditions if other code changes the attachments list.
1212 List<SceneObjectGroup> attachments = GetAttachments();
1213
1214 if (attachments.Count > 0)
1120 { 1215 {
1121 if (HasAttachments()) 1216 m_log.DebugFormat(
1122 { 1217 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1123 m_log.DebugFormat(
1124 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1125 1218
1126 // Resume scripts 1219 // Resume scripts
1127 Util.FireAndForget(delegate(object x) { 1220 foreach (SceneObjectGroup sog in attachments)
1128 foreach (SceneObjectGroup sog in m_attachments) 1221 {
1129 { 1222 sog.ScheduleGroupForFullUpdate();
1130 sog.ScheduleGroupForFullUpdate(); 1223 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1131 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1224 sog.ResumeScripts();
1132 sog.ResumeScripts();
1133 }
1134 });
1135 } 1225 }
1136 } 1226 }
1137 } 1227 }
@@ -1153,7 +1243,7 @@ namespace OpenSim.Region.Framework.Scenes
1153 1243
1154 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1244 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1155 1245
1156 m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd; 1246 return true;
1157 } 1247 }
1158 1248
1159 public int GetStateSource() 1249 public int GetStateSource()
@@ -1306,7 +1396,26 @@ namespace OpenSim.Region.Framework.Scenes
1306 1396
1307 public void StopFlying() 1397 public void StopFlying()
1308 { 1398 {
1309 ControllingClient.StopFlying(this); 1399 Vector3 pos = AbsolutePosition;
1400 if (Appearance.AvatarHeight != 127.0f)
1401 pos += new Vector3(0f, 0f, (Appearance.AvatarHeight / 6f));
1402 else
1403 pos += new Vector3(0f, 0f, (1.56f / 6f));
1404
1405 AbsolutePosition = pos;
1406
1407 // attach a suitable collision plane regardless of the actual situation to force the LLClient to land.
1408 // Collision plane below the avatar's position a 6th of the avatar's height is suitable.
1409 // Mind you, that this method doesn't get called if the avatar's velocity magnitude is greater then a
1410 // certain amount.. because the LLClient wouldn't land in that situation anyway.
1411
1412 // why are we still testing for this really old height value default???
1413 if (Appearance.AvatarHeight != 127.0f)
1414 CollisionPlane = new Vector4(0, 0, 0, pos.Z - Appearance.AvatarHeight / 6f);
1415 else
1416 CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f / 6f));
1417
1418 ControllingClient.SendAgentTerseUpdate(this);
1310 } 1419 }
1311 1420
1312 /// <summary> 1421 /// <summary>
@@ -1480,6 +1589,37 @@ namespace OpenSim.Region.Framework.Scenes
1480 1589
1481 } 1590 }
1482 1591
1592 private bool WaitForUpdateAgent(IClientAPI client)
1593 {
1594 // Before the source region executes UpdateAgent
1595 // (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination,
1596 // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the
1597 // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero
1598 int count = 50;
1599 UUID originID;
1600
1601 lock (m_originRegionIDAccessLock)
1602 originID = m_originRegionID;
1603
1604 while (originID.Equals(UUID.Zero) && count-- > 0)
1605 {
1606 lock (m_originRegionIDAccessLock)
1607 originID = m_originRegionID;
1608
1609 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name);
1610 Thread.Sleep(200);
1611 }
1612
1613 if (originID.Equals(UUID.Zero))
1614 {
1615 // Movement into region will fail
1616 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name);
1617 return false;
1618 }
1619
1620 return true;
1621 }
1622
1483 /// <summary> 1623 /// <summary>
1484 /// Complete Avatar's movement into the region. 1624 /// Complete Avatar's movement into the region.
1485 /// </summary> 1625 /// </summary>
@@ -1493,9 +1633,18 @@ namespace OpenSim.Region.Framework.Scenes
1493 { 1633 {
1494// DateTime startTime = DateTime.Now; 1634// DateTime startTime = DateTime.Now;
1495 1635
1496 m_log.DebugFormat( 1636 m_log.InfoFormat(
1497 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", 1637 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
1498 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); 1638 client.Name, Scene.Name, AbsolutePosition);
1639
1640 // Make sure it's not a login agent. We don't want to wait for updates during login
1641 if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0)
1642 {
1643 // Let's wait until UpdateAgent (called by departing region) is done
1644 if (!WaitForUpdateAgent(client))
1645 // The sending region never sent the UpdateAgent data, we have to refuse
1646 return;
1647 }
1499 1648
1500 Vector3 look = Velocity; 1649 Vector3 look = Velocity;
1501 1650
@@ -1517,12 +1666,25 @@ namespace OpenSim.Region.Framework.Scenes
1517 } 1666 }
1518 1667
1519 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1668 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1520 MakeRootAgent(AbsolutePosition, flying); 1669 if (!MakeRootAgent(AbsolutePosition, flying))
1670 {
1671 m_log.DebugFormat(
1672 "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root",
1673 Name, Scene.Name);
1674
1675 return;
1676 }
1677
1678 // Tell the client that we're totally ready
1521 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); 1679 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1522 1680
1681 // Remember in HandleUseCircuitCode, we delayed this to here
1682 if (m_teleportFlags > 0)
1683 SendInitialDataToMe();
1684
1523// m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); 1685// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1524 1686
1525 if ((m_callbackURI != null) && !m_callbackURI.Equals("")) 1687 if (!string.IsNullOrEmpty(m_callbackURI))
1526 { 1688 {
1527 // We cannot sleep here since this would hold up the inbound packet processing thread, as 1689 // 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 1690 // CompleteMovement() is executed synchronously. However, it might be better to delay the release
@@ -1535,7 +1697,12 @@ namespace OpenSim.Region.Framework.Scenes
1535 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", 1697 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
1536 client.Name, client.AgentId, m_callbackURI); 1698 client.Name, client.AgentId, m_callbackURI);
1537 1699
1538 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); 1700 UUID originID;
1701
1702 lock (m_originRegionIDAccessLock)
1703 originID = m_originRegionID;
1704
1705 Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
1539 m_callbackURI = null; 1706 m_callbackURI = null;
1540 } 1707 }
1541// else 1708// else
@@ -1550,7 +1717,6 @@ namespace OpenSim.Region.Framework.Scenes
1550 // Create child agents in neighbouring regions 1717 // Create child agents in neighbouring regions
1551 if (openChildAgents && !IsChildAgent) 1718 if (openChildAgents && !IsChildAgent)
1552 { 1719 {
1553
1554 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1720 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1555 if (m_agentTransfer != null) 1721 if (m_agentTransfer != null)
1556 m_agentTransfer.EnableChildAgents(this); 1722 m_agentTransfer.EnableChildAgents(this);
@@ -1573,6 +1739,7 @@ namespace OpenSim.Region.Framework.Scenes
1573// m_log.DebugFormat( 1739// m_log.DebugFormat(
1574// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1740// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
1575// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); 1741// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
1742
1576 } 1743 }
1577 1744
1578 /// <summary> 1745 /// <summary>
@@ -1653,9 +1820,9 @@ namespace OpenSim.Region.Framework.Scenes
1653 /// </summary> 1820 /// </summary>
1654 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1821 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1655 { 1822 {
1656// m_log.DebugFormat( 1823 //m_log.DebugFormat(
1657// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", 1824 // "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
1658// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); 1825 // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
1659 1826
1660 if (IsChildAgent) 1827 if (IsChildAgent)
1661 { 1828 {
@@ -1663,10 +1830,6 @@ namespace OpenSim.Region.Framework.Scenes
1663 return; 1830 return;
1664 } 1831 }
1665 1832
1666 ++m_movementUpdateCount;
1667 if (m_movementUpdateCount < 1)
1668 m_movementUpdateCount = 1;
1669
1670 #region Sanity Checking 1833 #region Sanity Checking
1671 1834
1672 // This is irritating. Really. 1835 // This is irritating. Really.
@@ -1697,21 +1860,6 @@ namespace OpenSim.Region.Framework.Scenes
1697 1860
1698 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; 1861 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
1699 1862
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 1863 // The Agent's Draw distance setting
1716 // When we get to the point of re-computing neighbors everytime this 1864 // When we get to the point of re-computing neighbors everytime this
1717 // changes, then start using the agent's drawdistance rather than the 1865 // changes, then start using the agent's drawdistance rather than the
@@ -1783,9 +1931,16 @@ namespace OpenSim.Region.Framework.Scenes
1783 // Here's where you get them. 1931 // Here's where you get them.
1784 m_AgentControlFlags = flags; 1932 m_AgentControlFlags = flags;
1785 m_headrotation = agentData.HeadRotation; 1933 m_headrotation = agentData.HeadRotation;
1934 byte oldState = State;
1786 State = agentData.State; 1935 State = agentData.State;
1787 1936
1937 // We need to send this back to the client in order to stop the edit beams
1938 if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None)
1939 ControllingClient.SendAgentTerseUpdate(this);
1940
1788 PhysicsActor actor = PhysicsActor; 1941 PhysicsActor actor = PhysicsActor;
1942
1943 // This will be the case if the agent is sitting on the groudn or on an object.
1789 if (actor == null) 1944 if (actor == null)
1790 { 1945 {
1791 SendControlsToScripts(flagsForScripts); 1946 SendControlsToScripts(flagsForScripts);
@@ -1794,12 +1949,13 @@ namespace OpenSim.Region.Framework.Scenes
1794 1949
1795 if (AllowMovement && !SitGround) 1950 if (AllowMovement && !SitGround)
1796 { 1951 {
1797 Quaternion bodyRotation = agentData.BodyRotation; 1952// m_log.DebugFormat("[SCENE PRESENCE]: Initial body rotation {0} for {1}", agentData.BodyRotation, Name);
1953
1798 bool update_rotation = false; 1954 bool update_rotation = false;
1799 1955
1800 if (bodyRotation != Rotation) 1956 if (agentData.BodyRotation != Rotation)
1801 { 1957 {
1802 Rotation = bodyRotation; 1958 Rotation = agentData.BodyRotation;
1803 update_rotation = true; 1959 update_rotation = true;
1804 } 1960 }
1805 1961
@@ -1845,10 +2001,7 @@ namespace OpenSim.Region.Framework.Scenes
1845 else 2001 else
1846 dirVectors = Dir_Vectors; 2002 dirVectors = Dir_Vectors;
1847 2003
1848 // The fact that MovementFlag is a byte needs to be fixed
1849 // it really should be a uint
1850 // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction. 2004 // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
1851 uint nudgehack = 250;
1852 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 2005 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1853 { 2006 {
1854 if (((uint)flags & (uint)DCF) != 0) 2007 if (((uint)flags & (uint)DCF) != 0)
@@ -1865,29 +2018,19 @@ namespace OpenSim.Region.Framework.Scenes
1865 // Why did I get this? 2018 // Why did I get this?
1866 } 2019 }
1867 2020
1868 if ((MovementFlag & (byte)(uint)DCF) == 0) 2021 if (((MovementFlag & (uint)DCF) == 0) & !AgentControlStopActive)
1869 { 2022 {
1870 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE ||
1871 DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT_NUDGE)
1872 {
1873 MovementFlag |= (byte)nudgehack;
1874 }
1875
1876 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); 2023 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
1877 MovementFlag += (byte)(uint)DCF; 2024 MovementFlag += (uint)DCF;
1878 update_movementflag = true; 2025 update_movementflag = true;
1879 } 2026 }
1880 } 2027 }
1881 else 2028 else
1882 { 2029 {
1883 if ((MovementFlag & (byte)(uint)DCF) != 0 || 2030 if ((MovementFlag & (uint)DCF) != 0)
1884 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE ||
1885 DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT_NUDGE)
1886 && ((MovementFlag & (byte)nudgehack) == nudgehack))
1887 ) // This or is for Nudge forward
1888 { 2031 {
1889 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 2032 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
1890 MovementFlag -= ((byte)(uint)DCF); 2033 MovementFlag -= (uint)DCF;
1891 update_movementflag = true; 2034 update_movementflag = true;
1892 2035
1893 /* 2036 /*
@@ -1907,6 +2050,13 @@ namespace OpenSim.Region.Framework.Scenes
1907 i++; 2050 i++;
1908 } 2051 }
1909 2052
2053 // Detect AGENT_CONTROL_STOP state changes
2054 if (AgentControlStopActive != ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STOP) != 0))
2055 {
2056 AgentControlStopActive = !AgentControlStopActive;
2057 update_movementflag = true;
2058 }
2059
1910 if (MovingToTarget) 2060 if (MovingToTarget)
1911 { 2061 {
1912 // If the user has pressed a key then we want to cancel any move to target. 2062 // If the user has pressed a key then we want to cancel any move to target.
@@ -1932,53 +2082,79 @@ namespace OpenSim.Region.Framework.Scenes
1932 // Only do this if we're flying 2082 // Only do this if we're flying
1933 if (Flying && !ForceFly) 2083 if (Flying && !ForceFly)
1934 { 2084 {
1935 // Landing detection code 2085 // Need to stop in mid air if user holds down AGENT_CONTROL_STOP
1936 2086 if (AgentControlStopActive)
1937 // Are the landing controls requirements filled?
1938 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
1939 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
1940
1941 //m_log.Debug("[CONTROL]: " +flags);
1942 // Applies a satisfying roll effect to the avatar when flying.
1943 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
1944 {
1945 ApplyFlyingRoll(
1946 FLY_ROLL_RADIANS_PER_UPDATE,
1947 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
1948 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
1949 }
1950 else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 &&
1951 (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
1952 { 2087 {
1953 ApplyFlyingRoll( 2088 agent_control_v3 = Vector3.Zero;
1954 -FLY_ROLL_RADIANS_PER_UPDATE,
1955 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
1956 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
1957 } 2089 }
1958 else 2090 else
1959 { 2091 {
1960 if (m_AngularVelocity.Z != 0) 2092 // Landing detection code
1961 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
1962 }
1963 2093
1964 if (Flying && IsColliding && controlland) 2094 // Are the landing controls requirements filled?
1965 { 2095 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
1966 // nesting this check because LengthSquared() is expensive and we don't 2096 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
1967 // want to do it every step when flying. 2097
1968 if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) 2098 //m_log.Debug("[CONTROL]: " +flags);
1969 StopFlying(); 2099 // Applies a satisfying roll effect to the avatar when flying.
2100 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
2101 {
2102 ApplyFlyingRoll(
2103 FLY_ROLL_RADIANS_PER_UPDATE,
2104 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
2105 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
2106 }
2107 else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 &&
2108 (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
2109 {
2110 ApplyFlyingRoll(
2111 -FLY_ROLL_RADIANS_PER_UPDATE,
2112 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
2113 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
2114 }
2115 else
2116 {
2117 if (m_AngularVelocity.Z != 0)
2118 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
2119 }
2120
2121 if (Flying && IsColliding && controlland)
2122 {
2123 // nesting this check because LengthSquared() is expensive and we don't
2124 // want to do it every step when flying.
2125 if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX))
2126 StopFlying();
2127 }
1970 } 2128 }
1971 } 2129 }
1972 2130
2131// m_log.DebugFormat("[SCENE PRESENCE]: MovementFlag {0} for {1}", MovementFlag, Name);
2132
1973 // If the agent update does move the avatar, then calculate the force ready for the velocity update, 2133 // If the agent update does move the avatar, then calculate the force ready for the velocity update,
1974 // which occurs later in the main scene loop 2134 // which occurs later in the main scene loop
1975 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 2135 // We also need to update if the user rotates their avatar whilst it is slow walking/running (if they
2136 // held down AGENT_CONTROL_STOP whilst normal walking/running). However, we do not want to update
2137 // if the user rotated whilst holding down AGENT_CONTROL_STOP when already still (which locks the
2138 // avatar location in place).
2139 if (update_movementflag
2140 || (update_rotation && DCFlagKeyPressed && (!AgentControlStopActive || MovementFlag != 0)))
1976 { 2141 {
1977// m_log.DebugFormat( 2142// if (update_movementflag || !AgentControlStopActive || MovementFlag != 0)
1978// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 2143// {
1979// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 2144// m_log.DebugFormat(
2145// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, mf = {4}, ur = {5}",
2146// m_scene.RegionInfo.RegionName, agent_control_v3, Name,
2147// update_movementflag, MovementFlag, update_rotation);
1980 2148
1981 AddNewMovement(agent_control_v3); 2149 float speedModifier;
2150
2151 if (AgentControlStopActive)
2152 speedModifier = AgentControlStopSlowWhilstMoving;
2153 else
2154 speedModifier = 1;
2155
2156 AddNewMovement(agent_control_v3, speedModifier);
2157// }
1982 } 2158 }
1983// else 2159// else
1984// { 2160// {
@@ -1991,15 +2167,86 @@ namespace OpenSim.Region.Framework.Scenes
1991// } 2167// }
1992 2168
1993 if (update_movementflag && ParentID == 0) 2169 if (update_movementflag && ParentID == 0)
2170 {
2171// m_log.DebugFormat("[SCENE PRESENCE]: Updating movement animations for {0}", Name);
1994 Animator.UpdateMovementAnimations(); 2172 Animator.UpdateMovementAnimations();
2173 }
1995 2174
1996 SendControlsToScripts(flagsForScripts); 2175 SendControlsToScripts(flagsForScripts);
1997 } 2176 }
1998 2177
2178 // We need to send this back to the client in order to see the edit beams
2179 if ((State & (uint)AgentState.Editing) != 0)
2180 ControllingClient.SendAgentTerseUpdate(this);
2181
1999 m_scene.EventManager.TriggerOnClientMovement(this); 2182 m_scene.EventManager.TriggerOnClientMovement(this);
2000 TriggerScenePresenceUpdated();
2001 } 2183 }
2002 2184
2185
2186 /// <summary>
2187 /// This is the event handler for client cameras. If a client is moving, or moving the camera, this event is triggering.
2188 /// </summary>
2189 private void HandleAgentCamerasUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
2190 {
2191 //m_log.DebugFormat(
2192 // "[SCENE PRESENCE]: In {0} received agent camera update from {1}, flags {2}",
2193 // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
2194
2195 if (IsChildAgent)
2196 {
2197 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
2198 return;
2199 }
2200
2201 ++m_movementUpdateCount;
2202 if (m_movementUpdateCount < 1)
2203 m_movementUpdateCount = 1;
2204
2205// AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
2206
2207 // Camera location in world. We'll need to raytrace
2208 // from this location from time to time.
2209 CameraPosition = agentData.CameraCenter;
2210 if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance)
2211 {
2212 ReprioritizeUpdates();
2213 m_lastCameraPosition = CameraPosition;
2214 }
2215
2216 // Use these three vectors to figure out what the agent is looking at
2217 // Convert it to a Matrix and/or Quaternion
2218 CameraAtAxis = agentData.CameraAtAxis;
2219 CameraLeftAxis = agentData.CameraLeftAxis;
2220 CameraUpAxis = agentData.CameraUpAxis;
2221
2222 // The Agent's Draw distance setting
2223 // When we get to the point of re-computing neighbors everytime this
2224 // changes, then start using the agent's drawdistance rather than the
2225 // region's draw distance.
2226 // DrawDistance = agentData.Far;
2227 DrawDistance = Scene.DefaultDrawDistance;
2228
2229 // Check if Client has camera in 'follow cam' or 'build' mode.
2230 Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
2231
2232 m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
2233 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
2234
2235
2236 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
2237 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
2238 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
2239 {
2240 if (m_followCamAuto)
2241 {
2242 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
2243 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback);
2244 }
2245 }
2246
2247 TriggerScenePresenceUpdated();
2248 }
2249
2003 /// <summary> 2250 /// <summary>
2004 /// Calculate an update to move the presence to the set target. 2251 /// Calculate an update to move the presence to the set target.
2005 /// </summary> 2252 /// </summary>
@@ -2252,17 +2499,13 @@ namespace OpenSim.Region.Framework.Scenes
2252 { 2499 {
2253// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2500// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
2254 2501
2502 bool satOnObject = IsSatOnObject;
2503 SceneObjectPart part = ParentPart;
2255 SitGround = false; 2504 SitGround = false;
2256 2505
2257/* move this down so avatar gets physical in the new position and not where it is siting 2506 if (satOnObject)
2258 if (PhysicsActor == null)
2259 AddToPhysicalScene(false);
2260 */
2261
2262 if (ParentID != 0)
2263 { 2507 {
2264 PrevSitOffset = m_pos; // Save sit offset 2508 PrevSitOffset = m_pos; // Save sit offset
2265 SceneObjectPart part = ParentPart;
2266 UnRegisterSeatControls(part.ParentGroup.UUID); 2509 UnRegisterSeatControls(part.ParentGroup.UUID);
2267 2510
2268 TaskInventoryDictionary taskIDict = part.TaskInventory; 2511 TaskInventoryDictionary taskIDict = part.TaskInventory;
@@ -2281,34 +2524,71 @@ namespace OpenSim.Region.Framework.Scenes
2281 } 2524 }
2282 2525
2283 part.ParentGroup.DeleteAvatar(UUID); 2526 part.ParentGroup.DeleteAvatar(UUID);
2284// ParentPosition = part.GetWorldPosition(); 2527 Vector3 sitPartWorldPosition = part.GetWorldPosition();
2285 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2528 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2286 2529
2287// m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2288// ParentPosition = Vector3.Zero;
2289 m_pos = part.AbsolutePosition + (m_pos * part.GetWorldRotation()) + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2290 if (part.SitTargetAvatar == UUID)
2291 m_bodyRot = part.GetWorldRotation() * part.SitTargetOrientation;
2292
2293 ParentID = 0; 2530 ParentID = 0;
2294 ParentPart = null; 2531 ParentPart = null;
2295 2532
2296 if (PhysicsActor == null) 2533 Quaternion standRotation;
2297 AddToPhysicalScene(false);
2298 2534
2535 if (part.SitTargetAvatar == UUID)
2536 {
2537 standRotation = part.GetWorldRotation();
2538
2539 if (!part.IsRoot)
2540 standRotation = standRotation * part.SitTargetOrientation;
2541// standRotation = part.RotationOffset * part.SitTargetOrientation;
2542// else
2543// standRotation = part.SitTargetOrientation;
2544
2545 }
2546 else
2547 {
2548 standRotation = Rotation;
2549 }
2550
2551 //Vector3 standPos = ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2552 //Vector3 standPos = ParentPosition;
2553
2554// Vector3 standPositionAdjustment
2555// = part.SitTargetPosition + new Vector3(0.5f, 0f, m_sitAvatarHeight / 2f);
2556 Vector3 adjustmentForSitPosition = part.SitTargetPosition * part.GetWorldRotation();
2557
2558 // XXX: This is based on the physics capsule sizes. Need to find a better way to read this rather than
2559 // hardcoding here.
2560 Vector3 adjustmentForSitPose = new Vector3(0.74f, 0f, 0f) * standRotation;
2561
2562 Vector3 standPos = sitPartWorldPosition + adjustmentForSitPosition + adjustmentForSitPose;
2563
2564// m_log.DebugFormat(
2565// "[SCENE PRESENCE]: Setting stand to pos {0}, (adjustmentForSitPosition {1}, adjustmentForSitPose {2}) rotation {3} for {4} in {5}",
2566// standPos, adjustmentForSitPosition, adjustmentForSitPose, standRotation, Name, Scene.Name);
2567
2568 Rotation = standRotation;
2569 AbsolutePosition = standPos;
2570 }
2571
2572 // We need to wait until we have calculated proper stand positions before sitting up the physical
2573 // avatar to avoid race conditions.
2574 if (PhysicsActor == null)
2575 AddToPhysicalScene(false);
2576
2577 if (satOnObject)
2578 {
2299 SendAvatarDataToAllAgents(); 2579 SendAvatarDataToAllAgents();
2300 m_requestedSitTargetID = 0; 2580 m_requestedSitTargetID = 0;
2301 2581
2302 part.RemoveSittingAvatar(UUID); 2582 part.RemoveSittingAvatar(UUID);
2303 2583
2304 if (part != null) 2584 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2305 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2306 } 2585 }
2307 2586
2308 else if (PhysicsActor == null) 2587 else if (PhysicsActor == null)
2309 AddToPhysicalScene(false); 2588 AddToPhysicalScene(false);
2310 2589
2311 Animator.TrySetMovementAnimation("STAND"); 2590 Animator.TrySetMovementAnimation("STAND");
2591 TriggerScenePresenceUpdated();
2312 } 2592 }
2313 2593
2314 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) 2594 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -2359,7 +2639,6 @@ namespace OpenSim.Region.Framework.Scenes
2359 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f; 2639 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2360 2640
2361 bool canSit = false; 2641 bool canSit = false;
2362 Vector3 pos = part.AbsolutePosition + offset;
2363 2642
2364 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) 2643 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
2365 { 2644 {
@@ -2369,6 +2648,17 @@ namespace OpenSim.Region.Framework.Scenes
2369 2648
2370 offset = part.SitTargetPosition; 2649 offset = part.SitTargetPosition;
2371 sitOrientation = part.SitTargetOrientation; 2650 sitOrientation = part.SitTargetOrientation;
2651
2652 if (!part.IsRoot)
2653 {
2654 // m_log.DebugFormat("Old sit orient {0}", sitOrientation);
2655 sitOrientation = part.RotationOffset * sitOrientation;
2656 // m_log.DebugFormat("New sit orient {0}", sitOrientation);
2657// m_log.DebugFormat("Old sit offset {0}", offset);
2658 offset = offset * part.RotationOffset;
2659// m_log.DebugFormat("New sit offset {0}", offset);
2660 }
2661
2372 canSit = true; 2662 canSit = true;
2373 } 2663 }
2374 else 2664 else
@@ -2376,9 +2666,10 @@ namespace OpenSim.Region.Framework.Scenes
2376 if (PhysicsSit(part,offset)) // physics engine 2666 if (PhysicsSit(part,offset)) // physics engine
2377 return; 2667 return;
2378 2668
2669 Vector3 pos = part.AbsolutePosition + offset;
2670
2379 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2671 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2380 { 2672 {
2381
2382 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2673 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2383 canSit = true; 2674 canSit = true;
2384 } 2675 }
@@ -2404,10 +2695,14 @@ namespace OpenSim.Region.Framework.Scenes
2404 cameraEyeOffset = part.GetCameraEyeOffset(); 2695 cameraEyeOffset = part.GetCameraEyeOffset();
2405 forceMouselook = part.GetForceMouselook(); 2696 forceMouselook = part.GetForceMouselook();
2406 2697
2698 // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is
2699 // being sat upon.
2700 offset += part.OffsetPosition;
2701
2407 ControllingClient.SendSitResponse( 2702 ControllingClient.SendSitResponse(
2408 part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 2703 part.ParentGroup.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2409 2704
2410 m_requestedSitTargetUUID = targetID; 2705 m_requestedSitTargetUUID = part.UUID;
2411 2706
2412 HandleAgentSit(ControllingClient, UUID); 2707 HandleAgentSit(ControllingClient, UUID);
2413 2708
@@ -2435,7 +2730,7 @@ namespace OpenSim.Region.Framework.Scenes
2435 if (part != null) 2730 if (part != null)
2436 { 2731 {
2437 m_requestedSitTargetID = part.LocalId; 2732 m_requestedSitTargetID = part.LocalId;
2438 m_requestedSitTargetUUID = targetID; 2733 m_requestedSitTargetUUID = part.UUID;
2439 2734
2440 } 2735 }
2441 else 2736 else
@@ -2554,6 +2849,9 @@ namespace OpenSim.Region.Framework.Scenes
2554 2849
2555 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2850 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2556 { 2851 {
2852 if (IsChildAgent)
2853 return;
2854
2557 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); 2855 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
2558 2856
2559 if (part != null) 2857 if (part != null)
@@ -2603,24 +2901,40 @@ namespace OpenSim.Region.Framework.Scenes
2603 Vector3 up = new Vector3((float)x, (float)y, (float)z); 2901 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2604 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f; 2902 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2605 2903
2606 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT; 2904 Vector3 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2905 Quaternion newRot;
2906
2907 if (part.IsRoot)
2908 {
2909 newRot = sitTargetOrient;
2910 }
2911 else
2912 {
2913 newPos = newPos * part.RotationOffset;
2914 newRot = part.RotationOffset * sitTargetOrient;
2915 }
2916
2917 newPos += part.OffsetPosition;
2918
2919 m_pos = newPos;
2920 Rotation = newRot;
2607 2921
2608// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2609 Rotation = sitTargetOrient;
2610// ParentPosition = part.AbsolutePosition; 2922// ParentPosition = part.AbsolutePosition;
2611 part.ParentGroup.AddAvatar(UUID);
2612 } 2923 }
2613 else 2924 else
2614 { 2925 {
2615 m_pos -= part.AbsolutePosition; 2926 // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is
2927 // being sat upon.
2928 m_pos -= part.GroupPosition;
2929
2616// ParentPosition = part.AbsolutePosition; 2930// ParentPosition = part.AbsolutePosition;
2617 part.ParentGroup.AddAvatar(UUID);
2618 2931
2619// m_log.DebugFormat( 2932// m_log.DebugFormat(
2620// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2933// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
2621// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); 2934// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
2622 } 2935 }
2623 2936
2937 part.ParentGroup.AddAvatar(UUID);
2624 ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID); 2938 ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
2625 ParentID = m_requestedSitTargetID; 2939 ParentID = m_requestedSitTargetID;
2626 m_AngularVelocity = Vector3.Zero; 2940 m_AngularVelocity = Vector3.Zero;
@@ -2634,14 +2948,19 @@ namespace OpenSim.Region.Framework.Scenes
2634 } 2948 }
2635 Animator.TrySetMovementAnimation(sitAnimation); 2949 Animator.TrySetMovementAnimation(sitAnimation);
2636 SendAvatarDataToAllAgents(); 2950 SendAvatarDataToAllAgents();
2951 TriggerScenePresenceUpdated();
2637 } 2952 }
2638 } 2953 }
2639 2954
2640 public void HandleAgentSitOnGround() 2955 public void HandleAgentSitOnGround()
2641 { 2956 {
2957 if (IsChildAgent)
2958 return;
2959
2642// m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. 2960// m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick..
2643 m_AngularVelocity = Vector3.Zero; 2961 m_AngularVelocity = Vector3.Zero;
2644 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 2962 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
2963 TriggerScenePresenceUpdated();
2645 SitGround = true; 2964 SitGround = true;
2646 RemoveFromPhysicalScene(); 2965 RemoveFromPhysicalScene();
2647 } 2966 }
@@ -2658,11 +2977,13 @@ namespace OpenSim.Region.Framework.Scenes
2658 public void HandleStartAnim(IClientAPI remoteClient, UUID animID) 2977 public void HandleStartAnim(IClientAPI remoteClient, UUID animID)
2659 { 2978 {
2660 Animator.AddAnimation(animID, UUID.Zero); 2979 Animator.AddAnimation(animID, UUID.Zero);
2980 TriggerScenePresenceUpdated();
2661 } 2981 }
2662 2982
2663 public void HandleStopAnim(IClientAPI remoteClient, UUID animID) 2983 public void HandleStopAnim(IClientAPI remoteClient, UUID animID)
2664 { 2984 {
2665 Animator.RemoveAnimation(animID, false); 2985 Animator.RemoveAnimation(animID, false);
2986 TriggerScenePresenceUpdated();
2666 } 2987 }
2667 2988
2668 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack) 2989 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
@@ -2676,10 +2997,13 @@ namespace OpenSim.Region.Framework.Scenes
2676 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2997 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2677 /// </summary> 2998 /// </summary>
2678 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2999 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2679 public void AddNewMovement(Vector3 vec) 3000 /// <param name="thisAddSpeedModifier">
3001 /// Optional additional speed modifier for this particular add. Default is 1</param>
3002 public void AddNewMovement(Vector3 vec, float thisAddSpeedModifier = 1)
2680 { 3003 {
2681// m_log.DebugFormat( 3004// m_log.DebugFormat(
2682// "[SCENE PRESENCE]: Adding new movement {0} with rotation {1} for {2}", vec, Rotation, Name); 3005// "[SCENE PRESENCE]: Adding new movement {0} with rotation {1}, thisAddSpeedModifier {2} for {3}",
3006// vec, Rotation, thisAddSpeedModifier, Name);
2683 3007
2684 Vector3 direc = vec * Rotation; 3008 Vector3 direc = vec * Rotation;
2685 direc.Normalize(); 3009 direc.Normalize();
@@ -2697,7 +3021,7 @@ namespace OpenSim.Region.Framework.Scenes
2697 if ((vec.Z == 0f) && !Flying) 3021 if ((vec.Z == 0f) && !Flying)
2698 direc.Z = 0f; // Prevent camera WASD up. 3022 direc.Z = 0f; // Prevent camera WASD up.
2699 3023
2700 direc *= 0.03f * 128f * SpeedModifier; 3024 direc *= 0.03f * 128f * SpeedModifier * thisAddSpeedModifier;
2701 3025
2702// m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name); 3026// m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name);
2703 3027
@@ -2843,6 +3167,7 @@ namespace OpenSim.Region.Framework.Scenes
2843 lastTerseUpdateToAllClientsTick = currentTick; 3167 lastTerseUpdateToAllClientsTick = currentTick;
2844 lastPositionSentToAllClients = OffsetPosition; 3168 lastPositionSentToAllClients = OffsetPosition;
2845 3169
3170// Console.WriteLine("Scheduled update for {0} in {1}", Name, Scene.Name);
2846 m_scene.ForEachClient(SendTerseUpdateToClient); 3171 m_scene.ForEachClient(SendTerseUpdateToClient);
2847 } 3172 }
2848 TriggerScenePresenceUpdated(); 3173 TriggerScenePresenceUpdated();
@@ -2880,11 +3205,12 @@ namespace OpenSim.Region.Framework.Scenes
2880 SendOtherAgentsAppearanceToMe(); 3205 SendOtherAgentsAppearanceToMe();
2881 3206
2882 EntityBase[] entities = Scene.Entities.GetEntities(); 3207 EntityBase[] entities = Scene.Entities.GetEntities();
2883 foreach(EntityBase e in entities) 3208 foreach (EntityBase e in entities)
2884 { 3209 {
2885 if (e != null && e is SceneObjectGroup) 3210 if (e != null && e is SceneObjectGroup)
2886 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); 3211 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
2887 } 3212 }
3213
2888 }); 3214 });
2889 } 3215 }
2890 3216
@@ -2919,12 +3245,14 @@ namespace OpenSim.Region.Framework.Scenes
2919 // again here... this comes after the cached appearance check because the avatars 3245 // again here... this comes after the cached appearance check because the avatars
2920 // appearance goes into the avatar update packet 3246 // appearance goes into the avatar update packet
2921 SendAvatarDataToAllAgents(); 3247 SendAvatarDataToAllAgents();
3248
3249 // This invocation always shows up in the viewer logs as an error. Is it needed?
2922 SendAppearanceToAgent(this); 3250 SendAppearanceToAgent(this);
2923 3251
2924 // If we are using the the cached appearance then send it out to everyone 3252 // If we are using the the cached appearance then send it out to everyone
2925 if (cachedappearance) 3253 if (cachedappearance)
2926 { 3254 {
2927 m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name); 3255 m_log.DebugFormat("[SCENE PRESENCE]: Baked textures are in the cache for {0} in {1}", Name, m_scene.Name);
2928 3256
2929 // If the avatars baked textures are all in the cache, then we have a 3257 // If the avatars baked textures are all in the cache, then we have a
2930 // complete appearance... send it out, if not, then we'll send it when 3258 // complete appearance... send it out, if not, then we'll send it when
@@ -3079,11 +3407,10 @@ namespace OpenSim.Region.Framework.Scenes
3079 } 3407 }
3080 3408
3081 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 3409 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
3082 if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || 3410 if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance)
3083 Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance)
3084 { 3411 {
3085 m_lastChildAgentUpdatePosition = AbsolutePosition; 3412 m_lastChildAgentUpdatePosition = AbsolutePosition;
3086 m_lastChildAgentUpdateCamPosition = CameraPosition; 3413// m_lastChildAgentUpdateCamPosition = CameraPosition;
3087 3414
3088 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); 3415 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate();
3089 cadu.ActiveGroupID = UUID.Zero.Guid; 3416 cadu.ActiveGroupID = UUID.Zero.Guid;
@@ -3110,7 +3437,7 @@ namespace OpenSim.Region.Framework.Scenes
3110 cadu.Velocity = Velocity; 3437 cadu.Velocity = Velocity;
3111 3438
3112 AgentPosition agentpos = new AgentPosition(); 3439 AgentPosition agentpos = new AgentPosition();
3113 agentpos.CopyFrom(cadu); 3440 agentpos.CopyFrom(cadu, ControllingClient.SessionId);
3114 3441
3115 // Let's get this out of the update loop 3442 // Let's get this out of the update loop
3116 Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); 3443 Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); });
@@ -3294,11 +3621,6 @@ namespace OpenSim.Region.Framework.Scenes
3294 } 3621 }
3295 } 3622 }
3296 3623
3297 public void RestoreInCurrentScene()
3298 {
3299 AddToPhysicalScene(false); // not exactly false
3300 }
3301
3302 public void Reset() 3624 public void Reset()
3303 { 3625 {
3304// m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName); 3626// m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName);
@@ -3348,10 +3670,12 @@ namespace OpenSim.Region.Framework.Scenes
3348 if (byebyeRegions.Count > 0) 3670 if (byebyeRegions.Count > 0)
3349 { 3671 {
3350 m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); 3672 m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents");
3351 Util.FireAndForget(delegate 3673
3352 { 3674 AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID);
3353 m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, byebyeRegions); 3675 string auth = string.Empty;
3354 }); 3676 if (acd != null)
3677 auth = acd.SessionID.ToString();
3678 m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions);
3355 } 3679 }
3356 3680
3357 foreach (ulong handle in byebyeRegions) 3681 foreach (ulong handle in byebyeRegions)
@@ -3392,7 +3716,7 @@ namespace OpenSim.Region.Framework.Scenes
3392 3716
3393 #region Child Agent Updates 3717 #region Child Agent Updates
3394 3718
3395 public void ChildAgentDataUpdate(AgentData cAgentData) 3719 public void UpdateChildAgent(AgentData cAgentData)
3396 { 3720 {
3397// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); 3721// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
3398 if (!IsChildAgent) 3722 if (!IsChildAgent)
@@ -3402,15 +3726,17 @@ namespace OpenSim.Region.Framework.Scenes
3402 } 3726 }
3403 3727
3404 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3728 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3729
3405 private void RaiseUpdateThrottles() 3730 private void RaiseUpdateThrottles()
3406 { 3731 {
3407 m_scene.EventManager.TriggerThrottleUpdate(this); 3732 m_scene.EventManager.TriggerThrottleUpdate(this);
3408 } 3733 }
3734
3409 /// <summary> 3735 /// <summary>
3410 /// This updates important decision making data about a child agent 3736 /// This updates important decision making data about a child agent
3411 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3737 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
3412 /// </summary> 3738 /// </summary>
3413 public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) 3739 public void UpdateChildAgent(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY)
3414 { 3740 {
3415 if (!IsChildAgent) 3741 if (!IsChildAgent)
3416 return; 3742 return;
@@ -3452,6 +3778,7 @@ namespace OpenSim.Region.Framework.Scenes
3452 3778
3453 cAgent.AgentID = UUID; 3779 cAgent.AgentID = UUID;
3454 cAgent.RegionID = Scene.RegionInfo.RegionID; 3780 cAgent.RegionID = Scene.RegionInfo.RegionID;
3781 cAgent.SessionID = ControllingClient.SessionId;
3455 3782
3456 cAgent.Position = AbsolutePosition; 3783 cAgent.Position = AbsolutePosition;
3457 cAgent.Velocity = m_velocity; 3784 cAgent.Velocity = m_velocity;
@@ -3517,7 +3844,8 @@ namespace OpenSim.Region.Framework.Scenes
3517 3844
3518 private void CopyFrom(AgentData cAgent) 3845 private void CopyFrom(AgentData cAgent)
3519 { 3846 {
3520 m_originRegionID = cAgent.RegionID; 3847 lock (m_originRegionIDAccessLock)
3848 m_originRegionID = cAgent.RegionID;
3521 3849
3522 m_callbackURI = cAgent.CallbackURI; 3850 m_callbackURI = cAgent.CallbackURI;
3523// m_log.DebugFormat( 3851// m_log.DebugFormat(
@@ -3611,8 +3939,6 @@ namespace OpenSim.Region.Framework.Scenes
3611 { 3939 {
3612 Vector3 force = m_forceToApply.Value; 3940 Vector3 force = m_forceToApply.Value;
3613 3941
3614 Updated = true;
3615
3616 Velocity = force; 3942 Velocity = force;
3617 3943
3618 m_forceToApply = null; 3944 m_forceToApply = null;
@@ -3694,7 +4020,8 @@ namespace OpenSim.Region.Framework.Scenes
3694 4020
3695// if (m_updateCount > 0) 4021// if (m_updateCount > 0)
3696// { 4022// {
3697 Animator.UpdateMovementAnimations(); 4023 if (Animator.UpdateMovementAnimations())
4024 TriggerScenePresenceUpdated();
3698// m_updateCount--; 4025// m_updateCount--;
3699// } 4026// }
3700 4027
@@ -3858,6 +4185,7 @@ namespace OpenSim.Region.Framework.Scenes
3858// Animator.Close(); 4185// Animator.Close();
3859 Animator = null; 4186 Animator = null;
3860 4187
4188 LifecycleState = ScenePresenceState.Removed;
3861 } 4189 }
3862 4190
3863 public void AddAttachment(SceneObjectGroup gobj) 4191 public void AddAttachment(SceneObjectGroup gobj)