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.cs577
1 files changed, 336 insertions, 241 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index d2f84e3..de9b1f3 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.Framework.Scenes
67 67
68 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs); 68 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs);
69 69
70 public class ScenePresence : EntityBase, ISceneEntity 70 public class ScenePresence : EntityBase, IScenePresence
71 { 71 {
72// ~ScenePresence() 72// ~ScenePresence()
73// { 73// {
@@ -76,6 +76,8 @@ namespace OpenSim.Region.Framework.Scenes
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 public PresenceType PresenceType { get; private set; }
80
79// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 81// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
80 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); 82 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
81 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); 83 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
@@ -92,6 +94,13 @@ namespace OpenSim.Region.Framework.Scenes
92 // Value revised by KF 091121 by comparison with SL. 94 // Value revised by KF 091121 by comparison with SL.
93 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 95 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
94 96
97 /// <summary>
98 /// Movement updates for agents in neighboring regions are sent directly to clients.
99 /// This value only affects how often agent positions are sent to neighbor regions
100 /// for things such as distance-based update prioritization
101 /// </summary>
102 public static readonly float SIGNIFICANT_MOVEMENT = 2.0f;
103
95 public UUID currentParcelUUID = UUID.Zero; 104 public UUID currentParcelUUID = UUID.Zero;
96 105
97 private ISceneViewer m_sceneViewer; 106 private ISceneViewer m_sceneViewer;
@@ -105,14 +114,13 @@ namespace OpenSim.Region.Framework.Scenes
105 } 114 }
106 protected ScenePresenceAnimator m_animator; 115 protected ScenePresenceAnimator m_animator;
107 116
108 /// <value> 117 /// <summary>
109 /// The scene objects attached to this avatar. Do not change this list directly - use methods such as 118 /// Attachments recorded on this avatar.
110 /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. 119 /// </summary>
111 /// </value> 120 /// <remarks>
112 public List<SceneObjectGroup> Attachments 121 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
113 { 122 /// necessary.
114 get { return m_attachments; } 123 /// </remarks>
115 }
116 124
117 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 125 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
118 126
@@ -120,7 +128,7 @@ namespace OpenSim.Region.Framework.Scenes
120 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; 128 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
121 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; 129 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
122 private bool MouseDown = false; 130 private bool MouseDown = false;
123 private SceneObjectGroup proxyObjectGroup; 131// private SceneObjectGroup proxyObjectGroup;
124 //private SceneObjectPart proxyObjectPart = null; 132 //private SceneObjectPart proxyObjectPart = null;
125 public Vector3 lastKnownAllowedPosition; 133 public Vector3 lastKnownAllowedPosition;
126 public Vector4 CollisionPlane = Vector4.UnitW; 134 public Vector4 CollisionPlane = Vector4.UnitW;
@@ -178,7 +186,7 @@ namespace OpenSim.Region.Framework.Scenes
178 186
179 private float m_speedModifier = 1.0f; 187 private float m_speedModifier = 1.0f;
180 188
181 private Quaternion m_bodyRot= Quaternion.Identity; 189 private Quaternion m_bodyRot = Quaternion.Identity;
182 190
183 private Quaternion m_bodyRotPrevious = Quaternion.Identity; 191 private Quaternion m_bodyRotPrevious = Quaternion.Identity;
184 192
@@ -224,8 +232,8 @@ namespace OpenSim.Region.Framework.Scenes
224 private string m_nextSitAnimation = String.Empty; 232 private string m_nextSitAnimation = String.Empty;
225 233
226 //PauPaw:Proper PID Controler for autopilot************ 234 //PauPaw:Proper PID Controler for autopilot************
227 private bool m_moveToPositionInProgress; 235 public bool MovingToTarget { get; private set; }
228 private Vector3 m_moveToPositionTarget; 236 public Vector3 MoveToPositionTarget { get; private set; }
229 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); 237 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
230 238
231 private bool m_followCamAuto; 239 private bool m_followCamAuto;
@@ -455,9 +463,6 @@ namespace OpenSim.Region.Framework.Scenes
455 463
456 protected PhysicsActor m_physicsActor; 464 protected PhysicsActor m_physicsActor;
457 465
458 /// <value>
459 /// The client controlling this presence
460 /// </value>
461 public IClientAPI ControllingClient 466 public IClientAPI ControllingClient
462 { 467 {
463 get { return m_controllingClient; } 468 get { return m_controllingClient; }
@@ -765,15 +770,13 @@ namespace OpenSim.Region.Framework.Scenes
765 770
766 #region Constructor(s) 771 #region Constructor(s)
767 772
768 public ScenePresence() 773 public ScenePresence(
774 IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type)
769 { 775 {
770 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 776 m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
771 CreateSceneViewer(); 777 m_sceneViewer = new SceneViewer(this);
772 m_animator = new ScenePresenceAnimator(this); 778 m_animator = new ScenePresenceAnimator(this);
773 } 779 PresenceType = type;
774
775 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
776 {
777 m_DrawDistance = world.DefaultDrawDistance; 780 m_DrawDistance = world.DefaultDrawDistance;
778 m_rootRegionHandle = reginfo.RegionHandle; 781 m_rootRegionHandle = reginfo.RegionHandle;
779 m_controllingClient = client; 782 m_controllingClient = client;
@@ -817,19 +820,10 @@ namespace OpenSim.Region.Framework.Scenes
817 820
818 RegisterToEvents(); 821 RegisterToEvents();
819 SetDirectionVectors(); 822 SetDirectionVectors();
820 }
821 823
822 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
823 : this(client, world, reginfo)
824 {
825 m_appearance = appearance; 824 m_appearance = appearance;
826 } 825 }
827 826
828 private void CreateSceneViewer()
829 {
830 m_sceneViewer = new SceneViewer(this);
831 }
832
833 public void RegisterToEvents() 827 public void RegisterToEvents()
834 { 828 {
835 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; 829 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -841,8 +835,7 @@ namespace OpenSim.Region.Framework.Scenes
841 m_controllingClient.OnStartAnim += HandleStartAnim; 835 m_controllingClient.OnStartAnim += HandleStartAnim;
842 m_controllingClient.OnStopAnim += HandleStopAnim; 836 m_controllingClient.OnStopAnim += HandleStopAnim;
843 m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; 837 m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls;
844 m_controllingClient.OnAutoPilotGo += DoAutoPilot; 838 m_controllingClient.OnAutoPilotGo += MoveToTarget;
845 m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition);
846 839
847 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 840 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
848 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 841 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -1029,11 +1022,8 @@ namespace OpenSim.Region.Framework.Scenes
1029 } 1022 }
1030 1023
1031 float localAVHeight = 1.56f; 1024 float localAVHeight = 1.56f;
1032 if (m_appearance != null) 1025 if (m_appearance.AvatarHeight > 0)
1033 { 1026 localAVHeight = m_appearance.AvatarHeight;
1034 if (m_appearance.AvatarHeight > 0)
1035 localAVHeight = m_appearance.AvatarHeight;
1036 }
1037 1027
1038 float posZLimit = 0; 1028 float posZLimit = 0;
1039 1029
@@ -1047,26 +1037,8 @@ namespace OpenSim.Region.Framework.Scenes
1047 } 1037 }
1048 AbsolutePosition = pos; 1038 AbsolutePosition = pos;
1049 1039
1050 if (m_appearance != null)
1051 {
1052 if (m_appearance.AvatarHeight > 0)
1053 SetHeight(m_appearance.AvatarHeight);
1054 }
1055 else
1056 {
1057 m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName);
1058 // emergency; this really shouldn't happen
1059 m_appearance = new AvatarAppearance(UUID);
1060 }
1061
1062 AddToPhysicalScene(isFlying); 1040 AddToPhysicalScene(isFlying);
1063 1041
1064 if (m_appearance != null)
1065 {
1066 if (m_appearance.AvatarHeight > 0)
1067 SetHeight(m_appearance.AvatarHeight);
1068 }
1069
1070 if (m_forceFly) 1042 if (m_forceFly)
1071 { 1043 {
1072 m_physicsActor.Flying = true; 1044 m_physicsActor.Flying = true;
@@ -1087,15 +1059,18 @@ namespace OpenSim.Region.Framework.Scenes
1087 // and it has already rezzed the attachments and started their scripts. 1059 // and it has already rezzed the attachments and started their scripts.
1088 // We do the following only for non-login agents, because their scripts 1060 // We do the following only for non-login agents, because their scripts
1089 // haven't started yet. 1061 // haven't started yet.
1090 if (wasChild && Attachments != null && Attachments.Count > 0) 1062 lock (m_attachments)
1091 { 1063 {
1092 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); 1064 if (wasChild && HasAttachments())
1093 // Resume scripts
1094 Attachments.ForEach(delegate(SceneObjectGroup sog)
1095 { 1065 {
1096 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1066 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
1097 sog.ResumeScripts(); 1067 // Resume scripts
1098 }); 1068 foreach (SceneObjectGroup sog in m_attachments)
1069 {
1070 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1071 sog.ResumeScripts();
1072 }
1073 }
1099 } 1074 }
1100 1075
1101 // send the animations of the other presences to me 1076 // send the animations of the other presences to me
@@ -1105,6 +1080,11 @@ namespace OpenSim.Region.Framework.Scenes
1105 presence.Animator.SendAnimPackToClient(ControllingClient); 1080 presence.Animator.SendAnimPackToClient(ControllingClient);
1106 }); 1081 });
1107 1082
1083 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1084 // stall on the border crossing since the existing child agent will still have the last movement
1085 // recorded, which stops the input from being processed.
1086 m_movementflag = 0;
1087
1108 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1088 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1109 } 1089 }
1110 1090
@@ -1196,11 +1176,6 @@ namespace OpenSim.Region.Framework.Scenes
1196 CheckLandingPoint(ref pos); 1176 CheckLandingPoint(ref pos);
1197 AbsolutePosition = pos; 1177 AbsolutePosition = pos;
1198 AddToPhysicalScene(isFlying); 1178 AddToPhysicalScene(isFlying);
1199 if (m_appearance != null)
1200 {
1201 if (m_appearance.AvatarHeight > 0)
1202 SetHeight(m_appearance.AvatarHeight);
1203 }
1204 1179
1205 SendTerseUpdateToAllClients(); 1180 SendTerseUpdateToAllClients();
1206 1181
@@ -1216,22 +1191,10 @@ namespace OpenSim.Region.Framework.Scenes
1216 CheckLandingPoint(ref pos); 1191 CheckLandingPoint(ref pos);
1217 AbsolutePosition = pos; 1192 AbsolutePosition = pos;
1218 AddToPhysicalScene(isFlying); 1193 AddToPhysicalScene(isFlying);
1219 if (m_appearance != null)
1220 {
1221 if (m_appearance.AvatarHeight > 0)
1222 SetHeight(m_appearance.AvatarHeight);
1223 }
1224 1194
1225 SendTerseUpdateToAllClients(); 1195 SendTerseUpdateToAllClients();
1226 } 1196 }
1227 1197
1228 /// <summary>
1229 ///
1230 /// </summary>
1231 public void StopMovement()
1232 {
1233 }
1234
1235 public void StopFlying() 1198 public void StopFlying()
1236 { 1199 {
1237 ControllingClient.StopFlying(this); 1200 ControllingClient.StopFlying(this);
@@ -1281,7 +1244,7 @@ namespace OpenSim.Region.Framework.Scenes
1281 #region Event Handlers 1244 #region Event Handlers
1282 1245
1283 /// <summary> 1246 /// <summary>
1284 /// Sets avatar height in the phyiscs plugin 1247 /// Sets avatar height in the physics plugin
1285 /// </summary> 1248 /// </summary>
1286 public void SetHeight(float height) 1249 public void SetHeight(float height)
1287 { 1250 {
@@ -1294,10 +1257,14 @@ namespace OpenSim.Region.Framework.Scenes
1294 1257
1295 /// <summary> 1258 /// <summary>
1296 /// Complete Avatar's movement into the region. 1259 /// Complete Avatar's movement into the region.
1297 /// This is called upon a very important packet sent from the client,
1298 /// so it's client-controlled. Never call this method directly.
1299 /// </summary> 1260 /// </summary>
1300 public void CompleteMovement(IClientAPI client) 1261 /// <param name="client"></param>
1262 /// <param name="openChildAgents">
1263 /// If true, send notification to neighbour regions to expect
1264 /// a child agent from the client. These neighbours can be some distance away, depending right now on the
1265 /// configuration of DefaultDrawDistance in the [Startup] section of config
1266 /// </param>
1267 public void CompleteMovement(IClientAPI client, bool openChildAgents)
1301 { 1268 {
1302// DateTime startTime = DateTime.Now; 1269// DateTime startTime = DateTime.Now;
1303 1270
@@ -1338,15 +1305,11 @@ namespace OpenSim.Region.Framework.Scenes
1338 SendInitialData(); 1305 SendInitialData();
1339 1306
1340 // Create child agents in neighbouring regions 1307 // Create child agents in neighbouring regions
1341 if (!m_isChildAgent) 1308 if (openChildAgents && !m_isChildAgent)
1342 { 1309 {
1343 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1310 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1344 if (m_agentTransfer != null) 1311 if (m_agentTransfer != null)
1345 m_agentTransfer.EnableChildAgents(this); 1312 m_agentTransfer.EnableChildAgents(this);
1346 else
1347 m_log.DebugFormat(
1348 "[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active for region {0}",
1349 m_scene.RegionInfo.RegionName);
1350 1313
1351 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1314 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1352 if (friendsModule != null) 1315 if (friendsModule != null)
@@ -1403,6 +1366,8 @@ namespace OpenSim.Region.Framework.Scenes
1403 /// </summary> 1366 /// </summary>
1404 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1367 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1405 { 1368 {
1369// m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1370
1406 //if (m_isChildAgent) 1371 //if (m_isChildAgent)
1407 //{ 1372 //{
1408 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); 1373 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
@@ -1445,7 +1410,6 @@ namespace OpenSim.Region.Framework.Scenes
1445 #region Inputs 1410 #region Inputs
1446 1411
1447 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; 1412 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
1448 Quaternion bodyRotation = agentData.BodyRotation;
1449 1413
1450 // Camera location in world. We'll need to raytrace 1414 // Camera location in world. We'll need to raytrace
1451 // from this location from time to time. 1415 // from this location from time to time.
@@ -1530,23 +1494,29 @@ namespace OpenSim.Region.Framework.Scenes
1530 { 1494 {
1531 return; 1495 return;
1532 } 1496 }
1533
1534 bool update_movementflag = false;
1535 1497
1536 if (m_allowMovement && !SitGround) 1498 if (m_allowMovement && !SitGround)
1537 { 1499 {
1500 Quaternion bodyRotation = agentData.BodyRotation;
1501 bool update_rotation = false;
1502
1503 if (bodyRotation != m_bodyRot)
1504 {
1505 Rotation = bodyRotation;
1506 update_rotation = true;
1507 }
1508
1509 bool update_movementflag = false;
1510
1538 if (agentData.UseClientAgentPosition) 1511 if (agentData.UseClientAgentPosition)
1539 { 1512 {
1540 m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; 1513 MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
1541 m_moveToPositionTarget = agentData.ClientAgentPosition; 1514 MoveToPositionTarget = agentData.ClientAgentPosition;
1542 } 1515 }
1543 1516
1544 int i = 0; 1517 int i = 0;
1545
1546 bool update_rotation = false;
1547 bool DCFlagKeyPressed = false; 1518 bool DCFlagKeyPressed = false;
1548 Vector3 agent_control_v3 = Vector3.Zero; 1519 Vector3 agent_control_v3 = Vector3.Zero;
1549 Quaternion q = bodyRotation;
1550 1520
1551 bool oldflying = PhysicsActor.Flying; 1521 bool oldflying = PhysicsActor.Flying;
1552 1522
@@ -1577,7 +1547,6 @@ namespace OpenSim.Region.Framework.Scenes
1577 if (m_parentID == 0) 1547 if (m_parentID == 0)
1578 { 1548 {
1579 bool bAllowUpdateMoveToPosition = false; 1549 bool bAllowUpdateMoveToPosition = false;
1580 bool bResetMoveToPosition = false;
1581 1550
1582 Vector3[] dirVectors; 1551 Vector3[] dirVectors;
1583 1552
@@ -1598,8 +1567,8 @@ namespace OpenSim.Region.Framework.Scenes
1598 { 1567 {
1599 if (((uint)flags & (uint)DCF) != 0) 1568 if (((uint)flags & (uint)DCF) != 0)
1600 { 1569 {
1601 bResetMoveToPosition = true;
1602 DCFlagKeyPressed = true; 1570 DCFlagKeyPressed = true;
1571
1603 try 1572 try
1604 { 1573 {
1605 agent_control_v3 += dirVectors[i]; 1574 agent_control_v3 += dirVectors[i];
@@ -1615,6 +1584,8 @@ namespace OpenSim.Region.Framework.Scenes
1615 1584
1616 if ((m_movementflag & (uint)DCF) == 0) 1585 if ((m_movementflag & (uint)DCF) == 0)
1617 { 1586 {
1587
1588// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF);
1618 m_movementflag += (byte)(uint)DCF; 1589 m_movementflag += (byte)(uint)DCF;
1619 update_movementflag = true; 1590 update_movementflag = true;
1620 } 1591 }
@@ -1631,10 +1602,10 @@ namespace OpenSim.Region.Framework.Scenes
1631 bAllowUpdateMoveToPosition = true; 1602 bAllowUpdateMoveToPosition = true;
1632 } 1603 }
1633 } 1604 }
1605
1634 i++; 1606 i++;
1635 } 1607 }
1636 //Paupaw:Do Proper PID for Autopilot here 1608 if (MovingToTarget)
1637 if (bResetMoveToPosition)
1638 { 1609 {
1639 m_moveToPositionTarget = Vector3.Zero; 1610 m_moveToPositionTarget = Vector3.Zero;
1640 m_moveToPositionInProgress = false; 1611 m_moveToPositionInProgress = false;
@@ -1680,12 +1651,10 @@ namespace OpenSim.Region.Framework.Scenes
1680// if (there) 1651// if (there)
1681 if (Util.GetDistanceTo(abspos, tgt) <= 0.5f) 1652 if (Util.GetDistanceTo(abspos, tgt) <= 0.5f)
1682 { 1653 {
1683 // we are close enough to the target 1654 ResetMoveToTarget();
1684 m_moveToPositionTarget = Vector3.Zero;
1685 m_moveToPositionInProgress = false;
1686 update_movementflag = true; 1655 update_movementflag = true;
1687 } 1656 }
1688 else 1657 else if (bAllowUpdateMoveToPosition)
1689 { 1658 {
1690 try 1659 try
1691 { 1660 {
@@ -1790,14 +1759,26 @@ namespace OpenSim.Region.Framework.Scenes
1790 // which occurs later in the main scene loop 1759 // which occurs later in the main scene loop
1791 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1760 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1792 { 1761 {
1793 // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); 1762// m_log.DebugFormat(
1794 // m_log.DebugFormat( 1763// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1795 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1764// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1796 1765
1797 AddNewMovement(agent_control_v3, q, Nudging); 1766 AddNewMovement(agent_control_v3, q, Nudging);
1798 1767
1799 1768
1800 } 1769 }
1770// else
1771// {
1772// if (!update_movementflag)
1773// {
1774// m_log.DebugFormat(
1775// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1776// m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1777// }
1778// }
1779
1780 if (update_movementflag && m_parentID == 0)
1781 Animator.UpdateMovementAnimations();
1801 } 1782 }
1802 1783
1803 if (update_movementflag && !SitGround) 1784 if (update_movementflag && !SitGround)
@@ -1808,30 +1789,18 @@ namespace OpenSim.Region.Framework.Scenes
1808 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 1789 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
1809 } 1790 }
1810 1791
1811 public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) 1792 /// <summary>
1793 /// Calculate an update to move the presence to the set target.
1794 /// </summary>
1795 /// <remarks>
1796 /// This doesn't actually perform the movement. Instead, it adds its vector to agent_control_v3.
1797 /// </remarks>
1798 /// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param>
1799 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1800 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1812 { 1801 {
1813 m_autopilotMoving = true; 1802// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1814 m_autoPilotTarget = Pos; 1803 bool updated = false;
1815 m_sitAtAutoTarget = false;
1816 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1817 //proxy.PCode = (byte)PCode.ParticleSystem;
1818 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1819 proxyObjectGroup.AttachToScene(m_scene);
1820
1821 // Commented out this code since it could never have executed, but might still be informative.
1822// if (proxyObjectGroup != null)
1823// {
1824 proxyObjectGroup.SendGroupFullUpdate();
1825 remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false);
1826 m_scene.DeleteSceneObject(proxyObjectGroup, false);
1827// }
1828// else
1829// {
1830// m_autopilotMoving = false;
1831// m_autoPilotTarget = Vector3.Zero;
1832// ControllingClient.SendAlertMessage("Autopilot cancelled");
1833// }
1834 }
1835 1804
1836 public void StopMoveToPosition() 1805 public void StopMoveToPosition()
1837 { 1806 {
@@ -1844,31 +1813,186 @@ namespace OpenSim.Region.Framework.Scenes
1844//Console.WriteLine("SP:DoMoveToPosition"); 1813//Console.WriteLine("SP:DoMoveToPosition");
1845 try 1814 try
1846 { 1815 {
1847 float locx = 0f; 1816 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1848 float locy = 0f; 1817// m_log.DebugFormat(
1849 float locz = 0f; 1818// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1850 uint regionX = 0; 1819// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1851 uint regionY = 0; 1820
1852 try 1821 // Check the error term of the current position in relation to the target position
1822 if (distanceToTarget <= 1)
1853 { 1823 {
1854 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); 1824 // We are close enough to the target
1855 locx = Convert.ToSingle(args[0]) - (float)regionX; 1825 AbsolutePosition = MoveToPositionTarget;
1856 locy = Convert.ToSingle(args[1]) - (float)regionY; 1826 ResetMoveToTarget();
1857 locz = Convert.ToSingle(args[2]); 1827 updated = true;
1858 } 1828 }
1859 catch (InvalidCastException) 1829 else
1860 { 1830 {
1861 m_log.Error("[CLIENT]: Invalid autopilot request"); 1831 try
1862 return; 1832 {
1833 // move avatar in 3D at one meter/second towards target, in avatar coordinate frame.
1834 // This movement vector gets added to the velocity through AddNewMovement().
1835 // Theoretically we might need a more complex PID approach here if other
1836 // unknown forces are acting on the avatar and we need to adaptively respond
1837 // to such forces, but the following simple approach seems to works fine.
1838 Vector3 LocalVectorToTarget3D =
1839 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1840 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1841 // Ignore z component of vector
1842// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1843 LocalVectorToTarget3D.Normalize();
1844
1845 // update avatar movement flags. the avatar coordinate system is as follows:
1846 //
1847 // +X (forward)
1848 //
1849 // ^
1850 // |
1851 // |
1852 // |
1853 // |
1854 // (left) +Y <--------o--------> -Y
1855 // avatar
1856 // |
1857 // |
1858 // |
1859 // |
1860 // v
1861 // -X
1862 //
1863
1864 // based on the above avatar coordinate system, classify the movement into
1865 // one of left/right/back/forward.
1866 if (LocalVectorToTarget3D.X < 0) //MoveBack
1867 {
1868 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1869 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1870 updated = true;
1871 }
1872 else if (LocalVectorToTarget3D.X > 0) //Move Forward
1873 {
1874 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1875 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1876 updated = true;
1877 }
1878
1879 if (LocalVectorToTarget3D.Y > 0) //MoveLeft
1880 {
1881 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1882 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1883 updated = true;
1884 }
1885 else if (LocalVectorToTarget3D.Y < 0) //MoveRight
1886 {
1887 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1888 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1889 updated = true;
1890 }
1891
1892 if (LocalVectorToTarget3D.Z > 0) //Up
1893 {
1894 // Don't set these flags for up or down - doing so will make the avatar crouch or
1895 // keep trying to jump even if walking along level ground
1896 //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
1897 //AgentControlFlags
1898 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
1899 updated = true;
1900 }
1901 else if (LocalVectorToTarget3D.Z < 0) //Down
1902 {
1903 //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
1904 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
1905 updated = true;
1906 }
1907
1908// m_log.DebugFormat(
1909// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1910// LocalVectorToTarget3D, agent_control_v3, Name);
1911
1912 agent_control_v3 += LocalVectorToTarget3D;
1913 }
1914 catch (Exception e)
1915 {
1916 //Avoid system crash, can be slower but...
1917 m_log.DebugFormat("Crash! {0}", e.ToString());
1918 }
1863 } 1919 }
1864 m_moveToPositionInProgress = true;
1865 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1866 } 1920 }
1867 catch (Exception ex) 1921
1868 { 1922 return updated;
1869 //Why did I get this error? 1923 }
1870 m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex); 1924
1871 } 1925 /// <summary>
1926 /// Move to the given target over time.
1927 /// </summary>
1928 /// <param name="pos"></param>
1929 /// <param name="noFly">
1930 /// If true, then don't allow the avatar to fly to the target, even if it's up in the air.
1931 /// This is to allow movement to targets that are known to be on an elevated platform with a continuous path
1932 /// from start to finish.
1933 /// </param>
1934 public void MoveToTarget(Vector3 pos, bool noFly)
1935 {
1936 m_log.DebugFormat(
1937 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1938 Name, pos, m_scene.RegionInfo.RegionName);
1939
1940 if (pos.X < 0 || pos.X >= Constants.RegionSize
1941 || pos.Y < 0 || pos.Y >= Constants.RegionSize
1942 || pos.Z < 0)
1943 return;
1944
1945// Vector3 heightAdjust = new Vector3(0, 0, Appearance.AvatarHeight / 2);
1946// pos += heightAdjust;
1947//
1948// // Anti duck-walking measure
1949// if (Math.Abs(pos.Z - AbsolutePosition.Z) < 0.2f)
1950// {
1951//// m_log.DebugFormat("[SCENE PRESENCE]: Adjusting MoveToPosition from {0} to {1}", pos, AbsolutePosition);
1952// pos.Z = AbsolutePosition.Z;
1953// }
1954
1955 float terrainHeight = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
1956 pos.Z = Math.Max(terrainHeight, pos.Z);
1957
1958 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is
1959 // always slightly higher than the actual terrain height.
1960 // FIXME: This constrains NOC movements as well, so should be somewhere else.
1961 if (pos.Z - terrainHeight < 0.2)
1962 pos.Z = terrainHeight;
1963
1964 m_log.DebugFormat(
1965 "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
1966 Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
1967
1968 if (noFly)
1969 PhysicsActor.Flying = false;
1970 else if (pos.Z > terrainHeight)
1971 PhysicsActor.Flying = true;
1972
1973 MovingToTarget = true;
1974 MoveToPositionTarget = pos;
1975
1976 Vector3 agent_control_v3 = new Vector3();
1977 HandleMoveToTargetUpdate(ref agent_control_v3);
1978 AddNewMovement(agent_control_v3);
1979 }
1980
1981 /// <summary>
1982 /// Reset the move to target.
1983 /// </summary>
1984 public void ResetMoveToTarget()
1985 {
1986 m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1987
1988 MovingToTarget = false;
1989 MoveToPositionTarget = Vector3.Zero;
1990
1991 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
1992 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
1993 // However, the line is here rather than in the NPC module since it also appears necessary to stop a
1994 // viewer that uses "go here" from juddering on all subsequent avatar movements.
1995 AgentControlFlags = (uint)AgentManager.ControlFlags.NONE;
1872 } 1996 }
1873 1997
1874 private void CheckAtSitTarget() 1998 private void CheckAtSitTarget()
@@ -1997,11 +2121,6 @@ namespace OpenSim.Region.Framework.Scenes
1997 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); 2121 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1998 SendAvatarDataToAllAgents(); 2122 SendAvatarDataToAllAgents();
1999 m_requestedSitTargetID = 0; 2123 m_requestedSitTargetID = 0;
2000 if (m_physicsActor != null && m_appearance != null)
2001 {
2002 if (m_appearance.AvatarHeight > 0)
2003 SetHeight(m_appearance.AvatarHeight);
2004 }
2005 } 2124 }
2006 Animator.TrySetMovementAnimation("STAND"); 2125 Animator.TrySetMovementAnimation("STAND");
2007 } 2126 }
@@ -2057,7 +2176,7 @@ namespace OpenSim.Region.Framework.Scenes
2057 bool forceMouselook = false; 2176 bool forceMouselook = false;
2058 2177
2059 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2178 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
2060 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2179 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2061 if (part == null) return; 2180 if (part == null) return;
2062 2181
2063 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2182 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
@@ -2215,14 +2334,23 @@ namespace OpenSim.Region.Framework.Scenes
2215 HandleAgentSit(remoteClient, UUID); 2334 HandleAgentSit(remoteClient, UUID);
2216 } 2335 }
2217 2336
2337 // public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
2218 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2338 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2219 { 2339 {
2220 if (m_parentID != 0) 2340 if (m_parentID != 0)
2221 { 2341 {
2222 StandUp(); 2342 StandUp();
2223 } 2343 }
2344
2345// if (!String.IsNullOrEmpty(sitAnimation))
2346// {
2347// m_nextSitAnimation = sitAnimation;
2348// }
2349// else
2350// {
2224 m_nextSitAnimation = "SIT"; 2351 m_nextSitAnimation = "SIT";
2225 2352// }
2353
2226 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2354 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
2227 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2355 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2228 2356
@@ -2247,7 +2375,6 @@ namespace OpenSim.Region.Framework.Scenes
2247 } 2375 }
2248 else 2376 else
2249 { 2377 {
2250
2251 m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); 2378 m_log.Warn("Sit requested on unknown object: " + targetID.ToString());
2252 } 2379 }
2253 2380
@@ -2445,44 +2572,7 @@ namespace OpenSim.Region.Framework.Scenes
2445 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2572 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity);
2446 } 2573 }
2447 */ 2574 */
2448 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
2449 {
2450 if (m_parentID != 0)
2451 {
2452 StandUp();
2453 }
2454 if (!String.IsNullOrEmpty(sitAnimation))
2455 {
2456 m_nextSitAnimation = sitAnimation;
2457 }
2458 else
2459 {
2460 m_nextSitAnimation = "SIT";
2461 }
2462
2463 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
2464 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2465 if (part != null)
2466 {
2467 m_requestedSitTargetID = part.LocalId;
2468 //m_requestedSitOffset = offset;
2469 m_requestedSitTargetUUID = targetID;
2470 2575
2471 m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2472
2473 if (m_scene.PhysicsScene.SupportsRayCast())
2474 {
2475 //SitRayCastAvatarPosition(part);
2476 //return;
2477 }
2478 }
2479 else
2480 {
2481 m_log.Warn("Sit requested on unknown object: " + targetID);
2482 }
2483
2484 SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity);
2485 }
2486 2576
2487 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2577 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2488 { 2578 {
@@ -2669,8 +2759,7 @@ namespace OpenSim.Region.Framework.Scenes
2669 2759
2670 m_perfMonMS = Util.EnvironmentTickCount(); 2760 m_perfMonMS = Util.EnvironmentTickCount();
2671 2761
2672 Rotation = rotation; 2762 Vector3 direc = vec * Rotation;
2673 Vector3 direc = vec * rotation;
2674 direc.Normalize(); 2763 direc.Normalize();
2675 PhysicsActor actor = m_physicsActor; 2764 PhysicsActor actor = m_physicsActor;
2676 2765
@@ -2901,13 +2990,7 @@ namespace OpenSim.Region.Framework.Scenes
2901 // We have an appearance but we may not have the baked textures. Check the asset cache 2990 // We have an appearance but we may not have the baked textures. Check the asset cache
2902 // to see if all the baked textures are already here. 2991 // to see if all the baked textures are already here.
2903 if (m_scene.AvatarFactory != null) 2992 if (m_scene.AvatarFactory != null)
2904 {
2905 cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient); 2993 cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient);
2906 }
2907 else
2908 {
2909 m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name);
2910 }
2911 2994
2912 // If we aren't using a cached appearance, then clear out the baked textures 2995 // If we aren't using a cached appearance, then clear out the baked textures
2913 if (!cachedappearance) 2996 if (!cachedappearance)
@@ -3064,19 +3147,21 @@ namespace OpenSim.Region.Framework.Scenes
3064 /// <param name="avatar"></param> 3147 /// <param name="avatar"></param>
3065 public void SendAppearanceToAgent(ScenePresence avatar) 3148 public void SendAppearanceToAgent(ScenePresence avatar)
3066 { 3149 {
3067// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); 3150// m_log.DebugFormat(
3151// "[SCENE PRESENCE] Send appearance from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID);
3068 3152
3069 avatar.ControllingClient.SendAppearance( 3153 avatar.ControllingClient.SendAppearance(
3070 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); 3154 UUID, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
3071 } 3155 }
3072 3156
3073 // Because appearance setting is in a module, we actually need
3074 // to give it access to our appearance directly, otherwise we
3075 // get a synchronization issue.
3076 public AvatarAppearance Appearance 3157 public AvatarAppearance Appearance
3077 { 3158 {
3078 get { return m_appearance; } 3159 get { return m_appearance; }
3079 set { m_appearance = value; } 3160 set
3161 {
3162 m_appearance = value;
3163// m_log.DebugFormat("[SCENE PRESENCE]: Set appearance for {0} to {1}", Name, value);
3164 }
3080 } 3165 }
3081 3166
3082 #endregion 3167 #endregion
@@ -3088,15 +3173,10 @@ namespace OpenSim.Region.Framework.Scenes
3088 /// </summary> 3173 /// </summary>
3089 protected void CheckForSignificantMovement() 3174 protected void CheckForSignificantMovement()
3090 { 3175 {
3091 // Movement updates for agents in neighboring regions are sent directly to clients.
3092 // This value only affects how often agent positions are sent to neighbor regions
3093 // for things such as distance-based update prioritization
3094 const float SIGNIFICANT_MOVEMENT = 2.0f;
3095
3096 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) 3176 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT)
3097 { 3177 {
3098 posLastSignificantMove = AbsolutePosition; 3178 posLastSignificantMove = AbsolutePosition;
3099 m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); 3179 m_scene.EventManager.TriggerSignificantClientMovement(this);
3100 } 3180 }
3101 3181
3102 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 3182 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
@@ -3579,7 +3659,7 @@ namespace OpenSim.Region.Framework.Scenes
3579 ISceneObject clone = sog.CloneForNewScene(); 3659 ISceneObject clone = sog.CloneForNewScene();
3580 // Attachment module assumes that GroupPosition holds the offsets...! 3660 // Attachment module assumes that GroupPosition holds the offsets...!
3581 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; 3661 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
3582 ((SceneObjectGroup)clone).RootPart.IsAttachment = false; 3662 ((SceneObjectGroup)clone).IsAttachment = false;
3583 cAgent.AttachmentObjects.Add(clone); 3663 cAgent.AttachmentObjects.Add(clone);
3584 string state = sog.GetStateSnapshot(); 3664 string state = sog.GetStateSnapshot();
3585 cAgent.AttachmentObjectStates.Add(state); 3665 cAgent.AttachmentObjectStates.Add(state);
@@ -3746,6 +3826,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
3746 m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3826 m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3747 m_physicsActor.SubscribeEvents(500); 3827 m_physicsActor.SubscribeEvents(500);
3748 m_physicsActor.LocalID = LocalId; 3828 m_physicsActor.LocalID = LocalId;
3829
3830 SetHeight(m_appearance.AvatarHeight);
3749 } 3831 }
3750 3832
3751 private void OutOfBoundsCall(Vector3 pos) 3833 private void OutOfBoundsCall(Vector3 pos)
@@ -4001,19 +4083,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4001 4083
4002 public void Close() 4084 public void Close()
4003 { 4085 {
4004 lock (m_attachments) 4086 m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
4005 {
4006 // Delete attachments from scene
4007 // Don't try to save, as this thread won't live long
4008 // enough to complete the save. This would cause no copy
4009 // attachments to poof!
4010 //
4011 foreach (SceneObjectGroup grp in m_attachments)
4012 {
4013 m_scene.DeleteSceneObject(grp, false);
4014 }
4015 m_attachments.Clear();
4016 }
4017 4087
4018 lock (m_knownChildRegions) 4088 lock (m_knownChildRegions)
4019 { 4089 {
@@ -4048,9 +4118,19 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4048 m_attachments.Add(gobj); 4118 m_attachments.Add(gobj);
4049 } 4119 }
4050 } 4120 }
4051 4121
4122 /// <summary>
4123 /// Get all the presence's attachments.
4124 /// </summary>
4125 /// <returns>A copy of the list which contains the attachments.</returns>
4126 public List<SceneObjectGroup> GetAttachments()
4127 {
4128 lock (m_attachments)
4129 return new List<SceneObjectGroup>(m_attachments);
4130 }
4131
4052 /// <summary> 4132 /// <summary>
4053 /// Get the scene object attached to the given point. 4133 /// Get the scene objects attached to the given point.
4054 /// </summary> 4134 /// </summary>
4055 /// <param name="attachmentPoint"></param> 4135 /// <param name="attachmentPoint"></param>
4056 /// <returns>Returns an empty list if there were no attachments at the point.</returns> 4136 /// <returns>Returns an empty list if there were no attachments at the point.</returns>
@@ -4062,7 +4142,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4062 { 4142 {
4063 foreach (SceneObjectGroup so in m_attachments) 4143 foreach (SceneObjectGroup so in m_attachments)
4064 { 4144 {
4065 if (attachmentPoint == so.RootPart.AttachmentPoint) 4145 if (attachmentPoint == so.AttachmentPoint)
4066 attachments.Add(so); 4146 attachments.Add(so);
4067 } 4147 }
4068 } 4148 }
@@ -4072,7 +4152,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4072 4152
4073 public bool HasAttachments() 4153 public bool HasAttachments()
4074 { 4154 {
4075 return m_attachments.Count > 0; 4155 lock (m_attachments)
4156 return m_attachments.Count > 0;
4076 } 4157 }
4077 4158
4078 public bool HasScriptedAttachments() 4159 public bool HasScriptedAttachments()
@@ -4094,12 +4175,16 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4094 public void RemoveAttachment(SceneObjectGroup gobj) 4175 public void RemoveAttachment(SceneObjectGroup gobj)
4095 { 4176 {
4096 lock (m_attachments) 4177 lock (m_attachments)
4097 { 4178 m_attachments.Remove(gobj);
4098 if (m_attachments.Contains(gobj)) 4179 }
4099 { 4180
4100 m_attachments.Remove(gobj); 4181 /// <summary>
4101 } 4182 /// Clear all attachments
4102 } 4183 /// </summary>
4184 public void ClearAttachments()
4185 {
4186 lock (m_attachments)
4187 m_attachments.Clear();
4103 } 4188 }
4104 4189
4105 public bool ValidateAttachments() 4190 public bool ValidateAttachments()
@@ -4110,12 +4195,22 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4110 foreach (SceneObjectGroup gobj in m_attachments) 4195 foreach (SceneObjectGroup gobj in m_attachments)
4111 { 4196 {
4112 if (gobj == null) 4197 if (gobj == null)
4198 {
4199 m_log.WarnFormat(
4200 "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null", Name);
4113 return false; 4201 return false;
4202 }
4114 4203
4115 if (gobj.IsDeleted) 4204 if (gobj.IsDeleted)
4205 {
4206 m_log.WarnFormat(
4207 "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted",
4208 gobj.Name, gobj.UUID, Name);
4116 return false; 4209 return false;
4210 }
4117 } 4211 }
4118 } 4212 }
4213
4119 return true; 4214 return true;
4120 } 4215 }
4121 4216
@@ -4553,4 +4648,4 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4553 } 4648 }
4554 } 4649 }
4555 } 4650 }
4556} 4651} \ No newline at end of file