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 f049b78..35f5566 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
@@ -892,6 +974,62 @@ namespace OpenSim.Region.Framework.Scenes
892 pos.Y = crossedBorder.BorderLine.Z - 1; 974 pos.Y = crossedBorder.BorderLine.Z - 1;
893 } 975 }
894 976
977 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
978 if (land != null)
979 {
980 // If we come in via login, landmark or map, we want to
981 // honor landing points. If we come in via Lure, we want
982 // to ignore them.
983 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
984 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
985 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
986 {
987 // Don't restrict gods, estate managers, or land owners to
988 // the TP point. This behaviour mimics agni.
989 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
990 land.LandData.UserLocation != Vector3.Zero &&
991 GodLevel < 200 &&
992 ((land.LandData.OwnerID != m_uuid &&
993 (!m_scene.Permissions.IsGod(m_uuid)) &&
994 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
995 {
996 pos = land.LandData.UserLocation;
997 }
998 }
999
1000 land.SendLandUpdateToClient(ControllingClient);
1001 }
1002
1003 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
1004 {
1005 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
1006
1007 if (pos.X < 0)
1008 {
1009 emergencyPos.X = (int)Constants.RegionSize + pos.X;
1010 if (!(pos.Y < 0))
1011 emergencyPos.Y = pos.Y;
1012 if (!(pos.Z < 0))
1013 emergencyPos.Z = pos.Z;
1014 }
1015 if (pos.Y < 0)
1016 {
1017 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
1018 if (!(pos.X < 0))
1019 emergencyPos.X = pos.X;
1020 if (!(pos.Z < 0))
1021 emergencyPos.Z = pos.Z;
1022 }
1023 if (pos.Z < 0)
1024 {
1025 emergencyPos.Z = 128;
1026 if (!(pos.Y < 0))
1027 emergencyPos.Y = pos.Y;
1028 if (!(pos.X < 0))
1029 emergencyPos.X = pos.X;
1030 }
1031 }
1032
895 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1033 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
896 { 1034 {
897 m_log.WarnFormat( 1035 m_log.WarnFormat(
@@ -1024,16 +1162,21 @@ namespace OpenSim.Region.Framework.Scenes
1024 /// <summary> 1162 /// <summary>
1025 /// Removes physics plugin scene representation of this agent if it exists. 1163 /// Removes physics plugin scene representation of this agent if it exists.
1026 /// </summary> 1164 /// </summary>
1027 private void RemoveFromPhysicalScene() 1165 public void RemoveFromPhysicalScene()
1028 { 1166 {
1029 if (PhysicsActor != null) 1167 if (PhysicsActor != null)
1030 { 1168 {
1031 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1169 try
1032 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1170 {
1033 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1171 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1034 m_physicsActor.UnSubscribeEvents(); 1172 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1035 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1173 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1036 PhysicsActor = null; 1174 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1175 m_physicsActor.UnSubscribeEvents();
1176 PhysicsActor = null;
1177 }
1178 catch
1179 { }
1037 } 1180 }
1038 } 1181 }
1039 1182
@@ -1044,15 +1187,18 @@ namespace OpenSim.Region.Framework.Scenes
1044 public void Teleport(Vector3 pos) 1187 public void Teleport(Vector3 pos)
1045 { 1188 {
1046 bool isFlying = false; 1189 bool isFlying = false;
1190
1047 if (m_physicsActor != null) 1191 if (m_physicsActor != null)
1048 isFlying = m_physicsActor.Flying; 1192 isFlying = m_physicsActor.Flying;
1049 1193
1050 RemoveFromPhysicalScene(); 1194 RemoveFromPhysicalScene();
1051 Velocity = Vector3.Zero; 1195 Velocity = Vector3.Zero;
1196 CheckLandingPoint(ref pos);
1052 AbsolutePosition = pos; 1197 AbsolutePosition = pos;
1053 AddToPhysicalScene(isFlying); 1198 AddToPhysicalScene(isFlying);
1054 1199
1055 SendTerseUpdateToAllClients(); 1200 SendTerseUpdateToAllClients();
1201
1056 } 1202 }
1057 1203
1058 public void TeleportWithMomentum(Vector3 pos) 1204 public void TeleportWithMomentum(Vector3 pos)
@@ -1062,6 +1208,7 @@ namespace OpenSim.Region.Framework.Scenes
1062 isFlying = m_physicsActor.Flying; 1208 isFlying = m_physicsActor.Flying;
1063 1209
1064 RemoveFromPhysicalScene(); 1210 RemoveFromPhysicalScene();
1211 CheckLandingPoint(ref pos);
1065 AbsolutePosition = pos; 1212 AbsolutePosition = pos;
1066 AddToPhysicalScene(isFlying); 1213 AddToPhysicalScene(isFlying);
1067 1214
@@ -1237,11 +1384,12 @@ namespace OpenSim.Region.Framework.Scenes
1237 /// <summary> 1384 /// <summary>
1238 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1385 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1239 /// </summary> 1386 /// </summary>
1387 /// <summary>
1388 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1389 /// </summary>
1240 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1390 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1241 { 1391 {
1242// m_log.DebugFormat( 1392 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1243// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1244// Scene.RegionInfo.RegionName, remoteClient.Name);
1245 1393
1246 //if (m_isChildAgent) 1394 //if (m_isChildAgent)
1247 //{ 1395 //{
@@ -1437,12 +1585,12 @@ namespace OpenSim.Region.Framework.Scenes
1437 1585
1438 if ((m_movementflag & (byte)(uint)DCF) == 0) 1586 if ((m_movementflag & (byte)(uint)DCF) == 0)
1439 { 1587 {
1440 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1588 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1441 { 1589 {
1442 m_movementflag |= (byte)nudgehack; 1590 m_movementflag |= (byte)nudgehack;
1443 } 1591 }
1444 1592
1445// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF); 1593 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF);
1446 m_movementflag += (byte)(uint)DCF; 1594 m_movementflag += (byte)(uint)DCF;
1447 update_movementflag = true; 1595 update_movementflag = true;
1448 } 1596 }
@@ -1450,11 +1598,11 @@ namespace OpenSim.Region.Framework.Scenes
1450 else 1598 else
1451 { 1599 {
1452 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1600 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1453 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1601 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1454 && ((m_movementflag & (byte)nudgehack) == nudgehack)) 1602 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1455 ) // This or is for Nudge forward 1603 ) // This or is for Nudge forward
1456 { 1604 {
1457// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF); 1605 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1458 m_movementflag -= ((byte)(uint)DCF); 1606 m_movementflag -= ((byte)(uint)DCF);
1459 update_movementflag = true; 1607 update_movementflag = true;
1460 1608
@@ -1519,21 +1667,21 @@ namespace OpenSim.Region.Framework.Scenes
1519 // which occurs later in the main scene loop 1667 // which occurs later in the main scene loop
1520 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1668 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1521 { 1669 {
1522// m_log.DebugFormat( 1670 // m_log.DebugFormat(
1523// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1671 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1524// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1672 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1525 1673
1526 AddNewMovement(agent_control_v3); 1674 AddNewMovement(agent_control_v3);
1527 } 1675 }
1528// else 1676 // else
1529// { 1677 // {
1530// if (!update_movementflag) 1678 // if (!update_movementflag)
1531// { 1679 // {
1532// m_log.DebugFormat( 1680 // m_log.DebugFormat(
1533// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1681 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1534// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1682 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1535// } 1683 // }
1536// } 1684 // }
1537 1685
1538 if (update_movementflag && m_parentID == 0) 1686 if (update_movementflag && m_parentID == 0)
1539 Animator.UpdateMovementAnimations(); 1687 Animator.UpdateMovementAnimations();
@@ -1555,20 +1703,20 @@ namespace OpenSim.Region.Framework.Scenes
1555 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1703 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1556 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1704 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1557 { 1705 {
1558// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1706 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1559 1707
1560 bool updated = false; 1708 bool updated = false;
1561 1709
1562// m_log.DebugFormat( 1710 // m_log.DebugFormat(
1563// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1711 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1564// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1712 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1565 1713
1566 if (!m_autopilotMoving) 1714 if (!m_autopilotMoving)
1567 { 1715 {
1568 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1716 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1569// m_log.DebugFormat( 1717 // m_log.DebugFormat(
1570// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1718 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1571// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1719 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1572 1720
1573 // Check the error term of the current position in relation to the target position 1721 // Check the error term of the current position in relation to the target position
1574 if (distanceToTarget <= 1) 1722 if (distanceToTarget <= 1)
@@ -1591,7 +1739,7 @@ namespace OpenSim.Region.Framework.Scenes
1591 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1739 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1592 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1740 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1593 // Ignore z component of vector 1741 // Ignore z component of vector
1594// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1742 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1595 LocalVectorToTarget3D.Normalize(); 1743 LocalVectorToTarget3D.Normalize();
1596 1744
1597 // update avatar movement flags. the avatar coordinate system is as follows: 1745 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1657,9 +1805,9 @@ namespace OpenSim.Region.Framework.Scenes
1657 updated = true; 1805 updated = true;
1658 } 1806 }
1659 1807
1660// m_log.DebugFormat( 1808 // m_log.DebugFormat(
1661// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1809 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1662// LocalVectorToTarget3D, agent_control_v3, Name); 1810 // LocalVectorToTarget3D, agent_control_v3, Name);
1663 1811
1664 agent_control_v3 += LocalVectorToTarget3D; 1812 agent_control_v3 += LocalVectorToTarget3D;
1665 } 1813 }
@@ -1780,7 +1928,7 @@ namespace OpenSim.Region.Framework.Scenes
1780 Velocity = Vector3.Zero; 1928 Velocity = Vector3.Zero;
1781 SendAvatarDataToAllAgents(); 1929 SendAvatarDataToAllAgents();
1782 1930
1783 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1931 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1784 } 1932 }
1785 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1933 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1786 m_requestedSitTargetUUID = UUID.Zero; 1934 m_requestedSitTargetUUID = UUID.Zero;
@@ -1817,25 +1965,22 @@ namespace OpenSim.Region.Framework.Scenes
1817 1965
1818 if (m_parentID != 0) 1966 if (m_parentID != 0)
1819 { 1967 {
1820 m_log.Debug("StandupCode Executed"); 1968 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1821 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1822 if (part != null) 1969 if (part != null)
1823 { 1970 {
1971 part.TaskInventory.LockItemsForRead(true);
1824 TaskInventoryDictionary taskIDict = part.TaskInventory; 1972 TaskInventoryDictionary taskIDict = part.TaskInventory;
1825 if (taskIDict != null) 1973 if (taskIDict != null)
1826 { 1974 {
1827 lock (taskIDict) 1975 foreach (UUID taskID in taskIDict.Keys)
1828 { 1976 {
1829 foreach (UUID taskID in taskIDict.Keys) 1977 UnRegisterControlEventsToScript(LocalId, taskID);
1830 { 1978 taskIDict[taskID].PermsMask &= ~(
1831 UnRegisterControlEventsToScript(LocalId, taskID); 1979 2048 | //PERMISSION_CONTROL_CAMERA
1832 taskIDict[taskID].PermsMask &= ~( 1980 4); // PERMISSION_TAKE_CONTROLS
1833 2048 | //PERMISSION_CONTROL_CAMERA
1834 4); // PERMISSION_TAKE_CONTROLS
1835 }
1836 } 1981 }
1837
1838 } 1982 }
1983 part.TaskInventory.LockItemsForRead(false);
1839 // Reset sit target. 1984 // Reset sit target.
1840 if (part.GetAvatarOnSitTarget() == UUID) 1985 if (part.GetAvatarOnSitTarget() == UUID)
1841 part.SitTargetAvatar = UUID.Zero; 1986 part.SitTargetAvatar = UUID.Zero;
@@ -1844,20 +1989,58 @@ namespace OpenSim.Region.Framework.Scenes
1844 m_parentPosition = part.GetWorldPosition(); 1989 m_parentPosition = part.GetWorldPosition();
1845 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1990 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1846 } 1991 }
1992 // part.GetWorldRotation() is the rotation of the object being sat on
1993 // Rotation is the sittiing Av's rotation
1994
1995 Quaternion partRot;
1996// if (part.LinkNum == 1)
1997// { // Root prim of linkset
1998// partRot = part.ParentGroup.RootPart.RotationOffset;
1999// }
2000// else
2001// { // single or child prim
2002
2003// }
2004 if (part == null) //CW: Part may be gone. llDie() for example.
2005 {
2006 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
2007 }
2008 else
2009 {
2010 partRot = part.GetWorldRotation();
2011 }
2012
2013 Quaternion partIRot = Quaternion.Inverse(partRot);
1847 2014
2015 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
2016 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
2017
2018
1848 if (m_physicsActor == null) 2019 if (m_physicsActor == null)
1849 { 2020 {
1850 AddToPhysicalScene(false); 2021 AddToPhysicalScene(false);
1851 } 2022 }
1852 2023 //CW: If the part isn't null then we can set the current position
1853 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2024 if (part != null)
1854 m_parentPosition = Vector3.Zero; 2025 {
1855 2026 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1856 m_parentID = 0; 2027 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2028 part.IsOccupied = false;
2029 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2030 }
2031 else
2032 {
2033 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2034 AbsolutePosition = m_lastWorldPosition;
2035 }
2036
2037 m_parentPosition = Vector3.Zero;
2038 m_parentID = 0;
2039 m_linkedPrim = UUID.Zero;
2040 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1857 SendAvatarDataToAllAgents(); 2041 SendAvatarDataToAllAgents();
1858 m_requestedSitTargetID = 0; 2042 m_requestedSitTargetID = 0;
1859 } 2043 }
1860
1861 Animator.TrySetMovementAnimation("STAND"); 2044 Animator.TrySetMovementAnimation("STAND");
1862 } 2045 }
1863 2046
@@ -1888,13 +2071,9 @@ namespace OpenSim.Region.Framework.Scenes
1888 Vector3 avSitOffSet = part.SitTargetPosition; 2071 Vector3 avSitOffSet = part.SitTargetPosition;
1889 Quaternion avSitOrientation = part.SitTargetOrientation; 2072 Quaternion avSitOrientation = part.SitTargetOrientation;
1890 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2073 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1891 2074 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1892 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2075 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1893 bool SitTargetisSet = 2076 if (SitTargetisSet && !SitTargetOccupied)
1894 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1895 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1896
1897 if (SitTargetisSet && SitTargetUnOccupied)
1898 { 2077 {
1899 //switch the target to this prim 2078 //switch the target to this prim
1900 return part; 2079 return part;
@@ -1908,85 +2087,168 @@ namespace OpenSim.Region.Framework.Scenes
1908 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2087 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1909 { 2088 {
1910 bool autopilot = true; 2089 bool autopilot = true;
2090 Vector3 autopilotTarget = new Vector3();
2091 Quaternion sitOrientation = Quaternion.Identity;
1911 Vector3 pos = new Vector3(); 2092 Vector3 pos = new Vector3();
1912 Quaternion sitOrientation = pSitOrientation;
1913 Vector3 cameraEyeOffset = Vector3.Zero; 2093 Vector3 cameraEyeOffset = Vector3.Zero;
1914 Vector3 cameraAtOffset = Vector3.Zero; 2094 Vector3 cameraAtOffset = Vector3.Zero;
1915 bool forceMouselook = false; 2095 bool forceMouselook = false;
1916 2096
1917 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2097 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1918 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2098 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1919 if (part != null) 2099 if (part == null) return;
2100
2101 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2102 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2103
2104 // part is the prim to sit on
2105 // offset is the world-ref vector distance from that prim center to the click-spot
2106 // UUID is the UUID of the Avatar doing the clicking
2107
2108 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2109
2110 // Is a sit target available?
2111 Vector3 avSitOffSet = part.SitTargetPosition;
2112 Quaternion avSitOrientation = part.SitTargetOrientation;
2113
2114 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2115 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2116 Quaternion partRot;
2117// if (part.LinkNum == 1)
2118// { // Root prim of linkset
2119// partRot = part.ParentGroup.RootPart.RotationOffset;
2120// }
2121// else
2122// { // single or child prim
2123 partRot = part.GetWorldRotation();
2124// }
2125 Quaternion partIRot = Quaternion.Inverse(partRot);
2126//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2127 // Sit analysis rewritten by KF 091125
2128 if (SitTargetisSet) // scipted sit
1920 { 2129 {
1921 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2130 if (!part.IsOccupied)
1922 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2131 {
1923 2132//Console.WriteLine("Scripted, unoccupied");
1924 // Is a sit target available? 2133 part.SitTargetAvatar = UUID; // set that Av will be on it
1925 Vector3 avSitOffSet = part.SitTargetPosition; 2134 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1926 Quaternion avSitOrientation = part.SitTargetOrientation; 2135
1927 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2136 Quaternion nrot = avSitOrientation;
1928 2137 if (!part.IsRoot)
1929 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1930 bool SitTargetisSet =
1931 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1932 (
1933 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1934 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1935 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1936 )
1937 ));
1938
1939 if (SitTargetisSet && SitTargetUnOccupied)
1940 {
1941 part.SitTargetAvatar = UUID;
1942 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1943 sitOrientation = avSitOrientation;
1944 autopilot = false;
1945 }
1946 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1947
1948 pos = part.AbsolutePosition + offset;
1949 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1950 //{
1951 // offset = pos;
1952 //autopilot = false;
1953 //}
1954 if (m_physicsActor != null)
1955 {
1956 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1957 // We can remove the physicsActor until they stand up.
1958 m_sitAvatarHeight = m_physicsActor.Size.Z;
1959
1960 if (autopilot)
1961 { 2138 {
1962 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2139 nrot = part.RotationOffset * avSitOrientation;
1963 {
1964 autopilot = false;
1965
1966 RemoveFromPhysicalScene();
1967 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1968 }
1969 } 2140 }
1970 else 2141 sitOrientation = nrot; // Change rotatione to the scripted one
2142 OffsetRotation = nrot;
2143 autopilot = false; // Jump direct to scripted llSitPos()
2144 }
2145 else
2146 {
2147//Console.WriteLine("Scripted, occupied");
2148 return;
2149 }
2150 }
2151 else // Not Scripted
2152 {
2153 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
2154 {
2155 // large prim & offset, ignore if other Avs sitting
2156// offset.Z -= 0.05f;
2157 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2158 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2159
2160//Console.WriteLine(" offset ={0}", offset);
2161//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2162//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2163
2164 }
2165 else // small offset
2166 {
2167//Console.WriteLine("Small offset");
2168 if (!part.IsOccupied)
2169 {
2170 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2171 autopilotTarget = part.AbsolutePosition;
2172//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2173 }
2174 else return; // occupied small
2175 } // end large/small
2176 } // end Scripted/not
2177
2178 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2179
2180 cameraAtOffset = part.GetCameraAtOffset();
2181 cameraEyeOffset = part.GetCameraEyeOffset();
2182 forceMouselook = part.GetForceMouselook();
2183 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2184 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2185
2186 if (m_physicsActor != null)
2187 {
2188 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2189 // We can remove the physicsActor until they stand up.
2190 m_sitAvatarHeight = m_physicsActor.Size.Z;
2191 if (autopilot)
2192 { // its not a scripted sit
2193// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2194 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1971 { 2195 {
2196 autopilot = false; // close enough
2197 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2198 Not using the part's position because returning the AV to the last known standing
2199 position is likely to be more friendly, isn't it? */
1972 RemoveFromPhysicalScene(); 2200 RemoveFromPhysicalScene();
1973 } 2201 Velocity = Vector3.Zero;
2202 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2203 } // else the autopilot will get us close
2204 }
2205 else
2206 { // its a scripted sit
2207 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2208 I *am* using the part's position this time because we have no real idea how far away
2209 the avatar is from the sit target. */
2210 RemoveFromPhysicalScene();
2211 Velocity = Vector3.Zero;
1974 } 2212 }
1975
1976 cameraAtOffset = part.GetCameraAtOffset();
1977 cameraEyeOffset = part.GetCameraEyeOffset();
1978 forceMouselook = part.GetForceMouselook();
1979 } 2213 }
1980 2214 else return; // physactor is null!
1981 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2215
1982 m_requestedSitTargetUUID = targetID; 2216 Vector3 offsetr; // = offset * partIRot;
2217 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2218 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2219 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2220 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2221 //offsetr = offset * partIRot;
2222//
2223 // }
2224 // else
2225 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2226 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2227 // (offset * partRot);
2228 // }
2229
2230//Console.WriteLine(" ");
2231//Console.WriteLine("link number ={0}", part.LinkNum);
2232//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2233//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2234//Console.WriteLine("Click offst ={0}", offset);
2235//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2236//Console.WriteLine("offsetr ={0}", offsetr);
2237//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2238//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2239
2240 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2241 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2242
2243 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1983 // This calls HandleAgentSit twice, once from here, and the client calls 2244 // This calls HandleAgentSit twice, once from here, and the client calls
1984 // HandleAgentSit itself after it gets to the location 2245 // HandleAgentSit itself after it gets to the location
1985 // It doesn't get to the location until we've moved them there though 2246 // It doesn't get to the location until we've moved them there though
1986 // which happens in HandleAgentSit :P 2247 // which happens in HandleAgentSit :P
1987 m_autopilotMoving = autopilot; 2248 m_autopilotMoving = autopilot;
1988 m_autoPilotTarget = pos; 2249 m_autoPilotTarget = autopilotTarget;
1989 m_sitAtAutoTarget = autopilot; 2250 m_sitAtAutoTarget = autopilot;
2251 m_initialSitTarget = autopilotTarget;
1990 if (!autopilot) 2252 if (!autopilot)
1991 HandleAgentSit(remoteClient, UUID); 2253 HandleAgentSit(remoteClient, UUID);
1992 } 2254 }
@@ -2251,47 +2513,130 @@ namespace OpenSim.Region.Framework.Scenes
2251 { 2513 {
2252 if (part != null) 2514 if (part != null)
2253 { 2515 {
2516//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2254 if (part.GetAvatarOnSitTarget() == UUID) 2517 if (part.GetAvatarOnSitTarget() == UUID)
2255 { 2518 {
2519//Console.WriteLine("Scripted Sit");
2520 // Scripted sit
2256 Vector3 sitTargetPos = part.SitTargetPosition; 2521 Vector3 sitTargetPos = part.SitTargetPosition;
2257 Quaternion sitTargetOrient = part.SitTargetOrientation; 2522 Quaternion sitTargetOrient = part.SitTargetOrientation;
2258
2259 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2260 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2261
2262 //Quaternion result = (sitTargetOrient * vq) * nq;
2263
2264 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2523 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2265 m_pos += SIT_TARGET_ADJUSTMENT; 2524 m_pos += SIT_TARGET_ADJUSTMENT;
2525 if (!part.IsRoot)
2526 {
2527 m_pos *= part.RotationOffset;
2528 }
2266 m_bodyRot = sitTargetOrient; 2529 m_bodyRot = sitTargetOrient;
2267 //Rotation = sitTargetOrient;
2268 m_parentPosition = part.AbsolutePosition; 2530 m_parentPosition = part.AbsolutePosition;
2269 2531 part.IsOccupied = true;
2270 //SendTerseUpdateToAllClients(); 2532 part.ParentGroup.AddAvatar(agentID);
2271 } 2533 }
2272 else 2534 else
2273 { 2535 {
2274 m_pos -= part.AbsolutePosition; 2536 // if m_avUnscriptedSitPos is zero then Av sits above center
2537 // Else Av sits at m_avUnscriptedSitPos
2538
2539 // Non-scripted sit by Kitto Flora 21Nov09
2540 // Calculate angle of line from prim to Av
2541 Quaternion partIRot;
2542// if (part.LinkNum == 1)
2543// { // Root prim of linkset
2544// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2545// }
2546// else
2547// { // single or child prim
2548 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2549// }
2550 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2551 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2552 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2553 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2554 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2555 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2556 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2557 // Av sits at world euler <0,0, z>, translated by part rotation
2558 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2559
2275 m_parentPosition = part.AbsolutePosition; 2560 m_parentPosition = part.AbsolutePosition;
2276 } 2561 part.IsOccupied = true;
2562 part.ParentGroup.AddAvatar(agentID);
2563 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2564 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2565 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2566 m_avUnscriptedSitPos; // adds click offset, if any
2567 //Set up raytrace to find top surface of prim
2568 Vector3 size = part.Scale;
2569 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2570 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2571 Vector3 down = new Vector3(0f, 0f, -1f);
2572//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2573 m_scene.PhysicsScene.RaycastWorld(
2574 start, // Vector3 position,
2575 down, // Vector3 direction,
2576 mag, // float length,
2577 SitAltitudeCallback); // retMethod
2578 } // end scripted/not
2277 } 2579 }
2278 else 2580 else // no Av
2279 { 2581 {
2280 return; 2582 return;
2281 } 2583 }
2282 } 2584 }
2283 m_parentID = m_requestedSitTargetID;
2284 2585
2586 //We want our offsets to reference the root prim, not the child we may have sat on
2587 if (!part.IsRoot)
2588 {
2589 m_parentID = part.ParentGroup.RootPart.LocalId;
2590 m_pos += part.OffsetPosition;
2591 }
2592 else
2593 {
2594 m_parentID = m_requestedSitTargetID;
2595 }
2596
2597 m_linkedPrim = part.UUID;
2598 if (part.GetAvatarOnSitTarget() != UUID)
2599 {
2600 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2601 }
2285 Velocity = Vector3.Zero; 2602 Velocity = Vector3.Zero;
2286 RemoveFromPhysicalScene(); 2603 RemoveFromPhysicalScene();
2287
2288 Animator.TrySetMovementAnimation(sitAnimation); 2604 Animator.TrySetMovementAnimation(sitAnimation);
2289 SendAvatarDataToAllAgents(); 2605 SendAvatarDataToAllAgents();
2290 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2291 // So we're also sending a terse update (which has avatar rotation)
2292 // [Update] We do now.
2293 //SendTerseUpdateToAllClients(); 2606 //SendTerseUpdateToAllClients();
2294 } 2607 }
2608
2609 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2610 {
2611 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2612 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2613 if(hitYN)
2614 {
2615 // m_pos = Av offset from prim center to make look like on center
2616 // m_parentPosition = Actual center pos of prim
2617 // collisionPoint = spot on prim where we want to sit
2618 // collisionPoint.Z = global sit surface height
2619 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2620 Quaternion partIRot;
2621// if (part.LinkNum == 1)
2622/// { // Root prim of linkset
2623// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2624// }
2625// else
2626// { // single or child prim
2627 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2628// }
2629 if (m_initialSitTarget != null)
2630 {
2631 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2632 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2633 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2634 m_pos += offset;
2635 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2636 }
2637
2638 }
2639 } // End SitAltitudeCallback KF.
2295 2640
2296 /// <summary> 2641 /// <summary>
2297 /// Event handler for the 'Always run' setting on the client 2642 /// Event handler for the 'Always run' setting on the client
@@ -2407,6 +2752,9 @@ namespace OpenSim.Region.Framework.Scenes
2407 2752
2408 CheckForSignificantMovement(); // sends update to the modules. 2753 CheckForSignificantMovement(); // sends update to the modules.
2409 } 2754 }
2755
2756 //Sending prim updates AFTER the avatar terse updates are sent
2757 SendPrimUpdates();
2410 } 2758 }
2411 2759
2412 #endregion 2760 #endregion
@@ -3201,6 +3549,7 @@ namespace OpenSim.Region.Framework.Scenes
3201 m_callbackURI = cAgent.CallbackURI; 3549 m_callbackURI = cAgent.CallbackURI;
3202 3550
3203 m_pos = cAgent.Position; 3551 m_pos = cAgent.Position;
3552
3204 m_velocity = cAgent.Velocity; 3553 m_velocity = cAgent.Velocity;
3205 m_CameraCenter = cAgent.Center; 3554 m_CameraCenter = cAgent.Center;
3206 m_CameraAtAxis = cAgent.AtAxis; 3555 m_CameraAtAxis = cAgent.AtAxis;
@@ -3317,10 +3666,8 @@ namespace OpenSim.Region.Framework.Scenes
3317 3666
3318 Vector3 pVec = AbsolutePosition; 3667 Vector3 pVec = AbsolutePosition;
3319 3668
3320 // Old bug where the height was in centimeters instead of meters 3669 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3321 m_physicsActor = scene.AddAvatar(LocalId, Firstname + "." + Lastname, pVec,
3322 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3670 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3323
3324 scene.AddPhysicsActorTaint(m_physicsActor); 3671 scene.AddPhysicsActorTaint(m_physicsActor);
3325 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3672 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3326 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3673 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3346,18 +3693,29 @@ namespace OpenSim.Region.Framework.Scenes
3346 { 3693 {
3347 if (e == null) 3694 if (e == null)
3348 return; 3695 return;
3349 3696
3350 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3697 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3351 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3352 // as of this comment the interval is set in AddToPhysicalScene 3698 // as of this comment the interval is set in AddToPhysicalScene
3353 if (Animator != null) 3699 if (Animator!=null)
3354 Animator.UpdateMovementAnimations(); 3700 {
3701 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3702 { // else its will lock out other animation changes, like ground sit.
3703 Animator.UpdateMovementAnimations();
3704 m_updateCount--;
3705 }
3706 }
3355 3707
3356 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3708 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3357 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3709 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3358 3710
3359 CollisionPlane = Vector4.UnitW; 3711 CollisionPlane = Vector4.UnitW;
3360 3712
3713 if (m_lastColCount != coldata.Count)
3714 {
3715 m_updateCount = UPDATE_COUNT;
3716 m_lastColCount = coldata.Count;
3717 }
3718
3361 if (coldata.Count != 0 && Animator != null) 3719 if (coldata.Count != 0 && Animator != null)
3362 { 3720 {
3363 switch (Animator.CurrentMovementAnimation) 3721 switch (Animator.CurrentMovementAnimation)
@@ -3387,6 +3745,148 @@ namespace OpenSim.Region.Framework.Scenes
3387 } 3745 }
3388 } 3746 }
3389 3747
3748 List<uint> thisHitColliders = new List<uint>();
3749 List<uint> endedColliders = new List<uint>();
3750 List<uint> startedColliders = new List<uint>();
3751
3752 foreach (uint localid in coldata.Keys)
3753 {
3754 thisHitColliders.Add(localid);
3755 if (!m_lastColliders.Contains(localid))
3756 {
3757 startedColliders.Add(localid);
3758 }
3759 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3760 }
3761
3762 // calculate things that ended colliding
3763 foreach (uint localID in m_lastColliders)
3764 {
3765 if (!thisHitColliders.Contains(localID))
3766 {
3767 endedColliders.Add(localID);
3768 }
3769 }
3770 //add the items that started colliding this time to the last colliders list.
3771 foreach (uint localID in startedColliders)
3772 {
3773 m_lastColliders.Add(localID);
3774 }
3775 // remove things that ended colliding from the last colliders list
3776 foreach (uint localID in endedColliders)
3777 {
3778 m_lastColliders.Remove(localID);
3779 }
3780
3781 // do event notification
3782 if (startedColliders.Count > 0)
3783 {
3784 ColliderArgs StartCollidingMessage = new ColliderArgs();
3785 List<DetectedObject> colliding = new List<DetectedObject>();
3786 foreach (uint localId in startedColliders)
3787 {
3788 if (localId == 0)
3789 continue;
3790
3791 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3792 string data = "";
3793 if (obj != null)
3794 {
3795 DetectedObject detobj = new DetectedObject();
3796 detobj.keyUUID = obj.UUID;
3797 detobj.nameStr = obj.Name;
3798 detobj.ownerUUID = obj.OwnerID;
3799 detobj.posVector = obj.AbsolutePosition;
3800 detobj.rotQuat = obj.GetWorldRotation();
3801 detobj.velVector = obj.Velocity;
3802 detobj.colliderType = 0;
3803 detobj.groupUUID = obj.GroupID;
3804 colliding.Add(detobj);
3805 }
3806 }
3807
3808 if (colliding.Count > 0)
3809 {
3810 StartCollidingMessage.Colliders = colliding;
3811
3812 foreach (SceneObjectGroup att in GetAttachments())
3813 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3814 }
3815 }
3816
3817 if (endedColliders.Count > 0)
3818 {
3819 ColliderArgs EndCollidingMessage = new ColliderArgs();
3820 List<DetectedObject> colliding = new List<DetectedObject>();
3821 foreach (uint localId in endedColliders)
3822 {
3823 if (localId == 0)
3824 continue;
3825
3826 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3827 string data = "";
3828 if (obj != null)
3829 {
3830 DetectedObject detobj = new DetectedObject();
3831 detobj.keyUUID = obj.UUID;
3832 detobj.nameStr = obj.Name;
3833 detobj.ownerUUID = obj.OwnerID;
3834 detobj.posVector = obj.AbsolutePosition;
3835 detobj.rotQuat = obj.GetWorldRotation();
3836 detobj.velVector = obj.Velocity;
3837 detobj.colliderType = 0;
3838 detobj.groupUUID = obj.GroupID;
3839 colliding.Add(detobj);
3840 }
3841 }
3842
3843 if (colliding.Count > 0)
3844 {
3845 EndCollidingMessage.Colliders = colliding;
3846
3847 foreach (SceneObjectGroup att in GetAttachments())
3848 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3849 }
3850 }
3851
3852 if (thisHitColliders.Count > 0)
3853 {
3854 ColliderArgs CollidingMessage = new ColliderArgs();
3855 List<DetectedObject> colliding = new List<DetectedObject>();
3856 foreach (uint localId in thisHitColliders)
3857 {
3858 if (localId == 0)
3859 continue;
3860
3861 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3862 string data = "";
3863 if (obj != null)
3864 {
3865 DetectedObject detobj = new DetectedObject();
3866 detobj.keyUUID = obj.UUID;
3867 detobj.nameStr = obj.Name;
3868 detobj.ownerUUID = obj.OwnerID;
3869 detobj.posVector = obj.AbsolutePosition;
3870 detobj.rotQuat = obj.GetWorldRotation();
3871 detobj.velVector = obj.Velocity;
3872 detobj.colliderType = 0;
3873 detobj.groupUUID = obj.GroupID;
3874 colliding.Add(detobj);
3875 }
3876 }
3877
3878 if (colliding.Count > 0)
3879 {
3880 CollidingMessage.Colliders = colliding;
3881
3882 lock (m_attachments)
3883 {
3884 foreach (SceneObjectGroup att in m_attachments)
3885 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3886 }
3887 }
3888 }
3889
3390 if (m_invulnerable) 3890 if (m_invulnerable)
3391 return; 3891 return;
3392 3892
@@ -3460,6 +3960,10 @@ namespace OpenSim.Region.Framework.Scenes
3460 { 3960 {
3461 lock (m_attachments) 3961 lock (m_attachments)
3462 { 3962 {
3963 // This may be true when the attachment comes back
3964 // from serialization after login. Clear it.
3965 gobj.IsDeleted = false;
3966
3463 m_attachments.Add(gobj); 3967 m_attachments.Add(gobj);
3464 } 3968 }
3465 } 3969 }
@@ -3823,5 +4327,39 @@ namespace OpenSim.Region.Framework.Scenes
3823 m_reprioritization_called = false; 4327 m_reprioritization_called = false;
3824 } 4328 }
3825 } 4329 }
4330
4331 private Vector3 Quat2Euler(Quaternion rot){
4332 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4333 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4334 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4335 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4336 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4337 return(new Vector3(x,y,z));
4338 }
4339
4340 private void CheckLandingPoint(ref Vector3 pos)
4341 {
4342 // Never constrain lures
4343 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4344 return;
4345
4346 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4347 return;
4348
4349 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4350
4351 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4352 land.LandData.UserLocation != Vector3.Zero &&
4353 land.LandData.OwnerID != m_uuid &&
4354 (!m_scene.Permissions.IsGod(m_uuid)) &&
4355 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4356 {
4357 float curr = Vector3.Distance(AbsolutePosition, pos);
4358 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4359 pos = land.LandData.UserLocation;
4360 else
4361 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4362 }
4363 }
3826 } 4364 }
3827} 4365}