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