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