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.cs893
1 files changed, 719 insertions, 174 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index e4e5f17..925a4f3 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.
@@ -117,6 +120,7 @@ namespace OpenSim.Region.Framework.Scenes
117 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 120 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
118 /// necessary. 121 /// necessary.
119 /// </remarks> 122 /// </remarks>
123
120 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 124 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
121 125
122 public Object AttachmentsSyncLock { get; private set; } 126 public Object AttachmentsSyncLock { get; private set; }
@@ -130,13 +134,21 @@ namespace OpenSim.Region.Framework.Scenes
130 public Vector3 lastKnownAllowedPosition; 134 public Vector3 lastKnownAllowedPosition;
131 public bool sentMessageAboutRestrictedParcelFlyingDown; 135 public bool sentMessageAboutRestrictedParcelFlyingDown;
132 public Vector4 CollisionPlane = Vector4.UnitW; 136 public Vector4 CollisionPlane = Vector4.UnitW;
133 137
138 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
139 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
134 private Vector3 m_lastPosition; 140 private Vector3 m_lastPosition;
141 private Vector3 m_lastWorldPosition;
135 private Quaternion m_lastRotation; 142 private Quaternion m_lastRotation;
136 private Vector3 m_lastVelocity; 143 private Vector3 m_lastVelocity;
137 //private int m_lastTerseSent; 144 //private int m_lastTerseSent;
138 145
139 private Vector3? m_forceToApply; 146 private Vector3? m_forceToApply;
147 private int m_userFlags;
148 public int UserFlags
149 {
150 get { return m_userFlags; }
151 }
140 private TeleportFlags m_teleportFlags; 152 private TeleportFlags m_teleportFlags;
141 public TeleportFlags TeleportFlags 153 public TeleportFlags TeleportFlags
142 { 154 {
@@ -161,6 +173,9 @@ namespace OpenSim.Region.Framework.Scenes
161 173
162 private int m_perfMonMS; 174 private int m_perfMonMS;
163 175
176 private bool m_flyingOld; // add for fly velocity control
177 public bool m_wasFlying; // add for fly velocity control
178
164 private const int LAND_VELOCITYMAG_MAX = 12; 179 private const int LAND_VELOCITYMAG_MAX = 12;
165 180
166 public bool IsRestrictedToRegion; 181 public bool IsRestrictedToRegion;
@@ -171,7 +186,8 @@ namespace OpenSim.Region.Framework.Scenes
171 186
172 protected ulong crossingFromRegion; 187 protected ulong crossingFromRegion;
173 188
174 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 189 private readonly Vector3[] Dir_Vectors = new Vector3[11];
190 private bool m_isNudging = false;
175 191
176 192
177 protected Timer m_reprioritization_timer; 193 protected Timer m_reprioritization_timer;
@@ -186,12 +202,14 @@ namespace OpenSim.Region.Framework.Scenes
186 private bool m_autopilotMoving; 202 private bool m_autopilotMoving;
187 private Vector3 m_autoPilotTarget; 203 private Vector3 m_autoPilotTarget;
188 private bool m_sitAtAutoTarget; 204 private bool m_sitAtAutoTarget;
205 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
189 206
190 private string m_nextSitAnimation = String.Empty; 207 private string m_nextSitAnimation = String.Empty;
191 208
192 //PauPaw:Proper PID Controler for autopilot************ 209 //PauPaw:Proper PID Controler for autopilot************
193 public bool MovingToTarget { get; private set; } 210 public bool MovingToTarget { get; private set; }
194 public Vector3 MoveToPositionTarget { get; private set; } 211 public Vector3 MoveToPositionTarget { get; private set; }
212 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
195 213
196 /// <summary> 214 /// <summary>
197 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying). 215 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying).
@@ -201,7 +219,13 @@ namespace OpenSim.Region.Framework.Scenes
201 private bool m_followCamAuto; 219 private bool m_followCamAuto;
202 220
203 private int m_movementUpdateCount; 221 private int m_movementUpdateCount;
222 private int m_lastColCount = -1; //KF: Look for Collision chnages
223 private int m_updateCount = 0; //KF: Update Anims for a while
224 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
204 private const int NumMovementsBetweenRayCast = 5; 225 private const int NumMovementsBetweenRayCast = 5;
226 private List<uint> m_lastColliders = new List<uint>();
227
228 private object m_syncRoot = new Object();
205 229
206 private bool CameraConstraintActive; 230 private bool CameraConstraintActive;
207 //private int m_moveToPositionStateStatus; 231 //private int m_moveToPositionStateStatus;
@@ -247,7 +271,9 @@ namespace OpenSim.Region.Framework.Scenes
247 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 271 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
248 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 272 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
249 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 273 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
250 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 274 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
275 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
276 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
251 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 277 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
252 } 278 }
253 279
@@ -483,9 +509,11 @@ namespace OpenSim.Region.Framework.Scenes
483 { 509 {
484 get 510 get
485 { 511 {
486 if (PhysicsActor != null) 512 PhysicsActor actor = m_physicsActor;
487 { 513// if (actor != null)
488 m_pos = PhysicsActor.Position; 514 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
515 {
516 m_pos = actor.Position;
489 517
490// m_log.DebugFormat( 518// m_log.DebugFormat(
491// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!", 519// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!",
@@ -511,7 +539,7 @@ namespace OpenSim.Region.Framework.Scenes
511 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 539 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
512 if (part != null) 540 if (part != null)
513 { 541 {
514 return ParentPosition + (m_pos * part.GetWorldRotation()); 542 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
515 } 543 }
516 else 544 else
517 { 545 {
@@ -537,8 +565,10 @@ namespace OpenSim.Region.Framework.Scenes
537 } 565 }
538 } 566 }
539 567
540 m_pos = value; 568// Changed this to update unconditionally to make npose work
541 ParentPosition = Vector3.Zero; 569// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
570 m_pos = value;
571 m_parentPosition = Vector3.Zero;
542 572
543// m_log.DebugFormat( 573// m_log.DebugFormat(
544// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 574// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
@@ -596,15 +626,39 @@ namespace OpenSim.Region.Framework.Scenes
596 } 626 }
597 } 627 }
598 628
629 public Quaternion OffsetRotation
630 {
631 get { return m_offsetRotation; }
632 set { m_offsetRotation = value; }
633 }
599 private Quaternion m_bodyRot = Quaternion.Identity; 634 private Quaternion m_bodyRot = Quaternion.Identity;
600 635
601 public Quaternion Rotation 636 public Quaternion Rotation
602 { 637 {
603 get { return m_bodyRot; } 638 get {
604 set 639 if (m_parentID != 0)
605 { 640 {
641 if (m_offsetRotation != null)
642 {
643 return m_offsetRotation;
644 }
645 else
646 {
647 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
648 }
649
650 }
651 else
652 {
653 return m_bodyRot;
654 }
655 }
656 set {
606 m_bodyRot = value; 657 m_bodyRot = value;
607// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 658 if (m_parentID != 0)
659 {
660 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
661 }
608 } 662 }
609 } 663 }
610 664
@@ -624,11 +678,21 @@ namespace OpenSim.Region.Framework.Scenes
624 678
625 private uint m_parentID; 679 private uint m_parentID;
626 680
681
682 private UUID m_linkedPrim;
683
627 public uint ParentID 684 public uint ParentID
628 { 685 {
629 get { return m_parentID; } 686 get { return m_parentID; }
630 set { m_parentID = value; } 687 set { m_parentID = value; }
631 } 688 }
689
690 public UUID LinkedPrim
691 {
692 get { return m_linkedPrim; }
693 set { m_linkedPrim = value; }
694 }
695
632 public float Health 696 public float Health
633 { 697 {
634 get { return m_health; } 698 get { return m_health; }
@@ -783,6 +847,7 @@ namespace OpenSim.Region.Framework.Scenes
783 m_localId = m_scene.AllocateLocalId(); 847 m_localId = m_scene.AllocateLocalId();
784 848
785 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 849 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
850 m_userFlags = account.UserFlags;
786 851
787 if (account != null) 852 if (account != null)
788 UserLevel = account.UserLevel; 853 UserLevel = account.UserLevel;
@@ -801,10 +866,7 @@ namespace OpenSim.Region.Framework.Scenes
801 m_reprioritization_timer.AutoReset = false; 866 m_reprioritization_timer.AutoReset = false;
802 867
803 AdjustKnownSeeds(); 868 AdjustKnownSeeds();
804
805 // TODO: I think, this won't send anything, as we are still a child here...
806 Animator.TrySetMovementAnimation("STAND"); 869 Animator.TrySetMovementAnimation("STAND");
807
808 // we created a new ScenePresence (a new child agent) in a fresh region. 870 // we created a new ScenePresence (a new child agent) in a fresh region.
809 // Request info about all the (root) agents in this region 871 // Request info about all the (root) agents in this region
810 // Note: This won't send data *to* other clients in that region (children don't send) 872 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -845,25 +907,47 @@ namespace OpenSim.Region.Framework.Scenes
845 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 907 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
846 Dir_Vectors[4] = Vector3.UnitZ; //UP 908 Dir_Vectors[4] = Vector3.UnitZ; //UP
847 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 909 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
848 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 910 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
849 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 911 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
850 Dir_Vectors[7] = -Vector3.UnitX; //BACK 912 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
913 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
914 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
851 } 915 }
852 916
853 private Vector3[] GetWalkDirectionVectors() 917 private Vector3[] GetWalkDirectionVectors()
854 { 918 {
855 Vector3[] vector = new Vector3[9]; 919 Vector3[] vector = new Vector3[11];
856 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z); //FORWARD 920 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
857 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK 921 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
858 vector[2] = Vector3.UnitY; //LEFT 922 vector[2] = Vector3.UnitY; //LEFT
859 vector[3] = -Vector3.UnitY; //RIGHT 923 vector[3] = -Vector3.UnitY; //RIGHT
860 vector[4] = new Vector3(CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 924 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
861 vector[5] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 925 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
862 vector[8] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 926 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
863 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z) * 2); //FORWARD Nudge 927 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
864 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK Nudge 928 vector[8] = Vector3.UnitY; //LEFT_NUDGE
929 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
930 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
865 return vector; 931 return vector;
866 } 932 }
933
934 private bool[] GetDirectionIsNudge()
935 {
936 bool[] isNudge = new bool[11];
937 isNudge[0] = false; //FORWARD
938 isNudge[1] = false; //BACK
939 isNudge[2] = false; //LEFT
940 isNudge[3] = false; //RIGHT
941 isNudge[4] = false; //UP
942 isNudge[5] = false; //DOWN
943 isNudge[6] = true; //FORWARD_NUDGE
944 isNudge[7] = true; //BACK_NUDGE
945 isNudge[8] = true; //LEFT_NUDGE
946 isNudge[9] = true; //RIGHT_NUDGE
947 isNudge[10] = true; //DOWN_Nudge
948 return isNudge;
949 }
950
867 951
868 #endregion 952 #endregion
869 953
@@ -879,6 +963,8 @@ namespace OpenSim.Region.Framework.Scenes
879 /// </summary> 963 /// </summary>
880 public void SendPrimUpdates() 964 public void SendPrimUpdates()
881 { 965 {
966 m_sceneViewer.SendPrimUpdates();
967
882 SceneViewer.SendPrimUpdates(); 968 SceneViewer.SendPrimUpdates();
883 } 969 }
884 970
@@ -924,6 +1010,62 @@ namespace OpenSim.Region.Framework.Scenes
924 pos.Y = crossedBorder.BorderLine.Z - 1; 1010 pos.Y = crossedBorder.BorderLine.Z - 1;
925 } 1011 }
926 1012
1013 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
1014 if (land != null)
1015 {
1016 // If we come in via login, landmark or map, we want to
1017 // honor landing points. If we come in via Lure, we want
1018 // to ignore them.
1019 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
1020 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
1021 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
1022 {
1023 // Don't restrict gods, estate managers, or land owners to
1024 // the TP point. This behaviour mimics agni.
1025 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
1026 land.LandData.UserLocation != Vector3.Zero &&
1027 GodLevel < 200 &&
1028 ((land.LandData.OwnerID != m_uuid &&
1029 (!m_scene.Permissions.IsGod(m_uuid)) &&
1030 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
1031 {
1032 pos = land.LandData.UserLocation;
1033 }
1034 }
1035
1036 land.SendLandUpdateToClient(ControllingClient);
1037 }
1038
1039 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
1040 {
1041 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
1042
1043 if (pos.X < 0)
1044 {
1045 emergencyPos.X = (int)Constants.RegionSize + pos.X;
1046 if (!(pos.Y < 0))
1047 emergencyPos.Y = pos.Y;
1048 if (!(pos.Z < 0))
1049 emergencyPos.Z = pos.Z;
1050 }
1051 if (pos.Y < 0)
1052 {
1053 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
1054 if (!(pos.X < 0))
1055 emergencyPos.X = pos.X;
1056 if (!(pos.Z < 0))
1057 emergencyPos.Z = pos.Z;
1058 }
1059 if (pos.Z < 0)
1060 {
1061 emergencyPos.Z = 128;
1062 if (!(pos.Y < 0))
1063 emergencyPos.Y = pos.Y;
1064 if (!(pos.X < 0))
1065 emergencyPos.X = pos.X;
1066 }
1067 }
1068
927 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1069 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
928 { 1070 {
929 m_log.WarnFormat( 1071 m_log.WarnFormat(
@@ -1056,16 +1198,21 @@ namespace OpenSim.Region.Framework.Scenes
1056 /// <summary> 1198 /// <summary>
1057 /// Removes physics plugin scene representation of this agent if it exists. 1199 /// Removes physics plugin scene representation of this agent if it exists.
1058 /// </summary> 1200 /// </summary>
1059 private void RemoveFromPhysicalScene() 1201 public void RemoveFromPhysicalScene()
1060 { 1202 {
1061 if (PhysicsActor != null) 1203 if (PhysicsActor != null)
1062 { 1204 {
1063 PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1205 try
1064 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1206 {
1065 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1207 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1066 PhysicsActor.UnSubscribeEvents(); 1208 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1067 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1209 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1068 PhysicsActor = null; 1210 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1211 m_physicsActor.UnSubscribeEvents();
1212 PhysicsActor = null;
1213 }
1214 catch
1215 { }
1069 } 1216 }
1070 } 1217 }
1071 1218
@@ -1081,10 +1228,12 @@ namespace OpenSim.Region.Framework.Scenes
1081 1228
1082 RemoveFromPhysicalScene(); 1229 RemoveFromPhysicalScene();
1083 Velocity = Vector3.Zero; 1230 Velocity = Vector3.Zero;
1231 CheckLandingPoint(ref pos);
1084 AbsolutePosition = pos; 1232 AbsolutePosition = pos;
1085 AddToPhysicalScene(isFlying); 1233 AddToPhysicalScene(isFlying);
1086 1234
1087 SendTerseUpdateToAllClients(); 1235 SendTerseUpdateToAllClients();
1236
1088 } 1237 }
1089 1238
1090 public void TeleportWithMomentum(Vector3 pos) 1239 public void TeleportWithMomentum(Vector3 pos)
@@ -1094,6 +1243,7 @@ namespace OpenSim.Region.Framework.Scenes
1094 isFlying = PhysicsActor.Flying; 1243 isFlying = PhysicsActor.Flying;
1095 1244
1096 RemoveFromPhysicalScene(); 1245 RemoveFromPhysicalScene();
1246 CheckLandingPoint(ref pos);
1097 AbsolutePosition = pos; 1247 AbsolutePosition = pos;
1098 AddToPhysicalScene(isFlying); 1248 AddToPhysicalScene(isFlying);
1099 1249
@@ -1269,11 +1419,12 @@ namespace OpenSim.Region.Framework.Scenes
1269 /// <summary> 1419 /// <summary>
1270 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1420 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1271 /// </summary> 1421 /// </summary>
1422 /// <summary>
1423 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1424 /// </summary>
1272 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1425 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1273 { 1426 {
1274// m_log.DebugFormat( 1427 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1275// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1276// Scene.RegionInfo.RegionName, remoteClient.Name);
1277 1428
1278 //if (IsChildAgent) 1429 //if (IsChildAgent)
1279 //{ 1430 //{
@@ -1469,7 +1620,7 @@ namespace OpenSim.Region.Framework.Scenes
1469 1620
1470 if ((MovementFlag & (byte)(uint)DCF) == 0) 1621 if ((MovementFlag & (byte)(uint)DCF) == 0)
1471 { 1622 {
1472 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1623 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1473 { 1624 {
1474 MovementFlag |= (byte)nudgehack; 1625 MovementFlag |= (byte)nudgehack;
1475 } 1626 }
@@ -1481,13 +1632,13 @@ namespace OpenSim.Region.Framework.Scenes
1481 } 1632 }
1482 else 1633 else
1483 { 1634 {
1484 if ((MovementFlag & (byte)(uint)DCF) != 0 || 1635 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1485 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1636 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1486 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1637 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1487 ) // This or is for Nudge forward 1638 ) // This or is for Nudge forward
1488 { 1639 {
1489// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1640 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1490 MovementFlag -= ((byte)(uint)DCF); 1641 m_movementflag -= ((byte)(uint)DCF);
1491 update_movementflag = true; 1642 update_movementflag = true;
1492 1643
1493 /* 1644 /*
@@ -1548,21 +1699,21 @@ namespace OpenSim.Region.Framework.Scenes
1548 // which occurs later in the main scene loop 1699 // which occurs later in the main scene loop
1549 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1700 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1550 { 1701 {
1551// m_log.DebugFormat( 1702 // m_log.DebugFormat(
1552// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1703 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1553// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1704 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1554 1705
1555 AddNewMovement(agent_control_v3); 1706 AddNewMovement(agent_control_v3);
1556 } 1707 }
1557// else 1708 // else
1558// { 1709 // {
1559// if (!update_movementflag) 1710 // if (!update_movementflag)
1560// { 1711 // {
1561// m_log.DebugFormat( 1712 // m_log.DebugFormat(
1562// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1713 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1563// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1714 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1564// } 1715 // }
1565// } 1716 // }
1566 1717
1567 if (update_movementflag && ParentID == 0) 1718 if (update_movementflag && ParentID == 0)
1568 Animator.UpdateMovementAnimations(); 1719 Animator.UpdateMovementAnimations();
@@ -1584,20 +1735,20 @@ namespace OpenSim.Region.Framework.Scenes
1584 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1735 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1585 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1736 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1586 { 1737 {
1587// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1738 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1588 1739
1589 bool updated = false; 1740 bool updated = false;
1590 1741
1591// m_log.DebugFormat( 1742 // m_log.DebugFormat(
1592// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1743 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1593// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1744 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1594 1745
1595 if (!m_autopilotMoving) 1746 if (!m_autopilotMoving)
1596 { 1747 {
1597 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1748 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1598// m_log.DebugFormat( 1749 // m_log.DebugFormat(
1599// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1750 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1600// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1751 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1601 1752
1602 // Check the error term of the current position in relation to the target position 1753 // Check the error term of the current position in relation to the target position
1603 if (distanceToTarget <= 1) 1754 if (distanceToTarget <= 1)
@@ -1620,7 +1771,7 @@ namespace OpenSim.Region.Framework.Scenes
1620 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1771 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1621 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1772 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1622 // Ignore z component of vector 1773 // Ignore z component of vector
1623// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1774 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1624 LocalVectorToTarget3D.Normalize(); 1775 LocalVectorToTarget3D.Normalize();
1625 1776
1626 // update avatar movement flags. the avatar coordinate system is as follows: 1777 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1686,9 +1837,9 @@ namespace OpenSim.Region.Framework.Scenes
1686 updated = true; 1837 updated = true;
1687 } 1838 }
1688 1839
1689// m_log.DebugFormat( 1840 // m_log.DebugFormat(
1690// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1841 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1691// LocalVectorToTarget3D, agent_control_v3, Name); 1842 // LocalVectorToTarget3D, agent_control_v3, Name);
1692 1843
1693 agent_control_v3 += LocalVectorToTarget3D; 1844 agent_control_v3 += LocalVectorToTarget3D;
1694 } 1845 }
@@ -1809,7 +1960,7 @@ namespace OpenSim.Region.Framework.Scenes
1809 Velocity = Vector3.Zero; 1960 Velocity = Vector3.Zero;
1810 SendAvatarDataToAllAgents(); 1961 SendAvatarDataToAllAgents();
1811 1962
1812 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1963 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1813 } 1964 }
1814 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1965 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1815 m_requestedSitTargetUUID = UUID.Zero; 1966 m_requestedSitTargetUUID = UUID.Zero;
@@ -1846,25 +1997,22 @@ namespace OpenSim.Region.Framework.Scenes
1846 1997
1847 if (ParentID != 0) 1998 if (ParentID != 0)
1848 { 1999 {
1849 m_log.Debug("StandupCode Executed"); 2000 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1850 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
1851 if (part != null) 2001 if (part != null)
1852 { 2002 {
2003 part.TaskInventory.LockItemsForRead(true);
1853 TaskInventoryDictionary taskIDict = part.TaskInventory; 2004 TaskInventoryDictionary taskIDict = part.TaskInventory;
1854 if (taskIDict != null) 2005 if (taskIDict != null)
1855 { 2006 {
1856 lock (taskIDict) 2007 foreach (UUID taskID in taskIDict.Keys)
1857 { 2008 {
1858 foreach (UUID taskID in taskIDict.Keys) 2009 UnRegisterControlEventsToScript(LocalId, taskID);
1859 { 2010 taskIDict[taskID].PermsMask &= ~(
1860 UnRegisterControlEventsToScript(LocalId, taskID); 2011 2048 | //PERMISSION_CONTROL_CAMERA
1861 taskIDict[taskID].PermsMask &= ~( 2012 4); // PERMISSION_TAKE_CONTROLS
1862 2048 | //PERMISSION_CONTROL_CAMERA
1863 4); // PERMISSION_TAKE_CONTROLS
1864 }
1865 } 2013 }
1866
1867 } 2014 }
2015 part.TaskInventory.LockItemsForRead(false);
1868 // Reset sit target. 2016 // Reset sit target.
1869 if (part.GetAvatarOnSitTarget() == UUID) 2017 if (part.GetAvatarOnSitTarget() == UUID)
1870 part.SitTargetAvatar = UUID.Zero; 2018 part.SitTargetAvatar = UUID.Zero;
@@ -1873,20 +2021,58 @@ namespace OpenSim.Region.Framework.Scenes
1873 ParentPosition = part.GetWorldPosition(); 2021 ParentPosition = part.GetWorldPosition();
1874 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2022 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1875 } 2023 }
1876 2024 // part.GetWorldRotation() is the rotation of the object being sat on
1877 if (PhysicsActor == null) 2025 // Rotation is the sittiing Av's rotation
2026
2027 Quaternion partRot;
2028// if (part.LinkNum == 1)
2029// { // Root prim of linkset
2030// partRot = part.ParentGroup.RootPart.RotationOffset;
2031// }
2032// else
2033// { // single or child prim
2034
2035// }
2036 if (part == null) //CW: Part may be gone. llDie() for example.
1878 { 2037 {
1879 AddToPhysicalScene(false); 2038 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
2039 }
2040 else
2041 {
2042 partRot = part.GetWorldRotation();
1880 } 2043 }
1881 2044
1882 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2045 Quaternion partIRot = Quaternion.Inverse(partRot);
1883 ParentPosition = Vector3.Zero; 2046
2047 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
2048 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1884 2049
1885 ParentID = 0; 2050
2051 if (m_physicsActor == null)
2052 {
2053 AddToPhysicalScene(false);
2054 }
2055 //CW: If the part isn't null then we can set the current position
2056 if (part != null)
2057 {
2058 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
2059 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2060 part.IsOccupied = false;
2061 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2062 }
2063 else
2064 {
2065 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2066 AbsolutePosition = m_lastWorldPosition;
2067 }
2068
2069 m_parentPosition = Vector3.Zero;
2070 m_parentID = 0;
2071 m_linkedPrim = UUID.Zero;
2072 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1886 SendAvatarDataToAllAgents(); 2073 SendAvatarDataToAllAgents();
1887 m_requestedSitTargetID = 0; 2074 m_requestedSitTargetID = 0;
1888 } 2075 }
1889
1890 Animator.TrySetMovementAnimation("STAND"); 2076 Animator.TrySetMovementAnimation("STAND");
1891 } 2077 }
1892 2078
@@ -1917,13 +2103,9 @@ namespace OpenSim.Region.Framework.Scenes
1917 Vector3 avSitOffSet = part.SitTargetPosition; 2103 Vector3 avSitOffSet = part.SitTargetPosition;
1918 Quaternion avSitOrientation = part.SitTargetOrientation; 2104 Quaternion avSitOrientation = part.SitTargetOrientation;
1919 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2105 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1920 2106 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1921 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2107 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1922 bool SitTargetisSet = 2108 if (SitTargetisSet && !SitTargetOccupied)
1923 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1924 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1925
1926 if (SitTargetisSet && SitTargetUnOccupied)
1927 { 2109 {
1928 //switch the target to this prim 2110 //switch the target to this prim
1929 return part; 2111 return part;
@@ -1937,85 +2119,168 @@ namespace OpenSim.Region.Framework.Scenes
1937 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2119 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1938 { 2120 {
1939 bool autopilot = true; 2121 bool autopilot = true;
2122 Vector3 autopilotTarget = new Vector3();
2123 Quaternion sitOrientation = Quaternion.Identity;
1940 Vector3 pos = new Vector3(); 2124 Vector3 pos = new Vector3();
1941 Quaternion sitOrientation = pSitOrientation;
1942 Vector3 cameraEyeOffset = Vector3.Zero; 2125 Vector3 cameraEyeOffset = Vector3.Zero;
1943 Vector3 cameraAtOffset = Vector3.Zero; 2126 Vector3 cameraAtOffset = Vector3.Zero;
1944 bool forceMouselook = false; 2127 bool forceMouselook = false;
1945 2128
1946 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2129 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1947 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2130 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1948 if (part != null) 2131 if (part == null) return;
2132
2133 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2134 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2135
2136 // part is the prim to sit on
2137 // offset is the world-ref vector distance from that prim center to the click-spot
2138 // UUID is the UUID of the Avatar doing the clicking
2139
2140 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2141
2142 // Is a sit target available?
2143 Vector3 avSitOffSet = part.SitTargetPosition;
2144 Quaternion avSitOrientation = part.SitTargetOrientation;
2145
2146 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2147 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2148 Quaternion partRot;
2149// if (part.LinkNum == 1)
2150// { // Root prim of linkset
2151// partRot = part.ParentGroup.RootPart.RotationOffset;
2152// }
2153// else
2154// { // single or child prim
2155 partRot = part.GetWorldRotation();
2156// }
2157 Quaternion partIRot = Quaternion.Inverse(partRot);
2158//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2159 // Sit analysis rewritten by KF 091125
2160 if (SitTargetisSet) // scipted sit
1949 { 2161 {
1950 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2162 if (!part.IsOccupied)
1951 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2163 {
1952 2164//Console.WriteLine("Scripted, unoccupied");
1953 // Is a sit target available? 2165 part.SitTargetAvatar = UUID; // set that Av will be on it
1954 Vector3 avSitOffSet = part.SitTargetPosition; 2166 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1955 Quaternion avSitOrientation = part.SitTargetOrientation; 2167
1956 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2168 Quaternion nrot = avSitOrientation;
1957 2169 if (!part.IsRoot)
1958 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1959 bool SitTargetisSet =
1960 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1961 (
1962 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1963 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1964 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1965 )
1966 ));
1967
1968 if (SitTargetisSet && SitTargetUnOccupied)
1969 {
1970 part.SitTargetAvatar = UUID;
1971 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1972 sitOrientation = avSitOrientation;
1973 autopilot = false;
1974 }
1975 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1976
1977 pos = part.AbsolutePosition + offset;
1978 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1979 //{
1980 // offset = pos;
1981 //autopilot = false;
1982 //}
1983 if (PhysicsActor != null)
1984 {
1985 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1986 // We can remove the physicsActor until they stand up.
1987 m_sitAvatarHeight = PhysicsActor.Size.Z;
1988
1989 if (autopilot)
1990 { 2170 {
1991 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2171 nrot = part.RotationOffset * avSitOrientation;
1992 {
1993 autopilot = false;
1994
1995 RemoveFromPhysicalScene();
1996 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1997 }
1998 } 2172 }
1999 else 2173 sitOrientation = nrot; // Change rotatione to the scripted one
2174 OffsetRotation = nrot;
2175 autopilot = false; // Jump direct to scripted llSitPos()
2176 }
2177 else
2178 {
2179//Console.WriteLine("Scripted, occupied");
2180 return;
2181 }
2182 }
2183 else // Not Scripted
2184 {
2185 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
2186 {
2187 // large prim & offset, ignore if other Avs sitting
2188// offset.Z -= 0.05f;
2189 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2190 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2191
2192//Console.WriteLine(" offset ={0}", offset);
2193//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2194//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2195
2196 }
2197 else // small offset
2198 {
2199//Console.WriteLine("Small offset");
2200 if (!part.IsOccupied)
2201 {
2202 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2203 autopilotTarget = part.AbsolutePosition;
2204//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2205 }
2206 else return; // occupied small
2207 } // end large/small
2208 } // end Scripted/not
2209
2210 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2211
2212 cameraAtOffset = part.GetCameraAtOffset();
2213 cameraEyeOffset = part.GetCameraEyeOffset();
2214 forceMouselook = part.GetForceMouselook();
2215 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2216 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2217
2218 if (m_physicsActor != null)
2219 {
2220 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2221 // We can remove the physicsActor until they stand up.
2222 m_sitAvatarHeight = m_physicsActor.Size.Z;
2223 if (autopilot)
2224 { // its not a scripted sit
2225// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2226 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
2000 { 2227 {
2228 autopilot = false; // close enough
2229 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2230 Not using the part's position because returning the AV to the last known standing
2231 position is likely to be more friendly, isn't it? */
2001 RemoveFromPhysicalScene(); 2232 RemoveFromPhysicalScene();
2002 } 2233 Velocity = Vector3.Zero;
2234 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2235 } // else the autopilot will get us close
2236 }
2237 else
2238 { // its a scripted sit
2239 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2240 I *am* using the part's position this time because we have no real idea how far away
2241 the avatar is from the sit target. */
2242 RemoveFromPhysicalScene();
2243 Velocity = Vector3.Zero;
2003 } 2244 }
2004
2005 cameraAtOffset = part.GetCameraAtOffset();
2006 cameraEyeOffset = part.GetCameraEyeOffset();
2007 forceMouselook = part.GetForceMouselook();
2008 } 2245 }
2009 2246 else return; // physactor is null!
2010 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2247
2011 m_requestedSitTargetUUID = targetID; 2248 Vector3 offsetr; // = offset * partIRot;
2249 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2250 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2251 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2252 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2253 //offsetr = offset * partIRot;
2254//
2255 // }
2256 // else
2257 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2258 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2259 // (offset * partRot);
2260 // }
2261
2262//Console.WriteLine(" ");
2263//Console.WriteLine("link number ={0}", part.LinkNum);
2264//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2265//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2266//Console.WriteLine("Click offst ={0}", offset);
2267//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2268//Console.WriteLine("offsetr ={0}", offsetr);
2269//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2270//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2271
2272 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2273 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2274
2275 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
2012 // This calls HandleAgentSit twice, once from here, and the client calls 2276 // This calls HandleAgentSit twice, once from here, and the client calls
2013 // HandleAgentSit itself after it gets to the location 2277 // HandleAgentSit itself after it gets to the location
2014 // It doesn't get to the location until we've moved them there though 2278 // It doesn't get to the location until we've moved them there though
2015 // which happens in HandleAgentSit :P 2279 // which happens in HandleAgentSit :P
2016 m_autopilotMoving = autopilot; 2280 m_autopilotMoving = autopilot;
2017 m_autoPilotTarget = pos; 2281 m_autoPilotTarget = autopilotTarget;
2018 m_sitAtAutoTarget = autopilot; 2282 m_sitAtAutoTarget = autopilot;
2283 m_initialSitTarget = autopilotTarget;
2019 if (!autopilot) 2284 if (!autopilot)
2020 HandleAgentSit(remoteClient, UUID); 2285 HandleAgentSit(remoteClient, UUID);
2021 } 2286 }
@@ -2280,47 +2545,131 @@ namespace OpenSim.Region.Framework.Scenes
2280 { 2545 {
2281 if (part != null) 2546 if (part != null)
2282 { 2547 {
2548//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2283 if (part.GetAvatarOnSitTarget() == UUID) 2549 if (part.GetAvatarOnSitTarget() == UUID)
2284 { 2550 {
2551//Console.WriteLine("Scripted Sit");
2552 // Scripted sit
2285 Vector3 sitTargetPos = part.SitTargetPosition; 2553 Vector3 sitTargetPos = part.SitTargetPosition;
2286 Quaternion sitTargetOrient = part.SitTargetOrientation; 2554 Quaternion sitTargetOrient = part.SitTargetOrientation;
2287
2288 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2289 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2290
2291 //Quaternion result = (sitTargetOrient * vq) * nq;
2292
2293 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2555 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2294 m_pos += SIT_TARGET_ADJUSTMENT; 2556 m_pos += SIT_TARGET_ADJUSTMENT;
2295 Rotation = sitTargetOrient; 2557 if (!part.IsRoot)
2296 //Rotation = sitTargetOrient; 2558 {
2297 ParentPosition = part.AbsolutePosition; 2559 m_pos *= part.RotationOffset;
2298 2560 }
2299 //SendTerseUpdateToAllClients(); 2561 m_bodyRot = sitTargetOrient;
2562 m_parentPosition = part.AbsolutePosition;
2563 part.IsOccupied = true;
2564 part.ParentGroup.AddAvatar(agentID);
2300 } 2565 }
2301 else 2566 else
2302 { 2567 {
2303 m_pos -= part.AbsolutePosition; 2568 // if m_avUnscriptedSitPos is zero then Av sits above center
2304 ParentPosition = part.AbsolutePosition; 2569 // Else Av sits at m_avUnscriptedSitPos
2305 } 2570
2571 // Non-scripted sit by Kitto Flora 21Nov09
2572 // Calculate angle of line from prim to Av
2573 Quaternion partIRot;
2574// if (part.LinkNum == 1)
2575// { // Root prim of linkset
2576// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2577// }
2578// else
2579// { // single or child prim
2580 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2581// }
2582 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2583 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2584 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2585 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2586 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2587 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2588 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2589 // Av sits at world euler <0,0, z>, translated by part rotation
2590 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2591
2592 m_parentPosition = part.AbsolutePosition;
2593 part.IsOccupied = true;
2594 part.ParentGroup.AddAvatar(agentID);
2595 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2596 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2597 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2598 m_avUnscriptedSitPos; // adds click offset, if any
2599 //Set up raytrace to find top surface of prim
2600 Vector3 size = part.Scale;
2601 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2602 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2603 Vector3 down = new Vector3(0f, 0f, -1f);
2604//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2605 m_scene.PhysicsScene.RaycastWorld(
2606 start, // Vector3 position,
2607 down, // Vector3 direction,
2608 mag, // float length,
2609 SitAltitudeCallback); // retMethod
2610 } // end scripted/not
2306 } 2611 }
2307 else 2612 else // no Av
2308 { 2613 {
2309 return; 2614 return;
2310 } 2615 }
2311 } 2616 }
2312 ParentID = m_requestedSitTargetID; 2617 ParentID = m_requestedSitTargetID;
2313 2618
2619 //We want our offsets to reference the root prim, not the child we may have sat on
2620 if (!part.IsRoot)
2621 {
2622 m_parentID = part.ParentGroup.RootPart.LocalId;
2623 m_pos += part.OffsetPosition;
2624 }
2625 else
2626 {
2627 m_parentID = m_requestedSitTargetID;
2628 }
2629
2630 m_linkedPrim = part.UUID;
2631 if (part.GetAvatarOnSitTarget() != UUID)
2632 {
2633 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2634 }
2314 Velocity = Vector3.Zero; 2635 Velocity = Vector3.Zero;
2315 RemoveFromPhysicalScene(); 2636 RemoveFromPhysicalScene();
2316
2317 Animator.TrySetMovementAnimation(sitAnimation); 2637 Animator.TrySetMovementAnimation(sitAnimation);
2318 SendAvatarDataToAllAgents(); 2638 SendAvatarDataToAllAgents();
2319 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2320 // So we're also sending a terse update (which has avatar rotation)
2321 // [Update] We do now.
2322 //SendTerseUpdateToAllClients(); 2639 //SendTerseUpdateToAllClients();
2323 } 2640 }
2641
2642 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2643 {
2644 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2645 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2646 if(hitYN)
2647 {
2648 // m_pos = Av offset from prim center to make look like on center
2649 // m_parentPosition = Actual center pos of prim
2650 // collisionPoint = spot on prim where we want to sit
2651 // collisionPoint.Z = global sit surface height
2652 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2653 Quaternion partIRot;
2654// if (part.LinkNum == 1)
2655/// { // Root prim of linkset
2656// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2657// }
2658// else
2659// { // single or child prim
2660 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2661// }
2662 if (m_initialSitTarget != null)
2663 {
2664 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2665 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2666 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2667 m_pos += offset;
2668 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2669 }
2670
2671 }
2672 } // End SitAltitudeCallback KF.
2324 2673
2325 /// <summary> 2674 /// <summary>
2326 /// Event handler for the 'Always run' setting on the client 2675 /// Event handler for the 'Always run' setting on the client
@@ -2428,6 +2777,9 @@ namespace OpenSim.Region.Framework.Scenes
2428 2777
2429 CheckForSignificantMovement(); // sends update to the modules. 2778 CheckForSignificantMovement(); // sends update to the modules.
2430 } 2779 }
2780
2781 //Sending prim updates AFTER the avatar terse updates are sent
2782 SendPrimUpdates();
2431 } 2783 }
2432 2784
2433 #endregion 2785 #endregion
@@ -3201,6 +3553,7 @@ namespace OpenSim.Region.Framework.Scenes
3201 m_callbackURI = cAgent.CallbackURI; 3553 m_callbackURI = cAgent.CallbackURI;
3202 3554
3203 m_pos = cAgent.Position; 3555 m_pos = cAgent.Position;
3556
3204 m_velocity = cAgent.Velocity; 3557 m_velocity = cAgent.Velocity;
3205 CameraPosition = cAgent.Center; 3558 CameraPosition = cAgent.Center;
3206 CameraAtAxis = cAgent.AtAxis; 3559 CameraAtAxis = cAgent.AtAxis;
@@ -3350,14 +3703,26 @@ namespace OpenSim.Region.Framework.Scenes
3350 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3703 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
3351 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( 3704 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
3352 // as of this comment the interval is set in AddToPhysicalScene 3705 // as of this comment the interval is set in AddToPhysicalScene
3353 if (Animator != null) 3706 if (Animator!=null)
3354 Animator.UpdateMovementAnimations(); 3707 {
3708 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3709 { // else its will lock out other animation changes, like ground sit.
3710 Animator.UpdateMovementAnimations();
3711 m_updateCount--;
3712 }
3713 }
3355 3714
3356 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3715 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3357 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3716 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3358 3717
3359 CollisionPlane = Vector4.UnitW; 3718 CollisionPlane = Vector4.UnitW;
3360 3719
3720 if (m_lastColCount != coldata.Count)
3721 {
3722 m_updateCount = UPDATE_COUNT;
3723 m_lastColCount = coldata.Count;
3724 }
3725
3361 if (coldata.Count != 0 && Animator != null) 3726 if (coldata.Count != 0 && Animator != null)
3362 { 3727 {
3363 switch (Animator.CurrentMovementAnimation) 3728 switch (Animator.CurrentMovementAnimation)
@@ -3387,6 +3752,148 @@ namespace OpenSim.Region.Framework.Scenes
3387 } 3752 }
3388 } 3753 }
3389 3754
3755 List<uint> thisHitColliders = new List<uint>();
3756 List<uint> endedColliders = new List<uint>();
3757 List<uint> startedColliders = new List<uint>();
3758
3759 foreach (uint localid in coldata.Keys)
3760 {
3761 thisHitColliders.Add(localid);
3762 if (!m_lastColliders.Contains(localid))
3763 {
3764 startedColliders.Add(localid);
3765 }
3766 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3767 }
3768
3769 // calculate things that ended colliding
3770 foreach (uint localID in m_lastColliders)
3771 {
3772 if (!thisHitColliders.Contains(localID))
3773 {
3774 endedColliders.Add(localID);
3775 }
3776 }
3777 //add the items that started colliding this time to the last colliders list.
3778 foreach (uint localID in startedColliders)
3779 {
3780 m_lastColliders.Add(localID);
3781 }
3782 // remove things that ended colliding from the last colliders list
3783 foreach (uint localID in endedColliders)
3784 {
3785 m_lastColliders.Remove(localID);
3786 }
3787
3788 // do event notification
3789 if (startedColliders.Count > 0)
3790 {
3791 ColliderArgs StartCollidingMessage = new ColliderArgs();
3792 List<DetectedObject> colliding = new List<DetectedObject>();
3793 foreach (uint localId in startedColliders)
3794 {
3795 if (localId == 0)
3796 continue;
3797
3798 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3799 string data = "";
3800 if (obj != null)
3801 {
3802 DetectedObject detobj = new DetectedObject();
3803 detobj.keyUUID = obj.UUID;
3804 detobj.nameStr = obj.Name;
3805 detobj.ownerUUID = obj.OwnerID;
3806 detobj.posVector = obj.AbsolutePosition;
3807 detobj.rotQuat = obj.GetWorldRotation();
3808 detobj.velVector = obj.Velocity;
3809 detobj.colliderType = 0;
3810 detobj.groupUUID = obj.GroupID;
3811 colliding.Add(detobj);
3812 }
3813 }
3814
3815 if (colliding.Count > 0)
3816 {
3817 StartCollidingMessage.Colliders = colliding;
3818
3819 foreach (SceneObjectGroup att in GetAttachments())
3820 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3821 }
3822 }
3823
3824 if (endedColliders.Count > 0)
3825 {
3826 ColliderArgs EndCollidingMessage = new ColliderArgs();
3827 List<DetectedObject> colliding = new List<DetectedObject>();
3828 foreach (uint localId in endedColliders)
3829 {
3830 if (localId == 0)
3831 continue;
3832
3833 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3834 string data = "";
3835 if (obj != null)
3836 {
3837 DetectedObject detobj = new DetectedObject();
3838 detobj.keyUUID = obj.UUID;
3839 detobj.nameStr = obj.Name;
3840 detobj.ownerUUID = obj.OwnerID;
3841 detobj.posVector = obj.AbsolutePosition;
3842 detobj.rotQuat = obj.GetWorldRotation();
3843 detobj.velVector = obj.Velocity;
3844 detobj.colliderType = 0;
3845 detobj.groupUUID = obj.GroupID;
3846 colliding.Add(detobj);
3847 }
3848 }
3849
3850 if (colliding.Count > 0)
3851 {
3852 EndCollidingMessage.Colliders = colliding;
3853
3854 foreach (SceneObjectGroup att in GetAttachments())
3855 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3856 }
3857 }
3858
3859 if (thisHitColliders.Count > 0)
3860 {
3861 ColliderArgs CollidingMessage = new ColliderArgs();
3862 List<DetectedObject> colliding = new List<DetectedObject>();
3863 foreach (uint localId in thisHitColliders)
3864 {
3865 if (localId == 0)
3866 continue;
3867
3868 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3869 string data = "";
3870 if (obj != null)
3871 {
3872 DetectedObject detobj = new DetectedObject();
3873 detobj.keyUUID = obj.UUID;
3874 detobj.nameStr = obj.Name;
3875 detobj.ownerUUID = obj.OwnerID;
3876 detobj.posVector = obj.AbsolutePosition;
3877 detobj.rotQuat = obj.GetWorldRotation();
3878 detobj.velVector = obj.Velocity;
3879 detobj.colliderType = 0;
3880 detobj.groupUUID = obj.GroupID;
3881 colliding.Add(detobj);
3882 }
3883 }
3884
3885 if (colliding.Count > 0)
3886 {
3887 CollidingMessage.Colliders = colliding;
3888
3889 lock (m_attachments)
3890 {
3891 foreach (SceneObjectGroup att in m_attachments)
3892 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3893 }
3894 }
3895 }
3896
3390 if (Invulnerable) 3897 if (Invulnerable)
3391 return; 3898 return;
3392 3899
@@ -3460,6 +3967,10 @@ namespace OpenSim.Region.Framework.Scenes
3460 { 3967 {
3461 lock (m_attachments) 3968 lock (m_attachments)
3462 { 3969 {
3970 // This may be true when the attachment comes back
3971 // from serialization after login. Clear it.
3972 gobj.IsDeleted = false;
3973
3463 m_attachments.Add(gobj); 3974 m_attachments.Add(gobj);
3464 } 3975 }
3465 } 3976 }
@@ -3823,5 +4334,39 @@ namespace OpenSim.Region.Framework.Scenes
3823 m_reprioritization_called = false; 4334 m_reprioritization_called = false;
3824 } 4335 }
3825 } 4336 }
4337
4338 private Vector3 Quat2Euler(Quaternion rot){
4339 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4340 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4341 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4342 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4343 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4344 return(new Vector3(x,y,z));
4345 }
4346
4347 private void CheckLandingPoint(ref Vector3 pos)
4348 {
4349 // Never constrain lures
4350 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4351 return;
4352
4353 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4354 return;
4355
4356 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4357
4358 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4359 land.LandData.UserLocation != Vector3.Zero &&
4360 land.LandData.OwnerID != m_uuid &&
4361 (!m_scene.Permissions.IsGod(m_uuid)) &&
4362 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4363 {
4364 float curr = Vector3.Distance(AbsolutePosition, pos);
4365 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4366 pos = land.LandData.UserLocation;
4367 else
4368 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4369 }
4370 }
3826 } 4371 }
3827} 4372}