aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs880
1 files changed, 709 insertions, 171 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 5a3e587..95d06fe 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Xml;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using System.Timers; 32using System.Timers;
@@ -72,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
72// { 73// {
73// m_log.Debug("[SCENE PRESENCE] Destructor called"); 74// m_log.Debug("[SCENE PRESENCE] Destructor called");
74// } 75// }
75 76
76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 78
78 public PresenceType PresenceType { get; private set; } 79 public PresenceType PresenceType { get; private set; }
@@ -89,7 +90,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 90 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 91 /// issue #1716
91 /// </summary> 92 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 93// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
94 // Value revised by KF 091121 by comparison with SL.
95 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 96
94 /// <summary> 97 /// <summary>
95 /// Movement updates for agents in neighboring regions are sent directly to clients. 98 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -118,6 +121,7 @@ namespace OpenSim.Region.Framework.Scenes
118 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 121 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
119 /// necessary. 122 /// necessary.
120 /// </remarks> 123 /// </remarks>
124
121 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 125 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
122 126
123 public Object AttachmentsSyncLock { get; private set; } 127 public Object AttachmentsSyncLock { get; private set; }
@@ -131,8 +135,11 @@ namespace OpenSim.Region.Framework.Scenes
131 public Vector3 lastKnownAllowedPosition; 135 public Vector3 lastKnownAllowedPosition;
132 public bool sentMessageAboutRestrictedParcelFlyingDown; 136 public bool sentMessageAboutRestrictedParcelFlyingDown;
133 public Vector4 CollisionPlane = Vector4.UnitW; 137 public Vector4 CollisionPlane = Vector4.UnitW;
134 138
139 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
140 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
135 private Vector3 m_lastPosition; 141 private Vector3 m_lastPosition;
142 private Vector3 m_lastWorldPosition;
136 private Quaternion m_lastRotation; 143 private Quaternion m_lastRotation;
137 private Vector3 m_lastVelocity; 144 private Vector3 m_lastVelocity;
138 //private int m_lastTerseSent; 145 //private int m_lastTerseSent;
@@ -140,6 +147,11 @@ namespace OpenSim.Region.Framework.Scenes
140 private bool m_updateflag; 147 private bool m_updateflag;
141 private byte m_movementflag; 148 private byte m_movementflag;
142 private Vector3? m_forceToApply; 149 private Vector3? m_forceToApply;
150 private int m_userFlags;
151 public int UserFlags
152 {
153 get { return m_userFlags; }
154 }
143 private TeleportFlags m_teleportFlags; 155 private TeleportFlags m_teleportFlags;
144 public TeleportFlags TeleportFlags 156 public TeleportFlags TeleportFlags
145 { 157 {
@@ -170,9 +182,10 @@ namespace OpenSim.Region.Framework.Scenes
170 private int m_perfMonMS; 182 private int m_perfMonMS;
171 183
172 private bool m_setAlwaysRun; 184 private bool m_setAlwaysRun;
173
174 private bool m_forceFly; 185 private bool m_forceFly;
175 private bool m_flyDisabled; 186 private bool m_flyDisabled;
187 private bool m_flyingOld; // add for fly velocity control
188 public bool m_wasFlying; // add for fly velocity control
176 189
177 private float m_speedModifier = 1.0f; 190 private float m_speedModifier = 1.0f;
178 191
@@ -190,7 +203,8 @@ namespace OpenSim.Region.Framework.Scenes
190 203
191 protected ulong crossingFromRegion; 204 protected ulong crossingFromRegion;
192 205
193 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 206 private readonly Vector3[] Dir_Vectors = new Vector3[11];
207 private bool m_isNudging = false;
194 208
195 // Position of agent's camera in world (region cordinates) 209 // Position of agent's camera in world (region cordinates)
196 protected Vector3 m_CameraCenter; 210 protected Vector3 m_CameraCenter;
@@ -215,17 +229,25 @@ namespace OpenSim.Region.Framework.Scenes
215 private bool m_autopilotMoving; 229 private bool m_autopilotMoving;
216 private Vector3 m_autoPilotTarget; 230 private Vector3 m_autoPilotTarget;
217 private bool m_sitAtAutoTarget; 231 private bool m_sitAtAutoTarget;
232 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
218 233
219 private string m_nextSitAnimation = String.Empty; 234 private string m_nextSitAnimation = String.Empty;
220 235
221 //PauPaw:Proper PID Controler for autopilot************ 236 //PauPaw:Proper PID Controler for autopilot************
222 public bool MovingToTarget { get; private set; } 237 public bool MovingToTarget { get; private set; }
223 public Vector3 MoveToPositionTarget { get; private set; } 238 public Vector3 MoveToPositionTarget { get; private set; }
239 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
224 240
225 private bool m_followCamAuto; 241 private bool m_followCamAuto;
226 242
227 private int m_movementUpdateCount; 243 private int m_movementUpdateCount;
244 private int m_lastColCount = -1; //KF: Look for Collision chnages
245 private int m_updateCount = 0; //KF: Update Anims for a while
246 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
228 private const int NumMovementsBetweenRayCast = 5; 247 private const int NumMovementsBetweenRayCast = 5;
248 private List<uint> m_lastColliders = new List<uint>();
249
250 private object m_syncRoot = new Object();
229 251
230 private bool CameraConstraintActive; 252 private bool CameraConstraintActive;
231 //private int m_moveToPositionStateStatus; 253 //private int m_moveToPositionStateStatus;
@@ -262,7 +284,9 @@ namespace OpenSim.Region.Framework.Scenes
262 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 284 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
263 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 285 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
264 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 286 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
265 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 287 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
288 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
289 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
266 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 290 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
267 } 291 }
268 292
@@ -466,8 +490,9 @@ namespace OpenSim.Region.Framework.Scenes
466 get 490 get
467 { 491 {
468 PhysicsActor actor = m_physicsActor; 492 PhysicsActor actor = m_physicsActor;
469 if (actor != null) 493// if (actor != null)
470 { 494 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
495 {
471 m_pos = actor.Position; 496 m_pos = actor.Position;
472 497
473// m_log.DebugFormat( 498// m_log.DebugFormat(
@@ -494,7 +519,7 @@ namespace OpenSim.Region.Framework.Scenes
494 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 519 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
495 if (part != null) 520 if (part != null)
496 { 521 {
497 return m_parentPosition + (m_pos * part.GetWorldRotation()); 522 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
498 } 523 }
499 else 524 else
500 { 525 {
@@ -521,7 +546,9 @@ namespace OpenSim.Region.Framework.Scenes
521 } 546 }
522 } 547 }
523 548
524 m_pos = value; 549// Changed this to update unconditionally to make npose work
550// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
551 m_pos = value;
525 m_parentPosition = Vector3.Zero; 552 m_parentPosition = Vector3.Zero;
526 553
527// m_log.DebugFormat( 554// m_log.DebugFormat(
@@ -582,13 +609,38 @@ namespace OpenSim.Region.Framework.Scenes
582 } 609 }
583 } 610 }
584 611
612 public Quaternion OffsetRotation
613 {
614 get { return m_offsetRotation; }
615 set { m_offsetRotation = value; }
616 }
617
585 public Quaternion Rotation 618 public Quaternion Rotation
586 { 619 {
587 get { return m_bodyRot; } 620 get {
588 set 621 if (m_parentID != 0)
589 { 622 {
623 if (m_offsetRotation != null)
624 {
625 return m_offsetRotation;
626 }
627 else
628 {
629 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
630 }
631
632 }
633 else
634 {
635 return m_bodyRot;
636 }
637 }
638 set {
590 m_bodyRot = value; 639 m_bodyRot = value;
591 m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 640 if (m_parentID != 0)
641 {
642 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
643 }
592 } 644 }
593 } 645 }
594 646
@@ -614,11 +666,21 @@ namespace OpenSim.Region.Framework.Scenes
614 666
615 private uint m_parentID; 667 private uint m_parentID;
616 668
669
670 private UUID m_linkedPrim;
671
617 public uint ParentID 672 public uint ParentID
618 { 673 {
619 get { return m_parentID; } 674 get { return m_parentID; }
620 set { m_parentID = value; } 675 set { m_parentID = value; }
621 } 676 }
677
678 public UUID LinkedPrim
679 {
680 get { return m_linkedPrim; }
681 set { m_linkedPrim = value; }
682 }
683
622 public float Health 684 public float Health
623 { 685 {
624 get { return m_health; } 686 get { return m_health; }
@@ -754,6 +816,7 @@ namespace OpenSim.Region.Framework.Scenes
754 m_localId = m_scene.AllocateLocalId(); 816 m_localId = m_scene.AllocateLocalId();
755 817
756 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 818 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
819 m_userFlags = account.UserFlags;
757 820
758 if (account != null) 821 if (account != null)
759 m_userLevel = account.UserLevel; 822 m_userLevel = account.UserLevel;
@@ -772,10 +835,7 @@ namespace OpenSim.Region.Framework.Scenes
772 m_reprioritization_timer.AutoReset = false; 835 m_reprioritization_timer.AutoReset = false;
773 836
774 AdjustKnownSeeds(); 837 AdjustKnownSeeds();
775
776 // TODO: I think, this won't send anything, as we are still a child here...
777 Animator.TrySetMovementAnimation("STAND"); 838 Animator.TrySetMovementAnimation("STAND");
778
779 // we created a new ScenePresence (a new child agent) in a fresh region. 839 // we created a new ScenePresence (a new child agent) in a fresh region.
780 // Request info about all the (root) agents in this region 840 // Request info about all the (root) agents in this region
781 // Note: This won't send data *to* other clients in that region (children don't send) 841 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -816,25 +876,47 @@ namespace OpenSim.Region.Framework.Scenes
816 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 876 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
817 Dir_Vectors[4] = Vector3.UnitZ; //UP 877 Dir_Vectors[4] = Vector3.UnitZ; //UP
818 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 878 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
819 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 879 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
820 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 880 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
821 Dir_Vectors[7] = -Vector3.UnitX; //BACK 881 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
882 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
883 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
822 } 884 }
823 885
824 private Vector3[] GetWalkDirectionVectors() 886 private Vector3[] GetWalkDirectionVectors()
825 { 887 {
826 Vector3[] vector = new Vector3[9]; 888 Vector3[] vector = new Vector3[11];
827 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 889 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
828 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 890 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
829 vector[2] = Vector3.UnitY; //LEFT 891 vector[2] = Vector3.UnitY; //LEFT
830 vector[3] = -Vector3.UnitY; //RIGHT 892 vector[3] = -Vector3.UnitY; //RIGHT
831 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 893 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
832 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 894 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
833 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 895 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
834 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 896 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
835 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 897 vector[8] = Vector3.UnitY; //LEFT_NUDGE
898 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
899 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
836 return vector; 900 return vector;
837 } 901 }
902
903 private bool[] GetDirectionIsNudge()
904 {
905 bool[] isNudge = new bool[11];
906 isNudge[0] = false; //FORWARD
907 isNudge[1] = false; //BACK
908 isNudge[2] = false; //LEFT
909 isNudge[3] = false; //RIGHT
910 isNudge[4] = false; //UP
911 isNudge[5] = false; //DOWN
912 isNudge[6] = true; //FORWARD_NUDGE
913 isNudge[7] = true; //BACK_NUDGE
914 isNudge[8] = true; //LEFT_NUDGE
915 isNudge[9] = true; //RIGHT_NUDGE
916 isNudge[10] = true; //DOWN_Nudge
917 return isNudge;
918 }
919
838 920
839 #endregion 921 #endregion
840 922
@@ -899,6 +981,62 @@ namespace OpenSim.Region.Framework.Scenes
899 pos.Y = crossedBorder.BorderLine.Z - 1; 981 pos.Y = crossedBorder.BorderLine.Z - 1;
900 } 982 }
901 983
984 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
985 if (land != null)
986 {
987 // If we come in via login, landmark or map, we want to
988 // honor landing points. If we come in via Lure, we want
989 // to ignore them.
990 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
991 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
992 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
993 {
994 // Don't restrict gods, estate managers, or land owners to
995 // the TP point. This behaviour mimics agni.
996 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
997 land.LandData.UserLocation != Vector3.Zero &&
998 GodLevel < 200 &&
999 ((land.LandData.OwnerID != m_uuid &&
1000 (!m_scene.Permissions.IsGod(m_uuid)) &&
1001 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
1002 {
1003 pos = land.LandData.UserLocation;
1004 }
1005 }
1006
1007 land.SendLandUpdateToClient(ControllingClient);
1008 }
1009
1010 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
1011 {
1012 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
1013
1014 if (pos.X < 0)
1015 {
1016 emergencyPos.X = (int)Constants.RegionSize + pos.X;
1017 if (!(pos.Y < 0))
1018 emergencyPos.Y = pos.Y;
1019 if (!(pos.Z < 0))
1020 emergencyPos.Z = pos.Z;
1021 }
1022 if (pos.Y < 0)
1023 {
1024 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
1025 if (!(pos.X < 0))
1026 emergencyPos.X = pos.X;
1027 if (!(pos.Z < 0))
1028 emergencyPos.Z = pos.Z;
1029 }
1030 if (pos.Z < 0)
1031 {
1032 emergencyPos.Z = 128;
1033 if (!(pos.Y < 0))
1034 emergencyPos.Y = pos.Y;
1035 if (!(pos.X < 0))
1036 emergencyPos.X = pos.X;
1037 }
1038 }
1039
902 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1040 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
903 { 1041 {
904 m_log.WarnFormat( 1042 m_log.WarnFormat(
@@ -1031,16 +1169,21 @@ namespace OpenSim.Region.Framework.Scenes
1031 /// <summary> 1169 /// <summary>
1032 /// Removes physics plugin scene representation of this agent if it exists. 1170 /// Removes physics plugin scene representation of this agent if it exists.
1033 /// </summary> 1171 /// </summary>
1034 private void RemoveFromPhysicalScene() 1172 public void RemoveFromPhysicalScene()
1035 { 1173 {
1036 if (PhysicsActor != null) 1174 if (PhysicsActor != null)
1037 { 1175 {
1038 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1176 try
1039 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1177 {
1040 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1178 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1041 m_physicsActor.UnSubscribeEvents(); 1179 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1042 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1180 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1043 PhysicsActor = null; 1181 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1182 m_physicsActor.UnSubscribeEvents();
1183 PhysicsActor = null;
1184 }
1185 catch
1186 { }
1044 } 1187 }
1045 } 1188 }
1046 1189
@@ -1051,15 +1194,18 @@ namespace OpenSim.Region.Framework.Scenes
1051 public void Teleport(Vector3 pos) 1194 public void Teleport(Vector3 pos)
1052 { 1195 {
1053 bool isFlying = false; 1196 bool isFlying = false;
1197
1054 if (m_physicsActor != null) 1198 if (m_physicsActor != null)
1055 isFlying = m_physicsActor.Flying; 1199 isFlying = m_physicsActor.Flying;
1056 1200
1057 RemoveFromPhysicalScene(); 1201 RemoveFromPhysicalScene();
1058 Velocity = Vector3.Zero; 1202 Velocity = Vector3.Zero;
1203 CheckLandingPoint(ref pos);
1059 AbsolutePosition = pos; 1204 AbsolutePosition = pos;
1060 AddToPhysicalScene(isFlying); 1205 AddToPhysicalScene(isFlying);
1061 1206
1062 SendTerseUpdateToAllClients(); 1207 SendTerseUpdateToAllClients();
1208
1063 } 1209 }
1064 1210
1065 public void TeleportWithMomentum(Vector3 pos) 1211 public void TeleportWithMomentum(Vector3 pos)
@@ -1069,6 +1215,7 @@ namespace OpenSim.Region.Framework.Scenes
1069 isFlying = m_physicsActor.Flying; 1215 isFlying = m_physicsActor.Flying;
1070 1216
1071 RemoveFromPhysicalScene(); 1217 RemoveFromPhysicalScene();
1218 CheckLandingPoint(ref pos);
1072 AbsolutePosition = pos; 1219 AbsolutePosition = pos;
1073 AddToPhysicalScene(isFlying); 1220 AddToPhysicalScene(isFlying);
1074 1221
@@ -1244,11 +1391,12 @@ namespace OpenSim.Region.Framework.Scenes
1244 /// <summary> 1391 /// <summary>
1245 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1392 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1246 /// </summary> 1393 /// </summary>
1394 /// <summary>
1395 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1396 /// </summary>
1247 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1397 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1248 { 1398 {
1249// m_log.DebugFormat( 1399 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1250// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1251// Scene.RegionInfo.RegionName, remoteClient.Name);
1252 1400
1253 //if (m_isChildAgent) 1401 //if (m_isChildAgent)
1254 //{ 1402 //{
@@ -1444,12 +1592,12 @@ namespace OpenSim.Region.Framework.Scenes
1444 1592
1445 if ((m_movementflag & (byte)(uint)DCF) == 0) 1593 if ((m_movementflag & (byte)(uint)DCF) == 0)
1446 { 1594 {
1447 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1595 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1448 { 1596 {
1449 m_movementflag |= (byte)nudgehack; 1597 m_movementflag |= (byte)nudgehack;
1450 } 1598 }
1451 1599
1452// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF); 1600 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF);
1453 m_movementflag += (byte)(uint)DCF; 1601 m_movementflag += (byte)(uint)DCF;
1454 update_movementflag = true; 1602 update_movementflag = true;
1455 } 1603 }
@@ -1457,11 +1605,11 @@ namespace OpenSim.Region.Framework.Scenes
1457 else 1605 else
1458 { 1606 {
1459 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1607 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1460 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1608 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1461 && ((m_movementflag & (byte)nudgehack) == nudgehack)) 1609 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1462 ) // This or is for Nudge forward 1610 ) // This or is for Nudge forward
1463 { 1611 {
1464// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF); 1612 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1465 m_movementflag -= ((byte)(uint)DCF); 1613 m_movementflag -= ((byte)(uint)DCF);
1466 update_movementflag = true; 1614 update_movementflag = true;
1467 1615
@@ -1526,21 +1674,21 @@ namespace OpenSim.Region.Framework.Scenes
1526 // which occurs later in the main scene loop 1674 // which occurs later in the main scene loop
1527 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1675 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1528 { 1676 {
1529// m_log.DebugFormat( 1677 // m_log.DebugFormat(
1530// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1678 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1531// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1679 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1532 1680
1533 AddNewMovement(agent_control_v3); 1681 AddNewMovement(agent_control_v3);
1534 } 1682 }
1535// else 1683 // else
1536// { 1684 // {
1537// if (!update_movementflag) 1685 // if (!update_movementflag)
1538// { 1686 // {
1539// m_log.DebugFormat( 1687 // m_log.DebugFormat(
1540// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1688 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1541// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1689 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1542// } 1690 // }
1543// } 1691 // }
1544 1692
1545 if (update_movementflag && m_parentID == 0) 1693 if (update_movementflag && m_parentID == 0)
1546 Animator.UpdateMovementAnimations(); 1694 Animator.UpdateMovementAnimations();
@@ -1561,20 +1709,20 @@ namespace OpenSim.Region.Framework.Scenes
1561 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1709 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1562 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1710 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1563 { 1711 {
1564// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1712 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1565 1713
1566 bool updated = false; 1714 bool updated = false;
1567 1715
1568// m_log.DebugFormat( 1716 // m_log.DebugFormat(
1569// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1717 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1570// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1718 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1571 1719
1572 if (!m_autopilotMoving) 1720 if (!m_autopilotMoving)
1573 { 1721 {
1574 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1722 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1575// m_log.DebugFormat( 1723 // m_log.DebugFormat(
1576// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1724 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1577// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1725 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1578 1726
1579 // Check the error term of the current position in relation to the target position 1727 // Check the error term of the current position in relation to the target position
1580 if (distanceToTarget <= 1) 1728 if (distanceToTarget <= 1)
@@ -1597,7 +1745,7 @@ namespace OpenSim.Region.Framework.Scenes
1597 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1745 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1598 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1746 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1599 // Ignore z component of vector 1747 // Ignore z component of vector
1600// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1748 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1601 LocalVectorToTarget3D.Normalize(); 1749 LocalVectorToTarget3D.Normalize();
1602 1750
1603 // update avatar movement flags. the avatar coordinate system is as follows: 1751 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1663,9 +1811,9 @@ namespace OpenSim.Region.Framework.Scenes
1663 updated = true; 1811 updated = true;
1664 } 1812 }
1665 1813
1666// m_log.DebugFormat( 1814 // m_log.DebugFormat(
1667// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1815 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1668// LocalVectorToTarget3D, agent_control_v3, Name); 1816 // LocalVectorToTarget3D, agent_control_v3, Name);
1669 1817
1670 agent_control_v3 += LocalVectorToTarget3D; 1818 agent_control_v3 += LocalVectorToTarget3D;
1671 } 1819 }
@@ -1782,7 +1930,7 @@ namespace OpenSim.Region.Framework.Scenes
1782 Velocity = Vector3.Zero; 1930 Velocity = Vector3.Zero;
1783 SendAvatarDataToAllAgents(); 1931 SendAvatarDataToAllAgents();
1784 1932
1785 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1933 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1786 } 1934 }
1787 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1935 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1788 m_requestedSitTargetUUID = UUID.Zero; 1936 m_requestedSitTargetUUID = UUID.Zero;
@@ -1819,25 +1967,22 @@ namespace OpenSim.Region.Framework.Scenes
1819 1967
1820 if (m_parentID != 0) 1968 if (m_parentID != 0)
1821 { 1969 {
1822 m_log.Debug("StandupCode Executed"); 1970 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1823 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1824 if (part != null) 1971 if (part != null)
1825 { 1972 {
1973 part.TaskInventory.LockItemsForRead(true);
1826 TaskInventoryDictionary taskIDict = part.TaskInventory; 1974 TaskInventoryDictionary taskIDict = part.TaskInventory;
1827 if (taskIDict != null) 1975 if (taskIDict != null)
1828 { 1976 {
1829 lock (taskIDict) 1977 foreach (UUID taskID in taskIDict.Keys)
1830 { 1978 {
1831 foreach (UUID taskID in taskIDict.Keys) 1979 UnRegisterControlEventsToScript(LocalId, taskID);
1832 { 1980 taskIDict[taskID].PermsMask &= ~(
1833 UnRegisterControlEventsToScript(LocalId, taskID); 1981 2048 | //PERMISSION_CONTROL_CAMERA
1834 taskIDict[taskID].PermsMask &= ~( 1982 4); // PERMISSION_TAKE_CONTROLS
1835 2048 | //PERMISSION_CONTROL_CAMERA
1836 4); // PERMISSION_TAKE_CONTROLS
1837 }
1838 } 1983 }
1839
1840 } 1984 }
1985 part.TaskInventory.LockItemsForRead(false);
1841 // Reset sit target. 1986 // Reset sit target.
1842 if (part.GetAvatarOnSitTarget() == UUID) 1987 if (part.GetAvatarOnSitTarget() == UUID)
1843 part.SitTargetAvatar = UUID.Zero; 1988 part.SitTargetAvatar = UUID.Zero;
@@ -1846,20 +1991,58 @@ namespace OpenSim.Region.Framework.Scenes
1846 m_parentPosition = part.GetWorldPosition(); 1991 m_parentPosition = part.GetWorldPosition();
1847 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1992 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1848 } 1993 }
1994 // part.GetWorldRotation() is the rotation of the object being sat on
1995 // Rotation is the sittiing Av's rotation
1996
1997 Quaternion partRot;
1998// if (part.LinkNum == 1)
1999// { // Root prim of linkset
2000// partRot = part.ParentGroup.RootPart.RotationOffset;
2001// }
2002// else
2003// { // single or child prim
2004
2005// }
2006 if (part == null) //CW: Part may be gone. llDie() for example.
2007 {
2008 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
2009 }
2010 else
2011 {
2012 partRot = part.GetWorldRotation();
2013 }
2014
2015 Quaternion partIRot = Quaternion.Inverse(partRot);
1849 2016
2017 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
2018 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
2019
2020
1850 if (m_physicsActor == null) 2021 if (m_physicsActor == null)
1851 { 2022 {
1852 AddToPhysicalScene(false); 2023 AddToPhysicalScene(false);
1853 } 2024 }
1854 2025 //CW: If the part isn't null then we can set the current position
1855 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2026 if (part != null)
1856 m_parentPosition = Vector3.Zero; 2027 {
1857 2028 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1858 m_parentID = 0; 2029 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2030 part.IsOccupied = false;
2031 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2032 }
2033 else
2034 {
2035 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2036 AbsolutePosition = m_lastWorldPosition;
2037 }
2038
2039 m_parentPosition = Vector3.Zero;
2040 m_parentID = 0;
2041 m_linkedPrim = UUID.Zero;
2042 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1859 SendAvatarDataToAllAgents(); 2043 SendAvatarDataToAllAgents();
1860 m_requestedSitTargetID = 0; 2044 m_requestedSitTargetID = 0;
1861 } 2045 }
1862
1863 Animator.TrySetMovementAnimation("STAND"); 2046 Animator.TrySetMovementAnimation("STAND");
1864 } 2047 }
1865 2048
@@ -1890,13 +2073,9 @@ namespace OpenSim.Region.Framework.Scenes
1890 Vector3 avSitOffSet = part.SitTargetPosition; 2073 Vector3 avSitOffSet = part.SitTargetPosition;
1891 Quaternion avSitOrientation = part.SitTargetOrientation; 2074 Quaternion avSitOrientation = part.SitTargetOrientation;
1892 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2075 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1893 2076 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1894 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2077 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1895 bool SitTargetisSet = 2078 if (SitTargetisSet && !SitTargetOccupied)
1896 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1897 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1898
1899 if (SitTargetisSet && SitTargetUnOccupied)
1900 { 2079 {
1901 //switch the target to this prim 2080 //switch the target to this prim
1902 return part; 2081 return part;
@@ -1910,85 +2089,168 @@ namespace OpenSim.Region.Framework.Scenes
1910 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2089 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1911 { 2090 {
1912 bool autopilot = true; 2091 bool autopilot = true;
2092 Vector3 autopilotTarget = new Vector3();
2093 Quaternion sitOrientation = Quaternion.Identity;
1913 Vector3 pos = new Vector3(); 2094 Vector3 pos = new Vector3();
1914 Quaternion sitOrientation = pSitOrientation;
1915 Vector3 cameraEyeOffset = Vector3.Zero; 2095 Vector3 cameraEyeOffset = Vector3.Zero;
1916 Vector3 cameraAtOffset = Vector3.Zero; 2096 Vector3 cameraAtOffset = Vector3.Zero;
1917 bool forceMouselook = false; 2097 bool forceMouselook = false;
1918 2098
1919 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2099 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1920 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2100 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1921 if (part != null) 2101 if (part == null) return;
2102
2103 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2104 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2105
2106 // part is the prim to sit on
2107 // offset is the world-ref vector distance from that prim center to the click-spot
2108 // UUID is the UUID of the Avatar doing the clicking
2109
2110 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2111
2112 // Is a sit target available?
2113 Vector3 avSitOffSet = part.SitTargetPosition;
2114 Quaternion avSitOrientation = part.SitTargetOrientation;
2115
2116 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2117 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2118 Quaternion partRot;
2119// if (part.LinkNum == 1)
2120// { // Root prim of linkset
2121// partRot = part.ParentGroup.RootPart.RotationOffset;
2122// }
2123// else
2124// { // single or child prim
2125 partRot = part.GetWorldRotation();
2126// }
2127 Quaternion partIRot = Quaternion.Inverse(partRot);
2128//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2129 // Sit analysis rewritten by KF 091125
2130 if (SitTargetisSet) // scipted sit
1922 { 2131 {
1923 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2132 if (!part.IsOccupied)
1924 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2133 {
1925 2134//Console.WriteLine("Scripted, unoccupied");
1926 // Is a sit target available? 2135 part.SitTargetAvatar = UUID; // set that Av will be on it
1927 Vector3 avSitOffSet = part.SitTargetPosition; 2136 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1928 Quaternion avSitOrientation = part.SitTargetOrientation; 2137
1929 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2138 Quaternion nrot = avSitOrientation;
1930 2139 if (!part.IsRoot)
1931 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1932 bool SitTargetisSet =
1933 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1934 (
1935 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1936 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1937 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1938 )
1939 ));
1940
1941 if (SitTargetisSet && SitTargetUnOccupied)
1942 {
1943 part.SitTargetAvatar = UUID;
1944 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1945 sitOrientation = avSitOrientation;
1946 autopilot = false;
1947 }
1948 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1949
1950 pos = part.AbsolutePosition + offset;
1951 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1952 //{
1953 // offset = pos;
1954 //autopilot = false;
1955 //}
1956 if (m_physicsActor != null)
1957 {
1958 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1959 // We can remove the physicsActor until they stand up.
1960 m_sitAvatarHeight = m_physicsActor.Size.Z;
1961
1962 if (autopilot)
1963 { 2140 {
1964 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2141 nrot = part.RotationOffset * avSitOrientation;
1965 {
1966 autopilot = false;
1967
1968 RemoveFromPhysicalScene();
1969 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1970 }
1971 } 2142 }
1972 else 2143 sitOrientation = nrot; // Change rotatione to the scripted one
2144 OffsetRotation = nrot;
2145 autopilot = false; // Jump direct to scripted llSitPos()
2146 }
2147 else
2148 {
2149//Console.WriteLine("Scripted, occupied");
2150 return;
2151 }
2152 }
2153 else // Not Scripted
2154 {
2155 if ( (Math.Abs(offset.X) > 0.1f) || (Math.Abs(offset.Y) > 0.1f) ) // Changed 0.5M to 0.1M as they want to be able to sit close together
2156 {
2157 // large prim & offset, ignore if other Avs sitting
2158// offset.Z -= 0.05f;
2159 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2160 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2161
2162//Console.WriteLine(" offset ={0}", offset);
2163//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2164//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2165
2166 }
2167 else // small offset
2168 {
2169//Console.WriteLine("Small offset");
2170 if (!part.IsOccupied)
2171 {
2172 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2173 autopilotTarget = part.AbsolutePosition;
2174//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2175 }
2176 else return; // occupied small
2177 } // end large/small
2178 } // end Scripted/not
2179
2180 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2181
2182 cameraAtOffset = part.GetCameraAtOffset();
2183 cameraEyeOffset = part.GetCameraEyeOffset();
2184 forceMouselook = part.GetForceMouselook();
2185 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2186 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2187
2188 if (m_physicsActor != null)
2189 {
2190 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2191 // We can remove the physicsActor until they stand up.
2192 m_sitAvatarHeight = m_physicsActor.Size.Z;
2193 if (autopilot)
2194 { // its not a scripted sit
2195// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2196 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1973 { 2197 {
2198 autopilot = false; // close enough
2199 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2200 Not using the part's position because returning the AV to the last known standing
2201 position is likely to be more friendly, isn't it? */
1974 RemoveFromPhysicalScene(); 2202 RemoveFromPhysicalScene();
1975 } 2203 Velocity = Vector3.Zero;
2204 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2205 } // else the autopilot will get us close
2206 }
2207 else
2208 { // its a scripted sit
2209 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2210 I *am* using the part's position this time because we have no real idea how far away
2211 the avatar is from the sit target. */
2212 RemoveFromPhysicalScene();
2213 Velocity = Vector3.Zero;
1976 } 2214 }
1977
1978 cameraAtOffset = part.GetCameraAtOffset();
1979 cameraEyeOffset = part.GetCameraEyeOffset();
1980 forceMouselook = part.GetForceMouselook();
1981 } 2215 }
1982 2216 else return; // physactor is null!
1983 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2217
1984 m_requestedSitTargetUUID = targetID; 2218 Vector3 offsetr; // = offset * partIRot;
2219 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2220 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2221 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2222 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2223 //offsetr = offset * partIRot;
2224//
2225 // }
2226 // else
2227 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2228 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2229 // (offset * partRot);
2230 // }
2231
2232//Console.WriteLine(" ");
2233//Console.WriteLine("link number ={0}", part.LinkNum);
2234//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2235//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2236//Console.WriteLine("Click offst ={0}", offset);
2237//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2238//Console.WriteLine("offsetr ={0}", offsetr);
2239//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2240//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2241
2242 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2243 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2244
2245 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1985 // This calls HandleAgentSit twice, once from here, and the client calls 2246 // This calls HandleAgentSit twice, once from here, and the client calls
1986 // HandleAgentSit itself after it gets to the location 2247 // HandleAgentSit itself after it gets to the location
1987 // It doesn't get to the location until we've moved them there though 2248 // It doesn't get to the location until we've moved them there though
1988 // which happens in HandleAgentSit :P 2249 // which happens in HandleAgentSit :P
1989 m_autopilotMoving = autopilot; 2250 m_autopilotMoving = autopilot;
1990 m_autoPilotTarget = pos; 2251 m_autoPilotTarget = autopilotTarget;
1991 m_sitAtAutoTarget = autopilot; 2252 m_sitAtAutoTarget = autopilot;
2253 m_initialSitTarget = autopilotTarget;
1992 if (!autopilot) 2254 if (!autopilot)
1993 HandleAgentSit(remoteClient, UUID); 2255 HandleAgentSit(remoteClient, UUID);
1994 } 2256 }
@@ -2253,47 +2515,130 @@ namespace OpenSim.Region.Framework.Scenes
2253 { 2515 {
2254 if (part != null) 2516 if (part != null)
2255 { 2517 {
2518//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2256 if (part.GetAvatarOnSitTarget() == UUID) 2519 if (part.GetAvatarOnSitTarget() == UUID)
2257 { 2520 {
2521//Console.WriteLine("Scripted Sit");
2522 // Scripted sit
2258 Vector3 sitTargetPos = part.SitTargetPosition; 2523 Vector3 sitTargetPos = part.SitTargetPosition;
2259 Quaternion sitTargetOrient = part.SitTargetOrientation; 2524 Quaternion sitTargetOrient = part.SitTargetOrientation;
2260
2261 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2262 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2263
2264 //Quaternion result = (sitTargetOrient * vq) * nq;
2265
2266 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2525 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2267 m_pos += SIT_TARGET_ADJUSTMENT; 2526 m_pos += SIT_TARGET_ADJUSTMENT;
2527 if (!part.IsRoot)
2528 {
2529 m_pos *= part.RotationOffset;
2530 }
2268 m_bodyRot = sitTargetOrient; 2531 m_bodyRot = sitTargetOrient;
2269 //Rotation = sitTargetOrient;
2270 m_parentPosition = part.AbsolutePosition; 2532 m_parentPosition = part.AbsolutePosition;
2271 2533 part.IsOccupied = true;
2272 //SendTerseUpdateToAllClients(); 2534 part.ParentGroup.AddAvatar(agentID);
2273 } 2535 }
2274 else 2536 else
2275 { 2537 {
2276 m_pos -= part.AbsolutePosition; 2538 // if m_avUnscriptedSitPos is zero then Av sits above center
2539 // Else Av sits at m_avUnscriptedSitPos
2540
2541 // Non-scripted sit by Kitto Flora 21Nov09
2542 // Calculate angle of line from prim to Av
2543 Quaternion partIRot;
2544// if (part.LinkNum == 1)
2545// { // Root prim of linkset
2546// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2547// }
2548// else
2549// { // single or child prim
2550 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2551// }
2552 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2553 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2554 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2555 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2556 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2557 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2558 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2559 // Av sits at world euler <0,0, z>, translated by part rotation
2560 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2561
2277 m_parentPosition = part.AbsolutePosition; 2562 m_parentPosition = part.AbsolutePosition;
2278 } 2563 part.IsOccupied = true;
2564 part.ParentGroup.AddAvatar(agentID);
2565 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2566 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2567 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2568 m_avUnscriptedSitPos; // adds click offset, if any
2569 //Set up raytrace to find top surface of prim
2570 Vector3 size = part.Scale;
2571 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2572 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2573 Vector3 down = new Vector3(0f, 0f, -1f);
2574//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2575 m_scene.PhysicsScene.RaycastWorld(
2576 start, // Vector3 position,
2577 down, // Vector3 direction,
2578 mag, // float length,
2579 SitAltitudeCallback); // retMethod
2580 } // end scripted/not
2279 } 2581 }
2280 else 2582 else // no Av
2281 { 2583 {
2282 return; 2584 return;
2283 } 2585 }
2284 } 2586 }
2285 m_parentID = m_requestedSitTargetID;
2286 2587
2588 //We want our offsets to reference the root prim, not the child we may have sat on
2589 if (!part.IsRoot)
2590 {
2591 m_parentID = part.ParentGroup.RootPart.LocalId;
2592 m_pos += part.OffsetPosition;
2593 }
2594 else
2595 {
2596 m_parentID = m_requestedSitTargetID;
2597 }
2598
2599 m_linkedPrim = part.UUID;
2600 if (part.GetAvatarOnSitTarget() != UUID)
2601 {
2602 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2603 }
2287 Velocity = Vector3.Zero; 2604 Velocity = Vector3.Zero;
2288 RemoveFromPhysicalScene(); 2605 RemoveFromPhysicalScene();
2289
2290 Animator.TrySetMovementAnimation(sitAnimation); 2606 Animator.TrySetMovementAnimation(sitAnimation);
2291 SendAvatarDataToAllAgents(); 2607 SendAvatarDataToAllAgents();
2292 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2293 // So we're also sending a terse update (which has avatar rotation)
2294 // [Update] We do now.
2295 //SendTerseUpdateToAllClients(); 2608 //SendTerseUpdateToAllClients();
2296 } 2609 }
2610
2611 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2612 {
2613 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2614 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2615 if(hitYN)
2616 {
2617 // m_pos = Av offset from prim center to make look like on center
2618 // m_parentPosition = Actual center pos of prim
2619 // collisionPoint = spot on prim where we want to sit
2620 // collisionPoint.Z = global sit surface height
2621 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2622 Quaternion partIRot;
2623// if (part.LinkNum == 1)
2624/// { // Root prim of linkset
2625// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2626// }
2627// else
2628// { // single or child prim
2629 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2630// }
2631 if (m_initialSitTarget != null)
2632 {
2633 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2634 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2635 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2636 m_pos += offset;
2637 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2638 }
2639
2640 }
2641 } // End SitAltitudeCallback KF.
2297 2642
2298 /// <summary> 2643 /// <summary>
2299 /// Event handler for the 'Always run' setting on the client 2644 /// Event handler for the 'Always run' setting on the client
@@ -2413,6 +2758,9 @@ namespace OpenSim.Region.Framework.Scenes
2413 2758
2414 CheckForSignificantMovement(); // sends update to the modules. 2759 CheckForSignificantMovement(); // sends update to the modules.
2415 } 2760 }
2761
2762 //Sending prim updates AFTER the avatar terse updates are sent
2763 SendPrimUpdates();
2416 } 2764 }
2417 2765
2418 #endregion 2766 #endregion
@@ -3226,6 +3574,7 @@ namespace OpenSim.Region.Framework.Scenes
3226 m_callbackURI = cAgent.CallbackURI; 3574 m_callbackURI = cAgent.CallbackURI;
3227 3575
3228 m_pos = cAgent.Position; 3576 m_pos = cAgent.Position;
3577
3229 m_velocity = cAgent.Velocity; 3578 m_velocity = cAgent.Velocity;
3230 m_CameraCenter = cAgent.Center; 3579 m_CameraCenter = cAgent.Center;
3231 m_CameraAtAxis = cAgent.AtAxis; 3580 m_CameraAtAxis = cAgent.AtAxis;
@@ -3342,10 +3691,8 @@ namespace OpenSim.Region.Framework.Scenes
3342 3691
3343 Vector3 pVec = AbsolutePosition; 3692 Vector3 pVec = AbsolutePosition;
3344 3693
3345 // Old bug where the height was in centimeters instead of meters 3694 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3346 m_physicsActor = scene.AddAvatar(LocalId, Firstname + "." + Lastname, pVec,
3347 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3695 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3348
3349 scene.AddPhysicsActorTaint(m_physicsActor); 3696 scene.AddPhysicsActorTaint(m_physicsActor);
3350 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3697 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3351 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3698 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3371,18 +3718,29 @@ namespace OpenSim.Region.Framework.Scenes
3371 { 3718 {
3372 if (e == null) 3719 if (e == null)
3373 return; 3720 return;
3374 3721
3375 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3722 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3376 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3377 // as of this comment the interval is set in AddToPhysicalScene 3723 // as of this comment the interval is set in AddToPhysicalScene
3378 if (Animator != null) 3724 if (Animator!=null)
3379 Animator.UpdateMovementAnimations(); 3725 {
3726 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3727 { // else its will lock out other animation changes, like ground sit.
3728 Animator.UpdateMovementAnimations();
3729 m_updateCount--;
3730 }
3731 }
3380 3732
3381 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3733 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3382 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3734 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3383 3735
3384 CollisionPlane = Vector4.UnitW; 3736 CollisionPlane = Vector4.UnitW;
3385 3737
3738 if (m_lastColCount != coldata.Count)
3739 {
3740 m_updateCount = UPDATE_COUNT;
3741 m_lastColCount = coldata.Count;
3742 }
3743
3386 if (coldata.Count != 0 && Animator != null) 3744 if (coldata.Count != 0 && Animator != null)
3387 { 3745 {
3388 switch (Animator.CurrentMovementAnimation) 3746 switch (Animator.CurrentMovementAnimation)
@@ -3412,6 +3770,148 @@ namespace OpenSim.Region.Framework.Scenes
3412 } 3770 }
3413 } 3771 }
3414 3772
3773 List<uint> thisHitColliders = new List<uint>();
3774 List<uint> endedColliders = new List<uint>();
3775 List<uint> startedColliders = new List<uint>();
3776
3777 foreach (uint localid in coldata.Keys)
3778 {
3779 thisHitColliders.Add(localid);
3780 if (!m_lastColliders.Contains(localid))
3781 {
3782 startedColliders.Add(localid);
3783 }
3784 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3785 }
3786
3787 // calculate things that ended colliding
3788 foreach (uint localID in m_lastColliders)
3789 {
3790 if (!thisHitColliders.Contains(localID))
3791 {
3792 endedColliders.Add(localID);
3793 }
3794 }
3795 //add the items that started colliding this time to the last colliders list.
3796 foreach (uint localID in startedColliders)
3797 {
3798 m_lastColliders.Add(localID);
3799 }
3800 // remove things that ended colliding from the last colliders list
3801 foreach (uint localID in endedColliders)
3802 {
3803 m_lastColliders.Remove(localID);
3804 }
3805
3806 // do event notification
3807 if (startedColliders.Count > 0)
3808 {
3809 ColliderArgs StartCollidingMessage = new ColliderArgs();
3810 List<DetectedObject> colliding = new List<DetectedObject>();
3811 foreach (uint localId in startedColliders)
3812 {
3813 if (localId == 0)
3814 continue;
3815
3816 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3817 string data = "";
3818 if (obj != null)
3819 {
3820 DetectedObject detobj = new DetectedObject();
3821 detobj.keyUUID = obj.UUID;
3822 detobj.nameStr = obj.Name;
3823 detobj.ownerUUID = obj.OwnerID;
3824 detobj.posVector = obj.AbsolutePosition;
3825 detobj.rotQuat = obj.GetWorldRotation();
3826 detobj.velVector = obj.Velocity;
3827 detobj.colliderType = 0;
3828 detobj.groupUUID = obj.GroupID;
3829 colliding.Add(detobj);
3830 }
3831 }
3832
3833 if (colliding.Count > 0)
3834 {
3835 StartCollidingMessage.Colliders = colliding;
3836
3837 foreach (SceneObjectGroup att in GetAttachments())
3838 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3839 }
3840 }
3841
3842 if (endedColliders.Count > 0)
3843 {
3844 ColliderArgs EndCollidingMessage = new ColliderArgs();
3845 List<DetectedObject> colliding = new List<DetectedObject>();
3846 foreach (uint localId in endedColliders)
3847 {
3848 if (localId == 0)
3849 continue;
3850
3851 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3852 string data = "";
3853 if (obj != null)
3854 {
3855 DetectedObject detobj = new DetectedObject();
3856 detobj.keyUUID = obj.UUID;
3857 detobj.nameStr = obj.Name;
3858 detobj.ownerUUID = obj.OwnerID;
3859 detobj.posVector = obj.AbsolutePosition;
3860 detobj.rotQuat = obj.GetWorldRotation();
3861 detobj.velVector = obj.Velocity;
3862 detobj.colliderType = 0;
3863 detobj.groupUUID = obj.GroupID;
3864 colliding.Add(detobj);
3865 }
3866 }
3867
3868 if (colliding.Count > 0)
3869 {
3870 EndCollidingMessage.Colliders = colliding;
3871
3872 foreach (SceneObjectGroup att in GetAttachments())
3873 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3874 }
3875 }
3876
3877 if (thisHitColliders.Count > 0)
3878 {
3879 ColliderArgs CollidingMessage = new ColliderArgs();
3880 List<DetectedObject> colliding = new List<DetectedObject>();
3881 foreach (uint localId in thisHitColliders)
3882 {
3883 if (localId == 0)
3884 continue;
3885
3886 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3887 string data = "";
3888 if (obj != null)
3889 {
3890 DetectedObject detobj = new DetectedObject();
3891 detobj.keyUUID = obj.UUID;
3892 detobj.nameStr = obj.Name;
3893 detobj.ownerUUID = obj.OwnerID;
3894 detobj.posVector = obj.AbsolutePosition;
3895 detobj.rotQuat = obj.GetWorldRotation();
3896 detobj.velVector = obj.Velocity;
3897 detobj.colliderType = 0;
3898 detobj.groupUUID = obj.GroupID;
3899 colliding.Add(detobj);
3900 }
3901 }
3902
3903 if (colliding.Count > 0)
3904 {
3905 CollidingMessage.Colliders = colliding;
3906
3907 lock (m_attachments)
3908 {
3909 foreach (SceneObjectGroup att in m_attachments)
3910 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3911 }
3912 }
3913 }
3914
3415 if (m_invulnerable) 3915 if (m_invulnerable)
3416 return; 3916 return;
3417 3917
@@ -3485,6 +3985,10 @@ namespace OpenSim.Region.Framework.Scenes
3485 { 3985 {
3486 lock (m_attachments) 3986 lock (m_attachments)
3487 { 3987 {
3988 // This may be true when the attachment comes back
3989 // from serialization after login. Clear it.
3990 gobj.IsDeleted = false;
3991
3488 m_attachments.Add(gobj); 3992 m_attachments.Add(gobj);
3489 } 3993 }
3490 } 3994 }
@@ -3848,5 +4352,39 @@ namespace OpenSim.Region.Framework.Scenes
3848 m_reprioritization_called = false; 4352 m_reprioritization_called = false;
3849 } 4353 }
3850 } 4354 }
4355
4356 private Vector3 Quat2Euler(Quaternion rot){
4357 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4358 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4359 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4360 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4361 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4362 return(new Vector3(x,y,z));
4363 }
4364
4365 private void CheckLandingPoint(ref Vector3 pos)
4366 {
4367 // Never constrain lures
4368 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4369 return;
4370
4371 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4372 return;
4373
4374 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4375
4376 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4377 land.LandData.UserLocation != Vector3.Zero &&
4378 land.LandData.OwnerID != m_uuid &&
4379 (!m_scene.Permissions.IsGod(m_uuid)) &&
4380 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4381 {
4382 float curr = Vector3.Distance(AbsolutePosition, pos);
4383 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4384 pos = land.LandData.UserLocation;
4385 else
4386 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4387 }
4388 }
3851 } 4389 }
3852} 4390}