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 1c7102b..975d855 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;
@@ -242,7 +266,9 @@ namespace OpenSim.Region.Framework.Scenes
242 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 266 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
243 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 267 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
244 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 268 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
245 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 269 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
270 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
271 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
246 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 272 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
247 } 273 }
248 274
@@ -478,9 +504,11 @@ namespace OpenSim.Region.Framework.Scenes
478 { 504 {
479 get 505 get
480 { 506 {
481 if (PhysicsActor != null) 507 PhysicsActor actor = m_physicsActor;
482 { 508// if (actor != null)
483 m_pos = PhysicsActor.Position; 509 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
510 {
511 m_pos = actor.Position;
484 512
485// m_log.DebugFormat( 513// m_log.DebugFormat(
486// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!", 514// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!",
@@ -506,7 +534,7 @@ namespace OpenSim.Region.Framework.Scenes
506 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 534 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
507 if (part != null) 535 if (part != null)
508 { 536 {
509 return ParentPosition + (m_pos * part.GetWorldRotation()); 537 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
510 } 538 }
511 else 539 else
512 { 540 {
@@ -532,8 +560,10 @@ namespace OpenSim.Region.Framework.Scenes
532 } 560 }
533 } 561 }
534 562
535 m_pos = value; 563// Changed this to update unconditionally to make npose work
536 ParentPosition = Vector3.Zero; 564// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
565 m_pos = value;
566 m_parentPosition = Vector3.Zero;
537 567
538// m_log.DebugFormat( 568// m_log.DebugFormat(
539// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 569// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
@@ -591,15 +621,39 @@ namespace OpenSim.Region.Framework.Scenes
591 } 621 }
592 } 622 }
593 623
624 public Quaternion OffsetRotation
625 {
626 get { return m_offsetRotation; }
627 set { m_offsetRotation = value; }
628 }
594 private Quaternion m_bodyRot = Quaternion.Identity; 629 private Quaternion m_bodyRot = Quaternion.Identity;
595 630
596 public Quaternion Rotation 631 public Quaternion Rotation
597 { 632 {
598 get { return m_bodyRot; } 633 get {
599 set 634 if (m_parentID != 0)
600 { 635 {
636 if (m_offsetRotation != null)
637 {
638 return m_offsetRotation;
639 }
640 else
641 {
642 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
643 }
644
645 }
646 else
647 {
648 return m_bodyRot;
649 }
650 }
651 set {
601 m_bodyRot = value; 652 m_bodyRot = value;
602// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 653 if (m_parentID != 0)
654 {
655 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
656 }
603 } 657 }
604 } 658 }
605 659
@@ -619,11 +673,21 @@ namespace OpenSim.Region.Framework.Scenes
619 673
620 private uint m_parentID; 674 private uint m_parentID;
621 675
676
677 private UUID m_linkedPrim;
678
622 public uint ParentID 679 public uint ParentID
623 { 680 {
624 get { return m_parentID; } 681 get { return m_parentID; }
625 set { m_parentID = value; } 682 set { m_parentID = value; }
626 } 683 }
684
685 public UUID LinkedPrim
686 {
687 get { return m_linkedPrim; }
688 set { m_linkedPrim = value; }
689 }
690
627 public float Health 691 public float Health
628 { 692 {
629 get { return m_health; } 693 get { return m_health; }
@@ -755,6 +819,7 @@ namespace OpenSim.Region.Framework.Scenes
755 m_localId = m_scene.AllocateLocalId(); 819 m_localId = m_scene.AllocateLocalId();
756 820
757 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 821 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
822 m_userFlags = account.UserFlags;
758 823
759 if (account != null) 824 if (account != null)
760 UserLevel = account.UserLevel; 825 UserLevel = account.UserLevel;
@@ -773,10 +838,7 @@ namespace OpenSim.Region.Framework.Scenes
773 m_reprioritization_timer.AutoReset = false; 838 m_reprioritization_timer.AutoReset = false;
774 839
775 AdjustKnownSeeds(); 840 AdjustKnownSeeds();
776
777 // TODO: I think, this won't send anything, as we are still a child here...
778 Animator.TrySetMovementAnimation("STAND"); 841 Animator.TrySetMovementAnimation("STAND");
779
780 // we created a new ScenePresence (a new child agent) in a fresh region. 842 // we created a new ScenePresence (a new child agent) in a fresh region.
781 // Request info about all the (root) agents in this region 843 // Request info about all the (root) agents in this region
782 // Note: This won't send data *to* other clients in that region (children don't send) 844 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -817,25 +879,47 @@ namespace OpenSim.Region.Framework.Scenes
817 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 879 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
818 Dir_Vectors[4] = Vector3.UnitZ; //UP 880 Dir_Vectors[4] = Vector3.UnitZ; //UP
819 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 881 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
820 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 882 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
821 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 883 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
822 Dir_Vectors[7] = -Vector3.UnitX; //BACK 884 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
885 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
886 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
823 } 887 }
824 888
825 private Vector3[] GetWalkDirectionVectors() 889 private Vector3[] GetWalkDirectionVectors()
826 { 890 {
827 Vector3[] vector = new Vector3[9]; 891 Vector3[] vector = new Vector3[11];
828 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z); //FORWARD 892 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
829 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK 893 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
830 vector[2] = Vector3.UnitY; //LEFT 894 vector[2] = Vector3.UnitY; //LEFT
831 vector[3] = -Vector3.UnitY; //RIGHT 895 vector[3] = -Vector3.UnitY; //RIGHT
832 vector[4] = new Vector3(CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 896 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
833 vector[5] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 897 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
834 vector[8] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 898 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
835 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z) * 2); //FORWARD Nudge 899 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
836 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK Nudge 900 vector[8] = Vector3.UnitY; //LEFT_NUDGE
901 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
902 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
837 return vector; 903 return vector;
838 } 904 }
905
906 private bool[] GetDirectionIsNudge()
907 {
908 bool[] isNudge = new bool[11];
909 isNudge[0] = false; //FORWARD
910 isNudge[1] = false; //BACK
911 isNudge[2] = false; //LEFT
912 isNudge[3] = false; //RIGHT
913 isNudge[4] = false; //UP
914 isNudge[5] = false; //DOWN
915 isNudge[6] = true; //FORWARD_NUDGE
916 isNudge[7] = true; //BACK_NUDGE
917 isNudge[8] = true; //LEFT_NUDGE
918 isNudge[9] = true; //RIGHT_NUDGE
919 isNudge[10] = true; //DOWN_Nudge
920 return isNudge;
921 }
922
839 923
840 #endregion 924 #endregion
841 925
@@ -851,6 +935,8 @@ namespace OpenSim.Region.Framework.Scenes
851 /// </summary> 935 /// </summary>
852 public void SendPrimUpdates() 936 public void SendPrimUpdates()
853 { 937 {
938 m_sceneViewer.SendPrimUpdates();
939
854 SceneViewer.SendPrimUpdates(); 940 SceneViewer.SendPrimUpdates();
855 } 941 }
856 942
@@ -896,6 +982,62 @@ namespace OpenSim.Region.Framework.Scenes
896 pos.Y = crossedBorder.BorderLine.Z - 1; 982 pos.Y = crossedBorder.BorderLine.Z - 1;
897 } 983 }
898 984
985 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
986 if (land != null)
987 {
988 // If we come in via login, landmark or map, we want to
989 // honor landing points. If we come in via Lure, we want
990 // to ignore them.
991 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
992 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
993 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
994 {
995 // Don't restrict gods, estate managers, or land owners to
996 // the TP point. This behaviour mimics agni.
997 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
998 land.LandData.UserLocation != Vector3.Zero &&
999 GodLevel < 200 &&
1000 ((land.LandData.OwnerID != m_uuid &&
1001 (!m_scene.Permissions.IsGod(m_uuid)) &&
1002 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
1003 {
1004 pos = land.LandData.UserLocation;
1005 }
1006 }
1007
1008 land.SendLandUpdateToClient(ControllingClient);
1009 }
1010
1011 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
1012 {
1013 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
1014
1015 if (pos.X < 0)
1016 {
1017 emergencyPos.X = (int)Constants.RegionSize + pos.X;
1018 if (!(pos.Y < 0))
1019 emergencyPos.Y = pos.Y;
1020 if (!(pos.Z < 0))
1021 emergencyPos.Z = pos.Z;
1022 }
1023 if (pos.Y < 0)
1024 {
1025 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
1026 if (!(pos.X < 0))
1027 emergencyPos.X = pos.X;
1028 if (!(pos.Z < 0))
1029 emergencyPos.Z = pos.Z;
1030 }
1031 if (pos.Z < 0)
1032 {
1033 emergencyPos.Z = 128;
1034 if (!(pos.Y < 0))
1035 emergencyPos.Y = pos.Y;
1036 if (!(pos.X < 0))
1037 emergencyPos.X = pos.X;
1038 }
1039 }
1040
899 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1041 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
900 { 1042 {
901 m_log.WarnFormat( 1043 m_log.WarnFormat(
@@ -1028,16 +1170,21 @@ namespace OpenSim.Region.Framework.Scenes
1028 /// <summary> 1170 /// <summary>
1029 /// Removes physics plugin scene representation of this agent if it exists. 1171 /// Removes physics plugin scene representation of this agent if it exists.
1030 /// </summary> 1172 /// </summary>
1031 private void RemoveFromPhysicalScene() 1173 public void RemoveFromPhysicalScene()
1032 { 1174 {
1033 if (PhysicsActor != null) 1175 if (PhysicsActor != null)
1034 { 1176 {
1035 PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1177 try
1036 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1178 {
1037 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1179 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1038 PhysicsActor.UnSubscribeEvents(); 1180 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1039 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1181 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1040 PhysicsActor = null; 1182 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1183 m_physicsActor.UnSubscribeEvents();
1184 PhysicsActor = null;
1185 }
1186 catch
1187 { }
1041 } 1188 }
1042 } 1189 }
1043 1190
@@ -1053,10 +1200,12 @@ namespace OpenSim.Region.Framework.Scenes
1053 1200
1054 RemoveFromPhysicalScene(); 1201 RemoveFromPhysicalScene();
1055 Velocity = Vector3.Zero; 1202 Velocity = Vector3.Zero;
1203 CheckLandingPoint(ref pos);
1056 AbsolutePosition = pos; 1204 AbsolutePosition = pos;
1057 AddToPhysicalScene(isFlying); 1205 AddToPhysicalScene(isFlying);
1058 1206
1059 SendTerseUpdateToAllClients(); 1207 SendTerseUpdateToAllClients();
1208
1060 } 1209 }
1061 1210
1062 public void TeleportWithMomentum(Vector3 pos) 1211 public void TeleportWithMomentum(Vector3 pos)
@@ -1066,6 +1215,7 @@ namespace OpenSim.Region.Framework.Scenes
1066 isFlying = PhysicsActor.Flying; 1215 isFlying = PhysicsActor.Flying;
1067 1216
1068 RemoveFromPhysicalScene(); 1217 RemoveFromPhysicalScene();
1218 CheckLandingPoint(ref pos);
1069 AbsolutePosition = pos; 1219 AbsolutePosition = pos;
1070 AddToPhysicalScene(isFlying); 1220 AddToPhysicalScene(isFlying);
1071 1221
@@ -1273,11 +1423,12 @@ namespace OpenSim.Region.Framework.Scenes
1273 /// <summary> 1423 /// <summary>
1274 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1424 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1275 /// </summary> 1425 /// </summary>
1426 /// <summary>
1427 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1428 /// </summary>
1276 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1429 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1277 { 1430 {
1278// m_log.DebugFormat( 1431 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1279// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1280// Scene.RegionInfo.RegionName, remoteClient.Name);
1281 1432
1282 //if (IsChildAgent) 1433 //if (IsChildAgent)
1283 //{ 1434 //{
@@ -1473,7 +1624,7 @@ namespace OpenSim.Region.Framework.Scenes
1473 1624
1474 if ((MovementFlag & (byte)(uint)DCF) == 0) 1625 if ((MovementFlag & (byte)(uint)DCF) == 0)
1475 { 1626 {
1476 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1627 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1477 { 1628 {
1478 MovementFlag |= (byte)nudgehack; 1629 MovementFlag |= (byte)nudgehack;
1479 } 1630 }
@@ -1485,13 +1636,13 @@ namespace OpenSim.Region.Framework.Scenes
1485 } 1636 }
1486 else 1637 else
1487 { 1638 {
1488 if ((MovementFlag & (byte)(uint)DCF) != 0 || 1639 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1489 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1640 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1490 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1641 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1491 ) // This or is for Nudge forward 1642 ) // This or is for Nudge forward
1492 { 1643 {
1493// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1644 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1494 MovementFlag -= ((byte)(uint)DCF); 1645 m_movementflag -= ((byte)(uint)DCF);
1495 update_movementflag = true; 1646 update_movementflag = true;
1496 1647
1497 /* 1648 /*
@@ -1552,21 +1703,21 @@ namespace OpenSim.Region.Framework.Scenes
1552 // which occurs later in the main scene loop 1703 // which occurs later in the main scene loop
1553 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1704 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1554 { 1705 {
1555// m_log.DebugFormat( 1706 // m_log.DebugFormat(
1556// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1707 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1557// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1708 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1558 1709
1559 AddNewMovement(agent_control_v3); 1710 AddNewMovement(agent_control_v3);
1560 } 1711 }
1561// else 1712 // else
1562// { 1713 // {
1563// if (!update_movementflag) 1714 // if (!update_movementflag)
1564// { 1715 // {
1565// m_log.DebugFormat( 1716 // m_log.DebugFormat(
1566// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1717 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1567// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1718 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1568// } 1719 // }
1569// } 1720 // }
1570 1721
1571 if (update_movementflag && ParentID == 0) 1722 if (update_movementflag && ParentID == 0)
1572 Animator.UpdateMovementAnimations(); 1723 Animator.UpdateMovementAnimations();
@@ -1588,20 +1739,20 @@ namespace OpenSim.Region.Framework.Scenes
1588 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1739 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1589 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1740 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1590 { 1741 {
1591// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1742 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1592 1743
1593 bool updated = false; 1744 bool updated = false;
1594 1745
1595// m_log.DebugFormat( 1746 // m_log.DebugFormat(
1596// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1747 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1597// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1748 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1598 1749
1599 if (!m_autopilotMoving) 1750 if (!m_autopilotMoving)
1600 { 1751 {
1601 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1752 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1602// m_log.DebugFormat( 1753 // m_log.DebugFormat(
1603// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1754 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1604// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1755 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1605 1756
1606 // Check the error term of the current position in relation to the target position 1757 // Check the error term of the current position in relation to the target position
1607 if (distanceToTarget <= 1) 1758 if (distanceToTarget <= 1)
@@ -1624,7 +1775,7 @@ namespace OpenSim.Region.Framework.Scenes
1624 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1775 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1625 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1776 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1626 // Ignore z component of vector 1777 // Ignore z component of vector
1627// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1778 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1628 LocalVectorToTarget3D.Normalize(); 1779 LocalVectorToTarget3D.Normalize();
1629 1780
1630 // update avatar movement flags. the avatar coordinate system is as follows: 1781 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1690,9 +1841,9 @@ namespace OpenSim.Region.Framework.Scenes
1690 updated = true; 1841 updated = true;
1691 } 1842 }
1692 1843
1693// m_log.DebugFormat( 1844 // m_log.DebugFormat(
1694// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1845 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1695// LocalVectorToTarget3D, agent_control_v3, Name); 1846 // LocalVectorToTarget3D, agent_control_v3, Name);
1696 1847
1697 agent_control_v3 += LocalVectorToTarget3D; 1848 agent_control_v3 += LocalVectorToTarget3D;
1698 } 1849 }
@@ -1813,7 +1964,7 @@ namespace OpenSim.Region.Framework.Scenes
1813 Velocity = Vector3.Zero; 1964 Velocity = Vector3.Zero;
1814 SendAvatarDataToAllAgents(); 1965 SendAvatarDataToAllAgents();
1815 1966
1816 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1967 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1817 } 1968 }
1818 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1969 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1819 m_requestedSitTargetUUID = UUID.Zero; 1970 m_requestedSitTargetUUID = UUID.Zero;
@@ -1850,25 +2001,22 @@ namespace OpenSim.Region.Framework.Scenes
1850 2001
1851 if (ParentID != 0) 2002 if (ParentID != 0)
1852 { 2003 {
1853 m_log.Debug("StandupCode Executed"); 2004 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1854 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
1855 if (part != null) 2005 if (part != null)
1856 { 2006 {
2007 part.TaskInventory.LockItemsForRead(true);
1857 TaskInventoryDictionary taskIDict = part.TaskInventory; 2008 TaskInventoryDictionary taskIDict = part.TaskInventory;
1858 if (taskIDict != null) 2009 if (taskIDict != null)
1859 { 2010 {
1860 lock (taskIDict) 2011 foreach (UUID taskID in taskIDict.Keys)
1861 { 2012 {
1862 foreach (UUID taskID in taskIDict.Keys) 2013 UnRegisterControlEventsToScript(LocalId, taskID);
1863 { 2014 taskIDict[taskID].PermsMask &= ~(
1864 UnRegisterControlEventsToScript(LocalId, taskID); 2015 2048 | //PERMISSION_CONTROL_CAMERA
1865 taskIDict[taskID].PermsMask &= ~( 2016 4); // PERMISSION_TAKE_CONTROLS
1866 2048 | //PERMISSION_CONTROL_CAMERA
1867 4); // PERMISSION_TAKE_CONTROLS
1868 }
1869 } 2017 }
1870
1871 } 2018 }
2019 part.TaskInventory.LockItemsForRead(false);
1872 // Reset sit target. 2020 // Reset sit target.
1873 if (part.GetAvatarOnSitTarget() == UUID) 2021 if (part.GetAvatarOnSitTarget() == UUID)
1874 part.SitTargetAvatar = UUID.Zero; 2022 part.SitTargetAvatar = UUID.Zero;
@@ -1877,20 +2025,58 @@ namespace OpenSim.Region.Framework.Scenes
1877 ParentPosition = part.GetWorldPosition(); 2025 ParentPosition = part.GetWorldPosition();
1878 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2026 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1879 } 2027 }
1880 2028 // part.GetWorldRotation() is the rotation of the object being sat on
1881 if (PhysicsActor == null) 2029 // Rotation is the sittiing Av's rotation
2030
2031 Quaternion partRot;
2032// if (part.LinkNum == 1)
2033// { // Root prim of linkset
2034// partRot = part.ParentGroup.RootPart.RotationOffset;
2035// }
2036// else
2037// { // single or child prim
2038
2039// }
2040 if (part == null) //CW: Part may be gone. llDie() for example.
1882 { 2041 {
1883 AddToPhysicalScene(false); 2042 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
2043 }
2044 else
2045 {
2046 partRot = part.GetWorldRotation();
1884 } 2047 }
1885 2048
1886 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2049 Quaternion partIRot = Quaternion.Inverse(partRot);
1887 ParentPosition = Vector3.Zero; 2050
2051 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
2052 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1888 2053
1889 ParentID = 0; 2054
2055 if (m_physicsActor == null)
2056 {
2057 AddToPhysicalScene(false);
2058 }
2059 //CW: If the part isn't null then we can set the current position
2060 if (part != null)
2061 {
2062 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
2063 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2064 part.IsOccupied = false;
2065 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2066 }
2067 else
2068 {
2069 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2070 AbsolutePosition = m_lastWorldPosition;
2071 }
2072
2073 m_parentPosition = Vector3.Zero;
2074 m_parentID = 0;
2075 m_linkedPrim = UUID.Zero;
2076 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1890 SendAvatarDataToAllAgents(); 2077 SendAvatarDataToAllAgents();
1891 m_requestedSitTargetID = 0; 2078 m_requestedSitTargetID = 0;
1892 } 2079 }
1893
1894 Animator.TrySetMovementAnimation("STAND"); 2080 Animator.TrySetMovementAnimation("STAND");
1895 } 2081 }
1896 2082
@@ -1921,13 +2107,9 @@ namespace OpenSim.Region.Framework.Scenes
1921 Vector3 avSitOffSet = part.SitTargetPosition; 2107 Vector3 avSitOffSet = part.SitTargetPosition;
1922 Quaternion avSitOrientation = part.SitTargetOrientation; 2108 Quaternion avSitOrientation = part.SitTargetOrientation;
1923 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2109 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1924 2110 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1925 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2111 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1926 bool SitTargetisSet = 2112 if (SitTargetisSet && !SitTargetOccupied)
1927 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1928 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1929
1930 if (SitTargetisSet && SitTargetUnOccupied)
1931 { 2113 {
1932 //switch the target to this prim 2114 //switch the target to this prim
1933 return part; 2115 return part;
@@ -1941,85 +2123,168 @@ namespace OpenSim.Region.Framework.Scenes
1941 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2123 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1942 { 2124 {
1943 bool autopilot = true; 2125 bool autopilot = true;
2126 Vector3 autopilotTarget = new Vector3();
2127 Quaternion sitOrientation = Quaternion.Identity;
1944 Vector3 pos = new Vector3(); 2128 Vector3 pos = new Vector3();
1945 Quaternion sitOrientation = pSitOrientation;
1946 Vector3 cameraEyeOffset = Vector3.Zero; 2129 Vector3 cameraEyeOffset = Vector3.Zero;
1947 Vector3 cameraAtOffset = Vector3.Zero; 2130 Vector3 cameraAtOffset = Vector3.Zero;
1948 bool forceMouselook = false; 2131 bool forceMouselook = false;
1949 2132
1950 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2133 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1951 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2134 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1952 if (part != null) 2135 if (part == null) return;
2136
2137 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2138 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2139
2140 // part is the prim to sit on
2141 // offset is the world-ref vector distance from that prim center to the click-spot
2142 // UUID is the UUID of the Avatar doing the clicking
2143
2144 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2145
2146 // Is a sit target available?
2147 Vector3 avSitOffSet = part.SitTargetPosition;
2148 Quaternion avSitOrientation = part.SitTargetOrientation;
2149
2150 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2151 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2152 Quaternion partRot;
2153// if (part.LinkNum == 1)
2154// { // Root prim of linkset
2155// partRot = part.ParentGroup.RootPart.RotationOffset;
2156// }
2157// else
2158// { // single or child prim
2159 partRot = part.GetWorldRotation();
2160// }
2161 Quaternion partIRot = Quaternion.Inverse(partRot);
2162//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2163 // Sit analysis rewritten by KF 091125
2164 if (SitTargetisSet) // scipted sit
1953 { 2165 {
1954 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2166 if (!part.IsOccupied)
1955 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2167 {
1956 2168//Console.WriteLine("Scripted, unoccupied");
1957 // Is a sit target available? 2169 part.SitTargetAvatar = UUID; // set that Av will be on it
1958 Vector3 avSitOffSet = part.SitTargetPosition; 2170 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1959 Quaternion avSitOrientation = part.SitTargetOrientation; 2171
1960 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2172 Quaternion nrot = avSitOrientation;
1961 2173 if (!part.IsRoot)
1962 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1963 bool SitTargetisSet =
1964 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1965 (
1966 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1967 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1968 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1969 )
1970 ));
1971
1972 if (SitTargetisSet && SitTargetUnOccupied)
1973 {
1974 part.SitTargetAvatar = UUID;
1975 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1976 sitOrientation = avSitOrientation;
1977 autopilot = false;
1978 }
1979 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1980
1981 pos = part.AbsolutePosition + offset;
1982 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1983 //{
1984 // offset = pos;
1985 //autopilot = false;
1986 //}
1987 if (PhysicsActor != null)
1988 {
1989 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1990 // We can remove the physicsActor until they stand up.
1991 m_sitAvatarHeight = PhysicsActor.Size.Z;
1992
1993 if (autopilot)
1994 { 2174 {
1995 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2175 nrot = part.RotationOffset * avSitOrientation;
1996 {
1997 autopilot = false;
1998
1999 RemoveFromPhysicalScene();
2000 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2001 }
2002 } 2176 }
2003 else 2177 sitOrientation = nrot; // Change rotatione to the scripted one
2178 OffsetRotation = nrot;
2179 autopilot = false; // Jump direct to scripted llSitPos()
2180 }
2181 else
2182 {
2183//Console.WriteLine("Scripted, occupied");
2184 return;
2185 }
2186 }
2187 else // Not Scripted
2188 {
2189 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
2190 {
2191 // large prim & offset, ignore if other Avs sitting
2192// offset.Z -= 0.05f;
2193 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2194 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2195
2196//Console.WriteLine(" offset ={0}", offset);
2197//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2198//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2199
2200 }
2201 else // small offset
2202 {
2203//Console.WriteLine("Small offset");
2204 if (!part.IsOccupied)
2205 {
2206 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2207 autopilotTarget = part.AbsolutePosition;
2208//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2209 }
2210 else return; // occupied small
2211 } // end large/small
2212 } // end Scripted/not
2213
2214 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2215
2216 cameraAtOffset = part.GetCameraAtOffset();
2217 cameraEyeOffset = part.GetCameraEyeOffset();
2218 forceMouselook = part.GetForceMouselook();
2219 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2220 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2221
2222 if (m_physicsActor != null)
2223 {
2224 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2225 // We can remove the physicsActor until they stand up.
2226 m_sitAvatarHeight = m_physicsActor.Size.Z;
2227 if (autopilot)
2228 { // its not a scripted sit
2229// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2230 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
2004 { 2231 {
2232 autopilot = false; // close enough
2233 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2234 Not using the part's position because returning the AV to the last known standing
2235 position is likely to be more friendly, isn't it? */
2005 RemoveFromPhysicalScene(); 2236 RemoveFromPhysicalScene();
2006 } 2237 Velocity = Vector3.Zero;
2238 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2239 } // else the autopilot will get us close
2240 }
2241 else
2242 { // its a scripted sit
2243 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2244 I *am* using the part's position this time because we have no real idea how far away
2245 the avatar is from the sit target. */
2246 RemoveFromPhysicalScene();
2247 Velocity = Vector3.Zero;
2007 } 2248 }
2008
2009 cameraAtOffset = part.GetCameraAtOffset();
2010 cameraEyeOffset = part.GetCameraEyeOffset();
2011 forceMouselook = part.GetForceMouselook();
2012 } 2249 }
2013 2250 else return; // physactor is null!
2014 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2251
2015 m_requestedSitTargetUUID = targetID; 2252 Vector3 offsetr; // = offset * partIRot;
2253 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2254 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2255 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2256 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2257 //offsetr = offset * partIRot;
2258//
2259 // }
2260 // else
2261 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2262 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2263 // (offset * partRot);
2264 // }
2265
2266//Console.WriteLine(" ");
2267//Console.WriteLine("link number ={0}", part.LinkNum);
2268//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2269//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2270//Console.WriteLine("Click offst ={0}", offset);
2271//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2272//Console.WriteLine("offsetr ={0}", offsetr);
2273//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2274//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2275
2276 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2277 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2278
2279 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
2016 // This calls HandleAgentSit twice, once from here, and the client calls 2280 // This calls HandleAgentSit twice, once from here, and the client calls
2017 // HandleAgentSit itself after it gets to the location 2281 // HandleAgentSit itself after it gets to the location
2018 // It doesn't get to the location until we've moved them there though 2282 // It doesn't get to the location until we've moved them there though
2019 // which happens in HandleAgentSit :P 2283 // which happens in HandleAgentSit :P
2020 m_autopilotMoving = autopilot; 2284 m_autopilotMoving = autopilot;
2021 m_autoPilotTarget = pos; 2285 m_autoPilotTarget = autopilotTarget;
2022 m_sitAtAutoTarget = autopilot; 2286 m_sitAtAutoTarget = autopilot;
2287 m_initialSitTarget = autopilotTarget;
2023 if (!autopilot) 2288 if (!autopilot)
2024 HandleAgentSit(remoteClient, UUID); 2289 HandleAgentSit(remoteClient, UUID);
2025 } 2290 }
@@ -2284,47 +2549,131 @@ namespace OpenSim.Region.Framework.Scenes
2284 { 2549 {
2285 if (part != null) 2550 if (part != null)
2286 { 2551 {
2552//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2287 if (part.GetAvatarOnSitTarget() == UUID) 2553 if (part.GetAvatarOnSitTarget() == UUID)
2288 { 2554 {
2555//Console.WriteLine("Scripted Sit");
2556 // Scripted sit
2289 Vector3 sitTargetPos = part.SitTargetPosition; 2557 Vector3 sitTargetPos = part.SitTargetPosition;
2290 Quaternion sitTargetOrient = part.SitTargetOrientation; 2558 Quaternion sitTargetOrient = part.SitTargetOrientation;
2291
2292 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2293 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2294
2295 //Quaternion result = (sitTargetOrient * vq) * nq;
2296
2297 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2559 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2298 m_pos += SIT_TARGET_ADJUSTMENT; 2560 m_pos += SIT_TARGET_ADJUSTMENT;
2299 Rotation = sitTargetOrient; 2561 if (!part.IsRoot)
2300 //Rotation = sitTargetOrient; 2562 {
2301 ParentPosition = part.AbsolutePosition; 2563 m_pos *= part.RotationOffset;
2302 2564 }
2303 //SendTerseUpdateToAllClients(); 2565 m_bodyRot = sitTargetOrient;
2566 m_parentPosition = part.AbsolutePosition;
2567 part.IsOccupied = true;
2568 part.ParentGroup.AddAvatar(agentID);
2304 } 2569 }
2305 else 2570 else
2306 { 2571 {
2307 m_pos -= part.AbsolutePosition; 2572 // if m_avUnscriptedSitPos is zero then Av sits above center
2308 ParentPosition = part.AbsolutePosition; 2573 // Else Av sits at m_avUnscriptedSitPos
2309 } 2574
2575 // Non-scripted sit by Kitto Flora 21Nov09
2576 // Calculate angle of line from prim to Av
2577 Quaternion partIRot;
2578// if (part.LinkNum == 1)
2579// { // Root prim of linkset
2580// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2581// }
2582// else
2583// { // single or child prim
2584 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2585// }
2586 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2587 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2588 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2589 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2590 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2591 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2592 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2593 // Av sits at world euler <0,0, z>, translated by part rotation
2594 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2595
2596 m_parentPosition = part.AbsolutePosition;
2597 part.IsOccupied = true;
2598 part.ParentGroup.AddAvatar(agentID);
2599 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2600 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2601 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2602 m_avUnscriptedSitPos; // adds click offset, if any
2603 //Set up raytrace to find top surface of prim
2604 Vector3 size = part.Scale;
2605 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2606 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2607 Vector3 down = new Vector3(0f, 0f, -1f);
2608//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2609 m_scene.PhysicsScene.RaycastWorld(
2610 start, // Vector3 position,
2611 down, // Vector3 direction,
2612 mag, // float length,
2613 SitAltitudeCallback); // retMethod
2614 } // end scripted/not
2310 } 2615 }
2311 else 2616 else // no Av
2312 { 2617 {
2313 return; 2618 return;
2314 } 2619 }
2315 } 2620 }
2316 ParentID = m_requestedSitTargetID; 2621 ParentID = m_requestedSitTargetID;
2317 2622
2623 //We want our offsets to reference the root prim, not the child we may have sat on
2624 if (!part.IsRoot)
2625 {
2626 m_parentID = part.ParentGroup.RootPart.LocalId;
2627 m_pos += part.OffsetPosition;
2628 }
2629 else
2630 {
2631 m_parentID = m_requestedSitTargetID;
2632 }
2633
2634 m_linkedPrim = part.UUID;
2635 if (part.GetAvatarOnSitTarget() != UUID)
2636 {
2637 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2638 }
2318 Velocity = Vector3.Zero; 2639 Velocity = Vector3.Zero;
2319 RemoveFromPhysicalScene(); 2640 RemoveFromPhysicalScene();
2320
2321 Animator.TrySetMovementAnimation(sitAnimation); 2641 Animator.TrySetMovementAnimation(sitAnimation);
2322 SendAvatarDataToAllAgents(); 2642 SendAvatarDataToAllAgents();
2323 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2324 // So we're also sending a terse update (which has avatar rotation)
2325 // [Update] We do now.
2326 //SendTerseUpdateToAllClients(); 2643 //SendTerseUpdateToAllClients();
2327 } 2644 }
2645
2646 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2647 {
2648 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2649 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2650 if(hitYN)
2651 {
2652 // m_pos = Av offset from prim center to make look like on center
2653 // m_parentPosition = Actual center pos of prim
2654 // collisionPoint = spot on prim where we want to sit
2655 // collisionPoint.Z = global sit surface height
2656 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2657 Quaternion partIRot;
2658// if (part.LinkNum == 1)
2659/// { // Root prim of linkset
2660// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2661// }
2662// else
2663// { // single or child prim
2664 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2665// }
2666 if (m_initialSitTarget != null)
2667 {
2668 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2669 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2670 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2671 m_pos += offset;
2672 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2673 }
2674
2675 }
2676 } // End SitAltitudeCallback KF.
2328 2677
2329 /// <summary> 2678 /// <summary>
2330 /// Event handler for the 'Always run' setting on the client 2679 /// Event handler for the 'Always run' setting on the client
@@ -2432,6 +2781,9 @@ namespace OpenSim.Region.Framework.Scenes
2432 2781
2433 CheckForSignificantMovement(); // sends update to the modules. 2782 CheckForSignificantMovement(); // sends update to the modules.
2434 } 2783 }
2784
2785 //Sending prim updates AFTER the avatar terse updates are sent
2786 SendPrimUpdates();
2435 } 2787 }
2436 2788
2437 #endregion 2789 #endregion
@@ -3203,6 +3555,7 @@ namespace OpenSim.Region.Framework.Scenes
3203 m_callbackURI = cAgent.CallbackURI; 3555 m_callbackURI = cAgent.CallbackURI;
3204 3556
3205 m_pos = cAgent.Position; 3557 m_pos = cAgent.Position;
3558
3206 m_velocity = cAgent.Velocity; 3559 m_velocity = cAgent.Velocity;
3207 CameraPosition = cAgent.Center; 3560 CameraPosition = cAgent.Center;
3208 CameraAtAxis = cAgent.AtAxis; 3561 CameraAtAxis = cAgent.AtAxis;
@@ -3352,14 +3705,26 @@ namespace OpenSim.Region.Framework.Scenes
3352 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3705 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
3353 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( 3706 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
3354 // as of this comment the interval is set in AddToPhysicalScene 3707 // as of this comment the interval is set in AddToPhysicalScene
3355 if (Animator != null) 3708 if (Animator!=null)
3356 Animator.UpdateMovementAnimations(); 3709 {
3710 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3711 { // else its will lock out other animation changes, like ground sit.
3712 Animator.UpdateMovementAnimations();
3713 m_updateCount--;
3714 }
3715 }
3357 3716
3358 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3717 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3359 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3718 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3360 3719
3361 CollisionPlane = Vector4.UnitW; 3720 CollisionPlane = Vector4.UnitW;
3362 3721
3722 if (m_lastColCount != coldata.Count)
3723 {
3724 m_updateCount = UPDATE_COUNT;
3725 m_lastColCount = coldata.Count;
3726 }
3727
3363 if (coldata.Count != 0 && Animator != null) 3728 if (coldata.Count != 0 && Animator != null)
3364 { 3729 {
3365 switch (Animator.CurrentMovementAnimation) 3730 switch (Animator.CurrentMovementAnimation)
@@ -3389,6 +3754,148 @@ namespace OpenSim.Region.Framework.Scenes
3389 } 3754 }
3390 } 3755 }
3391 3756
3757 List<uint> thisHitColliders = new List<uint>();
3758 List<uint> endedColliders = new List<uint>();
3759 List<uint> startedColliders = new List<uint>();
3760
3761 foreach (uint localid in coldata.Keys)
3762 {
3763 thisHitColliders.Add(localid);
3764 if (!m_lastColliders.Contains(localid))
3765 {
3766 startedColliders.Add(localid);
3767 }
3768 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3769 }
3770
3771 // calculate things that ended colliding
3772 foreach (uint localID in m_lastColliders)
3773 {
3774 if (!thisHitColliders.Contains(localID))
3775 {
3776 endedColliders.Add(localID);
3777 }
3778 }
3779 //add the items that started colliding this time to the last colliders list.
3780 foreach (uint localID in startedColliders)
3781 {
3782 m_lastColliders.Add(localID);
3783 }
3784 // remove things that ended colliding from the last colliders list
3785 foreach (uint localID in endedColliders)
3786 {
3787 m_lastColliders.Remove(localID);
3788 }
3789
3790 // do event notification
3791 if (startedColliders.Count > 0)
3792 {
3793 ColliderArgs StartCollidingMessage = new ColliderArgs();
3794 List<DetectedObject> colliding = new List<DetectedObject>();
3795 foreach (uint localId in startedColliders)
3796 {
3797 if (localId == 0)
3798 continue;
3799
3800 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3801 string data = "";
3802 if (obj != null)
3803 {
3804 DetectedObject detobj = new DetectedObject();
3805 detobj.keyUUID = obj.UUID;
3806 detobj.nameStr = obj.Name;
3807 detobj.ownerUUID = obj.OwnerID;
3808 detobj.posVector = obj.AbsolutePosition;
3809 detobj.rotQuat = obj.GetWorldRotation();
3810 detobj.velVector = obj.Velocity;
3811 detobj.colliderType = 0;
3812 detobj.groupUUID = obj.GroupID;
3813 colliding.Add(detobj);
3814 }
3815 }
3816
3817 if (colliding.Count > 0)
3818 {
3819 StartCollidingMessage.Colliders = colliding;
3820
3821 foreach (SceneObjectGroup att in GetAttachments())
3822 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3823 }
3824 }
3825
3826 if (endedColliders.Count > 0)
3827 {
3828 ColliderArgs EndCollidingMessage = new ColliderArgs();
3829 List<DetectedObject> colliding = new List<DetectedObject>();
3830 foreach (uint localId in endedColliders)
3831 {
3832 if (localId == 0)
3833 continue;
3834
3835 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3836 string data = "";
3837 if (obj != null)
3838 {
3839 DetectedObject detobj = new DetectedObject();
3840 detobj.keyUUID = obj.UUID;
3841 detobj.nameStr = obj.Name;
3842 detobj.ownerUUID = obj.OwnerID;
3843 detobj.posVector = obj.AbsolutePosition;
3844 detobj.rotQuat = obj.GetWorldRotation();
3845 detobj.velVector = obj.Velocity;
3846 detobj.colliderType = 0;
3847 detobj.groupUUID = obj.GroupID;
3848 colliding.Add(detobj);
3849 }
3850 }
3851
3852 if (colliding.Count > 0)
3853 {
3854 EndCollidingMessage.Colliders = colliding;
3855
3856 foreach (SceneObjectGroup att in GetAttachments())
3857 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3858 }
3859 }
3860
3861 if (thisHitColliders.Count > 0)
3862 {
3863 ColliderArgs CollidingMessage = new ColliderArgs();
3864 List<DetectedObject> colliding = new List<DetectedObject>();
3865 foreach (uint localId in thisHitColliders)
3866 {
3867 if (localId == 0)
3868 continue;
3869
3870 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3871 string data = "";
3872 if (obj != null)
3873 {
3874 DetectedObject detobj = new DetectedObject();
3875 detobj.keyUUID = obj.UUID;
3876 detobj.nameStr = obj.Name;
3877 detobj.ownerUUID = obj.OwnerID;
3878 detobj.posVector = obj.AbsolutePosition;
3879 detobj.rotQuat = obj.GetWorldRotation();
3880 detobj.velVector = obj.Velocity;
3881 detobj.colliderType = 0;
3882 detobj.groupUUID = obj.GroupID;
3883 colliding.Add(detobj);
3884 }
3885 }
3886
3887 if (colliding.Count > 0)
3888 {
3889 CollidingMessage.Colliders = colliding;
3890
3891 lock (m_attachments)
3892 {
3893 foreach (SceneObjectGroup att in m_attachments)
3894 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3895 }
3896 }
3897 }
3898
3392 if (Invulnerable) 3899 if (Invulnerable)
3393 return; 3900 return;
3394 3901
@@ -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}