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