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.cs873
1 files changed, 708 insertions, 165 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index a8eff70..fa6945c 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("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
74// } 75// }
75 76
76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 78
78 public PresenceType PresenceType { get; private set; } 79 public PresenceType PresenceType { get; private set; }
@@ -89,7 +90,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 90 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 91 /// issue #1716
91 /// </summary> 92 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 93// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
94 // Value revised by KF 091121 by comparison with SL.
95 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 96
94 /// <summary> 97 /// <summary>
95 /// Movement updates for agents in neighboring regions are sent directly to clients. 98 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -118,6 +121,7 @@ namespace OpenSim.Region.Framework.Scenes
118 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 121 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
119 /// necessary. 122 /// necessary.
120 /// </remarks> 123 /// </remarks>
124
121 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 125 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
122 126
123 public Object AttachmentsSyncLock { get; private set; } 127 public Object AttachmentsSyncLock { get; private set; }
@@ -131,8 +135,11 @@ namespace OpenSim.Region.Framework.Scenes
131 public Vector3 lastKnownAllowedPosition; 135 public Vector3 lastKnownAllowedPosition;
132 public bool sentMessageAboutRestrictedParcelFlyingDown; 136 public bool sentMessageAboutRestrictedParcelFlyingDown;
133 public Vector4 CollisionPlane = Vector4.UnitW; 137 public Vector4 CollisionPlane = Vector4.UnitW;
134 138
139 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
140 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
135 private Vector3 m_lastPosition; 141 private Vector3 m_lastPosition;
142 private Vector3 m_lastWorldPosition;
136 private Quaternion m_lastRotation; 143 private Quaternion m_lastRotation;
137 private Vector3 m_lastVelocity; 144 private Vector3 m_lastVelocity;
138 //private int m_lastTerseSent; 145 //private int m_lastTerseSent;
@@ -140,6 +147,11 @@ namespace OpenSim.Region.Framework.Scenes
140 private bool m_updateflag; 147 private bool m_updateflag;
141 private byte m_movementflag; 148 private byte m_movementflag;
142 private Vector3? m_forceToApply; 149 private Vector3? m_forceToApply;
150 private int m_userFlags;
151 public int UserFlags
152 {
153 get { return m_userFlags; }
154 }
143 private TeleportFlags m_teleportFlags; 155 private TeleportFlags m_teleportFlags;
144 public TeleportFlags TeleportFlags 156 public TeleportFlags TeleportFlags
145 { 157 {
@@ -170,9 +182,10 @@ namespace OpenSim.Region.Framework.Scenes
170 private int m_perfMonMS; 182 private int m_perfMonMS;
171 183
172 private bool m_setAlwaysRun; 184 private bool m_setAlwaysRun;
173
174 private bool m_forceFly; 185 private bool m_forceFly;
175 private bool m_flyDisabled; 186 private bool m_flyDisabled;
187 private bool m_flyingOld; // add for fly velocity control
188 public bool m_wasFlying; // add for fly velocity control
176 189
177 private float m_speedModifier = 1.0f; 190 private float m_speedModifier = 1.0f;
178 191
@@ -190,7 +203,8 @@ namespace OpenSim.Region.Framework.Scenes
190 203
191 protected ulong crossingFromRegion; 204 protected ulong crossingFromRegion;
192 205
193 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 206 private readonly Vector3[] Dir_Vectors = new Vector3[11];
207 private bool m_isNudging = false;
194 208
195 // Position of agent's camera in world (region cordinates) 209 // Position of agent's camera in world (region cordinates)
196 protected Vector3 m_CameraCenter; 210 protected Vector3 m_CameraCenter;
@@ -215,17 +229,25 @@ namespace OpenSim.Region.Framework.Scenes
215 private bool m_autopilotMoving; 229 private bool m_autopilotMoving;
216 private Vector3 m_autoPilotTarget; 230 private Vector3 m_autoPilotTarget;
217 private bool m_sitAtAutoTarget; 231 private bool m_sitAtAutoTarget;
232 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
218 233
219 private string m_nextSitAnimation = String.Empty; 234 private string m_nextSitAnimation = String.Empty;
220 235
221 //PauPaw:Proper PID Controler for autopilot************ 236 //PauPaw:Proper PID Controler for autopilot************
222 public bool MovingToTarget { get; private set; } 237 public bool MovingToTarget { get; private set; }
223 public Vector3 MoveToPositionTarget { get; private set; } 238 public Vector3 MoveToPositionTarget { get; private set; }
239 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
224 240
225 private bool m_followCamAuto; 241 private bool m_followCamAuto;
226 242
227 private int m_movementUpdateCount; 243 private int m_movementUpdateCount;
244 private int m_lastColCount = -1; //KF: Look for Collision chnages
245 private int m_updateCount = 0; //KF: Update Anims for a while
246 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
228 private const int NumMovementsBetweenRayCast = 5; 247 private const int NumMovementsBetweenRayCast = 5;
248 private List<uint> m_lastColliders = new List<uint>();
249
250 private object m_syncRoot = new Object();
229 251
230 private bool CameraConstraintActive; 252 private bool CameraConstraintActive;
231 //private int m_moveToPositionStateStatus; 253 //private int m_moveToPositionStateStatus;
@@ -262,7 +284,9 @@ namespace OpenSim.Region.Framework.Scenes
262 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 284 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
263 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 285 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
264 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 286 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
265 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 287 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
288 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
289 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
266 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 290 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
267 } 291 }
268 292
@@ -466,7 +490,8 @@ namespace OpenSim.Region.Framework.Scenes
466 get 490 get
467 { 491 {
468 PhysicsActor actor = m_physicsActor; 492 PhysicsActor actor = m_physicsActor;
469 if (actor != null) 493// if (actor != null)
494 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
470 m_pos = actor.Position; 495 m_pos = actor.Position;
471 else 496 else
472 { 497 {
@@ -488,7 +513,7 @@ namespace OpenSim.Region.Framework.Scenes
488 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 513 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
489 if (part != null) 514 if (part != null)
490 { 515 {
491 return m_parentPosition + (m_pos * part.GetWorldRotation()); 516 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
492 } 517 }
493 else 518 else
494 { 519 {
@@ -515,7 +540,8 @@ namespace OpenSim.Region.Framework.Scenes
515 } 540 }
516 } 541 }
517 542
518 m_pos = value; 543 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
544 m_pos = value;
519 m_parentPosition = Vector3.Zero; 545 m_parentPosition = Vector3.Zero;
520 } 546 }
521 } 547 }
@@ -559,10 +585,39 @@ namespace OpenSim.Region.Framework.Scenes
559 } 585 }
560 } 586 }
561 587
588 public Quaternion OffsetRotation
589 {
590 get { return m_offsetRotation; }
591 set { m_offsetRotation = value; }
592 }
593
562 public Quaternion Rotation 594 public Quaternion Rotation
563 { 595 {
564 get { return m_bodyRot; } 596 get {
565 set { m_bodyRot = value; } 597 if (m_parentID != 0)
598 {
599 if (m_offsetRotation != null)
600 {
601 return m_offsetRotation;
602 }
603 else
604 {
605 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
606 }
607
608 }
609 else
610 {
611 return m_bodyRot;
612 }
613 }
614 set {
615 m_bodyRot = value;
616 if (m_parentID != 0)
617 {
618 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
619 }
620 }
566 } 621 }
567 622
568 public Quaternion PreviousRotation 623 public Quaternion PreviousRotation
@@ -587,11 +642,21 @@ namespace OpenSim.Region.Framework.Scenes
587 642
588 private uint m_parentID; 643 private uint m_parentID;
589 644
645
646 private UUID m_linkedPrim;
647
590 public uint ParentID 648 public uint ParentID
591 { 649 {
592 get { return m_parentID; } 650 get { return m_parentID; }
593 set { m_parentID = value; } 651 set { m_parentID = value; }
594 } 652 }
653
654 public UUID LinkedPrim
655 {
656 get { return m_linkedPrim; }
657 set { m_linkedPrim = value; }
658 }
659
595 public float Health 660 public float Health
596 { 661 {
597 get { return m_health; } 662 get { return m_health; }
@@ -727,6 +792,7 @@ namespace OpenSim.Region.Framework.Scenes
727 m_localId = m_scene.AllocateLocalId(); 792 m_localId = m_scene.AllocateLocalId();
728 793
729 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 794 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
795 m_userFlags = account.UserFlags;
730 796
731 if (account != null) 797 if (account != null)
732 m_userLevel = account.UserLevel; 798 m_userLevel = account.UserLevel;
@@ -745,10 +811,7 @@ namespace OpenSim.Region.Framework.Scenes
745 m_reprioritization_timer.AutoReset = false; 811 m_reprioritization_timer.AutoReset = false;
746 812
747 AdjustKnownSeeds(); 813 AdjustKnownSeeds();
748
749 // TODO: I think, this won't send anything, as we are still a child here...
750 Animator.TrySetMovementAnimation("STAND"); 814 Animator.TrySetMovementAnimation("STAND");
751
752 // we created a new ScenePresence (a new child agent) in a fresh region. 815 // we created a new ScenePresence (a new child agent) in a fresh region.
753 // Request info about all the (root) agents in this region 816 // Request info about all the (root) agents in this region
754 // Note: This won't send data *to* other clients in that region (children don't send) 817 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -789,25 +852,47 @@ namespace OpenSim.Region.Framework.Scenes
789 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 852 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
790 Dir_Vectors[4] = Vector3.UnitZ; //UP 853 Dir_Vectors[4] = Vector3.UnitZ; //UP
791 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 854 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
792 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 855 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
793 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 856 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
794 Dir_Vectors[7] = -Vector3.UnitX; //BACK 857 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
858 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
859 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
795 } 860 }
796 861
797 private Vector3[] GetWalkDirectionVectors() 862 private Vector3[] GetWalkDirectionVectors()
798 { 863 {
799 Vector3[] vector = new Vector3[9]; 864 Vector3[] vector = new Vector3[11];
800 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 865 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
801 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 866 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
802 vector[2] = Vector3.UnitY; //LEFT 867 vector[2] = Vector3.UnitY; //LEFT
803 vector[3] = -Vector3.UnitY; //RIGHT 868 vector[3] = -Vector3.UnitY; //RIGHT
804 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 869 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
805 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 870 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
806 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 871 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
807 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 872 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
808 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 873 vector[8] = Vector3.UnitY; //LEFT_NUDGE
874 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
875 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
809 return vector; 876 return vector;
810 } 877 }
878
879 private bool[] GetDirectionIsNudge()
880 {
881 bool[] isNudge = new bool[11];
882 isNudge[0] = false; //FORWARD
883 isNudge[1] = false; //BACK
884 isNudge[2] = false; //LEFT
885 isNudge[3] = false; //RIGHT
886 isNudge[4] = false; //UP
887 isNudge[5] = false; //DOWN
888 isNudge[6] = true; //FORWARD_NUDGE
889 isNudge[7] = true; //BACK_NUDGE
890 isNudge[8] = true; //LEFT_NUDGE
891 isNudge[9] = true; //RIGHT_NUDGE
892 isNudge[10] = true; //DOWN_Nudge
893 return isNudge;
894 }
895
811 896
812 #endregion 897 #endregion
813 898
@@ -872,6 +957,62 @@ namespace OpenSim.Region.Framework.Scenes
872 pos.Y = crossedBorder.BorderLine.Z - 1; 957 pos.Y = crossedBorder.BorderLine.Z - 1;
873 } 958 }
874 959
960 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
961 if (land != null)
962 {
963 // If we come in via login, landmark or map, we want to
964 // honor landing points. If we come in via Lure, we want
965 // to ignore them.
966 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
967 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
968 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
969 {
970 // Don't restrict gods, estate managers, or land owners to
971 // the TP point. This behaviour mimics agni.
972 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
973 land.LandData.UserLocation != Vector3.Zero &&
974 GodLevel < 200 &&
975 ((land.LandData.OwnerID != m_uuid &&
976 (!m_scene.Permissions.IsGod(m_uuid)) &&
977 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
978 {
979 pos = land.LandData.UserLocation;
980 }
981 }
982
983 land.SendLandUpdateToClient(ControllingClient);
984 }
985
986 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
987 {
988 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
989
990 if (pos.X < 0)
991 {
992 emergencyPos.X = (int)Constants.RegionSize + pos.X;
993 if (!(pos.Y < 0))
994 emergencyPos.Y = pos.Y;
995 if (!(pos.Z < 0))
996 emergencyPos.Z = pos.Z;
997 }
998 if (pos.Y < 0)
999 {
1000 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
1001 if (!(pos.X < 0))
1002 emergencyPos.X = pos.X;
1003 if (!(pos.Z < 0))
1004 emergencyPos.Z = pos.Z;
1005 }
1006 if (pos.Z < 0)
1007 {
1008 emergencyPos.Z = 128;
1009 if (!(pos.Y < 0))
1010 emergencyPos.Y = pos.Y;
1011 if (!(pos.X < 0))
1012 emergencyPos.X = pos.X;
1013 }
1014 }
1015
875 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1016 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
876 { 1017 {
877 m_log.WarnFormat( 1018 m_log.WarnFormat(
@@ -1004,16 +1145,21 @@ namespace OpenSim.Region.Framework.Scenes
1004 /// <summary> 1145 /// <summary>
1005 /// Removes physics plugin scene representation of this agent if it exists. 1146 /// Removes physics plugin scene representation of this agent if it exists.
1006 /// </summary> 1147 /// </summary>
1007 private void RemoveFromPhysicalScene() 1148 public void RemoveFromPhysicalScene()
1008 { 1149 {
1009 if (PhysicsActor != null) 1150 if (PhysicsActor != null)
1010 { 1151 {
1011 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1152 try
1012 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1153 {
1013 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1154 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1014 m_physicsActor.UnSubscribeEvents(); 1155 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1015 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1156 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1016 PhysicsActor = null; 1157 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1158 m_physicsActor.UnSubscribeEvents();
1159 PhysicsActor = null;
1160 }
1161 catch
1162 { }
1017 } 1163 }
1018 } 1164 }
1019 1165
@@ -1024,15 +1170,18 @@ namespace OpenSim.Region.Framework.Scenes
1024 public void Teleport(Vector3 pos) 1170 public void Teleport(Vector3 pos)
1025 { 1171 {
1026 bool isFlying = false; 1172 bool isFlying = false;
1173
1027 if (m_physicsActor != null) 1174 if (m_physicsActor != null)
1028 isFlying = m_physicsActor.Flying; 1175 isFlying = m_physicsActor.Flying;
1029 1176
1030 RemoveFromPhysicalScene(); 1177 RemoveFromPhysicalScene();
1031 Velocity = Vector3.Zero; 1178 Velocity = Vector3.Zero;
1179 CheckLandingPoint(ref pos);
1032 AbsolutePosition = pos; 1180 AbsolutePosition = pos;
1033 AddToPhysicalScene(isFlying); 1181 AddToPhysicalScene(isFlying);
1034 1182
1035 SendTerseUpdateToAllClients(); 1183 SendTerseUpdateToAllClients();
1184
1036 } 1185 }
1037 1186
1038 public void TeleportWithMomentum(Vector3 pos) 1187 public void TeleportWithMomentum(Vector3 pos)
@@ -1042,6 +1191,7 @@ namespace OpenSim.Region.Framework.Scenes
1042 isFlying = m_physicsActor.Flying; 1191 isFlying = m_physicsActor.Flying;
1043 1192
1044 RemoveFromPhysicalScene(); 1193 RemoveFromPhysicalScene();
1194 CheckLandingPoint(ref pos);
1045 AbsolutePosition = pos; 1195 AbsolutePosition = pos;
1046 AddToPhysicalScene(isFlying); 1196 AddToPhysicalScene(isFlying);
1047 1197
@@ -1217,9 +1367,12 @@ namespace OpenSim.Region.Framework.Scenes
1217 /// <summary> 1367 /// <summary>
1218 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1368 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1219 /// </summary> 1369 /// </summary>
1370 /// <summary>
1371 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1372 /// </summary>
1220 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1373 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1221 { 1374 {
1222// m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name); 1375 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1223 1376
1224 //if (m_isChildAgent) 1377 //if (m_isChildAgent)
1225 //{ 1378 //{
@@ -1415,12 +1568,12 @@ namespace OpenSim.Region.Framework.Scenes
1415 1568
1416 if ((m_movementflag & (byte)(uint)DCF) == 0) 1569 if ((m_movementflag & (byte)(uint)DCF) == 0)
1417 { 1570 {
1418 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1571 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1419 { 1572 {
1420 m_movementflag |= (byte)nudgehack; 1573 m_movementflag |= (byte)nudgehack;
1421 } 1574 }
1422 1575
1423// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF); 1576 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF);
1424 m_movementflag += (byte)(uint)DCF; 1577 m_movementflag += (byte)(uint)DCF;
1425 update_movementflag = true; 1578 update_movementflag = true;
1426 } 1579 }
@@ -1428,11 +1581,11 @@ namespace OpenSim.Region.Framework.Scenes
1428 else 1581 else
1429 { 1582 {
1430 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1583 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1431 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1584 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1432 && ((m_movementflag & (byte)nudgehack) == nudgehack)) 1585 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1433 ) // This or is for Nudge forward 1586 ) // This or is for Nudge forward
1434 { 1587 {
1435// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF); 1588 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1436 m_movementflag -= ((byte)(uint)DCF); 1589 m_movementflag -= ((byte)(uint)DCF);
1437 update_movementflag = true; 1590 update_movementflag = true;
1438 1591
@@ -1497,21 +1650,21 @@ namespace OpenSim.Region.Framework.Scenes
1497 // which occurs later in the main scene loop 1650 // which occurs later in the main scene loop
1498 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1651 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1499 { 1652 {
1500// m_log.DebugFormat( 1653 // m_log.DebugFormat(
1501// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1654 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1502// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1655 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1503 1656
1504 AddNewMovement(agent_control_v3); 1657 AddNewMovement(agent_control_v3);
1505 } 1658 }
1506// else 1659 // else
1507// { 1660 // {
1508// if (!update_movementflag) 1661 // if (!update_movementflag)
1509// { 1662 // {
1510// m_log.DebugFormat( 1663 // m_log.DebugFormat(
1511// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1664 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1512// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1665 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1513// } 1666 // }
1514// } 1667 // }
1515 1668
1516 if (update_movementflag && m_parentID == 0) 1669 if (update_movementflag && m_parentID == 0)
1517 Animator.UpdateMovementAnimations(); 1670 Animator.UpdateMovementAnimations();
@@ -1532,20 +1685,20 @@ namespace OpenSim.Region.Framework.Scenes
1532 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1685 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1533 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1686 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1534 { 1687 {
1535// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1688 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1536 1689
1537 bool updated = false; 1690 bool updated = false;
1538 1691
1539// m_log.DebugFormat( 1692 // m_log.DebugFormat(
1540// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1693 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1541// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1694 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1542 1695
1543 if (!m_autopilotMoving) 1696 if (!m_autopilotMoving)
1544 { 1697 {
1545 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1698 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1546// m_log.DebugFormat( 1699 // m_log.DebugFormat(
1547// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1700 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1548// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1701 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1549 1702
1550 // Check the error term of the current position in relation to the target position 1703 // Check the error term of the current position in relation to the target position
1551 if (distanceToTarget <= 1) 1704 if (distanceToTarget <= 1)
@@ -1568,7 +1721,7 @@ namespace OpenSim.Region.Framework.Scenes
1568 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1721 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1569 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1722 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1570 // Ignore z component of vector 1723 // Ignore z component of vector
1571// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1724 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1572 LocalVectorToTarget3D.Normalize(); 1725 LocalVectorToTarget3D.Normalize();
1573 1726
1574 // update avatar movement flags. the avatar coordinate system is as follows: 1727 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1634,9 +1787,9 @@ namespace OpenSim.Region.Framework.Scenes
1634 updated = true; 1787 updated = true;
1635 } 1788 }
1636 1789
1637// m_log.DebugFormat( 1790 // m_log.DebugFormat(
1638// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1791 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1639// LocalVectorToTarget3D, agent_control_v3, Name); 1792 // LocalVectorToTarget3D, agent_control_v3, Name);
1640 1793
1641 agent_control_v3 += LocalVectorToTarget3D; 1794 agent_control_v3 += LocalVectorToTarget3D;
1642 } 1795 }
@@ -1738,7 +1891,7 @@ namespace OpenSim.Region.Framework.Scenes
1738 Velocity = Vector3.Zero; 1891 Velocity = Vector3.Zero;
1739 SendAvatarDataToAllAgents(); 1892 SendAvatarDataToAllAgents();
1740 1893
1741 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1894 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1742 } 1895 }
1743 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1896 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1744 m_requestedSitTargetUUID = UUID.Zero; 1897 m_requestedSitTargetUUID = UUID.Zero;
@@ -1775,25 +1928,22 @@ namespace OpenSim.Region.Framework.Scenes
1775 1928
1776 if (m_parentID != 0) 1929 if (m_parentID != 0)
1777 { 1930 {
1778 m_log.Debug("StandupCode Executed"); 1931 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1779 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1780 if (part != null) 1932 if (part != null)
1781 { 1933 {
1934 part.TaskInventory.LockItemsForRead(true);
1782 TaskInventoryDictionary taskIDict = part.TaskInventory; 1935 TaskInventoryDictionary taskIDict = part.TaskInventory;
1783 if (taskIDict != null) 1936 if (taskIDict != null)
1784 { 1937 {
1785 lock (taskIDict) 1938 foreach (UUID taskID in taskIDict.Keys)
1786 { 1939 {
1787 foreach (UUID taskID in taskIDict.Keys) 1940 UnRegisterControlEventsToScript(LocalId, taskID);
1788 { 1941 taskIDict[taskID].PermsMask &= ~(
1789 UnRegisterControlEventsToScript(LocalId, taskID); 1942 2048 | //PERMISSION_CONTROL_CAMERA
1790 taskIDict[taskID].PermsMask &= ~( 1943 4); // PERMISSION_TAKE_CONTROLS
1791 2048 | //PERMISSION_CONTROL_CAMERA
1792 4); // PERMISSION_TAKE_CONTROLS
1793 }
1794 } 1944 }
1795
1796 } 1945 }
1946 part.TaskInventory.LockItemsForRead(false);
1797 // Reset sit target. 1947 // Reset sit target.
1798 if (part.GetAvatarOnSitTarget() == UUID) 1948 if (part.GetAvatarOnSitTarget() == UUID)
1799 part.SitTargetAvatar = UUID.Zero; 1949 part.SitTargetAvatar = UUID.Zero;
@@ -1802,20 +1952,58 @@ namespace OpenSim.Region.Framework.Scenes
1802 m_parentPosition = part.GetWorldPosition(); 1952 m_parentPosition = part.GetWorldPosition();
1803 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1953 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1804 } 1954 }
1955 // part.GetWorldRotation() is the rotation of the object being sat on
1956 // Rotation is the sittiing Av's rotation
1957
1958 Quaternion partRot;
1959// if (part.LinkNum == 1)
1960// { // Root prim of linkset
1961// partRot = part.ParentGroup.RootPart.RotationOffset;
1962// }
1963// else
1964// { // single or child prim
1965
1966// }
1967 if (part == null) //CW: Part may be gone. llDie() for example.
1968 {
1969 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1970 }
1971 else
1972 {
1973 partRot = part.GetWorldRotation();
1974 }
1805 1975
1976 Quaternion partIRot = Quaternion.Inverse(partRot);
1977
1978 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1979 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1980
1981
1806 if (m_physicsActor == null) 1982 if (m_physicsActor == null)
1807 { 1983 {
1808 AddToPhysicalScene(false); 1984 AddToPhysicalScene(false);
1809 } 1985 }
1810 1986 //CW: If the part isn't null then we can set the current position
1811 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1987 if (part != null)
1812 m_parentPosition = Vector3.Zero; 1988 {
1813 1989 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1814 m_parentID = 0; 1990 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1991 part.IsOccupied = false;
1992 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1993 }
1994 else
1995 {
1996 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1997 AbsolutePosition = m_lastWorldPosition;
1998 }
1999
2000 m_parentPosition = Vector3.Zero;
2001 m_parentID = 0;
2002 m_linkedPrim = UUID.Zero;
2003 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1815 SendAvatarDataToAllAgents(); 2004 SendAvatarDataToAllAgents();
1816 m_requestedSitTargetID = 0; 2005 m_requestedSitTargetID = 0;
1817 } 2006 }
1818
1819 Animator.TrySetMovementAnimation("STAND"); 2007 Animator.TrySetMovementAnimation("STAND");
1820 } 2008 }
1821 2009
@@ -1846,13 +2034,9 @@ namespace OpenSim.Region.Framework.Scenes
1846 Vector3 avSitOffSet = part.SitTargetPosition; 2034 Vector3 avSitOffSet = part.SitTargetPosition;
1847 Quaternion avSitOrientation = part.SitTargetOrientation; 2035 Quaternion avSitOrientation = part.SitTargetOrientation;
1848 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2036 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1849 2037 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1850 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2038 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1851 bool SitTargetisSet = 2039 if (SitTargetisSet && !SitTargetOccupied)
1852 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1853 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1854
1855 if (SitTargetisSet && SitTargetUnOccupied)
1856 { 2040 {
1857 //switch the target to this prim 2041 //switch the target to this prim
1858 return part; 2042 return part;
@@ -1866,85 +2050,168 @@ namespace OpenSim.Region.Framework.Scenes
1866 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2050 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1867 { 2051 {
1868 bool autopilot = true; 2052 bool autopilot = true;
2053 Vector3 autopilotTarget = new Vector3();
2054 Quaternion sitOrientation = Quaternion.Identity;
1869 Vector3 pos = new Vector3(); 2055 Vector3 pos = new Vector3();
1870 Quaternion sitOrientation = pSitOrientation;
1871 Vector3 cameraEyeOffset = Vector3.Zero; 2056 Vector3 cameraEyeOffset = Vector3.Zero;
1872 Vector3 cameraAtOffset = Vector3.Zero; 2057 Vector3 cameraAtOffset = Vector3.Zero;
1873 bool forceMouselook = false; 2058 bool forceMouselook = false;
1874 2059
1875 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2060 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1876 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2061 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1877 if (part != null) 2062 if (part == null) return;
2063
2064 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2065 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2066
2067 // part is the prim to sit on
2068 // offset is the world-ref vector distance from that prim center to the click-spot
2069 // UUID is the UUID of the Avatar doing the clicking
2070
2071 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2072
2073 // Is a sit target available?
2074 Vector3 avSitOffSet = part.SitTargetPosition;
2075 Quaternion avSitOrientation = part.SitTargetOrientation;
2076
2077 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2078 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2079 Quaternion partRot;
2080// if (part.LinkNum == 1)
2081// { // Root prim of linkset
2082// partRot = part.ParentGroup.RootPart.RotationOffset;
2083// }
2084// else
2085// { // single or child prim
2086 partRot = part.GetWorldRotation();
2087// }
2088 Quaternion partIRot = Quaternion.Inverse(partRot);
2089//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2090 // Sit analysis rewritten by KF 091125
2091 if (SitTargetisSet) // scipted sit
1878 { 2092 {
1879 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2093 if (!part.IsOccupied)
1880 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2094 {
1881 2095//Console.WriteLine("Scripted, unoccupied");
1882 // Is a sit target available? 2096 part.SitTargetAvatar = UUID; // set that Av will be on it
1883 Vector3 avSitOffSet = part.SitTargetPosition; 2097 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1884 Quaternion avSitOrientation = part.SitTargetOrientation; 2098
1885 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2099 Quaternion nrot = avSitOrientation;
1886 2100 if (!part.IsRoot)
1887 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1888 bool SitTargetisSet =
1889 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1890 (
1891 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1892 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1893 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1894 )
1895 ));
1896
1897 if (SitTargetisSet && SitTargetUnOccupied)
1898 {
1899 part.SitTargetAvatar = UUID;
1900 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1901 sitOrientation = avSitOrientation;
1902 autopilot = false;
1903 }
1904 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1905
1906 pos = part.AbsolutePosition + offset;
1907 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1908 //{
1909 // offset = pos;
1910 //autopilot = false;
1911 //}
1912 if (m_physicsActor != null)
1913 {
1914 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1915 // We can remove the physicsActor until they stand up.
1916 m_sitAvatarHeight = m_physicsActor.Size.Z;
1917
1918 if (autopilot)
1919 { 2101 {
1920 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2102 nrot = part.RotationOffset * avSitOrientation;
1921 {
1922 autopilot = false;
1923
1924 RemoveFromPhysicalScene();
1925 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1926 }
1927 } 2103 }
1928 else 2104 sitOrientation = nrot; // Change rotatione to the scripted one
2105 OffsetRotation = nrot;
2106 autopilot = false; // Jump direct to scripted llSitPos()
2107 }
2108 else
2109 {
2110//Console.WriteLine("Scripted, occupied");
2111 return;
2112 }
2113 }
2114 else // Not Scripted
2115 {
2116 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
2117 {
2118 // large prim & offset, ignore if other Avs sitting
2119// offset.Z -= 0.05f;
2120 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2121 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2122
2123//Console.WriteLine(" offset ={0}", offset);
2124//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2125//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2126
2127 }
2128 else // small offset
2129 {
2130//Console.WriteLine("Small offset");
2131 if (!part.IsOccupied)
2132 {
2133 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2134 autopilotTarget = part.AbsolutePosition;
2135//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2136 }
2137 else return; // occupied small
2138 } // end large/small
2139 } // end Scripted/not
2140
2141 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2142
2143 cameraAtOffset = part.GetCameraAtOffset();
2144 cameraEyeOffset = part.GetCameraEyeOffset();
2145 forceMouselook = part.GetForceMouselook();
2146 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2147 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2148
2149 if (m_physicsActor != null)
2150 {
2151 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2152 // We can remove the physicsActor until they stand up.
2153 m_sitAvatarHeight = m_physicsActor.Size.Z;
2154 if (autopilot)
2155 { // its not a scripted sit
2156// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2157 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1929 { 2158 {
2159 autopilot = false; // close enough
2160 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2161 Not using the part's position because returning the AV to the last known standing
2162 position is likely to be more friendly, isn't it? */
1930 RemoveFromPhysicalScene(); 2163 RemoveFromPhysicalScene();
1931 } 2164 Velocity = Vector3.Zero;
2165 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2166 } // else the autopilot will get us close
2167 }
2168 else
2169 { // its a scripted sit
2170 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2171 I *am* using the part's position this time because we have no real idea how far away
2172 the avatar is from the sit target. */
2173 RemoveFromPhysicalScene();
2174 Velocity = Vector3.Zero;
1932 } 2175 }
1933
1934 cameraAtOffset = part.GetCameraAtOffset();
1935 cameraEyeOffset = part.GetCameraEyeOffset();
1936 forceMouselook = part.GetForceMouselook();
1937 } 2176 }
1938 2177 else return; // physactor is null!
1939 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2178
1940 m_requestedSitTargetUUID = targetID; 2179 Vector3 offsetr; // = offset * partIRot;
2180 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2181 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2182 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2183 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2184 //offsetr = offset * partIRot;
2185//
2186 // }
2187 // else
2188 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2189 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2190 // (offset * partRot);
2191 // }
2192
2193//Console.WriteLine(" ");
2194//Console.WriteLine("link number ={0}", part.LinkNum);
2195//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2196//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2197//Console.WriteLine("Click offst ={0}", offset);
2198//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2199//Console.WriteLine("offsetr ={0}", offsetr);
2200//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2201//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2202
2203 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2204 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2205
2206 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1941 // This calls HandleAgentSit twice, once from here, and the client calls 2207 // This calls HandleAgentSit twice, once from here, and the client calls
1942 // HandleAgentSit itself after it gets to the location 2208 // HandleAgentSit itself after it gets to the location
1943 // It doesn't get to the location until we've moved them there though 2209 // It doesn't get to the location until we've moved them there though
1944 // which happens in HandleAgentSit :P 2210 // which happens in HandleAgentSit :P
1945 m_autopilotMoving = autopilot; 2211 m_autopilotMoving = autopilot;
1946 m_autoPilotTarget = pos; 2212 m_autoPilotTarget = autopilotTarget;
1947 m_sitAtAutoTarget = autopilot; 2213 m_sitAtAutoTarget = autopilot;
2214 m_initialSitTarget = autopilotTarget;
1948 if (!autopilot) 2215 if (!autopilot)
1949 HandleAgentSit(remoteClient, UUID); 2216 HandleAgentSit(remoteClient, UUID);
1950 } 2217 }
@@ -2209,47 +2476,130 @@ namespace OpenSim.Region.Framework.Scenes
2209 { 2476 {
2210 if (part != null) 2477 if (part != null)
2211 { 2478 {
2479//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2212 if (part.GetAvatarOnSitTarget() == UUID) 2480 if (part.GetAvatarOnSitTarget() == UUID)
2213 { 2481 {
2482//Console.WriteLine("Scripted Sit");
2483 // Scripted sit
2214 Vector3 sitTargetPos = part.SitTargetPosition; 2484 Vector3 sitTargetPos = part.SitTargetPosition;
2215 Quaternion sitTargetOrient = part.SitTargetOrientation; 2485 Quaternion sitTargetOrient = part.SitTargetOrientation;
2216
2217 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2218 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2219
2220 //Quaternion result = (sitTargetOrient * vq) * nq;
2221
2222 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2486 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2223 m_pos += SIT_TARGET_ADJUSTMENT; 2487 m_pos += SIT_TARGET_ADJUSTMENT;
2488 if (!part.IsRoot)
2489 {
2490 m_pos *= part.RotationOffset;
2491 }
2224 m_bodyRot = sitTargetOrient; 2492 m_bodyRot = sitTargetOrient;
2225 //Rotation = sitTargetOrient;
2226 m_parentPosition = part.AbsolutePosition; 2493 m_parentPosition = part.AbsolutePosition;
2227 2494 part.IsOccupied = true;
2228 //SendTerseUpdateToAllClients(); 2495 part.ParentGroup.AddAvatar(agentID);
2229 } 2496 }
2230 else 2497 else
2231 { 2498 {
2232 m_pos -= part.AbsolutePosition; 2499 // if m_avUnscriptedSitPos is zero then Av sits above center
2500 // Else Av sits at m_avUnscriptedSitPos
2501
2502 // Non-scripted sit by Kitto Flora 21Nov09
2503 // Calculate angle of line from prim to Av
2504 Quaternion partIRot;
2505// if (part.LinkNum == 1)
2506// { // Root prim of linkset
2507// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2508// }
2509// else
2510// { // single or child prim
2511 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2512// }
2513 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2514 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2515 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2516 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2517 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2518 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2519 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2520 // Av sits at world euler <0,0, z>, translated by part rotation
2521 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2522
2233 m_parentPosition = part.AbsolutePosition; 2523 m_parentPosition = part.AbsolutePosition;
2234 } 2524 part.IsOccupied = true;
2525 part.ParentGroup.AddAvatar(agentID);
2526 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2527 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2528 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2529 m_avUnscriptedSitPos; // adds click offset, if any
2530 //Set up raytrace to find top surface of prim
2531 Vector3 size = part.Scale;
2532 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2533 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2534 Vector3 down = new Vector3(0f, 0f, -1f);
2535//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2536 m_scene.PhysicsScene.RaycastWorld(
2537 start, // Vector3 position,
2538 down, // Vector3 direction,
2539 mag, // float length,
2540 SitAltitudeCallback); // retMethod
2541 } // end scripted/not
2235 } 2542 }
2236 else 2543 else // no Av
2237 { 2544 {
2238 return; 2545 return;
2239 } 2546 }
2240 } 2547 }
2241 m_parentID = m_requestedSitTargetID;
2242 2548
2549 //We want our offsets to reference the root prim, not the child we may have sat on
2550 if (!part.IsRoot)
2551 {
2552 m_parentID = part.ParentGroup.RootPart.LocalId;
2553 m_pos += part.OffsetPosition;
2554 }
2555 else
2556 {
2557 m_parentID = m_requestedSitTargetID;
2558 }
2559
2560 m_linkedPrim = part.UUID;
2561 if (part.GetAvatarOnSitTarget() != UUID)
2562 {
2563 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2564 }
2243 Velocity = Vector3.Zero; 2565 Velocity = Vector3.Zero;
2244 RemoveFromPhysicalScene(); 2566 RemoveFromPhysicalScene();
2245
2246 Animator.TrySetMovementAnimation(sitAnimation); 2567 Animator.TrySetMovementAnimation(sitAnimation);
2247 SendAvatarDataToAllAgents(); 2568 SendAvatarDataToAllAgents();
2248 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2249 // So we're also sending a terse update (which has avatar rotation)
2250 // [Update] We do now.
2251 //SendTerseUpdateToAllClients(); 2569 //SendTerseUpdateToAllClients();
2252 } 2570 }
2571
2572 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2573 {
2574 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2575 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2576 if(hitYN)
2577 {
2578 // m_pos = Av offset from prim center to make look like on center
2579 // m_parentPosition = Actual center pos of prim
2580 // collisionPoint = spot on prim where we want to sit
2581 // collisionPoint.Z = global sit surface height
2582 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2583 Quaternion partIRot;
2584// if (part.LinkNum == 1)
2585/// { // Root prim of linkset
2586// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2587// }
2588// else
2589// { // single or child prim
2590 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2591// }
2592 if (m_initialSitTarget != null)
2593 {
2594 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2595 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2596 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2597 m_pos += offset;
2598 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2599 }
2600
2601 }
2602 } // End SitAltitudeCallback KF.
2253 2603
2254 /// <summary> 2604 /// <summary>
2255 /// Event handler for the 'Always run' setting on the client 2605 /// Event handler for the 'Always run' setting on the client
@@ -2369,6 +2719,9 @@ namespace OpenSim.Region.Framework.Scenes
2369 2719
2370 CheckForSignificantMovement(); // sends update to the modules. 2720 CheckForSignificantMovement(); // sends update to the modules.
2371 } 2721 }
2722
2723 //Sending prim updates AFTER the avatar terse updates are sent
2724 SendPrimUpdates();
2372 } 2725 }
2373 2726
2374 #endregion 2727 #endregion
@@ -3178,6 +3531,7 @@ namespace OpenSim.Region.Framework.Scenes
3178 m_callbackURI = cAgent.CallbackURI; 3531 m_callbackURI = cAgent.CallbackURI;
3179 3532
3180 m_pos = cAgent.Position; 3533 m_pos = cAgent.Position;
3534
3181 m_velocity = cAgent.Velocity; 3535 m_velocity = cAgent.Velocity;
3182 m_CameraCenter = cAgent.Center; 3536 m_CameraCenter = cAgent.Center;
3183 m_CameraAtAxis = cAgent.AtAxis; 3537 m_CameraAtAxis = cAgent.AtAxis;
@@ -3290,10 +3644,8 @@ namespace OpenSim.Region.Framework.Scenes
3290 3644
3291 Vector3 pVec = AbsolutePosition; 3645 Vector3 pVec = AbsolutePosition;
3292 3646
3293 // Old bug where the height was in centimeters instead of meters 3647 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3294 m_physicsActor = scene.AddAvatar(LocalId, Firstname + "." + Lastname, pVec,
3295 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3648 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3296
3297 scene.AddPhysicsActorTaint(m_physicsActor); 3649 scene.AddPhysicsActorTaint(m_physicsActor);
3298 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3650 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3299 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3651 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3319,18 +3671,29 @@ namespace OpenSim.Region.Framework.Scenes
3319 { 3671 {
3320 if (e == null) 3672 if (e == null)
3321 return; 3673 return;
3322 3674
3323 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3675 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3324 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3325 // as of this comment the interval is set in AddToPhysicalScene 3676 // as of this comment the interval is set in AddToPhysicalScene
3326 if (Animator!=null) 3677 if (Animator!=null)
3327 Animator.UpdateMovementAnimations(); 3678 {
3679 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3680 { // else its will lock out other animation changes, like ground sit.
3681 Animator.UpdateMovementAnimations();
3682 m_updateCount--;
3683 }
3684 }
3328 3685
3329 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3686 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3330 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3687 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3331 3688
3332 CollisionPlane = Vector4.UnitW; 3689 CollisionPlane = Vector4.UnitW;
3333 3690
3691 if (m_lastColCount != coldata.Count)
3692 {
3693 m_updateCount = UPDATE_COUNT;
3694 m_lastColCount = coldata.Count;
3695 }
3696
3334 if (coldata.Count != 0 && Animator != null) 3697 if (coldata.Count != 0 && Animator != null)
3335 { 3698 {
3336 switch (Animator.CurrentMovementAnimation) 3699 switch (Animator.CurrentMovementAnimation)
@@ -3360,6 +3723,148 @@ namespace OpenSim.Region.Framework.Scenes
3360 } 3723 }
3361 } 3724 }
3362 3725
3726 List<uint> thisHitColliders = new List<uint>();
3727 List<uint> endedColliders = new List<uint>();
3728 List<uint> startedColliders = new List<uint>();
3729
3730 foreach (uint localid in coldata.Keys)
3731 {
3732 thisHitColliders.Add(localid);
3733 if (!m_lastColliders.Contains(localid))
3734 {
3735 startedColliders.Add(localid);
3736 }
3737 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3738 }
3739
3740 // calculate things that ended colliding
3741 foreach (uint localID in m_lastColliders)
3742 {
3743 if (!thisHitColliders.Contains(localID))
3744 {
3745 endedColliders.Add(localID);
3746 }
3747 }
3748 //add the items that started colliding this time to the last colliders list.
3749 foreach (uint localID in startedColliders)
3750 {
3751 m_lastColliders.Add(localID);
3752 }
3753 // remove things that ended colliding from the last colliders list
3754 foreach (uint localID in endedColliders)
3755 {
3756 m_lastColliders.Remove(localID);
3757 }
3758
3759 // do event notification
3760 if (startedColliders.Count > 0)
3761 {
3762 ColliderArgs StartCollidingMessage = new ColliderArgs();
3763 List<DetectedObject> colliding = new List<DetectedObject>();
3764 foreach (uint localId in startedColliders)
3765 {
3766 if (localId == 0)
3767 continue;
3768
3769 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3770 string data = "";
3771 if (obj != null)
3772 {
3773 DetectedObject detobj = new DetectedObject();
3774 detobj.keyUUID = obj.UUID;
3775 detobj.nameStr = obj.Name;
3776 detobj.ownerUUID = obj.OwnerID;
3777 detobj.posVector = obj.AbsolutePosition;
3778 detobj.rotQuat = obj.GetWorldRotation();
3779 detobj.velVector = obj.Velocity;
3780 detobj.colliderType = 0;
3781 detobj.groupUUID = obj.GroupID;
3782 colliding.Add(detobj);
3783 }
3784 }
3785
3786 if (colliding.Count > 0)
3787 {
3788 StartCollidingMessage.Colliders = colliding;
3789
3790 foreach (SceneObjectGroup att in GetAttachments())
3791 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3792 }
3793 }
3794
3795 if (endedColliders.Count > 0)
3796 {
3797 ColliderArgs EndCollidingMessage = new ColliderArgs();
3798 List<DetectedObject> colliding = new List<DetectedObject>();
3799 foreach (uint localId in endedColliders)
3800 {
3801 if (localId == 0)
3802 continue;
3803
3804 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3805 string data = "";
3806 if (obj != null)
3807 {
3808 DetectedObject detobj = new DetectedObject();
3809 detobj.keyUUID = obj.UUID;
3810 detobj.nameStr = obj.Name;
3811 detobj.ownerUUID = obj.OwnerID;
3812 detobj.posVector = obj.AbsolutePosition;
3813 detobj.rotQuat = obj.GetWorldRotation();
3814 detobj.velVector = obj.Velocity;
3815 detobj.colliderType = 0;
3816 detobj.groupUUID = obj.GroupID;
3817 colliding.Add(detobj);
3818 }
3819 }
3820
3821 if (colliding.Count > 0)
3822 {
3823 EndCollidingMessage.Colliders = colliding;
3824
3825 foreach (SceneObjectGroup att in GetAttachments())
3826 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3827 }
3828 }
3829
3830 if (thisHitColliders.Count > 0)
3831 {
3832 ColliderArgs CollidingMessage = new ColliderArgs();
3833 List<DetectedObject> colliding = new List<DetectedObject>();
3834 foreach (uint localId in thisHitColliders)
3835 {
3836 if (localId == 0)
3837 continue;
3838
3839 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3840 string data = "";
3841 if (obj != null)
3842 {
3843 DetectedObject detobj = new DetectedObject();
3844 detobj.keyUUID = obj.UUID;
3845 detobj.nameStr = obj.Name;
3846 detobj.ownerUUID = obj.OwnerID;
3847 detobj.posVector = obj.AbsolutePosition;
3848 detobj.rotQuat = obj.GetWorldRotation();
3849 detobj.velVector = obj.Velocity;
3850 detobj.colliderType = 0;
3851 detobj.groupUUID = obj.GroupID;
3852 colliding.Add(detobj);
3853 }
3854 }
3855
3856 if (colliding.Count > 0)
3857 {
3858 CollidingMessage.Colliders = colliding;
3859
3860 lock (m_attachments)
3861 {
3862 foreach (SceneObjectGroup att in m_attachments)
3863 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3864 }
3865 }
3866 }
3867
3363 if (m_invulnerable) 3868 if (m_invulnerable)
3364 return; 3869 return;
3365 3870
@@ -3433,6 +3938,10 @@ namespace OpenSim.Region.Framework.Scenes
3433 { 3938 {
3434 lock (m_attachments) 3939 lock (m_attachments)
3435 { 3940 {
3941 // This may be true when the attachment comes back
3942 // from serialization after login. Clear it.
3943 gobj.IsDeleted = false;
3944
3436 m_attachments.Add(gobj); 3945 m_attachments.Add(gobj);
3437 } 3946 }
3438 } 3947 }
@@ -3796,5 +4305,39 @@ namespace OpenSim.Region.Framework.Scenes
3796 m_reprioritization_called = false; 4305 m_reprioritization_called = false;
3797 } 4306 }
3798 } 4307 }
4308
4309 private Vector3 Quat2Euler(Quaternion rot){
4310 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4311 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4312 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4313 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4314 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4315 return(new Vector3(x,y,z));
4316 }
4317
4318 private void CheckLandingPoint(ref Vector3 pos)
4319 {
4320 // Never constrain lures
4321 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4322 return;
4323
4324 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4325 return;
4326
4327 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4328
4329 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4330 land.LandData.UserLocation != Vector3.Zero &&
4331 land.LandData.OwnerID != m_uuid &&
4332 (!m_scene.Permissions.IsGod(m_uuid)) &&
4333 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4334 {
4335 float curr = Vector3.Distance(AbsolutePosition, pos);
4336 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4337 pos = land.LandData.UserLocation;
4338 else
4339 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4340 }
4341 }
3799 } 4342 }
3800} \ No newline at end of file 4343} \ No newline at end of file