aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
authoronefang2019-05-19 21:24:15 +1000
committeronefang2019-05-19 21:24:15 +1000
commit5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch)
treea9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Region/Framework/Scenes/ScenePresence.cs
parentAdd a build script. (diff)
downloadopensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs4969
1 files changed, 3336 insertions, 1633 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 1fddd91..74f765d 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -90,7 +90,26 @@ namespace OpenSim.Region.Framework.Scenes
90 m_scene.EventManager.TriggerScenePresenceUpdated(this); 90 m_scene.EventManager.TriggerScenePresenceUpdated(this);
91 } 91 }
92 92
93 public PresenceType PresenceType { get; private set; } 93 public bool IsNPC { get; private set; }
94
95 // simple yes or no isGOD from god level >= 200
96 // should only be set by GodController
97 // we have two to suport legacy behaviour
98 // IsViewerUIGod was controlled by viewer in older versions
99 // IsGod may now be also controled by viewer acording to options
100 public bool IsViewerUIGod { get; set; }
101 public bool IsGod { get; set; }
102
103 private PresenceType m_presenceType;
104 public PresenceType PresenceType
105 {
106 get {return m_presenceType;}
107 private set
108 {
109 m_presenceType = value;
110 IsNPC = (m_presenceType == PresenceType.Npc);
111 }
112 }
94 113
95 private ScenePresenceStateMachine m_stateMachine; 114 private ScenePresenceStateMachine m_stateMachine;
96 115
@@ -98,8 +117,8 @@ namespace OpenSim.Region.Framework.Scenes
98 /// The current state of this presence. Governs only the existence lifecycle. See ScenePresenceStateMachine 117 /// The current state of this presence. Governs only the existence lifecycle. See ScenePresenceStateMachine
99 /// for more details. 118 /// for more details.
100 /// </summary> 119 /// </summary>
101 public ScenePresenceState LifecycleState 120 public ScenePresenceState LifecycleState
102 { 121 {
103 get 122 get
104 { 123 {
105 return m_stateMachine.GetState(); 124 return m_stateMachine.GetState();
@@ -116,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes
116 /// the viewer fires these in quick succession. 135 /// the viewer fires these in quick succession.
117 /// </summary> 136 /// </summary>
118 /// <remarks> 137 /// <remarks>
119 /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement 138 /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement
120 /// regulation done there. 139 /// regulation done there.
121 /// </remarks> 140 /// </remarks>
122 private object m_completeMovementLock = new object(); 141 private object m_completeMovementLock = new object();
@@ -124,7 +143,7 @@ namespace OpenSim.Region.Framework.Scenes
124// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 143// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
125 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); 144 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
126 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); 145 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
127 146
128 /// <summary> 147 /// <summary>
129 /// Experimentally determined "fudge factor" to make sit-target positions 148 /// Experimentally determined "fudge factor" to make sit-target positions
130 /// the same as in SecondLife. Fudge factor was tested for 36 different 149 /// the same as in SecondLife. Fudge factor was tested for 36 different
@@ -134,21 +153,116 @@ namespace OpenSim.Region.Framework.Scenes
134 /// issue #1716 153 /// issue #1716
135 /// </summary> 154 /// </summary>
136 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f); 155 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
156 public bool LegacySitOffsets = true;
137 157
138 /// <summary> 158 /// <summary>
139 /// Movement updates for agents in neighboring regions are sent directly to clients. 159 /// Movement updates for agents in neighboring regions are sent directly to clients.
140 /// This value only affects how often agent positions are sent to neighbor regions 160 /// This value only affects how often agent positions are sent to neighbor regions
141 /// for things such as distance-based update prioritization 161 /// for things such as distance-based update prioritization
162 /// this are the square of real distances
142 /// </summary> 163 /// </summary>
143 public static readonly float SIGNIFICANT_MOVEMENT = 2.0f; 164 public static readonly float MOVEMENT = .25f;
165 public static readonly float SIGNIFICANT_MOVEMENT = 16.0f;
166 public static readonly float CHILDUPDATES_MOVEMENT = 100.0f;
167 public static readonly float CHILDUPDATES_TIME = 2000f; // min time between child updates (ms)
144 168
145 public UUID currentParcelUUID = UUID.Zero; 169 private UUID m_previusParcelUUID = UUID.Zero;
170 private UUID m_currentParcelUUID = UUID.Zero;
171 private bool m_previusParcelHide = false;
172 private bool m_currentParcelHide = false;
173 private object parcelLock = new Object();
174 public double ParcelDwellTickMS;
175
176 public UUID currentParcelUUID
177 {
178 get { return m_currentParcelUUID; }
179 set
180 {
181 lock (parcelLock)
182 {
183 bool oldhide = m_currentParcelHide;
184 bool checksame = true;
185 if (value != m_currentParcelUUID)
186 {
187 ParcelDwellTickMS = Util.GetTimeStampMS();
188 m_previusParcelHide = m_currentParcelHide;
189 m_previusParcelUUID = m_currentParcelUUID;
190 checksame = false;
191 }
192 m_currentParcelUUID = value;
193 m_currentParcelHide = false;
194
195 ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y);
196 if (land != null && !land.LandData.SeeAVs)
197 m_currentParcelHide = true;
198
199 if (m_previusParcelUUID != UUID.Zero || checksame)
200 ParcelCrossCheck(m_currentParcelUUID, m_previusParcelUUID, m_currentParcelHide, m_previusParcelHide, oldhide,checksame);
201 }
202 }
203 }
204
205 public void sitSOGmoved()
206 {
207/*
208 if (IsDeleted || !IsSatOnObject)
209 //what me? nahh
210 return;
211 if (IsInTransit)
212 return;
213
214 ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y);
215 if (land == null)
216 return; //??
217 UUID parcelID = land.LandData.GlobalID;
218 if (m_currentParcelUUID != parcelID)
219 currentParcelUUID = parcelID;
220*/
221 }
222
223 public bool ParcelAllowThisAvatarSounds
224 {
225 get
226 {
227 try
228 {
229 lock (parcelLock)
230 {
231 ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y);
232 if (land == null)
233 return true;
234 if (land.LandData.AnyAVSounds)
235 return true;
236 if (!land.LandData.GroupAVSounds)
237 return false;
238 return ControllingClient.IsGroupMember(land.LandData.GroupID);
239 }
240 }
241 catch
242 {
243 return true;
244 }
245 }
246 }
247
248 public bool ParcelHideThisAvatar
249 {
250 get
251 {
252 return m_currentParcelHide;
253 }
254 }
146 255
147 /// <value> 256 /// <value>
148 /// The animator for this avatar 257 /// The animator for this avatar
149 /// </value> 258 /// </value>
150 public ScenePresenceAnimator Animator { get; private set; } 259 public ScenePresenceAnimator Animator { get; private set; }
151 260
261 /// <value>
262 /// Server Side Animation Override
263 /// </value>
264 public MovementAnimationOverrides Overrides { get; private set; }
265 public String sitAnimation = "SIT";
152 /// <summary> 266 /// <summary>
153 /// Attachments recorded on this avatar. 267 /// Attachments recorded on this avatar.
154 /// </summary> 268 /// </summary>
@@ -164,21 +278,19 @@ namespace OpenSim.Region.Framework.Scenes
164 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; 278 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
165 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; 279 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
166 private bool MouseDown = false; 280 private bool MouseDown = false;
167// private SceneObjectGroup proxyObjectGroup;
168 //private SceneObjectPart proxyObjectPart = null;
169 public Vector3 lastKnownAllowedPosition; 281 public Vector3 lastKnownAllowedPosition;
170 public bool sentMessageAboutRestrictedParcelFlyingDown; 282 public bool sentMessageAboutRestrictedParcelFlyingDown;
283
171 public Vector4 CollisionPlane = Vector4.UnitW; 284 public Vector4 CollisionPlane = Vector4.UnitW;
172 285
286 public Vector4 m_lastCollisionPlane = Vector4.UnitW;
287 private byte m_lastState;
173 private Vector3 m_lastPosition; 288 private Vector3 m_lastPosition;
174 private Quaternion m_lastRotation; 289 private Quaternion m_lastRotation;
175 private Vector3 m_lastVelocity; 290 private Vector3 m_lastVelocity;
176 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); 291 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
292 private bool SentInitialData = false;
177 293
178 private bool m_followCamAuto = false;
179
180
181 private Vector3? m_forceToApply;
182 private int m_userFlags; 294 private int m_userFlags;
183 public int UserFlags 295 public int UserFlags
184 { 296 {
@@ -192,23 +304,14 @@ namespace OpenSim.Region.Framework.Scenes
192 set { PhysicsActor.Flying = value; } 304 set { PhysicsActor.Flying = value; }
193 } 305 }
194 306
195 // add for fly velocity control 307 public bool IsColliding
196 private bool FlyingOld {get; set;}
197 public bool WasFlying
198 {
199 get; private set;
200 }
201
202 public bool IsColliding
203 { 308 {
204 get { return PhysicsActor != null && PhysicsActor.IsColliding; } 309 get { return PhysicsActor != null && PhysicsActor.IsColliding; }
205 // We would expect setting IsColliding to be private but it's used by a hack in Scene 310 // We would expect setting IsColliding to be private but it's used by a hack in Scene
206 set { PhysicsActor.IsColliding = value; } 311 set { PhysicsActor.IsColliding = value; }
207 } 312 }
208 313
209// private int m_lastColCount = -1; //KF: Look for Collision chnages 314 private List<uint> m_lastColliders = new List<uint>();
210// private int m_updateCount = 0; //KF: Update Anims for a while
211// private static readonly int UPDATE_COUNT = 10; // how many frames to update for
212 315
213 private TeleportFlags m_teleportFlags; 316 private TeleportFlags m_teleportFlags;
214 public TeleportFlags TeleportFlags 317 public TeleportFlags TeleportFlags
@@ -233,9 +336,18 @@ namespace OpenSim.Region.Framework.Scenes
233 336
234 private float m_sitAvatarHeight = 2.0f; 337 private float m_sitAvatarHeight = 2.0f;
235 338
339 private bool m_childUpdatesBusy = false;
340 private int m_lastChildUpdatesTime;
341 private int m_lastChildAgentUpdateGodLevel;
342 private float m_lastChildAgentUpdateDrawDistance;
236 private Vector3 m_lastChildAgentUpdatePosition; 343 private Vector3 m_lastChildAgentUpdatePosition;
237// private Vector3 m_lastChildAgentUpdateCamPosition; 344// private Vector3 m_lastChildAgentUpdateCamPosition;
238 345
346 private Vector3 m_lastCameraRayCastCam;
347 private Vector3 m_lastCameraRayCastPos;
348
349 private float m_FOV = 1.04f;
350
239 private const int LAND_VELOCITYMAG_MAX = 12; 351 private const int LAND_VELOCITYMAG_MAX = 12;
240 352
241 private const float FLY_ROLL_MAX_RADIANS = 1.1f; 353 private const float FLY_ROLL_MAX_RADIANS = 1.1f;
@@ -244,32 +356,51 @@ namespace OpenSim.Region.Framework.Scenes
244 private const float FLY_ROLL_RESET_RADIANS_PER_UPDATE = 0.02f; 356 private const float FLY_ROLL_RESET_RADIANS_PER_UPDATE = 0.02f;
245 357
246 private float m_health = 100f; 358 private float m_health = 100f;
359 private float m_healRate = 1f;
360 private float m_healRatePerFrame = 0.05f;
247 361
248 protected ulong crossingFromRegion; 362 private readonly Vector3[] Dir_Vectors = new Vector3[12];
249 363
250 private readonly Vector3[] Dir_Vectors = new Vector3[11]; 364 protected int m_reprioritizationLastTime;
251 365 protected bool m_reprioritizationBusy;
252 protected Timer m_reprioritization_timer; 366 protected Vector3 m_reprioritizationLastPosition;
253 protected bool m_reprioritizing; 367 protected float m_reprioritizationLastDrawDistance;
254 protected bool m_reprioritization_called;
255 368
256 private Quaternion m_headrotation = Quaternion.Identity; 369 private Quaternion m_headrotation = Quaternion.Identity;
257 370
258 //PauPaw:Proper PID Controler for autopilot************ 371 //PauPaw:Proper PID Controler for autopilot************
259 public bool MovingToTarget { get; private set; } 372
260 public Vector3 MoveToPositionTarget { get; private set; } 373 private bool m_movingToTarget;
374 public bool MovingToTarget
375 {
376 get {return m_movingToTarget;}
377 private set {m_movingToTarget = value; }
378 }
379
380 private Vector3 m_moveToPositionTarget;
381 public Vector3 MoveToPositionTarget
382 {
383 get {return m_moveToPositionTarget;}
384 private set {m_moveToPositionTarget = value; }
385 }
386
387 private float m_moveToSpeed;
388 public float MoveToSpeed
389 {
390 get {return m_moveToSpeed;}
391 private set {m_moveToSpeed = value; }
392 }
393
394 private double m_delayedStop = -1.0;
261 395
262 /// <summary> 396 /// <summary>
263 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying). 397 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying).
264 /// </summary> 398 /// </summary>
265 public bool LandAtTarget { get; private set; } 399 public bool LandAtTarget { get; private set; }
266 400
267 private int m_movementUpdateCount;
268 private const int NumMovementsBetweenRayCast = 5;
269
270 private bool CameraConstraintActive; 401 private bool CameraConstraintActive;
271 //private int m_moveToPositionStateStatus; 402
272 //***************************************************** 403 private object m_collisionEventLock = new Object();
273 404
274 private int m_movementAnimationUpdateCounter = 0; 405 private int m_movementAnimationUpdateCounter = 0;
275 406
@@ -287,7 +418,6 @@ namespace OpenSim.Region.Framework.Scenes
287 } 418 }
288 } 419 }
289 420
290 public bool SentInitialDataToClient { get; private set; }
291 421
292 /// <summary> 422 /// <summary>
293 /// Copy of the script states while the agent is in transit. This state may 423 /// Copy of the script states while the agent is in transit. This state may
@@ -303,7 +433,7 @@ namespace OpenSim.Region.Framework.Scenes
303 /// <summary> 433 /// <summary>
304 /// Implemented Control Flags 434 /// Implemented Control Flags
305 /// </summary> 435 /// </summary>
306 private enum Dir_ControlFlags 436 private enum Dir_ControlFlags:uint
307 { 437 {
308 DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, 438 DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS,
309 DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, 439 DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG,
@@ -315,13 +445,15 @@ namespace OpenSim.Region.Framework.Scenes
315 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 445 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
316 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, 446 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
317 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, 447 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
448 DIR_CONTROL_FLAG_UP_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS,
318 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 449 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
319 } 450 }
320 451
321 /// <summary> 452 /// <summary>
322 /// Position at which a significant movement was made 453 /// Position at which a significant movement was made
323 /// </summary> 454 /// </summary>
324 private Vector3 posLastSignificantMove; 455 private Vector3 posLastSignificantMove;
456 private Vector3 posLastMove;
325 457
326 #region For teleports and crossings callbacks 458 #region For teleports and crossings callbacks
327 459
@@ -346,10 +478,7 @@ namespace OpenSim.Region.Framework.Scenes
346 /// </summary> 478 /// </summary>
347 private object m_originRegionIDAccessLock = new object(); 479 private object m_originRegionIDAccessLock = new object();
348 480
349 /// <summary> 481
350 /// Triggered on entity transfer after to allow CompleteMovement() to proceed after we have received an
351 /// UpdateAgent from the originating region.ddkjjkj
352 /// </summary>
353 private AutoResetEvent m_updateAgentReceivedAfterTransferEvent = new AutoResetEvent(false); 482 private AutoResetEvent m_updateAgentReceivedAfterTransferEvent = new AutoResetEvent(false);
354 483
355 /// <summary> 484 /// <summary>
@@ -366,6 +495,14 @@ namespace OpenSim.Region.Framework.Scenes
366 /// </value> 495 /// </value>
367 private IScriptModule[] m_scriptEngines; 496 private IScriptModule[] m_scriptEngines;
368 497
498 private enum LandingPointBehavior
499 {
500 OS = 1,
501 SL = 2
502 }
503
504 private LandingPointBehavior m_LandingPointBehavior = LandingPointBehavior.OS;
505
369 #region Properties 506 #region Properties
370 507
371 /// <summary> 508 /// <summary>
@@ -379,11 +516,6 @@ namespace OpenSim.Region.Framework.Scenes
379 public uint MovementFlag { get; private set; } 516 public uint MovementFlag { get; private set; }
380 517
381 /// <summary> 518 /// <summary>
382 /// Set this if we need to force a movement update on the next received AgentUpdate from the viewer.
383 /// </summary>
384 private const uint ForceUpdateMovementFlagValue = uint.MaxValue;
385
386 /// <summary>
387 /// Is the agent stop control flag currently active? 519 /// Is the agent stop control flag currently active?
388 /// </summary> 520 /// </summary>
389 public bool AgentControlStopActive { get; private set; } 521 public bool AgentControlStopActive { get; private set; }
@@ -396,28 +528,21 @@ namespace OpenSim.Region.Framework.Scenes
396 get { return m_invulnerable; } 528 get { return m_invulnerable; }
397 } 529 }
398 530
399 private int m_userLevel; 531 public GodController GodController { get; private set; }
400
401 public int UserLevel
402 {
403 get { return m_userLevel; }
404 private set { m_userLevel = value; }
405 }
406
407 private int m_godLevel;
408
409 public int GodLevel
410 {
411 get { return m_godLevel; }
412 private set { m_godLevel = value; }
413 }
414 532
415 private ulong m_rootRegionHandle; 533 private ulong m_rootRegionHandle;
534 private Vector3 m_rootRegionPosition = new Vector3();
416 535
417 public ulong RegionHandle 536 public ulong RegionHandle
418 { 537 {
419 get { return m_rootRegionHandle; } 538 get { return m_rootRegionHandle; }
420 private set { m_rootRegionHandle = value; } 539 private set
540 {
541 m_rootRegionHandle = value;
542 // position rounded to lower multiple of 256m
543 m_rootRegionPosition.X = (float)((m_rootRegionHandle >> 32) & 0xffffff00);
544 m_rootRegionPosition.Y = (float)(m_rootRegionHandle & 0xffffff00);
545 }
421 } 546 }
422 547
423 #region Client Camera 548 #region Client Camera
@@ -425,17 +550,13 @@ namespace OpenSim.Region.Framework.Scenes
425 /// <summary> 550 /// <summary>
426 /// Position of agent's camera in world (region cordinates) 551 /// Position of agent's camera in world (region cordinates)
427 /// </summary> 552 /// </summary>
428 protected Vector3 m_lastCameraPosition; 553// protected Vector3 m_lastCameraPosition;
429 554
430 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1); 555 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
431 private bool m_doingCamRayCast = false; 556 private bool m_doingCamRayCast = false;
432 557
433 public Vector3 CameraPosition { get; set; } 558 public Vector3 CameraPosition { get; set; }
434 559 public Quaternion CameraRotation { get; private set; }
435 public Quaternion CameraRotation
436 {
437 get { return Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis); }
438 }
439 560
440 // Use these three vectors to figure out what the agent is looking at 561 // Use these three vectors to figure out what the agent is looking at
441 // Convert it to a Matrix and/or Quaternion 562 // Convert it to a Matrix and/or Quaternion
@@ -449,39 +570,51 @@ namespace OpenSim.Region.Framework.Scenes
449 get 570 get
450 { 571 {
451 Vector3 a = new Vector3(CameraAtAxis.X, CameraAtAxis.Y, 0); 572 Vector3 a = new Vector3(CameraAtAxis.X, CameraAtAxis.Y, 0);
452 573 a.Normalize();
453 if (a == Vector3.Zero) 574 return a;
454 return a;
455
456 return Util.GetNormalizedVector(a);
457 } 575 }
458 } 576 }
459 #endregion 577 #endregion
460 578
461 public string Firstname { get; private set; } 579 public string Firstname { get; private set; }
462 public string Lastname { get; private set; } 580 public string Lastname { get; private set; }
463 581
582 public bool haveGroupInformation;
583 public bool gotCrossUpdate;
584 public byte crossingFlags;
585
464 public string Grouptitle 586 public string Grouptitle
465 { 587 {
466 get { return UseFakeGroupTitle ? "(Loading)" : m_groupTitle; } 588 get { return m_groupTitle; }
467 set { m_groupTitle = value; } 589 set { m_groupTitle = value; }
468 } 590 }
469 private string m_groupTitle; 591 private string m_groupTitle;
470 592
471 /// <summary>
472 /// When this is 'true', return a dummy group title instead of the real group title. This is
473 /// used as part of a hack to force viewers to update the displayed avatar name.
474 /// </summary>
475 public bool UseFakeGroupTitle { get; set; }
476
477
478 // Agent's Draw distance. 593 // Agent's Draw distance.
479 public float DrawDistance { get; set; } 594 private float m_drawDistance = 255f;
595 public float DrawDistance
596 {
597 get
598 {
599 return m_drawDistance;
600 }
601 set
602 {
603 m_drawDistance = Util.Clamp(value, 32f, m_scene.MaxDrawDistance);
604 }
605 }
606
607 public float RegionViewDistance
608 {
609 get
610 {
611 return Util.Clamp(m_drawDistance, 32f, m_scene.MaxRegionViewDistance);
612 }
613 }
480 614
481 public bool AllowMovement { get; set; } 615 public bool AllowMovement { get; set; }
482 616
483 private bool m_setAlwaysRun; 617 private bool m_setAlwaysRun;
484
485 public bool SetAlwaysRun 618 public bool SetAlwaysRun
486 { 619 {
487 get 620 get
@@ -557,12 +690,16 @@ namespace OpenSim.Region.Framework.Scenes
557 // in the sim unless the avatar is on a sit target. While 690 // in the sim unless the avatar is on a sit target. While
558 // on a sit target, m_pos will contain the desired offset 691 // on a sit target, m_pos will contain the desired offset
559 // without the parent rotation applied. 692 // without the parent rotation applied.
560 SceneObjectPart sitPart = ParentPart; 693 if (ParentPart != null)
561 694 {
562 if (sitPart != null) 695 SceneObjectPart rootPart = ParentPart.ParentGroup.RootPart;
563 return sitPart.ParentGroup.AbsolutePosition + (m_pos * sitPart.GetWorldRotation()); 696 // if (sitPart != null)
697 // return sitPart.AbsolutePosition + (m_pos * sitPart.GetWorldRotation());
698 if (rootPart != null)
699 return rootPart.AbsolutePosition + (m_pos * rootPart.GetWorldRotation());
700 }
564 } 701 }
565 702
566 return m_pos; 703 return m_pos;
567 } 704 }
568 set 705 set
@@ -614,11 +751,8 @@ namespace OpenSim.Region.Framework.Scenes
614 } 751 }
615 752
616 /// <summary> 753 /// <summary>
617 /// Velocity of the avatar with respect to its local reference frame. 754 /// Current velocity of the avatar.
618 /// </summary> 755 /// </summary>
619 /// <remarks>
620 /// So when sat on a vehicle this will be 0. To get velocity with respect to the world use GetWorldVelocity()
621 /// </remarks>
622 public override Vector3 Velocity 756 public override Vector3 Velocity
623 { 757 {
624 get 758 get
@@ -631,21 +765,12 @@ namespace OpenSim.Region.Framework.Scenes
631// "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!", 765// "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
632// m_velocity, Name, Scene.RegionInfo.RegionName); 766// m_velocity, Name, Scene.RegionInfo.RegionName);
633 } 767 }
634// else if (ParentPart != null)
635// {
636// return ParentPart.ParentGroup.Velocity;
637// }
638 768
639 return m_velocity; 769 return m_velocity;
640 } 770 }
641 771
642 set 772 set
643 { 773 {
644// Util.PrintCallStack();
645// m_log.DebugFormat(
646// "[SCENE PRESENCE]: In {0} set velocity of {1} to {2}",
647// Scene.RegionInfo.RegionName, Name, value);
648
649 if (PhysicsActor != null) 774 if (PhysicsActor != null)
650 { 775 {
651 try 776 try
@@ -658,27 +783,42 @@ namespace OpenSim.Region.Framework.Scenes
658 } 783 }
659 } 784 }
660 785
661 m_velocity = value; 786 m_velocity = value;
787
788// m_log.DebugFormat(
789// "[SCENE PRESENCE]: In {0} set velocity of {1} to {2}",
790// Scene.RegionInfo.RegionName, Name, m_velocity);
662 } 791 }
663 } 792 }
664/* 793
665 public override Vector3 AngularVelocity 794 // requested Velocity for physics engines avatar motors
795 // only makes sense if there is a physical rep
796 public Vector3 TargetVelocity
666 { 797 {
667 get 798 get
668 { 799 {
669 if (PhysicsActor != null) 800 if (PhysicsActor != null)
670 { 801 return PhysicsActor.TargetVelocity;
671 m_rotationalvelocity = PhysicsActor.RotationalVelocity; 802 else
803 return Vector3.Zero;
804 }
672 805
673 // m_log.DebugFormat( 806 set
674 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!", 807 {
675 // m_velocity, Name, Scene.RegionInfo.RegionName); 808 if (PhysicsActor != null)
809 {
810 try
811 {
812 PhysicsActor.TargetVelocity = value;
813 }
814 catch (Exception e)
815 {
816 m_log.Error("[SCENE PRESENCE]: TARGETVELOCITY " + e.Message);
817 }
676 } 818 }
677
678 return m_rotationalvelocity;
679 } 819 }
680 } 820 }
681*/ 821
682 private Quaternion m_bodyRot = Quaternion.Identity; 822 private Quaternion m_bodyRot = Quaternion.Identity;
683 823
684 /// <summary> 824 /// <summary>
@@ -691,9 +831,9 @@ namespace OpenSim.Region.Framework.Scenes
691 /// </remarks> 831 /// </remarks>
692 public Quaternion Rotation 832 public Quaternion Rotation
693 { 833 {
694 get 834 get
695 { 835 {
696 return m_bodyRot; 836 return m_bodyRot;
697 } 837 }
698 838
699 set 839 set
@@ -758,16 +898,42 @@ namespace OpenSim.Region.Framework.Scenes
758 set { m_health = value; } 898 set { m_health = value; }
759 } 899 }
760 900
901 public float HealRate
902 {
903 get { return m_healRate; }
904 set
905 {
906 if(value > 100.0f)
907 m_healRate = 100.0f;
908 else if (value <= 0.0)
909 m_healRate = 0.0f;
910 else
911 m_healRate = value;
912
913 if(Scene != null)
914 m_healRatePerFrame = m_healRate * Scene.FrameTime;
915 else
916 m_healRatePerFrame = 0.05f;
917 }
918 }
919
920
761 /// <summary> 921 /// <summary>
762 /// Get rotation relative to the world. 922 /// Gets the world rotation of this presence.
763 /// </summary> 923 /// </summary>
924 /// <remarks>
925 /// Unlike Rotation, this returns the world rotation no matter whether the avatar is sitting on a prim or not.
926 /// </remarks>
764 /// <returns></returns> 927 /// <returns></returns>
765 public Quaternion GetWorldRotation() 928 public Quaternion GetWorldRotation()
766 { 929 {
767 SceneObjectPart sitPart = ParentPart; 930 if (IsSatOnObject)
931 {
932 SceneObjectPart sitPart = ParentPart;
768 933
769 if (sitPart != null) 934 if (sitPart != null)
770 return sitPart.GetWorldRotation() * Rotation; 935 return sitPart.GetWorldRotation() * Rotation;
936 }
771 937
772 return Rotation; 938 return Rotation;
773 } 939 }
@@ -793,26 +959,7 @@ namespace OpenSim.Region.Framework.Scenes
793 seeds = Scene.CapsModule.GetChildrenSeeds(UUID); 959 seeds = Scene.CapsModule.GetChildrenSeeds(UUID);
794 else 960 else
795 seeds = new Dictionary<ulong, string>(); 961 seeds = new Dictionary<ulong, string>();
796
797 List<ulong> old = new List<ulong>();
798 foreach (ulong handle in seeds.Keys)
799 {
800 uint x, y;
801 Util.RegionHandleToRegionLoc(handle, out x, out y);
802
803 if (Util.IsOutsideView(DrawDistance, x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY))
804 {
805 old.Add(handle);
806 }
807 }
808 DropOldNeighbours(old);
809
810 if (Scene.CapsModule != null)
811 Scene.CapsModule.SetChildrenSeed(UUID, seeds);
812
813 KnownRegions = seeds; 962 KnownRegions = seeds;
814 //m_log.Debug(" ++++++++++AFTER+++++++++++++ ");
815 //DumpKnownRegions();
816 } 963 }
817 964
818 public void DumpKnownRegions() 965 public void DumpKnownRegions()
@@ -827,20 +974,20 @@ namespace OpenSim.Region.Framework.Scenes
827 } 974 }
828 975
829 private bool m_mouseLook; 976 private bool m_mouseLook;
830// private bool m_leftButtonDown; 977 private bool m_leftButtonDown;
831 978
832 private bool m_inTransit; 979 private bool m_inTransit;
833 980
834 /// <summary> 981 /// <summary>
835 /// This signals whether the presence is in transit between neighbouring regions. 982 /// This signals whether the presence is in transit between neighbouring regions.
836 /// </summary> 983 /// </summary>
837 /// <remarks> 984 /// <remarks>
838 /// It is not set when the presence is teleporting or logging in/out directly to a region. 985 /// It is not set when the presence is teleporting or logging in/out directly to a region.
839 /// </remarks> 986 /// </remarks>
840 public bool IsInTransit 987 public bool IsInTransit
841 { 988 {
842 get { return m_inTransit; } 989 get { return m_inTransit; }
843 set { 990 set {
844 if(value) 991 if(value)
845 { 992 {
846 if (Flying) 993 if (Flying)
@@ -851,14 +998,11 @@ namespace OpenSim.Region.Framework.Scenes
851 m_inTransit = value; 998 m_inTransit = value;
852 } 999 }
853 } 1000 }
1001 // this is is only valid if IsInTransit is true
1002 // only false on HG tps
1003 // used work arounf viewers asking source region about destination user
1004 public bool IsInLocalTransit {get; set; }
854 1005
855 private float m_speedModifier = 1.0f;
856
857 public float SpeedModifier
858 {
859 get { return m_speedModifier; }
860 set { m_speedModifier = value; }
861 }
862 1006
863 /// <summary> 1007 /// <summary>
864 /// Modifier for agent movement if we get an AGENT_CONTROL_STOP whilst walking or running 1008 /// Modifier for agent movement if we get an AGENT_CONTROL_STOP whilst walking or running
@@ -866,7 +1010,20 @@ namespace OpenSim.Region.Framework.Scenes
866 /// <remarks> 1010 /// <remarks>
867 /// AGENT_CONTRL_STOP comes about if user holds down space key on viewers. 1011 /// AGENT_CONTRL_STOP comes about if user holds down space key on viewers.
868 /// </remarks> 1012 /// </remarks>
869 private float AgentControlStopSlowWhilstMoving = 0.5f; 1013 private const float AgentControlStopSlowVel = 0.2f;
1014 // velocities
1015 public const float AgentControlNudgeVel = 1.0f; // setting this diferent from normal as no effect currently
1016 public const float AgentControlNormalVel = 1.0f;
1017
1018 // old normal speed was tuned to match sl normal plus Fast modifiers
1019 // so we need to rescale it
1020 private float m_speedModifier = 1.0f;
1021
1022 public float SpeedModifier
1023 {
1024 get { return m_speedModifier; }
1025 set { m_speedModifier = value; }
1026 }
870 1027
871 private bool m_forceFly; 1028 private bool m_forceFly;
872 1029
@@ -889,35 +1046,32 @@ namespace OpenSim.Region.Framework.Scenes
889 get { return Util.GetViewerName(m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode)); } 1046 get { return Util.GetViewerName(m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode)); }
890 } 1047 }
891 1048
892 /// <summary>
893 /// Count of how many terse updates we have sent out. It doesn't matter if this overflows.
894 /// </summary>
895 private int m_terseUpdateCount;
896
897 #endregion 1049 #endregion
898 1050
899 #region Constructor(s) 1051 #region Constructor(s)
900 1052
901 public ScenePresence( 1053 public ScenePresence(
902 IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) 1054 IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type)
903 { 1055 {
1056 m_scene = world;
904 AttachmentsSyncLock = new Object(); 1057 AttachmentsSyncLock = new Object();
905 AllowMovement = true; 1058 AllowMovement = true;
906 IsChildAgent = true; 1059 IsChildAgent = true;
907 IsLoggingIn = false; 1060 IsLoggingIn = false;
908 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 1061 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
909 Animator = new ScenePresenceAnimator(this); 1062 Animator = new ScenePresenceAnimator(this);
1063 Overrides = new MovementAnimationOverrides();
910 PresenceType = type; 1064 PresenceType = type;
911 // DrawDistance = world.DefaultDrawDistance; 1065 DrawDistance = world.DefaultDrawDistance;
912 DrawDistance = Constants.RegionSize;
913 RegionHandle = world.RegionInfo.RegionHandle; 1066 RegionHandle = world.RegionInfo.RegionHandle;
914 ControllingClient = client; 1067 ControllingClient = client;
915 Firstname = ControllingClient.FirstName; 1068 Firstname = ControllingClient.FirstName;
916 Lastname = ControllingClient.LastName; 1069 Lastname = ControllingClient.LastName;
917 m_name = String.Format("{0} {1}", Firstname, Lastname); 1070 m_name = String.Format("{0} {1}", Firstname, Lastname);
918 m_scene = world;
919 m_uuid = client.AgentId; 1071 m_uuid = client.AgentId;
920 LocalId = m_scene.AllocateLocalId(); 1072 LocalId = m_scene.AllocateLocalId();
1073 LegacySitOffsets = m_scene.LegacySitOffsets;
1074 IsInLocalTransit = true;
921 1075
922 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 1076 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
923 if (account != null) 1077 if (account != null)
@@ -925,32 +1079,52 @@ namespace OpenSim.Region.Framework.Scenes
925 else 1079 else
926 m_userFlags = 0; 1080 m_userFlags = 0;
927 1081
1082 int userlevel = 0;
928 if (account != null) 1083 if (account != null)
929 UserLevel = account.UserLevel; 1084 userlevel = account.UserLevel;
1085
1086 GodController = new GodController(world, this, userlevel);
930 1087
931 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); 1088 // IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
932 if (gm != null) 1089 // if (gm != null)
933 Grouptitle = gm.GetGroupTitle(m_uuid); 1090 // Grouptitle = gm.GetGroupTitle(m_uuid);
934 1091
935 m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); 1092 m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>();
936
937 AbsolutePosition = posLastSignificantMove = CameraPosition =
938 m_lastCameraPosition = ControllingClient.StartPos;
939 1093
940 m_reprioritization_timer = new Timer(world.ReprioritizationInterval); 1094 AbsolutePosition = posLastMove = posLastSignificantMove = CameraPosition =
941 m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); 1095 m_reprioritizationLastPosition = ControllingClient.StartPos;
942 m_reprioritization_timer.AutoReset = false; 1096
1097 m_reprioritizationLastDrawDistance = DrawDistance;
1098
1099 // disable updates workjobs for now
1100 m_childUpdatesBusy = true;
1101 m_reprioritizationBusy = true;
943 1102
944 AdjustKnownSeeds(); 1103 AdjustKnownSeeds();
945 1104
946 RegisterToEvents(); 1105 RegisterToClientEvents();
947 SetDirectionVectors(); 1106 SetDirectionVectors();
948 1107
949 Appearance = appearance; 1108 Appearance = appearance;
950 1109
951 m_stateMachine = new ScenePresenceStateMachine(this); 1110 m_stateMachine = new ScenePresenceStateMachine(this);
1111
1112 HealRate = 0.5f;
1113
1114 IConfig sconfig = m_scene.Config.Configs["EntityTransfer"];
1115 if (sconfig != null)
1116 {
1117 string lpb = sconfig.GetString("LandingPointBehavior", "LandingPointBehavior_OS");
1118 if (lpb == "LandingPointBehavior_SL")
1119 m_LandingPointBehavior = LandingPointBehavior.SL;
1120 }
1121
1122 ControllingClient.RefreshGroupMembership();
1123
952 } 1124 }
953 1125
1126 private float lastHealthSent = 0;
1127
954 private void RegionHeartbeatEnd(Scene scene) 1128 private void RegionHeartbeatEnd(Scene scene)
955 { 1129 {
956 if (IsChildAgent) 1130 if (IsChildAgent)
@@ -973,12 +1147,29 @@ namespace OpenSim.Region.Framework.Scenes
973 } 1147 }
974 else 1148 else
975 { 1149 {
976 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; 1150// m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1151 }
1152 }
1153
1154 if(m_healRatePerFrame != 0f && Health != 100.0f)
1155 {
1156 float last = Health;
1157 Health += m_healRatePerFrame;
1158 if(Health > 100.0f)
1159 {
1160 Health = 100.0f;
1161 lastHealthSent = Health;
1162 ControllingClient.SendHealth(Health);
1163 }
1164 else if(Math.Abs(Health - lastHealthSent) > 1.0)
1165 {
1166 lastHealthSent = Health;
1167 ControllingClient.SendHealth(Health);
977 } 1168 }
978 } 1169 }
979 } 1170 }
980 1171
981 public void RegisterToEvents() 1172 public void RegisterToClientEvents()
982 { 1173 {
983 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 1174 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
984 ControllingClient.OnAgentUpdate += HandleAgentUpdate; 1175 ControllingClient.OnAgentUpdate += HandleAgentUpdate;
@@ -988,28 +1179,48 @@ namespace OpenSim.Region.Framework.Scenes
988 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 1179 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
989 ControllingClient.OnStartAnim += HandleStartAnim; 1180 ControllingClient.OnStartAnim += HandleStartAnim;
990 ControllingClient.OnStopAnim += HandleStopAnim; 1181 ControllingClient.OnStopAnim += HandleStopAnim;
1182 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
991 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 1183 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
992 ControllingClient.OnAutoPilotGo += MoveToTarget; 1184 ControllingClient.OnAutoPilotGo += MoveToTargetHandle;
1185 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
1186// ControllingClient.OnAgentFOV += HandleAgentFOV;
993 1187
994 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 1188 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
995 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 1189 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
996 } 1190 }
997 1191
998 private void SetDirectionVectors() 1192 public void RemoveClientEvents()
999 { 1193 {
1000 Dir_Vectors[0] = Vector3.UnitX; //FORWARD 1194 ControllingClient.OnCompleteMovementToRegion -= CompleteMovement;
1001 Dir_Vectors[1] = -Vector3.UnitX; //BACK 1195 ControllingClient.OnAgentUpdate -= HandleAgentUpdate;
1002 Dir_Vectors[2] = Vector3.UnitY; //LEFT 1196 ControllingClient.OnAgentCameraUpdate -= HandleAgentCamerasUpdate;
1003 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 1197 ControllingClient.OnAgentRequestSit -= HandleAgentRequestSit;
1004 Dir_Vectors[4] = Vector3.UnitZ; //UP 1198 ControllingClient.OnAgentSit -= HandleAgentSit;
1005 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 1199 ControllingClient.OnSetAlwaysRun -= HandleSetAlwaysRun;
1006 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE 1200 ControllingClient.OnStartAnim -= HandleStartAnim;
1007 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE 1201 ControllingClient.OnStopAnim -= HandleStopAnim;
1008 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE 1202 ControllingClient.OnChangeAnim -= avnHandleChangeAnim;
1009 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE 1203 ControllingClient.OnForceReleaseControls -= HandleForceReleaseControls;
1010 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 1204 ControllingClient.OnAutoPilotGo -= MoveToTargetHandle;
1205 ControllingClient.OnUpdateThrottles -= RaiseUpdateThrottles;
1206// ControllingClient.OnAgentFOV += HandleAgentFOV;
1011 } 1207 }
1012 1208
1209 private void SetDirectionVectors()
1210 {
1211 Dir_Vectors[0] = new Vector3(AgentControlNormalVel,0,0); //FORWARD
1212 Dir_Vectors[1] = new Vector3(-AgentControlNormalVel,0,0);; //BACK
1213 Dir_Vectors[2] = new Vector3(0,AgentControlNormalVel,0); //LEFT
1214 Dir_Vectors[3] = new Vector3(0,-AgentControlNormalVel,0); //RIGHT
1215 Dir_Vectors[4] = new Vector3(0,0,AgentControlNormalVel); //UP
1216 Dir_Vectors[5] = new Vector3(0,0,-AgentControlNormalVel); //DOWN
1217 Dir_Vectors[6] = new Vector3(AgentControlNudgeVel, 0f, 0f); //FORWARD_NUDGE
1218 Dir_Vectors[7] = new Vector3(-AgentControlNudgeVel, 0f, 0f); //BACK_NUDGE
1219 Dir_Vectors[8] = new Vector3(0f, AgentControlNudgeVel, 0f); //LEFT_NUDGE
1220 Dir_Vectors[9] = new Vector3(0f, -AgentControlNudgeVel, 0f); //RIGHT_NUDGE
1221 Dir_Vectors[10] = new Vector3(0f, 0f, AgentControlNudgeVel); //UP_Nudge
1222 Dir_Vectors[11] = new Vector3(0f, 0f, -AgentControlNudgeVel); //DOWN_Nudge
1223 }
1013 #endregion 1224 #endregion
1014 1225
1015 #region Status Methods 1226 #region Status Methods
@@ -1026,18 +1237,29 @@ namespace OpenSim.Region.Framework.Scenes
1026 /// This method is on the critical path for transferring an avatar from one region to another. Delay here 1237 /// This method is on the critical path for transferring an avatar from one region to another. Delay here
1027 /// delays that crossing. 1238 /// delays that crossing.
1028 /// </remarks> 1239 /// </remarks>
1029 private bool MakeRootAgent(Vector3 pos, bool isFlying) 1240
1241 // constants for physics position search
1242 const float PhysSearchHeight = 600f;
1243 const float PhysMinSkipGap = 50f;
1244 const int PhysNumberCollisions = 30;
1245
1246 // only in use as part of completemovement
1247 // other uses need fix
1248 private bool MakeRootAgent(Vector3 pos, bool isFlying, ref Vector3 lookat)
1030 { 1249 {
1250 //int ts = Util.EnvironmentTickCount();
1251
1031 lock (m_completeMovementLock) 1252 lock (m_completeMovementLock)
1032 { 1253 {
1033 if (!IsChildAgent) 1254 if (!IsChildAgent)
1034 return false; 1255 return false;
1035 1256
1257 //m_log.DebugFormat("[MakeRootAgent] enter lock: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1036 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 1258 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
1037 1259
1038 // m_log.InfoFormat( 1260 // m_log.InfoFormat(
1039 // "[SCENE]: Upgrading child to root agent for {0} in {1}", 1261 // "[SCENE]: Upgrading child to root agent for {0} in {1}",
1040 // Name, m_scene.RegionInfo.RegionName); 1262 // Name, m_scene.RegionInfo.RegionName);
1041 1263
1042 if (ParentUUID != UUID.Zero) 1264 if (ParentUUID != UUID.Zero)
1043 { 1265 {
@@ -1046,20 +1268,33 @@ namespace OpenSim.Region.Framework.Scenes
1046 if (part == null) 1268 if (part == null)
1047 { 1269 {
1048 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); 1270 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1271 ParentID = 0;
1272 ParentPart = null;
1273 PrevSitOffset = Vector3.Zero;
1274 HandleForceReleaseControls(ControllingClient, UUID); // needs testing
1275 IsLoggingIn = false;
1049 } 1276 }
1050 else 1277 else
1051 { 1278 {
1052 part.AddSittingAvatar(this); 1279 part.AddSittingAvatar(this);
1053 // ParentPosition = part.GetWorldPosition(); 1280 // if not actually on the target invalidate it
1281 if(gotCrossUpdate && (crossingFlags & 0x04) == 0)
1282 part.SitTargetAvatar = UUID.Zero;
1283
1054 ParentID = part.LocalId; 1284 ParentID = part.LocalId;
1055 ParentPart = part; 1285 ParentPart = part;
1056 m_pos = PrevSitOffset; 1286 m_pos = PrevSitOffset;
1057 // pos = ParentPosition;
1058 pos = part.GetWorldPosition(); 1287 pos = part.GetWorldPosition();
1288 PhysicsActor partPhysActor = part.PhysActor;
1289 if(partPhysActor != null)
1290 {
1291 partPhysActor.OnPhysicsRequestingCameraData -=
1292 physActor_OnPhysicsRequestingCameraData;
1293 partPhysActor.OnPhysicsRequestingCameraData +=
1294 physActor_OnPhysicsRequestingCameraData;
1295 }
1059 } 1296 }
1060 ParentUUID = UUID.Zero; 1297 ParentUUID = UUID.Zero;
1061
1062 // Animator.TrySetMovementAnimation("SIT");
1063 } 1298 }
1064 else 1299 else
1065 { 1300 {
@@ -1069,135 +1304,144 @@ namespace OpenSim.Region.Framework.Scenes
1069 IsChildAgent = false; 1304 IsChildAgent = false;
1070 } 1305 }
1071 1306
1307 //m_log.DebugFormat("[MakeRootAgent] out lock: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1308
1072 // Must reset this here so that a teleport to a region next to an existing region does not keep the flag 1309 // Must reset this here so that a teleport to a region next to an existing region does not keep the flag
1073 // set and prevent the close of the connection on a subsequent re-teleport. 1310 // set and prevent the close of the connection on a subsequent re-teleport.
1074 // Should not be needed if we are not trying to tell this region to close 1311 // Should not be needed if we are not trying to tell this region to close
1075// DoNotCloseAfterTeleport = false; 1312 // DoNotCloseAfterTeleport = false;
1076
1077 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
1078 if (gm != null)
1079 Grouptitle = gm.GetGroupTitle(m_uuid);
1080
1081 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode);
1082 uint teleportFlags = (aCircuit == null) ? 0 : aCircuit.teleportFlags;
1083 if ((teleportFlags & (uint)TeleportFlags.ViaHGLogin) != 0)
1084 {
1085 // The avatar is arriving from another grid. This means that we may have changed the
1086 // avatar's name to or from the special Hypergrid format ("First.Last @grid.example.com").
1087 // Unfortunately, due to a viewer bug, viewers don't always show the new name.
1088 // But we have a trick that can force them to update the name anyway.
1089 ForceViewersUpdateName();
1090 }
1091 1313
1092 RegionHandle = m_scene.RegionInfo.RegionHandle; 1314 RegionHandle = m_scene.RegionInfo.RegionHandle;
1093 1315
1094 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1316 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
1317 //m_log.DebugFormat("[MakeRootAgent] TriggerSetRootAgentScene: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1095 1318
1096 UUID groupUUID = ControllingClient.ActiveGroupId; 1319 if (ParentID == 0)
1097 string groupName = string.Empty;
1098 ulong groupPowers = 0;
1099
1100 // ----------------------------------
1101 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1102 try
1103 { 1320 {
1104 if (groupUUID != UUID.Zero && gm != null) 1321 bool positionChanged = false;
1105 { 1322 bool success = true;
1106 GroupRecord record = gm.GetGroupRecord(groupUUID); 1323 if (m_LandingPointBehavior == LandingPointBehavior.OS)
1107 if (record != null) 1324 success = CheckAndAdjustLandingPoint_OS(ref pos, ref lookat, ref positionChanged);
1108 groupName = record.GroupName; 1325 else
1326 success = CheckAndAdjustLandingPoint_SL(ref pos, ref lookat, ref positionChanged);
1109 1327
1110 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid); 1328 if (!success)
1329 m_log.DebugFormat("[SCENE PRESENCE MakeRootAgent]: houston we have a problem.. {0} ({1} got banned)", Name, UUID);
1111 1330
1112 if (groupMembershipData != null) 1331 if (pos.X < 0f || pos.Y < 0f
1113 groupPowers = groupMembershipData.GroupPowers; 1332 || pos.X >= m_scene.RegionInfo.RegionSizeX
1333 || pos.Y >= m_scene.RegionInfo.RegionSizeY)
1334 {
1335 m_log.WarnFormat(
1336 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1337 pos, Name, UUID);
1338
1339 if (pos.X < 0f)
1340 pos.X = 0.5f;
1341 else if(pos.X >= m_scene.RegionInfo.RegionSizeX)
1342 pos.X = m_scene.RegionInfo.RegionSizeX - 0.5f;
1343 if (pos.Y < 0f)
1344 pos.Y = 0.5f;
1345 else if(pos.Y >= m_scene.RegionInfo.RegionSizeY)
1346 pos.Y = m_scene.RegionInfo.RegionSizeY - 0.5f;
1114 } 1347 }
1115 1348
1116 ControllingClient.SendAgentDataUpdate( 1349 float groundHeight = m_scene.GetGroundHeight(pos.X, pos.Y) + .01f;
1117 m_uuid, groupUUID, Firstname, Lastname, groupPowers, groupName, Grouptitle); 1350 float physTestHeight;
1118 }
1119 catch (Exception e)
1120 {
1121 m_log.Error("[AGENTUPDATE]: Error ", e);
1122 }
1123 // ------------------------------------
1124 1351
1125 if (ParentID == 0) 1352 if(PhysSearchHeight < groundHeight + 100f)
1126 { 1353 physTestHeight = groundHeight + 100f;
1127 // Moved this from SendInitialData to ensure that Appearance is initialized 1354 else
1128 // before the inventory is processed in MakeRootAgent. This fixes a race condition 1355 physTestHeight = PhysSearchHeight;
1129 // related to the handling of attachments
1130 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1131 1356
1132 /* RA 20140111: Commented out these TestBorderCross's. 1357 float localAVHalfHeight = 0.8f;
1133 * Not sure why this code is here. It is not checking all the borders 1358 if (Appearance != null && Appearance.AvatarHeight > 0)
1134 * and 'in region' sanity checking is done in CheckAndAdjustLandingPoint and below. 1359 localAVHalfHeight = 0.5f * Appearance.AvatarHeight;
1135 if (m_scene.TestBorderCross(pos, Cardinals.E))
1136 {
1137 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1138 pos.X = crossedBorder.BorderLine.Z - 1;
1139 }
1140 1360
1141 if (m_scene.TestBorderCross(pos, Cardinals.N)) 1361 groundHeight += localAVHalfHeight;
1142 { 1362 if (groundHeight > pos.Z)
1143 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1363 pos.Z = groundHeight;
1144 pos.Y = crossedBorder.BorderLine.Z - 1;
1145 }
1146 */
1147 1364
1148 CheckAndAdjustLandingPoint(ref pos); 1365 bool checkPhysics = !positionChanged &&
1366 m_scene.SupportsRayCastFiltered() &&
1367 pos.Z < physTestHeight &&
1368 ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
1369 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)
1370 || (m_teleportFlags & TeleportFlags.ViaLocation) != 0
1371 || (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0);
1149 1372
1150 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1373 if(checkPhysics)
1151 { 1374 {
1152 m_log.WarnFormat( 1375 // land check was done above
1153 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1376 RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull;
1154 pos, Name, UUID); 1377 rayfilter |= RayFilterFlags.PrimsNonPhantomAgents;
1155 1378
1156 if (pos.X < 0f) pos.X = 0f; 1379 int physcount = PhysNumberCollisions;
1157 if (pos.Y < 0f) pos.Y = 0f;
1158 if (pos.Z < 0f) pos.Z = 0f;
1159 }
1160 1380
1161 float localAVHeight = 1.56f; 1381 float dist = physTestHeight - groundHeight + localAVHalfHeight;
1162 if (Appearance.AvatarHeight > 0)
1163 localAVHeight = Appearance.AvatarHeight;
1164 1382
1165 float posZLimit = 0; 1383 Vector3 direction = new Vector3(0f, 0f, -1f);
1384 Vector3 RayStart = pos;
1385 RayStart.Z = physTestHeight;
1166 1386
1167 if (pos.X < m_scene.RegionInfo.RegionSizeX && pos.Y < m_scene.RegionInfo.RegionSizeY) 1387 List<ContactResult> physresults =
1168 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1388 (List<ContactResult>)m_scene.RayCastFiltered(RayStart, direction, dist, physcount, rayfilter);
1169 1389 if (physresults != null && physresults.Count > 0)
1170 float newPosZ = posZLimit + localAVHeight / 2; 1390 {
1171 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 1391 float dest = physresults[0].Pos.Z;
1172 { 1392
1173 pos.Z = newPosZ; 1393 if(physresults.Count > 1)
1394 {
1395 physresults.Sort(delegate(ContactResult a, ContactResult b)
1396 {
1397 return a.Depth.CompareTo(b.Depth);
1398 });
1399
1400 int sel = 0;
1401 int count = physresults.Count;
1402 float curd = physresults[0].Depth;
1403 float nextd = curd + PhysMinSkipGap;
1404 float maxDepth = dist - pos.Z;
1405 for(int i = 1; i < count; i++)
1406 {
1407 curd = physresults[i].Depth;
1408 if(curd >= nextd)
1409 {
1410 sel = i;
1411 if(curd >= maxDepth)
1412 break;
1413 }
1414 nextd = curd + PhysMinSkipGap;
1415 }
1416 dest = physresults[sel].Pos.Z;
1417 }
1418
1419 dest += localAVHalfHeight;
1420 if(dest > pos.Z)
1421 pos.Z = dest;
1422 }
1174 } 1423 }
1424
1175 AbsolutePosition = pos; 1425 AbsolutePosition = pos;
1176 1426
1177// m_log.DebugFormat( 1427// m_log.DebugFormat(
1178// "Set pos {0}, vel {1} in {1} to {2} from input position of {3} on MakeRootAgent", 1428// "Set pos {0}, vel {1} in {1} to {2} from input position of {3} on MakeRootAgent",
1179// Name, Scene.Name, AbsolutePosition, pos); 1429// Name, Scene.Name, AbsolutePosition, pos);
1180// 1430//
1181 if (m_teleportFlags == TeleportFlags.Default) 1431 if (m_teleportFlags == TeleportFlags.Default)
1182 { 1432 {
1433 Vector3 vel = Velocity;
1183 AddToPhysicalScene(isFlying); 1434 AddToPhysicalScene(isFlying);
1184// 1435 if (PhysicsActor != null)
1185// Console.WriteLine( 1436 PhysicsActor.SetMomentum(vel);
1186// "Set velocity of {0} in {1} to {2} from input velocity of {3} on MakeRootAgent",
1187// Name, Scene.Name, PhysicsActor.Velocity, vel);
1188// }
1189 } 1437 }
1190 else 1438 else
1191 { 1439 {
1192 AddToPhysicalScene(isFlying); 1440 AddToPhysicalScene(isFlying);
1193 }
1194 1441
1195 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1442 // reset camera to avatar pos
1196 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it 1443 CameraPosition = pos;
1197 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset 1444 }
1198 // the value to a negative position which does not trigger the border cross.
1199 // This may not be the best location for this.
1200 CheckForBorderCrossing();
1201 1445
1202 if (ForceFly) 1446 if (ForceFly)
1203 { 1447 {
@@ -1209,53 +1453,16 @@ namespace OpenSim.Region.Framework.Scenes
1209 } 1453 }
1210 } 1454 }
1211 1455
1212 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1456 //m_log.DebugFormat("[MakeRootAgent] position and physical: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1213 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1214 // elsewhere anyway
1215 // Animator.SendAnimPack();
1216
1217 m_scene.SwapRootAgentCount(false); 1457 m_scene.SwapRootAgentCount(false);
1218 1458
1219 if (Scene.AttachmentsModule != null)
1220 {
1221 // The initial login scene presence is already root when it gets here
1222 // and it has already rezzed the attachments and started their scripts.
1223 // We do the following only for non-login agents, because their scripts
1224 // haven't started yet.
1225 if (PresenceType == PresenceType.Npc || IsRealLogin(m_teleportFlags))
1226 {
1227 WorkManager.RunJob(
1228 "RezAttachments",
1229 o => Scene.AttachmentsModule.RezAttachments(this),
1230 null,
1231 string.Format("Rez attachments for {0} in {1}", Name, Scene.Name));
1232 }
1233 else
1234 {
1235 WorkManager.RunJob(
1236 "StartAttachmentScripts",
1237 o => RestartAttachmentScripts(),
1238 null,
1239 string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name),
1240 true);
1241 }
1242 }
1243
1244 SendAvatarDataToAllClients();
1245
1246 // send the animations of the other presences to me
1247 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1248 {
1249 if (presence != this)
1250 presence.Animator.SendAnimPackToClient(ControllingClient);
1251 });
1252
1253 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1459 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1254 // stall on the border crossing since the existing child agent will still have the last movement 1460 // stall on the border crossing since the existing child agent will still have the last movement
1255 // recorded, which stops the input from being processed. 1461 // recorded, which stops the input from being processed.
1256 MovementFlag = ForceUpdateMovementFlagValue; 1462 MovementFlag = 0;
1257 1463
1258 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1464 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1465 //m_log.DebugFormat("[MakeRootAgent] TriggerOnMakeRootAgent and done: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1259 1466
1260 return true; 1467 return true;
1261 } 1468 }
@@ -1304,12 +1511,13 @@ namespace OpenSim.Region.Framework.Scenes
1304 /// Group Title. So the following trick makes viewers update the avatar's name by briefly changing 1511 /// Group Title. So the following trick makes viewers update the avatar's name by briefly changing
1305 /// the group title (to "(Loading)"), and then restoring it. 1512 /// the group title (to "(Loading)"), and then restoring it.
1306 /// </remarks> 1513 /// </remarks>
1514/*
1307 public void ForceViewersUpdateName() 1515 public void ForceViewersUpdateName()
1308 { 1516 {
1309 m_log.DebugFormat("[SCENE PRESENCE]: Forcing viewers to update the avatar name for " + Name); 1517 m_log.DebugFormat("[SCENE PRESENCE]: Forcing viewers to update the avatar name for " + Name);
1310 1518
1311 UseFakeGroupTitle = true; 1519 UseFakeGroupTitle = true;
1312 SendAvatarDataToAllClients(false); 1520
1313 1521
1314 Util.FireAndForget(o => 1522 Util.FireAndForget(o =>
1315 { 1523 {
@@ -1323,7 +1531,7 @@ namespace OpenSim.Region.Framework.Scenes
1323 SendAvatarDataToAllClients(false); 1531 SendAvatarDataToAllClients(false);
1324 }, null, "Scenepresence.ForceViewersUpdateName"); 1532 }, null, "Scenepresence.ForceViewersUpdateName");
1325 } 1533 }
1326 1534*/
1327 public int GetStateSource() 1535 public int GetStateSource()
1328 { 1536 {
1329 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID); 1537 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID);
@@ -1347,11 +1555,17 @@ namespace OpenSim.Region.Framework.Scenes
1347 /// It doesn't get called for a teleport. Reason being, an agent that 1555 /// It doesn't get called for a teleport. Reason being, an agent that
1348 /// teleports out may not end up anywhere near this region 1556 /// teleports out may not end up anywhere near this region
1349 /// </remarks> 1557 /// </remarks>
1350 public void MakeChildAgent() 1558 public void MakeChildAgent(ulong newRegionHandle)
1351 { 1559 {
1560 haveGroupInformation = false;
1561 gotCrossUpdate = false;
1562 crossingFlags = 0;
1352 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; 1563 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1353 1564
1354 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1565 RegionHandle = newRegionHandle;
1566
1567 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1} from root region {2}",
1568 Name, Scene.RegionInfo.RegionName, newRegionHandle);
1355 1569
1356 // Reset the m_originRegionID as it has dual use as a flag to signal that the UpdateAgent() call orignating 1570 // Reset the m_originRegionID as it has dual use as a flag to signal that the UpdateAgent() call orignating
1357 // from the source simulator has completed on a V2 teleport. 1571 // from the source simulator has completed on a V2 teleport.
@@ -1371,7 +1585,7 @@ namespace OpenSim.Region.Framework.Scenes
1371 else 1585 else
1372 Animator.ResetAnimations(); 1586 Animator.ResetAnimations();
1373 1587
1374 1588
1375// m_log.DebugFormat( 1589// m_log.DebugFormat(
1376// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1590// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1377// Name, UUID, m_scene.RegionInfo.RegionName); 1591// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1379,14 +1593,21 @@ namespace OpenSim.Region.Framework.Scenes
1379 // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing, 1593 // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing,
1380 // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated. 1594 // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated.
1381 //Velocity = new Vector3(0, 0, 0); 1595 //Velocity = new Vector3(0, 0, 0);
1382 1596
1383 IsChildAgent = true; 1597 IsChildAgent = true;
1384 m_scene.SwapRootAgentCount(true); 1598 m_scene.SwapRootAgentCount(true);
1385 RemoveFromPhysicalScene(); 1599 RemoveFromPhysicalScene();
1386 ParentID = 0; // Child agents can't be sitting 1600 ParentID = 0; // Child agents can't be sitting
1387 1601
1602// we dont have land information for child
1603 m_previusParcelHide = false;
1604 m_previusParcelUUID = UUID.Zero;
1605 m_currentParcelHide = false;
1606 m_currentParcelUUID = UUID.Zero;
1388 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1607 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1389 1608
1609 CollisionPlane = Vector4.UnitW;
1610
1390 m_scene.EventManager.TriggerOnMakeChildAgent(this); 1611 m_scene.EventManager.TriggerOnMakeChildAgent(this);
1391 } 1612 }
1392 1613
@@ -1398,9 +1619,10 @@ namespace OpenSim.Region.Framework.Scenes
1398 if (PhysicsActor != null) 1619 if (PhysicsActor != null)
1399 { 1620 {
1400// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1621// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1401 PhysicsActor.UnSubscribeEvents(); 1622
1402 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1623 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1403 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1624 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1625 PhysicsActor.UnSubscribeEvents();
1404 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1626 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1405 PhysicsActor = null; 1627 PhysicsActor = null;
1406 } 1628 }
@@ -1423,12 +1645,16 @@ namespace OpenSim.Region.Framework.Scenes
1423 1645
1424 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1646 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
1425 { 1647 {
1648 if(!CheckLocalTPLandingPoint(ref pos))
1649 return;
1650
1426 if (ParentID != (uint)0) 1651 if (ParentID != (uint)0)
1427 StandUp(); 1652 StandUp();
1653
1428 bool isFlying = Flying; 1654 bool isFlying = Flying;
1429 Vector3 vel = Velocity; 1655 Vector3 vel = Velocity;
1430 RemoveFromPhysicalScene(); 1656 RemoveFromPhysicalScene();
1431 CheckLandingPoint(ref pos); 1657
1432 AbsolutePosition = pos; 1658 AbsolutePosition = pos;
1433 AddToPhysicalScene(isFlying); 1659 AddToPhysicalScene(isFlying);
1434 if (PhysicsActor != null) 1660 if (PhysicsActor != null)
@@ -1438,11 +1664,29 @@ namespace OpenSim.Region.Framework.Scenes
1438 else 1664 else
1439 PhysicsActor.SetMomentum(vel); 1665 PhysicsActor.SetMomentum(vel);
1440 } 1666 }
1667
1668 SendTerseUpdateToAllClients();
1669 }
1670
1671 public void TeleportOnEject(Vector3 pos)
1672 {
1673 if (ParentID != (uint)0)
1674 StandUp();
1675
1676 bool isFlying = Flying;
1677 RemoveFromPhysicalScene();
1678
1679 AbsolutePosition = pos;
1680
1681 AddToPhysicalScene(isFlying);
1682 SendTerseUpdateToAllClients();
1441 } 1683 }
1442 1684
1443 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY) 1685 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1444 { 1686 {
1445 CheckLandingPoint(ref newpos); 1687 if(!CheckLocalTPLandingPoint(ref newpos))
1688 return;
1689
1446 AbsolutePosition = newpos; 1690 AbsolutePosition = newpos;
1447 1691
1448 if (newvel.HasValue) 1692 if (newvel.HasValue)
@@ -1469,11 +1713,15 @@ namespace OpenSim.Region.Framework.Scenes
1469 } 1713 }
1470 } 1714 }
1471 } 1715 }
1716 SendTerseUpdateToAllClients();
1472 } 1717 }
1473 1718
1474 public void StopFlying() 1719 public void StopFlying()
1475 { 1720 {
1476 Vector3 pos = AbsolutePosition; 1721 if (IsInTransit)
1722 return;
1723
1724 Vector3 pos = AbsolutePosition;
1477 if (Appearance.AvatarHeight != 127.0f) 1725 if (Appearance.AvatarHeight != 127.0f)
1478 pos += new Vector3(0f, 0f, (Appearance.AvatarHeight / 6f)); 1726 pos += new Vector3(0f, 0f, (Appearance.AvatarHeight / 6f));
1479 else 1727 else
@@ -1492,7 +1740,7 @@ namespace OpenSim.Region.Framework.Scenes
1492 else 1740 else
1493 CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f / 6f)); 1741 CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f / 6f));
1494 1742
1495 ControllingClient.SendAgentTerseUpdate(this); 1743 SendAgentTerseUpdate(this);
1496 } 1744 }
1497 1745
1498 /// <summary> 1746 /// <summary>
@@ -1501,7 +1749,7 @@ namespace OpenSim.Region.Framework.Scenes
1501 /// <param name="amount">Postive or negative roll amount in radians</param> 1749 /// <param name="amount">Postive or negative roll amount in radians</param>
1502 private void ApplyFlyingRoll(float amount, bool PressingUp, bool PressingDown) 1750 private void ApplyFlyingRoll(float amount, bool PressingUp, bool PressingDown)
1503 { 1751 {
1504 1752
1505 float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS); 1753 float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS);
1506 m_AngularVelocity.Z = rollAmount; 1754 m_AngularVelocity.Z = rollAmount;
1507 1755
@@ -1553,17 +1801,14 @@ namespace OpenSim.Region.Framework.Scenes
1553 1801
1554 if (m_AngularVelocity.Z > 0) 1802 if (m_AngularVelocity.Z > 0)
1555 { 1803 {
1556
1557 float leftOverToMin = m_AngularVelocity.Z - rollMinRadians; 1804 float leftOverToMin = m_AngularVelocity.Z - rollMinRadians;
1558 if (amount > leftOverToMin) 1805 if (amount > leftOverToMin)
1559 return -leftOverToMin; 1806 return -leftOverToMin;
1560 else 1807 else
1561 return -amount; 1808 return -amount;
1562
1563 } 1809 }
1564 else 1810 else
1565 { 1811 {
1566
1567 float leftOverToMin = -m_AngularVelocity.Z - rollMinRadians; 1812 float leftOverToMin = -m_AngularVelocity.Z - rollMinRadians;
1568 if (amount > leftOverToMin) 1813 if (amount > leftOverToMin)
1569 return leftOverToMin; 1814 return leftOverToMin;
@@ -1571,22 +1816,65 @@ namespace OpenSim.Region.Framework.Scenes
1571 return amount; 1816 return amount;
1572 } 1817 }
1573 } 1818 }
1574
1575
1576 1819
1577 // neighbouring regions we have enabled a child agent in 1820 // neighbouring regions we have enabled a child agent in
1578 // holds the seed cap for the child agent in that region 1821 // holds the seed cap for the child agent in that region
1579 private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>(); 1822 private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
1580 1823
1581 public void AddNeighbourRegion(ulong regionHandle, string cap) 1824 struct spRegionSizeInfo
1825 {
1826 public int sizeX;
1827 public int sizeY;
1828 }
1829
1830 private Dictionary<ulong, spRegionSizeInfo> m_knownChildRegionsSizeInfo = new Dictionary<ulong, spRegionSizeInfo>();
1831
1832 public void AddNeighbourRegion(GridRegion region, string capsPath)
1833 {
1834 lock (m_knownChildRegions)
1835 {
1836 ulong regionHandle = region.RegionHandle;
1837 m_knownChildRegions.Add(regionHandle,capsPath);
1838
1839 spRegionSizeInfo sizeInfo = new spRegionSizeInfo();
1840 sizeInfo.sizeX = region.RegionSizeX;
1841 sizeInfo.sizeY = region.RegionSizeY;
1842 m_knownChildRegionsSizeInfo[regionHandle] = sizeInfo;
1843 }
1844 }
1845
1846 public void AddNeighbourRegionSizeInfo(GridRegion region)
1847 {
1848 lock (m_knownChildRegions)
1849 {
1850 spRegionSizeInfo sizeInfo = new spRegionSizeInfo();
1851 sizeInfo.sizeX = region.RegionSizeX;
1852 sizeInfo.sizeY = region.RegionSizeY;
1853 ulong regionHandle = region.RegionHandle;
1854
1855 if (!m_knownChildRegionsSizeInfo.ContainsKey(regionHandle))
1856 {
1857 m_knownChildRegionsSizeInfo.Add(regionHandle, sizeInfo);
1858
1859 }
1860 else
1861 m_knownChildRegionsSizeInfo[regionHandle] = sizeInfo;
1862 }
1863 }
1864
1865 public void SetNeighbourRegionSizeInfo(List<GridRegion> regionsList)
1582 { 1866 {
1583 lock (m_knownChildRegions) 1867 lock (m_knownChildRegions)
1584 { 1868 {
1585 if (!m_knownChildRegions.ContainsKey(regionHandle)) 1869 m_knownChildRegionsSizeInfo.Clear();
1870
1871 foreach (GridRegion region in regionsList)
1586 { 1872 {
1587 uint x, y; 1873 spRegionSizeInfo sizeInfo = new spRegionSizeInfo();
1588 Utils.LongToUInts(regionHandle, out x, out y); 1874 sizeInfo.sizeX = region.RegionSizeX;
1589 m_knownChildRegions.Add(regionHandle, cap); 1875 sizeInfo.sizeY = region.RegionSizeY;
1876 ulong regionHandle = region.RegionHandle;
1877 m_knownChildRegionsSizeInfo.Add(regionHandle, sizeInfo);
1590 } 1878 }
1591 } 1879 }
1592 } 1880 }
@@ -1600,9 +1888,16 @@ namespace OpenSim.Region.Framework.Scenes
1600 //if (m_knownChildRegions.ContainsKey(regionHandle)) 1888 //if (m_knownChildRegions.ContainsKey(regionHandle))
1601 // m_log.DebugFormat(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); 1889 // m_log.DebugFormat(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count);
1602 m_knownChildRegions.Remove(regionHandle); 1890 m_knownChildRegions.Remove(regionHandle);
1891 m_knownChildRegionsSizeInfo.Remove(regionHandle);
1603 } 1892 }
1604 } 1893 }
1605 1894
1895 public bool knowsNeighbourRegion(ulong regionHandle)
1896 {
1897 lock (m_knownChildRegions)
1898 return m_knownChildRegions.ContainsKey(regionHandle);
1899 }
1900
1606 public void DropOldNeighbours(List<ulong> oldRegions) 1901 public void DropOldNeighbours(List<ulong> oldRegions)
1607 { 1902 {
1608 foreach (ulong handle in oldRegions) 1903 foreach (ulong handle in oldRegions)
@@ -1612,6 +1907,13 @@ namespace OpenSim.Region.Framework.Scenes
1612 } 1907 }
1613 } 1908 }
1614 1909
1910 public void DropThisRootRegionFromNeighbours()
1911 {
1912 ulong handle = m_scene.RegionInfo.RegionHandle;
1913 RemoveNeighbourRegion(handle);
1914 Scene.CapsModule.DropChildSeed(UUID, handle);
1915 }
1916
1615 public Dictionary<ulong, string> KnownRegions 1917 public Dictionary<ulong, string> KnownRegions
1616 { 1918 {
1617 get 1919 get
@@ -1632,7 +1934,8 @@ namespace OpenSim.Region.Framework.Scenes
1632 { 1934 {
1633 get 1935 get
1634 { 1936 {
1635 return new List<ulong>(KnownRegions.Keys); 1937 lock (m_knownChildRegions)
1938 return new List<ulong>(m_knownChildRegions.Keys);
1636 } 1939 }
1637 } 1940 }
1638 1941
@@ -1662,35 +1965,66 @@ namespace OpenSim.Region.Framework.Scenes
1662 public void SetSize(Vector3 size, float feetoffset) 1965 public void SetSize(Vector3 size, float feetoffset)
1663 { 1966 {
1664 if (PhysicsActor != null && !IsChildAgent) 1967 if (PhysicsActor != null && !IsChildAgent)
1665 { 1968 PhysicsActor.setAvatarSize(size, feetoffset);
1666 // Eventually there will be a physics call that sets avatar size that includes offset info.
1667 // For the moment, just set the size as passed.
1668 PhysicsActor.Size = size;
1669 // PhysicsActor.setAvatarSize(size, feetoffset);
1670 }
1671 } 1969 }
1672 1970
1673 private bool WaitForUpdateAgent(IClientAPI client) 1971 private bool WaitForUpdateAgent(IClientAPI client)
1674 { 1972 {
1675 // Before the source region executes UpdateAgent 1973 // Before the source region executes UpdateAgent
1676 // (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination, 1974 // (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination,
1677 // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the 1975 // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the
1678 // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero 1976 // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero
1679 m_updateAgentReceivedAfterTransferEvent.WaitOne(10000);
1680 1977
1681 UUID originID = UUID.Zero; 1978 try
1979 {
1980 if(m_updateAgentReceivedAfterTransferEvent.WaitOne(10000))
1981 {
1982 UUID originID = UUID.Zero;
1682 1983
1683 lock (m_originRegionIDAccessLock) 1984 lock (m_originRegionIDAccessLock)
1684 originID = m_originRegionID; 1985 originID = m_originRegionID;
1986 if (originID.Equals(UUID.Zero))
1987 {
1988 // Movement into region will fail
1989 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} at {1} got invalid origin region id ", client.Name, Scene.Name);
1990 return false;
1991 }
1992 return true;
1993 }
1994 else
1995 {
1996 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} at {1} did not receive agent update ", client.Name, Scene.Name);
1997 return false;
1998 }
1999 }
2000 catch { }
1685 2001
1686 if (originID.Equals(UUID.Zero)) 2002 return false;
2003 }
2004
2005 public void RotateToLookAt(Vector3 lookAt)
2006 {
2007 if(ParentID == 0)
1687 { 2008 {
1688 // Movement into region will fail 2009 float n = lookAt.X * lookAt.X + lookAt.Y * lookAt.Y;
1689 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name); 2010 if(n < 0.0001f)
1690 return false; 2011 {
2012 Rotation = Quaternion.Identity;
2013 return;
2014 }
2015 n = lookAt.X/(float)Math.Sqrt(n);
2016 float angle = (float)Math.Acos(n);
2017 angle *= 0.5f;
2018 float s = (float)Math.Sin(angle);
2019 if(lookAt.Y < 0)
2020 s = -s;
2021 Rotation = new Quaternion(
2022 0f,
2023 0f,
2024 s,
2025 (float)Math.Cos(angle)
2026 );
1691 } 2027 }
1692
1693 return true;
1694 } 2028 }
1695 2029
1696 /// <summary> 2030 /// <summary>
@@ -1704,62 +2038,72 @@ namespace OpenSim.Region.Framework.Scenes
1704 /// </param> 2038 /// </param>
1705 public void CompleteMovement(IClientAPI client, bool openChildAgents) 2039 public void CompleteMovement(IClientAPI client, bool openChildAgents)
1706 { 2040 {
1707// DateTime startTime = DateTime.Now; 2041 int ts = Util.EnvironmentTickCount();
1708 2042
1709 m_log.InfoFormat( 2043 m_log.InfoFormat(
1710 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", 2044 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
1711 client.Name, Scene.Name, AbsolutePosition); 2045 client.Name, Scene.Name, AbsolutePosition);
1712 2046
1713 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); // Get this ahead of time because IsInTransit modifies 'm_AgentControlFlags' 2047 m_inTransit = true;
1714 2048
1715 IsInTransit = true;
1716 try 2049 try
1717 { 2050 {
1718 // Make sure it's not a login agent. We don't want to wait for updates during login 2051 // Make sure it's not a login agent. We don't want to wait for updates during login
1719 if (!(PresenceType == PresenceType.Npc || IsRealLogin(m_teleportFlags))) 2052 if (!IsNPC && !IsRealLogin(m_teleportFlags))
1720 { 2053 {
2054
1721 // Let's wait until UpdateAgent (called by departing region) is done 2055 // Let's wait until UpdateAgent (called by departing region) is done
1722 if (!WaitForUpdateAgent(client)) 2056 if (!WaitForUpdateAgent(client))
1723 // The sending region never sent the UpdateAgent data, we have to refuse 2057 // The sending region never sent the UpdateAgent data, we have to refuse
1724 return; 2058 return;
1725 } 2059 }
1726 2060
1727 Vector3 look = Velocity; 2061 //m_log.DebugFormat("[CompleteMovement] WaitForUpdateAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1728 2062
1729 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 2063 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1730 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1731 {
1732 look = new Vector3(0.99f, 0.042f, 0);
1733 }
1734 2064
1735 // Prevent teleporting to an underground location 2065 Vector3 look = Lookat;
1736 // (may crash client otherwise) 2066 look.Z = 0f;
1737 // 2067 if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01))
1738 Vector3 pos = AbsolutePosition;
1739 float ground = m_scene.GetGroundHeight(pos.X, pos.Y);
1740 if (pos.Z < ground + 1.5f)
1741 { 2068 {
1742 pos.Z = ground + 1.5f; 2069 look = Velocity;
1743 AbsolutePosition = pos; 2070 look.Normalize();
2071 if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01) )
2072 look = new Vector3(0.99f, 0.042f, 0);
1744 } 2073 }
1745 2074
1746 if (!MakeRootAgent(AbsolutePosition, flying)) 2075 // Check Default Location (Also See EntityTransferModule.TeleportAgentWithinRegion)
2076 if (AbsolutePosition.X == 128f && AbsolutePosition.Y == 128f && AbsolutePosition.Z == 22.5f)
2077 AbsolutePosition = Scene.RegionInfo.DefaultLandingPoint;
2078
2079 if (!MakeRootAgent(AbsolutePosition, flying, ref look))
1747 { 2080 {
1748 m_log.DebugFormat( 2081 m_log.DebugFormat(
1749 "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root", 2082 "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root",
1750 Name, Scene.Name); 2083 Name, Scene.Name);
1751 2084
1752 return; 2085 return;
1753 } 2086 }
1754 2087
1755 // Tell the client that we're totally ready
1756 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1757 2088
1758 // Child agents send initial data up in LLUDPServer.HandleUseCircuitCode() 2089 //m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1759 if (!SentInitialDataToClient)
1760 SendInitialDataToClient();
1761 2090
1762 // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); 2091 if(!haveGroupInformation && !IsChildAgent && !IsNPC)
2092 {
2093 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
2094 if (gm != null)
2095 Grouptitle = gm.GetGroupTitle(m_uuid);
2096
2097 //m_log.DebugFormat("[CompleteMovement] Missing Grouptitle: {0}ms", Util.EnvironmentTickCountSubtract(ts));
2098
2099 InventoryFolderBase cof = m_scene.InventoryService.GetFolderForType(client.AgentId, (FolderType)46);
2100 if (cof == null)
2101 COF = UUID.Zero;
2102 else
2103 COF = cof.ID;
2104
2105 m_log.DebugFormat("[CompleteMovement]: Missing COF for {0} is {1}", client.AgentId, COF);
2106 }
1763 2107
1764 if (!string.IsNullOrEmpty(m_callbackURI)) 2108 if (!string.IsNullOrEmpty(m_callbackURI))
1765 { 2109 {
@@ -1768,69 +2112,260 @@ namespace OpenSim.Region.Framework.Scenes
1768 // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete 2112 // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
1769 // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this 2113 // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
1770 // region as the current region, meaning that a close sent before then will fail the teleport. 2114 // region as the current region, meaning that a close sent before then will fail the teleport.
1771 // System.Threading.Thread.Sleep(2000); 2115 // System.Threading.Thread.Sleep(2000);
1772 2116
1773 m_log.DebugFormat( 2117 m_log.DebugFormat(
1774 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", 2118 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
1775 client.Name, client.AgentId, m_callbackURI); 2119 client.Name, client.AgentId, m_callbackURI);
1776 2120
1777 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); 2121 UUID originID;
2122
2123 lock (m_originRegionIDAccessLock)
2124 originID = m_originRegionID;
2125
2126 Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
1778 m_callbackURI = null; 2127 m_callbackURI = null;
2128 //m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1779 } 2129 }
1780 // else 2130// else
1781 // { 2131// {
1782 // m_log.DebugFormat( 2132// m_log.DebugFormat(
1783 // "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", 2133// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
1784 // client.Name, client.AgentId, m_scene.RegionInfo.RegionName); 2134// client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
1785 // } 2135// }
2136
2137
2138 // Tell the client that we're totally ready
2139 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
2140 //m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1786 2141
1787 ValidateAndSendAppearanceAndAgentData(); 2142 bool isHGTP = (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0;
1788 2143
1789 // Create child agents in neighbouring regions 2144 int delayctnr = Util.EnvironmentTickCount();
1790 if (openChildAgents && !IsChildAgent) 2145
2146 if (!IsChildAgent)
1791 { 2147 {
1792 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 2148 if( ParentPart != null && !IsNPC && (crossingFlags & 0x08) != 0)
1793 if (m_agentTransfer != null)
1794 { 2149 {
1795 // Note: this call can take a while, because it notifies each of the simulator's neighbours. 2150
1796 // It's important that we don't allow the avatar to cross regions meanwhile, as that will 2151// SceneObjectPart root = ParentPart.ParentGroup.RootPart;
1797 // cause serious errors. We've prevented that from happening by setting IsInTransit=true. 2152// if(root.LocalId != ParentPart.LocalId)
1798 m_agentTransfer.EnableChildAgents(this); 2153// ControllingClient.SendEntityTerseUpdateImmediate(root);
2154// ControllingClient.SendEntityTerseUpdateImmediate(ParentPart);
2155 ParentPart.ParentGroup.SendFullUpdateToClient(ControllingClient);
1799 } 2156 }
1800 2157
1801 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 2158 // verify baked textures and cache
1802 if (friendsModule != null) 2159 bool cachedbaked = false;
1803 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 2160
2161 if (IsNPC)
2162 cachedbaked = true;
2163 else
2164 {
2165 if (m_scene.AvatarFactory != null && !isHGTP)
2166 cachedbaked = m_scene.AvatarFactory.ValidateBakedTextureCache(this);
2167
2168 // not sure we need this
2169 if (!cachedbaked)
2170 {
2171 if (m_scene.AvatarFactory != null)
2172 m_scene.AvatarFactory.QueueAppearanceSave(UUID);
2173 }
2174 }
2175 //m_log.DebugFormat("[CompleteMovement] Baked check: {0}ms", Util.EnvironmentTickCountSubtract(ts));
2176 }
2177
2178 if(m_teleportFlags > 0)
2179 {
2180 gotCrossUpdate = false; // sanity check
2181 if(Util.EnvironmentTickCountSubtract(delayctnr)< 500)
2182 Thread.Sleep(500); // let viewers catch us
2183 }
2184
2185 if(!gotCrossUpdate)
2186 RotateToLookAt(look);
2187
2188 // HG
2189 if(isHGTP)
2190 {
2191// ControllingClient.SendNameReply(m_uuid, Firstname, Lastname);
2192 m_log.DebugFormat("[CompleteMovement] HG");
2193 }
2194
2195 m_previusParcelHide = false;
2196 m_previusParcelUUID = UUID.Zero;
2197 m_currentParcelHide = false;
2198 m_currentParcelUUID = UUID.Zero;
2199 ParcelDwellTickMS = Util.GetTimeStampMS();
2200
2201 if(!IsNPC)
2202 {
2203 GodController.SyncViewerState();
2204
2205 // start sending terrain patchs
2206 if (!gotCrossUpdate)
2207 Scene.SendLayerData(ControllingClient);
2208 }
2209 // send initial land overlay and parcel
2210 ILandChannel landch = m_scene.LandChannel;
2211 if (landch != null)
2212 landch.sendClientInitialLandInfo(client);
2213
2214 if (!IsChildAgent)
2215 {
2216 List<ScenePresence> allpresences = m_scene.GetScenePresences();
2217
2218 // send avatar object to all presences including us, so they cross it into region
2219 // then hide if necessary
2220
2221 SendInitialAvatarDataToAllAgents(allpresences);
2222
2223 // send this look
2224 SendAppearanceToAgent(this);
2225
2226 // send this animations
2227
2228 UUID[] animIDs = null;
2229 int[] animseqs = null;
2230 UUID[] animsobjs = null;
2231
2232 if (Animator != null)
2233 Animator.GetArrays(out animIDs, out animseqs, out animsobjs);
2234
2235 bool haveAnims = (animIDs != null && animseqs != null && animsobjs != null);
2236
2237 if (haveAnims)
2238 SendAnimPackToAgent(this, animIDs, animseqs, animsobjs);
2239
2240 // we should be able to receive updates, etc
2241 // so release them
2242 m_inTransit = false;
2243
2244 // send look and animations to others
2245 // if not cached we send greys
2246 // uncomented if will wait till avatar does baking
2247 //if (cachedbaked)
2248 {
2249 foreach (ScenePresence p in allpresences)
2250 {
2251 if (p == this)
2252 continue;
2253
2254 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
2255 continue;
2256
2257 SendAppearanceToAgentNF(p);
2258 if (haveAnims)
2259 SendAnimPackToAgentNF(p, animIDs, animseqs, animsobjs);
2260 }
2261 } // greys if
2262
2263 //m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts));
2264
2265 // attachments
2266 if (IsNPC || IsRealLogin(m_teleportFlags))
2267 {
2268 if (Scene.AttachmentsModule != null)
2269 // Util.FireAndForget(
2270 // o =>
2271 // {
2272
2273 if (!IsNPC)
2274 Scene.AttachmentsModule.RezAttachments(this);
2275 else
2276 Util.FireAndForget(x =>
2277 {
2278 Scene.AttachmentsModule.RezAttachments(this);
2279 });
2280
2281 // });
2282 }
2283 else
2284 {
2285 if (m_attachments.Count > 0)
2286 {
2287 m_log.DebugFormat(
2288 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1804 2289
2290 foreach (SceneObjectGroup sog in m_attachments)
2291 {
2292 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
2293 sog.ResumeScripts();
2294 }
2295
2296 foreach (ScenePresence p in allpresences)
2297 {
2298 if (p == this)
2299 {
2300 SendAttachmentsToAgentNF(this);
2301 continue;
2302 }
2303
2304 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
2305 continue;
2306
2307 SendAttachmentsToAgentNF(p);
2308 }
2309 }
2310 }
2311
2312 //m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts));
2313 if (openChildAgents)
2314 {
2315 // Create child agents in neighbouring regions
2316 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
2317 if (m_agentTransfer != null)
2318 {
2319 m_agentTransfer.EnableChildAgents(this);
2320 }
2321 }
2322 // let updates be sent, with some delay
2323 m_lastChildUpdatesTime = Util.EnvironmentTickCount() + 10000;
2324 m_lastChildAgentUpdateGodLevel = GodController.ViwerUIGodLevel;
2325 m_lastChildAgentUpdateDrawDistance = DrawDistance;
2326 m_lastChildAgentUpdatePosition = AbsolutePosition;
2327 m_childUpdatesBusy = false; // allow them
1805 } 2328 }
1806 2329
1807 // XXX: If we force an update after activity has completed, then multiple attachments do appear correctly on a destination region 2330 //m_log.DebugFormat("[CompleteMovement] openChildAgents: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1808 // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. 2331
1809 // This may be due to viewer code or it may be something we're not doing properly simulator side. 2332 // send the rest of the world
1810 WorkManager.RunJob( 2333 if (m_teleportFlags > 0 && !IsNPC || m_currentParcelHide)
1811 "ScheduleAttachmentsForFullUpdate", 2334 SendInitialDataToMe();
1812 o => ScheduleAttachmentsForFullUpdate(), 2335
1813 null, 2336 // priority uses avatar position only
1814 string.Format("Schedule attachments for full update for {0} in {1}", Name, Scene.Name), 2337// m_reprioritizationLastPosition = AbsolutePosition;
1815 true); 2338// m_reprioritizationLastDrawDistance = DrawDistance;
2339// m_reprioritizationLastTime = Util.EnvironmentTickCount() + 15000; // delay it
2340// m_reprioritizationBusy = false;
1816 2341
1817 // m_log.DebugFormat( 2342 //m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1818 // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 2343
1819 // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); 2344 if (!IsChildAgent && openChildAgents)
2345 {
2346 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
2347 if (friendsModule != null)
2348 {
2349 if(gotCrossUpdate)
2350 friendsModule.IsNowRoot(this);
2351 else
2352 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
2353 }
2354 //m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms", Util.EnvironmentTickCountSubtract(ts));
2355
2356 }
1820 } 2357 }
1821 finally 2358 finally
1822 { 2359 {
1823 IsInTransit = false; 2360 haveGroupInformation = false;
2361 gotCrossUpdate = false;
2362 crossingFlags = 0;
2363 m_inTransit = false;
1824 } 2364 }
1825 } 2365
2366 m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
1826 2367
1827 private void ScheduleAttachmentsForFullUpdate() 2368 m_log.DebugFormat("[CompleteMovement] end: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1828 {
1829 lock (m_attachments)
1830 {
1831 foreach (SceneObjectGroup sog in m_attachments)
1832 sog.ScheduleGroupForFullUpdate();
1833 }
1834 } 2369 }
1835 2370
1836 /// <summary> 2371 /// <summary>
@@ -1841,7 +2376,54 @@ namespace OpenSim.Region.Framework.Scenes
1841 /// <param name="collisionPoint"></param> 2376 /// <param name="collisionPoint"></param>
1842 /// <param name="localid"></param> 2377 /// <param name="localid"></param>
1843 /// <param name="distance"></param> 2378 /// <param name="distance"></param>
1844 /// 2379 ///
2380
2381 private void checkCameraCollision()
2382 {
2383 if(m_doingCamRayCast || !m_scene.PhysicsScene.SupportsRayCast())
2384 return;
2385
2386 if(m_mouseLook || ParentID != 0)
2387 {
2388 if (CameraConstraintActive)
2389 {
2390 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
2391 UpdateCameraCollisionPlane(plane);
2392 CameraConstraintActive = false;
2393 }
2394 return;
2395 }
2396
2397 Vector3 posAdjusted = AbsolutePosition;
2398 posAdjusted.Z += 1.0f; // viewer current camera focus point
2399
2400 if(posAdjusted.ApproxEquals(m_lastCameraRayCastPos, 0.2f) &&
2401 CameraPosition.ApproxEquals(m_lastCameraRayCastCam, 0.2f))
2402 return;
2403
2404 m_lastCameraRayCastCam = CameraPosition;
2405 m_lastCameraRayCastPos = posAdjusted;
2406
2407 Vector3 tocam = CameraPosition - posAdjusted;
2408
2409 float distTocamlen = tocam.LengthSquared();
2410 if (distTocamlen > 0.01f && distTocamlen < 400)
2411 {
2412 distTocamlen = (float)Math.Sqrt(distTocamlen);
2413 tocam *= (1.0f / distTocamlen);
2414
2415 m_doingCamRayCast = true;
2416 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
2417 return;
2418 }
2419
2420 if (CameraConstraintActive)
2421 {
2422 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
2423 UpdateCameraCollisionPlane(plane);
2424 CameraConstraintActive = false;
2425 }
2426 }
1845 2427
1846 private void UpdateCameraCollisionPlane(Vector4 plane) 2428 private void UpdateCameraCollisionPlane(Vector4 plane)
1847 { 2429 {
@@ -1854,17 +2436,11 @@ namespace OpenSim.Region.Framework.Scenes
1854 2436
1855 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 2437 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1856 { 2438 {
1857 const float POSITION_TOLERANCE = 0.02f;
1858 const float ROTATION_TOLERANCE = 0.02f;
1859
1860 m_doingCamRayCast = false;
1861 if (hitYN && localid != LocalId) 2439 if (hitYN && localid != LocalId)
1862 { 2440 {
1863 SceneObjectGroup group = m_scene.GetGroupByPrim(localid); 2441 if (localid != 0)
1864 bool IsPrim = group != null;
1865 if (IsPrim)
1866 { 2442 {
1867 SceneObjectPart part = group.GetPart(localid); 2443 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
1868 if (part != null && !part.VolumeDetectActive) 2444 if (part != null && !part.VolumeDetectActive)
1869 { 2445 {
1870 CameraConstraintActive = true; 2446 CameraConstraintActive = true;
@@ -1897,13 +2473,14 @@ namespace OpenSim.Region.Framework.Scenes
1897 UpdateCameraCollisionPlane(plane); 2473 UpdateCameraCollisionPlane(plane);
1898 } 2474 }
1899 } 2475 }
1900 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 2476 else if(CameraConstraintActive)
1901 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1902 { 2477 {
1903 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right... 2478 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1904 UpdateCameraCollisionPlane(plane); 2479 UpdateCameraCollisionPlane(plane);
1905 CameraConstraintActive = false; 2480 CameraConstraintActive = false;
1906 } 2481 }
2482
2483 m_doingCamRayCast = false;
1907 } 2484 }
1908 2485
1909 /// <summary> 2486 /// <summary>
@@ -1921,12 +2498,17 @@ namespace OpenSim.Region.Framework.Scenes
1921 return; 2498 return;
1922 } 2499 }
1923 2500
2501 if (IsInTransit)
2502 return;
2503
1924 #region Sanity Checking 2504 #region Sanity Checking
1925 2505
1926 // This is irritating. Really. 2506 // This is irritating. Really.
1927 if (!AbsolutePosition.IsFinite()) 2507 if (!AbsolutePosition.IsFinite())
1928 { 2508 {
1929 RemoveFromPhysicalScene(); 2509 bool isphysical = PhysicsActor != null;
2510 if(isphysical)
2511 RemoveFromPhysicalScene();
1930 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 2512 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1931 2513
1932 m_pos = m_LastFinitePos; 2514 m_pos = m_LastFinitePos;
@@ -1938,7 +2520,8 @@ namespace OpenSim.Region.Framework.Scenes
1938 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); 2520 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903");
1939 } 2521 }
1940 2522
1941 AddToPhysicalScene(false); 2523 if(isphysical)
2524 AddToPhysicalScene(false);
1942 } 2525 }
1943 else 2526 else
1944 { 2527 {
@@ -1953,18 +2536,18 @@ namespace OpenSim.Region.Framework.Scenes
1953 2536
1954 // The Agent's Draw distance setting 2537 // The Agent's Draw distance setting
1955 // When we get to the point of re-computing neighbors everytime this 2538 // When we get to the point of re-computing neighbors everytime this
1956 // changes, then start using the agent's drawdistance rather than the 2539 // changes, then start using the agent's drawdistance rather than the
1957 // region's draw distance. 2540 // region's draw distance.
2541
1958 DrawDistance = agentData.Far; 2542 DrawDistance = agentData.Far;
1959 // DrawDistance = Scene.DefaultDrawDistance;
1960 2543
1961 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; 2544 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
1962 2545
1963 // FIXME: This does not work as intended because the viewer only sends the lbutton down when the button 2546 // FIXME: This does not work as intended because the viewer only sends the lbutton down when the button
1964 // is first pressed, not whilst it is held down. If this is required in the future then need to look 2547 // is first pressed, not whilst it is held down. If this is required in the future then need to look
1965 // for an AGENT_CONTROL_LBUTTON_UP event and make sure to handle cases where an initial DOWN is not 2548 // for an AGENT_CONTROL_LBUTTON_UP event and make sure to handle cases where an initial DOWN is not
1966 // received (e.g. on holding LMB down on the avatar in a viewer). 2549 // received (e.g. on holding LMB down on the avatar in a viewer).
1967// m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; 2550 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
1968 2551
1969 #endregion Inputs 2552 #endregion Inputs
1970 2553
@@ -1977,6 +2560,7 @@ namespace OpenSim.Region.Framework.Scenes
1977// (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) 2560// (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
1978// m_updateCount = UPDATE_COUNT; 2561// m_updateCount = UPDATE_COUNT;
1979 2562
2563
1980 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) 2564 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
1981 { 2565 {
1982 StandUp(); 2566 StandUp();
@@ -1984,38 +2568,8 @@ namespace OpenSim.Region.Framework.Scenes
1984 2568
1985 // Raycast from the avatar's head to the camera to see if there's anything blocking the view 2569 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1986 // this exclude checks may not be complete 2570 // this exclude checks may not be complete
1987 2571 if(agentData.NeedsCameraCollision) // condition parentID may be wrong
1988 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast()) 2572 checkCameraCollision();
1989 {
1990 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1991 {
1992 Vector3 posAdjusted = AbsolutePosition;
1993// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1994 posAdjusted.Z += 1.0f; // viewer current camera focus point
1995 Vector3 tocam = CameraPosition - posAdjusted;
1996 tocam.X = (float)Math.Round(tocam.X, 1);
1997 tocam.Y = (float)Math.Round(tocam.Y, 1);
1998 tocam.Z = (float)Math.Round(tocam.Z, 1);
1999
2000 float distTocamlen = tocam.Length();
2001 if (distTocamlen > 0.3f)
2002 {
2003 tocam *= (1.0f / distTocamlen);
2004 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
2005 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
2006 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
2007
2008 m_doingCamRayCast = true;
2009 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
2010 }
2011 }
2012 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
2013 {
2014 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
2015 UpdateCameraCollisionPlane(plane);
2016 CameraConstraintActive = false;
2017 }
2018 }
2019 2573
2020 uint flagsForScripts = (uint)flags; 2574 uint flagsForScripts = (uint)flags;
2021 flags = RemoveIgnoredControls(flags, IgnoredControls); 2575 flags = RemoveIgnoredControls(flags, IgnoredControls);
@@ -2032,7 +2586,7 @@ namespace OpenSim.Region.Framework.Scenes
2032 2586
2033 // We need to send this back to the client in order to stop the edit beams 2587 // We need to send this back to the client in order to stop the edit beams
2034 if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None) 2588 if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None)
2035 ControllingClient.SendAgentTerseUpdate(this); 2589 SendAgentTerseUpdate(this);
2036 2590
2037 PhysicsActor actor = PhysicsActor; 2591 PhysicsActor actor = PhysicsActor;
2038 2592
@@ -2046,9 +2600,7 @@ namespace OpenSim.Region.Framework.Scenes
2046 if (AllowMovement && !SitGround) 2600 if (AllowMovement && !SitGround)
2047 { 2601 {
2048// m_log.DebugFormat("[SCENE PRESENCE]: Initial body rotation {0} for {1}", agentData.BodyRotation, Name); 2602// m_log.DebugFormat("[SCENE PRESENCE]: Initial body rotation {0} for {1}", agentData.BodyRotation, Name);
2049
2050 bool update_rotation = false; 2603 bool update_rotation = false;
2051
2052 if (agentData.BodyRotation != Rotation) 2604 if (agentData.BodyRotation != Rotation)
2053 { 2605 {
2054 Rotation = agentData.BodyRotation; 2606 Rotation = agentData.BodyRotation;
@@ -2056,31 +2608,26 @@ namespace OpenSim.Region.Framework.Scenes
2056 } 2608 }
2057 2609
2058 bool update_movementflag = false; 2610 bool update_movementflag = false;
2059 2611 bool mvToTarget = m_movingToTarget;
2060 // If we were just made root agent then we must perform movement updates for the first AgentUpdate that
2061 // we get
2062 if (MovementFlag == ForceUpdateMovementFlagValue)
2063 {
2064 MovementFlag = 0;
2065 update_movementflag = true;
2066 }
2067
2068 if (agentData.UseClientAgentPosition) 2612 if (agentData.UseClientAgentPosition)
2069 { 2613 {
2070 MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; 2614 m_movingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).LengthSquared() > 0.04f;
2071 MoveToPositionTarget = agentData.ClientAgentPosition; 2615 m_moveToPositionTarget = agentData.ClientAgentPosition;
2616 m_moveToSpeed = -1f;
2072 } 2617 }
2073 2618
2074 int i = 0; 2619 int i = 0;
2075 bool DCFlagKeyPressed = false; 2620 bool DCFlagKeyPressed = false;
2076 Vector3 agent_control_v3 = Vector3.Zero; 2621 Vector3 agent_control_v3 = Vector3.Zero;
2077 2622
2078 bool newFlying = actor.Flying; 2623 bool newFlying = false;
2079 2624
2080 if (ForceFly) 2625 if (ForceFly)
2081 newFlying = true; 2626 newFlying = true;
2082 else if (FlyDisabled) 2627 else if (FlyDisabled)
2083 newFlying = false; 2628 newFlying = false;
2629 else if(mvToTarget)
2630 newFlying = actor.Flying;
2084 else 2631 else
2085 newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 2632 newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
2086 2633
@@ -2096,6 +2643,15 @@ namespace OpenSim.Region.Framework.Scenes
2096 { 2643 {
2097 bool bAllowUpdateMoveToPosition = false; 2644 bool bAllowUpdateMoveToPosition = false;
2098 2645
2646 Vector3[] dirVectors;
2647
2648 // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying
2649 // this prevents 'jumping' in inappropriate situations.
2650// if (!Flying && (m_mouseLook || m_leftButtonDown))
2651// dirVectors = GetWalkDirectionVectors();
2652// else
2653 dirVectors = Dir_Vectors;
2654
2099 // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction. 2655 // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
2100 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 2656 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
2101 { 2657 {
@@ -2105,9 +2661,7 @@ namespace OpenSim.Region.Framework.Scenes
2105 2661
2106 try 2662 try
2107 { 2663 {
2108 // Don't slide against ground when crouching if camera is panned around avatar 2664 agent_control_v3 += Dir_Vectors[i];
2109 if (Flying || DCF != Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN)
2110 agent_control_v3 += Dir_Vectors[i];
2111 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 2665 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
2112 } 2666 }
2113 catch (IndexOutOfRangeException) 2667 catch (IndexOutOfRangeException)
@@ -2115,10 +2669,10 @@ namespace OpenSim.Region.Framework.Scenes
2115 // Why did I get this? 2669 // Why did I get this?
2116 } 2670 }
2117 2671
2118 if (((MovementFlag & (uint)DCF) == 0) & !AgentControlStopActive) 2672 if (((MovementFlag & (uint)DCF) == 0))
2119 { 2673 {
2120 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); 2674 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
2121 MovementFlag += (uint)DCF; 2675 MovementFlag |= (uint)DCF;
2122 update_movementflag = true; 2676 update_movementflag = true;
2123 } 2677 }
2124 } 2678 }
@@ -2127,7 +2681,7 @@ namespace OpenSim.Region.Framework.Scenes
2127 if ((MovementFlag & (uint)DCF) != 0) 2681 if ((MovementFlag & (uint)DCF) != 0)
2128 { 2682 {
2129 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 2683 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
2130 MovementFlag -= (uint)DCF; 2684 MovementFlag &= (uint)~DCF;
2131 update_movementflag = true; 2685 update_movementflag = true;
2132 2686
2133 /* 2687 /*
@@ -2154,7 +2708,7 @@ namespace OpenSim.Region.Framework.Scenes
2154 update_movementflag = true; 2708 update_movementflag = true;
2155 } 2709 }
2156 2710
2157 if (MovingToTarget) 2711 if (m_movingToTarget)
2158 { 2712 {
2159 // If the user has pressed a key then we want to cancel any move to target. 2713 // If the user has pressed a key then we want to cancel any move to target.
2160 if (DCFlagKeyPressed) 2714 if (DCFlagKeyPressed)
@@ -2167,7 +2721,7 @@ namespace OpenSim.Region.Framework.Scenes
2167 // The UseClientAgentPosition is set if parcel ban is forcing the avatar to move to a 2721 // The UseClientAgentPosition is set if parcel ban is forcing the avatar to move to a
2168 // certain position. It's only check for tolerance on returning to that position is 0.2 2722 // certain position. It's only check for tolerance on returning to that position is 0.2
2169 // rather than 1, at which point it removes its force target. 2723 // rather than 1, at which point it removes its force target.
2170 if (HandleMoveToTargetUpdate(agentData.UseClientAgentPosition ? 0.2 : 1, ref agent_control_v3)) 2724 if (HandleMoveToTargetUpdate(agentData.UseClientAgentPosition ? 0.2f : 1f, ref agent_control_v3))
2171 update_movementflag = true; 2725 update_movementflag = true;
2172 } 2726 }
2173 } 2727 }
@@ -2180,11 +2734,11 @@ namespace OpenSim.Region.Framework.Scenes
2180 if (Flying && !ForceFly) 2734 if (Flying && !ForceFly)
2181 { 2735 {
2182 // Need to stop in mid air if user holds down AGENT_CONTROL_STOP 2736 // Need to stop in mid air if user holds down AGENT_CONTROL_STOP
2183 if (AgentControlStopActive) 2737 // if (AgentControlStopActive)
2184 { 2738 // {
2185 agent_control_v3 = Vector3.Zero; 2739 // agent_control_v3 = Vector3.Zero;
2186 } 2740 // }
2187 else 2741 // else
2188 { 2742 {
2189 // Landing detection code 2743 // Landing detection code
2190 2744
@@ -2192,38 +2746,43 @@ namespace OpenSim.Region.Framework.Scenes
2192 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || 2746 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
2193 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2747 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2194 2748
2195 //m_log.Debug("[CONTROL]: " +flags); 2749 //m_log.Debug("[CONTROL]: " +flags);
2196 // Applies a satisfying roll effect to the avatar when flying. 2750 // Applies a satisfying roll effect to the avatar when flying.
2197 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) 2751 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
2198 { 2752 {
2199 ApplyFlyingRoll( 2753 ApplyFlyingRoll(
2200 FLY_ROLL_RADIANS_PER_UPDATE, 2754 FLY_ROLL_RADIANS_PER_UPDATE,
2201 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, 2755 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
2202 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); 2756 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
2203 } 2757 }
2204 else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 && 2758 else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 &&
2205 (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) 2759 (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
2206 { 2760 {
2207 ApplyFlyingRoll( 2761 ApplyFlyingRoll(
2208 -FLY_ROLL_RADIANS_PER_UPDATE, 2762 -FLY_ROLL_RADIANS_PER_UPDATE,
2209 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, 2763 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
2210 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); 2764 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
2211 } 2765 }
2212 else 2766 else
2213 { 2767 {
2214 if (m_AngularVelocity.Z != 0) 2768 if (m_AngularVelocity.Z != 0)
2215 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE); 2769 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
2216 }
2217
2218 if (Flying && IsColliding && controlland)
2219 {
2220 // nesting this check because LengthSquared() is expensive and we don't
2221 // want to do it every step when flying.
2222 if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX))
2223 StopFlying();
2224 } 2770 }
2771
2772 /*
2773 if (Flying && IsColliding && controlland)
2774 {
2775 // nesting this check because LengthSquared() is expensive and we don't
2776 // want to do it every step when flying.
2777 if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX))
2778 StopFlying();
2779 }
2780 */
2225 } 2781 }
2226 } 2782 }
2783 else if (IsColliding && agent_control_v3.Z < 0f)
2784 agent_control_v3.Z = 0;
2785// else if(AgentControlStopActive %% Velocity.Z <0.01f)
2227 2786
2228// m_log.DebugFormat("[SCENE PRESENCE]: MovementFlag {0} for {1}", MovementFlag, Name); 2787// m_log.DebugFormat("[SCENE PRESENCE]: MovementFlag {0} for {1}", MovementFlag, Name);
2229 2788
@@ -2231,54 +2790,60 @@ namespace OpenSim.Region.Framework.Scenes
2231 // which occurs later in the main scene loop 2790 // which occurs later in the main scene loop
2232 // We also need to update if the user rotates their avatar whilst it is slow walking/running (if they 2791 // We also need to update if the user rotates their avatar whilst it is slow walking/running (if they
2233 // held down AGENT_CONTROL_STOP whilst normal walking/running). However, we do not want to update 2792 // held down AGENT_CONTROL_STOP whilst normal walking/running). However, we do not want to update
2234 // if the user rotated whilst holding down AGENT_CONTROL_STOP when already still (which locks the 2793 // if the user rotated whilst holding down AGENT_CONTROL_STOP when already still (which locks the
2235 // avatar location in place). 2794 // avatar location in place).
2236 if (update_movementflag 2795
2796 if (update_movementflag
2237 || (update_rotation && DCFlagKeyPressed && (!AgentControlStopActive || MovementFlag != 0))) 2797 || (update_rotation && DCFlagKeyPressed && (!AgentControlStopActive || MovementFlag != 0)))
2238 { 2798 {
2239// if (update_movementflag || !AgentControlStopActive || MovementFlag != 0)
2240// {
2241// m_log.DebugFormat(
2242// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, mf = {4}, ur = {5}",
2243// m_scene.RegionInfo.RegionName, agent_control_v3, Name,
2244// update_movementflag, MovementFlag, update_rotation);
2245 2799
2246 float speedModifier; 2800 if (AgentControlStopActive)
2247 2801 {
2248 if (AgentControlStopActive) 2802 // if (MovementFlag == 0 && Animator.Falling)
2249 speedModifier = AgentControlStopSlowWhilstMoving; 2803 if (MovementFlag == 0 && Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling)
2804 {
2805 AddNewMovement(agent_control_v3, AgentControlStopSlowVel, true);
2806 }
2250 else 2807 else
2251 speedModifier = 1; 2808 AddNewMovement(agent_control_v3, AgentControlStopSlowVel);
2252 2809 }
2253 AddNewMovement(agent_control_v3, speedModifier); 2810 else
2254// } 2811 {
2812 if(m_movingToTarget ||
2813 (Animator.currentControlState != ScenePresenceAnimator.motionControlStates.flying &&
2814 Animator.currentControlState != ScenePresenceAnimator.motionControlStates.onsurface)
2815 )
2816 AddNewMovement(agent_control_v3);
2817 else
2818 {
2819 if (MovementFlag != 0)
2820 AddNewMovement(agent_control_v3);
2821 else
2822 m_delayedStop = Util.GetTimeStampMS() + 200.0;
2823 }
2824 }
2255 } 2825 }
2256// else 2826/*
2257// { 2827 if (update_movementflag && ParentID == 0 && m_delayedStop < 0)
2258// if (!update_movementflag)
2259// {
2260// m_log.DebugFormat(
2261// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
2262// m_scene.RegionInfo.RegionName, agent_control_v3, Name);
2263// }
2264// }
2265
2266 if (update_movementflag && ParentID == 0)
2267 { 2828 {
2268// m_log.DebugFormat("[SCENE PRESENCE]: Updating movement animations for {0}", Name); 2829// m_log.DebugFormat("[SCENE PRESENCE]: Updating movement animations for {0}", Name);
2269 Animator.UpdateMovementAnimations(); 2830 Animator.UpdateMovementAnimations();
2270 } 2831 }
2271 2832*/
2272 SendControlsToScripts(flagsForScripts); 2833 SendControlsToScripts(flagsForScripts);
2273 } 2834 }
2274 2835
2275 // We need to send this back to the client in order to see the edit beams 2836 // We need to send this back to the client in order to see the edit beams
2276 if ((State & (uint)AgentState.Editing) != 0) 2837 if ((State & (uint)AgentState.Editing) != 0)
2277 ControllingClient.SendAgentTerseUpdate(this); 2838 SendAgentTerseUpdate(this);
2278 2839
2279 m_scene.EventManager.TriggerOnClientMovement(this); 2840// m_scene.EventManager.TriggerOnClientMovement(this);
2280 } 2841 }
2281 2842
2843 private void HandleAgentFOV(IClientAPI remoteClient, float _fov)
2844 {
2845 m_FOV = _fov;
2846 }
2282 2847
2283 /// <summary> 2848 /// <summary>
2284 /// This is the event handler for client cameras. If a client is moving, or moving the camera, this event is triggering. 2849 /// This is the event handler for client cameras. If a client is moving, or moving the camera, this event is triggering.
@@ -2290,60 +2855,37 @@ namespace OpenSim.Region.Framework.Scenes
2290 // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); 2855 // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
2291 2856
2292 if (IsChildAgent) 2857 if (IsChildAgent)
2293 {
2294 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
2295 return; 2858 return;
2296 }
2297 2859
2298 ++m_movementUpdateCount; 2860 if(IsInTransit)
2299 if (m_movementUpdateCount < 1) 2861 return;
2300 m_movementUpdateCount = 1;
2301 2862
2302// AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; 2863// AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
2303 2864
2304 // Camera location in world. We'll need to raytrace 2865 // Camera location in world. We'll need to raytrace
2305 // from this location from time to time. 2866 // from this location from time to time.
2306 CameraPosition = agentData.CameraCenter; 2867 CameraPosition = agentData.CameraCenter;
2307 if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance)
2308 {
2309 ReprioritizeUpdates();
2310 m_lastCameraPosition = CameraPosition;
2311 }
2312
2313 // Use these three vectors to figure out what the agent is looking at 2868 // Use these three vectors to figure out what the agent is looking at
2314 // Convert it to a Matrix and/or Quaternion 2869 // Convert it to a Matrix and/or Quaternion
2870
2871 // this may need lock
2315 CameraAtAxis = agentData.CameraAtAxis; 2872 CameraAtAxis = agentData.CameraAtAxis;
2316 CameraLeftAxis = agentData.CameraLeftAxis; 2873 CameraLeftAxis = agentData.CameraLeftAxis;
2317 CameraUpAxis = agentData.CameraUpAxis; 2874 CameraUpAxis = agentData.CameraUpAxis;
2318
2319 // The Agent's Draw distance setting
2320 // When we get to the point of re-computing neighbors everytime this
2321 // changes, then start using the agent's drawdistance rather than the
2322 // region's draw distance.
2323 DrawDistance = agentData.Far; 2875 DrawDistance = agentData.Far;
2324 // DrawDistance = Scene.DefaultDrawDistance;
2325
2326 // Check if Client has camera in 'follow cam' or 'build' mode.
2327 Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
2328 2876
2329 m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f) 2877 CameraAtAxis.Normalize();
2330 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; 2878 CameraLeftAxis.Normalize();
2879 CameraUpAxis.Normalize();
2880 Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis);
2881 CameraRotation = camRot;
2331 2882
2332 2883 if(agentData.NeedsCameraCollision)
2333 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); 2884 checkCameraCollision();
2334 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
2335 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
2336 {
2337 if (m_followCamAuto)
2338 {
2339 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
2340 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback);
2341 }
2342 }
2343 2885
2344 TriggerScenePresenceUpdated(); 2886 TriggerScenePresenceUpdated();
2345 } 2887 }
2346 2888
2347 /// <summary> 2889 /// <summary>
2348 /// Calculate an update to move the presence to the set target. 2890 /// Calculate an update to move the presence to the set target.
2349 /// </summary> 2891 /// </summary>
@@ -2352,125 +2894,158 @@ namespace OpenSim.Region.Framework.Scenes
2352 /// </remarks> 2894 /// </remarks>
2353 /// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param> 2895 /// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param>
2354 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 2896 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
2355 public bool HandleMoveToTargetUpdate(double tolerance, ref Vector3 agent_control_v3) 2897 public bool HandleMoveToTargetUpdate(float tolerance, ref Vector3 agent_control_v3)
2356 { 2898 {
2357// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 2899// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
2358 2900
2359 bool updated = false; 2901 bool updated = false;
2360 2902
2903 Vector3 LocalVectorToTarget3D = m_moveToPositionTarget - AbsolutePosition;
2904
2361// m_log.DebugFormat( 2905// m_log.DebugFormat(
2362// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 2906// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
2363// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 2907// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
2364 2908
2365 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 2909 float distanceToTarget;
2910 if(Flying && !LandAtTarget)
2911 {
2912 distanceToTarget = LocalVectorToTarget3D.Length();
2913 }
2914 else
2915 {
2916 distanceToTarget = (float)Math.Sqrt(LocalVectorToTarget3D.X * LocalVectorToTarget3D.X +
2917 LocalVectorToTarget3D.Y * LocalVectorToTarget3D.Y);
2918 }
2366 2919
2367// m_log.DebugFormat( 2920 // m_log.DebugFormat(
2368// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 2921 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
2369// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 2922 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
2370 2923
2371 // Check the error term of the current position in relation to the target position 2924 // Check the error term of the current position in relation to the target position
2372 if (distanceToTarget <= tolerance) 2925 if (distanceToTarget <= tolerance)
2373 { 2926 {
2374 // We are close enough to the target 2927 // We are close enough to the target
2375 AbsolutePosition = MoveToPositionTarget; 2928 Velocity = Vector3.Zero;
2929 AbsolutePosition = m_moveToPositionTarget;
2930 if (Flying)
2931 {
2932 if (LandAtTarget)
2933 Flying = false;
2934
2935 // A horrible hack to stop the avatar dead in its tracks rather than having them overshoot
2936 // the target if flying.
2937 // We really need to be more subtle (slow the avatar as it approaches the target) or at
2938 // least be able to set collision status once, rather than 5 times to give it enough
2939 // weighting so that that PhysicsActor thinks it really is colliding.
2940 for (int i = 0; i < 5; i++)
2941 IsColliding = true;
2942 }
2376 ResetMoveToTarget(); 2943 ResetMoveToTarget();
2377 updated = true; 2944 return false;
2378 } 2945 }
2379 else 2946
2947 if(m_moveToSpeed > 0 && distanceToTarget <= m_moveToSpeed * Scene.FrameTime)
2948 m_moveToSpeed = distanceToTarget / Scene.FrameTime;
2949
2950 try
2380 { 2951 {
2381 try 2952 // move avatar in 3D towards target, in avatar coordinate frame.
2382 { 2953 // This movement vector gets added to the velocity through AddNewMovement().
2383 // move avatar in 3D at one meter/second towards target, in avatar coordinate frame. 2954 // Theoretically we might need a more complex PID approach here if other
2384 // This movement vector gets added to the velocity through AddNewMovement(). 2955 // unknown forces are acting on the avatar and we need to adaptively respond
2385 // Theoretically we might need a more complex PID approach here if other 2956 // to such forces, but the following simple approach seems to works fine.
2386 // unknown forces are acting on the avatar and we need to adaptively respond
2387 // to such forces, but the following simple approach seems to works fine.
2388 Vector3 LocalVectorToTarget3D =
2389 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
2390 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
2391 // Ignore z component of vector
2392// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
2393 LocalVectorToTarget3D.Normalize();
2394
2395 // update avatar movement flags. the avatar coordinate system is as follows:
2396 //
2397 // +X (forward)
2398 //
2399 // ^
2400 // |
2401 // |
2402 // |
2403 // |
2404 // (left) +Y <--------o--------> -Y
2405 // avatar
2406 // |
2407 // |
2408 // |
2409 // |
2410 // v
2411 // -X
2412 //
2413 2957
2414 // based on the above avatar coordinate system, classify the movement into 2958 float angle = 0.5f * (float)Math.Atan2(LocalVectorToTarget3D.Y, LocalVectorToTarget3D.X);
2415 // one of left/right/back/forward. 2959 Quaternion rot = new Quaternion(0,0, (float)Math.Sin(angle),(float)Math.Cos(angle));
2416 if (LocalVectorToTarget3D.X < 0) //MoveBack 2960 Rotation = rot;
2417 { 2961 LocalVectorToTarget3D = LocalVectorToTarget3D * Quaternion.Inverse(rot); // change to avatar coords
2418 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; 2962 LocalVectorToTarget3D.Normalize();
2419 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
2420 updated = true;
2421 }
2422 else if (LocalVectorToTarget3D.X > 0) //Move Forward
2423 {
2424 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
2425 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
2426 updated = true;
2427 }
2428 2963
2429 if (LocalVectorToTarget3D.Y > 0) //MoveLeft 2964 // update avatar movement flags. the avatar coordinate system is as follows:
2430 { 2965 //
2431 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; 2966 // +X (forward)
2432 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; 2967 //
2433 updated = true; 2968 // ^
2434 } 2969 // |
2435 else if (LocalVectorToTarget3D.Y < 0) //MoveRight 2970 // |
2436 { 2971 // |
2437 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; 2972 // |
2438 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; 2973 // (left) +Y <--------o--------> -Y
2439 updated = true; 2974 // avatar
2440 } 2975 // |
2976 // |
2977 // |
2978 // |
2979 // v
2980 // -X
2981 //
2441 2982
2442 if (LocalVectorToTarget3D.Z > 0) //Up 2983 // based on the above avatar coordinate system, classify the movement into
2443 { 2984 // one of left/right/back/forward.
2444 // Don't set these flags for up or down - doing so will make the avatar crouch or 2985
2445 // keep trying to jump even if walking along level ground 2986 const uint noMovFlagsMask = (uint)(~(Dir_ControlFlags.DIR_CONTROL_FLAG_BACK |
2446 //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; 2987 Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD | Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT |
2447 //AgentControlFlags 2988 Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT | Dir_ControlFlags.DIR_CONTROL_FLAG_UP |
2448 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; 2989 Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN));
2449 updated = true; 2990
2450 } 2991 MovementFlag &= noMovFlagsMask;
2451 else if (LocalVectorToTarget3D.Z < 0) //Down 2992 uint tmpAgentControlFlags = (uint)m_AgentControlFlags;
2452 { 2993 tmpAgentControlFlags &= noMovFlagsMask;
2453 //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
2454 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
2455 updated = true;
2456 }
2457 2994
2995 if (LocalVectorToTarget3D.X < 0) //MoveBack
2996 {
2997 MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
2998 tmpAgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
2999 updated = true;
3000 }
3001 else if (LocalVectorToTarget3D.X > 0) //Move Forward
3002 {
3003 MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
3004 tmpAgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
3005 updated = true;
3006 }
3007
3008 if (LocalVectorToTarget3D.Y > 0) //MoveLeft
3009 {
3010 MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
3011 tmpAgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
3012 updated = true;
3013 }
3014 else if (LocalVectorToTarget3D.Y < 0) //MoveRight
3015 {
3016 MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
3017 tmpAgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
3018 updated = true;
3019 }
3020
3021 if (LocalVectorToTarget3D.Z > 0) //Up
3022 updated = true;
3023
3024 else if (LocalVectorToTarget3D.Z < 0) //Down
3025 updated = true;
3026
2458// m_log.DebugFormat( 3027// m_log.DebugFormat(
2459// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 3028// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
2460// LocalVectorToTarget3D, agent_control_v3, Name); 3029// LocalVectorToTarget3D, agent_control_v3, Name);
2461 3030
3031 m_AgentControlFlags = (AgentManager.ControlFlags) tmpAgentControlFlags;
3032 if(updated)
2462 agent_control_v3 += LocalVectorToTarget3D; 3033 agent_control_v3 += LocalVectorToTarget3D;
2463 } 3034 }
2464 catch (Exception e) 3035 catch (Exception e)
2465 { 3036 {
2466 //Avoid system crash, can be slower but... 3037 //Avoid system crash, can be slower but...
2467 m_log.DebugFormat("Crash! {0}", e.ToString()); 3038 m_log.DebugFormat("Crash! {0}", e.ToString());
2468 }
2469 } 3039 }
2470 3040
2471 return updated; 3041 return updated;
3042// AddNewMovement(agent_control_v3);
2472 } 3043 }
2473 3044
3045 public void MoveToTargetHandle(Vector3 pos, bool noFly, bool landAtTarget)
3046 {
3047 MoveToTarget(pos, noFly, landAtTarget);
3048 }
2474 /// <summary> 3049 /// <summary>
2475 /// Move to the given target over time. 3050 /// Move to the given target over time.
2476 /// </summary> 3051 /// </summary>
@@ -2483,8 +3058,10 @@ namespace OpenSim.Region.Framework.Scenes
2483 /// <param name="landAtTarget"> 3058 /// <param name="landAtTarget">
2484 /// If true and the avatar starts flying during the move then land at the target. 3059 /// If true and the avatar starts flying during the move then land at the target.
2485 /// </param> 3060 /// </param>
2486 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget) 3061 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget, float tau = -1f)
2487 { 3062 {
3063 m_delayedStop = -1;
3064
2488 if (SitGround) 3065 if (SitGround)
2489 StandUp(); 3066 StandUp();
2490 3067
@@ -2494,89 +3071,61 @@ namespace OpenSim.Region.Framework.Scenes
2494 3071
2495 // Allow move to another sub-region within a megaregion 3072 // Allow move to another sub-region within a megaregion
2496 Vector2 regionSize; 3073 Vector2 regionSize;
2497 IRegionCombinerModule regionCombinerModule = m_scene.RequestModuleInterface<IRegionCombinerModule>(); 3074 regionSize = new Vector2(m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY);
2498 if (regionCombinerModule != null)
2499 regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
2500 else
2501 regionSize = new Vector2(m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY);
2502 3075
2503 if (pos.X < 0 || pos.X >= regionSize.X 3076 if (pos.X < 0 || pos.X >= regionSize.X
2504 || pos.Y < 0 || pos.Y >= regionSize.Y 3077 || pos.Y < 0 || pos.Y >= regionSize.Y
2505 || pos.Z < 0) 3078 || pos.Z < 0)
2506 return; 3079 return;
2507 3080
3081 float terrainHeight;
2508 Scene targetScene = m_scene; 3082 Scene targetScene = m_scene;
3083 terrainHeight = m_scene.GetGroundHeight(pos.X, pos.Y);
2509 3084
2510// Vector3 heightAdjust = new Vector3(0, 0, Appearance.AvatarHeight / 2); 3085 // dont try to land underground
2511// pos += heightAdjust; 3086 terrainHeight += Appearance.AvatarHeight * 0.5f + 0.2f;
2512//
2513// // Anti duck-walking measure
2514// if (Math.Abs(pos.Z - AbsolutePosition.Z) < 0.2f)
2515// {
2516//// m_log.DebugFormat("[SCENE PRESENCE]: Adjusting MoveToPosition from {0} to {1}", pos, AbsolutePosition);
2517// pos.Z = AbsolutePosition.Z;
2518// }
2519 3087
2520 // Get terrain height for sub-region in a megaregion if necessary 3088 if(terrainHeight > pos.Z)
2521
2522 //COMMENT: If its only nessesary in a megaregion, why do it on normal region's too?
2523
2524 if (regionCombinerModule != null)
2525 {
2526 int x = (int)((m_scene.RegionInfo.WorldLocX) + pos.X);
2527 int y = (int)((m_scene.RegionInfo.WorldLocY) + pos.Y);
2528 GridRegion target_region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, x, y);
2529
2530 // If X and Y is NaN, target_region will be null
2531 if (target_region == null)
2532 return;
2533
2534 SceneManager.Instance.TryGetScene(target_region.RegionID, out targetScene);
2535 }
2536
2537 float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % regionSize.X), (int)(pos.Y % regionSize.Y)];
2538 pos.Z = Math.Max(terrainHeight, pos.Z);
2539
2540 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is
2541 // always slightly higher than the actual terrain height.
2542 // FIXME: This constrains NPC movements as well, so should be somewhere else.
2543 if (pos.Z - terrainHeight < 0.2)
2544 pos.Z = terrainHeight; 3089 pos.Z = terrainHeight;
2545 3090
2546 if (noFly)
2547 Flying = false;
2548 else if (pos.Z > terrainHeight)
2549 Flying = true;
2550
2551// m_log.DebugFormat( 3091// m_log.DebugFormat(
2552// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", 3092// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
2553// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); 3093// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
2554 3094
2555 if (noFly) 3095 terrainHeight += Appearance.AvatarHeight; // so 1.5 * AvatarHeight above ground at target
2556 Flying = false; 3096 bool shouldfly = Flying;
2557 3097 if (noFly)
2558 LandAtTarget = landAtTarget; 3098 shouldfly = false;
2559 MovingToTarget = true; 3099 else if (pos.Z > terrainHeight || Flying)
2560 MoveToPositionTarget = pos; 3100 shouldfly = true;
2561 3101
2562 // Rotate presence around the z-axis to point in same direction as movement.
2563 // Ignore z component of vector
2564 Vector3 localVectorToTarget3D = pos - AbsolutePosition; 3102 Vector3 localVectorToTarget3D = pos - AbsolutePosition;
2565 Vector3 localVectorToTarget2D = new Vector3((float)(localVectorToTarget3D.X), (float)(localVectorToTarget3D.Y), 0f);
2566 3103
2567// m_log.DebugFormat("[SCENE PRESENCE]: Local vector to target is {0}", localVectorToTarget2D); 3104// m_log.DebugFormat("[SCENE PRESENCE]: Local vector to target is {0},[1}", localVectorToTarget3D.X,localVectorToTarget3D.Y);
3105
3106 m_movingToTarget = true;
3107 LandAtTarget = landAtTarget;
3108 m_moveToPositionTarget = pos;
3109 if(tau > 0)
3110 {
3111 if(tau < Scene.FrameTime)
3112 tau = Scene.FrameTime;
3113 m_moveToSpeed = localVectorToTarget3D.Length() / tau;
3114 if(m_moveToSpeed < 0.5f) //to tune
3115 m_moveToSpeed = 0.5f;
3116 else if(m_moveToSpeed > 50f)
3117 m_moveToSpeed = 50f;
2568 3118
2569 // Calculate the yaw. 3119 SetAlwaysRun = false;
2570 Vector3 angle = new Vector3(0, 0, (float)(Math.Atan2(localVectorToTarget2D.Y, localVectorToTarget2D.X))); 3120 }
3121 else
3122 m_moveToSpeed = 4.096f * m_speedModifier;
2571 3123
2572// m_log.DebugFormat("[SCENE PRESENCE]: Angle is {0}", angle); 3124 Flying = shouldfly;
2573 3125
2574 Rotation = Quaternion.CreateFromEulers(angle); 3126 Vector3 control = Vector3.Zero;
2575// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation); 3127 if(HandleMoveToTargetUpdate(1f, ref control))
2576 3128 AddNewMovement(control);
2577 Vector3 agent_control_v3 = new Vector3();
2578 HandleMoveToTargetUpdate(1, ref agent_control_v3);
2579 AddNewMovement(agent_control_v3);
2580 } 3129 }
2581 3130
2582 /// <summary> 3131 /// <summary>
@@ -2586,9 +3135,11 @@ namespace OpenSim.Region.Framework.Scenes
2586 { 3135 {
2587// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 3136// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2588 3137
2589 MovingToTarget = false; 3138 m_movingToTarget = false;
3139 m_moveToSpeed = -1f;
2590// MoveToPositionTarget = Vector3.Zero; 3140// MoveToPositionTarget = Vector3.Zero;
2591 m_forceToApply = null; // cancel possible last action 3141// lock(m_forceToApplyLock)
3142// m_forceToApplyValid = false; // cancel possible last action
2592 3143
2593 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 3144 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
2594 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 3145 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2629,69 +3180,65 @@ namespace OpenSim.Region.Framework.Scenes
2629 } 3180 }
2630 } 3181 }
2631 3182
3183// part.ParentGroup.DeleteAvatar(UUID);
3184
3185 Quaternion standRotation = part.ParentGroup.RootPart.RotationOffset;
3186 Vector3 sitPartWorldPosition = part.ParentGroup.AbsolutePosition + m_pos * standRotation;
2632 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 3187 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2633 3188
2634 ParentID = 0; 3189 ParentID = 0;
2635 ParentPart = null; 3190 ParentPart = null;
2636 3191
2637 Quaternion standRotation;
2638
2639 if (part.SitTargetAvatar == UUID) 3192 if (part.SitTargetAvatar == UUID)
2640 { 3193 standRotation = standRotation * part.SitTargetOrientation;
2641 standRotation = part.GetWorldRotation(); 3194 else
3195 standRotation = standRotation * m_bodyRot;
2642 3196
2643 if (!part.IsRoot) 3197 m_bodyRot = standRotation;
2644 standRotation = standRotation * part.SitTargetOrientation; 3198
2645// standRotation = part.RotationOffset * part.SitTargetOrientation; 3199 Quaternion standRotationZ = new Quaternion(0,0,standRotation.Z,standRotation.W);
2646// else
2647// standRotation = part.SitTargetOrientation;
2648 3200
3201 float t = standRotationZ.W * standRotationZ.W + standRotationZ.Z * standRotationZ.Z;
3202 if (t > 0)
3203 {
3204 t = 1.0f / (float)Math.Sqrt(t);
3205 standRotationZ.W *= t;
3206 standRotationZ.Z *= t;
2649 } 3207 }
2650 else 3208 else
2651 { 3209 {
2652 standRotation = Rotation; 3210 standRotationZ.W = 1.0f;
3211 standRotationZ.Z = 0f;
2653 } 3212 }
2654 3213
2655 //Vector3 standPos = ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 3214 Vector3 adjustmentForSitPose = new Vector3(0.75f, 0, m_sitAvatarHeight + .3f) * standRotationZ;
2656 //Vector3 standPos = ParentPosition;
2657
2658// Vector3 standPositionAdjustment
2659// = part.SitTargetPosition + new Vector3(0.5f, 0f, m_sitAvatarHeight / 2f);
2660 Vector3 adjustmentForSitPosition = OffsetPosition * part.ParentGroup.GroupRotation - SIT_TARGET_ADJUSTMENT * part.GetWorldRotation();
2661 3215
2662 // XXX: This is based on the physics capsule sizes. Need to find a better way to read this rather than 3216 Vector3 standPos = sitPartWorldPosition + adjustmentForSitPose;
2663 // hardcoding here. 3217 m_pos = standPos;
2664 Vector3 adjustmentForSitPose = new Vector3(0.74f, 0f, 0f) * standRotation;
2665 3218
2666 Vector3 standPos = part.ParentGroup.AbsolutePosition + adjustmentForSitPosition + adjustmentForSitPose;
2667
2668// m_log.DebugFormat(
2669// "[SCENE PRESENCE]: Setting stand to pos {0}, (adjustmentForSitPosition {1}, adjustmentForSitPose {2}) rotation {3} for {4} in {5}",
2670// standPos, adjustmentForSitPosition, adjustmentForSitPose, standRotation, Name, Scene.Name);
2671
2672 Rotation = standRotation;
2673 AbsolutePosition = standPos;
2674 } 3219 }
2675 3220
2676 // We need to wait until we have calculated proper stand positions before sitting up the physical 3221 // We need to wait until we have calculated proper stand positions before sitting up the physical
2677 // avatar to avoid race conditions. 3222 // avatar to avoid race conditions.
2678 if (PhysicsActor == null) 3223 if (PhysicsActor == null)
2679 AddToPhysicalScene(false); 3224 AddToPhysicalScene(false);
2680 3225
2681 if (satOnObject) 3226 if (satOnObject)
2682 { 3227 {
2683 SendAvatarDataToAllClients();
2684 m_requestedSitTargetID = 0; 3228 m_requestedSitTargetID = 0;
2685
2686 part.RemoveSittingAvatar(this); 3229 part.RemoveSittingAvatar(this);
2687
2688 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 3230 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
3231
3232 SendAvatarDataToAllAgents();
3233 m_scene.EventManager.TriggerParcelPrimCountTainted(); // update select/ sat on
2689 } 3234 }
2690 3235
2691 else if (PhysicsActor == null) 3236 // reset to default sitAnimation
2692 AddToPhysicalScene(false); 3237 sitAnimation = "SIT";
3238
3239// Animator.TrySetMovementAnimation("STAND");
3240 Animator.SetMovementAnimations("STAND");
2693 3241
2694 Animator.TrySetMovementAnimation("STAND");
2695 TriggerScenePresenceUpdated(); 3242 TriggerScenePresenceUpdated();
2696 } 3243 }
2697 3244
@@ -2746,28 +3293,14 @@ namespace OpenSim.Region.Framework.Scenes
2746 3293
2747 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) 3294 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
2748 { 3295 {
2749// m_log.DebugFormat(
2750// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
2751// Name, part.Name, part.LocalId);
2752
2753 offset = part.SitTargetPosition; 3296 offset = part.SitTargetPosition;
2754 sitOrientation = part.SitTargetOrientation; 3297 sitOrientation = part.SitTargetOrientation;
2755 3298
2756 if (!part.IsRoot)
2757 {
2758 // m_log.DebugFormat("Old sit orient {0}", sitOrientation);
2759 sitOrientation = part.RotationOffset * sitOrientation;
2760 // m_log.DebugFormat("New sit orient {0}", sitOrientation);
2761// m_log.DebugFormat("Old sit offset {0}", offset);
2762 offset = offset * part.RotationOffset;
2763// m_log.DebugFormat("New sit offset {0}", offset);
2764 }
2765
2766 canSit = true; 3299 canSit = true;
2767 } 3300 }
2768 else 3301 else
2769 { 3302 {
2770 if (PhysicsSit(part,offset)) // physics engine 3303 if (PhysicsSit(part,offset)) // physics engine
2771 return; 3304 return;
2772 3305
2773 Vector3 pos = part.AbsolutePosition + offset; 3306 Vector3 pos = part.AbsolutePosition + offset;
@@ -2781,55 +3314,45 @@ namespace OpenSim.Region.Framework.Scenes
2781 3314
2782 if (canSit) 3315 if (canSit)
2783 { 3316 {
2784
2785 if (PhysicsActor != null) 3317 if (PhysicsActor != null)
2786 { 3318 {
2787 // We can remove the physicsActor until they stand up. 3319 // We can remove the physicsActor until they stand up.
2788 RemoveFromPhysicalScene(); 3320 RemoveFromPhysicalScene();
2789 } 3321 }
2790 3322
2791 if (MovingToTarget) 3323 if (m_movingToTarget)
2792 ResetMoveToTarget(); 3324 ResetMoveToTarget();
2793 3325
2794 Velocity = Vector3.Zero; 3326 Velocity = Vector3.Zero;
3327 m_AngularVelocity = Vector3.Zero;
2795 3328
2796 part.AddSittingAvatar(this); 3329 part.AddSittingAvatar(this);
2797 3330
2798 cameraAtOffset = part.GetCameraAtOffset(); 3331 cameraAtOffset = part.GetCameraAtOffset();
2799
2800 if (!part.IsRoot && cameraAtOffset == Vector3.Zero)
2801 cameraAtOffset = part.ParentGroup.RootPart.GetCameraAtOffset();
2802
2803 bool cameraEyeOffsetFromRootForChild = false;
2804 cameraEyeOffset = part.GetCameraEyeOffset(); 3332 cameraEyeOffset = part.GetCameraEyeOffset();
2805 3333
2806 if (!part.IsRoot && cameraEyeOffset == Vector3.Zero) 3334 forceMouselook = part.GetForceMouselook();
2807 {
2808 cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset();
2809 cameraEyeOffsetFromRootForChild = true;
2810 }
2811 3335
2812 if ((cameraEyeOffset != Vector3.Zero && !cameraEyeOffsetFromRootForChild) || cameraAtOffset != Vector3.Zero) 3336 if (!part.IsRoot)
2813 { 3337 {
2814 if (!part.IsRoot) 3338 sitOrientation = part.RotationOffset * sitOrientation;
3339 offset = offset * part.RotationOffset;
3340 offset += part.OffsetPosition;
3341
3342 if (cameraAtOffset == Vector3.Zero && cameraEyeOffset == Vector3.Zero)
2815 { 3343 {
2816 cameraEyeOffset = cameraEyeOffset * part.RotationOffset; 3344 cameraAtOffset = part.ParentGroup.RootPart.GetCameraAtOffset();
3345 cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset();
3346 }
3347 else
3348 {
3349 cameraAtOffset = cameraAtOffset * part.RotationOffset;
2817 cameraAtOffset += part.OffsetPosition; 3350 cameraAtOffset += part.OffsetPosition;
3351 cameraEyeOffset = cameraEyeOffset * part.RotationOffset;
3352 cameraEyeOffset += part.OffsetPosition;
2818 } 3353 }
2819
2820 cameraEyeOffset += part.OffsetPosition;
2821 } 3354 }
2822 3355
2823// m_log.DebugFormat(
2824// "[SCENE PRESENCE]: Using cameraAtOffset {0}, cameraEyeOffset {1} for sit on {2} by {3} in {4}",
2825// cameraAtOffset, cameraEyeOffset, part.Name, Name, Scene.Name);
2826
2827 forceMouselook = part.GetForceMouselook();
2828
2829 // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is
2830 // being sat upon.
2831 offset += part.OffsetPosition;
2832
2833 ControllingClient.SendSitResponse( 3356 ControllingClient.SendSitResponse(
2834 part.ParentGroup.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 3357 part.ParentGroup.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2835 3358
@@ -2840,6 +3363,7 @@ namespace OpenSim.Region.Framework.Scenes
2840 // Moved here to avoid a race with default sit anim 3363 // Moved here to avoid a race with default sit anim
2841 // The script event needs to be raised after the default sit anim is set. 3364 // The script event needs to be raised after the default sit anim is set.
2842 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 3365 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
3366 m_scene.EventManager.TriggerParcelPrimCountTainted(); // update select/ sat on
2843 } 3367 }
2844 } 3368 }
2845 3369
@@ -2862,7 +3386,6 @@ namespace OpenSim.Region.Framework.Scenes
2862 { 3386 {
2863 m_requestedSitTargetID = part.LocalId; 3387 m_requestedSitTargetID = part.LocalId;
2864 m_requestedSitTargetUUID = part.UUID; 3388 m_requestedSitTargetUUID = part.UUID;
2865
2866 } 3389 }
2867 else 3390 else
2868 { 3391 {
@@ -2875,13 +3398,8 @@ namespace OpenSim.Region.Framework.Scenes
2875 // returns false if does not suport so older sit can be tried 3398 // returns false if does not suport so older sit can be tried
2876 public bool PhysicsSit(SceneObjectPart part, Vector3 offset) 3399 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2877 { 3400 {
2878// TODO: Pull in these bits
2879 return false;
2880/*
2881 if (part == null || part.ParentGroup.IsAttachment) 3401 if (part == null || part.ParentGroup.IsAttachment)
2882 {
2883 return true; 3402 return true;
2884 }
2885 3403
2886 if ( m_scene.PhysicsScene == null) 3404 if ( m_scene.PhysicsScene == null)
2887 return false; 3405 return false;
@@ -2893,24 +3411,20 @@ namespace OpenSim.Region.Framework.Scenes
2893 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot."); 3411 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2894 else 3412 else
2895 { // non physical phantom TODO 3413 { // non physical phantom TODO
2896 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot."); 3414// ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2897 return false; 3415 return false;
2898 } 3416 }
2899 return true; 3417 return true;
2900 } 3418 }
2901 3419
2902
2903 // not doing autopilot
2904 m_requestedSitTargetID = 0;
2905
2906 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0) 3420 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
3421 {
2907 return true; 3422 return true;
3423 }
2908 3424
2909 return false; 3425 return false;
2910*/
2911 } 3426 }
2912 3427
2913
2914 private bool CanEnterLandPosition(Vector3 testPos) 3428 private bool CanEnterLandPosition(Vector3 testPos)
2915 { 3429 {
2916 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y); 3430 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
@@ -2939,7 +3453,7 @@ namespace OpenSim.Region.Framework.Scenes
2939 if (part == null) 3453 if (part == null)
2940 return; 3454 return;
2941 3455
2942 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation(); 3456 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2943 if(!CanEnterLandPosition(targetPos)) 3457 if(!CanEnterLandPosition(targetPos))
2944 { 3458 {
2945 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot"); 3459 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
@@ -2948,36 +3462,58 @@ namespace OpenSim.Region.Framework.Scenes
2948 3462
2949 RemoveFromPhysicalScene(); 3463 RemoveFromPhysicalScene();
2950 3464
2951 if (MovingToTarget) 3465 if (m_movingToTarget)
2952 ResetMoveToTarget(); 3466 ResetMoveToTarget();
2953 3467
2954 Velocity = Vector3.Zero; 3468 Velocity = Vector3.Zero;
3469 m_AngularVelocity = Vector3.Zero;
2955 3470
3471 m_requestedSitTargetID = 0;
2956 part.AddSittingAvatar(this); 3472 part.AddSittingAvatar(this);
2957 3473
3474 ParentPart = part;
3475 ParentID = part.LocalId;
3476
2958 Vector3 cameraAtOffset = part.GetCameraAtOffset(); 3477 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2959 Vector3 cameraEyeOffset = part.GetCameraEyeOffset(); 3478 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2960 bool forceMouselook = part.GetForceMouselook(); 3479 bool forceMouselook = part.GetForceMouselook();
2961 3480
2962 ControllingClient.SendSitResponse( 3481 if (!part.IsRoot)
2963 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 3482 {
3483 Orientation = part.RotationOffset * Orientation;
3484 offset = offset * part.RotationOffset;
3485 offset += part.OffsetPosition;
2964 3486
2965 // not using autopilot 3487 if (cameraAtOffset == Vector3.Zero && cameraEyeOffset == Vector3.Zero)
3488 {
3489 cameraAtOffset = part.ParentGroup.RootPart.GetCameraAtOffset();
3490 cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset();
3491 }
3492 else
3493 {
3494 cameraAtOffset = cameraAtOffset * part.RotationOffset;
3495 cameraAtOffset += part.OffsetPosition;
3496 cameraEyeOffset = cameraEyeOffset * part.RotationOffset;
3497 cameraEyeOffset += part.OffsetPosition;
3498 }
3499 }
2966 3500
2967 Rotation = Orientation; 3501 m_bodyRot = Orientation;
2968 m_pos = offset; 3502 m_pos = offset;
2969 3503
2970 m_requestedSitTargetID = 0; 3504 ControllingClient.SendSitResponse(
3505 part.ParentGroup.UUID, offset, Orientation, true, cameraAtOffset, cameraEyeOffset, forceMouselook);
2971 3506
2972 ParentPart = part; 3507 SendAvatarDataToAllAgents();
2973 ParentID = part.LocalId; 3508
2974 if(status == 3) 3509 if (status == 3)
2975 Animator.TrySetMovementAnimation("SIT_GROUND"); 3510 sitAnimation = "SIT_GROUND";
2976 else 3511 else
2977 Animator.TrySetMovementAnimation("SIT"); 3512 sitAnimation = "SIT";
2978 SendAvatarDataToAllClients();
2979 3513
3514 Animator.SetMovementAnimations("SIT");
2980 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 3515 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
3516 m_scene.EventManager.TriggerParcelPrimCountTainted(); // update select/ sat on
2981 } 3517 }
2982 3518
2983 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 3519 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
@@ -2985,7 +3521,7 @@ namespace OpenSim.Region.Framework.Scenes
2985 if (IsChildAgent) 3521 if (IsChildAgent)
2986 return; 3522 return;
2987 3523
2988 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); 3524 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
2989 3525
2990 if (part != null) 3526 if (part != null)
2991 { 3527 {
@@ -3007,45 +3543,77 @@ namespace OpenSim.Region.Framework.Scenes
3007// "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}", 3543// "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}",
3008// Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId); 3544// Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId);
3009 3545
3010 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0); 3546 double x, y, z, m;
3011 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w); 3547 Vector3 sitOffset;
3012 3548 Quaternion r = sitTargetOrient;
3013 //Quaternion result = (sitTargetOrient * vq) * nq;
3014 3549
3015 double x, y, z, m1, m2; 3550 Vector3 newPos;
3016 3551
3017 Quaternion r = sitTargetOrient; 3552 if (LegacySitOffsets)
3018 m1 = r.X * r.X + r.Y * r.Y;
3019 m2 = r.Z * r.Z + r.W * r.W;
3020
3021 // Rotate the vector <0, 0, 1>
3022 x = 2 * (r.X * r.Z + r.Y * r.W);
3023 y = 2 * (-r.X * r.W + r.Y * r.Z);
3024 z = m2 - m1;
3025
3026 // Set m to be the square of the norm of r.
3027 double m = m1 + m2;
3028
3029 // This constant is emperically determined to be what is used in SL.
3030 // See also http://opensimulator.org/mantis/view.php?id=7096
3031 double offset = 0.05;
3032
3033 // Normally m will be ~ 1, but if someone passed a handcrafted quaternion
3034 // to llSitTarget with values so small that squaring them is rounded off
3035 // to zero, then m could be zero. The result of this floating point
3036 // round off error (causing us to skip this impossible normalization)
3037 // is only 5 cm.
3038 if (m > 0.000001)
3039 { 3553 {
3040 offset /= m; 3554 double m1,m2;
3555
3556 m1 = r.X * r.X + r.Y * r.Y;
3557 m2 = r.Z * r.Z + r.W * r.W;
3558
3559 // Rotate the vector <0, 0, 1>
3560 x = 2 * (r.X * r.Z + r.Y * r.W);
3561 y = 2 * (-r.X * r.W + r.Y * r.Z);
3562 z = m2 - m1;
3563
3564 // Set m to be the square of the norm of r.
3565 m = m1 + m2;
3566
3567 // This constant is emperically determined to be what is used in SL.
3568 // See also http://opensimulator.org/mantis/view.php?id=7096
3569 double offset = 0.05;
3570
3571 // Normally m will be ~ 1, but if someone passed a handcrafted quaternion
3572 // to llSitTarget with values so small that squaring them is rounded off
3573 // to zero, then m could be zero. The result of this floating point
3574 // round off error (causing us to skip this impossible normalization)
3575 // is only 5 cm.
3576 if (m > 0.000001)
3577 {
3578 offset /= m;
3579 }
3580
3581 Vector3 up = new Vector3((float)x, (float)y, (float)z);
3582 sitOffset = up * (float)offset;
3583 newPos = sitTargetPos - sitOffset + SIT_TARGET_ADJUSTMENT;
3041 } 3584 }
3585 else
3586 {
3587 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
3588
3589 if (Math.Abs(1.0 - m) > 0.000001)
3590 {
3591 if(m != 0)
3592 {
3593 m = 1.0 / Math.Sqrt(m);
3594 r.X *= (float)m;
3595 r.Y *= (float)m;
3596 r.Z *= (float)m;
3597 r.W *= (float)m;
3598 }
3599 else
3600 {
3601 r.X = 0.0f;
3602 r.Y = 0.0f;
3603 r.Z = 0.0f;
3604 r.W = 1.0f;
3605 m = 1.0f;
3606 }
3607 }
3042 3608
3043 Vector3 up = new Vector3((float)x, (float)y, (float)z); 3609 x = 2 * (r.X * r.Z + r.Y * r.W);
3044 Vector3 sitOffset = up * (float)offset; 3610 y = 2 * (-r.X * r.W + r.Y * r.Z);
3611 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
3612 Vector3 up = new Vector3((float)x, (float)y, (float)z);
3613 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
3614 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
3615 }
3045 3616
3046 // sitOffset is in Avatar Center coordinates: from origin to 'sitTargetPos + SIT_TARGET_ADJUSTMENT'.
3047 // So, we need to _substract_ it to get to the origin of the Avatar Center.
3048 Vector3 newPos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
3049 Quaternion newRot; 3617 Quaternion newRot;
3050 3618
3051 if (part.IsRoot) 3619 if (part.IsRoot)
@@ -3078,19 +3646,25 @@ namespace OpenSim.Region.Framework.Scenes
3078// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); 3646// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
3079 } 3647 }
3080 3648
3649 part.AddSittingAvatar(this);
3081 ParentPart = part; 3650 ParentPart = part;
3082 ParentID = m_requestedSitTargetID; 3651 ParentID = m_requestedSitTargetID;
3652
3653 RemoveFromPhysicalScene();
3083 m_AngularVelocity = Vector3.Zero; 3654 m_AngularVelocity = Vector3.Zero;
3084 Velocity = Vector3.Zero; 3655 Velocity = Vector3.Zero;
3085 RemoveFromPhysicalScene();
3086 3656
3087 String sitAnimation = "SIT"; 3657 m_requestedSitTargetID = 0;
3658
3659 SendAvatarDataToAllAgents();
3660
3661 sitAnimation = "SIT";
3088 if (!String.IsNullOrEmpty(part.SitAnimation)) 3662 if (!String.IsNullOrEmpty(part.SitAnimation))
3089 { 3663 {
3090 sitAnimation = part.SitAnimation; 3664 sitAnimation = part.SitAnimation;
3091 } 3665 }
3092 Animator.TrySetMovementAnimation(sitAnimation); 3666// Animator.TrySetMovementAnimation(sitAnimation);
3093 SendAvatarDataToAllClients(); 3667 Animator.SetMovementAnimations("SIT");
3094 TriggerScenePresenceUpdated(); 3668 TriggerScenePresenceUpdated();
3095 } 3669 }
3096 } 3670 }
@@ -3101,11 +3675,17 @@ namespace OpenSim.Region.Framework.Scenes
3101 return; 3675 return;
3102 3676
3103// m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. 3677// m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick..
3104 m_AngularVelocity = Vector3.Zero; 3678 sitAnimation = "SIT_GROUND_CONSTRAINED";
3105 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 3679// Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
3106 TriggerScenePresenceUpdated(); 3680// TriggerScenePresenceUpdated();
3107 SitGround = true; 3681 SitGround = true;
3108 RemoveFromPhysicalScene(); 3682 RemoveFromPhysicalScene();
3683
3684 m_AngularVelocity = Vector3.Zero;
3685 Velocity = Vector3.Zero;
3686
3687 Animator.SetMovementAnimations("SITGROUND");
3688 TriggerScenePresenceUpdated();
3109 } 3689 }
3110 3690
3111 /// <summary> 3691 /// <summary>
@@ -3129,86 +3709,84 @@ namespace OpenSim.Region.Framework.Scenes
3129 TriggerScenePresenceUpdated(); 3709 TriggerScenePresenceUpdated();
3130 } 3710 }
3131 3711
3712 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
3713 {
3714 Animator.avnChangeAnim(animID, addRemove, sendPack);
3715 }
3716
3132 /// <summary> 3717 /// <summary>
3133 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 3718 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
3134 /// </summary> 3719 /// </summary>
3135 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 3720 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
3136 /// <param name="thisAddSpeedModifier"> 3721 /// <param name="thisAddSpeedModifier">
3137 /// Optional additional speed modifier for this particular add. Default is 1</param> 3722 /// Optional additional speed modifier for this particular add. Default is 1</param>
3138 public void AddNewMovement(Vector3 vec, float thisAddSpeedModifier = 1) 3723 public void AddNewMovement(Vector3 vec, float thisAddSpeedModifier = 1, bool breaking = false)
3139 { 3724 {
3140// m_log.DebugFormat( 3725 // m_log.DebugFormat(
3141// "[SCENE PRESENCE]: Adding new movement {0} with rotation {1}, thisAddSpeedModifier {2} for {3}", 3726 // "[SCENE PRESENCE]: Adding new movement {0} with rotation {1}, thisAddSpeedModifier {2} for {3}",
3142// vec, Rotation, thisAddSpeedModifier, Name); 3727 // vec, Rotation, thisAddSpeedModifier, Name);
3143 3728 m_delayedStop = -1;
3729 // rotate from avatar coord space to world
3144 Quaternion rot = Rotation; 3730 Quaternion rot = Rotation;
3145 if (!Flying && PresenceType != PresenceType.Npc) 3731 if (!Flying && PresenceType != PresenceType.Npc)
3146 { 3732 {
3147 // The only situation in which we care about X and Y is avatar flying. The rest of the time 3733 // force rotation to be around Z only, if not flying
3148 // these parameters are not relevant for determining avatar movement direction and cause issues such 3734 // needed for mouselook
3149 // as wrong walk speed if the camera is rotated.
3150 rot.X = 0; 3735 rot.X = 0;
3151 rot.Y = 0; 3736 rot.Y = 0;
3152 rot.Normalize();
3153 } 3737 }
3154 3738
3155 Vector3 direc = vec * rot; 3739 Vector3 direc = vec * rot;
3156 direc.Normalize(); 3740 direc.Normalize();
3157 3741
3158 if (Flying != FlyingOld) // add for fly velocity control
3159 {
3160 FlyingOld = Flying; // add for fly velocity control
3161 if (!Flying)
3162 WasFlying = true; // add for fly velocity control
3163 }
3164
3165 if (IsColliding)
3166 WasFlying = false; // add for fly velocity control
3167
3168 if ((vec.Z == 0f) && !Flying) 3742 if ((vec.Z == 0f) && !Flying)
3169 direc.Z = 0f; // Prevent camera WASD up. 3743 direc.Z = 0f; // Prevent camera WASD up.
3170 3744
3171 direc *= 0.03f * 128f * SpeedModifier * thisAddSpeedModifier; 3745 bool notmvtrgt = !m_movingToTarget || m_moveToSpeed <= 0;
3746 // odd rescalings
3747 if(notmvtrgt)
3748 direc *= 4.096f * SpeedModifier * thisAddSpeedModifier;
3749 else
3750 direc *= m_moveToSpeed;
3172 3751
3173// m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name); 3752 // m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name);
3174 3753
3175 if (PhysicsActor != null) 3754 if (Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling
3755 && (PhysicsActor == null || !PhysicsActor.PIDHoverActive))
3176 { 3756 {
3177 if (Flying) 3757 if (breaking)
3178 { 3758 direc.Z = -9999f; //hack to tell physics to stop on Z
3759 else
3760 direc = Vector3.Zero;
3761 }
3762 else if (Flying)
3763 {
3764 if (IsColliding && direc.Z < 0)
3765 // landing situation, prevent avatar moving or it may fail to land
3766 // animator will handle this condition and do the land
3767 direc = Vector3.Zero;
3768 else if(notmvtrgt)
3179 direc *= 4.0f; 3769 direc *= 4.0f;
3180 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 3770 }
3181 //if (controlland) 3771 else if (IsColliding)
3182 // m_log.Info("[AGENT]: landCommand"); 3772 {
3183 //if (IsColliding) 3773 if (direc.Z > 2.0f && notmvtrgt) // reinforce jumps
3184 // m_log.Info("[AGENT]: colliding");
3185 //if (Flying && IsColliding && controlland)
3186 //{
3187 // StopFlying();
3188 // m_log.Info("[AGENT]: Stop Flying");
3189 //}
3190 }
3191 if (Animator.Falling && WasFlying) // if falling from flying, disable motion add
3192 {
3193 direc *= 0.0f;
3194 }
3195 else if (!Flying && IsColliding)
3196 { 3774 {
3197 if (direc.Z > 2.0f) 3775 direc.Z *= 2.6f;
3198 {
3199 direc.Z *= 2.6f;
3200
3201 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
3202// Animator.TrySetMovementAnimation("PREJUMP");
3203// Animator.TrySetMovementAnimation("JUMP");
3204 }
3205 } 3776 }
3777 else if (direc.Z < 0) // on a surface moving down (pg down) only changes animation
3778 direc.Z = 0;
3206 } 3779 }
3207 3780
3208// m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name); 3781 // m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name);
3209 3782/*
3210 // TODO: Add the force instead of only setting it to support multiple forces per frame? 3783 lock(m_forceToApplyLock)
3211 m_forceToApply = direc; 3784 {
3785 m_forceToApply = direc;
3786 m_forceToApplyValid = true;
3787 }
3788*/
3789 TargetVelocity = direc;
3212 Animator.UpdateMovementAnimations(); 3790 Animator.UpdateMovementAnimations();
3213 } 3791 }
3214 3792
@@ -3216,51 +3794,116 @@ namespace OpenSim.Region.Framework.Scenes
3216 3794
3217 #region Overridden Methods 3795 #region Overridden Methods
3218 3796
3797 const float ROTATION_TOLERANCE = 0.01f;
3798 const float VELOCITY_TOLERANCE = 0.1f;
3799 const float LOWVELOCITYSQ = 0.1f;
3800 const float POSITION_LARGETOLERANCE = 5f;
3801 const float POSITION_SMALLTOLERANCE = 0.05f;
3802
3219 public override void Update() 3803 public override void Update()
3220 { 3804 {
3221 if (IsChildAgent == false) 3805 if(IsChildAgent || IsDeleted)
3222 { 3806 return;
3223 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 3807
3224 // grab the latest PhysicsActor velocity, whereas m_velocity is often 3808 CheckForBorderCrossing();
3225 // storing a requested force instead of an actual traveling velocity
3226 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
3227 SendAvatarDataToAllClients();
3228 3809
3229 // Allow any updates for sitting avatars to that llSetPrimitiveLinkParams() can work for very 3810 if (IsInTransit || IsLoggingIn)
3230 // small increments (e.g. sit position adjusters). An alternative may be to eliminate the tolerance 3811 return;
3231 // checks on all updates but the ramifications of this would need careful consideration.
3232 bool updateClients
3233 = IsSatOnObject && (Rotation != m_lastRotation || Velocity != m_lastVelocity || m_pos != m_lastPosition);
3234
3235 if (!updateClients)
3236 updateClients
3237 = !Rotation.ApproxEquals(m_lastRotation, Scene.RootRotationUpdateTolerance)
3238 || !Velocity.ApproxEquals(m_lastVelocity, Scene.RootVelocityUpdateTolerance)
3239 || !m_pos.ApproxEquals(m_lastPosition, Scene.RootPositionUpdateTolerance);
3240 3812
3241 if (updateClients) 3813 if(m_movingToTarget)
3814 {
3815 m_delayedStop = -1;
3816 Vector3 control = Vector3.Zero;
3817 if(HandleMoveToTargetUpdate(1f, ref control))
3818 AddNewMovement(control);
3819 }
3820 else if(m_delayedStop > 0)
3821 {
3822 if(IsSatOnObject)
3823 m_delayedStop = -1;
3824 else
3825 if(Util.GetTimeStampMS() > m_delayedStop)
3826 AddNewMovement(Vector3.Zero);
3827 }
3828
3829 if (Appearance.AvatarSize != m_lastSize)
3830 SendAvatarDataToAllAgents();
3831
3832 // Send terse position update if not sitting and position, velocity, or rotation
3833 // has changed significantly from last sent update
3834 if (!IsSatOnObject)
3835 {
3836 // this does need to be more complex later
3837 Vector3 vel = Velocity;
3838 Vector3 dpos = m_pos - m_lastPosition;
3839 if( State != m_lastState ||
3840 Math.Abs(vel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
3841 Math.Abs(vel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
3842 Math.Abs(vel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE ||
3843
3844 Math.Abs(m_bodyRot.X - m_lastRotation.X) > ROTATION_TOLERANCE ||
3845 Math.Abs(m_bodyRot.Y - m_lastRotation.Y) > ROTATION_TOLERANCE ||
3846 Math.Abs(m_bodyRot.Z - m_lastRotation.Z) > ROTATION_TOLERANCE ||
3847
3848 (vel == Vector3.Zero && m_lastVelocity != Vector3.Zero) ||
3849
3850 Math.Abs(dpos.X) > POSITION_LARGETOLERANCE ||
3851 Math.Abs(dpos.Y) > POSITION_LARGETOLERANCE ||
3852 Math.Abs(dpos.Z) > POSITION_LARGETOLERANCE ||
3853
3854 ( (Math.Abs(dpos.X) > POSITION_SMALLTOLERANCE ||
3855 Math.Abs(dpos.Y) > POSITION_SMALLTOLERANCE ||
3856 Math.Abs(dpos.Z) > POSITION_SMALLTOLERANCE)
3857 && vel.LengthSquared() < LOWVELOCITYSQ
3858 ) ||
3859
3860 Math.Abs(CollisionPlane.X - m_lastCollisionPlane.X) > POSITION_SMALLTOLERANCE ||
3861 Math.Abs(CollisionPlane.Y - m_lastCollisionPlane.Y) > POSITION_SMALLTOLERANCE ||
3862 Math.Abs(CollisionPlane.W - m_lastCollisionPlane.W) > POSITION_SMALLTOLERANCE
3863 )
3242 { 3864 {
3243 SendTerseUpdateToAllClients(); 3865 SendTerseUpdateToAllClients();
3244
3245 // Update the "last" values
3246 m_lastPosition = m_pos;
3247 m_lastRotation = Rotation;
3248 m_lastVelocity = Velocity;
3249 } 3866 }
3250
3251 if (Scene.AllowAvatarCrossing)
3252 CheckForBorderCrossing();
3253
3254 CheckForSignificantMovement(); // sends update to the modules.
3255 } 3867 }
3868 CheckForSignificantMovement();
3256 } 3869 }
3257 3870
3258 #endregion 3871 #endregion
3259 3872
3260 #region Update Client(s) 3873 #region Update Client(s)
3261 3874
3875 public void SendUpdateToAgent(ScenePresence p)
3876 {
3877 IClientAPI remoteClient = p.ControllingClient;
3878
3879 if (remoteClient.IsActive)
3880 {
3881 //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
3882 remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate);
3883 m_scene.StatsReporter.AddAgentUpdates(1);
3884 }
3885 }
3886
3887 public void SendFullUpdateToClient(IClientAPI remoteClient)
3888 {
3889 if (remoteClient.IsActive)
3890 {
3891 //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
3892 remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate);
3893 m_scene.StatsReporter.AddAgentUpdates(1);
3894 }
3895 }
3896
3897 // this is diferente from SendTerseUpdateToClient
3898 // this sends bypassing entities updates
3899 public void SendAgentTerseUpdate(ISceneEntity p)
3900 {
3901 ControllingClient.SendAgentTerseUpdate(p);
3902 }
3903
3262 /// <summary> 3904 /// <summary>
3263 /// Sends a location update to the client connected to this scenePresence 3905 /// Sends a location update to the client connected to this scenePresence
3906 /// via entity updates
3264 /// </summary> 3907 /// </summary>
3265 /// <param name="remoteClient"></param> 3908 /// <param name="remoteClient"></param>
3266 public void SendTerseUpdateToClient(IClientAPI remoteClient) 3909 public void SendTerseUpdateToClient(IClientAPI remoteClient)
@@ -3269,31 +3912,7 @@ namespace OpenSim.Region.Framework.Scenes
3269 // server. 3912 // server.
3270 if (remoteClient.IsActive) 3913 if (remoteClient.IsActive)
3271 { 3914 {
3272 if (Scene.RootTerseUpdatePeriod > 1)
3273 {
3274// Console.WriteLine(
3275// "{0} {1} {2} {3} {4} {5} for {6} to {7}",
3276// remoteClient.AgentId, UUID, remoteClient.SceneAgent.IsChildAgent, m_terseUpdateCount, Scene.RootTerseUpdatePeriod, Velocity.ApproxEquals(Vector3.Zero, 0.001f), Name, remoteClient.Name);
3277 if (remoteClient.AgentId != UUID
3278 && !remoteClient.SceneAgent.IsChildAgent
3279 && m_terseUpdateCount % Scene.RootTerseUpdatePeriod != 0
3280 && !Velocity.ApproxEquals(Vector3.Zero, 0.001f))
3281 {
3282// m_log.DebugFormat("[SCENE PRESENCE]: Discarded update from {0} to {1}, args {2} {3} {4} {5} {6} {7}",
3283// Name, remoteClient.Name, remoteClient.AgentId, UUID, remoteClient.SceneAgent.IsChildAgent, m_terseUpdateCount, Scene.RootTerseUpdatePeriod, Velocity.ApproxEquals(Vector3.Zero, 0.001f));
3284
3285 return;
3286 }
3287 }
3288
3289 if (Scene.ChildTerseUpdatePeriod > 1
3290 && remoteClient.SceneAgent.IsChildAgent
3291 && m_terseUpdateCount % Scene.ChildTerseUpdatePeriod != 0
3292 && !Velocity.ApproxEquals(Vector3.Zero, 0.001f))
3293 return;
3294
3295 //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); 3915 //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
3296
3297 remoteClient.SendEntityUpdate( 3916 remoteClient.SendEntityUpdate(
3298 this, 3917 this,
3299 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity 3918 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
@@ -3303,59 +3922,51 @@ namespace OpenSim.Region.Framework.Scenes
3303 } 3922 }
3304 } 3923 }
3305 3924
3306 3925 public void SendTerseUpdateToAgent(ScenePresence p)
3307 // vars to support reduced update frequency when velocity is unchanged
3308 private Vector3 lastVelocitySentToAllClients = Vector3.Zero;
3309 private Vector3 lastPositionSentToAllClients = Vector3.Zero;
3310 private int lastTerseUpdateToAllClientsTick = Util.EnvironmentTickCount();
3311
3312 /// <summary>
3313 /// Send a location/velocity/accelleration update to all agents in scene
3314 /// </summary>
3315 public void SendTerseUpdateToAllClients()
3316 { 3926 {
3317 int currentTick = Util.EnvironmentTickCount(); 3927 IClientAPI remoteClient = p.ControllingClient;
3318
3319 // Decrease update frequency when avatar is moving but velocity is
3320 // not changing.
3321 // If there is a mismatch between distance travelled and expected
3322 // distance based on last velocity sent and velocity hasnt changed,
3323 // then send a new terse update
3324
3325 float timeSinceLastUpdate = (currentTick - lastTerseUpdateToAllClientsTick) * 0.001f;
3326
3327 Vector3 expectedPosition = lastPositionSentToAllClients + lastVelocitySentToAllClients * timeSinceLastUpdate;
3328 3928
3329 float distanceError = Vector3.Distance(OffsetPosition, expectedPosition); 3929 if (!remoteClient.IsActive)
3930 return;
3330 3931
3331 float speed = Velocity.Length(); 3932 if (ParcelHideThisAvatar && p.currentParcelUUID != currentParcelUUID && !p.IsViewerUIGod)
3332 float velocityDiff = Vector3.Distance(lastVelocitySentToAllClients, Velocity); 3933 return;
3333 3934
3334// m_log.DebugFormat( 3935 //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
3335// "[SCENE PRESENCE]: Delta-v {0}, lastVelocity {1}, Velocity {2} for {3} in {4}", 3936 remoteClient.SendEntityUpdate(
3336// velocidyDiff, lastVelocitySentToAllClients, Velocity, Name, Scene.Name); 3937 this,
3938 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
3939 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
3337 3940
3338 // assuming 5 ms. worst case precision for timer, use 2x that 3941 m_scene.StatsReporter.AddAgentUpdates(1);
3339 // for distance error threshold 3942 }
3340 float distanceErrorThreshold = speed * 0.01f;
3341 3943
3342 if (speed < 0.01f // allow rotation updates if avatar position is unchanged 3944 public void SendTerseUpdateToAgentNF(ScenePresence p)
3343 || Math.Abs(distanceError) > distanceErrorThreshold 3945 {
3344 || velocityDiff > 0.01f) // did velocity change from last update? 3946 IClientAPI remoteClient = p.ControllingClient;
3947 if (remoteClient.IsActive)
3345 { 3948 {
3346// m_log.DebugFormat( 3949 //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
3347// "[SCENE PRESENCE]: Update triggered with speed {0}, distanceError {1}, distanceThreshold {2}, delta-v {3} for {4} in {5}", 3950 remoteClient.SendEntityUpdate(this,
3348// speed, distanceError, distanceErrorThreshold, velocidyDiff, Name, Scene.Name); 3951 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
3349 3952 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
3350 lastVelocitySentToAllClients = Velocity; 3953 m_scene.StatsReporter.AddAgentUpdates(1);
3351 lastTerseUpdateToAllClientsTick = currentTick; 3954 }
3352 lastPositionSentToAllClients = OffsetPosition; 3955 }
3353 3956
3354 m_terseUpdateCount++; 3957 /// <summary>
3958 /// Send a location/velocity/accelleration update to all agents in scene
3959 /// </summary>
3960 public void SendTerseUpdateToAllClients()
3961 {
3962 m_lastState = State;
3963 m_lastPosition = m_pos;
3964 m_lastRotation = m_bodyRot;
3965 m_lastVelocity = Velocity;
3966 m_lastCollisionPlane = CollisionPlane;
3355 3967
3356// Console.WriteLine("Scheduled update for {0} in {1}", Name, Scene.Name); 3968 m_scene.ForEachScenePresence(SendTerseUpdateToAgent);
3357 m_scene.ForEachClient(SendTerseUpdateToClient); 3969 // Update the "last" values
3358 }
3359 TriggerScenePresenceUpdated(); 3970 TriggerScenePresenceUpdated();
3360 } 3971 }
3361 3972
@@ -3379,89 +3990,75 @@ namespace OpenSim.Region.Framework.Scenes
3379 ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); 3990 ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations);
3380 } 3991 }
3381 3992
3382 public void SendInitialDataToClient() 3993 public void SendInitialDataToMe()
3383 { 3994 {
3384 SentInitialDataToClient = true;
3385
3386 // Send all scene object to the new client 3995 // Send all scene object to the new client
3387 WorkManager.RunJob("SendInitialDataToClient", delegate 3996 SentInitialData = true;
3997 Util.FireAndForget(delegate
3388 { 3998 {
3389// m_log.DebugFormat(
3390// "[SCENE PRESENCE]: Sending initial data to {0} agent {1} in {2}, tp flags {3}",
3391// IsChildAgent ? "child" : "root", Name, Scene.Name, m_teleportFlags);
3392
3393 // we created a new ScenePresence (a new child agent) in a fresh region. 3999 // we created a new ScenePresence (a new child agent) in a fresh region.
3394 // Request info about all the (root) agents in this region 4000 // Request info about all the (root) agents in this region
3395 // Note: This won't send data *to* other clients in that region (children don't send) 4001 // Note: This won't send data *to* other clients in that region (children don't send)
3396 SendOtherAgentsAvatarDataToClient(); 4002 if (m_teleportFlags <= 0)
3397 SendOtherAgentsAppearanceToClient(); 4003 {
4004 Scene.SendLayerData(ControllingClient);
3398 4005
4006 ILandChannel landch = m_scene.LandChannel;
4007 if (landch != null)
4008 {
4009 landch.sendClientInitialLandInfo(ControllingClient);
4010 }
4011 }
4012
4013 SendOtherAgentsAvatarFullToMe();
3399 EntityBase[] entities = Scene.Entities.GetEntities(); 4014 EntityBase[] entities = Scene.Entities.GetEntities();
3400 foreach (EntityBase e in entities) 4015 foreach (EntityBase e in entities)
3401 { 4016 {
3402 if (e != null && e is SceneObjectGroup) 4017 if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment)
3403 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); 4018 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
3404 } 4019 }
3405 }, null, string.Format("SendInitialDataToClient ({0} in {1})", Name, Scene.Name), false, true); 4020
4021 m_reprioritizationLastPosition = AbsolutePosition;
4022 m_reprioritizationLastDrawDistance = DrawDistance;
4023 m_reprioritizationLastTime = Util.EnvironmentTickCount() + 15000; // delay it
4024 m_reprioritizationBusy = false;
4025
4026 });
3406 } 4027 }
3407 4028
3408 /// <summary> 4029 /// <summary>
3409 /// Do everything required once a client completes its movement into a region and becomes 4030 /// Send avatar full data appearance and animations for all other root agents to this agent, this agent
3410 /// a root agent. 4031 /// can be either a child or root
3411 /// </summary> 4032 /// </summary>
3412 private void ValidateAndSendAppearanceAndAgentData() 4033 public void SendOtherAgentsAvatarFullToMe()
3413 { 4034 {
3414 //m_log.DebugFormat("[SCENE PRESENCE] SendInitialData: {0} ({1})", Name, UUID); 4035 int count = 0;
3415 // Moved this into CompleteMovement to ensure that Appearance is initialized before 4036 m_scene.ForEachRootScenePresence(delegate(ScenePresence p)
3416 // the inventory arrives
3417 // m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
3418
3419 bool cachedappearance = false;
3420
3421 // We have an appearance but we may not have the baked textures. Check the asset cache
3422 // to see if all the baked textures are already here.
3423 if (m_scene.AvatarFactory != null)
3424 cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(this);
3425
3426 // If we aren't using a cached appearance, then clear out the baked textures
3427 if (!cachedappearance)
3428 { 4037 {
3429 Appearance.ResetAppearance(); 4038 // only send information about other root agents
3430 if (m_scene.AvatarFactory != null) 4039 if (p.UUID == UUID)
3431 m_scene.AvatarFactory.QueueAppearanceSave(UUID); 4040 return;
3432 }
3433
3434 // This agent just became root. We are going to tell everyone about it. The process of
3435 // getting other avatars information was initiated elsewhere immediately after the child circuit connected... don't do it
3436 // again here... this comes after the cached appearance check because the avatars
3437 // appearance goes into the avatar update packet
3438 SendAvatarDataToAllClients();
3439 4041
3440 // This invocation always shows up in the viewer logs as an error. Is it needed? 4042 // get the avatar, then a kill if can't see it
3441 SendAppearanceToClient(this); 4043 p.SendInitialAvatarDataToAgent(this);
3442 4044
3443 // If we are using the the cached appearance then send it out to everyone 4045 if (p.ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !IsViewerUIGod)
3444 if (cachedappearance) 4046 return;
3445 {
3446 m_log.DebugFormat("[SCENE PRESENCE]: Baked textures are in the cache for {0} in {1}", Name, m_scene.Name);
3447 4047
3448 // If the avatars baked textures are all in the cache, then we have a 4048 p.SendAppearanceToAgentNF(this);
3449 // complete appearance... send it out, if not, then we'll send it when 4049 p.SendAnimPackToAgentNF(this);
3450 // the avatar finishes updating its appearance 4050 p.SendAttachmentsToAgentNF(this);
3451 SendAppearanceToAllOtherClients(); 4051 count++;
3452 } 4052 });
3453 }
3454 4053
3455 public void SendAvatarDataToAllClients() 4054 m_scene.StatsReporter.AddAgentUpdates(count);
3456 {
3457 SendAvatarDataToAllClients(true);
3458 } 4055 }
3459 4056
3460 /// <summary> 4057 /// <summary>
3461 /// Send this agent's avatar data to all other root and child agents in the scene 4058 /// Send this agent's avatar data to all other root and child agents in the scene
3462 /// This agent must be root. This avatar will receive its own update. 4059 /// This agent must be root. This avatar will receive its own update.
3463 /// </summary> 4060 /// </summary>
3464 public void SendAvatarDataToAllClients(bool full) 4061 public void SendAvatarDataToAllAgents()
3465 { 4062 {
3466 //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAllAgents: {0} ({1})", Name, UUID); 4063 //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAllAgents: {0} ({1})", Name, UUID);
3467 // only send update from root agents to other clients; children are only "listening posts" 4064 // only send update from root agents to other clients; children are only "listening posts"
@@ -3470,64 +4067,73 @@ namespace OpenSim.Region.Framework.Scenes
3470 m_log.WarnFormat( 4067 m_log.WarnFormat(
3471 "[SCENE PRESENCE]: Attempt to send avatar data from a child agent for {0} in {1}", 4068 "[SCENE PRESENCE]: Attempt to send avatar data from a child agent for {0} in {1}",
3472 Name, Scene.RegionInfo.RegionName); 4069 Name, Scene.RegionInfo.RegionName);
3473
3474 return; 4070 return;
3475 } 4071 }
3476 4072
3477 m_lastSize = Appearance.AvatarSize; 4073 m_lastSize = Appearance.AvatarSize;
3478
3479 int count = 0; 4074 int count = 0;
4075
3480 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 4076 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3481 { 4077 {
3482 if (full) 4078 SendAvatarDataToAgent(scenePresence);
3483 SendAvatarDataToClient(scenePresence);
3484 else
3485 scenePresence.ControllingClient.SendAvatarDataImmediate(this);
3486 count++; 4079 count++;
3487 }); 4080 });
3488 4081
3489 m_scene.StatsReporter.AddAgentUpdates(count); 4082 m_scene.StatsReporter.AddAgentUpdates(count);
3490 } 4083 }
3491 4084 // sends avatar object to all clients so they cross it into region
3492 /// <summary> 4085 // then sends kills to hide
3493 /// Send avatar data for all other root agents to this agent, this agent 4086 public void SendInitialAvatarDataToAllAgents(List<ScenePresence> presences)
3494 /// can be either a child or root
3495 /// </summary>
3496 public void SendOtherAgentsAvatarDataToClient()
3497 { 4087 {
4088 m_lastSize = Appearance.AvatarSize;
3498 int count = 0; 4089 int count = 0;
3499 m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) 4090 foreach (ScenePresence p in presences)
3500 { 4091 {
3501 // only send information about other root agents 4092 p.ControllingClient.SendEntityFullUpdateImmediate(this);
3502 if (scenePresence.UUID == UUID) 4093 if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
3503 return; 4094 // either just kill the object
3504 4095 // p.ControllingClient.SendKillObject(new List<uint> {LocalId});
3505 scenePresence.SendAvatarDataToClient(this); 4096 // or also attachments viewer may still know about
3506 count++; 4097 SendKillTo(p);
3507 }); 4098 count++;
3508 4099 }
3509 m_scene.StatsReporter.AddAgentUpdates(count); 4100 m_scene.StatsReporter.AddAgentUpdates(count);
3510 } 4101 }
3511 4102
4103 public void SendInitialAvatarDataToAgent(ScenePresence p)
4104 {
4105 p.ControllingClient.SendEntityFullUpdateImmediate(this);
4106 if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
4107 // either just kill the object
4108 // p.ControllingClient.SendKillObject(new List<uint> {LocalId});
4109 // or also attachments viewer may still know about
4110 SendKillTo(p);
4111 }
4112
3512 /// <summary> 4113 /// <summary>
3513 /// Send avatar data to an agent. 4114 /// Send avatar data to an agent.
3514 /// </summary> 4115 /// </summary>
3515 /// <param name="avatar"></param> 4116 /// <param name="avatar"></param>
3516 public void SendAvatarDataToClient(ScenePresence avatar) 4117 public void SendAvatarDataToAgent(ScenePresence avatar)
3517 { 4118 {
3518 //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToClient from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); 4119 //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID);
4120 if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && !avatar.IsViewerUIGod)
4121 return;
4122 avatar.ControllingClient.SendEntityFullUpdateImmediate(this);
4123 }
3519 4124
3520 avatar.ControllingClient.SendAvatarDataImmediate(this); 4125 public void SendAvatarDataToAgentNF(ScenePresence avatar)
3521 Animator.SendAnimPackToClient(avatar.ControllingClient); 4126 {
4127 avatar.ControllingClient.SendEntityFullUpdateImmediate(this);
3522 } 4128 }
3523 4129
3524 /// <summary> 4130 /// <summary>
3525 /// Send this agent's appearance to all other root and child agents in the scene 4131 /// Send this agent's appearance to all other root and child agents in the scene
3526 /// This agent must be root. 4132 /// This agent must be root.
3527 /// </summary> 4133 /// </summary>
3528 public void SendAppearanceToAllOtherClients() 4134 public void SendAppearanceToAllOtherAgents()
3529 { 4135 {
3530// m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherClients: {0} {1}", Name, UUID); 4136 // m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} {1}", Name, UUID);
3531 4137
3532 // only send update from root agents to other clients; children are only "listening posts" 4138 // only send update from root agents to other clients; children are only "listening posts"
3533 if (IsChildAgent) 4139 if (IsChildAgent)
@@ -3538,109 +4144,217 @@ namespace OpenSim.Region.Framework.Scenes
3538 4144
3539 return; 4145 return;
3540 } 4146 }
3541 4147
3542 int count = 0; 4148 int count = 0;
3543 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 4149 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3544 { 4150 {
3545 // only send information to other root agents 4151 // only send information to other root agents
3546 if (scenePresence.UUID == UUID) 4152 if (scenePresence.UUID == UUID)
3547 return; 4153 return;
3548
3549 SendAppearanceToClient(scenePresence);
3550 count++;
3551 });
3552 4154
4155 SendAppearanceToAgent(scenePresence);
4156 count++;
4157 });
3553 m_scene.StatsReporter.AddAgentUpdates(count); 4158 m_scene.StatsReporter.AddAgentUpdates(count);
3554 } 4159 }
3555 4160
3556 /// <summary> 4161 public void SendAppearanceToAgent(ScenePresence avatar)
3557 /// Send appearance from all other root agents to this agent. this agent
3558 /// can be either root or child
3559 /// </summary>
3560 public void SendOtherAgentsAppearanceToClient()
3561 { 4162 {
3562// m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToClient {0} {1}", Name, UUID); 4163 // m_log.DebugFormat(
4164 // "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID);
4165 if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && !avatar.IsViewerUIGod)
4166 return;
4167 SendAppearanceToAgentNF(avatar);
4168 }
3563 4169
3564 int count = 0; 4170 public void SendAppearanceToAgentNF(ScenePresence avatar)
3565 m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) 4171 {
3566 { 4172 avatar.ControllingClient.SendAppearance(
3567 // only send information about other root agents 4173 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3568 if (scenePresence.UUID == UUID) 4174 }
3569 return;
3570
3571 scenePresence.SendAppearanceToClient(this);
3572 count++;
3573 });
3574 4175
3575 m_scene.StatsReporter.AddAgentUpdates(count); 4176 public void SendAnimPackToAgent(ScenePresence p)
4177 {
4178 if (IsChildAgent || Animator == null)
4179 return;
4180
4181 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
4182 return;
4183
4184 Animator.SendAnimPackToClient(p.ControllingClient);
3576 } 4185 }
3577 4186
3578 /// <summary> 4187 public void SendAnimPackToAgent(ScenePresence p, UUID[] animations, int[] seqs, UUID[] objectIDs)
3579 /// Send appearance data to an agent.
3580 /// </summary>
3581 /// <param name="avatar"></param>
3582 public void SendAppearanceToClient(ScenePresence avatar)
3583 { 4188 {
3584// m_log.DebugFormat( 4189 if (IsChildAgent)
3585// "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); 4190 return;
3586 4191
3587 avatar.ControllingClient.SendAppearance( 4192 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
3588 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 4193 return;
4194
4195 p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
4196 }
4197
4198 public void SendAnimPackToAgentNF(ScenePresence p)
4199 {
4200 if (IsChildAgent || Animator == null)
4201 return;
4202 Animator.SendAnimPackToClient(p.ControllingClient);
4203 }
4204
4205 public void SendAnimPackToAgentNF(ScenePresence p, UUID[] animations, int[] seqs, UUID[] objectIDs)
4206 {
4207 p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
4208 }
4209
4210 public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
4211 {
4212 if (IsChildAgent)
4213 return;
3589 4214
3590 4215 m_scene.ForEachScenePresence(delegate(ScenePresence p)
4216 {
4217 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
4218 return;
4219 p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
4220 });
3591 } 4221 }
3592 4222
3593 #endregion 4223 #endregion
3594 4224
3595 #region Significant Movement Method 4225 #region Significant Movement Method
3596 4226
4227 private void checkRePrioritization()
4228 {
4229 if(IsDeleted || !ControllingClient.IsActive)
4230 return;
4231
4232 if(!SentInitialData)
4233 {
4234 SendInitialDataToMe();
4235 return;
4236 }
4237
4238 if(m_reprioritizationBusy)
4239 return;
4240
4241 float limit = Scene.ReprioritizationDistance;
4242 bool byDrawdistance = Scene.ObjectsCullingByDistance;
4243 if(byDrawdistance)
4244 {
4245 float minregionSize = (float)Scene.RegionInfo.RegionSizeX;
4246 if(minregionSize > (float)Scene.RegionInfo.RegionSizeY)
4247 minregionSize = (float)Scene.RegionInfo.RegionSizeY;
4248 minregionSize *= 0.5f;
4249 if(DrawDistance > minregionSize && m_reprioritizationLastDrawDistance > minregionSize)
4250 byDrawdistance = false;
4251 else
4252 byDrawdistance = (Math.Abs(DrawDistance - m_reprioritizationLastDrawDistance) > 0.5f * limit);
4253 }
4254
4255 int tdiff = Util.EnvironmentTickCountSubtract(m_reprioritizationLastTime);
4256 if(!byDrawdistance && tdiff < Scene.ReprioritizationInterval)
4257 return;
4258 // priority uses avatar position
4259 Vector3 pos = AbsolutePosition;
4260 Vector3 diff = pos - m_reprioritizationLastPosition;
4261 limit *= limit;
4262 if (!byDrawdistance && diff.LengthSquared() < limit)
4263 return;
4264
4265 m_reprioritizationBusy = true;
4266 m_reprioritizationLastPosition = pos;
4267 m_reprioritizationLastDrawDistance = DrawDistance;
4268
4269 Util.FireAndForget(
4270 o =>
4271 {
4272 ControllingClient.ReprioritizeUpdates();
4273 m_reprioritizationLastTime = Util.EnvironmentTickCount();
4274 m_reprioritizationBusy = false;
4275 }, null, "ScenePresence.Reprioritization");
4276 }
3597 /// <summary> 4277 /// <summary>
3598 /// This checks for a significant movement and sends a coarselocationchange update 4278 /// This checks for a significant movement and sends a coarselocationchange update
3599 /// </summary> 4279 /// </summary>
3600 protected void CheckForSignificantMovement() 4280 protected void CheckForSignificantMovement()
3601 { 4281 {
3602 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) 4282 Vector3 pos = AbsolutePosition;
4283
4284 Vector3 diff = pos - posLastMove;
4285 if (diff.LengthSquared() > MOVEMENT)
3603 { 4286 {
3604 posLastSignificantMove = AbsolutePosition; 4287 posLastMove = pos;
3605 m_scene.EventManager.TriggerSignificantClientMovement(this); 4288 m_scene.EventManager.TriggerOnClientMovement(this);
3606 } 4289 }
3607 4290
3608 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 4291 diff = pos - posLastSignificantMove;
3609 if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) 4292 if (diff.LengthSquared() > SIGNIFICANT_MOVEMENT)
3610 { 4293 {
3611 m_lastChildAgentUpdatePosition = AbsolutePosition; 4294 posLastSignificantMove = pos;
3612// m_lastChildAgentUpdateCamPosition = CameraPosition; 4295 m_scene.EventManager.TriggerSignificantClientMovement(this);
4296 }
3613 4297
3614 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); 4298 // updates priority recalc
3615 cadu.ActiveGroupID = UUID.Zero.Guid; 4299 checkRePrioritization();
3616 cadu.AgentID = UUID.Guid;
3617 cadu.alwaysrun = SetAlwaysRun;
3618 cadu.AVHeight = Appearance.AvatarHeight;
3619 cadu.cameraPosition = CameraPosition;
3620 cadu.drawdistance = DrawDistance;
3621 cadu.GroupAccess = 0;
3622 cadu.Position = AbsolutePosition;
3623 cadu.regionHandle = RegionHandle;
3624 4300
3625 // Throttles 4301 if(m_childUpdatesBusy)
3626 float multiplier = 1; 4302 return;
3627 int childRegions = KnownRegionCount;
3628 if (childRegions != 0)
3629 multiplier = 1f / childRegions;
3630 4303
3631 // Minimum throttle for a child region is 1/4 of the root region throttle 4304 //possible KnownRegionHandles always contains current region and this check is not needed
3632 if (multiplier <= 0.25f) 4305 int minhandles = 0;
3633 multiplier = 0.25f; 4306 if(KnownRegionHandles.Contains(RegionHandle))
4307 minhandles++;
3634 4308
3635 cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); 4309 if(KnownRegionHandles.Count > minhandles)
3636 cadu.Velocity = Velocity; 4310 {
4311 int tdiff = Util.EnvironmentTickCountSubtract(m_lastChildUpdatesTime);
4312 if(tdiff < CHILDUPDATES_TIME)
4313 return;
3637 4314
3638 AgentPosition agentpos = new AgentPosition(); 4315 bool doUpdate = false;
3639 agentpos.CopyFrom(cadu, ControllingClient.SessionId); 4316 if(m_lastChildAgentUpdateGodLevel != GodController.ViwerUIGodLevel)
4317 doUpdate = true;
4318
4319 if(!doUpdate && Math.Abs(DrawDistance - m_lastChildAgentUpdateDrawDistance) > 32.0f)
4320 doUpdate = true;
4321
4322 if(!doUpdate)
4323 {
4324 diff = pos - m_lastChildAgentUpdatePosition;
4325 if (diff.LengthSquared() > CHILDUPDATES_MOVEMENT)
4326 doUpdate = true;
4327 }
3640 4328
3641 // Let's get this out of the update loop 4329 if(doUpdate)
3642 Util.FireAndForget( 4330 {
3643 o => m_scene.SendOutChildAgentUpdates(agentpos, this), null, "ScenePresence.SendOutChildAgentUpdates"); 4331 m_childUpdatesBusy = true;
4332 m_lastChildAgentUpdatePosition = pos;
4333 m_lastChildAgentUpdateGodLevel = GodController.ViwerUIGodLevel;
4334 m_lastChildAgentUpdateDrawDistance = DrawDistance;
4335// m_lastChildAgentUpdateCamPosition = CameraPosition;
4336
4337 AgentPosition agentpos = new AgentPosition();
4338 agentpos.AgentID = new UUID(UUID.Guid);
4339 agentpos.SessionID = ControllingClient.SessionId;
4340 agentpos.Size = Appearance.AvatarSize;
4341 agentpos.Center = CameraPosition;
4342 agentpos.Far = DrawDistance;
4343 agentpos.Position = AbsolutePosition;
4344 agentpos.Velocity = Velocity;
4345 agentpos.RegionHandle = RegionHandle;
4346 agentpos.GodData = GodController.State();
4347 agentpos.Throttles = ControllingClient.GetThrottlesPacked(1);
4348
4349 // Let's get this out of the update loop
4350 Util.FireAndForget(
4351 o =>
4352 {
4353 m_scene.SendOutChildAgentUpdates(agentpos, this);
4354 m_lastChildUpdatesTime = Util.EnvironmentTickCount();
4355 m_childUpdatesBusy = false;
4356 }, null, "ScenePresence.SendOutChildAgentUpdates");
4357 }
3644 } 4358 }
3645 } 4359 }
3646 4360
@@ -3657,7 +4371,7 @@ namespace OpenSim.Region.Framework.Scenes
3657 protected void CheckForBorderCrossing() 4371 protected void CheckForBorderCrossing()
3658 { 4372 {
3659 // Check that we we are not a child 4373 // Check that we we are not a child
3660 if (IsChildAgent) 4374 if (IsChildAgent || IsInTransit)
3661 return; 4375 return;
3662 4376
3663 // If we don't have a PhysActor, we can't cross anyway 4377 // If we don't have a PhysActor, we can't cross anyway
@@ -3667,79 +4381,71 @@ namespace OpenSim.Region.Framework.Scenes
3667 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero) 4381 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3668 return; 4382 return;
3669 4383
3670 if (IsInTransit)
3671 return;
3672
3673 Vector3 pos2 = AbsolutePosition; 4384 Vector3 pos2 = AbsolutePosition;
3674 Vector3 origPosition = pos2;
3675 Vector3 vel = Velocity; 4385 Vector3 vel = Velocity;
3676 4386
3677 // Compute the future avatar position. 4387 float timeStep = 0.1f;
3678 // If the avatar will be crossing, we force the crossing to happen now 4388 pos2.X += vel.X * timeStep;
3679 // in the hope that this will make the avatar movement smoother when crossing. 4389 pos2.Y += vel.Y * timeStep;
3680 pos2 += vel * 0.05f; 4390 pos2.Z += vel.Z * timeStep;
3681
3682 if (m_scene.PositionIsInCurrentRegion(pos2))
3683 return;
3684
3685 m_log.DebugFormat("{0} CheckForBorderCrossing: position outside region. {1} in {2} at pos {3}",
3686 LogHeader, Name, Scene.Name, pos2);
3687 4391
3688 // Disconnect from the current region 4392// m_log.DebugFormat(
3689 bool isFlying = Flying; 4393// "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}",
3690 RemoveFromPhysicalScene(); 4394// pos2, Name, Scene.Name);
3691 4395
3692 // pos2 is the forcasted position so make that the 'current' position so the crossing 4396 if (Scene.PositionIsInCurrentRegion(pos2))
3693 // code will move us into the newly addressed region. 4397 return;
3694 m_pos = pos2;
3695 4398
3696 if (CrossToNewRegion()) 4399 if (!CrossToNewRegion() && m_requestedSitTargetUUID == UUID.Zero)
3697 {
3698 AddToPhysicalScene(isFlying);
3699 }
3700 else
3701 { 4400 {
3702 // Tried to make crossing happen but it failed. 4401 // we don't have entity transfer module
3703 if (m_requestedSitTargetUUID == UUID.Zero) 4402 Vector3 pos = AbsolutePosition;
3704 { 4403 vel = Velocity;
3705 m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader); 4404 float px = pos.X;
3706 4405 if (px < 0)
3707 Velocity = Vector3.Zero; 4406 pos.X += vel.X * 2;
3708 AbsolutePosition = EnforceSanityOnPosition(origPosition); 4407 else if (px > m_scene.RegionInfo.RegionSizeX)
4408 pos.X -= vel.X * 2;
4409
4410 float py = pos.Y;
4411 if (py < 0)
4412 pos.Y += vel.Y * 2;
4413 else if (py > m_scene.RegionInfo.RegionSizeY)
4414 pos.Y -= vel.Y * 2;
3709 4415
3710 AddToPhysicalScene(isFlying); 4416 Velocity = Vector3.Zero;
3711 } 4417 m_AngularVelocity = Vector3.Zero;
4418 AbsolutePosition = pos;
3712 } 4419 }
3713 } 4420 }
3714 4421
3715 // Given a position, make sure it is within the current region. 4422 public void CrossToNewRegionFail()
3716 // If just outside some border, the returned position will be just inside the border on that side.
3717 private Vector3 EnforceSanityOnPosition(Vector3 origPosition)
3718 { 4423 {
3719 const float borderFudge = 0.1f; 4424 if (m_requestedSitTargetUUID == UUID.Zero)
3720 Vector3 ret = origPosition;
3721
3722 // Sanity checking on the position to make sure it is in the region we couldn't cross from
3723 float extentX = (float)m_scene.RegionInfo.RegionSizeX;
3724 float extentY = (float)m_scene.RegionInfo.RegionSizeY;
3725 IRegionCombinerModule combiner = m_scene.RequestModuleInterface<IRegionCombinerModule>();
3726 if (combiner != null)
3727 { 4425 {
3728 // If a mega-region, the size could be much bigger 4426 bool isFlying = Flying;
3729 Vector2 megaExtent = combiner.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); 4427 RemoveFromPhysicalScene();
3730 extentX = megaExtent.X; 4428
3731 extentY = megaExtent.Y; 4429 Vector3 pos = AbsolutePosition;
3732 } 4430 Vector3 vel = Velocity;
3733 if (ret.X < 0) 4431 float px = pos.X;
3734 ret.X = borderFudge; 4432 if (px < 0)
3735 else if (ret.X >= extentX) 4433 pos.X += vel.X * 2;
3736 ret.X = extentX - borderFudge; 4434 else if (px > m_scene.RegionInfo.RegionSizeX)
3737 if (ret.Y < 0) 4435 pos.X -= vel.X * 2;
3738 ret.Y = borderFudge; 4436
3739 else if (ret.Y >= extentY) 4437 float py = pos.Y;
3740 ret.Y = extentY - borderFudge; 4438 if (py < 0)
4439 pos.Y += vel.Y * 2;
4440 else if (py > m_scene.RegionInfo.RegionSizeY)
4441 pos.Y -= vel.Y * 2;
4442
4443 Velocity = Vector3.Zero;
4444 m_AngularVelocity = Vector3.Zero;
4445 AbsolutePosition = pos;
3741 4446
3742 return ret; 4447 AddToPhysicalScene(isFlying);
4448 }
3743 } 4449 }
3744 4450
3745 /// <summary> 4451 /// <summary>
@@ -3750,62 +4456,93 @@ namespace OpenSim.Region.Framework.Scenes
3750 /// </summary> 4456 /// </summary>
3751 protected bool CrossToNewRegion() 4457 protected bool CrossToNewRegion()
3752 { 4458 {
4459 bool result = false;
4460// parcelRegionCross(false);
3753 try 4461 try
3754 { 4462 {
3755 return m_scene.CrossAgentToNewRegion(this, Flying); 4463 result = m_scene.CrossAgentToNewRegion(this, Flying);
3756 } 4464 }
3757 catch 4465 catch
3758 { 4466 {
3759 return m_scene.CrossAgentToNewRegion(this, false); 4467// result = m_scene.CrossAgentToNewRegion(this, false);
4468 return false;
3760 } 4469 }
3761 } 4470 // if(!result)
4471 // parcelRegionCross(true);
3762 4472
3763 public void Reset() 4473 return result;
3764 {
3765// m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName);
3766
3767 // Put the child agent back at the center
3768 AbsolutePosition
3769 = new Vector3(((float)m_scene.RegionInfo.RegionSizeX * 0.5f), ((float)m_scene.RegionInfo.RegionSizeY * 0.5f), 70);
3770 4474
3771 Animator.ResetAnimations();
3772 } 4475 }
3773 4476
3774 /// <summary> 4477 /// <summary>
3775 /// Computes which child agents to close when the scene presence moves to another region. 4478 /// Computes which child agents to close when the scene presence moves to another region.
3776 /// Removes those regions from m_knownRegions. 4479 /// Removes those regions from m_knownRegions.
3777 /// </summary> 4480 /// </summary>
3778 /// <param name="newRegionX">The new region's x on the map</param> 4481 /// <param name="newRegionHandle">The new region's handle</param>
3779 /// <param name="newRegionY">The new region's y on the map</param> 4482 /// <param name="newRegionSizeX">The new region's size x</param>
4483 /// <param name="newRegionSizeY">The new region's size y</param>
3780 /// <returns></returns> 4484 /// <returns></returns>
3781 public void CloseChildAgents(uint newRegionX, uint newRegionY) 4485 public List<ulong> GetChildAgentsToClose(ulong newRegionHandle, int newRegionSizeX, int newRegionSizeY)
3782 { 4486 {
4487 ulong curRegionHandle = m_scene.RegionInfo.RegionHandle;
3783 List<ulong> byebyeRegions = new List<ulong>(); 4488 List<ulong> byebyeRegions = new List<ulong>();
4489
4490 if(newRegionHandle == curRegionHandle) //??
4491 return byebyeRegions;
4492
4493 uint newRegionX, newRegionY;
3784 List<ulong> knownRegions = KnownRegionHandles; 4494 List<ulong> knownRegions = KnownRegionHandles;
3785 m_log.DebugFormat( 4495 m_log.DebugFormat(
3786 "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", 4496 "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}",
3787 knownRegions.Count, Scene.RegionInfo.RegionName); 4497 knownRegions.Count, Scene.RegionInfo.RegionName);
3788 //DumpKnownRegions(); 4498
4499 Util.RegionHandleToRegionLoc(newRegionHandle, out newRegionX, out newRegionY);
4500 uint x, y;
4501 spRegionSizeInfo regInfo;
3789 4502
3790 foreach (ulong handle in knownRegions) 4503 foreach (ulong handle in knownRegions)
3791 { 4504 {
3792 // Don't close the agent on this region yet 4505 if(newRegionY == 0) // HG
3793 if (handle != Scene.RegionInfo.RegionHandle) 4506 byebyeRegions.Add(handle);
4507 else if(handle == curRegionHandle)
3794 { 4508 {
3795 uint x, y; 4509 RegionInfo curreg = m_scene.RegionInfo;
3796 Util.RegionHandleToRegionLoc(handle, out x, out y); 4510 if (Util.IsOutsideView(255, curreg.RegionLocX, newRegionX, curreg.RegionLocY, newRegionY,
3797 4511 (int)curreg.RegionSizeX, (int)curreg.RegionSizeX, newRegionSizeX, newRegionSizeY))
3798// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
3799// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
3800 float dist = (float)Math.Max(Scene.DefaultDrawDistance,
3801 (float)Math.Max(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY));
3802 if (Util.IsOutsideView(dist, x, newRegionX, y, newRegionY))
3803 { 4512 {
3804 byebyeRegions.Add(handle); 4513 byebyeRegions.Add(handle);
3805 } 4514 }
3806 } 4515 }
4516 else
4517 {
4518 Util.RegionHandleToRegionLoc(handle, out x, out y);
4519 if (m_knownChildRegionsSizeInfo.TryGetValue(handle, out regInfo))
4520 {
4521// if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY,
4522 // for now need to close all but first order bc RegionViewDistance it the target value not ours
4523 if (Util.IsOutsideView(255, x, newRegionX, y, newRegionY,
4524 regInfo.sizeX, regInfo.sizeY, newRegionSizeX, newRegionSizeY))
4525 {
4526 byebyeRegions.Add(handle);
4527 }
4528 }
4529 else
4530 {
4531// if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY,
4532 if (Util.IsOutsideView(255, x, newRegionX, y, newRegionY,
4533 (int)Constants.RegionSize, (int)Constants.RegionSize, newRegionSizeX, newRegionSizeY))
4534 {
4535 byebyeRegions.Add(handle);
4536 }
4537 }
4538 }
3807 } 4539 }
3808 4540 return byebyeRegions;
4541 }
4542
4543 public void CloseChildAgents(List<ulong> byebyeRegions)
4544 {
4545 byebyeRegions.Remove(Scene.RegionInfo.RegionHandle);
3809 if (byebyeRegions.Count > 0) 4546 if (byebyeRegions.Count > 0)
3810 { 4547 {
3811 m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); 4548 m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents");
@@ -3814,43 +4551,56 @@ namespace OpenSim.Region.Framework.Scenes
3814 string auth = string.Empty; 4551 string auth = string.Empty;
3815 if (acd != null) 4552 if (acd != null)
3816 auth = acd.SessionID.ToString(); 4553 auth = acd.SessionID.ToString();
3817 m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions); 4554 m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions);
3818 } 4555 }
3819 4556
3820 foreach (ulong handle in byebyeRegions) 4557 foreach (ulong handle in byebyeRegions)
3821 { 4558 {
3822 RemoveNeighbourRegion(handle); 4559 RemoveNeighbourRegion(handle);
4560 Scene.CapsModule.DropChildSeed(UUID, handle);
3823 } 4561 }
3824 } 4562 }
3825 4563
3826 #endregion 4564 public void closeAllChildAgents()
3827
3828 /// <summary>
3829 /// This allows the Sim owner the abiility to kick users from their sim currently.
3830 /// It tells the client that the agent has permission to do so.
3831 /// </summary>
3832 public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus)
3833 { 4565 {
3834 if (godStatus) 4566 List<ulong> byebyeRegions = new List<ulong>();
4567 List<ulong> knownRegions = KnownRegionHandles;
4568 foreach (ulong handle in knownRegions)
3835 { 4569 {
3836 // For now, assign god level 200 to anyone 4570 if (handle != Scene.RegionInfo.RegionHandle)
3837 // who is granted god powers, but has no god level set.
3838 //
3839 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, agentID);
3840 if (account != null)
3841 { 4571 {
3842 if (account.UserLevel > 0) 4572 byebyeRegions.Add(handle);
3843 GodLevel = account.UserLevel; 4573 RemoveNeighbourRegion(handle);
3844 else 4574 Scene.CapsModule.DropChildSeed(UUID, handle);
3845 GodLevel = 200;
3846 } 4575 }
3847 } 4576 }
3848 else 4577
4578 if (byebyeRegions.Count > 0)
3849 { 4579 {
3850 GodLevel = 0; 4580 m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents");
4581
4582 AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID);
4583 string auth = string.Empty;
4584 if (acd != null)
4585 auth = acd.SessionID.ToString();
4586 m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions);
3851 } 4587 }
4588 }
4589
4590 #endregion
3852 4591
3853 ControllingClient.SendAdminResponse(token, (uint)GodLevel); 4592 /// <summary>
4593 /// handle god level requests.
4594 /// </summary>
4595 public void GrantGodlikePowers(UUID token, bool godStatus)
4596 {
4597 if (IsNPC)
4598 return;
4599
4600 bool wasgod = IsViewerUIGod;
4601 GodController.RequestGodMode(godStatus);
4602 if (wasgod != IsViewerUIGod)
4603 parcelGodCheck(m_currentParcelUUID);
3854 } 4604 }
3855 4605
3856 #region Child Agent Updates 4606 #region Child Agent Updates
@@ -3862,12 +4612,16 @@ namespace OpenSim.Region.Framework.Scenes
3862 return; 4612 return;
3863 4613
3864 CopyFrom(cAgentData); 4614 CopyFrom(cAgentData);
3865
3866 m_updateAgentReceivedAfterTransferEvent.Set(); 4615 m_updateAgentReceivedAfterTransferEvent.Set();
3867 } 4616 }
3868 4617
3869 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 4618 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3870 4619
4620 private void RaiseUpdateThrottles()
4621 {
4622 m_scene.EventManager.TriggerThrottleUpdate(this);
4623 }
4624
3871 /// <summary> 4625 /// <summary>
3872 /// This updates important decision making data about a child agent 4626 /// This updates important decision making data about a child agent
3873 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 4627 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3877,44 +4631,59 @@ namespace OpenSim.Region.Framework.Scenes
3877 if (!IsChildAgent) 4631 if (!IsChildAgent)
3878 return; 4632 return;
3879 4633
3880// m_log.DebugFormat( 4634 GodController.SetState(cAgentData.GodData);
3881// "[SCENE PRESENCE]: ChildAgentPositionUpdate for {0} in {1}, tRegion {2},{3}, rRegion {4},{5}, pos {6}", 4635
3882// Name, Scene.Name, tRegionX, tRegionY, rRegionX, rRegionY, cAgentData.Position); 4636 RegionHandle = cAgentData.RegionHandle;
3883 4637
3884 // Find the distance (in meters) between the two regions 4638 //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY);
3885 // XXX: We cannot use Util.RegionLocToHandle() here because a negative value will silently overflow the 4639 int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize;
3886 // uint 4640 int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize;
3887 int shiftx = (int)(((int)rRegionX - (int)tRegionX) * Constants.RegionSize);
3888 int shifty = (int)(((int)rRegionY - (int)tRegionY) * Constants.RegionSize);
3889 4641
3890 Vector3 offset = new Vector3(shiftx, shifty, 0f); 4642 Vector3 offset = new Vector3(shiftx, shifty, 0f);
3891 4643
3892 // When we get to the point of re-computing neighbors everytime this
3893 // changes, then start using the agent's drawdistance rather than the
3894 // region's draw distance.
3895 DrawDistance = cAgentData.Far; 4644 DrawDistance = cAgentData.Far;
3896 // DrawDistance = Scene.DefaultDrawDistance;
3897 4645
3898 if (cAgentData.Position != marker) // UGH!! 4646 if (cAgentData.Position != marker) // UGH!!
3899 m_pos = cAgentData.Position + offset; 4647 m_pos = cAgentData.Position + offset;
3900 4648
3901 if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) 4649 CameraPosition = cAgentData.Center + offset;
4650
4651 if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0)
3902 { 4652 {
3903 posLastSignificantMove = AbsolutePosition; 4653 // some scaling factor
3904 ReprioritizeUpdates(); 4654 float x = m_pos.X;
4655 if (x > m_scene.RegionInfo.RegionSizeX)
4656 x -= m_scene.RegionInfo.RegionSizeX;
4657 float y = m_pos.Y;
4658 if (y > m_scene.RegionInfo.RegionSizeY)
4659 y -= m_scene.RegionInfo.RegionSizeY;
4660
4661 x = x * x + y * y;
4662
4663 const float distScale = 0.4f / Constants.RegionSize / Constants.RegionSize;
4664 float factor = 1.0f - distScale * x;
4665 if (factor < 0.2f)
4666 factor = 0.2f;
4667
4668 ControllingClient.SetChildAgentThrottle(cAgentData.Throttles,factor);
3905 } 4669 }
3906 4670
3907 CameraPosition = cAgentData.Center + offset; 4671 if(cAgentData.ChildrenCapSeeds != null && cAgentData.ChildrenCapSeeds.Count >0)
4672 {
4673 if (Scene.CapsModule != null)
4674 {
4675 Scene.CapsModule.SetChildrenSeed(UUID, cAgentData.ChildrenCapSeeds);
4676 }
3908 4677
3909 if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) 4678 KnownRegions = cAgentData.ChildrenCapSeeds;
3910 ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); 4679 }
3911 4680
3912 //cAgentData.AVHeight; 4681 //cAgentData.AVHeight;
3913 RegionHandle = cAgentData.RegionHandle;
3914 //m_velocity = cAgentData.Velocity; 4682 //m_velocity = cAgentData.Velocity;
4683 checkRePrioritization();
3915 } 4684 }
3916 4685
3917 public void CopyTo(AgentData cAgent) 4686 public void CopyTo(AgentData cAgent, bool isCrossUpdate)
3918 { 4687 {
3919 cAgent.CallbackURI = m_callbackURI; 4688 cAgent.CallbackURI = m_callbackURI;
3920 4689
@@ -3930,35 +4699,23 @@ namespace OpenSim.Region.Framework.Scenes
3930 cAgent.UpAxis = CameraUpAxis; 4699 cAgent.UpAxis = CameraUpAxis;
3931 4700
3932 cAgent.Far = DrawDistance; 4701 cAgent.Far = DrawDistance;
4702 cAgent.GodData = GodController.State();
3933 4703
3934 // Throttles 4704 // Throttles
3935 float multiplier = 1; 4705 cAgent.Throttles = ControllingClient.GetThrottlesPacked(1);
3936 int childRegions = KnownRegionCount;
3937 if (childRegions != 0)
3938 multiplier = 1f / childRegions;
3939
3940 // Minimum throttle for a child region is 1/4 of the root region throttle
3941 if (multiplier <= 0.25f)
3942 multiplier = 0.25f;
3943
3944 cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier);
3945 4706
3946 cAgent.HeadRotation = m_headrotation; 4707 cAgent.HeadRotation = m_headrotation;
3947 cAgent.BodyRotation = Rotation; 4708 cAgent.BodyRotation = Rotation;
3948 cAgent.ControlFlags = (uint)m_AgentControlFlags; 4709 cAgent.ControlFlags = (uint)m_AgentControlFlags;
3949 4710
3950 if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
3951 cAgent.GodLevel = (byte)GodLevel;
3952 else
3953 cAgent.GodLevel = (byte) 0;
3954
3955 cAgent.AlwaysRun = SetAlwaysRun; 4711 cAgent.AlwaysRun = SetAlwaysRun;
3956 4712
3957 cAgent.Appearance = new AvatarAppearance(Appearance); 4713 // make clear we want the all thing
4714 cAgent.Appearance = new AvatarAppearance(Appearance,true,true);
3958 4715
3959 cAgent.ParentPart = ParentUUID; 4716 cAgent.ParentPart = ParentUUID;
3960 cAgent.SitOffset = PrevSitOffset; 4717 cAgent.SitOffset = PrevSitOffset;
3961 4718
3962 lock (scriptedcontrols) 4719 lock (scriptedcontrols)
3963 { 4720 {
3964 ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; 4721 ControllerData[] controls = new ControllerData[scriptedcontrols.Count];
@@ -3980,8 +4737,36 @@ namespace OpenSim.Region.Framework.Scenes
3980 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; 4737 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation;
3981 cAgent.AnimState = Animator.Animations.ImplicitDefaultAnimation; 4738 cAgent.AnimState = Animator.Animations.ImplicitDefaultAnimation;
3982 4739
4740 cAgent.MovementAnimationOverRides = Overrides.CloneAOPairs();
4741
4742 cAgent.MotionState = (byte)Animator.currentControlState;
4743
3983 if (Scene.AttachmentsModule != null) 4744 if (Scene.AttachmentsModule != null)
3984 Scene.AttachmentsModule.CopyAttachments(this, cAgent); 4745 Scene.AttachmentsModule.CopyAttachments(this, cAgent);
4746
4747 if(isCrossUpdate)
4748 {
4749 cAgent.CrossingFlags = crossingFlags;
4750 cAgent.CrossingFlags |= 1;
4751 cAgent.CrossExtraFlags = 0;
4752 if((LastCommands & ScriptControlled.CONTROL_LBUTTON) != 0)
4753 cAgent.CrossExtraFlags |= 1;
4754 if((LastCommands & ScriptControlled.CONTROL_ML_LBUTTON) != 0)
4755 cAgent.CrossExtraFlags |= 2;
4756 }
4757 else
4758 cAgent.CrossingFlags = 0;
4759
4760 if(isCrossUpdate)
4761 {
4762 cAgent.agentCOF = COF;
4763 cAgent.ActiveGroupID = ControllingClient.ActiveGroupId;
4764 cAgent.ActiveGroupName = ControllingClient.ActiveGroupName;
4765 if(Grouptitle == null)
4766 cAgent.ActiveGroupTitle = String.Empty;
4767 else
4768 cAgent.ActiveGroupTitle = Grouptitle;
4769 }
3985 } 4770 }
3986 4771
3987 private void CopyFrom(AgentData cAgent) 4772 private void CopyFrom(AgentData cAgent)
@@ -3991,40 +4776,59 @@ namespace OpenSim.Region.Framework.Scenes
3991// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()", 4776// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
3992// Name, m_scene.RegionInfo.RegionName, m_callbackURI); 4777// Name, m_scene.RegionInfo.RegionName, m_callbackURI);
3993 4778
4779 GodController.SetState(cAgent.GodData);
4780
3994 m_pos = cAgent.Position; 4781 m_pos = cAgent.Position;
3995 m_velocity = cAgent.Velocity; 4782 m_velocity = cAgent.Velocity;
3996 CameraPosition = cAgent.Center; 4783 CameraPosition = cAgent.Center;
3997 CameraAtAxis = cAgent.AtAxis; 4784 CameraAtAxis = cAgent.AtAxis;
3998 CameraLeftAxis = cAgent.LeftAxis; 4785 CameraLeftAxis = cAgent.LeftAxis;
3999 CameraUpAxis = cAgent.UpAxis; 4786 CameraUpAxis = cAgent.UpAxis;
4787
4788 Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis);
4789 CameraRotation = camRot;
4790
4000 ParentUUID = cAgent.ParentPart; 4791 ParentUUID = cAgent.ParentPart;
4001 PrevSitOffset = cAgent.SitOffset; 4792 PrevSitOffset = cAgent.SitOffset;
4002 4793
4003 // When we get to the point of re-computing neighbors everytime this 4794 // When we get to the point of re-computing neighbors everytime this
4004 // changes, then start using the agent's drawdistance rather than the 4795 // changes, then start using the agent's drawdistance rather than the
4005 // region's draw distance. 4796 // region's draw distance.
4006 DrawDistance = cAgent.Far; 4797 DrawDistance = cAgent.Far;
4007 // DrawDistance = Scene.DefaultDrawDistance; 4798 //DrawDistance = Scene.DefaultDrawDistance;
4799
4800 if (cAgent.ChildrenCapSeeds != null && cAgent.ChildrenCapSeeds.Count > 0)
4801 {
4802 if (Scene.CapsModule != null)
4803 {
4804 Scene.CapsModule.SetChildrenSeed(UUID, cAgent.ChildrenCapSeeds);
4805 }
4806 KnownRegions = cAgent.ChildrenCapSeeds;
4807 }
4008 4808
4009 if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) 4809 if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
4010 ControllingClient.SetChildAgentThrottle(cAgent.Throttles); 4810 ControllingClient.SetChildAgentThrottle(cAgent.Throttles);
4011 4811
4012 m_headrotation = cAgent.HeadRotation; 4812 m_headrotation = cAgent.HeadRotation;
4013 Rotation = cAgent.BodyRotation; 4813 Rotation = cAgent.BodyRotation;
4014 m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; 4814 m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags;
4015 4815
4016 if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
4017 GodLevel = cAgent.GodLevel;
4018 SetAlwaysRun = cAgent.AlwaysRun; 4816 SetAlwaysRun = cAgent.AlwaysRun;
4019 4817
4020 Appearance = new AvatarAppearance(cAgent.Appearance); 4818 Appearance = new AvatarAppearance(cAgent.Appearance);
4819/*
4820 bool isFlying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
4821
4021 if (PhysicsActor != null) 4822 if (PhysicsActor != null)
4022 { 4823 {
4023 bool isFlying = Flying;
4024 RemoveFromPhysicalScene(); 4824 RemoveFromPhysicalScene();
4025 AddToPhysicalScene(isFlying); 4825 AddToPhysicalScene(isFlying);
4026 } 4826 }
4027 4827*/
4828
4829 if (Scene.AttachmentsModule != null)
4830 Scene.AttachmentsModule.CopyAttachments(cAgent, this);
4831
4028 try 4832 try
4029 { 4833 {
4030 lock (scriptedcontrols) 4834 lock (scriptedcontrols)
@@ -4032,6 +4836,7 @@ namespace OpenSim.Region.Framework.Scenes
4032 if (cAgent.Controllers != null) 4836 if (cAgent.Controllers != null)
4033 { 4837 {
4034 scriptedcontrols.Clear(); 4838 scriptedcontrols.Clear();
4839 IgnoredControls = ScriptControlled.CONTROL_ZERO;
4035 4840
4036 foreach (ControllerData c in cAgent.Controllers) 4841 foreach (ControllerData c in cAgent.Controllers)
4037 { 4842 {
@@ -4042,40 +4847,63 @@ namespace OpenSim.Region.Framework.Scenes
4042 sc.eventControls = (ScriptControlled)c.EventControls; 4847 sc.eventControls = (ScriptControlled)c.EventControls;
4043 4848
4044 scriptedcontrols[sc.itemID] = sc; 4849 scriptedcontrols[sc.itemID] = sc;
4850 IgnoredControls |= sc.ignoreControls; // this is not correct, aparently only last applied should count
4045 } 4851 }
4046 } 4852 }
4047 } 4853 }
4048 } 4854 }
4049 catch { } 4855 catch { }
4050 4856
4857 Animator.ResetAnimations();
4858
4859 Overrides.CopyAOPairsFrom(cAgent.MovementAnimationOverRides);
4860
4051 // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object? 4861 // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object?
4052 if (cAgent.Anims != null)
4053 Animator.Animations.FromArray(cAgent.Anims);
4054 if (cAgent.DefaultAnim != null) 4862 if (cAgent.DefaultAnim != null)
4055 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); 4863 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
4056 if (cAgent.AnimState != null) 4864 if (cAgent.AnimState != null)
4057 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); 4865 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
4866 if (cAgent.Anims != null)
4867 Animator.Animations.FromArray(cAgent.Anims);
4868 if (cAgent.MotionState != 0)
4869 Animator.currentControlState = (ScenePresenceAnimator.motionControlStates) cAgent.MotionState;
4058 4870
4059 if (Scene.AttachmentsModule != null) 4871
4872 crossingFlags = cAgent.CrossingFlags;
4873 gotCrossUpdate = (crossingFlags != 0);
4874 if(gotCrossUpdate)
4875 {
4876 LastCommands &= ~(ScriptControlled.CONTROL_LBUTTON | ScriptControlled.CONTROL_ML_LBUTTON);
4877 if((cAgent.CrossExtraFlags & 1) != 0)
4878 LastCommands |= ScriptControlled.CONTROL_LBUTTON;
4879 if((cAgent.CrossExtraFlags & 2) != 0)
4880 LastCommands |= ScriptControlled.CONTROL_ML_LBUTTON;
4881 MouseDown = (cAgent.CrossExtraFlags & 3) != 0;
4882 }
4883
4884 haveGroupInformation = false;
4885 // using this as protocol detection don't want to mess with the numbers for now
4886 if(cAgent.ActiveGroupTitle != null)
4060 { 4887 {
4061 // If the JobEngine is running we can schedule this job now and continue rather than waiting for all 4888 haveGroupInformation = true;
4062 // attachments to copy, which might take a long time in the Hypergrid case as the entire inventory 4889 COF = cAgent.agentCOF;
4063 // graph is inspected for each attachments and assets possibly fetched. 4890 if(ControllingClient.IsGroupMember(cAgent.ActiveGroupID))
4064 // 4891 {
4065 // We don't need to worry about a race condition as the job to later start the scripts is also 4892 ControllingClient.ActiveGroupId = cAgent.ActiveGroupID;
4066 // JobEngine scheduled and so will always occur after this task. 4893 ControllingClient.ActiveGroupName = cAgent.ActiveGroupName;
4067 // XXX: This will not be true if JobEngine ever gets more than one thread. 4894 Grouptitle = cAgent.ActiveGroupTitle;
4068 WorkManager.RunJob( 4895 ControllingClient.ActiveGroupPowers =
4069 "CopyAttachments", 4896 ControllingClient.GetGroupPowers(cAgent.ActiveGroupID);
4070 o => Scene.AttachmentsModule.CopyAttachments(cAgent, this), 4897 }
4071 null, 4898 else
4072 string.Format("Copy attachments for {0} entering {1}", Name, Scene.Name), 4899 {
4073 true); 4900 // we got a unknown active group so get what groups thinks about us
4074 } 4901 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
4075 4902 if (gm != null)
4076 // This must occur after attachments are copied or scheduled to be copied, as it releases the CompleteMovement() calling thread 4903 gm.SendAgentGroupDataUpdate(ControllingClient);
4077 // originating from the client completing a teleport. Otherwise, CompleteMovement() code to restart 4904 }
4078 // script attachments can outrace this thread. 4905 }
4906
4079 lock (m_originRegionIDAccessLock) 4907 lock (m_originRegionIDAccessLock)
4080 m_originRegionID = cAgent.RegionID; 4908 m_originRegionID = cAgent.RegionID;
4081 } 4909 }
@@ -4083,7 +4911,7 @@ namespace OpenSim.Region.Framework.Scenes
4083 public bool CopyAgent(out IAgentData agent) 4911 public bool CopyAgent(out IAgentData agent)
4084 { 4912 {
4085 agent = new CompleteAgentData(); 4913 agent = new CompleteAgentData();
4086 CopyTo((AgentData)agent); 4914 CopyTo((AgentData)agent, false);
4087 return true; 4915 return true;
4088 } 4916 }
4089 4917
@@ -4094,15 +4922,21 @@ namespace OpenSim.Region.Framework.Scenes
4094 /// </summary> 4922 /// </summary>
4095 public void UpdateMovement() 4923 public void UpdateMovement()
4096 { 4924 {
4097 if (m_forceToApply.HasValue) 4925/*
4098 { 4926 if (IsInTransit)
4099 Vector3 force = m_forceToApply.Value; 4927 return;
4100 4928
4101 Velocity = force; 4929 lock(m_forceToApplyLock)
4930 {
4931 if (m_forceToApplyValid)
4932 {
4933 Velocity = m_forceToApply;
4102 4934
4103 m_forceToApply = null; 4935 m_forceToApplyValid = false;
4104 TriggerScenePresenceUpdated(); 4936 TriggerScenePresenceUpdated();
4937 }
4105 } 4938 }
4939*/
4106 } 4940 }
4107 4941
4108 /// <summary> 4942 /// <summary>
@@ -4124,22 +4958,23 @@ namespace OpenSim.Region.Framework.Scenes
4124 if (Appearance.AvatarHeight == 0) 4958 if (Appearance.AvatarHeight == 0)
4125// Appearance.SetHeight(); 4959// Appearance.SetHeight();
4126 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f)); 4960 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
4127
4128/*
4129 PhysicsActor = scene.AddAvatar(
4130 LocalId, Firstname + "." + Lastname, pVec,
4131 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
4132*/
4133 4961
4134 PhysicsActor = m_scene.PhysicsScene.AddAvatar( 4962// lock(m_forceToApplyLock)
4135 LocalId, Firstname + "." + Lastname, AbsolutePosition, Velocity, 4963// m_forceToApplyValid = false;
4136 Appearance.AvatarBoxSize, isFlying); 4964
4965 PhysicsScene scene = m_scene.PhysicsScene;
4966 Vector3 pVec = AbsolutePosition;
4137 4967
4968 PhysicsActor = scene.AddAvatar(
4969 LocalId, Firstname + "." + Lastname, pVec,
4970 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
4971 PhysicsActor.Orientation = m_bodyRot;
4138 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 4972 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
4139 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 4973 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
4140 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 4974 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
4141 PhysicsActor.SubscribeEvents(100); 4975 PhysicsActor.SubscribeEvents(100);
4142 PhysicsActor.LocalID = LocalId; 4976 PhysicsActor.LocalID = LocalId;
4977 PhysicsActor.SetAlwaysRun = m_setAlwaysRun;
4143 } 4978 }
4144 4979
4145 private void OutOfBoundsCall(Vector3 pos) 4980 private void OutOfBoundsCall(Vector3 pos)
@@ -4152,7 +4987,6 @@ namespace OpenSim.Region.Framework.Scenes
4152 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 4987 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
4153 } 4988 }
4154 4989
4155
4156 /// <summary> 4990 /// <summary>
4157 /// Event called by the physics plugin to tell the avatar about a collision. 4991 /// Event called by the physics plugin to tell the avatar about a collision.
4158 /// </summary> 4992 /// </summary>
@@ -4166,24 +5000,26 @@ namespace OpenSim.Region.Framework.Scenes
4166 /// <param name="e"></param> 5000 /// <param name="e"></param>
4167 public void PhysicsCollisionUpdate(EventArgs e) 5001 public void PhysicsCollisionUpdate(EventArgs e)
4168 { 5002 {
4169 if (IsChildAgent || Animator == null) 5003 if (IsChildAgent)
4170 return; 5004 return;
4171 5005
5006 if(IsInTransit)
5007 return;
5008
4172 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 5009 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
4173 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( 5010 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
4174 // as of this comment the interval is set in AddToPhysicalScene 5011 // as of this comment the interval is set in AddToPhysicalScene
4175 5012
4176// if (m_updateCount > 0) 5013// if (m_updateCount > 0)
4177// { 5014// {
4178 if (Animator.UpdateMovementAnimations()) 5015// if (Animator != null && Animator.UpdateMovementAnimations())
4179 TriggerScenePresenceUpdated(); 5016// TriggerScenePresenceUpdated();
4180// m_updateCount--; 5017// m_updateCount--;
4181// } 5018// }
4182 5019
4183 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 5020 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
4184 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 5021 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
4185 5022
4186
4187// // No collisions at all means we may be flying. Update always 5023// // No collisions at all means we may be flying. Update always
4188// // to make falling work 5024// // to make falling work
4189// if (m_lastColCount != coldata.Count || coldata.Count == 0) 5025// if (m_lastColCount != coldata.Count || coldata.Count == 0)
@@ -4192,81 +5028,98 @@ namespace OpenSim.Region.Framework.Scenes
4192// m_lastColCount = coldata.Count; 5028// m_lastColCount = coldata.Count;
4193// } 5029// }
4194 5030
4195 CollisionPlane = Vector4.UnitW; 5031 if (coldata.Count != 0)
5032 {
5033 ContactPoint lowest;
5034 lowest.SurfaceNormal = Vector3.Zero;
5035 lowest.Position = Vector3.Zero;
5036 lowest.Position.Z = float.MaxValue;
5037
5038 foreach (ContactPoint contact in coldata.Values)
5039 {
5040 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
5041 lowest = contact;
5042 }
5043
5044 if (lowest.Position.Z != float.MaxValue)
5045 {
5046 lowest.SurfaceNormal = -lowest.SurfaceNormal;
5047 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
5048 }
5049 else
5050 CollisionPlane = Vector4.UnitW;
5051 }
5052 else
5053 CollisionPlane = Vector4.UnitW;
5054
5055 RaiseCollisionScriptEvents(coldata);
4196 5056
4197 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 5057 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
4198 if (Invulnerable || GodLevel > 0) 5058 if (Invulnerable || IsViewerUIGod)
4199 return; 5059 return;
4200 5060
4201 // The following may be better in the ICombatModule 5061 // The following may be better in the ICombatModule
4202 // probably tweaking of the values for ground and normal prim collisions will be needed 5062 // probably tweaking of the values for ground and normal prim collisions will be needed
4203 float starthealth = Health; 5063 float startHealth = Health;
4204 uint killerObj = 0; 5064 if(coldata.Count > 0)
4205 SceneObjectPart part = null;
4206 foreach (uint localid in coldata.Keys)
4207 { 5065 {
4208 if (localid == 0) 5066 uint killerObj = 0;
4209 { 5067 SceneObjectPart part = null;
4210 part = null; 5068 float rvel; // relative velocity, negative on approch
4211 } 5069 foreach (uint localid in coldata.Keys)
4212 else
4213 {
4214 part = Scene.GetSceneObjectPart(localid);
4215 }
4216 if (part != null)
4217 { 5070 {
4218 // Ignore if it has been deleted or volume detect 5071 if (localid == 0)
4219 if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect) 5072 {
5073 // 0 is the ground
5074 rvel = coldata[0].RelativeSpeed;
5075 if(rvel < -5.0f)
5076 Health -= 0.01f * rvel * rvel;
5077 }
5078 else
4220 { 5079 {
4221 if (part.ParentGroup.Damage > 0.0f) 5080 part = Scene.GetSceneObjectPart(localid);
5081
5082 if(part != null && !part.ParentGroup.IsVolumeDetect)
4222 { 5083 {
4223 // Something with damage... 5084 if (part.ParentGroup.Damage > 0.0f)
4224 Health -= part.ParentGroup.Damage; 5085 {
4225 part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false); 5086 // Something with damage...
5087 Health -= part.ParentGroup.Damage;
5088 part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false);
5089 }
5090 else
5091 {
5092 // An ordinary prim
5093 rvel = coldata[localid].RelativeSpeed;
5094 if(rvel < -5.0f)
5095 {
5096 Health -= 0.005f * rvel * rvel;
5097 }
5098 }
4226 } 5099 }
4227 else 5100 else
4228 { 5101 {
4229 // An ordinary prim 5102
4230 if (coldata[localid].PenetrationDepth >= 0.10f)
4231 Health -= coldata[localid].PenetrationDepth * 5.0f;
4232 } 5103 }
4233 } 5104 }
4234 }
4235 else
4236 {
4237 // 0 is the ground
4238 // what about collisions with other avatars?
4239 if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f)
4240 Health -= coldata[localid].PenetrationDepth * 5.0f;
4241 }
4242
4243 5105
4244 if (Health <= 0.0f) 5106 if (Health <= 0.0f)
4245 { 5107 {
4246 if (localid != 0) 5108 if (localid != 0)
4247 killerObj = localid; 5109 killerObj = localid;
4248 } 5110 }
4249 //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString());
4250 }
4251 //Health = 100;
4252 if (!Invulnerable)
4253 {
4254 if (starthealth != Health)
4255 {
4256 ControllingClient.SendHealth(Health);
4257 } 5111 }
5112
4258 if (Health <= 0) 5113 if (Health <= 0)
4259 { 5114 {
4260 m_scene.EventManager.TriggerAvatarKill(killerObj, this);
4261 }
4262 if (starthealth == Health && Health < 100.0f)
4263 {
4264 Health += 0.03f;
4265 if (Health > 100.0f)
4266 Health = 100.0f;
4267 ControllingClient.SendHealth(Health); 5115 ControllingClient.SendHealth(Health);
5116 m_scene.EventManager.TriggerAvatarKill(killerObj, this);
5117 return;
4268 } 5118 }
4269 } 5119 }
5120
5121 if(Math.Abs(Health - startHealth) > 1.0)
5122 ControllingClient.SendHealth(Health);
4270 } 5123 }
4271 5124
4272 public void setHealthWithUpdate(float health) 5125 public void setHealthWithUpdate(float health)
@@ -4280,25 +5133,25 @@ namespace OpenSim.Region.Framework.Scenes
4280 // Clear known regions 5133 // Clear known regions
4281 KnownRegions = new Dictionary<ulong, string>(); 5134 KnownRegions = new Dictionary<ulong, string>();
4282 5135
4283 lock (m_reprioritization_timer)
4284 {
4285 m_reprioritization_timer.Enabled = false;
4286 m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize);
4287 }
4288
4289 // I don't get it but mono crashes when you try to dispose of this timer, 5136 // I don't get it but mono crashes when you try to dispose of this timer,
4290 // unsetting the elapsed callback should be enough to allow for cleanup however. 5137 // unsetting the elapsed callback should be enough to allow for cleanup however.
4291 // m_reprioritizationTimer.Dispose(); 5138 // m_reprioritizationTimer.Dispose();
4292 5139
4293 RemoveFromPhysicalScene(); 5140 RemoveFromPhysicalScene();
4294 5141
4295 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; 5142 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
5143 RemoveClientEvents();
4296 5144
4297// if (Animator != null) 5145// if (Animator != null)
4298// Animator.Close(); 5146// Animator.Close();
4299 Animator = null; 5147 Animator = null;
4300 5148
5149 scriptedcontrols.Clear();
5150 ControllingClient = null;
4301 LifecycleState = ScenePresenceState.Removed; 5151 LifecycleState = ScenePresenceState.Removed;
5152 IsDeleted = true;
5153 m_updateAgentReceivedAfterTransferEvent.Dispose();
5154 m_updateAgentReceivedAfterTransferEvent = null;
4302 } 5155 }
4303 5156
4304 public void AddAttachment(SceneObjectGroup gobj) 5157 public void AddAttachment(SceneObjectGroup gobj)
@@ -4311,6 +5164,10 @@ namespace OpenSim.Region.Framework.Scenes
4311 5164
4312 m_attachments.Add(gobj); 5165 m_attachments.Add(gobj);
4313 } 5166 }
5167
5168 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
5169 if (bakedModule != null)
5170 bakedModule.UpdateMeshAvatar(m_uuid);
4314 } 5171 }
4315 5172
4316 /// <summary> 5173 /// <summary>
@@ -4343,7 +5200,7 @@ namespace OpenSim.Region.Framework.Scenes
4343 } 5200 }
4344 } 5201 }
4345 } 5202 }
4346 5203
4347 return attachments; 5204 return attachments;
4348 } 5205 }
4349 5206
@@ -4474,6 +5331,287 @@ namespace OpenSim.Region.Framework.Scenes
4474 return validated; 5331 return validated;
4475 } 5332 }
4476 5333
5334 public void SendAttachmentsToAllAgents()
5335 {
5336 lock (m_attachments)
5337 {
5338 foreach (SceneObjectGroup sog in m_attachments)
5339 {
5340 m_scene.ForEachScenePresence(delegate(ScenePresence p)
5341 {
5342 if (p != this && sog.HasPrivateAttachmentPoint)
5343 return;
5344
5345 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
5346 return;
5347
5348 SendTerseUpdateToAgentNF(p);
5349 SendAttachmentFullUpdateToAgentNF(sog, p);
5350 });
5351 }
5352 }
5353 }
5354
5355 // send attachments to a client without filters except for huds
5356 // for now they are checked in several places down the line...
5357 public void SendAttachmentsToAgentNF(ScenePresence p)
5358 {
5359 SendTerseUpdateToAgentNF(p);
5360// SendAvatarDataToAgentNF(this);
5361 lock (m_attachments)
5362 {
5363 foreach (SceneObjectGroup sog in m_attachments)
5364 {
5365 SendAttachmentFullUpdateToAgentNF(sog, p);
5366 }
5367 }
5368 }
5369
5370 public void SendAttachmentFullUpdateToAgentNF(SceneObjectGroup sog, ScenePresence p)
5371 {
5372 if (p != this && sog.HasPrivateAttachmentPoint)
5373 return;
5374
5375 SceneObjectPart[] parts = sog.Parts;
5376 SceneObjectPart rootpart = sog.RootPart;
5377
5378 p.ControllingClient.SendEntityUpdate(rootpart, PrimUpdateFlags.FullUpdate);
5379
5380 for (int i = 0; i < parts.Length; i++)
5381 {
5382 SceneObjectPart part = parts[i];
5383 if (part == rootpart)
5384 continue;
5385 p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate);
5386 }
5387 }
5388
5389 public void SendAttachmentScheduleUpdate(SceneObjectGroup sog)
5390 {
5391 if (IsChildAgent || IsInTransit)
5392 return;
5393
5394 SceneObjectPart[] origparts = sog.Parts;
5395 SceneObjectPart[] parts = new SceneObjectPart[origparts.Length];
5396 PrimUpdateFlags[] flags = new PrimUpdateFlags[origparts.Length];
5397
5398 SceneObjectPart rootpart = sog.RootPart;
5399 UpdateRequired rootreq = sog.RootPart.UpdateFlag;
5400
5401 int j = 0;
5402 bool allterse = true;
5403 for (int i = 0; i < origparts.Length; i++)
5404 {
5405 if (origparts[i] != rootpart)
5406 {
5407 switch (origparts[i].UpdateFlag)
5408 {
5409 case UpdateRequired.NONE:
5410 break;
5411
5412 case UpdateRequired.TERSE:
5413 flags[j] = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5414 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5415 parts[j] = origparts[i];
5416 j++;
5417 break;
5418
5419 case UpdateRequired.FULL:
5420 flags[j] = PrimUpdateFlags.FullUpdate;
5421 allterse = false;
5422 parts[j] = origparts[i];
5423 j++;
5424 break;
5425 }
5426 }
5427 origparts[i].UpdateFlag = 0;
5428 }
5429
5430 if (j == 0 && rootreq == UpdateRequired.NONE)
5431 return;
5432
5433 PrimUpdateFlags rootflag = PrimUpdateFlags.FullUpdate;
5434
5435 if (rootreq != UpdateRequired.FULL && allterse)
5436 {
5437 rootflag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5438 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5439 }
5440
5441 int nparts = j;
5442
5443 ControllingClient.SendEntityUpdate(rootpart, rootflag);
5444
5445 for (int i = 0; i < nparts; i++)
5446 {
5447 ControllingClient.SendEntityUpdate(parts[i], flags[i]);
5448 }
5449
5450 if (sog.HasPrivateAttachmentPoint)
5451 return;
5452
5453 List<ScenePresence> allPresences = m_scene.GetScenePresences();
5454 foreach (ScenePresence p in allPresences)
5455 {
5456 if (p == this)
5457 continue;
5458
5459 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
5460 continue;
5461
5462 p.ControllingClient.SendEntityUpdate(rootpart, rootflag);
5463
5464 for (int i = 0; i < nparts; i++)
5465 {
5466 p.ControllingClient.SendEntityUpdate(parts[i], flags[i]);
5467 }
5468 }
5469 }
5470
5471 public void SendAttachmentUpdate(SceneObjectGroup sog, UpdateRequired UpdateFlag)
5472 {
5473 if (IsChildAgent || IsInTransit)
5474 return;
5475
5476 PrimUpdateFlags flag;
5477 switch (UpdateFlag)
5478 {
5479 case UpdateRequired.TERSE:
5480 flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5481 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5482 break;
5483
5484 case UpdateRequired.FULL:
5485 flag = PrimUpdateFlags.FullUpdate;
5486 break;
5487
5488 default:
5489 return;
5490 }
5491
5492 SceneObjectPart[] parts = sog.Parts;
5493 SceneObjectPart rootpart = sog.RootPart;
5494
5495// rootpart.UpdateFlag = 0;
5496
5497 ControllingClient.SendEntityUpdate(rootpart, flag);
5498
5499 for (int i = 0; i < parts.Length; i++)
5500 {
5501 SceneObjectPart part = parts[i];
5502 if (part == rootpart)
5503 continue;
5504 ControllingClient.SendEntityUpdate(part, flag);
5505// part.UpdateFlag = 0;
5506 }
5507
5508 if (sog.HasPrivateAttachmentPoint)
5509 return;
5510
5511 List<ScenePresence> allPresences = m_scene.GetScenePresences();
5512 foreach (ScenePresence p in allPresences)
5513 {
5514 if (p == this)
5515 continue;
5516
5517 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
5518 continue;
5519
5520 p.ControllingClient.SendEntityUpdate(rootpart, flag);
5521
5522 for (int i = 0; i < parts.Length; i++)
5523 {
5524 SceneObjectPart part = parts[i];
5525 if (part == rootpart)
5526 continue;
5527 p.ControllingClient.SendEntityUpdate(part, flag);
5528 }
5529 }
5530 }
5531
5532 public void SendAttachmentScheduleUpdate(SceneObjectPart part)
5533 {
5534 if (IsChildAgent || IsInTransit)
5535 return;
5536
5537
5538 PrimUpdateFlags flag;
5539 switch (part.UpdateFlag)
5540 {
5541 case UpdateRequired.TERSE:
5542 flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5543 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5544 break;
5545
5546 case UpdateRequired.FULL:
5547 flag = PrimUpdateFlags.FullUpdate;
5548 break;
5549
5550 default:
5551 return;
5552 }
5553
5554 part.UpdateFlag = 0;
5555
5556 ControllingClient.SendEntityUpdate(part, flag);
5557
5558 if (part.ParentGroup.HasPrivateAttachmentPoint)
5559 return;
5560
5561 List<ScenePresence> allPresences = m_scene.GetScenePresences();
5562 foreach (ScenePresence p in allPresences)
5563 {
5564 if (p == this)
5565 continue;
5566
5567 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
5568 continue;
5569
5570 p.ControllingClient.SendEntityUpdate(part, flag);
5571 }
5572 }
5573
5574
5575 public void SendAttachmentUpdate(SceneObjectPart part, UpdateRequired UpdateFlag)
5576 {
5577 if (IsChildAgent || IsInTransit)
5578 return;
5579
5580 PrimUpdateFlags flag;
5581 switch (UpdateFlag)
5582 {
5583 case UpdateRequired.TERSE:
5584 flag = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
5585 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity;
5586 break;
5587
5588 case UpdateRequired.FULL:
5589 flag = PrimUpdateFlags.FullUpdate;
5590 break;
5591
5592 default:
5593 return;
5594 }
5595
5596// part.UpdateFlag = 0;
5597
5598 ControllingClient.SendEntityUpdate(part, flag);
5599
5600 if (part.ParentGroup.HasPrivateAttachmentPoint)
5601 return;
5602
5603 List<ScenePresence> allPresences = m_scene.GetScenePresences();
5604 foreach (ScenePresence p in allPresences)
5605 {
5606 if (p == this)
5607 continue;
5608 if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod)
5609 continue;
5610
5611 p.ControllingClient.SendEntityUpdate(part, flag);
5612 }
5613 }
5614
4477 /// <summary> 5615 /// <summary>
4478 /// Send a script event to this scene presence's attachments 5616 /// Send a script event to this scene presence's attachments
4479 /// </summary> 5617 /// </summary>
@@ -4530,10 +5668,21 @@ namespace OpenSim.Region.Framework.Scenes
4530 } 5668 }
4531 } 5669 }
4532 5670
5671 CameraData physActor_OnPhysicsRequestingCameraData()
5672 {
5673 return new CameraData
5674 {
5675 Valid = true,
5676 MouseLook = this.m_mouseLook,
5677 CameraRotation = this.CameraRotation,
5678 CameraAtAxis = this.CameraAtAxis
5679 };
5680 }
5681
4533 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 5682 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
4534 { 5683 {
4535 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID); 5684 SceneObjectPart part = m_scene.GetSceneObjectPart(Obj_localID);
4536 if (p == null) 5685 if (part == null)
4537 return; 5686 return;
4538 5687
4539 ControllingClient.SendTakeControls(controls, false, false); 5688 ControllingClient.SendTakeControls(controls, false, false);
@@ -4543,7 +5692,7 @@ namespace OpenSim.Region.Framework.Scenes
4543 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 5692 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4544 obj.eventControls = ScriptControlled.CONTROL_ZERO; 5693 obj.eventControls = ScriptControlled.CONTROL_ZERO;
4545 5694
4546 obj.objectID = p.ParentGroup.UUID; 5695 obj.objectID = part.ParentGroup.UUID;
4547 obj.itemID = Script_item_UUID; 5696 obj.itemID = Script_item_UUID;
4548 if (pass_on == 0 && accept == 0) 5697 if (pass_on == 0 && accept == 0)
4549 { 5698 {
@@ -4562,7 +5711,6 @@ namespace OpenSim.Region.Framework.Scenes
4562 { 5711 {
4563 IgnoredControls = ScriptControlled.CONTROL_ZERO; 5712 IgnoredControls = ScriptControlled.CONTROL_ZERO;
4564 obj.eventControls = (ScriptControlled)controls; 5713 obj.eventControls = (ScriptControlled)controls;
4565 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4566 } 5714 }
4567 5715
4568 lock (scriptedcontrols) 5716 lock (scriptedcontrols)
@@ -4571,19 +5719,52 @@ namespace OpenSim.Region.Framework.Scenes
4571 { 5719 {
4572 IgnoredControls &= ~(ScriptControlled)controls; 5720 IgnoredControls &= ~(ScriptControlled)controls;
4573 if (scriptedcontrols.ContainsKey(Script_item_UUID)) 5721 if (scriptedcontrols.ContainsKey(Script_item_UUID))
4574 scriptedcontrols.Remove(Script_item_UUID); 5722 RemoveScriptFromControlNotifications(Script_item_UUID, part);
4575 } 5723 }
4576 else 5724 else
4577 { 5725 {
4578 scriptedcontrols[Script_item_UUID] = obj; 5726 AddScriptToControlNotifications(Script_item_UUID, part, ref obj);
4579 } 5727 }
4580 } 5728 }
4581 5729
4582 ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); 5730 ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true);
4583 } 5731 }
4584 5732
5733 private void AddScriptToControlNotifications(OpenMetaverse.UUID Script_item_UUID, SceneObjectPart part, ref ScriptControllers obj)
5734 {
5735 scriptedcontrols[Script_item_UUID] = obj;
5736
5737 PhysicsActor physActor = part.ParentGroup.RootPart.PhysActor;
5738 if (physActor != null)
5739 {
5740 physActor.OnPhysicsRequestingCameraData -= physActor_OnPhysicsRequestingCameraData;
5741 physActor.OnPhysicsRequestingCameraData += physActor_OnPhysicsRequestingCameraData;
5742 }
5743 }
5744
5745 private void RemoveScriptFromControlNotifications(OpenMetaverse.UUID Script_item_UUID, SceneObjectPart part)
5746 {
5747 scriptedcontrols.Remove(Script_item_UUID);
5748
5749 if (part != null)
5750 {
5751 PhysicsActor physActor = part.ParentGroup.RootPart.PhysActor;
5752 if (physActor != null)
5753 {
5754 physActor.OnPhysicsRequestingCameraData -= physActor_OnPhysicsRequestingCameraData;
5755 }
5756 }
5757 }
5758
4585 public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID) 5759 public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID)
4586 { 5760 {
5761 foreach (ScriptControllers c in scriptedcontrols.Values)
5762 {
5763 SceneObjectGroup sog = m_scene.GetSceneObjectGroup(c.objectID);
5764 if(sog != null && !sog.IsDeleted && sog.RootPart.PhysActor != null)
5765 sog.RootPart.PhysActor.OnPhysicsRequestingCameraData -= physActor_OnPhysicsRequestingCameraData;
5766 }
5767
4587 IgnoredControls = ScriptControlled.CONTROL_ZERO; 5768 IgnoredControls = ScriptControlled.CONTROL_ZERO;
4588 lock (scriptedcontrols) 5769 lock (scriptedcontrols)
4589 { 5770 {
@@ -4592,7 +5773,36 @@ namespace OpenSim.Region.Framework.Scenes
4592 ControllingClient.SendTakeControls(int.MaxValue, false, false); 5773 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4593 } 5774 }
4594 5775
4595 private void UnRegisterSeatControls(UUID obj) 5776 public void HandleRevokePermissions(UUID objectID, uint permissions )
5777 {
5778
5779 // still skeleton code
5780 if((permissions & (16 | 0x8000 )) == 0) //PERMISSION_TRIGGER_ANIMATION | PERMISSION_OVERRIDE_ANIMATIONS
5781 return;
5782 if(objectID == m_scene.RegionInfo.RegionID) // for all objects
5783 {
5784
5785 }
5786 else
5787 {
5788 SceneObjectPart part = m_scene.GetSceneObjectPart(objectID);
5789 if(part != null)
5790 {
5791
5792 }
5793 }
5794 }
5795
5796 public void ClearControls()
5797 {
5798 IgnoredControls = ScriptControlled.CONTROL_ZERO;
5799 lock (scriptedcontrols)
5800 {
5801 scriptedcontrols.Clear();
5802 }
5803 }
5804
5805 public void UnRegisterSeatControls(UUID obj)
4596 { 5806 {
4597 List<UUID> takers = new List<UUID>(); 5807 List<UUID> takers = new List<UUID>();
4598 5808
@@ -4610,17 +5820,18 @@ namespace OpenSim.Region.Framework.Scenes
4610 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 5820 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4611 { 5821 {
4612 ScriptControllers takecontrols; 5822 ScriptControllers takecontrols;
5823 SceneObjectPart part = m_scene.GetSceneObjectPart(Obj_localID);
4613 5824
4614 lock (scriptedcontrols) 5825 lock (scriptedcontrols)
4615 { 5826 {
4616 if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols)) 5827 if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols))
4617 { 5828 {
4618 ScriptControlled sctc = takecontrols.eventControls; 5829 ScriptControlled sctc = takecontrols.eventControls;
4619 5830
4620 ControllingClient.SendTakeControls((int)sctc, false, false); 5831 ControllingClient.SendTakeControls((int)sctc, false, false);
4621 ControllingClient.SendTakeControls((int)sctc, true, false); 5832 ControllingClient.SendTakeControls((int)sctc, true, false);
4622 5833
4623 scriptedcontrols.Remove(Script_item_UUID); 5834 RemoveScriptFromControlNotifications(Script_item_UUID, part);
4624 IgnoredControls = ScriptControlled.CONTROL_ZERO; 5835 IgnoredControls = ScriptControlled.CONTROL_ZERO;
4625 foreach (ScriptControllers scData in scriptedcontrols.Values) 5836 foreach (ScriptControllers scData in scriptedcontrols.Values)
4626 { 5837 {
@@ -4639,46 +5850,38 @@ namespace OpenSim.Region.Framework.Scenes
4639 if (scriptedcontrols.Count <= 0) 5850 if (scriptedcontrols.Count <= 0)
4640 return; 5851 return;
4641 5852
4642 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; 5853 ScriptControlled allflags;
4643 5854 // convert mouse from edge to level
4644 if (MouseDown) 5855 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 ||
5856 (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0)
4645 { 5857 {
4646 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); 5858 allflags = ScriptControlled.CONTROL_ZERO;
4647 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0)
4648 {
4649 allflags = ScriptControlled.CONTROL_ZERO;
4650 MouseDown = true;
4651 }
4652 } 5859 }
4653 5860 else // recover last state of mouse
5861 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
5862
4654 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) 5863 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0)
4655 {
4656 allflags |= ScriptControlled.CONTROL_ML_LBUTTON; 5864 allflags |= ScriptControlled.CONTROL_ML_LBUTTON;
4657 MouseDown = true; 5865
4658 }
4659
4660 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) 5866 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0)
4661 {
4662 allflags |= ScriptControlled.CONTROL_LBUTTON; 5867 allflags |= ScriptControlled.CONTROL_LBUTTON;
4663 MouseDown = true; 5868
4664 }
4665
4666 // find all activated controls, whether the scripts are interested in them or not 5869 // find all activated controls, whether the scripts are interested in them or not
4667 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) 5870 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0)
4668 { 5871 {
4669 allflags |= ScriptControlled.CONTROL_FWD; 5872 allflags |= ScriptControlled.CONTROL_FWD;
4670 } 5873 }
4671 5874
4672 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) 5875 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
4673 { 5876 {
4674 allflags |= ScriptControlled.CONTROL_BACK; 5877 allflags |= ScriptControlled.CONTROL_BACK;
4675 } 5878 }
4676 5879
4677 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) 5880 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
4678 { 5881 {
4679 allflags |= ScriptControlled.CONTROL_UP; 5882 allflags |= ScriptControlled.CONTROL_UP;
4680 } 5883 }
4681 5884
4682 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) 5885 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
4683 { 5886 {
4684 allflags |= ScriptControlled.CONTROL_DOWN; 5887 allflags |= ScriptControlled.CONTROL_DOWN;
@@ -4688,17 +5891,17 @@ namespace OpenSim.Region.Framework.Scenes
4688 { 5891 {
4689 allflags |= ScriptControlled.CONTROL_LEFT; 5892 allflags |= ScriptControlled.CONTROL_LEFT;
4690 } 5893 }
4691 5894
4692 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) 5895 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
4693 { 5896 {
4694 allflags |= ScriptControlled.CONTROL_RIGHT; 5897 allflags |= ScriptControlled.CONTROL_RIGHT;
4695 } 5898 }
4696 5899
4697 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) 5900 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
4698 { 5901 {
4699 allflags |= ScriptControlled.CONTROL_ROT_RIGHT; 5902 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
4700 } 5903 }
4701 5904
4702 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) 5905 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
4703 { 5906 {
4704 allflags |= ScriptControlled.CONTROL_ROT_LEFT; 5907 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
@@ -4711,7 +5914,7 @@ namespace OpenSim.Region.Framework.Scenes
4711 { 5914 {
4712 UUID scriptUUID = kvp.Key; 5915 UUID scriptUUID = kvp.Key;
4713 ScriptControllers scriptControlData = kvp.Value; 5916 ScriptControllers scriptControlData = kvp.Value;
4714 5917
4715 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us 5918 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us
4716 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle 5919 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle
4717 ScriptControlled localChange = localHeld ^ localLast; // the changed bits 5920 ScriptControlled localChange = localHeld ^ localLast; // the changed bits
@@ -4723,8 +5926,9 @@ namespace OpenSim.Region.Framework.Scenes
4723 } 5926 }
4724 } 5927 }
4725 } 5928 }
4726 5929
4727 LastCommands = allflags; 5930 LastCommands = allflags;
5931 MouseDown = (allflags & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON)) != 0;
4728 } 5932 }
4729 } 5933 }
4730 5934
@@ -4765,191 +5969,252 @@ namespace OpenSim.Region.Framework.Scenes
4765 return flags; 5969 return flags;
4766 } 5970 }
4767 5971
4768 private void ReprioritizeUpdates() 5972 // returns true it local teleport allowed and sets the destiny position into pos
5973
5974 private bool CheckLocalTPLandingPoint(ref Vector3 pos)
4769 { 5975 {
4770 if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) 5976 // Never constrain lures
5977 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
5978 return true;
5979
5980 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
5981 return true;
5982
5983 // do not constrain gods and estate managers
5984 if(m_scene.Permissions.IsGod(m_uuid) ||
5985 m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid))
5986 return true;
5987
5988 // will teleport to a telehub spawn point or landpoint if that results in getting closer to target
5989 // if not the local teleport fails.
5990
5991 float currDistanceSQ = Vector3.DistanceSquared(AbsolutePosition, pos);
5992
5993 // first check telehub
5994
5995 UUID TelehubObjectID = m_scene.RegionInfo.RegionSettings.TelehubObject;
5996 if ( TelehubObjectID != UUID.Zero)
4771 { 5997 {
4772 lock (m_reprioritization_timer) 5998 SceneObjectGroup telehubSOG = m_scene.GetSceneObjectGroup(TelehubObjectID);
5999 if(telehubSOG != null)
4773 { 6000 {
4774 if (!m_reprioritizing) 6001 Vector3 spawnPos;
4775 m_reprioritization_timer.Enabled = m_reprioritizing = true; 6002 float spawnDistSQ;
6003
6004 SpawnPoint[] spawnPoints = m_scene.RegionInfo.RegionSettings.SpawnPoints().ToArray();
6005 if(spawnPoints.Length == 0)
6006 {
6007 spawnPos = new Vector3(128.0f, 128.0f, pos.Z);
6008 spawnDistSQ = Vector3.DistanceSquared(spawnPos, pos);
6009 }
4776 else 6010 else
4777 m_reprioritization_called = true; 6011 {
4778 } 6012 Vector3 hubPos = telehubSOG.AbsolutePosition;
4779 } 6013 Quaternion hubRot = telehubSOG.GroupRotation;
4780 }
4781 6014
4782 private void Reprioritize(object sender, ElapsedEventArgs e) 6015 spawnPos = spawnPoints[0].GetLocation(hubPos, hubRot);
4783 { 6016 spawnDistSQ = Vector3.DistanceSquared(spawnPos, pos);
4784 ControllingClient.ReprioritizeUpdates();
4785 6017
4786 lock (m_reprioritization_timer) 6018 float testDistSQ;
4787 { 6019 Vector3 testSpawnPos;
4788 m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called; 6020 for(int i = 1; i< spawnPoints.Length; i++)
4789 m_reprioritization_called = false; 6021 {
6022 testSpawnPos = spawnPoints[i].GetLocation(hubPos, hubRot);
6023 testDistSQ = Vector3.DistanceSquared(testSpawnPos, pos);
6024
6025 if(testDistSQ < spawnDistSQ)
6026 {
6027 spawnPos = testSpawnPos;
6028 spawnDistSQ = testDistSQ;
6029 }
6030 }
6031 }
6032 if (currDistanceSQ < spawnDistSQ)
6033 {
6034 // we are already close
6035 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
6036 return false;
6037 }
6038 else
6039 {
6040 pos = spawnPos;
6041 return true;
6042 }
6043 }
4790 } 6044 }
4791 }
4792 6045
4793 private void CheckLandingPoint(ref Vector3 pos) 6046 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4794 {
4795 // Never constrain lures
4796 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4797 return;
4798 6047
4799 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport) 6048 if (land.LandData.LandingType != (byte)LandingType.LandingPoint
4800 return; 6049 || land.LandData.OwnerID == m_uuid)
6050 return true;
4801 6051
4802 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); 6052 Vector3 landLocation = land.LandData.UserLocation;
6053 if(landLocation == Vector3.Zero)
6054 return true;
4803 6055
4804 if (land.LandData.LandingType == (byte)LandingType.LandingPoint && 6056 if (currDistanceSQ < Vector3.DistanceSquared(landLocation, pos))
4805 land.LandData.UserLocation != Vector3.Zero &&
4806 land.LandData.OwnerID != m_uuid &&
4807 (!m_scene.Permissions.IsGod(m_uuid)) &&
4808 (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)))
4809 { 6057 {
4810 float curr = Vector3.Distance(AbsolutePosition, pos); 6058 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4811 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) 6059 return false;
4812 pos = land.LandData.UserLocation;
4813 else
4814 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4815 } 6060 }
6061
6062 pos = land.LandData.UserLocation;
6063 return true;
4816 } 6064 }
4817 6065
4818 private void CheckAndAdjustTelehub(SceneObjectGroup telehub, ref Vector3 pos) 6066 const TeleportFlags TeleHubTPFlags = TeleportFlags.ViaLogin
6067 | TeleportFlags.ViaHGLogin | TeleportFlags.ViaLocation;
6068
6069 private bool CheckAndAdjustTelehub(SceneObjectGroup telehub, ref Vector3 pos, ref bool positionChanged)
4819 { 6070 {
4820 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == 6071 // forcing telehubs on any tp that reachs this
4821 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || 6072 if ((m_teleportFlags & TeleHubTPFlags) != 0 ||
4822 (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) || 6073 (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )))
4823 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4824 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)
4825 { 6074 {
6075 ILandObject land;
6076 Vector3 teleHubPosition = telehub.AbsolutePosition;
4826 6077
4827 if (GodLevel < 200 && 6078 SpawnPoint[] spawnPoints = m_scene.RegionInfo.RegionSettings.SpawnPoints().ToArray();
4828 ((!m_scene.Permissions.IsGod(m_uuid) && 6079 if(spawnPoints.Length == 0)
4829 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4830 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4831 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4832 { 6080 {
4833 SpawnPoint[] spawnPoints = m_scene.RegionInfo.RegionSettings.SpawnPoints().ToArray(); 6081 land = m_scene.LandChannel.GetLandObject(teleHubPosition.X,teleHubPosition.Y);
4834 if (spawnPoints.Length == 0) 6082 if(land != null)
4835 { 6083 {
4836 if(m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) 6084 pos = teleHubPosition;
4837 { 6085 if(land.IsEitherBannedOrRestricted(UUID))
4838 pos.X = 128.0f; 6086 return false;
4839 pos.Y = 128.0f; 6087 positionChanged = true;
4840 } 6088 return true;
4841 return;
4842 } 6089 }
6090 else
6091 return false;
6092 }
4843 6093
4844 int index; 6094 int index;
4845 bool selected = false; 6095 int tries;
4846 6096 bool selected = false;
4847 switch (m_scene.SpawnPointRouting) 6097 bool validhub = false;
4848 { 6098 Vector3 spawnPosition;
4849 case "random":
4850 6099
4851 if (spawnPoints.Length == 0) 6100 Quaternion teleHubRotation = telehub.GroupRotation;
4852 return;
4853 do
4854 {
4855 index = Util.RandomClass.Next(spawnPoints.Length - 1);
4856
4857 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4858 telehub.AbsolutePosition,
4859 telehub.GroupRotation
4860 );
4861 // SpawnPoint sp = spawnPoints[index];
4862 6101
4863 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); 6102 switch(m_scene.SpawnPointRouting)
6103 {
6104 case "random":
6105 tries = spawnPoints.Length;
6106 if(tries < 3) // no much sense in random with a few points when there same can have bans
6107 goto case "sequence";
6108 do
6109 {
6110 index = Util.RandomClass.Next(spawnPoints.Length - 1);
4864 6111
4865 if (land == null || land.IsEitherBannedOrRestricted(UUID)) 6112 spawnPosition = spawnPoints[index].GetLocation(teleHubPosition, teleHubRotation);
4866 selected = false; 6113 land = m_scene.LandChannel.GetLandObject(spawnPosition.X,spawnPosition.Y);
4867 else 6114 if(land != null && !land.IsEitherBannedOrRestricted(UUID))
4868 selected = true; 6115 selected = true;
4869 6116
4870 } while ( selected == false); 6117 } while(selected == false && --tries > 0 );
4871 6118
4872 pos = spawnPoints[index].GetLocation( 6119 if(tries <= 0)
4873 telehub.AbsolutePosition, 6120 goto case "sequence";
4874 telehub.GroupRotation
4875 );
4876 return;
4877 6121
4878 case "sequence": 6122 pos = spawnPosition;
6123 return true;
4879 6124
4880 do 6125 case "sequence":
6126 tries = spawnPoints.Length;
6127 selected = false;
6128 validhub = false;
6129 do
6130 {
6131 index = m_scene.SpawnPoint();
6132 spawnPosition = spawnPoints[index].GetLocation(teleHubPosition, teleHubRotation);
6133 land = m_scene.LandChannel.GetLandObject(spawnPosition.X,spawnPosition.Y);
6134 if(land != null)
4881 { 6135 {
4882 index = m_scene.SpawnPoint(); 6136 validhub = true;
4883 6137 if(land.IsEitherBannedOrRestricted(UUID))
4884 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4885 telehub.AbsolutePosition,
4886 telehub.GroupRotation
4887 );
4888 // SpawnPoint sp = spawnPoints[index];
4889
4890 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4891 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4892 selected = false; 6138 selected = false;
4893 else 6139 else
4894 selected = true; 6140 selected = true;
6141 }
4895 6142
4896 } while (selected == false); 6143 } while(selected == false && --tries > 0);
4897 6144
4898 pos = spawnPoints[index].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 6145 if(!validhub)
4899 ; 6146 return false;
4900 return;
4901 6147
4902 default: 6148 pos = spawnPosition;
4903 case "closest":
4904 6149
4905 float distance = 9999; 6150 if(!selected)
4906 int closest = -1; 6151 return false;
4907 6152 positionChanged = true;
4908 for (int i = 0; i < spawnPoints.Length; i++) 6153 return true;
4909 {
4910 Vector3 spawnPosition = spawnPoints[i].GetLocation(
4911 telehub.AbsolutePosition,
4912 telehub.GroupRotation
4913 );
4914 Vector3 offset = spawnPosition - pos;
4915 float d = Vector3.Mag(offset);
4916 if (d >= distance)
4917 continue;
4918 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4919 if (land == null)
4920 continue;
4921 if (land.IsEitherBannedOrRestricted(UUID))
4922 continue;
4923 distance = d;
4924 closest = i;
4925 }
4926 if (closest == -1)
4927 return;
4928
4929 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4930 return;
4931 6154
4932 } 6155 default:
6156 case "closest":
6157 float distancesq = float.MaxValue;
6158 int closest = -1;
6159 validhub = false;
6160
6161 for(int i = 0; i < spawnPoints.Length; i++)
6162 {
6163 spawnPosition = spawnPoints[i].GetLocation(teleHubPosition, teleHubRotation);
6164 Vector3 offset = spawnPosition - pos;
6165 float dsq = offset.LengthSquared();
6166 land = m_scene.LandChannel.GetLandObject(spawnPosition.X,spawnPosition.Y);
6167 if(land == null)
6168 continue;
6169
6170 validhub = true;
6171 if(land.IsEitherBannedOrRestricted(UUID))
6172 continue;
6173
6174 if(dsq >= distancesq)
6175 continue;
6176 distancesq = dsq;
6177 closest = i;
6178 }
6179
6180 if(!validhub)
6181 return false;
6182
6183 if(closest < 0)
6184 {
6185 pos = spawnPoints[0].GetLocation(teleHubPosition, teleHubRotation);
6186 positionChanged = true;
6187 return false;
6188 }
6189
6190 pos = spawnPoints[closest].GetLocation(teleHubPosition, teleHubRotation);
6191 positionChanged = true;
6192 return true;
4933 } 6193 }
4934 } 6194 }
6195 return false;
4935 } 6196 }
4936 6197
6198 const TeleportFlags adicionalLandPointFlags = TeleportFlags.ViaLandmark |
6199 TeleportFlags.ViaLocation | TeleportFlags.ViaHGLogin;
6200
4937 // Modify landing point based on possible banning, telehubs or parcel restrictions. 6201 // Modify landing point based on possible banning, telehubs or parcel restrictions.
4938 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 6202 // This is the behavior in OpenSim for a very long time, different from SL
6203 private bool CheckAndAdjustLandingPoint_OS(ref Vector3 pos, ref Vector3 lookat, ref bool positionChanged)
4939 { 6204 {
4940 string reason; 6205 string reason;
4941 6206
4942 // Honor bans 6207 // Honor bans
4943 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y)) 6208 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4944 return; 6209 return false;
4945 6210
4946 SceneObjectGroup telehub = null; 6211 SceneObjectGroup telehub = null;
4947 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 6212 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4948 { 6213 {
4949 if (!m_scene.RegionInfo.EstateSettings.AllowDirectTeleport) 6214 if (!m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4950 { 6215 {
4951 CheckAndAdjustTelehub(telehub, ref pos); 6216 CheckAndAdjustTelehub(telehub, ref pos, ref positionChanged);
4952 return; 6217 return true;
4953 } 6218 }
4954 } 6219 }
4955 6220
@@ -4964,27 +6229,84 @@ namespace OpenSim.Region.Framework.Scenes
4964 // to ignore them. 6229 // to ignore them.
4965 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == 6230 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
4966 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || 6231 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
4967 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || 6232 (m_teleportFlags & adicionalLandPointFlags) != 0)
4968 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4969 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)
4970 { 6233 {
4971 // Don't restrict gods, estate managers, or land owners to 6234 // Don't restrict gods, estate managers, or land owners to
4972 // the TP point. This behaviour mimics agni. 6235 // the TP point. This behaviour mimics agni.
4973 if (land.LandData.LandingType == (byte)LandingType.LandingPoint && 6236 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4974 land.LandData.UserLocation != Vector3.Zero && 6237 land.LandData.UserLocation != Vector3.Zero &&
4975 GodLevel < 200 && 6238 !IsViewerUIGod &&
4976 ((land.LandData.OwnerID != m_uuid && 6239 ((land.LandData.OwnerID != m_uuid &&
4977 !m_scene.Permissions.IsGod(m_uuid) && 6240 !m_scene.Permissions.IsGod(m_uuid) &&
4978 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) || 6241 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4979 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 6242 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4980 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 6243 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4981 { 6244 {
4982 pos = land.LandData.UserLocation; 6245 pos = land.LandData.UserLocation;
6246 positionChanged = true;
4983 } 6247 }
4984 } 6248 }
4985 6249
4986 land.SendLandUpdateToClient(ControllingClient); 6250 land.SendLandUpdateToClient(ControllingClient);
4987 } 6251 }
6252
6253 return true;
6254 }
6255
6256 // Modify landing point based on telehubs or parcel restrictions.
6257 // This is a behavior coming from AVN, somewhat mimicking SL
6258 private bool CheckAndAdjustLandingPoint_SL(ref Vector3 pos, ref Vector3 lookat, ref bool positionChanged)
6259 {
6260 string reason;
6261
6262 // dont mess with gods
6263 if(IsGod)
6264 return true;
6265
6266 // respect region owner and managers
6267// if(m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid))
6268// return true;
6269
6270 if (!m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
6271 {
6272 SceneObjectGroup telehub = null;
6273 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
6274 {
6275 if(CheckAndAdjustTelehub(telehub, ref pos, ref positionChanged))
6276 return true;
6277 }
6278 }
6279
6280 // Honor bans, actually we don't honour them
6281 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
6282 return false;
6283
6284 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
6285 if (land != null)
6286 {
6287 if (Scene.DebugTeleporting)
6288 TeleportFlagsDebug();
6289
6290 // If we come in via login, landmark or map, we want to
6291 // honor landing points. If we come in via Lure, we want
6292 // to ignore them.
6293 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
6294 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)
6295 || (m_teleportFlags & adicionalLandPointFlags) != 0)
6296 {
6297 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
6298 land.LandData.UserLocation != Vector3.Zero )
6299 // &&
6300 // land.LandData.OwnerID != m_uuid )
6301 {
6302 pos = land.LandData.UserLocation;
6303 if(land.LandData.UserLookAt != Vector3.Zero)
6304 lookat = land.LandData.UserLookAt;
6305 positionChanged = true;
6306 }
6307 }
6308 }
6309 return true;
4988 } 6310 }
4989 6311
4990 private DetectedObject CreateDetObject(SceneObjectPart obj) 6312 private DetectedObject CreateDetObject(SceneObjectPart obj)
@@ -4998,6 +6320,7 @@ namespace OpenSim.Region.Framework.Scenes
4998 detobj.velVector = obj.Velocity; 6320 detobj.velVector = obj.Velocity;
4999 detobj.colliderType = 0; 6321 detobj.colliderType = 0;
5000 detobj.groupUUID = obj.GroupID; 6322 detobj.groupUUID = obj.GroupID;
6323 detobj.linkNumber = 0;
5001 6324
5002 return detobj; 6325 return detobj;
5003 } 6326 }
@@ -5011,8 +6334,13 @@ namespace OpenSim.Region.Framework.Scenes
5011 detobj.posVector = av.AbsolutePosition; 6334 detobj.posVector = av.AbsolutePosition;
5012 detobj.rotQuat = av.Rotation; 6335 detobj.rotQuat = av.Rotation;
5013 detobj.velVector = av.Velocity; 6336 detobj.velVector = av.Velocity;
5014 detobj.colliderType = 0; 6337 detobj.colliderType = av.IsNPC ? 0x20 : 0x1; // OpenSim\Region\ScriptEngine\Shared\Helpers.cs
6338 if(av.IsSatOnObject)
6339 detobj.colliderType |= 0x4; //passive
6340 else if(detobj.velVector != Vector3.Zero)
6341 detobj.colliderType |= 0x2; //active
5015 detobj.groupUUID = av.ControllingClient.ActiveGroupId; 6342 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
6343 detobj.linkNumber = 0;
5016 6344
5017 return detobj; 6345 return detobj;
5018 } 6346 }
@@ -5028,7 +6356,7 @@ namespace OpenSim.Region.Framework.Scenes
5028 detobj.velVector = Vector3.Zero; 6356 detobj.velVector = Vector3.Zero;
5029 detobj.colliderType = 0; 6357 detobj.colliderType = 0;
5030 detobj.groupUUID = UUID.Zero; 6358 detobj.groupUUID = UUID.Zero;
5031 6359 detobj.linkNumber = 0;
5032 return detobj; 6360 return detobj;
5033 } 6361 }
5034 6362
@@ -5095,29 +6423,404 @@ namespace OpenSim.Region.Framework.Scenes
5095 } 6423 }
5096 } 6424 }
5097 6425
6426 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
6427 {
6428 try
6429 {
6430 List<uint> thisHitColliders = new List<uint>();
6431 List<uint> endedColliders = new List<uint>();
6432 List<uint> startedColliders = new List<uint>();
6433
6434 if (coldata.Count == 0)
6435 {
6436 if (m_lastColliders.Count == 0)
6437 return; // nothing to do
6438
6439 foreach (uint localID in m_lastColliders)
6440 {
6441 endedColliders.Add(localID);
6442 }
6443 m_lastColliders.Clear();
6444 }
6445 else
6446 {
6447 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
6448 if(ParcelAllowThisAvatarSounds)
6449 {
6450 CollisionForSoundInfo soundinfo;
6451 ContactPoint curcontact;
6452
6453 foreach (uint id in coldata.Keys)
6454 {
6455 thisHitColliders.Add(id);
6456 if (!m_lastColliders.Contains(id))
6457 {
6458 startedColliders.Add(id);
6459 curcontact = coldata[id];
6460 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
6461 {
6462 soundinfo = new CollisionForSoundInfo();
6463 soundinfo.colliderID = id;
6464 soundinfo.position = curcontact.Position;
6465 soundinfo.relativeVel = curcontact.RelativeSpeed;
6466 soundinfolist.Add(soundinfo);
6467 }
6468 }
6469 }
6470 }
6471 else
6472 {
6473 foreach (uint id in coldata.Keys)
6474 {
6475 thisHitColliders.Add(id);
6476 if (!m_lastColliders.Contains(id))
6477 startedColliders.Add(id);
6478 }
6479 }
6480 // calculate things that ended colliding
6481 foreach (uint localID in m_lastColliders)
6482 {
6483 if (!thisHitColliders.Contains(localID))
6484 {
6485 endedColliders.Add(localID);
6486 }
6487 }
6488 //add the items that started colliding this time to the last colliders list.
6489 foreach (uint localID in startedColliders)
6490 {
6491 m_lastColliders.Add(localID);
6492 }
6493 // remove things that ended colliding from the last colliders list
6494 foreach (uint localID in endedColliders)
6495 {
6496 m_lastColliders.Remove(localID);
6497 }
6498
6499 if (soundinfolist.Count > 0)
6500 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
6501 }
6502
6503 foreach (SceneObjectGroup att in GetAttachments())
6504 {
6505 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
6506 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
6507 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
6508
6509 if (startedColliders.Contains(0))
6510 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
6511 if (m_lastColliders.Contains(0))
6512 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
6513 if (endedColliders.Contains(0))
6514 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
6515 }
6516 }
6517 catch { }
6518// finally
6519// {
6520// m_collisionEventFlag = false;
6521// }
6522 }
6523
5098 private void TeleportFlagsDebug() { 6524 private void TeleportFlagsDebug() {
5099 6525
5100 // Some temporary debugging help to show all the TeleportFlags we have... 6526 // Some temporary debugging help to show all the TeleportFlags we have...
5101 bool HG = false; 6527 bool HG = false;
5102 if((m_teleportFlags & TeleportFlags.ViaHGLogin) == TeleportFlags.ViaHGLogin) 6528 if((m_teleportFlags & TeleportFlags.ViaHGLogin) == TeleportFlags.ViaHGLogin)
5103 HG = true; 6529 HG = true;
5104 6530
5105 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 6531 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
5106 6532
5107 uint i = 0u; 6533 uint i = 0u;
5108 for (int x = 0; x <= 30 ; x++, i = 1u << x) 6534 for (int x = 0; x <= 30 ; x++, i = 1u << x)
5109 { 6535 {
5110 i = 1u << x; 6536 i = 1u << x;
5111 6537
5112 if((m_teleportFlags & (TeleportFlags)i) == (TeleportFlags)i) 6538 if((m_teleportFlags & (TeleportFlags)i) == (TeleportFlags)i)
5113 if (HG == false) 6539 if (HG == false)
5114 m_log.InfoFormat("[SCENE PRESENCE]: Teleport Flags include {0}", ((TeleportFlags) i).ToString()); 6540 m_log.InfoFormat("[SCENE PRESENCE]: Teleport Flags include {0}", ((TeleportFlags) i).ToString());
5115 else 6541 else
5116 m_log.InfoFormat("[SCENE PRESENCE]: HG Teleport Flags include {0}", ((TeleportFlags)i).ToString()); 6542 m_log.InfoFormat("[SCENE PRESENCE]: HG Teleport Flags include {0}", ((TeleportFlags)i).ToString());
5117 } 6543 }
5118 6544
5119 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 6545 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
5120 6546
6547 }
6548
6549 private void parcelGodCheck(UUID currentParcelID)
6550 {
6551 List<ScenePresence> allpresences = m_scene.GetScenePresences();
6552
6553 foreach (ScenePresence p in allpresences)
6554 {
6555 if (p.IsDeleted || p.IsChildAgent || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6556 continue;
6557
6558 if (p.ParcelHideThisAvatar && p.currentParcelUUID != currentParcelID)
6559 {
6560 if (IsViewerUIGod)
6561 p.SendViewTo(this);
6562 else
6563 p.SendKillTo(this);
6564 }
6565 }
6566 }
6567
6568 private void ParcelCrossCheck(UUID currentParcelID,UUID previusParcelID,
6569 bool currentParcelHide, bool previusParcelHide, bool oldhide, bool check)
6570 {
6571 List<ScenePresence> killsToSendto = new List<ScenePresence>();
6572 List<ScenePresence> killsToSendme = new List<ScenePresence>();
6573 List<ScenePresence> viewsToSendto = new List<ScenePresence>();
6574 List<ScenePresence> viewsToSendme = new List<ScenePresence>();
6575 List<ScenePresence> allpresences = null;
6576
6577 if (IsInTransit || IsChildAgent)
6578 return;
6579
6580 if (check)
6581 {
6582 // check is relative to current parcel only
6583 if (oldhide == currentParcelHide)
6584 return;
6585
6586 allpresences = m_scene.GetScenePresences();
6587
6588 if (oldhide)
6589 { // where private
6590 foreach (ScenePresence p in allpresences)
6591 {
6592 if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6593 continue;
6594
6595 // those on not on parcel see me
6596 if (currentParcelID != p.currentParcelUUID)
6597 {
6598 viewsToSendto.Add(p); // they see me
6599 }
6600 }
6601 } // where private end
6602
6603 else
6604 { // where public
6605 foreach (ScenePresence p in allpresences)
6606 {
6607 if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6608 continue;
6609
6610 // those not on parcel dont see me
6611 if (currentParcelID != p.currentParcelUUID && !p.IsViewerUIGod)
6612 {
6613 killsToSendto.Add(p); // they dont see me
6614 }
6615 }
6616 } // where public end
6617
6618 allpresences.Clear();
6619 }
6620 else
6621 {
6622 if (currentParcelHide)
6623 {
6624 // now on a private parcel
6625 allpresences = m_scene.GetScenePresences();
6626
6627 if (previusParcelHide && previusParcelID != UUID.Zero)
6628 {
6629 foreach (ScenePresence p in allpresences)
6630 {
6631 if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6632 continue;
6633
6634 // only those on previus parcel need receive kills
6635 if (previusParcelID == p.currentParcelUUID)
6636 {
6637 if(!p.IsViewerUIGod)
6638 killsToSendto.Add(p); // they dont see me
6639 if(!IsViewerUIGod)
6640 killsToSendme.Add(p); // i dont see them
6641 }
6642 // only those on new parcel need see
6643 if (currentParcelID == p.currentParcelUUID)
6644 {
6645 viewsToSendto.Add(p); // they see me
6646 viewsToSendme.Add(p); // i see them
6647 }
6648 }
6649 }
6650 else
6651 {
6652 //was on a public area
6653 allpresences = m_scene.GetScenePresences();
6654
6655 foreach (ScenePresence p in allpresences)
6656 {
6657 if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6658 continue;
6659
6660 // those not on new parcel dont see me
6661 if (currentParcelID != p.currentParcelUUID && !p.IsViewerUIGod)
6662 {
6663 killsToSendto.Add(p); // they dont see me
6664 }
6665 else
6666 {
6667 viewsToSendme.Add(p); // i see those on it
6668 }
6669 }
6670 }
6671 allpresences.Clear();
6672 } // now on a private parcel end
6673
6674 else
6675 {
6676 // now on public parcel
6677 if (previusParcelHide && previusParcelID != UUID.Zero)
6678 {
6679 // was on private area
6680 allpresences = m_scene.GetScenePresences();
6681
6682 foreach (ScenePresence p in allpresences)
6683 {
6684 if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
6685 continue;
6686 // only those old parcel need kills
6687 if (previusParcelID == p.currentParcelUUID && !IsViewerUIGod)
6688 {
6689 killsToSendme.Add(p); // i dont see them
6690 }
6691 else
6692 {
6693 viewsToSendto.Add(p); // they see me
6694 }
6695 }
6696 }
6697 else
6698 return; // was on a public area also
6699 } // now on public parcel end
6700 }
6701
6702 // send the things
6703
6704 if (killsToSendto.Count > 0)
6705 {
6706 foreach (ScenePresence p in killsToSendto)
6707 {
6708// m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname);
6709 SendKillTo(p);
6710 }
6711 }
6712
6713 if (killsToSendme.Count > 0)
6714 {
6715 foreach (ScenePresence p in killsToSendme)
6716 {
6717// m_log.Debug("[AVATAR]: killToMe: " + Lastname + " " + p.Lastname);
6718 p.SendKillTo(this);
6719 }
6720 }
6721
6722 if (viewsToSendto.Count > 0)
6723 {
6724 foreach (ScenePresence p in viewsToSendto)
6725 {
6726 SendViewTo(p);
6727 }
6728 }
6729
6730 if (viewsToSendme.Count > 0 )
6731 {
6732 foreach (ScenePresence p in viewsToSendme)
6733 {
6734 if (p.IsChildAgent)
6735 continue;
6736// m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname);
6737 p.SendViewTo(this);
6738 }
6739 }
6740 }
6741
6742 public void HasMovedAway(bool nearRegion)
6743 {
6744 if (nearRegion)
6745 {
6746 if (Scene.AttachmentsModule != null)
6747 Scene.AttachmentsModule.DeleteAttachmentsFromScene(this, true);
6748
6749 if (!ParcelHideThisAvatar || IsViewerUIGod)
6750 return;
6751
6752 List<ScenePresence> allpresences = m_scene.GetScenePresences();
6753 foreach (ScenePresence p in allpresences)
6754 {
6755 if (p.IsDeleted || p == this || p.IsChildAgent || p.ControllingClient == null || !p.ControllingClient.IsActive)
6756 continue;
6757
6758 if (p.currentParcelUUID == m_currentParcelUUID)
6759 {
6760 p.SendKillTo(this);
6761 }
6762 }
6763 }
6764 else
6765 {
6766 GodController.HasMovedAway();
6767 List<ScenePresence> allpresences = m_scene.GetScenePresences();
6768 foreach (ScenePresence p in allpresences)
6769 {
6770 if (p == this)
6771 continue;
6772 SendKillTo(p);
6773 if (!p.IsChildAgent)
6774 p.SendKillTo(this);
6775 }
6776
6777 if (Scene.AttachmentsModule != null)
6778 Scene.AttachmentsModule.DeleteAttachmentsFromScene(this, true);
6779 }
6780 }
6781
6782
6783// kill with attachs root kills
6784 public void SendKillTo(ScenePresence p)
6785 {
6786 List<uint> ids = new List<uint>(m_attachments.Count + 1);
6787 foreach (SceneObjectGroup sog in m_attachments)
6788 {
6789 ids.Add(sog.RootPart.LocalId);
6790 }
6791
6792 ids.Add(LocalId);
6793 p.ControllingClient.SendKillObject(ids);
6794 }
6795
6796/*
6797// kill with hack
6798 public void SendKillTo(ScenePresence p)
6799 {
6800 foreach (SceneObjectGroup sog in m_attachments)
6801 p.ControllingClient.SendPartFullUpdate(sog.RootPart, LocalId + 1);
6802 p.ControllingClient.SendKillObject(new List<uint> { LocalId });
6803 }
6804*/
6805 public void SendViewTo(ScenePresence p)
6806 {
6807 SendAvatarDataToAgentNF(p);
6808 SendAppearanceToAgent(p);
6809 if (Animator != null)
6810 Animator.SendAnimPackToClient(p.ControllingClient);
6811 SendAttachmentsToAgentNF(p);
6812 }
6813
6814 public void SetAnimationOverride(string animState, UUID animID)
6815 {
6816 Overrides.SetOverride(animState, animID);
6817// Animator.SendAnimPack();
6818 Animator.ForceUpdateMovementAnimations();
6819 }
6820
6821 public UUID GetAnimationOverride(string animState)
6822 {
6823 return Overrides.GetOverriddenAnimation(animState);
5121 } 6824 }
5122 } 6825 }
5123} 6826}