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