diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2659 |
1 files changed, 1962 insertions, 697 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7004d23..c58847b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -29,7 +29,9 @@ using System; | |||
29 | using System.Xml; | 29 | using System.Xml; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Threading; | ||
32 | using System.Timers; | 33 | using System.Timers; |
34 | using Timer = System.Timers.Timer; | ||
33 | using OpenMetaverse; | 35 | using OpenMetaverse; |
34 | using log4net; | 36 | using log4net; |
35 | using Nini.Config; | 37 | using Nini.Config; |
@@ -73,20 +75,59 @@ namespace OpenSim.Region.Framework.Scenes | |||
73 | 75 | ||
74 | public class ScenePresence : EntityBase, IScenePresence | 76 | public class ScenePresence : EntityBase, IScenePresence |
75 | { | 77 | { |
78 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
79 | |||
76 | // ~ScenePresence() | 80 | // ~ScenePresence() |
77 | // { | 81 | // { |
78 | // m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name); | 82 | // m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name); |
79 | // } | 83 | // } |
80 | 84 | ||
81 | private void TriggerScenePresenceUpdated() | 85 | public void TriggerScenePresenceUpdated() |
82 | { | 86 | { |
83 | if (m_scene != null) | 87 | if (m_scene != null) |
84 | m_scene.EventManager.TriggerScenePresenceUpdated(this); | 88 | m_scene.EventManager.TriggerScenePresenceUpdated(this); |
85 | } | 89 | } |
86 | 90 | ||
87 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 91 | public bool isNPC { get; private set; } |
92 | |||
93 | private PresenceType m_presenceType; | ||
94 | public PresenceType PresenceType { | ||
95 | get {return m_presenceType;} | ||
96 | private set | ||
97 | { | ||
98 | m_presenceType = value; | ||
99 | isNPC = (m_presenceType == PresenceType.Npc); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | private ScenePresenceStateMachine m_stateMachine; | ||
104 | |||
105 | /// <summary> | ||
106 | /// The current state of this presence. Governs only the existence lifecycle. See ScenePresenceStateMachine | ||
107 | /// for more details. | ||
108 | /// </summary> | ||
109 | public ScenePresenceState LifecycleState | ||
110 | { | ||
111 | get | ||
112 | { | ||
113 | return m_stateMachine.GetState(); | ||
114 | } | ||
115 | |||
116 | set | ||
117 | { | ||
118 | m_stateMachine.SetState(value); | ||
119 | } | ||
120 | } | ||
88 | 121 | ||
89 | public PresenceType PresenceType { get; private set; } | 122 | /// <summary> |
123 | /// This exists to prevent race conditions between two CompleteMovement threads if the simulator is slow and | ||
124 | /// the viewer fires these in quick succession. | ||
125 | /// </summary> | ||
126 | /// <remarks> | ||
127 | /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement | ||
128 | /// regulation done there. | ||
129 | /// </remarks> | ||
130 | private object m_completeMovementLock = new object(); | ||
90 | 131 | ||
91 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); | 132 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); |
92 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); | 133 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); |
@@ -109,13 +150,100 @@ namespace OpenSim.Region.Framework.Scenes | |||
109 | /// </summary> | 150 | /// </summary> |
110 | public static readonly float SIGNIFICANT_MOVEMENT = 2.0f; | 151 | public static readonly float SIGNIFICANT_MOVEMENT = 2.0f; |
111 | 152 | ||
112 | public UUID currentParcelUUID = UUID.Zero; | 153 | private UUID m_previusParcelUUID = UUID.Zero; |
154 | private UUID m_currentParcelUUID = UUID.Zero; | ||
155 | private bool m_previusParcelHide = false; | ||
156 | private bool m_currentParcelHide = false; | ||
157 | private object parcelLock = new Object(); | ||
158 | |||
159 | public UUID currentParcelUUID | ||
160 | { | ||
161 | get { return m_currentParcelUUID; } | ||
162 | set | ||
163 | { | ||
164 | lock (parcelLock) | ||
165 | { | ||
166 | bool oldhide = m_currentParcelHide; | ||
167 | bool checksame = true; | ||
168 | if (value != m_currentParcelUUID) | ||
169 | { | ||
170 | m_previusParcelHide = m_currentParcelHide; | ||
171 | m_previusParcelUUID = m_currentParcelUUID; | ||
172 | checksame = false; | ||
173 | } | ||
174 | m_currentParcelUUID = value; | ||
175 | m_currentParcelHide = false; | ||
176 | |||
177 | ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y); | ||
178 | if (land != null && !land.LandData.SeeAVs) | ||
179 | m_currentParcelHide = true; | ||
113 | 180 | ||
181 | if (m_previusParcelUUID != UUID.Zero || checksame) | ||
182 | ParcelCrossCheck(m_currentParcelUUID,m_previusParcelUUID,m_currentParcelHide, m_previusParcelHide, oldhide,checksame); | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | |||
187 | public void sitSOGmoved() | ||
188 | { | ||
189 | if (IsDeleted || !IsSatOnObject) | ||
190 | //what me? nahh | ||
191 | return; | ||
192 | if (IsInTransit) | ||
193 | return; | ||
194 | |||
195 | ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y); | ||
196 | if (land == null) | ||
197 | return; //?? | ||
198 | UUID parcelID = land.LandData.GlobalID; | ||
199 | if (m_currentParcelUUID != parcelID) | ||
200 | currentParcelUUID = parcelID; | ||
201 | } | ||
202 | |||
203 | |||
204 | public bool ParcelAllowThisAvatarSounds | ||
205 | { | ||
206 | get | ||
207 | { | ||
208 | try | ||
209 | { | ||
210 | lock (parcelLock) | ||
211 | { | ||
212 | ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y); | ||
213 | if (land == null) | ||
214 | return true; | ||
215 | if (land.LandData.AnyAVSounds) | ||
216 | return true; | ||
217 | if (!land.LandData.GroupAVSounds) | ||
218 | return false; | ||
219 | return land.LandData.GroupID == ControllingClient.ActiveGroupId; | ||
220 | } | ||
221 | } | ||
222 | catch | ||
223 | { | ||
224 | return true; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | |||
229 | public bool ParcelHideThisAvatar | ||
230 | { | ||
231 | get | ||
232 | { | ||
233 | return m_currentParcelHide; | ||
234 | } | ||
235 | } | ||
236 | |||
114 | /// <value> | 237 | /// <value> |
115 | /// The animator for this avatar | 238 | /// The animator for this avatar |
116 | /// </value> | 239 | /// </value> |
117 | public ScenePresenceAnimator Animator { get; private set; } | 240 | public ScenePresenceAnimator Animator { get; private set; } |
118 | 241 | ||
242 | /// <value> | ||
243 | /// Server Side Animation Override | ||
244 | /// </value> | ||
245 | public MovementAnimationOverrides Overrides { get; private set; } | ||
246 | public String sitAnimation = "SIT"; | ||
119 | /// <summary> | 247 | /// <summary> |
120 | /// Attachments recorded on this avatar. | 248 | /// Attachments recorded on this avatar. |
121 | /// </summary> | 249 | /// </summary> |
@@ -142,6 +270,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
142 | private Vector3 m_lastVelocity; | 270 | private Vector3 m_lastVelocity; |
143 | private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); | 271 | private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); |
144 | 272 | ||
273 | private bool m_followCamAuto = false; | ||
274 | |||
145 | 275 | ||
146 | private Vector3? m_forceToApply; | 276 | private Vector3? m_forceToApply; |
147 | private int m_userFlags; | 277 | private int m_userFlags; |
@@ -157,14 +287,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
157 | set { PhysicsActor.Flying = value; } | 287 | set { PhysicsActor.Flying = value; } |
158 | } | 288 | } |
159 | 289 | ||
160 | // add for fly velocity control | 290 | public bool IsColliding |
161 | private bool FlyingOld {get; set;} | ||
162 | public bool WasFlying | ||
163 | { | ||
164 | get; private set; | ||
165 | } | ||
166 | |||
167 | public bool IsColliding | ||
168 | { | 291 | { |
169 | get { return PhysicsActor != null && PhysicsActor.IsColliding; } | 292 | get { return PhysicsActor != null && PhysicsActor.IsColliding; } |
170 | // We would expect setting IsColliding to be private but it's used by a hack in Scene | 293 | // We would expect setting IsColliding to be private but it's used by a hack in Scene |
@@ -200,7 +323,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
200 | private float m_sitAvatarHeight = 2.0f; | 323 | private float m_sitAvatarHeight = 2.0f; |
201 | 324 | ||
202 | private Vector3 m_lastChildAgentUpdatePosition; | 325 | private Vector3 m_lastChildAgentUpdatePosition; |
203 | private Vector3 m_lastChildAgentUpdateCamPosition; | 326 | // private Vector3 m_lastChildAgentUpdateCamPosition; |
204 | 327 | ||
205 | private const int LAND_VELOCITYMAG_MAX = 12; | 328 | private const int LAND_VELOCITYMAG_MAX = 12; |
206 | 329 | ||
@@ -213,7 +336,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
213 | 336 | ||
214 | protected ulong crossingFromRegion; | 337 | protected ulong crossingFromRegion; |
215 | 338 | ||
216 | private readonly Vector3[] Dir_Vectors = new Vector3[11]; | 339 | private readonly Vector3[] Dir_Vectors = new Vector3[12]; |
217 | 340 | ||
218 | protected Timer m_reprioritization_timer; | 341 | protected Timer m_reprioritization_timer; |
219 | protected bool m_reprioritizing; | 342 | protected bool m_reprioritizing; |
@@ -270,7 +393,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
270 | /// <summary> | 393 | /// <summary> |
271 | /// Implemented Control Flags | 394 | /// Implemented Control Flags |
272 | /// </summary> | 395 | /// </summary> |
273 | private enum Dir_ControlFlags | 396 | private enum Dir_ControlFlags:uint |
274 | { | 397 | { |
275 | DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, | 398 | DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, |
276 | DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, | 399 | DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, |
@@ -282,6 +405,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
282 | DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, | 405 | DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, |
283 | DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, | 406 | DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, |
284 | DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, | 407 | DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, |
408 | DIR_CONTROL_FLAG_UP_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS, | ||
285 | DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG | 409 | DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG |
286 | } | 410 | } |
287 | 411 | ||
@@ -290,9 +414,37 @@ namespace OpenSim.Region.Framework.Scenes | |||
290 | /// </summary> | 414 | /// </summary> |
291 | private Vector3 posLastSignificantMove; | 415 | private Vector3 posLastSignificantMove; |
292 | 416 | ||
293 | // For teleports and crossings callbacks | 417 | #region For teleports and crossings callbacks |
294 | string m_callbackURI; | 418 | |
295 | UUID m_originRegionID; | 419 | /// <summary> |
420 | /// In the V1 teleport protocol, the destination simulator sends ReleaseAgent to this address. | ||
421 | /// </summary> | ||
422 | private string m_callbackURI; | ||
423 | |||
424 | /// <summary> | ||
425 | /// Records the region from which this presence originated, if not from login. | ||
426 | /// </summary> | ||
427 | /// <remarks> | ||
428 | /// Also acts as a signal in the teleport V2 process to release UpdateAgent after a viewer has triggered | ||
429 | /// CompleteMovement and made the previous child agent a root agent. | ||
430 | /// </remarks> | ||
431 | private UUID m_originRegionID; | ||
432 | |||
433 | /// <summary> | ||
434 | /// This object is used as a lock before accessing m_originRegionID to make sure that every thread is seeing | ||
435 | /// the very latest value and not using some cached version. Cannot make m_originRegionID itself volatite as | ||
436 | /// it is a value type. | ||
437 | /// </summary> | ||
438 | private object m_originRegionIDAccessLock = new object(); | ||
439 | |||
440 | /// <summary> | ||
441 | /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent | ||
442 | /// teleport is reusing the connection. | ||
443 | /// </summary> | ||
444 | /// <remarks>May be refactored or move somewhere else soon.</remarks> | ||
445 | public bool DoNotCloseAfterTeleport { get; set; } | ||
446 | |||
447 | #endregion | ||
296 | 448 | ||
297 | /// <value> | 449 | /// <value> |
298 | /// Script engines present in the scene | 450 | /// Script engines present in the scene |
@@ -309,15 +461,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
309 | /// <summary> | 461 | /// <summary> |
310 | /// Record user movement inputs. | 462 | /// Record user movement inputs. |
311 | /// </summary> | 463 | /// </summary> |
312 | public byte MovementFlag { get; private set; } | 464 | public uint MovementFlag { get; private set; } |
313 | 465 | ||
314 | private bool m_updateflag; | 466 | /// <summary> |
315 | 467 | /// Is the agent stop control flag currently active? | |
316 | public bool Updated | 468 | /// </summary> |
317 | { | 469 | public bool AgentControlStopActive { get; private set; } |
318 | set { m_updateflag = value; } | ||
319 | get { return m_updateflag; } | ||
320 | } | ||
321 | 470 | ||
322 | private bool m_invulnerable = true; | 471 | private bool m_invulnerable = true; |
323 | 472 | ||
@@ -344,11 +493,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
344 | } | 493 | } |
345 | 494 | ||
346 | private ulong m_rootRegionHandle; | 495 | private ulong m_rootRegionHandle; |
496 | private Vector3 m_rootRegionPosition = new Vector3(); | ||
347 | 497 | ||
348 | public ulong RegionHandle | 498 | public ulong RegionHandle |
349 | { | 499 | { |
350 | get { return m_rootRegionHandle; } | 500 | get { return m_rootRegionHandle; } |
351 | private set { m_rootRegionHandle = value; } | 501 | private set |
502 | { | ||
503 | m_rootRegionHandle = value; | ||
504 | // position rounded to lower multiple of 256m | ||
505 | m_rootRegionPosition.X = (float)((m_rootRegionHandle >> 32) & 0xffffff00); | ||
506 | m_rootRegionPosition.Y = (float)(m_rootRegionHandle & 0xffffff00); | ||
507 | } | ||
352 | } | 508 | } |
353 | 509 | ||
354 | #region Client Camera | 510 | #region Client Camera |
@@ -380,11 +536,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
380 | get | 536 | get |
381 | { | 537 | { |
382 | Vector3 a = new Vector3(CameraAtAxis.X, CameraAtAxis.Y, 0); | 538 | Vector3 a = new Vector3(CameraAtAxis.X, CameraAtAxis.Y, 0); |
383 | 539 | a.Normalize(); | |
384 | if (a == Vector3.Zero) | 540 | return a; |
385 | return a; | ||
386 | |||
387 | return Util.GetNormalizedVector(a); | ||
388 | } | 541 | } |
389 | } | 542 | } |
390 | #endregion | 543 | #endregion |
@@ -424,6 +577,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
424 | } | 577 | } |
425 | } | 578 | } |
426 | 579 | ||
580 | |||
427 | public byte State { get; set; } | 581 | public byte State { get; set; } |
428 | 582 | ||
429 | private AgentManager.ControlFlags m_AgentControlFlags; | 583 | private AgentManager.ControlFlags m_AgentControlFlags; |
@@ -462,6 +616,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
462 | } | 616 | } |
463 | else | 617 | else |
464 | { | 618 | { |
619 | // m_log.DebugFormat("[SCENE PRESENCE]: Fetching abs pos where PhysicsActor == null and parent part {0} for {1}", Name, Scene.Name); | ||
465 | // Obtain the correct position of a seated avatar. | 620 | // Obtain the correct position of a seated avatar. |
466 | // In addition to providing the correct position while | 621 | // In addition to providing the correct position while |
467 | // the avatar is seated, this value will also | 622 | // the avatar is seated, this value will also |
@@ -475,17 +630,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
475 | // in the sim unless the avatar is on a sit target. While | 630 | // in the sim unless the avatar is on a sit target. While |
476 | // on a sit target, m_pos will contain the desired offset | 631 | // on a sit target, m_pos will contain the desired offset |
477 | // without the parent rotation applied. | 632 | // without the parent rotation applied. |
478 | SceneObjectPart sitPart = ParentPart; | 633 | if (ParentPart != null) |
479 | 634 | { | |
480 | if (sitPart != null) | 635 | SceneObjectPart rootPart = ParentPart.ParentGroup.RootPart; |
481 | return sitPart.AbsolutePosition + (m_pos * sitPart.GetWorldRotation()); | 636 | // if (sitPart != null) |
637 | // return sitPart.AbsolutePosition + (m_pos * sitPart.GetWorldRotation()); | ||
638 | if (rootPart != null) | ||
639 | return rootPart.AbsolutePosition + (m_pos * rootPart.GetWorldRotation()); | ||
640 | } | ||
482 | } | 641 | } |
483 | 642 | ||
484 | return m_pos; | 643 | return m_pos; |
485 | } | 644 | } |
486 | set | 645 | set |
487 | { | 646 | { |
488 | // m_log.DebugFormat("[SCENE PRESENCE]: Setting position of {0} in {1} to {2}", Name, Scene.Name, value); | 647 | // m_log.DebugFormat("[SCENE PRESENCE]: Setting position of {0} to {1} in {2}", Name, value, Scene.Name); |
489 | // Util.PrintCallStack(); | 648 | // Util.PrintCallStack(); |
490 | 649 | ||
491 | if (PhysicsActor != null) | 650 | if (PhysicsActor != null) |
@@ -502,10 +661,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
502 | 661 | ||
503 | // Don't update while sitting. The PhysicsActor above is null whilst sitting. | 662 | // Don't update while sitting. The PhysicsActor above is null whilst sitting. |
504 | if (ParentID == 0) | 663 | if (ParentID == 0) |
505 | { | ||
506 | m_pos = value; | 664 | m_pos = value; |
507 | // ParentPosition = Vector3.Zero; | ||
508 | } | ||
509 | 665 | ||
510 | //m_log.DebugFormat( | 666 | //m_log.DebugFormat( |
511 | // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", | 667 | // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", |
@@ -573,24 +729,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
573 | // Scene.RegionInfo.RegionName, Name, m_velocity); | 729 | // Scene.RegionInfo.RegionName, Name, m_velocity); |
574 | } | 730 | } |
575 | } | 731 | } |
576 | /* | ||
577 | public override Vector3 AngularVelocity | ||
578 | { | ||
579 | get | ||
580 | { | ||
581 | if (PhysicsActor != null) | ||
582 | { | ||
583 | m_rotationalvelocity = PhysicsActor.RotationalVelocity; | ||
584 | 732 | ||
585 | // m_log.DebugFormat( | ||
586 | // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!", | ||
587 | // m_velocity, Name, Scene.RegionInfo.RegionName); | ||
588 | } | ||
589 | |||
590 | return m_rotationalvelocity; | ||
591 | } | ||
592 | } | ||
593 | */ | ||
594 | private Quaternion m_bodyRot = Quaternion.Identity; | 733 | private Quaternion m_bodyRot = Quaternion.Identity; |
595 | 734 | ||
596 | /// <summary> | 735 | /// <summary> |
@@ -760,6 +899,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
760 | } | 899 | } |
761 | } | 900 | } |
762 | 901 | ||
902 | |||
903 | /// <summary> | ||
904 | /// Modifier for agent movement if we get an AGENT_CONTROL_STOP whilst walking or running | ||
905 | /// </summary> | ||
906 | /// <remarks> | ||
907 | /// AGENT_CONTRL_STOP comes about if user holds down space key on viewers. | ||
908 | /// </remarks> | ||
909 | private const float AgentControlStopSlowVel = 0.2f; | ||
910 | // velocities | ||
911 | public const float AgentControlNudgeVel = 1.0f; // setting this diferent from normal as no effect currently | ||
912 | public const float AgentControlNormalVel = 1.0f; | ||
913 | |||
914 | // old normal speed was tuned to match sl normal plus Fast modifiers | ||
915 | // so we need to rescale it | ||
763 | private float m_speedModifier = 1.0f; | 916 | private float m_speedModifier = 1.0f; |
764 | 917 | ||
765 | public float SpeedModifier | 918 | public float SpeedModifier |
@@ -795,13 +948,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
795 | 948 | ||
796 | public ScenePresence( | 949 | public ScenePresence( |
797 | IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) | 950 | IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) |
798 | { | 951 | { |
799 | AttachmentsSyncLock = new Object(); | 952 | AttachmentsSyncLock = new Object(); |
800 | AllowMovement = true; | 953 | AllowMovement = true; |
801 | IsChildAgent = true; | 954 | IsChildAgent = true; |
802 | IsLoggingIn = false; | 955 | IsLoggingIn = false; |
803 | m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; | 956 | m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; |
804 | Animator = new ScenePresenceAnimator(this); | 957 | Animator = new ScenePresenceAnimator(this); |
958 | Overrides = new MovementAnimationOverrides(); | ||
805 | PresenceType = type; | 959 | PresenceType = type; |
806 | DrawDistance = world.DefaultDrawDistance; | 960 | DrawDistance = world.DefaultDrawDistance; |
807 | RegionHandle = world.RegionInfo.RegionHandle; | 961 | RegionHandle = world.RegionInfo.RegionHandle; |
@@ -811,7 +965,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
811 | m_name = String.Format("{0} {1}", Firstname, Lastname); | 965 | m_name = String.Format("{0} {1}", Firstname, Lastname); |
812 | m_scene = world; | 966 | m_scene = world; |
813 | m_uuid = client.AgentId; | 967 | m_uuid = client.AgentId; |
814 | LocalId = m_scene.AllocateLocalId(); | 968 | LocalId = m_scene.AllocatePresenceLocalId(); |
815 | 969 | ||
816 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); | 970 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); |
817 | if (account != null) | 971 | if (account != null) |
@@ -824,7 +978,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
824 | 978 | ||
825 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); | 979 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); |
826 | if (gm != null) | 980 | if (gm != null) |
827 | Grouptitle = gm.GetGroupTitle(m_uuid); | 981 | Grouptitle = gm.GetGroupTitle(m_uuid); |
828 | 982 | ||
829 | m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); | 983 | m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); |
830 | 984 | ||
@@ -841,6 +995,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
841 | SetDirectionVectors(); | 995 | SetDirectionVectors(); |
842 | 996 | ||
843 | Appearance = appearance; | 997 | Appearance = appearance; |
998 | |||
999 | m_stateMachine = new ScenePresenceStateMachine(this); | ||
844 | } | 1000 | } |
845 | 1001 | ||
846 | private void RegionHeartbeatEnd(Scene scene) | 1002 | private void RegionHeartbeatEnd(Scene scene) |
@@ -874,6 +1030,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
874 | { | 1030 | { |
875 | ControllingClient.OnCompleteMovementToRegion += CompleteMovement; | 1031 | ControllingClient.OnCompleteMovementToRegion += CompleteMovement; |
876 | ControllingClient.OnAgentUpdate += HandleAgentUpdate; | 1032 | ControllingClient.OnAgentUpdate += HandleAgentUpdate; |
1033 | ControllingClient.OnAgentCameraUpdate += HandleAgentCamerasUpdate; | ||
877 | ControllingClient.OnAgentRequestSit += HandleAgentRequestSit; | 1034 | ControllingClient.OnAgentRequestSit += HandleAgentRequestSit; |
878 | ControllingClient.OnAgentSit += HandleAgentSit; | 1035 | ControllingClient.OnAgentSit += HandleAgentSit; |
879 | ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; | 1036 | ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; |
@@ -890,22 +1047,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
890 | 1047 | ||
891 | private void SetDirectionVectors() | 1048 | private void SetDirectionVectors() |
892 | { | 1049 | { |
893 | Dir_Vectors[0] = Vector3.UnitX; //FORWARD | 1050 | Dir_Vectors[0] = new Vector3(AgentControlNormalVel,0,0); //FORWARD |
894 | Dir_Vectors[1] = -Vector3.UnitX; //BACK | 1051 | Dir_Vectors[1] = new Vector3(-AgentControlNormalVel,0,0);; //BACK |
895 | Dir_Vectors[2] = Vector3.UnitY; //LEFT | 1052 | Dir_Vectors[2] = new Vector3(0,AgentControlNormalVel,0); //LEFT |
896 | Dir_Vectors[3] = -Vector3.UnitY; //RIGHT | 1053 | Dir_Vectors[3] = new Vector3(0,-AgentControlNormalVel,0); //RIGHT |
897 | Dir_Vectors[4] = Vector3.UnitZ; //UP | 1054 | Dir_Vectors[4] = new Vector3(0,0,AgentControlNormalVel); //UP |
898 | Dir_Vectors[5] = -Vector3.UnitZ; //DOWN | 1055 | Dir_Vectors[5] = new Vector3(0,0,-AgentControlNormalVel); //DOWN |
899 | Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE | 1056 | Dir_Vectors[6] = new Vector3(AgentControlNudgeVel, 0f, 0f); //FORWARD_NUDGE |
900 | Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE | 1057 | Dir_Vectors[7] = new Vector3(-AgentControlNudgeVel, 0f, 0f); //BACK_NUDGE |
901 | Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE | 1058 | Dir_Vectors[8] = new Vector3(0f, AgentControlNudgeVel, 0f); //LEFT_NUDGE |
902 | Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE | 1059 | Dir_Vectors[9] = new Vector3(0f, -AgentControlNudgeVel, 0f); //RIGHT_NUDGE |
903 | Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge | 1060 | Dir_Vectors[10] = new Vector3(0f, 0f, AgentControlNudgeVel); //UP_Nudge |
904 | } | 1061 | Dir_Vectors[11] = new Vector3(0f, 0f, -AgentControlNudgeVel); //DOWN_Nudge |
905 | 1062 | } | |
1063 | |||
1064 | /* dont see any use for this | ||
906 | private Vector3[] GetWalkDirectionVectors() | 1065 | private Vector3[] GetWalkDirectionVectors() |
907 | { | 1066 | { |
908 | Vector3[] vector = new Vector3[11]; | 1067 | Vector3[] vector = new Vector3[12]; |
909 | vector[0] = new Vector3(CameraUpAxis.Z, 0f, -CameraAtAxis.Z); //FORWARD | 1068 | vector[0] = new Vector3(CameraUpAxis.Z, 0f, -CameraAtAxis.Z); //FORWARD |
910 | vector[1] = new Vector3(-CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK | 1069 | vector[1] = new Vector3(-CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK |
911 | vector[2] = Vector3.UnitY; //LEFT | 1070 | vector[2] = Vector3.UnitY; //LEFT |
@@ -916,10 +1075,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
916 | vector[7] = new Vector3(-CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK_NUDGE | 1075 | vector[7] = new Vector3(-CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK_NUDGE |
917 | vector[8] = Vector3.UnitY; //LEFT_NUDGE | 1076 | vector[8] = Vector3.UnitY; //LEFT_NUDGE |
918 | vector[9] = -Vector3.UnitY; //RIGHT_NUDGE | 1077 | vector[9] = -Vector3.UnitY; //RIGHT_NUDGE |
919 | vector[10] = new Vector3(-CameraAtAxis.Z, 0f, -CameraUpAxis.Z); //DOWN_NUDGE | 1078 | vector[10] = new Vector3(CameraAtAxis.Z, 0f, CameraUpAxis.Z); //UP_NUDGE |
1079 | vector[11] = new Vector3(-CameraAtAxis.Z, 0f, -CameraUpAxis.Z); //DOWN_NUDGE | ||
920 | return vector; | 1080 | return vector; |
921 | } | 1081 | } |
922 | 1082 | */ | |
923 | #endregion | 1083 | #endregion |
924 | 1084 | ||
925 | #region Status Methods | 1085 | #region Status Methods |
@@ -927,6 +1087,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
927 | /// <summary> | 1087 | /// <summary> |
928 | /// Turns a child agent into a root agent. | 1088 | /// Turns a child agent into a root agent. |
929 | /// </summary> | 1089 | /// </summary> |
1090 | /// <remarks> | ||
930 | /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the | 1091 | /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the |
931 | /// avatar is actual in the sim. They can perform all actions. | 1092 | /// avatar is actual in the sim. They can perform all actions. |
932 | /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, | 1093 | /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, |
@@ -934,90 +1095,81 @@ namespace OpenSim.Region.Framework.Scenes | |||
934 | /// | 1095 | /// |
935 | /// This method is on the critical path for transferring an avatar from one region to another. Delay here | 1096 | /// This method is on the critical path for transferring an avatar from one region to another. Delay here |
936 | /// delays that crossing. | 1097 | /// delays that crossing. |
937 | /// </summary> | 1098 | /// </remarks> |
938 | public void MakeRootAgent(Vector3 pos, bool isFlying) | 1099 | |
1100 | |||
1101 | // only in use as part of completemovement | ||
1102 | // other uses need fix | ||
1103 | private bool MakeRootAgent(Vector3 pos, bool isFlying) | ||
939 | { | 1104 | { |
940 | m_log.DebugFormat( | 1105 | int ts = Util.EnvironmentTickCount(); |
941 | "[SCENE]: Upgrading child to root agent for {0} in {1}", | ||
942 | Name, m_scene.RegionInfo.RegionName); | ||
943 | 1106 | ||
944 | if (ParentUUID != UUID.Zero) | 1107 | lock (m_completeMovementLock) |
945 | { | 1108 | { |
946 | m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); | 1109 | if (!IsChildAgent) |
947 | SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); | 1110 | return false; |
948 | if (part == null) | 1111 | |
1112 | m_log.DebugFormat("[MakeRootAgent] enter lock: {0}ms", Util.EnvironmentTickCountSubtract(ts)); | ||
1113 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | ||
1114 | |||
1115 | // m_log.InfoFormat( | ||
1116 | // "[SCENE]: Upgrading child to root agent for {0} in {1}", | ||
1117 | // Name, m_scene.RegionInfo.RegionName); | ||
1118 | |||
1119 | if (ParentUUID != UUID.Zero) | ||
949 | { | 1120 | { |
950 | m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); | 1121 | m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); |
1122 | SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); | ||
1123 | if (part == null) | ||
1124 | { | ||
1125 | m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); | ||
1126 | ParentID = 0; | ||
1127 | ParentPart = null; | ||
1128 | PrevSitOffset = Vector3.Zero; | ||
1129 | HandleForceReleaseControls(ControllingClient, UUID); // needs testing | ||
1130 | IsLoggingIn = false; | ||
1131 | } | ||
1132 | else | ||
1133 | { | ||
1134 | part.ParentGroup.AddAvatar(UUID); | ||
1135 | if (part.SitTargetPosition != Vector3.Zero) | ||
1136 | part.SitTargetAvatar = UUID; | ||
1137 | ParentID = part.LocalId; | ||
1138 | ParentPart = part; | ||
1139 | m_pos = PrevSitOffset; | ||
1140 | pos = part.GetWorldPosition(); | ||
1141 | } | ||
1142 | ParentUUID = UUID.Zero; | ||
951 | } | 1143 | } |
952 | else | 1144 | else |
953 | { | 1145 | { |
954 | part.ParentGroup.AddAvatar(UUID); | 1146 | IsLoggingIn = false; |
955 | if (part.SitTargetPosition != Vector3.Zero) | ||
956 | part.SitTargetAvatar = UUID; | ||
957 | // ParentPosition = part.GetWorldPosition(); | ||
958 | ParentID = part.LocalId; | ||
959 | ParentPart = part; | ||
960 | m_pos = PrevSitOffset; | ||
961 | // pos = ParentPosition; | ||
962 | pos = part.GetWorldPosition(); | ||
963 | } | 1147 | } |
964 | ParentUUID = UUID.Zero; | ||
965 | 1148 | ||
966 | IsChildAgent = false; | 1149 | IsChildAgent = false; |
967 | |||
968 | // Animator.TrySetMovementAnimation("SIT"); | ||
969 | } | ||
970 | else | ||
971 | { | ||
972 | IsChildAgent = false; | ||
973 | IsLoggingIn = false; | ||
974 | } | 1150 | } |
975 | 1151 | ||
976 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | 1152 | m_log.DebugFormat("[MakeRootAgent] out lock: {0}ms", Util.EnvironmentTickCountSubtract(ts)); |
977 | 1153 | ||
978 | IsChildAgent = false; | 1154 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag |
1155 | // set and prevent the close of the connection on a subsequent re-teleport. | ||
1156 | // Should not be needed if we are not trying to tell this region to close | ||
1157 | // DoNotCloseAfterTeleport = false; | ||
979 | 1158 | ||
980 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); | 1159 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); |
981 | if (gm != null) | 1160 | if (gm != null) |
982 | Grouptitle = gm.GetGroupTitle(m_uuid); | 1161 | Grouptitle = gm.GetGroupTitle(m_uuid); |
983 | 1162 | ||
1163 | m_log.DebugFormat("[MakeRootAgent] Grouptitle: {0}ms", Util.EnvironmentTickCountSubtract(ts)); | ||
1164 | |||
984 | RegionHandle = m_scene.RegionInfo.RegionHandle; | 1165 | RegionHandle = m_scene.RegionInfo.RegionHandle; |
985 | 1166 | ||
986 | m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); | 1167 | m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); |
1168 | m_log.DebugFormat("[MakeRootAgent] TriggerSetRootAgentScene: {0}ms", Util.EnvironmentTickCountSubtract(ts)); | ||
987 | 1169 | ||
988 | UUID groupUUID = UUID.Zero; | ||
989 | string GroupName = string.Empty; | ||
990 | ulong groupPowers = 0; | ||
991 | |||
992 | // ---------------------------------- | ||
993 | // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status | ||
994 | try | ||
995 | { | ||
996 | if (gm != null) | ||
997 | { | ||
998 | groupUUID = ControllingClient.ActiveGroupId; | ||
999 | GroupRecord record = gm.GetGroupRecord(groupUUID); | ||
1000 | if (record != null) | ||
1001 | GroupName = record.GroupName; | ||
1002 | GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid); | ||
1003 | if (groupMembershipData != null) | ||
1004 | groupPowers = groupMembershipData.GroupPowers; | ||
1005 | } | ||
1006 | ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName, | ||
1007 | Grouptitle); | ||
1008 | } | ||
1009 | catch (Exception e) | ||
1010 | { | ||
1011 | m_log.Debug("[AGENTUPDATE]: " + e.ToString()); | ||
1012 | } | ||
1013 | // ------------------------------------ | ||
1014 | 1170 | ||
1015 | if (ParentID == 0) | 1171 | if (ParentID == 0) |
1016 | { | 1172 | { |
1017 | // Moved this from SendInitialData to ensure that Appearance is initialized | ||
1018 | // before the inventory is processed in MakeRootAgent. This fixes a race condition | ||
1019 | // related to the handling of attachments | ||
1020 | //m_scene.GetAvatarAppearance(ControllingClient, out Appearance); | ||
1021 | if (m_scene.TestBorderCross(pos, Cardinals.E)) | 1173 | if (m_scene.TestBorderCross(pos, Cardinals.E)) |
1022 | { | 1174 | { |
1023 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); | 1175 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); |
@@ -1051,7 +1203,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1051 | 1203 | ||
1052 | if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) | 1204 | if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) |
1053 | posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; | 1205 | posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; |
1054 | 1206 | ||
1055 | float newPosZ = posZLimit + localAVHeight / 2; | 1207 | float newPosZ = posZLimit + localAVHeight / 2; |
1056 | if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) | 1208 | if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) |
1057 | { | 1209 | { |
@@ -1059,6 +1211,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1059 | } | 1211 | } |
1060 | AbsolutePosition = pos; | 1212 | AbsolutePosition = pos; |
1061 | 1213 | ||
1214 | |||
1062 | if (m_teleportFlags == TeleportFlags.Default) | 1215 | if (m_teleportFlags == TeleportFlags.Default) |
1063 | { | 1216 | { |
1064 | Vector3 vel = Velocity; | 1217 | Vector3 vel = Velocity; |
@@ -1069,12 +1222,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1069 | else | 1222 | else |
1070 | AddToPhysicalScene(isFlying); | 1223 | AddToPhysicalScene(isFlying); |
1071 | 1224 | ||
1072 | // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a | ||
1073 | // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it | ||
1074 | // since it requires a physics actor to be present. If it is left any later, then physics appears to reset | ||
1075 | // the value to a negative position which does not trigger the border cross. | ||
1076 | // This may not be the best location for this. | ||
1077 | CheckForBorderCrossing(); | ||
1078 | 1225 | ||
1079 | if (ForceFly) | 1226 | if (ForceFly) |
1080 | { | 1227 | { |
@@ -1084,66 +1231,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1084 | { | 1231 | { |
1085 | Flying = false; | 1232 | Flying = false; |
1086 | } | 1233 | } |
1087 | } | ||
1088 | // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying | ||
1089 | // avatar to return to the standing position in mid-air. On login it looks like this is being sent | ||
1090 | // elsewhere anyway | ||
1091 | // Animator.SendAnimPack(); | ||
1092 | 1234 | ||
1093 | m_scene.SwapRootAgentCount(false); | 1235 | // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a |
1236 | // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it | ||
1237 | // since it requires a physics actor to be present. If it is left any later, then physics appears to reset | ||
1238 | // the value to a negative position which does not trigger the border cross. | ||
1239 | // This may not be the best location for this. | ||
1094 | 1240 | ||
1095 | // The initial login scene presence is already root when it gets here | ||
1096 | // and it has already rezzed the attachments and started their scripts. | ||
1097 | // We do the following only for non-login agents, because their scripts | ||
1098 | // haven't started yet. | ||
1099 | if (PresenceType == PresenceType.Npc || (TeleportFlags & TeleportFlags.ViaLogin) != 0) | ||
1100 | { | ||
1101 | // Viewers which have a current outfit folder will actually rez their own attachments. However, | ||
1102 | // viewers without (e.g. v1 viewers) will not, so we still need to make this call. | ||
1103 | if (Scene.AttachmentsModule != null) | ||
1104 | Util.FireAndForget( | ||
1105 | o => | ||
1106 | { | ||
1107 | // if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) | ||
1108 | // System.Threading.Thread.Sleep(7000); | ||
1109 | 1241 | ||
1110 | Scene.AttachmentsModule.RezAttachments(this); | 1242 | // its not |
1111 | }); | 1243 | // CheckForBorderCrossing(); |
1112 | } | 1244 | } |
1113 | else | 1245 | |
1114 | { | 1246 | m_log.DebugFormat("[MakeRootAgent] position and physical: {0}ms", Util.EnvironmentTickCountSubtract(ts)); |
1115 | // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT | 1247 | m_scene.SwapRootAgentCount(false); |
1116 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | ||
1117 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | ||
1118 | // not transporting the required data. | ||
1119 | lock (m_attachments) | ||
1120 | { | ||
1121 | if (HasAttachments()) | ||
1122 | { | ||
1123 | m_log.DebugFormat( | ||
1124 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | ||
1125 | |||
1126 | // Resume scripts | ||
1127 | Util.FireAndForget(delegate(object x) { | ||
1128 | foreach (SceneObjectGroup sog in m_attachments) | ||
1129 | { | ||
1130 | sog.ScheduleGroupForFullUpdate(); | ||
1131 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | ||
1132 | sog.ResumeScripts(); | ||
1133 | } | ||
1134 | }); | ||
1135 | } | ||
1136 | } | ||
1137 | } | ||
1138 | |||
1139 | SendAvatarDataToAllAgents(); | ||
1140 | 1248 | ||
1141 | // send the animations of the other presences to me | ||
1142 | m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) | ||
1143 | { | ||
1144 | if (presence != this) | ||
1145 | presence.Animator.SendAnimPackToClient(ControllingClient); | ||
1146 | }); | ||
1147 | 1249 | ||
1148 | // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will | 1250 | // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will |
1149 | // stall on the border crossing since the existing child agent will still have the last movement | 1251 | // stall on the border crossing since the existing child agent will still have the last movement |
@@ -1152,8 +1254,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1152 | MovementFlag = 0; | 1254 | MovementFlag = 0; |
1153 | 1255 | ||
1154 | m_scene.EventManager.TriggerOnMakeRootAgent(this); | 1256 | m_scene.EventManager.TriggerOnMakeRootAgent(this); |
1257 | m_log.DebugFormat("[MakeRootAgent] TriggerOnMakeRootAgent and done: {0}ms", Util.EnvironmentTickCountSubtract(ts)); | ||
1155 | 1258 | ||
1156 | m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd; | 1259 | return true; |
1157 | } | 1260 | } |
1158 | 1261 | ||
1159 | public int GetStateSource() | 1262 | public int GetStateSource() |
@@ -1179,11 +1282,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1179 | /// It doesn't get called for a teleport. Reason being, an agent that | 1282 | /// It doesn't get called for a teleport. Reason being, an agent that |
1180 | /// teleports out may not end up anywhere near this region | 1283 | /// teleports out may not end up anywhere near this region |
1181 | /// </remarks> | 1284 | /// </remarks> |
1182 | public void MakeChildAgent() | 1285 | public void MakeChildAgent(ulong newRegionHandle) |
1183 | { | 1286 | { |
1184 | m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; | 1287 | m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; |
1185 | 1288 | ||
1186 | m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); | 1289 | RegionHandle = newRegionHandle; |
1290 | |||
1291 | m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1} from root region {2}", | ||
1292 | Name, Scene.RegionInfo.RegionName, newRegionHandle); | ||
1293 | |||
1294 | // Reset the m_originRegionID as it has dual use as a flag to signal that the UpdateAgent() call orignating | ||
1295 | // from the source simulator has completed on a V2 teleport. | ||
1296 | lock (m_originRegionIDAccessLock) | ||
1297 | m_originRegionID = UUID.Zero; | ||
1187 | 1298 | ||
1188 | // Reset these so that teleporting in and walking out isn't seen | 1299 | // Reset these so that teleporting in and walking out isn't seen |
1189 | // as teleporting back | 1300 | // as teleporting back |
@@ -1198,7 +1309,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1198 | else | 1309 | else |
1199 | Animator.ResetAnimations(); | 1310 | Animator.ResetAnimations(); |
1200 | 1311 | ||
1201 | 1312 | ||
1202 | // m_log.DebugFormat( | 1313 | // m_log.DebugFormat( |
1203 | // "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", | 1314 | // "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", |
1204 | // Name, UUID, m_scene.RegionInfo.RegionName); | 1315 | // Name, UUID, m_scene.RegionInfo.RegionName); |
@@ -1212,8 +1323,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1212 | RemoveFromPhysicalScene(); | 1323 | RemoveFromPhysicalScene(); |
1213 | ParentID = 0; // Child agents can't be sitting | 1324 | ParentID = 0; // Child agents can't be sitting |
1214 | 1325 | ||
1326 | // we dont have land information for child | ||
1327 | m_previusParcelHide = false; | ||
1328 | m_previusParcelUUID = UUID.Zero; | ||
1329 | m_currentParcelHide = false; | ||
1330 | m_currentParcelUUID = UUID.Zero; | ||
1215 | // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into | 1331 | // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into |
1216 | 1332 | ||
1333 | CollisionPlane = Vector4.UnitW; | ||
1334 | |||
1217 | m_scene.EventManager.TriggerOnMakeChildAgent(this); | 1335 | m_scene.EventManager.TriggerOnMakeChildAgent(this); |
1218 | } | 1336 | } |
1219 | 1337 | ||
@@ -1306,7 +1424,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
1306 | 1424 | ||
1307 | public void StopFlying() | 1425 | public void StopFlying() |
1308 | { | 1426 | { |
1309 | ControllingClient.StopFlying(this); | 1427 | if (IsInTransit) |
1428 | return; | ||
1429 | |||
1430 | Vector3 pos = AbsolutePosition; | ||
1431 | if (Appearance.AvatarHeight != 127.0f) | ||
1432 | pos += new Vector3(0f, 0f, (Appearance.AvatarHeight / 6f)); | ||
1433 | else | ||
1434 | pos += new Vector3(0f, 0f, (1.56f / 6f)); | ||
1435 | |||
1436 | AbsolutePosition = pos; | ||
1437 | |||
1438 | // attach a suitable collision plane regardless of the actual situation to force the LLClient to land. | ||
1439 | // Collision plane below the avatar's position a 6th of the avatar's height is suitable. | ||
1440 | // Mind you, that this method doesn't get called if the avatar's velocity magnitude is greater then a | ||
1441 | // certain amount.. because the LLClient wouldn't land in that situation anyway. | ||
1442 | |||
1443 | // why are we still testing for this really old height value default??? | ||
1444 | if (Appearance.AvatarHeight != 127.0f) | ||
1445 | CollisionPlane = new Vector4(0, 0, 0, pos.Z - Appearance.AvatarHeight / 6f); | ||
1446 | else | ||
1447 | CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f / 6f)); | ||
1448 | |||
1449 | SendAgentTerseUpdate(this); | ||
1310 | } | 1450 | } |
1311 | 1451 | ||
1312 | /// <summary> | 1452 | /// <summary> |
@@ -1426,6 +1566,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1426 | } | 1566 | } |
1427 | } | 1567 | } |
1428 | 1568 | ||
1569 | public void DropThisRootRegionFromNeighbours() | ||
1570 | { | ||
1571 | ulong handle = m_scene.RegionInfo.RegionHandle; | ||
1572 | RemoveNeighbourRegion(handle); | ||
1573 | Scene.CapsModule.DropChildSeed(UUID, handle); | ||
1574 | } | ||
1575 | |||
1576 | |||
1429 | public Dictionary<ulong, string> KnownRegions | 1577 | public Dictionary<ulong, string> KnownRegions |
1430 | { | 1578 | { |
1431 | get | 1579 | get |
@@ -1480,6 +1628,37 @@ namespace OpenSim.Region.Framework.Scenes | |||
1480 | 1628 | ||
1481 | } | 1629 | } |
1482 | 1630 | ||
1631 | private bool WaitForUpdateAgent(IClientAPI client) | ||
1632 | { | ||
1633 | // Before the source region executes UpdateAgent | ||
1634 | // (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination, | ||
1635 | // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the | ||
1636 | // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero | ||
1637 | int count = 50; | ||
1638 | UUID originID; | ||
1639 | |||
1640 | lock (m_originRegionIDAccessLock) | ||
1641 | originID = m_originRegionID; | ||
1642 | |||
1643 | while (originID.Equals(UUID.Zero) && count-- > 0) | ||
1644 | { | ||
1645 | lock (m_originRegionIDAccessLock) | ||
1646 | originID = m_originRegionID; | ||
1647 | |||
1648 | m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); | ||
1649 | Thread.Sleep(200); | ||
1650 | } | ||
1651 | |||
1652 | if (originID.Equals(UUID.Zero)) | ||
1653 | { | ||
1654 | // Movement into region will fail | ||
1655 | m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name); | ||
1656 | return false; | ||
1657 | } | ||
1658 | |||
1659 | return true; | ||
1660 | } | ||
1661 | |||
1483 | /// <summary> | 1662 | /// <summary> |
1484 | /// Complete Avatar's movement into the region. | 1663 | /// Complete Avatar's movement into the region. |
1485 | /// </summary> | 1664 | /// </summary> |
@@ -1491,53 +1670,88 @@ namespace OpenSim.Region.Framework.Scenes | |||
1491 | /// </param> | 1670 | /// </param> |
1492 | public void CompleteMovement(IClientAPI client, bool openChildAgents) | 1671 | public void CompleteMovement(IClientAPI client, bool openChildAgents) |
1493 | { | 1672 | { |
1494 | // DateTime startTime = DateTime.Now; | 1673 | int ts = Util.EnvironmentTickCount(); |
1495 | 1674 | ||
1496 | m_log.DebugFormat( | 1675 | m_log.InfoFormat( |
1497 | "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", | 1676 | "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", |
1498 | client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); | 1677 | client.Name, Scene.Name, AbsolutePosition); |
1499 | 1678 | ||
1500 | Vector3 look = Velocity; | 1679 | m_inTransit = true; |
1501 | 1680 | ||
1502 | // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) | 1681 | try |
1503 | if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1)) | ||
1504 | { | 1682 | { |
1505 | look = new Vector3(0.99f, 0.042f, 0); | 1683 | // Make sure it's not a login agent. We don't want to wait for updates during login |
1506 | } | 1684 | if (!isNPC && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) |
1685 | { | ||
1507 | 1686 | ||
1508 | // Prevent teleporting to an underground location | 1687 | // Let's wait until UpdateAgent (called by departing region) is done |
1509 | // (may crash client otherwise) | 1688 | if (!WaitForUpdateAgent(client)) |
1510 | // | 1689 | // The sending region never sent the UpdateAgent data, we have to refuse |
1511 | Vector3 pos = AbsolutePosition; | 1690 | return; |
1512 | float ground = m_scene.GetGroundHeight(pos.X, pos.Y); | 1691 | } |
1513 | if (pos.Z < ground + 1.5f) | ||
1514 | { | ||
1515 | pos.Z = ground + 1.5f; | ||
1516 | AbsolutePosition = pos; | ||
1517 | } | ||
1518 | 1692 | ||
1519 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1693 | m_log.DebugFormat("[CompleteMovement] WaitForUpdateAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); |
1520 | MakeRootAgent(AbsolutePosition, flying); | ||
1521 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); | ||
1522 | 1694 | ||
1523 | // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); | 1695 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1524 | 1696 | ||
1525 | if ((m_callbackURI != null) && !m_callbackURI.Equals("")) | 1697 | if (!MakeRootAgent(AbsolutePosition, flying)) |
1526 | { | 1698 | { |
1527 | // We cannot sleep here since this would hold up the inbound packet processing thread, as | 1699 | m_log.DebugFormat( |
1528 | // CompleteMovement() is executed synchronously. However, it might be better to delay the release | 1700 | "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root", |
1529 | // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete | 1701 | Name, Scene.Name); |
1530 | // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this | ||
1531 | // region as the current region, meaning that a close sent before then will fail the teleport. | ||
1532 | // System.Threading.Thread.Sleep(2000); | ||
1533 | 1702 | ||
1534 | m_log.DebugFormat( | 1703 | return; |
1535 | "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", | 1704 | } |
1536 | client.Name, client.AgentId, m_callbackURI); | ||
1537 | 1705 | ||
1538 | Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); | 1706 | m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); |
1539 | m_callbackURI = null; | 1707 | |
1540 | } | 1708 | Vector3 look = Lookat; |
1709 | if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01)) | ||
1710 | { | ||
1711 | look = Velocity; | ||
1712 | look.Z = 0; | ||
1713 | look.Normalize(); | ||
1714 | if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01) ) | ||
1715 | look = new Vector3(0.99f, 0.042f, 0); | ||
1716 | } | ||
1717 | |||
1718 | if (!IsChildAgent && !isNPC) | ||
1719 | { | ||
1720 | InventoryFolderBase cof = m_scene.InventoryService.GetFolderForType(client.AgentId, (AssetType)46); | ||
1721 | if (cof == null) | ||
1722 | COF = UUID.Zero; | ||
1723 | else | ||
1724 | COF = cof.ID; | ||
1725 | |||
1726 | m_log.DebugFormat("[ScenePresence]: CompleteMovement COF for {0} is {1}", client.AgentId, COF); | ||
1727 | } | ||
1728 | |||
1729 | // Tell the client that we're totally ready | ||
1730 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); | ||
1731 | |||
1732 | m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts)); | ||
1733 | |||
1734 | if (!string.IsNullOrEmpty(m_callbackURI)) | ||
1735 | { | ||
1736 | // We cannot sleep here since this would hold up the inbound packet processing thread, as | ||
1737 | // CompleteMovement() is executed synchronously. However, it might be better to delay the release | ||
1738 | // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete | ||
1739 | // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this | ||
1740 | // region as the current region, meaning that a close sent before then will fail the teleport. | ||
1741 | // System.Threading.Thread.Sleep(2000); | ||
1742 | |||
1743 | m_log.DebugFormat( | ||
1744 | "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", | ||
1745 | client.Name, client.AgentId, m_callbackURI); | ||
1746 | |||
1747 | UUID originID; | ||
1748 | |||
1749 | lock (m_originRegionIDAccessLock) | ||
1750 | originID = m_originRegionID; | ||
1751 | |||
1752 | Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); | ||
1753 | m_callbackURI = null; | ||
1754 | } | ||
1541 | // else | 1755 | // else |
1542 | // { | 1756 | // { |
1543 | // m_log.DebugFormat( | 1757 | // m_log.DebugFormat( |
@@ -1545,34 +1759,181 @@ namespace OpenSim.Region.Framework.Scenes | |||
1545 | // client.Name, client.AgentId, m_scene.RegionInfo.RegionName); | 1759 | // client.Name, client.AgentId, m_scene.RegionInfo.RegionName); |
1546 | // } | 1760 | // } |
1547 | 1761 | ||
1548 | ValidateAndSendAppearanceAndAgentData(); | 1762 | m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); |
1549 | 1763 | ||
1550 | // Create child agents in neighbouring regions | 1764 | m_previusParcelHide = false; |
1551 | if (openChildAgents && !IsChildAgent) | 1765 | m_previusParcelUUID = UUID.Zero; |
1552 | { | 1766 | m_currentParcelHide = false; |
1767 | m_currentParcelUUID = UUID.Zero; | ||
1553 | 1768 | ||
1554 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | 1769 | // send initial land overlay and parcel |
1555 | if (m_agentTransfer != null) | 1770 | ILandChannel landch = m_scene.LandChannel; |
1556 | m_agentTransfer.EnableChildAgents(this); | 1771 | if (landch != null) |
1772 | landch.sendClientInitialLandInfo(client); | ||
1557 | 1773 | ||
1558 | IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); | 1774 | if (!IsChildAgent) |
1559 | if (friendsModule != null) | 1775 | { |
1560 | friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); | ||
1561 | 1776 | ||
1562 | } | 1777 | // ValidateAndSendAppearanceAndAgentData(); |
1563 | 1778 | ||
1564 | // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region | 1779 | // do it here in line |
1565 | // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. | 1780 | // so sequence is clear |
1566 | // This may be due to viewer code or it may be something we're not doing properly simulator side. | 1781 | |
1567 | lock (m_attachments) | 1782 | // verify baked textures and cache |
1783 | |||
1784 | |||
1785 | bool cachedbaked = false; | ||
1786 | |||
1787 | if (isNPC) | ||
1788 | cachedbaked = true; | ||
1789 | else | ||
1790 | { | ||
1791 | if (m_scene.AvatarFactory != null) | ||
1792 | cachedbaked = m_scene.AvatarFactory.ValidateBakedTextureCache(this); | ||
1793 | |||
1794 | // not sure we need this | ||
1795 | if (!cachedbaked) | ||
1796 | { | ||
1797 | if (m_scene.AvatarFactory != null) | ||
1798 | m_scene.AvatarFactory.QueueAppearanceSave(UUID); | ||
1799 | } | ||
1800 | } | ||
1801 | |||
1802 | List<ScenePresence> allpresences = m_scene.GetScenePresences(); | ||
1803 | |||
1804 | // send avatar object to all presences including us, so they cross it into region | ||
1805 | // then hide if necessary | ||
1806 | SendInitialAvatarDataToAllAgents(allpresences); | ||
1807 | |||
1808 | // send this look | ||
1809 | SendAppearanceToAgent(this); | ||
1810 | |||
1811 | // send this animations | ||
1812 | |||
1813 | UUID[] animIDs = null; | ||
1814 | int[] animseqs = null; | ||
1815 | UUID[] animsobjs = null; | ||
1816 | |||
1817 | if (Animator != null) | ||
1818 | Animator.GetArrays(out animIDs, out animseqs, out animsobjs); | ||
1819 | |||
1820 | bool haveAnims = (animIDs != null && animseqs != null && animsobjs != null); | ||
1821 | |||
1822 | if(haveAnims) | ||
1823 | SendAnimPackToAgent(this, animIDs, animseqs, animsobjs); | ||
1824 | |||
1825 | // we should be able to receive updates, etc | ||
1826 | // so release them | ||
1827 | m_inTransit = false; | ||
1828 | |||
1829 | // send look and animations to others | ||
1830 | // if not cached we send greys | ||
1831 | // uncomented if will wait till avatar does baking | ||
1832 | //if (cachedbaked) | ||
1833 | { | ||
1834 | foreach (ScenePresence p in allpresences) | ||
1835 | { | ||
1836 | if (p == this) | ||
1837 | continue; | ||
1838 | |||
1839 | if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
1840 | continue; | ||
1841 | |||
1842 | SendAppearanceToAgentNF(p); | ||
1843 | if (haveAnims) | ||
1844 | SendAnimPackToAgentNF(p, animIDs, animseqs, animsobjs); | ||
1845 | } | ||
1846 | } // greys if | ||
1847 | |||
1848 | m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts)); | ||
1849 | |||
1850 | // attachments | ||
1851 | |||
1852 | if (isNPC || (TeleportFlags & TeleportFlags.ViaLogin) != 0) | ||
1853 | { | ||
1854 | if (Scene.AttachmentsModule != null) | ||
1855 | // Util.FireAndForget( | ||
1856 | // o => | ||
1857 | // { | ||
1858 | Scene.AttachmentsModule.RezAttachments(this); | ||
1859 | // }); | ||
1860 | } | ||
1861 | else | ||
1862 | { | ||
1863 | if (m_attachments.Count > 0) | ||
1864 | { | ||
1865 | m_log.DebugFormat( | ||
1866 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | ||
1867 | |||
1868 | foreach(SceneObjectGroup sog in m_attachments) | ||
1869 | { | ||
1870 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | ||
1871 | sog.ResumeScripts(); | ||
1872 | } | ||
1873 | |||
1874 | foreach (ScenePresence p in allpresences) | ||
1875 | { | ||
1876 | if (p == this) | ||
1877 | { | ||
1878 | SendTerseUpdateToAgentNF(this); | ||
1879 | SendAttachmentsToAgentNF(this); | ||
1880 | continue; | ||
1881 | } | ||
1882 | |||
1883 | if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
1884 | continue; | ||
1885 | |||
1886 | SendTerseUpdateToAgentNF(p); | ||
1887 | SendAttachmentsToAgentNF(p); | ||
1888 | } | ||
1889 | } | ||
1890 | } | ||
1891 | |||
1892 | m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts)); | ||
1893 | |||
1894 | // Create child agents in neighbouring regions | ||
1895 | if (openChildAgents) | ||
1896 | { | ||
1897 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | ||
1898 | if (m_agentTransfer != null) | ||
1899 | { | ||
1900 | m_agentTransfer.EnableChildAgents(this); | ||
1901 | } | ||
1902 | } | ||
1903 | } | ||
1904 | |||
1905 | m_log.DebugFormat("[CompleteMovement] openChildAgents: {0}ms", Util.EnvironmentTickCountSubtract(ts)); | ||
1906 | |||
1907 | // send the rest of the world | ||
1908 | if (m_teleportFlags > 0 && !isNPC || m_currentParcelHide) | ||
1909 | SendInitialDataToMe(); | ||
1910 | |||
1911 | m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts)); | ||
1912 | |||
1913 | if (!IsChildAgent && openChildAgents) | ||
1914 | { | ||
1915 | IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); | ||
1916 | if (friendsModule != null) | ||
1917 | friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); | ||
1918 | |||
1919 | m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms", Util.EnvironmentTickCountSubtract(ts)); | ||
1920 | |||
1921 | } | ||
1922 | } | ||
1923 | finally | ||
1568 | { | 1924 | { |
1569 | foreach (SceneObjectGroup sog in m_attachments) | 1925 | m_inTransit = false; |
1570 | sog.ScheduleGroupForFullUpdate(); | ||
1571 | } | 1926 | } |
1927 | // if hide force a check | ||
1928 | // if (!IsChildAgent && newhide) | ||
1929 | // { | ||
1930 | // ParcelLoginCheck(m_currentParcelUUID); | ||
1931 | // m_currentParcelHide = newhide; | ||
1932 | // } | ||
1572 | 1933 | ||
1573 | // m_log.DebugFormat( | 1934 | m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd; |
1574 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", | 1935 | |
1575 | // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); | 1936 | m_log.DebugFormat("[CompleteMovement] end: {0}ms", Util.EnvironmentTickCountSubtract(ts)); |
1576 | } | 1937 | } |
1577 | 1938 | ||
1578 | /// <summary> | 1939 | /// <summary> |
@@ -1653,9 +2014,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1653 | /// </summary> | 2014 | /// </summary> |
1654 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | 2015 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) |
1655 | { | 2016 | { |
1656 | // m_log.DebugFormat( | 2017 | //m_log.DebugFormat( |
1657 | // "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", | 2018 | // "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", |
1658 | // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); | 2019 | // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); |
1659 | 2020 | ||
1660 | if (IsChildAgent) | 2021 | if (IsChildAgent) |
1661 | { | 2022 | { |
@@ -1663,9 +2024,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1663 | return; | 2024 | return; |
1664 | } | 2025 | } |
1665 | 2026 | ||
1666 | ++m_movementUpdateCount; | 2027 | if (IsInTransit) |
1667 | if (m_movementUpdateCount < 1) | 2028 | return; |
1668 | m_movementUpdateCount = 1; | ||
1669 | 2029 | ||
1670 | #region Sanity Checking | 2030 | #region Sanity Checking |
1671 | 2031 | ||
@@ -1697,21 +2057,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1697 | 2057 | ||
1698 | AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; | 2058 | AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; |
1699 | 2059 | ||
1700 | // Camera location in world. We'll need to raytrace | ||
1701 | // from this location from time to time. | ||
1702 | CameraPosition = agentData.CameraCenter; | ||
1703 | if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance) | ||
1704 | { | ||
1705 | ReprioritizeUpdates(); | ||
1706 | m_lastCameraPosition = CameraPosition; | ||
1707 | } | ||
1708 | |||
1709 | // Use these three vectors to figure out what the agent is looking at | ||
1710 | // Convert it to a Matrix and/or Quaternion | ||
1711 | CameraAtAxis = agentData.CameraAtAxis; | ||
1712 | CameraLeftAxis = agentData.CameraLeftAxis; | ||
1713 | CameraUpAxis = agentData.CameraUpAxis; | ||
1714 | |||
1715 | // The Agent's Draw distance setting | 2060 | // The Agent's Draw distance setting |
1716 | // When we get to the point of re-computing neighbors everytime this | 2061 | // When we get to the point of re-computing neighbors everytime this |
1717 | // changes, then start using the agent's drawdistance rather than the | 2062 | // changes, then start using the agent's drawdistance rather than the |
@@ -1733,6 +2078,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1733 | // (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) | 2078 | // (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) |
1734 | // m_updateCount = UPDATE_COUNT; | 2079 | // m_updateCount = UPDATE_COUNT; |
1735 | 2080 | ||
2081 | |||
1736 | if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) | 2082 | if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) |
1737 | { | 2083 | { |
1738 | StandUp(); | 2084 | StandUp(); |
@@ -1783,9 +2129,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1783 | // Here's where you get them. | 2129 | // Here's where you get them. |
1784 | m_AgentControlFlags = flags; | 2130 | m_AgentControlFlags = flags; |
1785 | m_headrotation = agentData.HeadRotation; | 2131 | m_headrotation = agentData.HeadRotation; |
2132 | byte oldState = State; | ||
1786 | State = agentData.State; | 2133 | State = agentData.State; |
1787 | 2134 | ||
2135 | // We need to send this back to the client in order to stop the edit beams | ||
2136 | if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None) | ||
2137 | SendAgentTerseUpdate(this); | ||
2138 | |||
1788 | PhysicsActor actor = PhysicsActor; | 2139 | PhysicsActor actor = PhysicsActor; |
2140 | |||
2141 | // This will be the case if the agent is sitting on the groudn or on an object. | ||
1789 | if (actor == null) | 2142 | if (actor == null) |
1790 | { | 2143 | { |
1791 | SendControlsToScripts(flagsForScripts); | 2144 | SendControlsToScripts(flagsForScripts); |
@@ -1794,12 +2147,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1794 | 2147 | ||
1795 | if (AllowMovement && !SitGround) | 2148 | if (AllowMovement && !SitGround) |
1796 | { | 2149 | { |
1797 | Quaternion bodyRotation = agentData.BodyRotation; | 2150 | // m_log.DebugFormat("[SCENE PRESENCE]: Initial body rotation {0} for {1}", agentData.BodyRotation, Name); |
1798 | bool update_rotation = false; | 2151 | bool update_rotation = false; |
1799 | 2152 | if (agentData.BodyRotation != Rotation) | |
1800 | if (bodyRotation != Rotation) | ||
1801 | { | 2153 | { |
1802 | Rotation = bodyRotation; | 2154 | Rotation = agentData.BodyRotation; |
1803 | update_rotation = true; | 2155 | update_rotation = true; |
1804 | } | 2156 | } |
1805 | 2157 | ||
@@ -1815,7 +2167,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1815 | bool DCFlagKeyPressed = false; | 2167 | bool DCFlagKeyPressed = false; |
1816 | Vector3 agent_control_v3 = Vector3.Zero; | 2168 | Vector3 agent_control_v3 = Vector3.Zero; |
1817 | 2169 | ||
1818 | bool newFlying = actor.Flying; | 2170 | bool newFlying = false; |
1819 | 2171 | ||
1820 | if (ForceFly) | 2172 | if (ForceFly) |
1821 | newFlying = true; | 2173 | newFlying = true; |
@@ -1840,15 +2192,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1840 | 2192 | ||
1841 | // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying | 2193 | // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying |
1842 | // this prevents 'jumping' in inappropriate situations. | 2194 | // this prevents 'jumping' in inappropriate situations. |
1843 | if (!Flying && (m_mouseLook || m_leftButtonDown)) | 2195 | // if (!Flying && (m_mouseLook || m_leftButtonDown)) |
1844 | dirVectors = GetWalkDirectionVectors(); | 2196 | // dirVectors = GetWalkDirectionVectors(); |
1845 | else | 2197 | // else |
1846 | dirVectors = Dir_Vectors; | 2198 | dirVectors = Dir_Vectors; |
1847 | 2199 | ||
1848 | // The fact that MovementFlag is a byte needs to be fixed | 2200 | |
1849 | // it really should be a uint | ||
1850 | // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction. | 2201 | // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction. |
1851 | uint nudgehack = 250; | ||
1852 | foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) | 2202 | foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) |
1853 | { | 2203 | { |
1854 | if (((uint)flags & (uint)DCF) != 0) | 2204 | if (((uint)flags & (uint)DCF) != 0) |
@@ -1865,29 +2215,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1865 | // Why did I get this? | 2215 | // Why did I get this? |
1866 | } | 2216 | } |
1867 | 2217 | ||
1868 | if ((MovementFlag & (byte)(uint)DCF) == 0) | 2218 | if (((MovementFlag & (uint)DCF) == 0)) |
1869 | { | 2219 | { |
1870 | if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE || | ||
1871 | DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT_NUDGE) | ||
1872 | { | ||
1873 | MovementFlag |= (byte)nudgehack; | ||
1874 | } | ||
1875 | |||
1876 | //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); | 2220 | //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); |
1877 | MovementFlag += (byte)(uint)DCF; | 2221 | MovementFlag |= (uint)DCF; |
1878 | update_movementflag = true; | 2222 | update_movementflag = true; |
1879 | } | 2223 | } |
1880 | } | 2224 | } |
1881 | else | 2225 | else |
1882 | { | 2226 | { |
1883 | if ((MovementFlag & (byte)(uint)DCF) != 0 || | 2227 | if ((MovementFlag & (uint)DCF) != 0) |
1884 | ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE || | ||
1885 | DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT_NUDGE) | ||
1886 | && ((MovementFlag & (byte)nudgehack) == nudgehack)) | ||
1887 | ) // This or is for Nudge forward | ||
1888 | { | 2228 | { |
1889 | //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); | 2229 | //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); |
1890 | MovementFlag -= ((byte)(uint)DCF); | 2230 | MovementFlag &= (uint)~DCF; |
1891 | update_movementflag = true; | 2231 | update_movementflag = true; |
1892 | 2232 | ||
1893 | /* | 2233 | /* |
@@ -1907,6 +2247,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1907 | i++; | 2247 | i++; |
1908 | } | 2248 | } |
1909 | 2249 | ||
2250 | // Detect AGENT_CONTROL_STOP state changes | ||
2251 | if (AgentControlStopActive != ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STOP) != 0)) | ||
2252 | { | ||
2253 | AgentControlStopActive = !AgentControlStopActive; | ||
2254 | update_movementflag = true; | ||
2255 | } | ||
2256 | |||
1910 | if (MovingToTarget) | 2257 | if (MovingToTarget) |
1911 | { | 2258 | { |
1912 | // If the user has pressed a key then we want to cancel any move to target. | 2259 | // If the user has pressed a key then we want to cancel any move to target. |
@@ -1932,74 +2279,168 @@ namespace OpenSim.Region.Framework.Scenes | |||
1932 | // Only do this if we're flying | 2279 | // Only do this if we're flying |
1933 | if (Flying && !ForceFly) | 2280 | if (Flying && !ForceFly) |
1934 | { | 2281 | { |
1935 | // Landing detection code | 2282 | // Need to stop in mid air if user holds down AGENT_CONTROL_STOP |
1936 | 2283 | // if (AgentControlStopActive) | |
1937 | // Are the landing controls requirements filled? | 2284 | // { |
1938 | bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || | 2285 | // agent_control_v3 = Vector3.Zero; |
1939 | ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); | 2286 | // } |
1940 | 2287 | // else | |
1941 | //m_log.Debug("[CONTROL]: " +flags); | ||
1942 | // Applies a satisfying roll effect to the avatar when flying. | ||
1943 | if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) | ||
1944 | { | ||
1945 | ApplyFlyingRoll( | ||
1946 | FLY_ROLL_RADIANS_PER_UPDATE, | ||
1947 | (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, | ||
1948 | (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); | ||
1949 | } | ||
1950 | else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 && | ||
1951 | (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) | ||
1952 | { | 2288 | { |
1953 | ApplyFlyingRoll( | 2289 | // Landing detection code |
1954 | -FLY_ROLL_RADIANS_PER_UPDATE, | ||
1955 | (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, | ||
1956 | (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); | ||
1957 | } | ||
1958 | else | ||
1959 | { | ||
1960 | if (m_AngularVelocity.Z != 0) | ||
1961 | m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE); | ||
1962 | } | ||
1963 | 2290 | ||
1964 | if (Flying && IsColliding && controlland) | 2291 | // Are the landing controls requirements filled? |
1965 | { | 2292 | bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || |
1966 | // nesting this check because LengthSquared() is expensive and we don't | 2293 | ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); |
1967 | // want to do it every step when flying. | 2294 | |
1968 | if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) | 2295 | //m_log.Debug("[CONTROL]: " +flags); |
1969 | StopFlying(); | 2296 | // Applies a satisfying roll effect to the avatar when flying. |
2297 | if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) | ||
2298 | { | ||
2299 | ApplyFlyingRoll( | ||
2300 | FLY_ROLL_RADIANS_PER_UPDATE, | ||
2301 | (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, | ||
2302 | (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); | ||
2303 | } | ||
2304 | else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 && | ||
2305 | (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) | ||
2306 | { | ||
2307 | ApplyFlyingRoll( | ||
2308 | -FLY_ROLL_RADIANS_PER_UPDATE, | ||
2309 | (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, | ||
2310 | (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); | ||
2311 | } | ||
2312 | else | ||
2313 | { | ||
2314 | if (m_AngularVelocity.Z != 0) | ||
2315 | m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE); | ||
2316 | } | ||
2317 | |||
2318 | /* | ||
2319 | if (Flying && IsColliding && controlland) | ||
2320 | { | ||
2321 | // nesting this check because LengthSquared() is expensive and we don't | ||
2322 | // want to do it every step when flying. | ||
2323 | if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) | ||
2324 | StopFlying(); | ||
2325 | } | ||
2326 | */ | ||
1970 | } | 2327 | } |
1971 | } | 2328 | } |
2329 | else if (IsColliding && agent_control_v3.Z < 0f) | ||
2330 | agent_control_v3.Z = 0; | ||
2331 | // else if(AgentControlStopActive %% Velocity.Z <0.01f) | ||
2332 | |||
2333 | |||
2334 | // m_log.DebugFormat("[SCENE PRESENCE]: MovementFlag {0} for {1}", MovementFlag, Name); | ||
1972 | 2335 | ||
1973 | // If the agent update does move the avatar, then calculate the force ready for the velocity update, | 2336 | // If the agent update does move the avatar, then calculate the force ready for the velocity update, |
1974 | // which occurs later in the main scene loop | 2337 | // which occurs later in the main scene loop |
1975 | if (update_movementflag || (update_rotation && DCFlagKeyPressed)) | 2338 | // We also need to update if the user rotates their avatar whilst it is slow walking/running (if they |
2339 | // held down AGENT_CONTROL_STOP whilst normal walking/running). However, we do not want to update | ||
2340 | // if the user rotated whilst holding down AGENT_CONTROL_STOP when already still (which locks the | ||
2341 | // avatar location in place). | ||
2342 | if (update_movementflag | ||
2343 | || (update_rotation && DCFlagKeyPressed && (!AgentControlStopActive || MovementFlag != 0))) | ||
1976 | { | 2344 | { |
1977 | // m_log.DebugFormat( | ||
1978 | // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", | ||
1979 | // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); | ||
1980 | 2345 | ||
1981 | AddNewMovement(agent_control_v3); | 2346 | if (AgentControlStopActive) |
2347 | { | ||
2348 | // if (MovementFlag == 0 && Animator.Falling) | ||
2349 | if (MovementFlag == 0 && Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling) | ||
2350 | { | ||
2351 | AddNewMovement(agent_control_v3, AgentControlStopSlowVel, true); | ||
2352 | } | ||
2353 | else | ||
2354 | AddNewMovement(agent_control_v3, AgentControlStopSlowVel); | ||
2355 | } | ||
2356 | else | ||
2357 | { | ||
2358 | AddNewMovement(agent_control_v3); | ||
2359 | } | ||
2360 | |||
1982 | } | 2361 | } |
1983 | // else | ||
1984 | // { | ||
1985 | // if (!update_movementflag) | ||
1986 | // { | ||
1987 | // m_log.DebugFormat( | ||
1988 | // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", | ||
1989 | // m_scene.RegionInfo.RegionName, agent_control_v3, Name); | ||
1990 | // } | ||
1991 | // } | ||
1992 | 2362 | ||
1993 | if (update_movementflag && ParentID == 0) | 2363 | if (update_movementflag && ParentID == 0) |
2364 | { | ||
2365 | // m_log.DebugFormat("[SCENE PRESENCE]: Updating movement animations for {0}", Name); | ||
1994 | Animator.UpdateMovementAnimations(); | 2366 | Animator.UpdateMovementAnimations(); |
2367 | } | ||
1995 | 2368 | ||
1996 | SendControlsToScripts(flagsForScripts); | 2369 | SendControlsToScripts(flagsForScripts); |
1997 | } | 2370 | } |
1998 | 2371 | ||
2372 | // We need to send this back to the client in order to see the edit beams | ||
2373 | if ((State & (uint)AgentState.Editing) != 0) | ||
2374 | SendAgentTerseUpdate(this); | ||
2375 | |||
1999 | m_scene.EventManager.TriggerOnClientMovement(this); | 2376 | m_scene.EventManager.TriggerOnClientMovement(this); |
2000 | TriggerScenePresenceUpdated(); | ||
2001 | } | 2377 | } |
2002 | 2378 | ||
2379 | |||
2380 | /// <summary> | ||
2381 | /// This is the event handler for client cameras. If a client is moving, or moving the camera, this event is triggering. | ||
2382 | /// </summary> | ||
2383 | private void HandleAgentCamerasUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | ||
2384 | { | ||
2385 | //m_log.DebugFormat( | ||
2386 | // "[SCENE PRESENCE]: In {0} received agent camera update from {1}, flags {2}", | ||
2387 | // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); | ||
2388 | |||
2389 | if (IsChildAgent) | ||
2390 | { | ||
2391 | // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); | ||
2392 | return; | ||
2393 | } | ||
2394 | |||
2395 | ++m_movementUpdateCount; | ||
2396 | if (m_movementUpdateCount < 1) | ||
2397 | m_movementUpdateCount = 1; | ||
2398 | |||
2399 | // AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; | ||
2400 | |||
2401 | // Camera location in world. We'll need to raytrace | ||
2402 | // from this location from time to time. | ||
2403 | CameraPosition = agentData.CameraCenter; | ||
2404 | if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance) | ||
2405 | { | ||
2406 | ReprioritizeUpdates(); | ||
2407 | m_lastCameraPosition = CameraPosition; | ||
2408 | } | ||
2409 | |||
2410 | // Use these three vectors to figure out what the agent is looking at | ||
2411 | // Convert it to a Matrix and/or Quaternion | ||
2412 | CameraAtAxis = agentData.CameraAtAxis; | ||
2413 | CameraLeftAxis = agentData.CameraLeftAxis; | ||
2414 | CameraUpAxis = agentData.CameraUpAxis; | ||
2415 | |||
2416 | // The Agent's Draw distance setting | ||
2417 | // When we get to the point of re-computing neighbors everytime this | ||
2418 | // changes, then start using the agent's drawdistance rather than the | ||
2419 | // region's draw distance. | ||
2420 | // DrawDistance = agentData.Far; | ||
2421 | DrawDistance = Scene.DefaultDrawDistance; | ||
2422 | |||
2423 | // Check if Client has camera in 'follow cam' or 'build' mode. | ||
2424 | Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation); | ||
2425 | |||
2426 | m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f) | ||
2427 | && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; | ||
2428 | |||
2429 | |||
2430 | //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); | ||
2431 | // Raycast from the avatar's head to the camera to see if there's anything blocking the view | ||
2432 | if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) | ||
2433 | { | ||
2434 | if (m_followCamAuto) | ||
2435 | { | ||
2436 | Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; | ||
2437 | m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback); | ||
2438 | } | ||
2439 | } | ||
2440 | |||
2441 | TriggerScenePresenceUpdated(); | ||
2442 | } | ||
2443 | |||
2003 | /// <summary> | 2444 | /// <summary> |
2004 | /// Calculate an update to move the presence to the set target. | 2445 | /// Calculate an update to move the presence to the set target. |
2005 | /// </summary> | 2446 | /// </summary> |
@@ -2014,11 +2455,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2014 | 2455 | ||
2015 | bool updated = false; | 2456 | bool updated = false; |
2016 | 2457 | ||
2458 | Vector3 LocalVectorToTarget3D = MoveToPositionTarget - AbsolutePosition; | ||
2459 | |||
2017 | // m_log.DebugFormat( | 2460 | // m_log.DebugFormat( |
2018 | // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", | 2461 | // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", |
2019 | // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); | 2462 | // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); |
2020 | 2463 | ||
2021 | double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); | 2464 | double distanceToTarget = LocalVectorToTarget3D.Length(); |
2022 | 2465 | ||
2023 | // m_log.DebugFormat( | 2466 | // m_log.DebugFormat( |
2024 | // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", | 2467 | // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", |
@@ -2041,11 +2484,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2041 | // Theoretically we might need a more complex PID approach here if other | 2484 | // Theoretically we might need a more complex PID approach here if other |
2042 | // unknown forces are acting on the avatar and we need to adaptively respond | 2485 | // unknown forces are acting on the avatar and we need to adaptively respond |
2043 | // to such forces, but the following simple approach seems to works fine. | 2486 | // to such forces, but the following simple approach seems to works fine. |
2044 | Vector3 LocalVectorToTarget3D = | 2487 | |
2045 | (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords | 2488 | LocalVectorToTarget3D = LocalVectorToTarget3D * Quaternion.Inverse(Rotation); // change to avatar coords |
2046 | * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords | ||
2047 | // Ignore z component of vector | 2489 | // Ignore z component of vector |
2048 | // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); | 2490 | // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); |
2491 | |||
2049 | LocalVectorToTarget3D.Normalize(); | 2492 | LocalVectorToTarget3D.Normalize(); |
2050 | 2493 | ||
2051 | // update avatar movement flags. the avatar coordinate system is as follows: | 2494 | // update avatar movement flags. the avatar coordinate system is as follows: |
@@ -2069,28 +2512,37 @@ namespace OpenSim.Region.Framework.Scenes | |||
2069 | 2512 | ||
2070 | // based on the above avatar coordinate system, classify the movement into | 2513 | // based on the above avatar coordinate system, classify the movement into |
2071 | // one of left/right/back/forward. | 2514 | // one of left/right/back/forward. |
2515 | |||
2516 | const uint noMovFlagsMask = (uint)(~(Dir_ControlFlags.DIR_CONTROL_FLAG_BACK | | ||
2517 | Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD | Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT | | ||
2518 | Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT | Dir_ControlFlags.DIR_CONTROL_FLAG_UP | | ||
2519 | Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN)); | ||
2520 | |||
2521 | MovementFlag &= noMovFlagsMask; | ||
2522 | AgentControlFlags &= noMovFlagsMask; | ||
2523 | |||
2072 | if (LocalVectorToTarget3D.X < 0) //MoveBack | 2524 | if (LocalVectorToTarget3D.X < 0) //MoveBack |
2073 | { | 2525 | { |
2074 | MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; | 2526 | MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; |
2075 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; | 2527 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; |
2076 | updated = true; | 2528 | updated = true; |
2077 | } | 2529 | } |
2078 | else if (LocalVectorToTarget3D.X > 0) //Move Forward | 2530 | else if (LocalVectorToTarget3D.X > 0) //Move Forward |
2079 | { | 2531 | { |
2080 | MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; | 2532 | MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; |
2081 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; | 2533 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; |
2082 | updated = true; | 2534 | updated = true; |
2083 | } | 2535 | } |
2084 | 2536 | ||
2085 | if (LocalVectorToTarget3D.Y > 0) //MoveLeft | 2537 | if (LocalVectorToTarget3D.Y > 0) //MoveLeft |
2086 | { | 2538 | { |
2087 | MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; | 2539 | MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; |
2088 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; | 2540 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; |
2089 | updated = true; | 2541 | updated = true; |
2090 | } | 2542 | } |
2091 | else if (LocalVectorToTarget3D.Y < 0) //MoveRight | 2543 | else if (LocalVectorToTarget3D.Y < 0) //MoveRight |
2092 | { | 2544 | { |
2093 | MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; | 2545 | MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; |
2094 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; | 2546 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; |
2095 | updated = true; | 2547 | updated = true; |
2096 | } | 2548 | } |
@@ -2185,6 +2637,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2185 | targetScene = m_scene; | 2637 | targetScene = m_scene; |
2186 | 2638 | ||
2187 | float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % Constants.RegionSize), (int)(pos.Y % Constants.RegionSize)]; | 2639 | float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % Constants.RegionSize), (int)(pos.Y % Constants.RegionSize)]; |
2640 | // dont try to land underground | ||
2641 | terrainHeight += Appearance.AvatarHeight / 2; | ||
2188 | pos.Z = Math.Max(terrainHeight, pos.Z); | 2642 | pos.Z = Math.Max(terrainHeight, pos.Z); |
2189 | 2643 | ||
2190 | // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is | 2644 | // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is |
@@ -2196,10 +2650,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2196 | // m_log.DebugFormat( | 2650 | // m_log.DebugFormat( |
2197 | // "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", | 2651 | // "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", |
2198 | // Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); | 2652 | // Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); |
2653 | |||
2199 | 2654 | ||
2200 | if (noFly) | 2655 | if (noFly) |
2201 | Flying = false; | 2656 | Flying = false; |
2202 | else if (pos.Z > terrainHeight) | 2657 | else if (pos.Z > terrainHeight + Appearance.AvatarHeight / 2 || Flying) |
2203 | Flying = true; | 2658 | Flying = true; |
2204 | 2659 | ||
2205 | LandAtTarget = landAtTarget; | 2660 | LandAtTarget = landAtTarget; |
@@ -2252,17 +2707,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2252 | { | 2707 | { |
2253 | // m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); | 2708 | // m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); |
2254 | 2709 | ||
2710 | bool satOnObject = IsSatOnObject; | ||
2711 | SceneObjectPart part = ParentPart; | ||
2255 | SitGround = false; | 2712 | SitGround = false; |
2256 | 2713 | ||
2257 | /* move this down so avatar gets physical in the new position and not where it is siting | 2714 | if (satOnObject) |
2258 | if (PhysicsActor == null) | ||
2259 | AddToPhysicalScene(false); | ||
2260 | */ | ||
2261 | |||
2262 | if (ParentID != 0) | ||
2263 | { | 2715 | { |
2264 | PrevSitOffset = m_pos; // Save sit offset | 2716 | PrevSitOffset = m_pos; // Save sit offset |
2265 | SceneObjectPart part = ParentPart; | ||
2266 | UnRegisterSeatControls(part.ParentGroup.UUID); | 2717 | UnRegisterSeatControls(part.ParentGroup.UUID); |
2267 | 2718 | ||
2268 | TaskInventoryDictionary taskIDict = part.TaskInventory; | 2719 | TaskInventoryDictionary taskIDict = part.TaskInventory; |
@@ -2281,34 +2732,64 @@ namespace OpenSim.Region.Framework.Scenes | |||
2281 | } | 2732 | } |
2282 | 2733 | ||
2283 | part.ParentGroup.DeleteAvatar(UUID); | 2734 | part.ParentGroup.DeleteAvatar(UUID); |
2284 | // ParentPosition = part.GetWorldPosition(); | ||
2285 | ControllingClient.SendClearFollowCamProperties(part.ParentUUID); | ||
2286 | 2735 | ||
2287 | // m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); | 2736 | Quaternion standRotation = part.ParentGroup.RootPart.RotationOffset; |
2288 | // ParentPosition = Vector3.Zero; | 2737 | Vector3 sitPartWorldPosition = part.ParentGroup.AbsolutePosition + m_pos * standRotation; |
2289 | m_pos = part.AbsolutePosition + (m_pos * part.GetWorldRotation()) + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); | 2738 | ControllingClient.SendClearFollowCamProperties(part.ParentUUID); |
2290 | if (part.SitTargetAvatar == UUID) | ||
2291 | m_bodyRot = part.GetWorldRotation() * part.SitTargetOrientation; | ||
2292 | 2739 | ||
2293 | ParentID = 0; | 2740 | ParentID = 0; |
2294 | ParentPart = null; | 2741 | ParentPart = null; |
2295 | 2742 | ||
2296 | if (PhysicsActor == null) | 2743 | if (part.SitTargetAvatar == UUID) |
2297 | AddToPhysicalScene(false); | 2744 | standRotation = standRotation * part.SitTargetOrientation; |
2745 | else | ||
2746 | standRotation = standRotation * m_bodyRot; | ||
2298 | 2747 | ||
2299 | SendAvatarDataToAllAgents(); | 2748 | m_bodyRot = standRotation; |
2300 | m_requestedSitTargetID = 0; | ||
2301 | 2749 | ||
2302 | part.RemoveSittingAvatar(UUID); | 2750 | Quaternion standRotationZ = new Quaternion(0,0,standRotation.Z,standRotation.W); |
2303 | 2751 | ||
2304 | if (part != null) | 2752 | float t = standRotationZ.W * standRotationZ.W + standRotationZ.Z * standRotationZ.Z; |
2305 | part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); | 2753 | if (t > 0) |
2754 | { | ||
2755 | t = 1.0f / (float)Math.Sqrt(t); | ||
2756 | standRotationZ.W *= t; | ||
2757 | standRotationZ.Z *= t; | ||
2758 | } | ||
2759 | else | ||
2760 | { | ||
2761 | standRotationZ.W = 1.0f; | ||
2762 | standRotationZ.Z = 0f; | ||
2763 | } | ||
2764 | |||
2765 | Vector3 adjustmentForSitPose = new Vector3(0.75f, 0, m_sitAvatarHeight + .3f) * standRotationZ; | ||
2766 | |||
2767 | Vector3 standPos = sitPartWorldPosition + adjustmentForSitPose; | ||
2768 | |||
2769 | m_pos = standPos; | ||
2306 | } | 2770 | } |
2307 | 2771 | ||
2308 | else if (PhysicsActor == null) | 2772 | // We need to wait until we have calculated proper stand positions before sitting up the physical |
2773 | // avatar to avoid race conditions. | ||
2774 | if (PhysicsActor == null) | ||
2309 | AddToPhysicalScene(false); | 2775 | AddToPhysicalScene(false); |
2310 | 2776 | ||
2311 | Animator.TrySetMovementAnimation("STAND"); | 2777 | if (satOnObject) |
2778 | { | ||
2779 | m_requestedSitTargetID = 0; | ||
2780 | part.RemoveSittingAvatar(UUID); | ||
2781 | part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); | ||
2782 | |||
2783 | SendAvatarDataToAllAgents(); | ||
2784 | } | ||
2785 | |||
2786 | // reset to default sitAnimation | ||
2787 | sitAnimation = "SIT"; | ||
2788 | |||
2789 | // Animator.TrySetMovementAnimation("STAND"); | ||
2790 | Animator.SetMovementAnimations("STAND"); | ||
2791 | |||
2792 | TriggerScenePresenceUpdated(); | ||
2312 | } | 2793 | } |
2313 | 2794 | ||
2314 | private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) | 2795 | private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) |
@@ -2355,20 +2836,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
2355 | if (part == null) | 2836 | if (part == null) |
2356 | return; | 2837 | return; |
2357 | 2838 | ||
2839 | |||
2358 | if (PhysicsActor != null) | 2840 | if (PhysicsActor != null) |
2359 | m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f; | 2841 | m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f; |
2360 | 2842 | ||
2361 | bool canSit = false; | 2843 | bool canSit = false; |
2362 | Vector3 pos = part.AbsolutePosition + offset; | ||
2363 | 2844 | ||
2364 | if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) | 2845 | if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) |
2365 | { | 2846 | { |
2366 | // m_log.DebugFormat( | ||
2367 | // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", | ||
2368 | // Name, part.Name, part.LocalId); | ||
2369 | |||
2370 | offset = part.SitTargetPosition; | 2847 | offset = part.SitTargetPosition; |
2371 | sitOrientation = part.SitTargetOrientation; | 2848 | sitOrientation = part.SitTargetOrientation; |
2849 | |||
2372 | canSit = true; | 2850 | canSit = true; |
2373 | } | 2851 | } |
2374 | else | 2852 | else |
@@ -2376,9 +2854,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2376 | if (PhysicsSit(part,offset)) // physics engine | 2854 | if (PhysicsSit(part,offset)) // physics engine |
2377 | return; | 2855 | return; |
2378 | 2856 | ||
2857 | Vector3 pos = part.AbsolutePosition + offset; | ||
2858 | |||
2379 | if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) | 2859 | if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) |
2380 | { | 2860 | { |
2381 | |||
2382 | AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); | 2861 | AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); |
2383 | canSit = true; | 2862 | canSit = true; |
2384 | } | 2863 | } |
@@ -2404,10 +2883,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
2404 | cameraEyeOffset = part.GetCameraEyeOffset(); | 2883 | cameraEyeOffset = part.GetCameraEyeOffset(); |
2405 | forceMouselook = part.GetForceMouselook(); | 2884 | forceMouselook = part.GetForceMouselook(); |
2406 | 2885 | ||
2886 | if (!part.IsRoot) | ||
2887 | { | ||
2888 | sitOrientation = part.RotationOffset * sitOrientation; | ||
2889 | offset = offset * part.RotationOffset; | ||
2890 | offset += part.OffsetPosition; | ||
2891 | |||
2892 | if (CameraAtAxis == Vector3.Zero && cameraEyeOffset == Vector3.Zero) | ||
2893 | { | ||
2894 | CameraAtAxis = part.ParentGroup.RootPart.GetCameraAtOffset(); | ||
2895 | cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset(); | ||
2896 | } | ||
2897 | else | ||
2898 | { | ||
2899 | cameraAtOffset = cameraAtOffset * part.RotationOffset; | ||
2900 | cameraAtOffset += part.OffsetPosition; | ||
2901 | cameraEyeOffset = cameraEyeOffset * part.RotationOffset; | ||
2902 | cameraEyeOffset += part.OffsetPosition; | ||
2903 | } | ||
2904 | } | ||
2905 | |||
2906 | |||
2407 | ControllingClient.SendSitResponse( | 2907 | ControllingClient.SendSitResponse( |
2408 | part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); | 2908 | part.ParentGroup.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); |
2409 | 2909 | ||
2410 | m_requestedSitTargetUUID = targetID; | 2910 | m_requestedSitTargetUUID = part.UUID; |
2411 | 2911 | ||
2412 | HandleAgentSit(ControllingClient, UUID); | 2912 | HandleAgentSit(ControllingClient, UUID); |
2413 | 2913 | ||
@@ -2435,7 +2935,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2435 | if (part != null) | 2935 | if (part != null) |
2436 | { | 2936 | { |
2437 | m_requestedSitTargetID = part.LocalId; | 2937 | m_requestedSitTargetID = part.LocalId; |
2438 | m_requestedSitTargetUUID = targetID; | 2938 | m_requestedSitTargetUUID = part.UUID; |
2439 | 2939 | ||
2440 | } | 2940 | } |
2441 | else | 2941 | else |
@@ -2522,6 +3022,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2522 | ResetMoveToTarget(); | 3022 | ResetMoveToTarget(); |
2523 | 3023 | ||
2524 | Velocity = Vector3.Zero; | 3024 | Velocity = Vector3.Zero; |
3025 | m_AngularVelocity = Vector3.Zero; | ||
2525 | 3026 | ||
2526 | part.AddSittingAvatar(UUID); | 3027 | part.AddSittingAvatar(UUID); |
2527 | 3028 | ||
@@ -2529,24 +3030,55 @@ namespace OpenSim.Region.Framework.Scenes | |||
2529 | Vector3 cameraEyeOffset = part.GetCameraEyeOffset(); | 3030 | Vector3 cameraEyeOffset = part.GetCameraEyeOffset(); |
2530 | bool forceMouselook = part.GetForceMouselook(); | 3031 | bool forceMouselook = part.GetForceMouselook(); |
2531 | 3032 | ||
2532 | ControllingClient.SendSitResponse( | 3033 | m_bodyRot = Orientation; |
2533 | part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); | ||
2534 | 3034 | ||
2535 | // not using autopilot | 3035 | if (!part.IsRoot) |
3036 | { | ||
3037 | Orientation = part.RotationOffset * Orientation; | ||
3038 | offset = offset * part.RotationOffset; | ||
3039 | offset += part.OffsetPosition; | ||
3040 | |||
3041 | if (CameraAtAxis == Vector3.Zero && cameraEyeOffset == Vector3.Zero) | ||
3042 | { | ||
3043 | CameraAtAxis = part.ParentGroup.RootPart.GetCameraAtOffset(); | ||
3044 | cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset(); | ||
3045 | } | ||
3046 | else | ||
3047 | { | ||
3048 | cameraAtOffset = cameraAtOffset * part.RotationOffset; | ||
3049 | cameraAtOffset += part.OffsetPosition; | ||
3050 | cameraEyeOffset = cameraEyeOffset * part.RotationOffset; | ||
3051 | cameraEyeOffset += part.OffsetPosition; | ||
3052 | } | ||
3053 | |||
3054 | } | ||
2536 | 3055 | ||
2537 | Rotation = Orientation; | ||
2538 | m_pos = offset; | 3056 | m_pos = offset; |
2539 | 3057 | ||
3058 | ControllingClient.SendSitResponse( | ||
3059 | part.ParentGroup.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); | ||
3060 | |||
3061 | |||
2540 | m_requestedSitTargetID = 0; | 3062 | m_requestedSitTargetID = 0; |
2541 | part.ParentGroup.AddAvatar(UUID); | 3063 | part.ParentGroup.AddAvatar(UUID); |
2542 | 3064 | ||
2543 | ParentPart = part; | 3065 | ParentPart = part; |
2544 | ParentID = part.LocalId; | 3066 | ParentID = part.LocalId; |
3067 | |||
3068 | SendAvatarDataToAllAgents(); | ||
3069 | |||
3070 | /* | ||
2545 | if(status == 3) | 3071 | if(status == 3) |
2546 | Animator.TrySetMovementAnimation("SIT_GROUND"); | 3072 | Animator.TrySetMovementAnimation("SIT_GROUND"); |
2547 | else | 3073 | else |
2548 | Animator.TrySetMovementAnimation("SIT"); | 3074 | Animator.TrySetMovementAnimation("SIT"); |
2549 | SendAvatarDataToAllAgents(); | 3075 | */ |
3076 | if (status == 3) | ||
3077 | sitAnimation = "SIT_GROUND"; | ||
3078 | else | ||
3079 | sitAnimation = "SIT"; | ||
3080 | |||
3081 | Animator.SetMovementAnimations("SIT"); | ||
2550 | 3082 | ||
2551 | part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); | 3083 | part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); |
2552 | } | 3084 | } |
@@ -2554,6 +3086,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2554 | 3086 | ||
2555 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) | 3087 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) |
2556 | { | 3088 | { |
3089 | if (IsChildAgent) | ||
3090 | return; | ||
3091 | |||
2557 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); | 3092 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); |
2558 | 3093 | ||
2559 | if (part != null) | 3094 | if (part != null) |
@@ -2603,47 +3138,74 @@ namespace OpenSim.Region.Framework.Scenes | |||
2603 | Vector3 up = new Vector3((float)x, (float)y, (float)z); | 3138 | Vector3 up = new Vector3((float)x, (float)y, (float)z); |
2604 | Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f; | 3139 | Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f; |
2605 | 3140 | ||
2606 | m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT; | 3141 | Vector3 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT; |
3142 | Quaternion newRot; | ||
3143 | |||
3144 | if (part.IsRoot) | ||
3145 | { | ||
3146 | newRot = sitTargetOrient; | ||
3147 | } | ||
3148 | else | ||
3149 | { | ||
3150 | newPos = newPos * part.RotationOffset; | ||
3151 | newRot = part.RotationOffset * sitTargetOrient; | ||
3152 | } | ||
3153 | |||
3154 | newPos += part.OffsetPosition; | ||
3155 | |||
3156 | m_pos = newPos; | ||
3157 | Rotation = newRot; | ||
2607 | 3158 | ||
2608 | // m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset; | ||
2609 | Rotation = sitTargetOrient; | ||
2610 | // ParentPosition = part.AbsolutePosition; | 3159 | // ParentPosition = part.AbsolutePosition; |
2611 | part.ParentGroup.AddAvatar(UUID); | ||
2612 | } | 3160 | } |
2613 | else | 3161 | else |
2614 | { | 3162 | { |
2615 | m_pos -= part.AbsolutePosition; | 3163 | // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is |
3164 | // being sat upon. | ||
3165 | m_pos -= part.GroupPosition; | ||
3166 | |||
2616 | // ParentPosition = part.AbsolutePosition; | 3167 | // ParentPosition = part.AbsolutePosition; |
2617 | part.ParentGroup.AddAvatar(UUID); | ||
2618 | 3168 | ||
2619 | // m_log.DebugFormat( | 3169 | // m_log.DebugFormat( |
2620 | // "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", | 3170 | // "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", |
2621 | // Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); | 3171 | // Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); |
2622 | } | 3172 | } |
2623 | 3173 | ||
3174 | part.ParentGroup.AddAvatar(UUID); | ||
2624 | ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID); | 3175 | ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID); |
2625 | ParentID = m_requestedSitTargetID; | 3176 | ParentID = m_requestedSitTargetID; |
2626 | m_AngularVelocity = Vector3.Zero; | 3177 | m_AngularVelocity = Vector3.Zero; |
2627 | Velocity = Vector3.Zero; | 3178 | Velocity = Vector3.Zero; |
2628 | RemoveFromPhysicalScene(); | 3179 | RemoveFromPhysicalScene(); |
2629 | 3180 | ||
2630 | String sitAnimation = "SIT"; | 3181 | SendAvatarDataToAllAgents(); |
3182 | |||
3183 | sitAnimation = "SIT"; | ||
2631 | if (!String.IsNullOrEmpty(part.SitAnimation)) | 3184 | if (!String.IsNullOrEmpty(part.SitAnimation)) |
2632 | { | 3185 | { |
2633 | sitAnimation = part.SitAnimation; | 3186 | sitAnimation = part.SitAnimation; |
2634 | } | 3187 | } |
2635 | Animator.TrySetMovementAnimation(sitAnimation); | 3188 | // Animator.TrySetMovementAnimation(sitAnimation); |
2636 | SendAvatarDataToAllAgents(); | 3189 | Animator.SetMovementAnimations("SIT"); |
3190 | TriggerScenePresenceUpdated(); | ||
2637 | } | 3191 | } |
2638 | } | 3192 | } |
2639 | 3193 | ||
2640 | public void HandleAgentSitOnGround() | 3194 | public void HandleAgentSitOnGround() |
2641 | { | 3195 | { |
3196 | if (IsChildAgent) | ||
3197 | return; | ||
3198 | |||
2642 | // m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. | 3199 | // m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. |
2643 | m_AngularVelocity = Vector3.Zero; | 3200 | m_AngularVelocity = Vector3.Zero; |
2644 | Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); | 3201 | sitAnimation = "SIT_GROUND_CONSTRAINED"; |
3202 | // Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); | ||
3203 | // TriggerScenePresenceUpdated(); | ||
2645 | SitGround = true; | 3204 | SitGround = true; |
2646 | RemoveFromPhysicalScene(); | 3205 | RemoveFromPhysicalScene(); |
3206 | |||
3207 | Animator.SetMovementAnimations("SITGROUND"); | ||
3208 | TriggerScenePresenceUpdated(); | ||
2647 | } | 3209 | } |
2648 | 3210 | ||
2649 | /// <summary> | 3211 | /// <summary> |
@@ -2658,11 +3220,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2658 | public void HandleStartAnim(IClientAPI remoteClient, UUID animID) | 3220 | public void HandleStartAnim(IClientAPI remoteClient, UUID animID) |
2659 | { | 3221 | { |
2660 | Animator.AddAnimation(animID, UUID.Zero); | 3222 | Animator.AddAnimation(animID, UUID.Zero); |
3223 | TriggerScenePresenceUpdated(); | ||
2661 | } | 3224 | } |
2662 | 3225 | ||
2663 | public void HandleStopAnim(IClientAPI remoteClient, UUID animID) | 3226 | public void HandleStopAnim(IClientAPI remoteClient, UUID animID) |
2664 | { | 3227 | { |
2665 | Animator.RemoveAnimation(animID, false); | 3228 | Animator.RemoveAnimation(animID, false); |
3229 | TriggerScenePresenceUpdated(); | ||
2666 | } | 3230 | } |
2667 | 3231 | ||
2668 | public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack) | 3232 | public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack) |
@@ -2676,67 +3240,57 @@ namespace OpenSim.Region.Framework.Scenes | |||
2676 | /// Rotate the avatar to the given rotation and apply a movement in the given relative vector | 3240 | /// Rotate the avatar to the given rotation and apply a movement in the given relative vector |
2677 | /// </summary> | 3241 | /// </summary> |
2678 | /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> | 3242 | /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> |
2679 | public void AddNewMovement(Vector3 vec) | 3243 | /// <param name="thisAddSpeedModifier"> |
3244 | /// Optional additional speed modifier for this particular add. Default is 1</param> | ||
3245 | public void AddNewMovement(Vector3 vec, float thisAddSpeedModifier = 1, bool breaking = false) | ||
2680 | { | 3246 | { |
2681 | // m_log.DebugFormat( | 3247 | // m_log.DebugFormat( |
2682 | // "[SCENE PRESENCE]: Adding new movement {0} with rotation {1} for {2}", vec, Rotation, Name); | 3248 | // "[SCENE PRESENCE]: Adding new movement {0} with rotation {1}, thisAddSpeedModifier {2} for {3}", |
3249 | // vec, Rotation, thisAddSpeedModifier, Name); | ||
2683 | 3250 | ||
3251 | // rotate from avatar coord space to world | ||
3252 | // for now all controls assume this is only a rotation around Z | ||
3253 | // if not all checks below need to be done before this rotation | ||
2684 | Vector3 direc = vec * Rotation; | 3254 | Vector3 direc = vec * Rotation; |
2685 | direc.Normalize(); | 3255 | direc.Normalize(); |
2686 | 3256 | ||
2687 | if (Flying != FlyingOld) // add for fly velocity control | 3257 | // mouse look situation ? |
2688 | { | ||
2689 | FlyingOld = Flying; // add for fly velocity control | ||
2690 | if (!Flying) | ||
2691 | WasFlying = true; // add for fly velocity control | ||
2692 | } | ||
2693 | |||
2694 | if (IsColliding) | ||
2695 | WasFlying = false; // add for fly velocity control | ||
2696 | |||
2697 | if ((vec.Z == 0f) && !Flying) | 3258 | if ((vec.Z == 0f) && !Flying) |
2698 | direc.Z = 0f; // Prevent camera WASD up. | 3259 | direc.Z = 0f; // Prevent camera WASD up. |
2699 | 3260 | ||
2700 | direc *= 0.03f * 128f * SpeedModifier; | 3261 | // odd rescalings |
3262 | direc *= 0.03f * 128f * SpeedModifier * thisAddSpeedModifier; | ||
2701 | 3263 | ||
2702 | // m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name); | 3264 | // m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name); |
2703 | 3265 | ||
2704 | if (PhysicsActor != null) | 3266 | if (Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling) |
2705 | { | 3267 | { |
2706 | if (Flying) | 3268 | if (breaking) |
2707 | { | 3269 | direc.Z = -9999f; //hack to tell physics to stop on Z |
3270 | else | ||
3271 | direc = Vector3.Zero; | ||
3272 | } | ||
3273 | else if (Flying) | ||
3274 | { | ||
3275 | if (IsColliding && direc.Z < 0) | ||
3276 | // landing situation, prevent avatar moving or it may fail to land | ||
3277 | // animator will handle this condition and do the land | ||
3278 | direc = Vector3.Zero; | ||
3279 | else | ||
2708 | direc *= 4.0f; | 3280 | direc *= 4.0f; |
2709 | //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); | 3281 | } |
2710 | //if (controlland) | 3282 | else if (IsColliding) |
2711 | // m_log.Info("[AGENT]: landCommand"); | 3283 | { |
2712 | //if (IsColliding) | 3284 | if (direc.Z > 2.0f) // reinforce jumps |
2713 | // m_log.Info("[AGENT]: colliding"); | ||
2714 | //if (Flying && IsColliding && controlland) | ||
2715 | //{ | ||
2716 | // StopFlying(); | ||
2717 | // m_log.Info("[AGENT]: Stop Flying"); | ||
2718 | //} | ||
2719 | } | ||
2720 | if (Animator.Falling && WasFlying) // if falling from flying, disable motion add | ||
2721 | { | ||
2722 | direc *= 0.0f; | ||
2723 | } | ||
2724 | else if (!Flying && IsColliding) | ||
2725 | { | 3285 | { |
2726 | if (direc.Z > 2.0f) | 3286 | direc.Z *= 2.6f; |
2727 | { | ||
2728 | direc.Z *= 2.6f; | ||
2729 | |||
2730 | // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. | ||
2731 | // Animator.TrySetMovementAnimation("PREJUMP"); | ||
2732 | // Animator.TrySetMovementAnimation("JUMP"); | ||
2733 | } | ||
2734 | } | 3287 | } |
3288 | else if (direc.Z < 0) // on a surface moving down (pg down) only changes animation | ||
3289 | direc.Z = 0; | ||
2735 | } | 3290 | } |
2736 | 3291 | ||
2737 | // m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name); | 3292 | // m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name); |
2738 | 3293 | ||
2739 | // TODO: Add the force instead of only setting it to support multiple forces per frame? | ||
2740 | m_forceToApply = direc; | 3294 | m_forceToApply = direc; |
2741 | Animator.UpdateMovementAnimations(); | 3295 | Animator.UpdateMovementAnimations(); |
2742 | } | 3296 | } |
@@ -2753,6 +3307,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2753 | 3307 | ||
2754 | if (IsChildAgent == false) | 3308 | if (IsChildAgent == false) |
2755 | { | 3309 | { |
3310 | CheckForBorderCrossing(); | ||
3311 | |||
3312 | if (IsInTransit) | ||
3313 | return; | ||
3314 | |||
2756 | // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to | 3315 | // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to |
2757 | // grab the latest PhysicsActor velocity, whereas m_velocity is often | 3316 | // grab the latest PhysicsActor velocity, whereas m_velocity is often |
2758 | // storing a requested force instead of an actual traveling velocity | 3317 | // storing a requested force instead of an actual traveling velocity |
@@ -2771,8 +3330,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2771 | m_lastVelocity = Velocity; | 3330 | m_lastVelocity = Velocity; |
2772 | } | 3331 | } |
2773 | 3332 | ||
2774 | CheckForBorderCrossing(); | ||
2775 | |||
2776 | CheckForSignificantMovement(); // sends update to the modules. | 3333 | CheckForSignificantMovement(); // sends update to the modules. |
2777 | } | 3334 | } |
2778 | } | 3335 | } |
@@ -2781,9 +3338,38 @@ namespace OpenSim.Region.Framework.Scenes | |||
2781 | 3338 | ||
2782 | #region Update Client(s) | 3339 | #region Update Client(s) |
2783 | 3340 | ||
3341 | public void SendUpdateToAgent(ScenePresence p) | ||
3342 | { | ||
3343 | IClientAPI remoteClient = p.ControllingClient; | ||
3344 | |||
3345 | if (remoteClient.IsActive) | ||
3346 | { | ||
3347 | //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); | ||
3348 | remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate); | ||
3349 | m_scene.StatsReporter.AddAgentUpdates(1); | ||
3350 | } | ||
3351 | } | ||
3352 | |||
3353 | public void SendFullUpdateToClient(IClientAPI remoteClient) | ||
3354 | { | ||
3355 | if (remoteClient.IsActive) | ||
3356 | { | ||
3357 | //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); | ||
3358 | remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate); | ||
3359 | m_scene.StatsReporter.AddAgentUpdates(1); | ||
3360 | } | ||
3361 | } | ||
3362 | |||
3363 | // this is diferente from SendTerseUpdateToClient | ||
3364 | // this sends bypassing entities updates | ||
3365 | public void SendAgentTerseUpdate(ISceneEntity p) | ||
3366 | { | ||
3367 | ControllingClient.SendAgentTerseUpdate(p); | ||
3368 | } | ||
2784 | 3369 | ||
2785 | /// <summary> | 3370 | /// <summary> |
2786 | /// Sends a location update to the client connected to this scenePresence | 3371 | /// Sends a location update to the client connected to this scenePresence |
3372 | /// via entity updates | ||
2787 | /// </summary> | 3373 | /// </summary> |
2788 | /// <param name="remoteClient"></param> | 3374 | /// <param name="remoteClient"></param> |
2789 | public void SendTerseUpdateToClient(IClientAPI remoteClient) | 3375 | public void SendTerseUpdateToClient(IClientAPI remoteClient) |
@@ -2793,7 +3379,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2793 | if (remoteClient.IsActive) | 3379 | if (remoteClient.IsActive) |
2794 | { | 3380 | { |
2795 | //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); | 3381 | //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); |
2796 | |||
2797 | remoteClient.SendEntityUpdate( | 3382 | remoteClient.SendEntityUpdate( |
2798 | this, | 3383 | this, |
2799 | PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | 3384 | PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity |
@@ -2803,6 +3388,38 @@ namespace OpenSim.Region.Framework.Scenes | |||
2803 | } | 3388 | } |
2804 | } | 3389 | } |
2805 | 3390 | ||
3391 | public void SendTerseUpdateToAgent(ScenePresence p) | ||
3392 | { | ||
3393 | IClientAPI remoteClient = p.ControllingClient; | ||
3394 | |||
3395 | if (!remoteClient.IsActive) | ||
3396 | return; | ||
3397 | |||
3398 | if (ParcelHideThisAvatar && p.currentParcelUUID != currentParcelUUID && p.GodLevel < 200) | ||
3399 | return; | ||
3400 | |||
3401 | //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); | ||
3402 | remoteClient.SendEntityUpdate( | ||
3403 | this, | ||
3404 | PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | ||
3405 | | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); | ||
3406 | |||
3407 | m_scene.StatsReporter.AddAgentUpdates(1); | ||
3408 | } | ||
3409 | |||
3410 | public void SendTerseUpdateToAgentNF(ScenePresence p) | ||
3411 | { | ||
3412 | IClientAPI remoteClient = p.ControllingClient; | ||
3413 | if (remoteClient.IsActive) | ||
3414 | { | ||
3415 | //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); | ||
3416 | remoteClient.SendEntityUpdate(this, | ||
3417 | PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | ||
3418 | | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); | ||
3419 | m_scene.StatsReporter.AddAgentUpdates(1); | ||
3420 | } | ||
3421 | } | ||
3422 | |||
2806 | 3423 | ||
2807 | // vars to support reduced update frequency when velocity is unchanged | 3424 | // vars to support reduced update frequency when velocity is unchanged |
2808 | private Vector3 lastVelocitySentToAllClients = Vector3.Zero; | 3425 | private Vector3 lastVelocitySentToAllClients = Vector3.Zero; |
@@ -2843,7 +3460,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2843 | lastTerseUpdateToAllClientsTick = currentTick; | 3460 | lastTerseUpdateToAllClientsTick = currentTick; |
2844 | lastPositionSentToAllClients = OffsetPosition; | 3461 | lastPositionSentToAllClients = OffsetPosition; |
2845 | 3462 | ||
2846 | m_scene.ForEachClient(SendTerseUpdateToClient); | 3463 | // Console.WriteLine("Scheduled update for {0} in {1}", Name, Scene.Name); |
3464 | // m_scene.ForEachClient(SendTerseUpdateToClient); | ||
3465 | m_scene.ForEachScenePresence(SendTerseUpdateToAgent); | ||
2847 | } | 3466 | } |
2848 | TriggerScenePresenceUpdated(); | 3467 | TriggerScenePresenceUpdated(); |
2849 | } | 3468 | } |
@@ -2876,13 +3495,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
2876 | // we created a new ScenePresence (a new child agent) in a fresh region. | 3495 | // we created a new ScenePresence (a new child agent) in a fresh region. |
2877 | // Request info about all the (root) agents in this region | 3496 | // Request info about all the (root) agents in this region |
2878 | // Note: This won't send data *to* other clients in that region (children don't send) | 3497 | // Note: This won't send data *to* other clients in that region (children don't send) |
2879 | SendOtherAgentsAvatarDataToMe(); | 3498 | if (m_teleportFlags <= 0) |
2880 | SendOtherAgentsAppearanceToMe(); | 3499 | { |
3500 | ILandChannel landch = m_scene.LandChannel; | ||
3501 | if (landch != null) | ||
3502 | { | ||
3503 | landch.sendClientInitialLandInfo(ControllingClient); | ||
3504 | } | ||
3505 | } | ||
2881 | 3506 | ||
3507 | SendOtherAgentsAvatarFullToMe(); | ||
2882 | EntityBase[] entities = Scene.Entities.GetEntities(); | 3508 | EntityBase[] entities = Scene.Entities.GetEntities(); |
2883 | foreach(EntityBase e in entities) | 3509 | foreach (EntityBase e in entities) |
2884 | { | 3510 | { |
2885 | if (e != null && e is SceneObjectGroup) | 3511 | if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment) |
2886 | ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); | 3512 | ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); |
2887 | } | 3513 | } |
2888 | }); | 3514 | }); |
@@ -2892,6 +3518,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2892 | /// Do everything required once a client completes its movement into a region and becomes | 3518 | /// Do everything required once a client completes its movement into a region and becomes |
2893 | /// a root agent. | 3519 | /// a root agent. |
2894 | /// </summary> | 3520 | /// </summary> |
3521 | /// | ||
3522 | /* only called from on place, do done inline there | ||
2895 | private void ValidateAndSendAppearanceAndAgentData() | 3523 | private void ValidateAndSendAppearanceAndAgentData() |
2896 | { | 3524 | { |
2897 | //m_log.DebugFormat("[SCENE PRESENCE] SendInitialData: {0} ({1})", Name, UUID); | 3525 | //m_log.DebugFormat("[SCENE PRESENCE] SendInitialData: {0} ({1})", Name, UUID); |
@@ -2905,32 +3533,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
2905 | // to see if all the baked textures are already here. | 3533 | // to see if all the baked textures are already here. |
2906 | if (m_scene.AvatarFactory != null) | 3534 | if (m_scene.AvatarFactory != null) |
2907 | cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(this); | 3535 | cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(this); |
2908 | 3536 | ||
2909 | // If we aren't using a cached appearance, then clear out the baked textures | 3537 | // If we aren't using a cached appearance, then clear out the baked textures |
2910 | if (!cachedappearance) | 3538 | if (!cachedappearance) |
2911 | { | 3539 | { |
2912 | Appearance.ResetAppearance(); | ||
2913 | if (m_scene.AvatarFactory != null) | 3540 | if (m_scene.AvatarFactory != null) |
2914 | m_scene.AvatarFactory.QueueAppearanceSave(UUID); | 3541 | m_scene.AvatarFactory.QueueAppearanceSave(UUID); |
2915 | } | 3542 | } |
2916 | 3543 | ||
2917 | // This agent just became root. We are going to tell everyone about it. The process of | 3544 | // send avatar object to all viewers so they cross it into region |
2918 | // getting other avatars information was initiated elsewhere immediately after the child circuit connected... don't do it | 3545 | bool newhide = m_currentParcelHide; |
2919 | // again here... this comes after the cached appearance check because the avatars | 3546 | m_currentParcelHide = false; |
2920 | // appearance goes into the avatar update packet | 3547 | |
2921 | SendAvatarDataToAllAgents(); | 3548 | SendAvatarDataToAllAgents(); |
3549 | |||
3550 | // now hide | ||
3551 | if (newhide) | ||
3552 | { | ||
3553 | ParcelLoginCheck(m_currentParcelUUID); | ||
3554 | m_currentParcelHide = true; | ||
3555 | } | ||
3556 | |||
2922 | SendAppearanceToAgent(this); | 3557 | SendAppearanceToAgent(this); |
2923 | 3558 | ||
2924 | // If we are using the the cached appearance then send it out to everyone | 3559 | m_inTransit = false; |
2925 | if (cachedappearance) | 3560 | |
3561 | SendAppearanceToAllOtherAgents(); | ||
3562 | |||
3563 | if(Animator!= null) | ||
3564 | Animator.SendAnimPack(); | ||
3565 | } | ||
3566 | */ | ||
3567 | /// <summary> | ||
3568 | /// Send avatar full data appearance and animations for all other root agents to this agent, this agent | ||
3569 | /// can be either a child or root | ||
3570 | /// </summary> | ||
3571 | public void SendOtherAgentsAvatarFullToMe() | ||
3572 | { | ||
3573 | int count = 0; | ||
3574 | m_scene.ForEachRootScenePresence(delegate(ScenePresence p) | ||
2926 | { | 3575 | { |
2927 | m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name); | 3576 | // only send information about other root agents |
3577 | if (p.UUID == UUID) | ||
3578 | return; | ||
2928 | 3579 | ||
2929 | // If the avatars baked textures are all in the cache, then we have a | 3580 | // get the avatar, then a kill if can't see it |
2930 | // complete appearance... send it out, if not, then we'll send it when | 3581 | p.SendInitialAvatarDataToAgent(this); |
2931 | // the avatar finishes updating its appearance | 3582 | |
2932 | SendAppearanceToAllOtherAgents(); | 3583 | if (p.ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && GodLevel < 200) |
2933 | } | 3584 | return; |
3585 | |||
3586 | p.SendAppearanceToAgentNF(this); | ||
3587 | p.SendAnimPackToAgentNF(this); | ||
3588 | p.SendAttachmentsToAgentNF(this); | ||
3589 | count++; | ||
3590 | }); | ||
3591 | |||
3592 | m_scene.StatsReporter.AddAgentUpdates(count); | ||
2934 | } | 3593 | } |
2935 | 3594 | ||
2936 | /// <summary> | 3595 | /// <summary> |
@@ -2946,42 +3605,51 @@ namespace OpenSim.Region.Framework.Scenes | |||
2946 | m_log.WarnFormat( | 3605 | m_log.WarnFormat( |
2947 | "[SCENE PRESENCE]: Attempt to send avatar data from a child agent for {0} in {1}", | 3606 | "[SCENE PRESENCE]: Attempt to send avatar data from a child agent for {0} in {1}", |
2948 | Name, Scene.RegionInfo.RegionName); | 3607 | Name, Scene.RegionInfo.RegionName); |
2949 | |||
2950 | return; | 3608 | return; |
2951 | } | 3609 | } |
2952 | 3610 | ||
2953 | m_lastSize = Appearance.AvatarSize; | 3611 | m_lastSize = Appearance.AvatarSize; |
2954 | |||
2955 | int count = 0; | 3612 | int count = 0; |
3613 | |||
2956 | m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) | 3614 | m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) |
2957 | { | 3615 | { |
2958 | SendAvatarDataToAgent(scenePresence); | 3616 | SendAvatarDataToAgent(scenePresence); |
2959 | count++; | 3617 | count++; |
2960 | }); | 3618 | }); |
2961 | 3619 | ||
2962 | m_scene.StatsReporter.AddAgentUpdates(count); | 3620 | m_scene.StatsReporter.AddAgentUpdates(count); |
2963 | } | 3621 | } |
2964 | 3622 | ||
2965 | /// <summary> | 3623 | // sends avatar object to all clients so they cross it into region |
2966 | /// Send avatar data for all other root agents to this agent, this agent | 3624 | // then sends kills to hide |
2967 | /// can be either a child or root | 3625 | public void SendInitialAvatarDataToAllAgents(List<ScenePresence> presences) |
2968 | /// </summary> | ||
2969 | public void SendOtherAgentsAvatarDataToMe() | ||
2970 | { | 3626 | { |
3627 | m_lastSize = Appearance.AvatarSize; | ||
2971 | int count = 0; | 3628 | int count = 0; |
2972 | m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) | ||
2973 | { | ||
2974 | // only send information about other root agents | ||
2975 | if (scenePresence.UUID == UUID) | ||
2976 | return; | ||
2977 | |||
2978 | scenePresence.SendAvatarDataToAgent(this); | ||
2979 | count++; | ||
2980 | }); | ||
2981 | 3629 | ||
3630 | foreach (ScenePresence p in presences) | ||
3631 | { | ||
3632 | p.ControllingClient.SendAvatarDataImmediate(this); | ||
3633 | if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
3634 | // either just kill the object | ||
3635 | // p.ControllingClient.SendKillObject(new List<uint> {LocalId}); | ||
3636 | // or also attachments viewer may still know about | ||
3637 | SendKillTo(p); | ||
3638 | count++; | ||
3639 | } | ||
2982 | m_scene.StatsReporter.AddAgentUpdates(count); | 3640 | m_scene.StatsReporter.AddAgentUpdates(count); |
2983 | } | 3641 | } |
2984 | 3642 | ||
3643 | public void SendInitialAvatarDataToAgent(ScenePresence p) | ||
3644 | { | ||
3645 | p.ControllingClient.SendAvatarDataImmediate(this); | ||
3646 | if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
3647 | // either just kill the object | ||
3648 | // p.ControllingClient.SendKillObject(new List<uint> {LocalId}); | ||
3649 | // or also attachments viewer may still know about | ||
3650 | SendKillTo(p); | ||
3651 | } | ||
3652 | |||
2985 | /// <summary> | 3653 | /// <summary> |
2986 | /// Send avatar data to an agent. | 3654 | /// Send avatar data to an agent. |
2987 | /// </summary> | 3655 | /// </summary> |
@@ -2989,18 +3657,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
2989 | public void SendAvatarDataToAgent(ScenePresence avatar) | 3657 | public void SendAvatarDataToAgent(ScenePresence avatar) |
2990 | { | 3658 | { |
2991 | //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); | 3659 | //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); |
2992 | 3660 | if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200) | |
3661 | return; | ||
2993 | avatar.ControllingClient.SendAvatarDataImmediate(this); | 3662 | avatar.ControllingClient.SendAvatarDataImmediate(this); |
2994 | Animator.SendAnimPackToClient(avatar.ControllingClient); | ||
2995 | } | 3663 | } |
2996 | 3664 | ||
3665 | public void SendAvatarDataToAgentNF(ScenePresence avatar) | ||
3666 | { | ||
3667 | avatar.ControllingClient.SendAvatarDataImmediate(this); | ||
3668 | } | ||
3669 | |||
2997 | /// <summary> | 3670 | /// <summary> |
2998 | /// Send this agent's appearance to all other root and child agents in the scene | 3671 | /// Send this agent's appearance to all other root and child agents in the scene |
2999 | /// This agent must be root. | 3672 | /// This agent must be root. |
3000 | /// </summary> | 3673 | /// </summary> |
3001 | public void SendAppearanceToAllOtherAgents() | 3674 | public void SendAppearanceToAllOtherAgents() |
3002 | { | 3675 | { |
3003 | // m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} {1}", Name, UUID); | 3676 | // m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} {1}", Name, UUID); |
3004 | 3677 | ||
3005 | // only send update from root agents to other clients; children are only "listening posts" | 3678 | // only send update from root agents to other clients; children are only "listening posts" |
3006 | if (IsChildAgent) | 3679 | if (IsChildAgent) |
@@ -3011,7 +3684,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3011 | 3684 | ||
3012 | return; | 3685 | return; |
3013 | } | 3686 | } |
3014 | 3687 | ||
3015 | int count = 0; | 3688 | int count = 0; |
3016 | m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) | 3689 | m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) |
3017 | { | 3690 | { |
@@ -3022,29 +3695,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3022 | SendAppearanceToAgent(scenePresence); | 3695 | SendAppearanceToAgent(scenePresence); |
3023 | count++; | 3696 | count++; |
3024 | }); | 3697 | }); |
3025 | |||
3026 | m_scene.StatsReporter.AddAgentUpdates(count); | ||
3027 | } | ||
3028 | |||
3029 | /// <summary> | ||
3030 | /// Send appearance from all other root agents to this agent. this agent | ||
3031 | /// can be either root or child | ||
3032 | /// </summary> | ||
3033 | public void SendOtherAgentsAppearanceToMe() | ||
3034 | { | ||
3035 | // m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToMe: {0} {1}", Name, UUID); | ||
3036 | |||
3037 | int count = 0; | ||
3038 | m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) | ||
3039 | { | ||
3040 | // only send information about other root agents | ||
3041 | if (scenePresence.UUID == UUID) | ||
3042 | return; | ||
3043 | |||
3044 | scenePresence.SendAppearanceToAgent(this); | ||
3045 | count++; | ||
3046 | }); | ||
3047 | |||
3048 | m_scene.StatsReporter.AddAgentUpdates(count); | 3698 | m_scene.StatsReporter.AddAgentUpdates(count); |
3049 | } | 3699 | } |
3050 | 3700 | ||
@@ -3056,11 +3706,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
3056 | { | 3706 | { |
3057 | // m_log.DebugFormat( | 3707 | // m_log.DebugFormat( |
3058 | // "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); | 3708 | // "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); |
3709 | if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200) | ||
3710 | return; | ||
3711 | avatar.ControllingClient.SendAppearance( | ||
3712 | UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); | ||
3713 | } | ||
3059 | 3714 | ||
3715 | public void SendAppearanceToAgentNF(ScenePresence avatar) | ||
3716 | { | ||
3060 | avatar.ControllingClient.SendAppearance( | 3717 | avatar.ControllingClient.SendAppearance( |
3061 | UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); | 3718 | UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); |
3719 | } | ||
3062 | 3720 | ||
3063 | 3721 | public void SendAnimPackToAgent(ScenePresence p) | |
3722 | { | ||
3723 | if (IsChildAgent || Animator == null) | ||
3724 | return; | ||
3725 | |||
3726 | if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
3727 | return; | ||
3728 | |||
3729 | Animator.SendAnimPackToClient(p.ControllingClient); | ||
3730 | } | ||
3731 | |||
3732 | public void SendAnimPackToAgent(ScenePresence p, UUID[] animations, int[] seqs, UUID[] objectIDs) | ||
3733 | { | ||
3734 | if (IsChildAgent) | ||
3735 | return; | ||
3736 | |||
3737 | if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
3738 | return; | ||
3739 | |||
3740 | p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs); | ||
3741 | } | ||
3742 | |||
3743 | public void SendAnimPackToAgentNF(ScenePresence p) | ||
3744 | { | ||
3745 | if (IsChildAgent || Animator == null) | ||
3746 | return; | ||
3747 | Animator.SendAnimPackToClient(p.ControllingClient); | ||
3748 | } | ||
3749 | |||
3750 | public void SendAnimPackToAgentNF(ScenePresence p, UUID[] animations, int[] seqs, UUID[] objectIDs) | ||
3751 | { | ||
3752 | p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs); | ||
3753 | } | ||
3754 | |||
3755 | public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs) | ||
3756 | { | ||
3757 | if (IsChildAgent) | ||
3758 | return; | ||
3759 | |||
3760 | m_scene.ForEachScenePresence(delegate(ScenePresence p) | ||
3761 | { | ||
3762 | if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
3763 | return; | ||
3764 | p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs); | ||
3765 | }); | ||
3064 | } | 3766 | } |
3065 | 3767 | ||
3066 | #endregion | 3768 | #endregion |
@@ -3079,12 +3781,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3079 | } | 3781 | } |
3080 | 3782 | ||
3081 | // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m | 3783 | // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m |
3082 | if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || | 3784 | if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) |
3083 | Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) | ||
3084 | { | 3785 | { |
3085 | m_lastChildAgentUpdatePosition = AbsolutePosition; | 3786 | m_lastChildAgentUpdatePosition = AbsolutePosition; |
3086 | m_lastChildAgentUpdateCamPosition = CameraPosition; | 3787 | // m_lastChildAgentUpdateCamPosition = CameraPosition; |
3087 | 3788 | ||
3789 | /* cadu is not used | ||
3088 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); | 3790 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); |
3089 | cadu.ActiveGroupID = UUID.Zero.Guid; | 3791 | cadu.ActiveGroupID = UUID.Zero.Guid; |
3090 | cadu.AgentID = UUID.Guid; | 3792 | cadu.AgentID = UUID.Guid; |
@@ -3098,6 +3800,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3098 | 3800 | ||
3099 | // Throttles | 3801 | // Throttles |
3100 | float multiplier = 1; | 3802 | float multiplier = 1; |
3803 | |||
3101 | int childRegions = KnownRegionCount; | 3804 | int childRegions = KnownRegionCount; |
3102 | if (childRegions != 0) | 3805 | if (childRegions != 0) |
3103 | multiplier = 1f / childRegions; | 3806 | multiplier = 1f / childRegions; |
@@ -3108,9 +3811,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
3108 | 3811 | ||
3109 | cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); | 3812 | cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); |
3110 | cadu.Velocity = Velocity; | 3813 | cadu.Velocity = Velocity; |
3111 | 3814 | */ | |
3112 | AgentPosition agentpos = new AgentPosition(); | 3815 | AgentPosition agentpos = new AgentPosition(); |
3113 | agentpos.CopyFrom(cadu); | 3816 | // agentpos.CopyFrom(cadu, ControllingClient.SessionId); |
3817 | |||
3818 | agentpos.AgentID = new UUID(UUID.Guid); | ||
3819 | agentpos.SessionID = ControllingClient.SessionId; | ||
3820 | |||
3821 | agentpos.Size = Appearance.AvatarSize; | ||
3822 | |||
3823 | agentpos.Center = CameraPosition; | ||
3824 | agentpos.Far = DrawDistance; | ||
3825 | agentpos.Position = AbsolutePosition; | ||
3826 | agentpos.Velocity = Velocity; | ||
3827 | agentpos.RegionHandle = RegionHandle; | ||
3828 | agentpos.Throttles = ControllingClient.GetThrottlesPacked(1); | ||
3829 | |||
3114 | 3830 | ||
3115 | // Let's get this out of the update loop | 3831 | // Let's get this out of the update loop |
3116 | Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); | 3832 | Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); |
@@ -3130,7 +3846,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3130 | protected void CheckForBorderCrossing() | 3846 | protected void CheckForBorderCrossing() |
3131 | { | 3847 | { |
3132 | // Check that we we are not a child | 3848 | // Check that we we are not a child |
3133 | if (IsChildAgent) | 3849 | if (IsChildAgent || IsInTransit) |
3134 | return; | 3850 | return; |
3135 | 3851 | ||
3136 | // If we don't have a PhysActor, we can't cross anyway | 3852 | // If we don't have a PhysActor, we can't cross anyway |
@@ -3140,140 +3856,72 @@ namespace OpenSim.Region.Framework.Scenes | |||
3140 | if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero) | 3856 | if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero) |
3141 | return; | 3857 | return; |
3142 | 3858 | ||
3143 | if (!IsInTransit) | 3859 | Vector3 pos2 = AbsolutePosition; |
3144 | { | 3860 | Vector3 vel = Velocity; |
3145 | Vector3 pos2 = AbsolutePosition; | ||
3146 | Vector3 vel = Velocity; | ||
3147 | int neighbor = 0; | ||
3148 | int[] fix = new int[2]; | ||
3149 | 3861 | ||
3150 | float timeStep = 0.1f; | 3862 | float timeStep = 0.1f; |
3151 | pos2.X = pos2.X + (vel.X * timeStep); | 3863 | pos2.X += vel.X * timeStep; |
3152 | pos2.Y = pos2.Y + (vel.Y * timeStep); | 3864 | pos2.Y += vel.Y * timeStep; |
3153 | pos2.Z = pos2.Z + (vel.Z * timeStep); | 3865 | pos2.Z += vel.Z * timeStep; |
3154 | 3866 | ||
3155 | if (!IsInTransit) | ||
3156 | { | ||
3157 | // m_log.DebugFormat( | 3867 | // m_log.DebugFormat( |
3158 | // "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}", | 3868 | // "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}", |
3159 | // pos2, Name, Scene.Name); | 3869 | // pos2, Name, Scene.Name); |
3160 | 3870 | ||
3161 | // Checks if where it's headed exists a region | 3871 | if( Scene.TestBorderCross(pos2, Cardinals.E) || |
3162 | bool needsTransit = false; | 3872 | Scene.TestBorderCross(pos2, Cardinals.W) || |
3163 | if (m_scene.TestBorderCross(pos2, Cardinals.W)) | 3873 | Scene.TestBorderCross(pos2, Cardinals.N) || |
3164 | { | 3874 | Scene.TestBorderCross(pos2, Cardinals.S) |
3165 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) | 3875 | ) |
3166 | { | 3876 | { |
3167 | needsTransit = true; | 3877 | if (!CrossToNewRegion() && m_requestedSitTargetUUID == UUID.Zero) |
3168 | neighbor = m_scene.HaveNeighbor(Cardinals.SW, ref fix); | ||
3169 | } | ||
3170 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | ||
3171 | { | ||
3172 | needsTransit = true; | ||
3173 | neighbor = m_scene.HaveNeighbor(Cardinals.NW, ref fix); | ||
3174 | } | ||
3175 | else | ||
3176 | { | ||
3177 | needsTransit = true; | ||
3178 | neighbor = m_scene.HaveNeighbor(Cardinals.W, ref fix); | ||
3179 | } | ||
3180 | } | ||
3181 | else if (m_scene.TestBorderCross(pos2, Cardinals.E)) | ||
3182 | { | ||
3183 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) | ||
3184 | { | ||
3185 | needsTransit = true; | ||
3186 | neighbor = m_scene.HaveNeighbor(Cardinals.SE, ref fix); | ||
3187 | } | ||
3188 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | ||
3189 | { | ||
3190 | needsTransit = true; | ||
3191 | neighbor = m_scene.HaveNeighbor(Cardinals.NE, ref fix); | ||
3192 | } | ||
3193 | else | ||
3194 | { | ||
3195 | needsTransit = true; | ||
3196 | neighbor = m_scene.HaveNeighbor(Cardinals.E, ref fix); | ||
3197 | } | ||
3198 | } | ||
3199 | else if (m_scene.TestBorderCross(pos2, Cardinals.S)) | ||
3200 | { | ||
3201 | needsTransit = true; | ||
3202 | neighbor = m_scene.HaveNeighbor(Cardinals.S, ref fix); | ||
3203 | } | ||
3204 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | ||
3205 | { | ||
3206 | needsTransit = true; | ||
3207 | neighbor = m_scene.HaveNeighbor(Cardinals.N, ref fix); | ||
3208 | } | ||
3209 | |||
3210 | // Makes sure avatar does not end up outside region | ||
3211 | if (neighbor <= 0) | ||
3212 | { | ||
3213 | if (needsTransit) | ||
3214 | { | ||
3215 | if (m_requestedSitTargetUUID == UUID.Zero) | ||
3216 | { | ||
3217 | bool isFlying = Flying; | ||
3218 | RemoveFromPhysicalScene(); | ||
3219 | |||
3220 | Vector3 pos = AbsolutePosition; | ||
3221 | if (AbsolutePosition.X < 0) | ||
3222 | pos.X += Velocity.X * 2; | ||
3223 | else if (AbsolutePosition.X > Constants.RegionSize) | ||
3224 | pos.X -= Velocity.X * 2; | ||
3225 | if (AbsolutePosition.Y < 0) | ||
3226 | pos.Y += Velocity.Y * 2; | ||
3227 | else if (AbsolutePosition.Y > Constants.RegionSize) | ||
3228 | pos.Y -= Velocity.Y * 2; | ||
3229 | Velocity = Vector3.Zero; | ||
3230 | AbsolutePosition = pos; | ||
3231 | |||
3232 | // m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition); | ||
3233 | |||
3234 | AddToPhysicalScene(isFlying); | ||
3235 | } | ||
3236 | } | ||
3237 | } | ||
3238 | else if (neighbor > 0) | ||
3239 | { | ||
3240 | if (!CrossToNewRegion()) | ||
3241 | { | ||
3242 | if (m_requestedSitTargetUUID == UUID.Zero) | ||
3243 | { | ||
3244 | bool isFlying = Flying; | ||
3245 | RemoveFromPhysicalScene(); | ||
3246 | |||
3247 | Vector3 pos = AbsolutePosition; | ||
3248 | if (AbsolutePosition.X < 0) | ||
3249 | pos.X += Velocity.X * 2; | ||
3250 | else if (AbsolutePosition.X > Constants.RegionSize) | ||
3251 | pos.X -= Velocity.X * 2; | ||
3252 | if (AbsolutePosition.Y < 0) | ||
3253 | pos.Y += Velocity.Y * 2; | ||
3254 | else if (AbsolutePosition.Y > Constants.RegionSize) | ||
3255 | pos.Y -= Velocity.Y * 2; | ||
3256 | Velocity = Vector3.Zero; | ||
3257 | AbsolutePosition = pos; | ||
3258 | |||
3259 | AddToPhysicalScene(isFlying); | ||
3260 | } | ||
3261 | } | ||
3262 | } | ||
3263 | } | ||
3264 | else | ||
3265 | { | 3878 | { |
3266 | // This constant has been inferred from experimentation | 3879 | // we don't have entity transfer module |
3267 | // I'm not sure what this value should be, so I tried a few values. | 3880 | Vector3 pos = AbsolutePosition; |
3268 | timeStep = 0.04f; | 3881 | float px = pos.X; |
3269 | pos2 = AbsolutePosition; | 3882 | if (px < 0) |
3270 | pos2.X = pos2.X + (vel.X * timeStep); | 3883 | pos.X += Velocity.X * 2; |
3271 | pos2.Y = pos2.Y + (vel.Y * timeStep); | 3884 | else if (px > m_scene.RegionInfo.RegionSizeX) |
3272 | // Don't touch the Z | 3885 | pos.X -= Velocity.X * 2; |
3273 | m_pos = pos2; | 3886 | |
3274 | m_log.DebugFormat("[SCENE PRESENCE]: In transit m_pos={0}", m_pos); | 3887 | float py = pos.Y; |
3888 | if (py < 0) | ||
3889 | pos.Y += Velocity.Y * 2; | ||
3890 | else if (py > m_scene.RegionInfo.RegionSizeY) | ||
3891 | pos.Y -= Velocity.Y * 2; | ||
3892 | |||
3893 | Velocity = Vector3.Zero; | ||
3894 | AbsolutePosition = pos; | ||
3275 | } | 3895 | } |
3276 | } | 3896 | } |
3897 | } | ||
3898 | |||
3899 | public void CrossToNewRegionFail() | ||
3900 | { | ||
3901 | if (m_requestedSitTargetUUID == UUID.Zero) | ||
3902 | { | ||
3903 | bool isFlying = Flying; | ||
3904 | RemoveFromPhysicalScene(); | ||
3905 | |||
3906 | Vector3 pos = AbsolutePosition; | ||
3907 | float px = pos.X; | ||
3908 | if (px < 0) | ||
3909 | pos.X += Velocity.X * 2; | ||
3910 | else if (px > m_scene.RegionInfo.RegionSizeX) | ||
3911 | pos.X -= Velocity.X * 2; | ||
3912 | |||
3913 | float py = pos.Y; | ||
3914 | if (py < 0) | ||
3915 | pos.Y += Velocity.Y * 2; | ||
3916 | else if (py > m_scene.RegionInfo.RegionSizeY) | ||
3917 | pos.Y -= Velocity.Y * 2; | ||
3918 | |||
3919 | Velocity = Vector3.Zero; | ||
3920 | AbsolutePosition = pos; | ||
3921 | |||
3922 | AddToPhysicalScene(isFlying); | ||
3923 | } | ||
3924 | |||
3277 | } | 3925 | } |
3278 | 3926 | ||
3279 | /// <summary> | 3927 | /// <summary> |
@@ -3284,21 +3932,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
3284 | /// </summary> | 3932 | /// </summary> |
3285 | protected bool CrossToNewRegion() | 3933 | protected bool CrossToNewRegion() |
3286 | { | 3934 | { |
3935 | bool result = false; | ||
3936 | // parcelRegionCross(false); | ||
3287 | try | 3937 | try |
3288 | { | 3938 | { |
3289 | return m_scene.CrossAgentToNewRegion(this, Flying); | 3939 | result = m_scene.CrossAgentToNewRegion(this, Flying); |
3290 | } | 3940 | } |
3291 | catch | 3941 | catch |
3292 | { | 3942 | { |
3293 | return m_scene.CrossAgentToNewRegion(this, false); | 3943 | // result = m_scene.CrossAgentToNewRegion(this, false); |
3944 | return false; | ||
3294 | } | 3945 | } |
3295 | } | 3946 | // if(!result) |
3947 | // parcelRegionCross(true); | ||
3948 | |||
3949 | return result; | ||
3296 | 3950 | ||
3297 | public void RestoreInCurrentScene() | ||
3298 | { | ||
3299 | AddToPhysicalScene(false); // not exactly false | ||
3300 | } | 3951 | } |
3301 | 3952 | ||
3953 | /* useless. Either use MakeChild or delete the presence | ||
3302 | public void Reset() | 3954 | public void Reset() |
3303 | { | 3955 | { |
3304 | // m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName); | 3956 | // m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName); |
@@ -3309,7 +3961,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3309 | 3961 | ||
3310 | Animator.ResetAnimations(); | 3962 | Animator.ResetAnimations(); |
3311 | } | 3963 | } |
3312 | 3964 | */ | |
3313 | /// <summary> | 3965 | /// <summary> |
3314 | /// Computes which child agents to close when the scene presence moves to another region. | 3966 | /// Computes which child agents to close when the scene presence moves to another region. |
3315 | /// Removes those regions from m_knownRegions. | 3967 | /// Removes those regions from m_knownRegions. |
@@ -3348,10 +4000,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3348 | if (byebyeRegions.Count > 0) | 4000 | if (byebyeRegions.Count > 0) |
3349 | { | 4001 | { |
3350 | m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); | 4002 | m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); |
3351 | Util.FireAndForget(delegate | 4003 | |
3352 | { | 4004 | AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID); |
3353 | m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, byebyeRegions); | 4005 | string auth = string.Empty; |
3354 | }); | 4006 | if (acd != null) |
4007 | auth = acd.SessionID.ToString(); | ||
4008 | m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions); | ||
3355 | } | 4009 | } |
3356 | 4010 | ||
3357 | foreach (ulong handle in byebyeRegions) | 4011 | foreach (ulong handle in byebyeRegions) |
@@ -3368,6 +4022,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3368 | /// </summary> | 4022 | /// </summary> |
3369 | public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus) | 4023 | public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus) |
3370 | { | 4024 | { |
4025 | int oldgodlevel = GodLevel; | ||
4026 | |||
3371 | if (godStatus) | 4027 | if (godStatus) |
3372 | { | 4028 | { |
3373 | // For now, assign god level 200 to anyone | 4029 | // For now, assign god level 200 to anyone |
@@ -3388,11 +4044,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3388 | } | 4044 | } |
3389 | 4045 | ||
3390 | ControllingClient.SendAdminResponse(token, (uint)GodLevel); | 4046 | ControllingClient.SendAdminResponse(token, (uint)GodLevel); |
4047 | |||
4048 | if(oldgodlevel != GodLevel) | ||
4049 | parcelGodCheck(m_currentParcelUUID, GodLevel >= 200); | ||
3391 | } | 4050 | } |
3392 | 4051 | ||
3393 | #region Child Agent Updates | 4052 | #region Child Agent Updates |
3394 | 4053 | ||
3395 | public void ChildAgentDataUpdate(AgentData cAgentData) | 4054 | public void UpdateChildAgent(AgentData cAgentData) |
3396 | { | 4055 | { |
3397 | // m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); | 4056 | // m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); |
3398 | if (!IsChildAgent) | 4057 | if (!IsChildAgent) |
@@ -3402,19 +4061,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
3402 | } | 4061 | } |
3403 | 4062 | ||
3404 | private static Vector3 marker = new Vector3(-1f, -1f, -1f); | 4063 | private static Vector3 marker = new Vector3(-1f, -1f, -1f); |
4064 | |||
3405 | private void RaiseUpdateThrottles() | 4065 | private void RaiseUpdateThrottles() |
3406 | { | 4066 | { |
3407 | m_scene.EventManager.TriggerThrottleUpdate(this); | 4067 | m_scene.EventManager.TriggerThrottleUpdate(this); |
3408 | } | 4068 | } |
4069 | |||
3409 | /// <summary> | 4070 | /// <summary> |
3410 | /// This updates important decision making data about a child agent | 4071 | /// This updates important decision making data about a child agent |
3411 | /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region | 4072 | /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region |
3412 | /// </summary> | 4073 | /// </summary> |
3413 | public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) | 4074 | public void UpdateChildAgent(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) |
3414 | { | 4075 | { |
3415 | if (!IsChildAgent) | 4076 | if (!IsChildAgent) |
3416 | return; | 4077 | return; |
3417 | 4078 | ||
4079 | RegionHandle = cAgentData.RegionHandle; | ||
4080 | |||
3418 | //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); | 4081 | //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); |
3419 | int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; | 4082 | int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; |
3420 | int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; | 4083 | int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; |
@@ -3441,8 +4104,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3441 | if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) | 4104 | if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) |
3442 | ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); | 4105 | ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); |
3443 | 4106 | ||
4107 | if(cAgentData.ChildrenCapSeeds != null && cAgentData.ChildrenCapSeeds.Count >0) | ||
4108 | { | ||
4109 | if (Scene.CapsModule != null) | ||
4110 | { | ||
4111 | Scene.CapsModule.SetChildrenSeed(UUID, cAgentData.ChildrenCapSeeds); | ||
4112 | } | ||
4113 | |||
4114 | KnownRegions = cAgentData.ChildrenCapSeeds; | ||
4115 | } | ||
4116 | |||
3444 | //cAgentData.AVHeight; | 4117 | //cAgentData.AVHeight; |
3445 | RegionHandle = cAgentData.RegionHandle; | ||
3446 | //m_velocity = cAgentData.Velocity; | 4118 | //m_velocity = cAgentData.Velocity; |
3447 | } | 4119 | } |
3448 | 4120 | ||
@@ -3452,6 +4124,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3452 | 4124 | ||
3453 | cAgent.AgentID = UUID; | 4125 | cAgent.AgentID = UUID; |
3454 | cAgent.RegionID = Scene.RegionInfo.RegionID; | 4126 | cAgent.RegionID = Scene.RegionInfo.RegionID; |
4127 | cAgent.SessionID = ControllingClient.SessionId; | ||
3455 | 4128 | ||
3456 | cAgent.Position = AbsolutePosition; | 4129 | cAgent.Position = AbsolutePosition; |
3457 | cAgent.Velocity = m_velocity; | 4130 | cAgent.Velocity = m_velocity; |
@@ -3463,16 +4136,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3463 | cAgent.Far = DrawDistance; | 4136 | cAgent.Far = DrawDistance; |
3464 | 4137 | ||
3465 | // Throttles | 4138 | // Throttles |
3466 | float multiplier = 1; | 4139 | cAgent.Throttles = ControllingClient.GetThrottlesPacked(1); |
3467 | int childRegions = KnownRegionCount; | ||
3468 | if (childRegions != 0) | ||
3469 | multiplier = 1f / childRegions; | ||
3470 | |||
3471 | // Minimum throttle for a child region is 1/4 of the root region throttle | ||
3472 | if (multiplier <= 0.25f) | ||
3473 | multiplier = 0.25f; | ||
3474 | |||
3475 | cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier); | ||
3476 | 4140 | ||
3477 | cAgent.HeadRotation = m_headrotation; | 4141 | cAgent.HeadRotation = m_headrotation; |
3478 | cAgent.BodyRotation = Rotation; | 4142 | cAgent.BodyRotation = Rotation; |
@@ -3485,7 +4149,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3485 | 4149 | ||
3486 | cAgent.AlwaysRun = SetAlwaysRun; | 4150 | cAgent.AlwaysRun = SetAlwaysRun; |
3487 | 4151 | ||
3488 | cAgent.Appearance = new AvatarAppearance(Appearance); | 4152 | // make clear we want the all thing |
4153 | cAgent.Appearance = new AvatarAppearance(Appearance,true,true); | ||
3489 | 4154 | ||
3490 | cAgent.ParentPart = ParentUUID; | 4155 | cAgent.ParentPart = ParentUUID; |
3491 | cAgent.SitOffset = PrevSitOffset; | 4156 | cAgent.SitOffset = PrevSitOffset; |
@@ -3511,13 +4176,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
3511 | cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; | 4176 | cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; |
3512 | cAgent.AnimState = Animator.Animations.ImplicitDefaultAnimation; | 4177 | cAgent.AnimState = Animator.Animations.ImplicitDefaultAnimation; |
3513 | 4178 | ||
4179 | cAgent.MovementAnimationOverRides = Overrides.CloneAOPairs(); | ||
4180 | |||
4181 | cAgent.MotionState = (byte)Animator.currentControlState; | ||
4182 | |||
3514 | if (Scene.AttachmentsModule != null) | 4183 | if (Scene.AttachmentsModule != null) |
3515 | Scene.AttachmentsModule.CopyAttachments(this, cAgent); | 4184 | Scene.AttachmentsModule.CopyAttachments(this, cAgent); |
3516 | } | 4185 | } |
3517 | 4186 | ||
3518 | private void CopyFrom(AgentData cAgent) | 4187 | private void CopyFrom(AgentData cAgent) |
3519 | { | 4188 | { |
3520 | m_originRegionID = cAgent.RegionID; | ||
3521 | 4189 | ||
3522 | m_callbackURI = cAgent.CallbackURI; | 4190 | m_callbackURI = cAgent.CallbackURI; |
3523 | // m_log.DebugFormat( | 4191 | // m_log.DebugFormat( |
@@ -3539,6 +4207,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
3539 | // DrawDistance = cAgent.Far; | 4207 | // DrawDistance = cAgent.Far; |
3540 | DrawDistance = Scene.DefaultDrawDistance; | 4208 | DrawDistance = Scene.DefaultDrawDistance; |
3541 | 4209 | ||
4210 | if (cAgent.ChildrenCapSeeds != null && cAgent.ChildrenCapSeeds.Count > 0) | ||
4211 | { | ||
4212 | if (Scene.CapsModule != null) | ||
4213 | { | ||
4214 | Scene.CapsModule.SetChildrenSeed(UUID, cAgent.ChildrenCapSeeds); | ||
4215 | } | ||
4216 | KnownRegions = cAgent.ChildrenCapSeeds; | ||
4217 | } | ||
4218 | |||
3542 | if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) | 4219 | if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) |
3543 | ControllingClient.SetChildAgentThrottle(cAgent.Throttles); | 4220 | ControllingClient.SetChildAgentThrottle(cAgent.Throttles); |
3544 | 4221 | ||
@@ -3550,14 +4227,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3550 | GodLevel = cAgent.GodLevel; | 4227 | GodLevel = cAgent.GodLevel; |
3551 | SetAlwaysRun = cAgent.AlwaysRun; | 4228 | SetAlwaysRun = cAgent.AlwaysRun; |
3552 | 4229 | ||
4230 | |||
3553 | Appearance = new AvatarAppearance(cAgent.Appearance); | 4231 | Appearance = new AvatarAppearance(cAgent.Appearance); |
4232 | /* | ||
4233 | bool isFlying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | ||
4234 | |||
3554 | if (PhysicsActor != null) | 4235 | if (PhysicsActor != null) |
3555 | { | 4236 | { |
3556 | bool isFlying = Flying; | ||
3557 | RemoveFromPhysicalScene(); | 4237 | RemoveFromPhysicalScene(); |
3558 | AddToPhysicalScene(isFlying); | 4238 | AddToPhysicalScene(isFlying); |
3559 | } | 4239 | } |
3560 | 4240 | */ | |
3561 | try | 4241 | try |
3562 | { | 4242 | { |
3563 | lock (scriptedcontrols) | 4243 | lock (scriptedcontrols) |
@@ -3581,16 +4261,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
3581 | } | 4261 | } |
3582 | catch { } | 4262 | catch { } |
3583 | 4263 | ||
4264 | Animator.ResetAnimations(); | ||
4265 | |||
4266 | Overrides.CopyAOPairsFrom(cAgent.MovementAnimationOverRides); | ||
4267 | |||
3584 | // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object? | 4268 | // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object? |
3585 | if (cAgent.Anims != null) | ||
3586 | Animator.Animations.FromArray(cAgent.Anims); | ||
3587 | if (cAgent.DefaultAnim != null) | 4269 | if (cAgent.DefaultAnim != null) |
3588 | Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); | 4270 | Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); |
3589 | if (cAgent.AnimState != null) | 4271 | if (cAgent.AnimState != null) |
3590 | Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); | 4272 | Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); |
4273 | if (cAgent.Anims != null) | ||
4274 | Animator.Animations.FromArray(cAgent.Anims); | ||
4275 | if (cAgent.MotionState != 0) | ||
4276 | Animator.currentControlState = (ScenePresenceAnimator.motionControlStates) cAgent.MotionState; | ||
3591 | 4277 | ||
3592 | if (Scene.AttachmentsModule != null) | 4278 | if (Scene.AttachmentsModule != null) |
3593 | Scene.AttachmentsModule.CopyAttachments(cAgent, this); | 4279 | Scene.AttachmentsModule.CopyAttachments(cAgent, this); |
4280 | |||
4281 | lock (m_originRegionIDAccessLock) | ||
4282 | m_originRegionID = cAgent.RegionID; | ||
4283 | |||
3594 | } | 4284 | } |
3595 | 4285 | ||
3596 | public bool CopyAgent(out IAgentData agent) | 4286 | public bool CopyAgent(out IAgentData agent) |
@@ -3607,12 +4297,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3607 | /// </summary> | 4297 | /// </summary> |
3608 | public void UpdateMovement() | 4298 | public void UpdateMovement() |
3609 | { | 4299 | { |
4300 | if (IsInTransit) | ||
4301 | return; | ||
3610 | if (m_forceToApply.HasValue) | 4302 | if (m_forceToApply.HasValue) |
3611 | { | 4303 | { |
3612 | Vector3 force = m_forceToApply.Value; | 4304 | Vector3 force = m_forceToApply.Value; |
3613 | 4305 | ||
3614 | Updated = true; | ||
3615 | |||
3616 | Velocity = force; | 4306 | Velocity = force; |
3617 | 4307 | ||
3618 | m_forceToApply = null; | 4308 | m_forceToApply = null; |
@@ -3687,14 +4377,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3687 | { | 4377 | { |
3688 | if (IsChildAgent || Animator == null) | 4378 | if (IsChildAgent || Animator == null) |
3689 | return; | 4379 | return; |
3690 | 4380 | ||
4381 | if(IsInTransit) | ||
4382 | return; | ||
3691 | //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) | 4383 | //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) |
3692 | // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( | 4384 | // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( |
3693 | // as of this comment the interval is set in AddToPhysicalScene | 4385 | // as of this comment the interval is set in AddToPhysicalScene |
3694 | 4386 | ||
3695 | // if (m_updateCount > 0) | 4387 | // if (m_updateCount > 0) |
3696 | // { | 4388 | // { |
3697 | Animator.UpdateMovementAnimations(); | 4389 | if (Animator.UpdateMovementAnimations()) |
4390 | TriggerScenePresenceUpdated(); | ||
3698 | // m_updateCount--; | 4391 | // m_updateCount--; |
3699 | // } | 4392 | // } |
3700 | 4393 | ||
@@ -3858,6 +4551,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3858 | // Animator.Close(); | 4551 | // Animator.Close(); |
3859 | Animator = null; | 4552 | Animator = null; |
3860 | 4553 | ||
4554 | LifecycleState = ScenePresenceState.Removed; | ||
3861 | } | 4555 | } |
3862 | 4556 | ||
3863 | public void AddAttachment(SceneObjectGroup gobj) | 4557 | public void AddAttachment(SceneObjectGroup gobj) |
@@ -4033,6 +4727,287 @@ namespace OpenSim.Region.Framework.Scenes | |||
4033 | return validated; | 4727 | return validated; |
4034 | } | 4728 | } |
4035 | 4729 | ||
4730 | public void SendAttachmentsToAllAgents() | ||
4731 | { | ||
4732 | lock (m_attachments) | ||
4733 | { | ||
4734 | foreach (SceneObjectGroup sog in m_attachments) | ||
4735 | { | ||
4736 | m_scene.ForEachScenePresence(delegate(ScenePresence p) | ||
4737 | { | ||
4738 | if (p != this && sog.HasPrivateAttachmentPoint) | ||
4739 | return; | ||
4740 | |||
4741 | if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
4742 | return; | ||
4743 | |||
4744 | SendTerseUpdateToAgentNF(p); | ||
4745 | SendAttachmentFullUpdateToAgentNF(sog, p); | ||
4746 | }); | ||
4747 | } | ||
4748 | } | ||
4749 | } | ||
4750 | |||
4751 | // send attachments to a client without filters except for huds | ||
4752 | // for now they are checked in several places down the line... | ||
4753 | public void SendAttachmentsToAgentNF(ScenePresence p) | ||
4754 | { | ||
4755 | SendTerseUpdateToAgentNF(p); | ||
4756 | lock (m_attachments) | ||
4757 | { | ||
4758 | foreach (SceneObjectGroup sog in m_attachments) | ||
4759 | { | ||
4760 | SendAttachmentFullUpdateToAgentNF(sog, p); | ||
4761 | } | ||
4762 | } | ||
4763 | } | ||
4764 | |||
4765 | public void SendAttachmentFullUpdateToAgentNF(SceneObjectGroup sog, ScenePresence p) | ||
4766 | { | ||
4767 | if (p != this && sog.HasPrivateAttachmentPoint) | ||
4768 | return; | ||
4769 | |||
4770 | SceneObjectPart[] parts = sog.Parts; | ||
4771 | SceneObjectPart rootpart = sog.RootPart; | ||
4772 | |||
4773 | p.ControllingClient.SendEntityUpdate(rootpart, PrimUpdateFlags.FullUpdate); | ||
4774 | |||
4775 | for (int i = 0; i < parts.Length; i++) | ||
4776 | { | ||
4777 | SceneObjectPart part = parts[i]; | ||
4778 | if (part == rootpart) | ||
4779 | continue; | ||
4780 | p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate); | ||
4781 | } | ||
4782 | } | ||
4783 | |||
4784 | public void SendAttachmentScheduleUpdate(SceneObjectGroup sog) | ||
4785 | { | ||
4786 | if (IsChildAgent || IsInTransit) | ||
4787 | return; | ||
4788 | |||
4789 | SceneObjectPart[] origparts = sog.Parts; | ||
4790 | SceneObjectPart[] parts = new SceneObjectPart[origparts.Length]; | ||
4791 | PrimUpdateFlags[] flags = new PrimUpdateFlags[origparts.Length]; | ||
4792 | |||
4793 | SceneObjectPart rootpart = sog.RootPart; | ||
4794 | UpdateRequired rootreq = sog.RootPart.UpdateFlag; | ||
4795 | |||
4796 | int j = 0; | ||
4797 | bool allterse = true; | ||
4798 | for (int i = 0; i < origparts.Length; i++) | ||
4799 | { | ||
4800 | if (origparts[i] != rootpart) | ||
4801 | { | ||
4802 | switch (origparts[i].UpdateFlag) | ||
4803 | { | ||
4804 | case UpdateRequired.NONE: | ||
4805 | break; | ||
4806 | |||
4807 | case UpdateRequired.TERSE: | ||
4808 | flags[j] = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | ||
4809 | | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity; | ||
4810 | parts[j] = origparts[i]; | ||
4811 | j++; | ||
4812 | break; | ||
4813 | |||
4814 | case UpdateRequired.FULL: | ||
4815 | flags[j] = PrimUpdateFlags.FullUpdate; | ||
4816 | allterse = false; | ||
4817 | parts[j] = origparts[i]; | ||
4818 | j++; | ||
4819 | break; | ||
4820 | } | ||
4821 | } | ||
4822 | origparts[i].UpdateFlag = 0; | ||
4823 | } | ||
4824 | |||
4825 | if (j == 0 && rootreq == UpdateRequired.NONE) | ||
4826 | return; | ||
4827 | |||
4828 | PrimUpdateFlags rootflag = PrimUpdateFlags.FullUpdate; | ||
4829 | |||
4830 | if (rootreq != UpdateRequired.FULL && allterse) | ||
4831 | { | ||
4832 | rootflag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | ||
4833 | | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity; | ||
4834 | } | ||
4835 | |||
4836 | int nparts = j; | ||
4837 | |||
4838 | ControllingClient.SendEntityUpdate(rootpart, rootflag); | ||
4839 | |||
4840 | for (int i = 0; i < nparts; i++) | ||
4841 | { | ||
4842 | ControllingClient.SendEntityUpdate(parts[i], flags[i]); | ||
4843 | } | ||
4844 | |||
4845 | if (sog.HasPrivateAttachmentPoint) | ||
4846 | return; | ||
4847 | |||
4848 | List<ScenePresence> allPresences = m_scene.GetScenePresences(); | ||
4849 | foreach (ScenePresence p in allPresences) | ||
4850 | { | ||
4851 | if (p == this) | ||
4852 | continue; | ||
4853 | |||
4854 | if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
4855 | continue; | ||
4856 | |||
4857 | p.ControllingClient.SendEntityUpdate(rootpart, rootflag); | ||
4858 | |||
4859 | for (int i = 0; i < nparts; i++) | ||
4860 | { | ||
4861 | p.ControllingClient.SendEntityUpdate(parts[i], flags[i]); | ||
4862 | } | ||
4863 | } | ||
4864 | } | ||
4865 | |||
4866 | public void SendAttachmentUpdate(SceneObjectGroup sog, UpdateRequired UpdateFlag) | ||
4867 | { | ||
4868 | if (IsChildAgent || IsInTransit) | ||
4869 | return; | ||
4870 | |||
4871 | PrimUpdateFlags flag; | ||
4872 | switch (UpdateFlag) | ||
4873 | { | ||
4874 | case UpdateRequired.TERSE: | ||
4875 | flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | ||
4876 | | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity; | ||
4877 | break; | ||
4878 | |||
4879 | case UpdateRequired.FULL: | ||
4880 | flag = PrimUpdateFlags.FullUpdate; | ||
4881 | break; | ||
4882 | |||
4883 | default: | ||
4884 | return; | ||
4885 | } | ||
4886 | |||
4887 | SceneObjectPart[] parts = sog.Parts; | ||
4888 | SceneObjectPart rootpart = sog.RootPart; | ||
4889 | |||
4890 | // rootpart.UpdateFlag = 0; | ||
4891 | |||
4892 | ControllingClient.SendEntityUpdate(rootpart, flag); | ||
4893 | |||
4894 | for (int i = 0; i < parts.Length; i++) | ||
4895 | { | ||
4896 | SceneObjectPart part = parts[i]; | ||
4897 | if (part == rootpart) | ||
4898 | continue; | ||
4899 | ControllingClient.SendEntityUpdate(part, flag); | ||
4900 | // part.UpdateFlag = 0; | ||
4901 | } | ||
4902 | |||
4903 | if (sog.HasPrivateAttachmentPoint) | ||
4904 | return; | ||
4905 | |||
4906 | |||
4907 | List<ScenePresence> allPresences = m_scene.GetScenePresences(); | ||
4908 | foreach (ScenePresence p in allPresences) | ||
4909 | { | ||
4910 | if (p == this) | ||
4911 | continue; | ||
4912 | |||
4913 | if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
4914 | continue; | ||
4915 | |||
4916 | p.ControllingClient.SendEntityUpdate(rootpart, flag); | ||
4917 | |||
4918 | for (int i = 0; i < parts.Length; i++) | ||
4919 | { | ||
4920 | SceneObjectPart part = parts[i]; | ||
4921 | if (part == rootpart) | ||
4922 | continue; | ||
4923 | p.ControllingClient.SendEntityUpdate(part, flag); | ||
4924 | } | ||
4925 | } | ||
4926 | } | ||
4927 | |||
4928 | public void SendAttachmentScheduleUpdate(SceneObjectPart part) | ||
4929 | { | ||
4930 | if (IsChildAgent || IsInTransit) | ||
4931 | return; | ||
4932 | |||
4933 | |||
4934 | PrimUpdateFlags flag; | ||
4935 | switch (part.UpdateFlag) | ||
4936 | { | ||
4937 | case UpdateRequired.TERSE: | ||
4938 | flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | ||
4939 | | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity; | ||
4940 | break; | ||
4941 | |||
4942 | case UpdateRequired.FULL: | ||
4943 | flag = PrimUpdateFlags.FullUpdate; | ||
4944 | break; | ||
4945 | |||
4946 | default: | ||
4947 | return; | ||
4948 | } | ||
4949 | |||
4950 | part.UpdateFlag = 0; | ||
4951 | |||
4952 | ControllingClient.SendEntityUpdate(part, flag); | ||
4953 | |||
4954 | if (part.ParentGroup.HasPrivateAttachmentPoint) | ||
4955 | return; | ||
4956 | |||
4957 | List<ScenePresence> allPresences = m_scene.GetScenePresences(); | ||
4958 | foreach (ScenePresence p in allPresences) | ||
4959 | { | ||
4960 | if (p == this) | ||
4961 | continue; | ||
4962 | |||
4963 | if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
4964 | continue; | ||
4965 | |||
4966 | p.ControllingClient.SendEntityUpdate(part, flag); | ||
4967 | } | ||
4968 | } | ||
4969 | |||
4970 | |||
4971 | public void SendAttachmentUpdate(SceneObjectPart part, UpdateRequired UpdateFlag) | ||
4972 | { | ||
4973 | if (IsChildAgent || IsInTransit) | ||
4974 | return; | ||
4975 | |||
4976 | PrimUpdateFlags flag; | ||
4977 | switch (UpdateFlag) | ||
4978 | { | ||
4979 | case UpdateRequired.TERSE: | ||
4980 | flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | ||
4981 | | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity; | ||
4982 | break; | ||
4983 | |||
4984 | case UpdateRequired.FULL: | ||
4985 | flag = PrimUpdateFlags.FullUpdate; | ||
4986 | break; | ||
4987 | |||
4988 | default: | ||
4989 | return; | ||
4990 | } | ||
4991 | |||
4992 | // part.UpdateFlag = 0; | ||
4993 | |||
4994 | ControllingClient.SendEntityUpdate(part, flag); | ||
4995 | |||
4996 | if (part.ParentGroup.HasPrivateAttachmentPoint) | ||
4997 | return; | ||
4998 | |||
4999 | List<ScenePresence> allPresences = m_scene.GetScenePresences(); | ||
5000 | foreach (ScenePresence p in allPresences) | ||
5001 | { | ||
5002 | if (p == this) | ||
5003 | continue; | ||
5004 | if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) | ||
5005 | continue; | ||
5006 | |||
5007 | p.ControllingClient.SendEntityUpdate(part, flag); | ||
5008 | } | ||
5009 | } | ||
5010 | |||
4036 | /// <summary> | 5011 | /// <summary> |
4037 | /// Send a script event to this scene presence's attachments | 5012 | /// Send a script event to this scene presence's attachments |
4038 | /// </summary> | 5013 | /// </summary> |
@@ -4151,6 +5126,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
4151 | ControllingClient.SendTakeControls(int.MaxValue, false, false); | 5126 | ControllingClient.SendTakeControls(int.MaxValue, false, false); |
4152 | } | 5127 | } |
4153 | 5128 | ||
5129 | public void ClearControls() | ||
5130 | { | ||
5131 | IgnoredControls = ScriptControlled.CONTROL_ZERO; | ||
5132 | lock (scriptedcontrols) | ||
5133 | { | ||
5134 | scriptedcontrols.Clear(); | ||
5135 | } | ||
5136 | } | ||
5137 | |||
4154 | private void UnRegisterSeatControls(UUID obj) | 5138 | private void UnRegisterSeatControls(UUID obj) |
4155 | { | 5139 | { |
4156 | List<UUID> takers = new List<UUID>(); | 5140 | List<UUID> takers = new List<UUID>(); |
@@ -4540,8 +5524,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4540 | pos = land.LandData.UserLocation; | 5524 | pos = land.LandData.UserLocation; |
4541 | } | 5525 | } |
4542 | } | 5526 | } |
4543 | 5527 | // this is now done in completeMovement for all cases and not just this | |
4544 | land.SendLandUpdateToClient(ControllingClient); | 5528 | // land.SendLandUpdateToClient(ControllingClient); |
4545 | } | 5529 | } |
4546 | } | 5530 | } |
4547 | 5531 | ||
@@ -4556,6 +5540,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4556 | detobj.velVector = obj.Velocity; | 5540 | detobj.velVector = obj.Velocity; |
4557 | detobj.colliderType = 0; | 5541 | detobj.colliderType = 0; |
4558 | detobj.groupUUID = obj.GroupID; | 5542 | detobj.groupUUID = obj.GroupID; |
5543 | detobj.linkNumber = 0; | ||
4559 | 5544 | ||
4560 | return detobj; | 5545 | return detobj; |
4561 | } | 5546 | } |
@@ -4571,6 +5556,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4571 | detobj.velVector = av.Velocity; | 5556 | detobj.velVector = av.Velocity; |
4572 | detobj.colliderType = 0; | 5557 | detobj.colliderType = 0; |
4573 | detobj.groupUUID = av.ControllingClient.ActiveGroupId; | 5558 | detobj.groupUUID = av.ControllingClient.ActiveGroupId; |
5559 | detobj.linkNumber = 0; | ||
4574 | 5560 | ||
4575 | return detobj; | 5561 | return detobj; |
4576 | } | 5562 | } |
@@ -4586,7 +5572,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4586 | detobj.velVector = Vector3.Zero; | 5572 | detobj.velVector = Vector3.Zero; |
4587 | detobj.colliderType = 0; | 5573 | detobj.colliderType = 0; |
4588 | detobj.groupUUID = UUID.Zero; | 5574 | detobj.groupUUID = UUID.Zero; |
4589 | 5575 | detobj.linkNumber = 0; | |
4590 | return detobj; | 5576 | return detobj; |
4591 | } | 5577 | } |
4592 | 5578 | ||
@@ -4678,6 +5664,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4678 | 5664 | ||
4679 | else | 5665 | else |
4680 | { | 5666 | { |
5667 | bool candoparcelSound = ParcelAllowThisAvatarSounds; | ||
5668 | |||
4681 | foreach (uint id in coldata.Keys) | 5669 | foreach (uint id in coldata.Keys) |
4682 | { | 5670 | { |
4683 | thisHitColliders.Add(id); | 5671 | thisHitColliders.Add(id); |
@@ -4685,7 +5673,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4685 | { | 5673 | { |
4686 | startedColliders.Add(id); | 5674 | startedColliders.Add(id); |
4687 | curcontact = coldata[id]; | 5675 | curcontact = coldata[id]; |
4688 | if (Math.Abs(curcontact.RelativeSpeed) > 0.2) | 5676 | if (candoparcelSound && Math.Abs(curcontact.RelativeSpeed) > 0.2) |
4689 | { | 5677 | { |
4690 | soundinfo = new CollisionForSoundInfo(); | 5678 | soundinfo = new CollisionForSoundInfo(); |
4691 | soundinfo.colliderID = id; | 5679 | soundinfo.colliderID = id; |
@@ -4764,5 +5752,282 @@ namespace OpenSim.Region.Framework.Scenes | |||
4764 | m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); | 5752 | m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); |
4765 | 5753 | ||
4766 | } | 5754 | } |
5755 | |||
5756 | private void parcelGodCheck(UUID currentParcelID, bool isGod) | ||
5757 | { | ||
5758 | List<ScenePresence> allpresences = m_scene.GetScenePresences(); | ||
5759 | |||
5760 | foreach (ScenePresence p in allpresences) | ||
5761 | { | ||
5762 | if (p.IsDeleted || p.IsChildAgent || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5763 | continue; | ||
5764 | |||
5765 | if (p.ParcelHideThisAvatar && p.currentParcelUUID != currentParcelID) | ||
5766 | { | ||
5767 | if (isGod) | ||
5768 | p.SendViewTo(this); | ||
5769 | else | ||
5770 | p.SendKillTo(this); | ||
5771 | } | ||
5772 | } | ||
5773 | } | ||
5774 | |||
5775 | private void ParcelCrossCheck(UUID currentParcelID,UUID previusParcelID, | ||
5776 | bool currentParcelHide, bool previusParcelHide, bool oldhide,bool check) | ||
5777 | { | ||
5778 | List<ScenePresence> killsToSendto = new List<ScenePresence>(); | ||
5779 | List<ScenePresence> killsToSendme = new List<ScenePresence>(); | ||
5780 | List<ScenePresence> viewsToSendto = new List<ScenePresence>(); | ||
5781 | List<ScenePresence> viewsToSendme = new List<ScenePresence>(); | ||
5782 | List<ScenePresence> allpresences = null; | ||
5783 | |||
5784 | if (IsInTransit || IsChildAgent) | ||
5785 | return; | ||
5786 | |||
5787 | if (check) | ||
5788 | { | ||
5789 | // check is relative to current parcel only | ||
5790 | if (currentParcelUUID == null || oldhide == currentParcelHide) | ||
5791 | return; | ||
5792 | |||
5793 | allpresences = m_scene.GetScenePresences(); | ||
5794 | |||
5795 | if (oldhide) | ||
5796 | { // where private | ||
5797 | foreach (ScenePresence p in allpresences) | ||
5798 | { | ||
5799 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5800 | continue; | ||
5801 | |||
5802 | // those on not on parcel see me | ||
5803 | if (currentParcelID != p.currentParcelUUID) | ||
5804 | { | ||
5805 | viewsToSendto.Add(p); // they see me | ||
5806 | } | ||
5807 | } | ||
5808 | } // where private end | ||
5809 | |||
5810 | else | ||
5811 | { // where public | ||
5812 | foreach (ScenePresence p in allpresences) | ||
5813 | { | ||
5814 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5815 | continue; | ||
5816 | |||
5817 | // those not on parcel dont see me | ||
5818 | if (currentParcelID != p.currentParcelUUID && p.GodLevel < 200) | ||
5819 | { | ||
5820 | killsToSendto.Add(p); // they dont see me | ||
5821 | } | ||
5822 | } | ||
5823 | } // where public end | ||
5824 | |||
5825 | allpresences.Clear(); | ||
5826 | } | ||
5827 | else | ||
5828 | { | ||
5829 | if (currentParcelHide) | ||
5830 | { | ||
5831 | // now on a private parcel | ||
5832 | allpresences = m_scene.GetScenePresences(); | ||
5833 | |||
5834 | if (previusParcelHide && previusParcelID != UUID.Zero) | ||
5835 | { | ||
5836 | foreach (ScenePresence p in allpresences) | ||
5837 | { | ||
5838 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5839 | continue; | ||
5840 | |||
5841 | // only those on previus parcel need receive kills | ||
5842 | if (previusParcelID == p.currentParcelUUID) | ||
5843 | { | ||
5844 | if(p.GodLevel < 200) | ||
5845 | killsToSendto.Add(p); // they dont see me | ||
5846 | if(GodLevel < 200) | ||
5847 | killsToSendme.Add(p); // i dont see them | ||
5848 | } | ||
5849 | // only those on new parcel need see | ||
5850 | if (currentParcelID == p.currentParcelUUID) | ||
5851 | { | ||
5852 | viewsToSendto.Add(p); // they see me | ||
5853 | viewsToSendme.Add(p); // i see them | ||
5854 | } | ||
5855 | } | ||
5856 | } | ||
5857 | else | ||
5858 | { | ||
5859 | //was on a public area | ||
5860 | allpresences = m_scene.GetScenePresences(); | ||
5861 | |||
5862 | foreach (ScenePresence p in allpresences) | ||
5863 | { | ||
5864 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5865 | continue; | ||
5866 | |||
5867 | // those not on new parcel dont see me | ||
5868 | if (currentParcelID != p.currentParcelUUID && p.GodLevel < 200) | ||
5869 | { | ||
5870 | killsToSendto.Add(p); // they dont see me | ||
5871 | } | ||
5872 | else | ||
5873 | { | ||
5874 | viewsToSendme.Add(p); // i see those on it | ||
5875 | } | ||
5876 | } | ||
5877 | } | ||
5878 | allpresences.Clear(); | ||
5879 | } // now on a private parcel end | ||
5880 | |||
5881 | else | ||
5882 | { | ||
5883 | // now on public parcel | ||
5884 | if (previusParcelHide && previusParcelID != UUID.Zero) | ||
5885 | { | ||
5886 | // was on private area | ||
5887 | allpresences = m_scene.GetScenePresences(); | ||
5888 | |||
5889 | foreach (ScenePresence p in allpresences) | ||
5890 | { | ||
5891 | if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5892 | continue; | ||
5893 | // only those old parcel need kills | ||
5894 | if (previusParcelID == p.currentParcelUUID && GodLevel < 200) | ||
5895 | { | ||
5896 | killsToSendme.Add(p); // i dont see them | ||
5897 | } | ||
5898 | else | ||
5899 | { | ||
5900 | viewsToSendto.Add(p); // they see me | ||
5901 | } | ||
5902 | } | ||
5903 | } | ||
5904 | else | ||
5905 | return; // was on a public area also | ||
5906 | } // now on public parcel end | ||
5907 | } | ||
5908 | |||
5909 | // send the things | ||
5910 | |||
5911 | if (killsToSendto.Count > 0) | ||
5912 | { | ||
5913 | foreach (ScenePresence p in killsToSendto) | ||
5914 | { | ||
5915 | m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); | ||
5916 | SendKillTo(p); | ||
5917 | } | ||
5918 | } | ||
5919 | |||
5920 | if (killsToSendme.Count > 0) | ||
5921 | { | ||
5922 | foreach (ScenePresence p in killsToSendme) | ||
5923 | { | ||
5924 | m_log.Debug("[AVATAR]: killToMe: " + Lastname + " " + p.Lastname); | ||
5925 | p.SendKillTo(this); | ||
5926 | } | ||
5927 | } | ||
5928 | |||
5929 | if (viewsToSendto.Count > 0) | ||
5930 | { | ||
5931 | foreach (ScenePresence p in viewsToSendto) | ||
5932 | { | ||
5933 | SendViewTo(p); | ||
5934 | } | ||
5935 | } | ||
5936 | |||
5937 | if (viewsToSendme.Count > 0 ) | ||
5938 | { | ||
5939 | foreach (ScenePresence p in viewsToSendme) | ||
5940 | { | ||
5941 | if (p.IsChildAgent) | ||
5942 | continue; | ||
5943 | // m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname); | ||
5944 | p.SendViewTo(this); | ||
5945 | } | ||
5946 | } | ||
5947 | } | ||
5948 | |||
5949 | public void HasMovedAway(bool nearRegion) | ||
5950 | { | ||
5951 | |||
5952 | if (nearRegion) | ||
5953 | { | ||
5954 | if (Scene.AttachmentsModule != null) | ||
5955 | Scene.AttachmentsModule.DeleteAttachmentsFromScene(this, true); | ||
5956 | |||
5957 | if (!ParcelHideThisAvatar || GodLevel >= 200) | ||
5958 | return; | ||
5959 | |||
5960 | List<ScenePresence> allpresences = m_scene.GetScenePresences(); | ||
5961 | foreach (ScenePresence p in allpresences) | ||
5962 | { | ||
5963 | if (p.IsDeleted || p == this || p.IsChildAgent || p.ControllingClient == null || !p.ControllingClient.IsActive) | ||
5964 | continue; | ||
5965 | |||
5966 | if (p.currentParcelUUID == m_currentParcelUUID) | ||
5967 | { | ||
5968 | p.SendKillTo(this); | ||
5969 | } | ||
5970 | } | ||
5971 | } | ||
5972 | else | ||
5973 | { | ||
5974 | List<ScenePresence> allpresences = m_scene.GetScenePresences(); | ||
5975 | foreach (ScenePresence p in allpresences) | ||
5976 | { | ||
5977 | if (p == this) | ||
5978 | continue; | ||
5979 | SendKillTo(p); | ||
5980 | if (!p.IsChildAgent) | ||
5981 | p.SendKillTo(this); | ||
5982 | } | ||
5983 | |||
5984 | if (Scene.AttachmentsModule != null) | ||
5985 | Scene.AttachmentsModule.DeleteAttachmentsFromScene(this, true); | ||
5986 | } | ||
5987 | } | ||
5988 | |||
5989 | |||
5990 | // kill with attachs root kills | ||
5991 | public void SendKillTo(ScenePresence p) | ||
5992 | { | ||
5993 | List<uint> ids = new List<uint>(m_attachments.Count + 1); | ||
5994 | foreach (SceneObjectGroup sog in m_attachments) | ||
5995 | { | ||
5996 | ids.Add(sog.RootPart.LocalId); | ||
5997 | } | ||
5998 | |||
5999 | ids.Add(LocalId); | ||
6000 | p.ControllingClient.SendKillObject(ids); | ||
6001 | } | ||
6002 | |||
6003 | /* | ||
6004 | // kill with hack | ||
6005 | public void SendKillTo(ScenePresence p) | ||
6006 | { | ||
6007 | foreach (SceneObjectGroup sog in m_attachments) | ||
6008 | p.ControllingClient.SendPartFullUpdate(sog.RootPart, LocalId + 1); | ||
6009 | p.ControllingClient.SendKillObject(new List<uint> { LocalId }); | ||
6010 | } | ||
6011 | */ | ||
6012 | public void SendViewTo(ScenePresence p) | ||
6013 | { | ||
6014 | SendAvatarDataToAgentNF(p); | ||
6015 | SendAppearanceToAgent(p); | ||
6016 | if (Animator != null) | ||
6017 | Animator.SendAnimPackToClient(p.ControllingClient); | ||
6018 | SendAttachmentsToAgentNF(p); | ||
6019 | } | ||
6020 | |||
6021 | public void SetAnimationOverride(string animState, UUID animID) | ||
6022 | { | ||
6023 | Overrides.SetOverride(animState, animID); | ||
6024 | // Animator.SendAnimPack(); | ||
6025 | Animator.ForceUpdateMovementAnimations(); | ||
6026 | } | ||
6027 | |||
6028 | public UUID GetAnimationOverride(string animState) | ||
6029 | { | ||
6030 | return Overrides.GetOverriddenAnimation(animState); | ||
6031 | } | ||
4767 | } | 6032 | } |
4768 | } | 6033 | } |