diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 577 |
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 |