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