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, 711 insertions, 169 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index b1094cc..fc8f8b9 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
@@ -190,7 +203,8 @@ namespace OpenSim.Region.Framework.Scenes
190 203
191 protected ulong crossingFromRegion; 204 protected ulong crossingFromRegion;
192 205
193 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 206 private readonly Vector3[] Dir_Vectors = new Vector3[11];
207 private bool m_isNudging = false;
194 208
195 // Position of agent's camera in world (region cordinates) 209 // Position of agent's camera in world (region cordinates)
196 protected Vector3 m_CameraCenter; 210 protected Vector3 m_CameraCenter;
@@ -215,17 +229,25 @@ namespace OpenSim.Region.Framework.Scenes
215 private bool m_autopilotMoving; 229 private bool m_autopilotMoving;
216 private Vector3 m_autoPilotTarget; 230 private Vector3 m_autoPilotTarget;
217 private bool m_sitAtAutoTarget; 231 private bool m_sitAtAutoTarget;
232 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
218 233
219 private string m_nextSitAnimation = String.Empty; 234 private string m_nextSitAnimation = String.Empty;
220 235
221 //PauPaw:Proper PID Controler for autopilot************ 236 //PauPaw:Proper PID Controler for autopilot************
222 public bool MovingToTarget { get; private set; } 237 public bool MovingToTarget { get; private set; }
223 public Vector3 MoveToPositionTarget { get; private set; } 238 public Vector3 MoveToPositionTarget { get; private set; }
239 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
224 240
225 private bool m_followCamAuto; 241 private bool m_followCamAuto;
226 242
227 private int m_movementUpdateCount; 243 private int m_movementUpdateCount;
244 private int m_lastColCount = -1; //KF: Look for Collision chnages
245 private int m_updateCount = 0; //KF: Update Anims for a while
246 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
228 private const int NumMovementsBetweenRayCast = 5; 247 private const int NumMovementsBetweenRayCast = 5;
248 private List<uint> m_lastColliders = new List<uint>();
249
250 private object m_syncRoot = new Object();
229 251
230 private bool CameraConstraintActive; 252 private bool CameraConstraintActive;
231 //private int m_moveToPositionStateStatus; 253 //private int m_moveToPositionStateStatus;
@@ -262,7 +284,9 @@ namespace OpenSim.Region.Framework.Scenes
262 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 284 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
263 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 285 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
264 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 286 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
265 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 287 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
288 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
289 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
266 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 290 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
267 } 291 }
268 292
@@ -466,8 +490,9 @@ namespace OpenSim.Region.Framework.Scenes
466 get 490 get
467 { 491 {
468 PhysicsActor actor = m_physicsActor; 492 PhysicsActor actor = m_physicsActor;
469 if (actor != null) 493// if (actor != null)
470 { 494 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
495 {
471 m_pos = actor.Position; 496 m_pos = actor.Position;
472 497
473// m_log.DebugFormat( 498// m_log.DebugFormat(
@@ -494,7 +519,7 @@ namespace OpenSim.Region.Framework.Scenes
494 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 519 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
495 if (part != null) 520 if (part != null)
496 { 521 {
497 return m_parentPosition + (m_pos * part.GetWorldRotation()); 522 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
498 } 523 }
499 else 524 else
500 { 525 {
@@ -521,7 +546,9 @@ namespace OpenSim.Region.Framework.Scenes
521 } 546 }
522 } 547 }
523 548
524 m_pos = value; 549// Changed this to update unconditionally to make npose work
550// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
551 m_pos = value;
525 m_parentPosition = Vector3.Zero; 552 m_parentPosition = Vector3.Zero;
526 553
527// m_log.DebugFormat( 554// m_log.DebugFormat(
@@ -582,10 +609,39 @@ namespace OpenSim.Region.Framework.Scenes
582 } 609 }
583 } 610 }
584 611
612 public Quaternion OffsetRotation
613 {
614 get { return m_offsetRotation; }
615 set { m_offsetRotation = value; }
616 }
617
585 public Quaternion Rotation 618 public Quaternion Rotation
586 { 619 {
587 get { return m_bodyRot; } 620 get {
588 set { m_bodyRot = value; } 621 if (m_parentID != 0)
622 {
623 if (m_offsetRotation != null)
624 {
625 return m_offsetRotation;
626 }
627 else
628 {
629 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
630 }
631
632 }
633 else
634 {
635 return m_bodyRot;
636 }
637 }
638 set {
639 m_bodyRot = value;
640 if (m_parentID != 0)
641 {
642 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
643 }
644 }
589 } 645 }
590 646
591 public Quaternion PreviousRotation 647 public Quaternion PreviousRotation
@@ -610,11 +666,21 @@ namespace OpenSim.Region.Framework.Scenes
610 666
611 private uint m_parentID; 667 private uint m_parentID;
612 668
669
670 private UUID m_linkedPrim;
671
613 public uint ParentID 672 public uint ParentID
614 { 673 {
615 get { return m_parentID; } 674 get { return m_parentID; }
616 set { m_parentID = value; } 675 set { m_parentID = value; }
617 } 676 }
677
678 public UUID LinkedPrim
679 {
680 get { return m_linkedPrim; }
681 set { m_linkedPrim = value; }
682 }
683
618 public float Health 684 public float Health
619 { 685 {
620 get { return m_health; } 686 get { return m_health; }
@@ -750,6 +816,7 @@ namespace OpenSim.Region.Framework.Scenes
750 m_localId = m_scene.AllocateLocalId(); 816 m_localId = m_scene.AllocateLocalId();
751 817
752 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 818 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
819 m_userFlags = account.UserFlags;
753 820
754 if (account != null) 821 if (account != null)
755 m_userLevel = account.UserLevel; 822 m_userLevel = account.UserLevel;
@@ -768,10 +835,7 @@ namespace OpenSim.Region.Framework.Scenes
768 m_reprioritization_timer.AutoReset = false; 835 m_reprioritization_timer.AutoReset = false;
769 836
770 AdjustKnownSeeds(); 837 AdjustKnownSeeds();
771
772 // TODO: I think, this won't send anything, as we are still a child here...
773 Animator.TrySetMovementAnimation("STAND"); 838 Animator.TrySetMovementAnimation("STAND");
774
775 // we created a new ScenePresence (a new child agent) in a fresh region. 839 // we created a new ScenePresence (a new child agent) in a fresh region.
776 // Request info about all the (root) agents in this region 840 // Request info about all the (root) agents in this region
777 // Note: This won't send data *to* other clients in that region (children don't send) 841 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -812,25 +876,47 @@ namespace OpenSim.Region.Framework.Scenes
812 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 876 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
813 Dir_Vectors[4] = Vector3.UnitZ; //UP 877 Dir_Vectors[4] = Vector3.UnitZ; //UP
814 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 878 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
815 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 879 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
816 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 880 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
817 Dir_Vectors[7] = -Vector3.UnitX; //BACK 881 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
882 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
883 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
818 } 884 }
819 885
820 private Vector3[] GetWalkDirectionVectors() 886 private Vector3[] GetWalkDirectionVectors()
821 { 887 {
822 Vector3[] vector = new Vector3[9]; 888 Vector3[] vector = new Vector3[11];
823 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 889 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
824 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 890 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
825 vector[2] = Vector3.UnitY; //LEFT 891 vector[2] = Vector3.UnitY; //LEFT
826 vector[3] = -Vector3.UnitY; //RIGHT 892 vector[3] = -Vector3.UnitY; //RIGHT
827 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 893 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
828 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 894 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
829 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 895 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
830 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 896 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
831 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 897 vector[8] = Vector3.UnitY; //LEFT_NUDGE
898 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
899 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
832 return vector; 900 return vector;
833 } 901 }
902
903 private bool[] GetDirectionIsNudge()
904 {
905 bool[] isNudge = new bool[11];
906 isNudge[0] = false; //FORWARD
907 isNudge[1] = false; //BACK
908 isNudge[2] = false; //LEFT
909 isNudge[3] = false; //RIGHT
910 isNudge[4] = false; //UP
911 isNudge[5] = false; //DOWN
912 isNudge[6] = true; //FORWARD_NUDGE
913 isNudge[7] = true; //BACK_NUDGE
914 isNudge[8] = true; //LEFT_NUDGE
915 isNudge[9] = true; //RIGHT_NUDGE
916 isNudge[10] = true; //DOWN_Nudge
917 return isNudge;
918 }
919
834 920
835 #endregion 921 #endregion
836 922
@@ -895,6 +981,62 @@ namespace OpenSim.Region.Framework.Scenes
895 pos.Y = crossedBorder.BorderLine.Z - 1; 981 pos.Y = crossedBorder.BorderLine.Z - 1;
896 } 982 }
897 983
984 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
985 if (land != null)
986 {
987 // If we come in via login, landmark or map, we want to
988 // honor landing points. If we come in via Lure, we want
989 // to ignore them.
990 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
991 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
992 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
993 {
994 // Don't restrict gods, estate managers, or land owners to
995 // the TP point. This behaviour mimics agni.
996 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
997 land.LandData.UserLocation != Vector3.Zero &&
998 GodLevel < 200 &&
999 ((land.LandData.OwnerID != m_uuid &&
1000 (!m_scene.Permissions.IsGod(m_uuid)) &&
1001 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
1002 {
1003 pos = land.LandData.UserLocation;
1004 }
1005 }
1006
1007 land.SendLandUpdateToClient(ControllingClient);
1008 }
1009
1010 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
1011 {
1012 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
1013
1014 if (pos.X < 0)
1015 {
1016 emergencyPos.X = (int)Constants.RegionSize + pos.X;
1017 if (!(pos.Y < 0))
1018 emergencyPos.Y = pos.Y;
1019 if (!(pos.Z < 0))
1020 emergencyPos.Z = pos.Z;
1021 }
1022 if (pos.Y < 0)
1023 {
1024 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
1025 if (!(pos.X < 0))
1026 emergencyPos.X = pos.X;
1027 if (!(pos.Z < 0))
1028 emergencyPos.Z = pos.Z;
1029 }
1030 if (pos.Z < 0)
1031 {
1032 emergencyPos.Z = 128;
1033 if (!(pos.Y < 0))
1034 emergencyPos.Y = pos.Y;
1035 if (!(pos.X < 0))
1036 emergencyPos.X = pos.X;
1037 }
1038 }
1039
898 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1040 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
899 { 1041 {
900 m_log.WarnFormat( 1042 m_log.WarnFormat(
@@ -1027,16 +1169,21 @@ namespace OpenSim.Region.Framework.Scenes
1027 /// <summary> 1169 /// <summary>
1028 /// Removes physics plugin scene representation of this agent if it exists. 1170 /// Removes physics plugin scene representation of this agent if it exists.
1029 /// </summary> 1171 /// </summary>
1030 private void RemoveFromPhysicalScene() 1172 public void RemoveFromPhysicalScene()
1031 { 1173 {
1032 if (PhysicsActor != null) 1174 if (PhysicsActor != null)
1033 { 1175 {
1034 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1176 try
1035 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1177 {
1036 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1178 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1037 m_physicsActor.UnSubscribeEvents(); 1179 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1038 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1180 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1039 PhysicsActor = null; 1181 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1182 m_physicsActor.UnSubscribeEvents();
1183 PhysicsActor = null;
1184 }
1185 catch
1186 { }
1040 } 1187 }
1041 } 1188 }
1042 1189
@@ -1047,15 +1194,18 @@ namespace OpenSim.Region.Framework.Scenes
1047 public void Teleport(Vector3 pos) 1194 public void Teleport(Vector3 pos)
1048 { 1195 {
1049 bool isFlying = false; 1196 bool isFlying = false;
1197
1050 if (m_physicsActor != null) 1198 if (m_physicsActor != null)
1051 isFlying = m_physicsActor.Flying; 1199 isFlying = m_physicsActor.Flying;
1052 1200
1053 RemoveFromPhysicalScene(); 1201 RemoveFromPhysicalScene();
1054 Velocity = Vector3.Zero; 1202 Velocity = Vector3.Zero;
1203 CheckLandingPoint(ref pos);
1055 AbsolutePosition = pos; 1204 AbsolutePosition = pos;
1056 AddToPhysicalScene(isFlying); 1205 AddToPhysicalScene(isFlying);
1057 1206
1058 SendTerseUpdateToAllClients(); 1207 SendTerseUpdateToAllClients();
1208
1059 } 1209 }
1060 1210
1061 public void TeleportWithMomentum(Vector3 pos) 1211 public void TeleportWithMomentum(Vector3 pos)
@@ -1065,6 +1215,7 @@ namespace OpenSim.Region.Framework.Scenes
1065 isFlying = m_physicsActor.Flying; 1215 isFlying = m_physicsActor.Flying;
1066 1216
1067 RemoveFromPhysicalScene(); 1217 RemoveFromPhysicalScene();
1218 CheckLandingPoint(ref pos);
1068 AbsolutePosition = pos; 1219 AbsolutePosition = pos;
1069 AddToPhysicalScene(isFlying); 1220 AddToPhysicalScene(isFlying);
1070 1221
@@ -1240,11 +1391,12 @@ namespace OpenSim.Region.Framework.Scenes
1240 /// <summary> 1391 /// <summary>
1241 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1392 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1242 /// </summary> 1393 /// </summary>
1394 /// <summary>
1395 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1396 /// </summary>
1243 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1397 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1244 { 1398 {
1245// m_log.DebugFormat( 1399 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1246// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1247// Scene.RegionInfo.RegionName, remoteClient.Name);
1248 1400
1249 //if (m_isChildAgent) 1401 //if (m_isChildAgent)
1250 //{ 1402 //{
@@ -1440,12 +1592,12 @@ namespace OpenSim.Region.Framework.Scenes
1440 1592
1441 if ((m_movementflag & (byte)(uint)DCF) == 0) 1593 if ((m_movementflag & (byte)(uint)DCF) == 0)
1442 { 1594 {
1443 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1595 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1444 { 1596 {
1445 m_movementflag |= (byte)nudgehack; 1597 m_movementflag |= (byte)nudgehack;
1446 } 1598 }
1447 1599
1448// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF); 1600 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF);
1449 m_movementflag += (byte)(uint)DCF; 1601 m_movementflag += (byte)(uint)DCF;
1450 update_movementflag = true; 1602 update_movementflag = true;
1451 } 1603 }
@@ -1453,11 +1605,11 @@ namespace OpenSim.Region.Framework.Scenes
1453 else 1605 else
1454 { 1606 {
1455 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1607 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1456 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1608 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1457 && ((m_movementflag & (byte)nudgehack) == nudgehack)) 1609 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1458 ) // This or is for Nudge forward 1610 ) // This or is for Nudge forward
1459 { 1611 {
1460// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF); 1612 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1461 m_movementflag -= ((byte)(uint)DCF); 1613 m_movementflag -= ((byte)(uint)DCF);
1462 update_movementflag = true; 1614 update_movementflag = true;
1463 1615
@@ -1522,21 +1674,21 @@ namespace OpenSim.Region.Framework.Scenes
1522 // which occurs later in the main scene loop 1674 // which occurs later in the main scene loop
1523 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1675 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1524 { 1676 {
1525// m_log.DebugFormat( 1677 // m_log.DebugFormat(
1526// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1678 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1527// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1679 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1528 1680
1529 AddNewMovement(agent_control_v3); 1681 AddNewMovement(agent_control_v3);
1530 } 1682 }
1531// else 1683 // else
1532// { 1684 // {
1533// if (!update_movementflag) 1685 // if (!update_movementflag)
1534// { 1686 // {
1535// m_log.DebugFormat( 1687 // m_log.DebugFormat(
1536// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1688 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1537// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1689 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1538// } 1690 // }
1539// } 1691 // }
1540 1692
1541 if (update_movementflag && m_parentID == 0) 1693 if (update_movementflag && m_parentID == 0)
1542 Animator.UpdateMovementAnimations(); 1694 Animator.UpdateMovementAnimations();
@@ -1557,20 +1709,20 @@ namespace OpenSim.Region.Framework.Scenes
1557 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1709 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1558 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1710 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1559 { 1711 {
1560// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1712 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1561 1713
1562 bool updated = false; 1714 bool updated = false;
1563 1715
1564// m_log.DebugFormat( 1716 // m_log.DebugFormat(
1565// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1717 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1566// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1718 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1567 1719
1568 if (!m_autopilotMoving) 1720 if (!m_autopilotMoving)
1569 { 1721 {
1570 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1722 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1571// m_log.DebugFormat( 1723 // m_log.DebugFormat(
1572// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1724 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1573// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1725 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1574 1726
1575 // Check the error term of the current position in relation to the target position 1727 // Check the error term of the current position in relation to the target position
1576 if (distanceToTarget <= 1) 1728 if (distanceToTarget <= 1)
@@ -1593,7 +1745,7 @@ namespace OpenSim.Region.Framework.Scenes
1593 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1745 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1594 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1746 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1595 // Ignore z component of vector 1747 // Ignore z component of vector
1596// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1748 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1597 LocalVectorToTarget3D.Normalize(); 1749 LocalVectorToTarget3D.Normalize();
1598 1750
1599 // update avatar movement flags. the avatar coordinate system is as follows: 1751 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1659,9 +1811,9 @@ namespace OpenSim.Region.Framework.Scenes
1659 updated = true; 1811 updated = true;
1660 } 1812 }
1661 1813
1662// m_log.DebugFormat( 1814 // m_log.DebugFormat(
1663// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1815 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1664// LocalVectorToTarget3D, agent_control_v3, Name); 1816 // LocalVectorToTarget3D, agent_control_v3, Name);
1665 1817
1666 agent_control_v3 += LocalVectorToTarget3D; 1818 agent_control_v3 += LocalVectorToTarget3D;
1667 } 1819 }
@@ -1763,7 +1915,7 @@ namespace OpenSim.Region.Framework.Scenes
1763 Velocity = Vector3.Zero; 1915 Velocity = Vector3.Zero;
1764 SendAvatarDataToAllAgents(); 1916 SendAvatarDataToAllAgents();
1765 1917
1766 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1918 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1767 } 1919 }
1768 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1920 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1769 m_requestedSitTargetUUID = UUID.Zero; 1921 m_requestedSitTargetUUID = UUID.Zero;
@@ -1800,25 +1952,22 @@ namespace OpenSim.Region.Framework.Scenes
1800 1952
1801 if (m_parentID != 0) 1953 if (m_parentID != 0)
1802 { 1954 {
1803 m_log.Debug("StandupCode Executed"); 1955 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1804 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1805 if (part != null) 1956 if (part != null)
1806 { 1957 {
1958 part.TaskInventory.LockItemsForRead(true);
1807 TaskInventoryDictionary taskIDict = part.TaskInventory; 1959 TaskInventoryDictionary taskIDict = part.TaskInventory;
1808 if (taskIDict != null) 1960 if (taskIDict != null)
1809 { 1961 {
1810 lock (taskIDict) 1962 foreach (UUID taskID in taskIDict.Keys)
1811 { 1963 {
1812 foreach (UUID taskID in taskIDict.Keys) 1964 UnRegisterControlEventsToScript(LocalId, taskID);
1813 { 1965 taskIDict[taskID].PermsMask &= ~(
1814 UnRegisterControlEventsToScript(LocalId, taskID); 1966 2048 | //PERMISSION_CONTROL_CAMERA
1815 taskIDict[taskID].PermsMask &= ~( 1967 4); // PERMISSION_TAKE_CONTROLS
1816 2048 | //PERMISSION_CONTROL_CAMERA
1817 4); // PERMISSION_TAKE_CONTROLS
1818 }
1819 } 1968 }
1820
1821 } 1969 }
1970 part.TaskInventory.LockItemsForRead(false);
1822 // Reset sit target. 1971 // Reset sit target.
1823 if (part.GetAvatarOnSitTarget() == UUID) 1972 if (part.GetAvatarOnSitTarget() == UUID)
1824 part.SitTargetAvatar = UUID.Zero; 1973 part.SitTargetAvatar = UUID.Zero;
@@ -1827,20 +1976,58 @@ namespace OpenSim.Region.Framework.Scenes
1827 m_parentPosition = part.GetWorldPosition(); 1976 m_parentPosition = part.GetWorldPosition();
1828 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1977 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1829 } 1978 }
1979 // part.GetWorldRotation() is the rotation of the object being sat on
1980 // Rotation is the sittiing Av's rotation
1981
1982 Quaternion partRot;
1983// if (part.LinkNum == 1)
1984// { // Root prim of linkset
1985// partRot = part.ParentGroup.RootPart.RotationOffset;
1986// }
1987// else
1988// { // single or child prim
1989
1990// }
1991 if (part == null) //CW: Part may be gone. llDie() for example.
1992 {
1993 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1994 }
1995 else
1996 {
1997 partRot = part.GetWorldRotation();
1998 }
1999
2000 Quaternion partIRot = Quaternion.Inverse(partRot);
2001
2002 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
2003 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1830 2004
2005
1831 if (m_physicsActor == null) 2006 if (m_physicsActor == null)
1832 { 2007 {
1833 AddToPhysicalScene(false); 2008 AddToPhysicalScene(false);
1834 } 2009 }
1835 2010 //CW: If the part isn't null then we can set the current position
1836 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2011 if (part != null)
1837 m_parentPosition = Vector3.Zero; 2012 {
1838 2013 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1839 m_parentID = 0; 2014 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2015 part.IsOccupied = false;
2016 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2017 }
2018 else
2019 {
2020 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2021 AbsolutePosition = m_lastWorldPosition;
2022 }
2023
2024 m_parentPosition = Vector3.Zero;
2025 m_parentID = 0;
2026 m_linkedPrim = UUID.Zero;
2027 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1840 SendAvatarDataToAllAgents(); 2028 SendAvatarDataToAllAgents();
1841 m_requestedSitTargetID = 0; 2029 m_requestedSitTargetID = 0;
1842 } 2030 }
1843
1844 Animator.TrySetMovementAnimation("STAND"); 2031 Animator.TrySetMovementAnimation("STAND");
1845 } 2032 }
1846 2033
@@ -1871,13 +2058,9 @@ namespace OpenSim.Region.Framework.Scenes
1871 Vector3 avSitOffSet = part.SitTargetPosition; 2058 Vector3 avSitOffSet = part.SitTargetPosition;
1872 Quaternion avSitOrientation = part.SitTargetOrientation; 2059 Quaternion avSitOrientation = part.SitTargetOrientation;
1873 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2060 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1874 2061 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1875 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2062 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1876 bool SitTargetisSet = 2063 if (SitTargetisSet && !SitTargetOccupied)
1877 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1878 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1879
1880 if (SitTargetisSet && SitTargetUnOccupied)
1881 { 2064 {
1882 //switch the target to this prim 2065 //switch the target to this prim
1883 return part; 2066 return part;
@@ -1891,85 +2074,168 @@ namespace OpenSim.Region.Framework.Scenes
1891 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2074 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1892 { 2075 {
1893 bool autopilot = true; 2076 bool autopilot = true;
2077 Vector3 autopilotTarget = new Vector3();
2078 Quaternion sitOrientation = Quaternion.Identity;
1894 Vector3 pos = new Vector3(); 2079 Vector3 pos = new Vector3();
1895 Quaternion sitOrientation = pSitOrientation;
1896 Vector3 cameraEyeOffset = Vector3.Zero; 2080 Vector3 cameraEyeOffset = Vector3.Zero;
1897 Vector3 cameraAtOffset = Vector3.Zero; 2081 Vector3 cameraAtOffset = Vector3.Zero;
1898 bool forceMouselook = false; 2082 bool forceMouselook = false;
1899 2083
1900 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2084 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1901 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2085 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1902 if (part != null) 2086 if (part == null) return;
2087
2088 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2089 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2090
2091 // part is the prim to sit on
2092 // offset is the world-ref vector distance from that prim center to the click-spot
2093 // UUID is the UUID of the Avatar doing the clicking
2094
2095 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2096
2097 // Is a sit target available?
2098 Vector3 avSitOffSet = part.SitTargetPosition;
2099 Quaternion avSitOrientation = part.SitTargetOrientation;
2100
2101 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2102 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2103 Quaternion partRot;
2104// if (part.LinkNum == 1)
2105// { // Root prim of linkset
2106// partRot = part.ParentGroup.RootPart.RotationOffset;
2107// }
2108// else
2109// { // single or child prim
2110 partRot = part.GetWorldRotation();
2111// }
2112 Quaternion partIRot = Quaternion.Inverse(partRot);
2113//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2114 // Sit analysis rewritten by KF 091125
2115 if (SitTargetisSet) // scipted sit
1903 { 2116 {
1904 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2117 if (!part.IsOccupied)
1905 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2118 {
1906 2119//Console.WriteLine("Scripted, unoccupied");
1907 // Is a sit target available? 2120 part.SitTargetAvatar = UUID; // set that Av will be on it
1908 Vector3 avSitOffSet = part.SitTargetPosition; 2121 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1909 Quaternion avSitOrientation = part.SitTargetOrientation; 2122
1910 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2123 Quaternion nrot = avSitOrientation;
1911 2124 if (!part.IsRoot)
1912 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1913 bool SitTargetisSet =
1914 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1915 (
1916 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1917 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1918 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1919 )
1920 ));
1921
1922 if (SitTargetisSet && SitTargetUnOccupied)
1923 {
1924 part.SitTargetAvatar = UUID;
1925 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1926 sitOrientation = avSitOrientation;
1927 autopilot = false;
1928 }
1929 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1930
1931 pos = part.AbsolutePosition + offset;
1932 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1933 //{
1934 // offset = pos;
1935 //autopilot = false;
1936 //}
1937 if (m_physicsActor != null)
1938 {
1939 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1940 // We can remove the physicsActor until they stand up.
1941 m_sitAvatarHeight = m_physicsActor.Size.Z;
1942
1943 if (autopilot)
1944 { 2125 {
1945 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2126 nrot = part.RotationOffset * avSitOrientation;
1946 {
1947 autopilot = false;
1948
1949 RemoveFromPhysicalScene();
1950 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1951 }
1952 } 2127 }
1953 else 2128 sitOrientation = nrot; // Change rotatione to the scripted one
2129 OffsetRotation = nrot;
2130 autopilot = false; // Jump direct to scripted llSitPos()
2131 }
2132 else
2133 {
2134//Console.WriteLine("Scripted, occupied");
2135 return;
2136 }
2137 }
2138 else // Not Scripted
2139 {
2140 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
2141 {
2142 // large prim & offset, ignore if other Avs sitting
2143// offset.Z -= 0.05f;
2144 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2145 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2146
2147//Console.WriteLine(" offset ={0}", offset);
2148//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2149//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2150
2151 }
2152 else // small offset
2153 {
2154//Console.WriteLine("Small offset");
2155 if (!part.IsOccupied)
2156 {
2157 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2158 autopilotTarget = part.AbsolutePosition;
2159//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2160 }
2161 else return; // occupied small
2162 } // end large/small
2163 } // end Scripted/not
2164
2165 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2166
2167 cameraAtOffset = part.GetCameraAtOffset();
2168 cameraEyeOffset = part.GetCameraEyeOffset();
2169 forceMouselook = part.GetForceMouselook();
2170 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2171 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2172
2173 if (m_physicsActor != null)
2174 {
2175 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2176 // We can remove the physicsActor until they stand up.
2177 m_sitAvatarHeight = m_physicsActor.Size.Z;
2178 if (autopilot)
2179 { // its not a scripted sit
2180// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2181 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1954 { 2182 {
2183 autopilot = false; // close enough
2184 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2185 Not using the part's position because returning the AV to the last known standing
2186 position is likely to be more friendly, isn't it? */
1955 RemoveFromPhysicalScene(); 2187 RemoveFromPhysicalScene();
1956 } 2188 Velocity = Vector3.Zero;
2189 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2190 } // else the autopilot will get us close
2191 }
2192 else
2193 { // its a scripted sit
2194 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2195 I *am* using the part's position this time because we have no real idea how far away
2196 the avatar is from the sit target. */
2197 RemoveFromPhysicalScene();
2198 Velocity = Vector3.Zero;
1957 } 2199 }
1958
1959 cameraAtOffset = part.GetCameraAtOffset();
1960 cameraEyeOffset = part.GetCameraEyeOffset();
1961 forceMouselook = part.GetForceMouselook();
1962 } 2200 }
1963 2201 else return; // physactor is null!
1964 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2202
1965 m_requestedSitTargetUUID = targetID; 2203 Vector3 offsetr; // = offset * partIRot;
2204 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2205 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2206 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2207 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2208 //offsetr = offset * partIRot;
2209//
2210 // }
2211 // else
2212 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2213 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2214 // (offset * partRot);
2215 // }
2216
2217//Console.WriteLine(" ");
2218//Console.WriteLine("link number ={0}", part.LinkNum);
2219//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2220//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2221//Console.WriteLine("Click offst ={0}", offset);
2222//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2223//Console.WriteLine("offsetr ={0}", offsetr);
2224//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2225//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2226
2227 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2228 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2229
2230 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1966 // This calls HandleAgentSit twice, once from here, and the client calls 2231 // This calls HandleAgentSit twice, once from here, and the client calls
1967 // HandleAgentSit itself after it gets to the location 2232 // HandleAgentSit itself after it gets to the location
1968 // It doesn't get to the location until we've moved them there though 2233 // It doesn't get to the location until we've moved them there though
1969 // which happens in HandleAgentSit :P 2234 // which happens in HandleAgentSit :P
1970 m_autopilotMoving = autopilot; 2235 m_autopilotMoving = autopilot;
1971 m_autoPilotTarget = pos; 2236 m_autoPilotTarget = autopilotTarget;
1972 m_sitAtAutoTarget = autopilot; 2237 m_sitAtAutoTarget = autopilot;
2238 m_initialSitTarget = autopilotTarget;
1973 if (!autopilot) 2239 if (!autopilot)
1974 HandleAgentSit(remoteClient, UUID); 2240 HandleAgentSit(remoteClient, UUID);
1975 } 2241 }
@@ -2234,47 +2500,130 @@ namespace OpenSim.Region.Framework.Scenes
2234 { 2500 {
2235 if (part != null) 2501 if (part != null)
2236 { 2502 {
2503//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2237 if (part.GetAvatarOnSitTarget() == UUID) 2504 if (part.GetAvatarOnSitTarget() == UUID)
2238 { 2505 {
2506//Console.WriteLine("Scripted Sit");
2507 // Scripted sit
2239 Vector3 sitTargetPos = part.SitTargetPosition; 2508 Vector3 sitTargetPos = part.SitTargetPosition;
2240 Quaternion sitTargetOrient = part.SitTargetOrientation; 2509 Quaternion sitTargetOrient = part.SitTargetOrientation;
2241
2242 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2243 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2244
2245 //Quaternion result = (sitTargetOrient * vq) * nq;
2246
2247 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2510 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2248 m_pos += SIT_TARGET_ADJUSTMENT; 2511 m_pos += SIT_TARGET_ADJUSTMENT;
2512 if (!part.IsRoot)
2513 {
2514 m_pos *= part.RotationOffset;
2515 }
2249 m_bodyRot = sitTargetOrient; 2516 m_bodyRot = sitTargetOrient;
2250 //Rotation = sitTargetOrient;
2251 m_parentPosition = part.AbsolutePosition; 2517 m_parentPosition = part.AbsolutePosition;
2252 2518 part.IsOccupied = true;
2253 //SendTerseUpdateToAllClients(); 2519 part.ParentGroup.AddAvatar(agentID);
2254 } 2520 }
2255 else 2521 else
2256 { 2522 {
2257 m_pos -= part.AbsolutePosition; 2523 // if m_avUnscriptedSitPos is zero then Av sits above center
2524 // Else Av sits at m_avUnscriptedSitPos
2525
2526 // Non-scripted sit by Kitto Flora 21Nov09
2527 // Calculate angle of line from prim to Av
2528 Quaternion partIRot;
2529// if (part.LinkNum == 1)
2530// { // Root prim of linkset
2531// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2532// }
2533// else
2534// { // single or child prim
2535 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2536// }
2537 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2538 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2539 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2540 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2541 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2542 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2543 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2544 // Av sits at world euler <0,0, z>, translated by part rotation
2545 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2546
2258 m_parentPosition = part.AbsolutePosition; 2547 m_parentPosition = part.AbsolutePosition;
2259 } 2548 part.IsOccupied = true;
2549 part.ParentGroup.AddAvatar(agentID);
2550 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2551 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2552 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2553 m_avUnscriptedSitPos; // adds click offset, if any
2554 //Set up raytrace to find top surface of prim
2555 Vector3 size = part.Scale;
2556 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2557 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2558 Vector3 down = new Vector3(0f, 0f, -1f);
2559//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2560 m_scene.PhysicsScene.RaycastWorld(
2561 start, // Vector3 position,
2562 down, // Vector3 direction,
2563 mag, // float length,
2564 SitAltitudeCallback); // retMethod
2565 } // end scripted/not
2260 } 2566 }
2261 else 2567 else // no Av
2262 { 2568 {
2263 return; 2569 return;
2264 } 2570 }
2265 } 2571 }
2266 m_parentID = m_requestedSitTargetID;
2267 2572
2573 //We want our offsets to reference the root prim, not the child we may have sat on
2574 if (!part.IsRoot)
2575 {
2576 m_parentID = part.ParentGroup.RootPart.LocalId;
2577 m_pos += part.OffsetPosition;
2578 }
2579 else
2580 {
2581 m_parentID = m_requestedSitTargetID;
2582 }
2583
2584 m_linkedPrim = part.UUID;
2585 if (part.GetAvatarOnSitTarget() != UUID)
2586 {
2587 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2588 }
2268 Velocity = Vector3.Zero; 2589 Velocity = Vector3.Zero;
2269 RemoveFromPhysicalScene(); 2590 RemoveFromPhysicalScene();
2270
2271 Animator.TrySetMovementAnimation(sitAnimation); 2591 Animator.TrySetMovementAnimation(sitAnimation);
2272 SendAvatarDataToAllAgents(); 2592 SendAvatarDataToAllAgents();
2273 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2274 // So we're also sending a terse update (which has avatar rotation)
2275 // [Update] We do now.
2276 //SendTerseUpdateToAllClients(); 2593 //SendTerseUpdateToAllClients();
2277 } 2594 }
2595
2596 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2597 {
2598 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2599 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2600 if(hitYN)
2601 {
2602 // m_pos = Av offset from prim center to make look like on center
2603 // m_parentPosition = Actual center pos of prim
2604 // collisionPoint = spot on prim where we want to sit
2605 // collisionPoint.Z = global sit surface height
2606 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2607 Quaternion partIRot;
2608// if (part.LinkNum == 1)
2609/// { // Root prim of linkset
2610// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2611// }
2612// else
2613// { // single or child prim
2614 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2615// }
2616 if (m_initialSitTarget != null)
2617 {
2618 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2619 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2620 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2621 m_pos += offset;
2622 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2623 }
2624
2625 }
2626 } // End SitAltitudeCallback KF.
2278 2627
2279 /// <summary> 2628 /// <summary>
2280 /// Event handler for the 'Always run' setting on the client 2629 /// Event handler for the 'Always run' setting on the client
@@ -2394,6 +2743,9 @@ namespace OpenSim.Region.Framework.Scenes
2394 2743
2395 CheckForSignificantMovement(); // sends update to the modules. 2744 CheckForSignificantMovement(); // sends update to the modules.
2396 } 2745 }
2746
2747 //Sending prim updates AFTER the avatar terse updates are sent
2748 SendPrimUpdates();
2397 } 2749 }
2398 2750
2399 #endregion 2751 #endregion
@@ -3207,6 +3559,7 @@ namespace OpenSim.Region.Framework.Scenes
3207 m_callbackURI = cAgent.CallbackURI; 3559 m_callbackURI = cAgent.CallbackURI;
3208 3560
3209 m_pos = cAgent.Position; 3561 m_pos = cAgent.Position;
3562
3210 m_velocity = cAgent.Velocity; 3563 m_velocity = cAgent.Velocity;
3211 m_CameraCenter = cAgent.Center; 3564 m_CameraCenter = cAgent.Center;
3212 m_CameraAtAxis = cAgent.AtAxis; 3565 m_CameraAtAxis = cAgent.AtAxis;
@@ -3323,10 +3676,8 @@ namespace OpenSim.Region.Framework.Scenes
3323 3676
3324 Vector3 pVec = AbsolutePosition; 3677 Vector3 pVec = AbsolutePosition;
3325 3678
3326 // Old bug where the height was in centimeters instead of meters 3679 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3327 m_physicsActor = scene.AddAvatar(LocalId, Firstname + "." + Lastname, pVec,
3328 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3680 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3329
3330 scene.AddPhysicsActorTaint(m_physicsActor); 3681 scene.AddPhysicsActorTaint(m_physicsActor);
3331 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3682 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3332 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3683 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3352,18 +3703,29 @@ namespace OpenSim.Region.Framework.Scenes
3352 { 3703 {
3353 if (e == null) 3704 if (e == null)
3354 return; 3705 return;
3355 3706
3356 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3707 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3357 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3358 // as of this comment the interval is set in AddToPhysicalScene 3708 // as of this comment the interval is set in AddToPhysicalScene
3359 if (Animator != null) 3709 if (Animator!=null)
3360 Animator.UpdateMovementAnimations(); 3710 {
3711 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3712 { // else its will lock out other animation changes, like ground sit.
3713 Animator.UpdateMovementAnimations();
3714 m_updateCount--;
3715 }
3716 }
3361 3717
3362 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3718 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3363 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3719 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3364 3720
3365 CollisionPlane = Vector4.UnitW; 3721 CollisionPlane = Vector4.UnitW;
3366 3722
3723 if (m_lastColCount != coldata.Count)
3724 {
3725 m_updateCount = UPDATE_COUNT;
3726 m_lastColCount = coldata.Count;
3727 }
3728
3367 if (coldata.Count != 0 && Animator != null) 3729 if (coldata.Count != 0 && Animator != null)
3368 { 3730 {
3369 switch (Animator.CurrentMovementAnimation) 3731 switch (Animator.CurrentMovementAnimation)
@@ -3393,6 +3755,148 @@ namespace OpenSim.Region.Framework.Scenes
3393 } 3755 }
3394 } 3756 }
3395 3757
3758 List<uint> thisHitColliders = new List<uint>();
3759 List<uint> endedColliders = new List<uint>();
3760 List<uint> startedColliders = new List<uint>();
3761
3762 foreach (uint localid in coldata.Keys)
3763 {
3764 thisHitColliders.Add(localid);
3765 if (!m_lastColliders.Contains(localid))
3766 {
3767 startedColliders.Add(localid);
3768 }
3769 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3770 }
3771
3772 // calculate things that ended colliding
3773 foreach (uint localID in m_lastColliders)
3774 {
3775 if (!thisHitColliders.Contains(localID))
3776 {
3777 endedColliders.Add(localID);
3778 }
3779 }
3780 //add the items that started colliding this time to the last colliders list.
3781 foreach (uint localID in startedColliders)
3782 {
3783 m_lastColliders.Add(localID);
3784 }
3785 // remove things that ended colliding from the last colliders list
3786 foreach (uint localID in endedColliders)
3787 {
3788 m_lastColliders.Remove(localID);
3789 }
3790
3791 // do event notification
3792 if (startedColliders.Count > 0)
3793 {
3794 ColliderArgs StartCollidingMessage = new ColliderArgs();
3795 List<DetectedObject> colliding = new List<DetectedObject>();
3796 foreach (uint localId in startedColliders)
3797 {
3798 if (localId == 0)
3799 continue;
3800
3801 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3802 string data = "";
3803 if (obj != null)
3804 {
3805 DetectedObject detobj = new DetectedObject();
3806 detobj.keyUUID = obj.UUID;
3807 detobj.nameStr = obj.Name;
3808 detobj.ownerUUID = obj.OwnerID;
3809 detobj.posVector = obj.AbsolutePosition;
3810 detobj.rotQuat = obj.GetWorldRotation();
3811 detobj.velVector = obj.Velocity;
3812 detobj.colliderType = 0;
3813 detobj.groupUUID = obj.GroupID;
3814 colliding.Add(detobj);
3815 }
3816 }
3817
3818 if (colliding.Count > 0)
3819 {
3820 StartCollidingMessage.Colliders = colliding;
3821
3822 foreach (SceneObjectGroup att in GetAttachments())
3823 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3824 }
3825 }
3826
3827 if (endedColliders.Count > 0)
3828 {
3829 ColliderArgs EndCollidingMessage = new ColliderArgs();
3830 List<DetectedObject> colliding = new List<DetectedObject>();
3831 foreach (uint localId in endedColliders)
3832 {
3833 if (localId == 0)
3834 continue;
3835
3836 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3837 string data = "";
3838 if (obj != null)
3839 {
3840 DetectedObject detobj = new DetectedObject();
3841 detobj.keyUUID = obj.UUID;
3842 detobj.nameStr = obj.Name;
3843 detobj.ownerUUID = obj.OwnerID;
3844 detobj.posVector = obj.AbsolutePosition;
3845 detobj.rotQuat = obj.GetWorldRotation();
3846 detobj.velVector = obj.Velocity;
3847 detobj.colliderType = 0;
3848 detobj.groupUUID = obj.GroupID;
3849 colliding.Add(detobj);
3850 }
3851 }
3852
3853 if (colliding.Count > 0)
3854 {
3855 EndCollidingMessage.Colliders = colliding;
3856
3857 foreach (SceneObjectGroup att in GetAttachments())
3858 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3859 }
3860 }
3861
3862 if (thisHitColliders.Count > 0)
3863 {
3864 ColliderArgs CollidingMessage = new ColliderArgs();
3865 List<DetectedObject> colliding = new List<DetectedObject>();
3866 foreach (uint localId in thisHitColliders)
3867 {
3868 if (localId == 0)
3869 continue;
3870
3871 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3872 string data = "";
3873 if (obj != null)
3874 {
3875 DetectedObject detobj = new DetectedObject();
3876 detobj.keyUUID = obj.UUID;
3877 detobj.nameStr = obj.Name;
3878 detobj.ownerUUID = obj.OwnerID;
3879 detobj.posVector = obj.AbsolutePosition;
3880 detobj.rotQuat = obj.GetWorldRotation();
3881 detobj.velVector = obj.Velocity;
3882 detobj.colliderType = 0;
3883 detobj.groupUUID = obj.GroupID;
3884 colliding.Add(detobj);
3885 }
3886 }
3887
3888 if (colliding.Count > 0)
3889 {
3890 CollidingMessage.Colliders = colliding;
3891
3892 lock (m_attachments)
3893 {
3894 foreach (SceneObjectGroup att in m_attachments)
3895 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3896 }
3897 }
3898 }
3899
3396 if (m_invulnerable) 3900 if (m_invulnerable)
3397 return; 3901 return;
3398 3902
@@ -3466,6 +3970,10 @@ namespace OpenSim.Region.Framework.Scenes
3466 { 3970 {
3467 lock (m_attachments) 3971 lock (m_attachments)
3468 { 3972 {
3973 // This may be true when the attachment comes back
3974 // from serialization after login. Clear it.
3975 gobj.IsDeleted = false;
3976
3469 m_attachments.Add(gobj); 3977 m_attachments.Add(gobj);
3470 } 3978 }
3471 } 3979 }
@@ -3829,5 +4337,39 @@ namespace OpenSim.Region.Framework.Scenes
3829 m_reprioritization_called = false; 4337 m_reprioritization_called = false;
3830 } 4338 }
3831 } 4339 }
4340
4341 private Vector3 Quat2Euler(Quaternion rot){
4342 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4343 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4344 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4345 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4346 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4347 return(new Vector3(x,y,z));
4348 }
4349
4350 private void CheckLandingPoint(ref Vector3 pos)
4351 {
4352 // Never constrain lures
4353 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4354 return;
4355
4356 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4357 return;
4358
4359 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4360
4361 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4362 land.LandData.UserLocation != Vector3.Zero &&
4363 land.LandData.OwnerID != m_uuid &&
4364 (!m_scene.Permissions.IsGod(m_uuid)) &&
4365 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4366 {
4367 float curr = Vector3.Distance(AbsolutePosition, pos);
4368 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4369 pos = land.LandData.UserLocation;
4370 else
4371 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4372 }
4373 }
3832 } 4374 }
3833} 4375}