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.cs920
1 files changed, 738 insertions, 182 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 1c7102b..d43f67f 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Xml;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using System.Timers; 32using System.Timers;
@@ -72,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
72// { 73// {
73// m_log.Debug("[SCENE PRESENCE] Destructor called"); 74// m_log.Debug("[SCENE PRESENCE] Destructor called");
74// } 75// }
75 76
76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 78
78 public PresenceType PresenceType { get; private set; } 79 public PresenceType PresenceType { get; private set; }
@@ -89,7 +90,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 90 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 91 /// issue #1716
91 /// </summary> 92 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 93// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
94 // Value revised by KF 091121 by comparison with SL.
95 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 96
94 /// <summary> 97 /// <summary>
95 /// Movement updates for agents in neighboring regions are sent directly to clients. 98 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -117,6 +120,7 @@ namespace OpenSim.Region.Framework.Scenes
117 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 120 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
118 /// necessary. 121 /// necessary.
119 /// </remarks> 122 /// </remarks>
123
120 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 124 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
121 125
122 public Object AttachmentsSyncLock { get; private set; } 126 public Object AttachmentsSyncLock { get; private set; }
@@ -130,13 +134,21 @@ namespace OpenSim.Region.Framework.Scenes
130 public Vector3 lastKnownAllowedPosition; 134 public Vector3 lastKnownAllowedPosition;
131 public bool sentMessageAboutRestrictedParcelFlyingDown; 135 public bool sentMessageAboutRestrictedParcelFlyingDown;
132 public Vector4 CollisionPlane = Vector4.UnitW; 136 public Vector4 CollisionPlane = Vector4.UnitW;
133 137
138 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
139 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
134 private Vector3 m_lastPosition; 140 private Vector3 m_lastPosition;
141 private Vector3 m_lastWorldPosition;
135 private Quaternion m_lastRotation; 142 private Quaternion m_lastRotation;
136 private Vector3 m_lastVelocity; 143 private Vector3 m_lastVelocity;
137 //private int m_lastTerseSent; 144 //private int m_lastTerseSent;
138 145
139 private Vector3? m_forceToApply; 146 private Vector3? m_forceToApply;
147 private int m_userFlags;
148 public int UserFlags
149 {
150 get { return m_userFlags; }
151 }
140 private TeleportFlags m_teleportFlags; 152 private TeleportFlags m_teleportFlags;
141 public TeleportFlags TeleportFlags 153 public TeleportFlags TeleportFlags
142 { 154 {
@@ -161,6 +173,9 @@ namespace OpenSim.Region.Framework.Scenes
161 173
162 private int m_perfMonMS; 174 private int m_perfMonMS;
163 175
176 private bool m_flyingOld; // add for fly velocity control
177 public bool m_wasFlying; // add for fly velocity control
178
164 private const int LAND_VELOCITYMAG_MAX = 12; 179 private const int LAND_VELOCITYMAG_MAX = 12;
165 180
166 public bool IsRestrictedToRegion; 181 public bool IsRestrictedToRegion;
@@ -171,7 +186,7 @@ namespace OpenSim.Region.Framework.Scenes
171 186
172 protected ulong crossingFromRegion; 187 protected ulong crossingFromRegion;
173 188
174 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 189 private readonly Vector3[] Dir_Vectors = new Vector3[11];
175 190
176 191
177 protected Timer m_reprioritization_timer; 192 protected Timer m_reprioritization_timer;
@@ -186,12 +201,14 @@ namespace OpenSim.Region.Framework.Scenes
186 private bool m_autopilotMoving; 201 private bool m_autopilotMoving;
187 private Vector3 m_autoPilotTarget; 202 private Vector3 m_autoPilotTarget;
188 private bool m_sitAtAutoTarget; 203 private bool m_sitAtAutoTarget;
204 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
189 205
190 private string m_nextSitAnimation = String.Empty; 206 private string m_nextSitAnimation = String.Empty;
191 207
192 //PauPaw:Proper PID Controler for autopilot************ 208 //PauPaw:Proper PID Controler for autopilot************
193 public bool MovingToTarget { get; private set; } 209 public bool MovingToTarget { get; private set; }
194 public Vector3 MoveToPositionTarget { get; private set; } 210 public Vector3 MoveToPositionTarget { get; private set; }
211 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
195 212
196 /// <summary> 213 /// <summary>
197 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying). 214 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying).
@@ -201,7 +218,13 @@ namespace OpenSim.Region.Framework.Scenes
201 private bool m_followCamAuto; 218 private bool m_followCamAuto;
202 219
203 private int m_movementUpdateCount; 220 private int m_movementUpdateCount;
221 private int m_lastColCount = -1; //KF: Look for Collision chnages
222 private int m_updateCount = 0; //KF: Update Anims for a while
223 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
204 private const int NumMovementsBetweenRayCast = 5; 224 private const int NumMovementsBetweenRayCast = 5;
225 private List<uint> m_lastColliders = new List<uint>();
226
227 private object m_syncRoot = new Object();
205 228
206 private bool CameraConstraintActive; 229 private bool CameraConstraintActive;
207 //private int m_moveToPositionStateStatus; 230 //private int m_moveToPositionStateStatus;
@@ -242,7 +265,9 @@ namespace OpenSim.Region.Framework.Scenes
242 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 265 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
243 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 266 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
244 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 267 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
245 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 268 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
269 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
270 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
246 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 271 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
247 } 272 }
248 273
@@ -478,9 +503,11 @@ namespace OpenSim.Region.Framework.Scenes
478 { 503 {
479 get 504 get
480 { 505 {
481 if (PhysicsActor != null) 506 PhysicsActor actor = m_physicsActor;
482 { 507// if (actor != null)
483 m_pos = PhysicsActor.Position; 508 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
509 {
510 m_pos = actor.Position;
484 511
485// m_log.DebugFormat( 512// m_log.DebugFormat(
486// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!", 513// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!",
@@ -506,7 +533,7 @@ namespace OpenSim.Region.Framework.Scenes
506 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 533 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
507 if (part != null) 534 if (part != null)
508 { 535 {
509 return ParentPosition + (m_pos * part.GetWorldRotation()); 536 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
510 } 537 }
511 else 538 else
512 { 539 {
@@ -532,8 +559,10 @@ namespace OpenSim.Region.Framework.Scenes
532 } 559 }
533 } 560 }
534 561
535 m_pos = value; 562// Changed this to update unconditionally to make npose work
536 ParentPosition = Vector3.Zero; 563// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
564 m_pos = value;
565 m_parentPosition = Vector3.Zero;
537 566
538// m_log.DebugFormat( 567// m_log.DebugFormat(
539// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 568// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
@@ -591,15 +620,39 @@ namespace OpenSim.Region.Framework.Scenes
591 } 620 }
592 } 621 }
593 622
623 public Quaternion OffsetRotation
624 {
625 get { return m_offsetRotation; }
626 set { m_offsetRotation = value; }
627 }
594 private Quaternion m_bodyRot = Quaternion.Identity; 628 private Quaternion m_bodyRot = Quaternion.Identity;
595 629
596 public Quaternion Rotation 630 public Quaternion Rotation
597 { 631 {
598 get { return m_bodyRot; } 632 get {
599 set 633 if (m_parentID != 0)
600 { 634 {
635 if (m_offsetRotation != null)
636 {
637 return m_offsetRotation;
638 }
639 else
640 {
641 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
642 }
643
644 }
645 else
646 {
647 return m_bodyRot;
648 }
649 }
650 set {
601 m_bodyRot = value; 651 m_bodyRot = value;
602// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 652 if (m_parentID != 0)
653 {
654 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
655 }
603 } 656 }
604 } 657 }
605 658
@@ -619,11 +672,21 @@ namespace OpenSim.Region.Framework.Scenes
619 672
620 private uint m_parentID; 673 private uint m_parentID;
621 674
675
676 private UUID m_linkedPrim;
677
622 public uint ParentID 678 public uint ParentID
623 { 679 {
624 get { return m_parentID; } 680 get { return m_parentID; }
625 set { m_parentID = value; } 681 set { m_parentID = value; }
626 } 682 }
683
684 public UUID LinkedPrim
685 {
686 get { return m_linkedPrim; }
687 set { m_linkedPrim = value; }
688 }
689
627 public float Health 690 public float Health
628 { 691 {
629 get { return m_health; } 692 get { return m_health; }
@@ -755,6 +818,7 @@ namespace OpenSim.Region.Framework.Scenes
755 m_localId = m_scene.AllocateLocalId(); 818 m_localId = m_scene.AllocateLocalId();
756 819
757 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 820 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
821 m_userFlags = account.UserFlags;
758 822
759 if (account != null) 823 if (account != null)
760 UserLevel = account.UserLevel; 824 UserLevel = account.UserLevel;
@@ -773,10 +837,7 @@ namespace OpenSim.Region.Framework.Scenes
773 m_reprioritization_timer.AutoReset = false; 837 m_reprioritization_timer.AutoReset = false;
774 838
775 AdjustKnownSeeds(); 839 AdjustKnownSeeds();
776
777 // TODO: I think, this won't send anything, as we are still a child here...
778 Animator.TrySetMovementAnimation("STAND"); 840 Animator.TrySetMovementAnimation("STAND");
779
780 // we created a new ScenePresence (a new child agent) in a fresh region. 841 // we created a new ScenePresence (a new child agent) in a fresh region.
781 // Request info about all the (root) agents in this region 842 // Request info about all the (root) agents in this region
782 // Note: This won't send data *to* other clients in that region (children don't send) 843 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -817,26 +878,30 @@ namespace OpenSim.Region.Framework.Scenes
817 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 878 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
818 Dir_Vectors[4] = Vector3.UnitZ; //UP 879 Dir_Vectors[4] = Vector3.UnitZ; //UP
819 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 880 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
820 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 881 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
821 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 882 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
822 Dir_Vectors[7] = -Vector3.UnitX; //BACK 883 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
884 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
885 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
823 } 886 }
824 887
825 private Vector3[] GetWalkDirectionVectors() 888 private Vector3[] GetWalkDirectionVectors()
826 { 889 {
827 Vector3[] vector = new Vector3[9]; 890 Vector3[] vector = new Vector3[11];
828 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z); //FORWARD 891 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
829 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK 892 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
830 vector[2] = Vector3.UnitY; //LEFT 893 vector[2] = Vector3.UnitY; //LEFT
831 vector[3] = -Vector3.UnitY; //RIGHT 894 vector[3] = -Vector3.UnitY; //RIGHT
832 vector[4] = new Vector3(CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 895 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
833 vector[5] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 896 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
834 vector[8] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 897 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
835 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z) * 2); //FORWARD Nudge 898 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
836 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK Nudge 899 vector[8] = Vector3.UnitY; //LEFT_NUDGE
900 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
901 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
837 return vector; 902 return vector;
838 } 903 }
839 904
840 #endregion 905 #endregion
841 906
842 public uint GenerateClientFlags(UUID ObjectID) 907 public uint GenerateClientFlags(UUID ObjectID)
@@ -851,6 +916,8 @@ namespace OpenSim.Region.Framework.Scenes
851 /// </summary> 916 /// </summary>
852 public void SendPrimUpdates() 917 public void SendPrimUpdates()
853 { 918 {
919 m_sceneViewer.SendPrimUpdates();
920
854 SceneViewer.SendPrimUpdates(); 921 SceneViewer.SendPrimUpdates();
855 } 922 }
856 923
@@ -896,6 +963,62 @@ namespace OpenSim.Region.Framework.Scenes
896 pos.Y = crossedBorder.BorderLine.Z - 1; 963 pos.Y = crossedBorder.BorderLine.Z - 1;
897 } 964 }
898 965
966 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
967 if (land != null)
968 {
969 // If we come in via login, landmark or map, we want to
970 // honor landing points. If we come in via Lure, we want
971 // to ignore them.
972 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
973 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
974 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
975 {
976 // Don't restrict gods, estate managers, or land owners to
977 // the TP point. This behaviour mimics agni.
978 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
979 land.LandData.UserLocation != Vector3.Zero &&
980 GodLevel < 200 &&
981 ((land.LandData.OwnerID != m_uuid &&
982 (!m_scene.Permissions.IsGod(m_uuid)) &&
983 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
984 {
985 pos = land.LandData.UserLocation;
986 }
987 }
988
989 land.SendLandUpdateToClient(ControllingClient);
990 }
991
992 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
993 {
994 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
995
996 if (pos.X < 0)
997 {
998 emergencyPos.X = (int)Constants.RegionSize + pos.X;
999 if (!(pos.Y < 0))
1000 emergencyPos.Y = pos.Y;
1001 if (!(pos.Z < 0))
1002 emergencyPos.Z = pos.Z;
1003 }
1004 if (pos.Y < 0)
1005 {
1006 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
1007 if (!(pos.X < 0))
1008 emergencyPos.X = pos.X;
1009 if (!(pos.Z < 0))
1010 emergencyPos.Z = pos.Z;
1011 }
1012 if (pos.Z < 0)
1013 {
1014 emergencyPos.Z = 128;
1015 if (!(pos.Y < 0))
1016 emergencyPos.Y = pos.Y;
1017 if (!(pos.X < 0))
1018 emergencyPos.X = pos.X;
1019 }
1020 }
1021
899 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1022 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
900 { 1023 {
901 m_log.WarnFormat( 1024 m_log.WarnFormat(
@@ -1028,16 +1151,21 @@ namespace OpenSim.Region.Framework.Scenes
1028 /// <summary> 1151 /// <summary>
1029 /// Removes physics plugin scene representation of this agent if it exists. 1152 /// Removes physics plugin scene representation of this agent if it exists.
1030 /// </summary> 1153 /// </summary>
1031 private void RemoveFromPhysicalScene() 1154 public void RemoveFromPhysicalScene()
1032 { 1155 {
1033 if (PhysicsActor != null) 1156 if (PhysicsActor != null)
1034 { 1157 {
1035 PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1158 try
1036 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1159 {
1037 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1160 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1038 PhysicsActor.UnSubscribeEvents(); 1161 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1039 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1162 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1040 PhysicsActor = null; 1163 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1164 m_physicsActor.UnSubscribeEvents();
1165 PhysicsActor = null;
1166 }
1167 catch
1168 { }
1041 } 1169 }
1042 } 1170 }
1043 1171
@@ -1053,10 +1181,12 @@ namespace OpenSim.Region.Framework.Scenes
1053 1181
1054 RemoveFromPhysicalScene(); 1182 RemoveFromPhysicalScene();
1055 Velocity = Vector3.Zero; 1183 Velocity = Vector3.Zero;
1184 CheckLandingPoint(ref pos);
1056 AbsolutePosition = pos; 1185 AbsolutePosition = pos;
1057 AddToPhysicalScene(isFlying); 1186 AddToPhysicalScene(isFlying);
1058 1187
1059 SendTerseUpdateToAllClients(); 1188 SendTerseUpdateToAllClients();
1189
1060 } 1190 }
1061 1191
1062 public void TeleportWithMomentum(Vector3 pos) 1192 public void TeleportWithMomentum(Vector3 pos)
@@ -1066,6 +1196,7 @@ namespace OpenSim.Region.Framework.Scenes
1066 isFlying = PhysicsActor.Flying; 1196 isFlying = PhysicsActor.Flying;
1067 1197
1068 RemoveFromPhysicalScene(); 1198 RemoveFromPhysicalScene();
1199 CheckLandingPoint(ref pos);
1069 AbsolutePosition = pos; 1200 AbsolutePosition = pos;
1070 AddToPhysicalScene(isFlying); 1201 AddToPhysicalScene(isFlying);
1071 1202
@@ -1273,11 +1404,12 @@ namespace OpenSim.Region.Framework.Scenes
1273 /// <summary> 1404 /// <summary>
1274 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1405 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1275 /// </summary> 1406 /// </summary>
1407 /// <summary>
1408 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1409 /// </summary>
1276 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1410 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1277 { 1411 {
1278// m_log.DebugFormat( 1412 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1279// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1280// Scene.RegionInfo.RegionName, remoteClient.Name);
1281 1413
1282 //if (IsChildAgent) 1414 //if (IsChildAgent)
1283 //{ 1415 //{
@@ -1354,6 +1486,10 @@ namespace OpenSim.Region.Framework.Scenes
1354 1486
1355 #endregion Inputs 1487 #endregion Inputs
1356 1488
1489 // Make anims work for client side autopilot
1490 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
1491 m_updateCount = UPDATE_COUNT;
1492
1357 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) 1493 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
1358 { 1494 {
1359 StandUp(); 1495 StandUp();
@@ -1384,6 +1520,9 @@ namespace OpenSim.Region.Framework.Scenes
1384 1520
1385 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1521 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1386 { 1522 {
1523 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1524 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1525
1387 // TODO: This doesn't prevent the user from walking yet. 1526 // TODO: This doesn't prevent the user from walking yet.
1388 // Setting parent ID would fix this, if we knew what value 1527 // Setting parent ID would fix this, if we knew what value
1389 // to use. Or we could add a m_isSitting variable. 1528 // to use. Or we could add a m_isSitting variable.
@@ -1473,7 +1612,7 @@ namespace OpenSim.Region.Framework.Scenes
1473 1612
1474 if ((MovementFlag & (byte)(uint)DCF) == 0) 1613 if ((MovementFlag & (byte)(uint)DCF) == 0)
1475 { 1614 {
1476 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1615 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1477 { 1616 {
1478 MovementFlag |= (byte)nudgehack; 1617 MovementFlag |= (byte)nudgehack;
1479 } 1618 }
@@ -1485,13 +1624,13 @@ namespace OpenSim.Region.Framework.Scenes
1485 } 1624 }
1486 else 1625 else
1487 { 1626 {
1488 if ((MovementFlag & (byte)(uint)DCF) != 0 || 1627 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1489 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1628 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1490 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1629 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1491 ) // This or is for Nudge forward 1630 ) // This or is for Nudge forward
1492 { 1631 {
1493// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1632 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1494 MovementFlag -= ((byte)(uint)DCF); 1633 m_movementflag -= ((byte)(uint)DCF);
1495 update_movementflag = true; 1634 update_movementflag = true;
1496 1635
1497 /* 1636 /*
@@ -1552,21 +1691,21 @@ namespace OpenSim.Region.Framework.Scenes
1552 // which occurs later in the main scene loop 1691 // which occurs later in the main scene loop
1553 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1692 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1554 { 1693 {
1555// m_log.DebugFormat( 1694 // m_log.DebugFormat(
1556// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1695 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1557// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1696 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1558 1697
1559 AddNewMovement(agent_control_v3); 1698 AddNewMovement(agent_control_v3);
1560 } 1699 }
1561// else 1700 // else
1562// { 1701 // {
1563// if (!update_movementflag) 1702 // if (!update_movementflag)
1564// { 1703 // {
1565// m_log.DebugFormat( 1704 // m_log.DebugFormat(
1566// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1705 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1567// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1706 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1568// } 1707 // }
1569// } 1708 // }
1570 1709
1571 if (update_movementflag && ParentID == 0) 1710 if (update_movementflag && ParentID == 0)
1572 Animator.UpdateMovementAnimations(); 1711 Animator.UpdateMovementAnimations();
@@ -1588,20 +1727,20 @@ namespace OpenSim.Region.Framework.Scenes
1588 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1727 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1589 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1728 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1590 { 1729 {
1591// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1730 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1592 1731
1593 bool updated = false; 1732 bool updated = false;
1594 1733
1595// m_log.DebugFormat( 1734 // m_log.DebugFormat(
1596// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1735 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1597// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1736 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1598 1737
1599 if (!m_autopilotMoving) 1738 if (!m_autopilotMoving)
1600 { 1739 {
1601 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1740 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1602// m_log.DebugFormat( 1741 // m_log.DebugFormat(
1603// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1742 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1604// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1743 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1605 1744
1606 // Check the error term of the current position in relation to the target position 1745 // Check the error term of the current position in relation to the target position
1607 if (distanceToTarget <= 1) 1746 if (distanceToTarget <= 1)
@@ -1624,7 +1763,7 @@ namespace OpenSim.Region.Framework.Scenes
1624 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1763 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1625 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1764 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1626 // Ignore z component of vector 1765 // Ignore z component of vector
1627// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1766 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1628 LocalVectorToTarget3D.Normalize(); 1767 LocalVectorToTarget3D.Normalize();
1629 1768
1630 // update avatar movement flags. the avatar coordinate system is as follows: 1769 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1690,9 +1829,9 @@ namespace OpenSim.Region.Framework.Scenes
1690 updated = true; 1829 updated = true;
1691 } 1830 }
1692 1831
1693// m_log.DebugFormat( 1832 // m_log.DebugFormat(
1694// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1833 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1695// LocalVectorToTarget3D, agent_control_v3, Name); 1834 // LocalVectorToTarget3D, agent_control_v3, Name);
1696 1835
1697 agent_control_v3 += LocalVectorToTarget3D; 1836 agent_control_v3 += LocalVectorToTarget3D;
1698 } 1837 }
@@ -1721,9 +1860,12 @@ namespace OpenSim.Region.Framework.Scenes
1721 /// </param> 1860 /// </param>
1722 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget) 1861 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget)
1723 { 1862 {
1724 m_log.DebugFormat( 1863 if (SitGround)
1725 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", 1864 StandUp();
1726 Name, pos, m_scene.RegionInfo.RegionName); 1865
1866// m_log.DebugFormat(
1867// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1868// Name, pos, m_scene.RegionInfo.RegionName);
1727 1869
1728 if (pos.X < 0 || pos.X >= Constants.RegionSize 1870 if (pos.X < 0 || pos.X >= Constants.RegionSize
1729 || pos.Y < 0 || pos.Y >= Constants.RegionSize 1871 || pos.Y < 0 || pos.Y >= Constants.RegionSize
@@ -1749,9 +1891,9 @@ namespace OpenSim.Region.Framework.Scenes
1749 if (pos.Z - terrainHeight < 0.2) 1891 if (pos.Z - terrainHeight < 0.2)
1750 pos.Z = terrainHeight; 1892 pos.Z = terrainHeight;
1751 1893
1752 m_log.DebugFormat( 1894// m_log.DebugFormat(
1753 "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", 1895// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
1754 Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); 1896// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
1755 1897
1756 if (noFly) 1898 if (noFly)
1757 PhysicsActor.Flying = false; 1899 PhysicsActor.Flying = false;
@@ -1787,7 +1929,7 @@ namespace OpenSim.Region.Framework.Scenes
1787 /// </summary> 1929 /// </summary>
1788 public void ResetMoveToTarget() 1930 public void ResetMoveToTarget()
1789 { 1931 {
1790 m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 1932// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1791 1933
1792 MovingToTarget = false; 1934 MovingToTarget = false;
1793 MoveToPositionTarget = Vector3.Zero; 1935 MoveToPositionTarget = Vector3.Zero;
@@ -1813,7 +1955,7 @@ namespace OpenSim.Region.Framework.Scenes
1813 Velocity = Vector3.Zero; 1955 Velocity = Vector3.Zero;
1814 SendAvatarDataToAllAgents(); 1956 SendAvatarDataToAllAgents();
1815 1957
1816 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1958 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1817 } 1959 }
1818 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1960 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1819 m_requestedSitTargetUUID = UUID.Zero; 1961 m_requestedSitTargetUUID = UUID.Zero;
@@ -1850,25 +1992,22 @@ namespace OpenSim.Region.Framework.Scenes
1850 1992
1851 if (ParentID != 0) 1993 if (ParentID != 0)
1852 { 1994 {
1853 m_log.Debug("StandupCode Executed"); 1995 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1854 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
1855 if (part != null) 1996 if (part != null)
1856 { 1997 {
1998 part.TaskInventory.LockItemsForRead(true);
1857 TaskInventoryDictionary taskIDict = part.TaskInventory; 1999 TaskInventoryDictionary taskIDict = part.TaskInventory;
1858 if (taskIDict != null) 2000 if (taskIDict != null)
1859 { 2001 {
1860 lock (taskIDict) 2002 foreach (UUID taskID in taskIDict.Keys)
1861 { 2003 {
1862 foreach (UUID taskID in taskIDict.Keys) 2004 UnRegisterControlEventsToScript(LocalId, taskID);
1863 { 2005 taskIDict[taskID].PermsMask &= ~(
1864 UnRegisterControlEventsToScript(LocalId, taskID); 2006 2048 | //PERMISSION_CONTROL_CAMERA
1865 taskIDict[taskID].PermsMask &= ~( 2007 4); // PERMISSION_TAKE_CONTROLS
1866 2048 | //PERMISSION_CONTROL_CAMERA
1867 4); // PERMISSION_TAKE_CONTROLS
1868 }
1869 } 2008 }
1870
1871 } 2009 }
2010 part.TaskInventory.LockItemsForRead(false);
1872 // Reset sit target. 2011 // Reset sit target.
1873 if (part.GetAvatarOnSitTarget() == UUID) 2012 if (part.GetAvatarOnSitTarget() == UUID)
1874 part.SitTargetAvatar = UUID.Zero; 2013 part.SitTargetAvatar = UUID.Zero;
@@ -1877,21 +2016,60 @@ namespace OpenSim.Region.Framework.Scenes
1877 ParentPosition = part.GetWorldPosition(); 2016 ParentPosition = part.GetWorldPosition();
1878 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2017 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1879 } 2018 }
1880 2019 // part.GetWorldRotation() is the rotation of the object being sat on
1881 if (PhysicsActor == null) 2020 // Rotation is the sittiing Av's rotation
2021
2022 Quaternion partRot;
2023// if (part.LinkNum == 1)
2024// { // Root prim of linkset
2025// partRot = part.ParentGroup.RootPart.RotationOffset;
2026// }
2027// else
2028// { // single or child prim
2029
2030// }
2031 if (part == null) //CW: Part may be gone. llDie() for example.
1882 { 2032 {
1883 AddToPhysicalScene(false); 2033 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
2034 }
2035 else
2036 {
2037 partRot = part.GetWorldRotation();
1884 } 2038 }
1885 2039
1886 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2040 Quaternion partIRot = Quaternion.Inverse(partRot);
1887 ParentPosition = Vector3.Zero;
1888 2041
1889 ParentID = 0; 2042 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
2043 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
2044
2045
2046 if (m_physicsActor == null)
2047 {
2048 AddToPhysicalScene(false);
2049 }
2050 //CW: If the part isn't null then we can set the current position
2051 if (part != null)
2052 {
2053 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
2054 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2055 part.IsOccupied = false;
2056 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2057 }
2058 else
2059 {
2060 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2061 AbsolutePosition = m_lastWorldPosition;
2062 }
2063
2064 m_parentPosition = Vector3.Zero;
2065 m_parentID = 0;
2066 m_linkedPrim = UUID.Zero;
2067 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1890 SendAvatarDataToAllAgents(); 2068 SendAvatarDataToAllAgents();
1891 m_requestedSitTargetID = 0; 2069 m_requestedSitTargetID = 0;
1892 } 2070 }
1893 2071
1894 Animator.TrySetMovementAnimation("STAND"); 2072 Animator.UpdateMovementAnimations();
1895 } 2073 }
1896 2074
1897 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) 2075 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -1921,13 +2099,9 @@ namespace OpenSim.Region.Framework.Scenes
1921 Vector3 avSitOffSet = part.SitTargetPosition; 2099 Vector3 avSitOffSet = part.SitTargetPosition;
1922 Quaternion avSitOrientation = part.SitTargetOrientation; 2100 Quaternion avSitOrientation = part.SitTargetOrientation;
1923 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2101 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1924 2102 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1925 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2103 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1926 bool SitTargetisSet = 2104 if (SitTargetisSet && !SitTargetOccupied)
1927 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1928 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1929
1930 if (SitTargetisSet && SitTargetUnOccupied)
1931 { 2105 {
1932 //switch the target to this prim 2106 //switch the target to this prim
1933 return part; 2107 return part;
@@ -1941,85 +2115,168 @@ namespace OpenSim.Region.Framework.Scenes
1941 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2115 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1942 { 2116 {
1943 bool autopilot = true; 2117 bool autopilot = true;
2118 Vector3 autopilotTarget = new Vector3();
2119 Quaternion sitOrientation = Quaternion.Identity;
1944 Vector3 pos = new Vector3(); 2120 Vector3 pos = new Vector3();
1945 Quaternion sitOrientation = pSitOrientation;
1946 Vector3 cameraEyeOffset = Vector3.Zero; 2121 Vector3 cameraEyeOffset = Vector3.Zero;
1947 Vector3 cameraAtOffset = Vector3.Zero; 2122 Vector3 cameraAtOffset = Vector3.Zero;
1948 bool forceMouselook = false; 2123 bool forceMouselook = false;
1949 2124
1950 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2125 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1951 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2126 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1952 if (part != null) 2127 if (part == null) return;
2128
2129 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2130 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2131
2132 // part is the prim to sit on
2133 // offset is the world-ref vector distance from that prim center to the click-spot
2134 // UUID is the UUID of the Avatar doing the clicking
2135
2136 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2137
2138 // Is a sit target available?
2139 Vector3 avSitOffSet = part.SitTargetPosition;
2140 Quaternion avSitOrientation = part.SitTargetOrientation;
2141
2142 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2143 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2144 Quaternion partRot;
2145// if (part.LinkNum == 1)
2146// { // Root prim of linkset
2147// partRot = part.ParentGroup.RootPart.RotationOffset;
2148// }
2149// else
2150// { // single or child prim
2151 partRot = part.GetWorldRotation();
2152// }
2153 Quaternion partIRot = Quaternion.Inverse(partRot);
2154//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2155 // Sit analysis rewritten by KF 091125
2156 if (SitTargetisSet) // scipted sit
1953 { 2157 {
1954 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2158 if (!part.IsOccupied)
1955 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2159 {
1956 2160//Console.WriteLine("Scripted, unoccupied");
1957 // Is a sit target available? 2161 part.SitTargetAvatar = UUID; // set that Av will be on it
1958 Vector3 avSitOffSet = part.SitTargetPosition; 2162 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1959 Quaternion avSitOrientation = part.SitTargetOrientation; 2163
1960 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2164 Quaternion nrot = avSitOrientation;
1961 2165 if (!part.IsRoot)
1962 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1963 bool SitTargetisSet =
1964 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1965 (
1966 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1967 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1968 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1969 )
1970 ));
1971
1972 if (SitTargetisSet && SitTargetUnOccupied)
1973 {
1974 part.SitTargetAvatar = UUID;
1975 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1976 sitOrientation = avSitOrientation;
1977 autopilot = false;
1978 }
1979 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1980
1981 pos = part.AbsolutePosition + offset;
1982 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1983 //{
1984 // offset = pos;
1985 //autopilot = false;
1986 //}
1987 if (PhysicsActor != null)
1988 {
1989 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1990 // We can remove the physicsActor until they stand up.
1991 m_sitAvatarHeight = PhysicsActor.Size.Z;
1992
1993 if (autopilot)
1994 { 2166 {
1995 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2167 nrot = part.RotationOffset * avSitOrientation;
1996 {
1997 autopilot = false;
1998
1999 RemoveFromPhysicalScene();
2000 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2001 }
2002 } 2168 }
2003 else 2169 sitOrientation = nrot; // Change rotatione to the scripted one
2170 OffsetRotation = nrot;
2171 autopilot = false; // Jump direct to scripted llSitPos()
2172 }
2173 else
2174 {
2175//Console.WriteLine("Scripted, occupied");
2176 return;
2177 }
2178 }
2179 else // Not Scripted
2180 {
2181 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
2182 {
2183 // large prim & offset, ignore if other Avs sitting
2184// offset.Z -= 0.05f;
2185 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2186 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2187
2188//Console.WriteLine(" offset ={0}", offset);
2189//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2190//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2191
2192 }
2193 else // small offset
2194 {
2195//Console.WriteLine("Small offset");
2196 if (!part.IsOccupied)
2197 {
2198 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2199 autopilotTarget = part.AbsolutePosition;
2200//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2201 }
2202 else return; // occupied small
2203 } // end large/small
2204 } // end Scripted/not
2205
2206 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2207
2208 cameraAtOffset = part.GetCameraAtOffset();
2209 cameraEyeOffset = part.GetCameraEyeOffset();
2210 forceMouselook = part.GetForceMouselook();
2211 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2212 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2213
2214 if (m_physicsActor != null)
2215 {
2216 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2217 // We can remove the physicsActor until they stand up.
2218 m_sitAvatarHeight = m_physicsActor.Size.Z;
2219 if (autopilot)
2220 { // its not a scripted sit
2221// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2222 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
2004 { 2223 {
2224 autopilot = false; // close enough
2225 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2226 Not using the part's position because returning the AV to the last known standing
2227 position is likely to be more friendly, isn't it? */
2005 RemoveFromPhysicalScene(); 2228 RemoveFromPhysicalScene();
2006 } 2229 Velocity = Vector3.Zero;
2230 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2231 } // else the autopilot will get us close
2232 }
2233 else
2234 { // its a scripted sit
2235 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2236 I *am* using the part's position this time because we have no real idea how far away
2237 the avatar is from the sit target. */
2238 RemoveFromPhysicalScene();
2239 Velocity = Vector3.Zero;
2007 } 2240 }
2008
2009 cameraAtOffset = part.GetCameraAtOffset();
2010 cameraEyeOffset = part.GetCameraEyeOffset();
2011 forceMouselook = part.GetForceMouselook();
2012 } 2241 }
2013 2242 else return; // physactor is null!
2014 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2243
2015 m_requestedSitTargetUUID = targetID; 2244 Vector3 offsetr; // = offset * partIRot;
2245 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2246 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2247 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2248 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2249 //offsetr = offset * partIRot;
2250//
2251 // }
2252 // else
2253 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2254 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2255 // (offset * partRot);
2256 // }
2257
2258//Console.WriteLine(" ");
2259//Console.WriteLine("link number ={0}", part.LinkNum);
2260//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2261//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2262//Console.WriteLine("Click offst ={0}", offset);
2263//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2264//Console.WriteLine("offsetr ={0}", offsetr);
2265//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2266//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2267
2268 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2269 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2270
2271 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
2016 // This calls HandleAgentSit twice, once from here, and the client calls 2272 // This calls HandleAgentSit twice, once from here, and the client calls
2017 // HandleAgentSit itself after it gets to the location 2273 // HandleAgentSit itself after it gets to the location
2018 // It doesn't get to the location until we've moved them there though 2274 // It doesn't get to the location until we've moved them there though
2019 // which happens in HandleAgentSit :P 2275 // which happens in HandleAgentSit :P
2020 m_autopilotMoving = autopilot; 2276 m_autopilotMoving = autopilot;
2021 m_autoPilotTarget = pos; 2277 m_autoPilotTarget = autopilotTarget;
2022 m_sitAtAutoTarget = autopilot; 2278 m_sitAtAutoTarget = autopilot;
2279 m_initialSitTarget = autopilotTarget;
2023 if (!autopilot) 2280 if (!autopilot)
2024 HandleAgentSit(remoteClient, UUID); 2281 HandleAgentSit(remoteClient, UUID);
2025 } 2282 }
@@ -2284,47 +2541,131 @@ namespace OpenSim.Region.Framework.Scenes
2284 { 2541 {
2285 if (part != null) 2542 if (part != null)
2286 { 2543 {
2544//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2287 if (part.GetAvatarOnSitTarget() == UUID) 2545 if (part.GetAvatarOnSitTarget() == UUID)
2288 { 2546 {
2547//Console.WriteLine("Scripted Sit");
2548 // Scripted sit
2289 Vector3 sitTargetPos = part.SitTargetPosition; 2549 Vector3 sitTargetPos = part.SitTargetPosition;
2290 Quaternion sitTargetOrient = part.SitTargetOrientation; 2550 Quaternion sitTargetOrient = part.SitTargetOrientation;
2291
2292 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2293 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2294
2295 //Quaternion result = (sitTargetOrient * vq) * nq;
2296
2297 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2551 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2298 m_pos += SIT_TARGET_ADJUSTMENT; 2552 m_pos += SIT_TARGET_ADJUSTMENT;
2299 Rotation = sitTargetOrient; 2553 if (!part.IsRoot)
2300 //Rotation = sitTargetOrient; 2554 {
2301 ParentPosition = part.AbsolutePosition; 2555 m_pos *= part.RotationOffset;
2302 2556 }
2303 //SendTerseUpdateToAllClients(); 2557 m_bodyRot = sitTargetOrient;
2558 m_parentPosition = part.AbsolutePosition;
2559 part.IsOccupied = true;
2560 part.ParentGroup.AddAvatar(agentID);
2304 } 2561 }
2305 else 2562 else
2306 { 2563 {
2307 m_pos -= part.AbsolutePosition; 2564 // if m_avUnscriptedSitPos is zero then Av sits above center
2308 ParentPosition = part.AbsolutePosition; 2565 // Else Av sits at m_avUnscriptedSitPos
2309 } 2566
2567 // Non-scripted sit by Kitto Flora 21Nov09
2568 // Calculate angle of line from prim to Av
2569 Quaternion partIRot;
2570// if (part.LinkNum == 1)
2571// { // Root prim of linkset
2572// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2573// }
2574// else
2575// { // single or child prim
2576 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2577// }
2578 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2579 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2580 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2581 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2582 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2583 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2584 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2585 // Av sits at world euler <0,0, z>, translated by part rotation
2586 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2587
2588 m_parentPosition = part.AbsolutePosition;
2589 part.IsOccupied = true;
2590 part.ParentGroup.AddAvatar(agentID);
2591 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2592 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2593 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2594 m_avUnscriptedSitPos; // adds click offset, if any
2595 //Set up raytrace to find top surface of prim
2596 Vector3 size = part.Scale;
2597 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2598 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2599 Vector3 down = new Vector3(0f, 0f, -1f);
2600//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2601 m_scene.PhysicsScene.RaycastWorld(
2602 start, // Vector3 position,
2603 down, // Vector3 direction,
2604 mag, // float length,
2605 SitAltitudeCallback); // retMethod
2606 } // end scripted/not
2310 } 2607 }
2311 else 2608 else // no Av
2312 { 2609 {
2313 return; 2610 return;
2314 } 2611 }
2315 } 2612 }
2316 ParentID = m_requestedSitTargetID; 2613 ParentID = m_requestedSitTargetID;
2317 2614
2615 //We want our offsets to reference the root prim, not the child we may have sat on
2616 if (!part.IsRoot)
2617 {
2618 m_parentID = part.ParentGroup.RootPart.LocalId;
2619 m_pos += part.OffsetPosition;
2620 }
2621 else
2622 {
2623 m_parentID = m_requestedSitTargetID;
2624 }
2625
2626 m_linkedPrim = part.UUID;
2627 if (part.GetAvatarOnSitTarget() != UUID)
2628 {
2629 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2630 }
2318 Velocity = Vector3.Zero; 2631 Velocity = Vector3.Zero;
2319 RemoveFromPhysicalScene(); 2632 RemoveFromPhysicalScene();
2320
2321 Animator.TrySetMovementAnimation(sitAnimation); 2633 Animator.TrySetMovementAnimation(sitAnimation);
2322 SendAvatarDataToAllAgents(); 2634 SendAvatarDataToAllAgents();
2323 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2324 // So we're also sending a terse update (which has avatar rotation)
2325 // [Update] We do now.
2326 //SendTerseUpdateToAllClients(); 2635 //SendTerseUpdateToAllClients();
2327 } 2636 }
2637
2638 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2639 {
2640 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2641 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2642 if(hitYN)
2643 {
2644 // m_pos = Av offset from prim center to make look like on center
2645 // m_parentPosition = Actual center pos of prim
2646 // collisionPoint = spot on prim where we want to sit
2647 // collisionPoint.Z = global sit surface height
2648 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2649 Quaternion partIRot;
2650// if (part.LinkNum == 1)
2651/// { // Root prim of linkset
2652// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2653// }
2654// else
2655// { // single or child prim
2656 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2657// }
2658 if (m_initialSitTarget != null)
2659 {
2660 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2661 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2662 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2663 m_pos += offset;
2664 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2665 }
2666
2667 }
2668 } // End SitAltitudeCallback KF.
2328 2669
2329 /// <summary> 2670 /// <summary>
2330 /// Event handler for the 'Always run' setting on the client 2671 /// Event handler for the 'Always run' setting on the client
@@ -2354,6 +2695,19 @@ namespace OpenSim.Region.Framework.Scenes
2354 Vector3 direc = vec * Rotation; 2695 Vector3 direc = vec * Rotation;
2355 direc.Normalize(); 2696 direc.Normalize();
2356 2697
2698 if (PhysicsActor.Flying != m_flyingOld) // add for fly velocity control
2699 {
2700 m_flyingOld = PhysicsActor.Flying; // add for fly velocity control
2701 if (!PhysicsActor.Flying)
2702 m_wasFlying = true; // add for fly velocity control
2703 }
2704
2705 if (PhysicsActor.IsColliding == true)
2706 m_wasFlying = false; // add for fly velocity control
2707
2708 if ((vec.Z == 0f) && !PhysicsActor.Flying)
2709 direc.Z = 0f; // Prevent camera WASD up.
2710
2357 direc *= 0.03f * 128f * SpeedModifier; 2711 direc *= 0.03f * 128f * SpeedModifier;
2358 2712
2359 if (PhysicsActor != null) 2713 if (PhysicsActor != null)
@@ -2372,6 +2726,10 @@ namespace OpenSim.Region.Framework.Scenes
2372 // m_log.Info("[AGENT]: Stop Flying"); 2726 // m_log.Info("[AGENT]: Stop Flying");
2373 //} 2727 //}
2374 } 2728 }
2729 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2730 {
2731 direc *= 0.0f;
2732 }
2375 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding) 2733 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding)
2376 { 2734 {
2377 if (direc.Z > 2.0f) 2735 if (direc.Z > 2.0f)
@@ -2432,6 +2790,9 @@ namespace OpenSim.Region.Framework.Scenes
2432 2790
2433 CheckForSignificantMovement(); // sends update to the modules. 2791 CheckForSignificantMovement(); // sends update to the modules.
2434 } 2792 }
2793
2794 //Sending prim updates AFTER the avatar terse updates are sent
2795 SendPrimUpdates();
2435 } 2796 }
2436 2797
2437 #endregion 2798 #endregion
@@ -3203,6 +3564,7 @@ namespace OpenSim.Region.Framework.Scenes
3203 m_callbackURI = cAgent.CallbackURI; 3564 m_callbackURI = cAgent.CallbackURI;
3204 3565
3205 m_pos = cAgent.Position; 3566 m_pos = cAgent.Position;
3567
3206 m_velocity = cAgent.Velocity; 3568 m_velocity = cAgent.Velocity;
3207 CameraPosition = cAgent.Center; 3569 CameraPosition = cAgent.Center;
3208 CameraAtAxis = cAgent.AtAxis; 3570 CameraAtAxis = cAgent.AtAxis;
@@ -3352,14 +3714,28 @@ namespace OpenSim.Region.Framework.Scenes
3352 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3714 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
3353 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( 3715 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
3354 // as of this comment the interval is set in AddToPhysicalScene 3716 // as of this comment the interval is set in AddToPhysicalScene
3355 if (Animator != null) 3717 if (Animator!=null)
3356 Animator.UpdateMovementAnimations(); 3718 {
3719 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3720 { // else its will lock out other animation changes, like ground sit.
3721 Animator.UpdateMovementAnimations();
3722 m_updateCount--;
3723 }
3724 }
3357 3725
3358 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3726 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3359 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3727 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3360 3728
3361 CollisionPlane = Vector4.UnitW; 3729 CollisionPlane = Vector4.UnitW;
3362 3730
3731 // No collisions at all means we may be flying. Update always
3732 // to make falling work
3733 if (m_lastColCount != coldata.Count || coldata.Count == 0)
3734 {
3735 m_updateCount = UPDATE_COUNT;
3736 m_lastColCount = coldata.Count;
3737 }
3738
3363 if (coldata.Count != 0 && Animator != null) 3739 if (coldata.Count != 0 && Animator != null)
3364 { 3740 {
3365 switch (Animator.CurrentMovementAnimation) 3741 switch (Animator.CurrentMovementAnimation)
@@ -3389,6 +3765,148 @@ namespace OpenSim.Region.Framework.Scenes
3389 } 3765 }
3390 } 3766 }
3391 3767
3768 List<uint> thisHitColliders = new List<uint>();
3769 List<uint> endedColliders = new List<uint>();
3770 List<uint> startedColliders = new List<uint>();
3771
3772 foreach (uint localid in coldata.Keys)
3773 {
3774 thisHitColliders.Add(localid);
3775 if (!m_lastColliders.Contains(localid))
3776 {
3777 startedColliders.Add(localid);
3778 }
3779 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3780 }
3781
3782 // calculate things that ended colliding
3783 foreach (uint localID in m_lastColliders)
3784 {
3785 if (!thisHitColliders.Contains(localID))
3786 {
3787 endedColliders.Add(localID);
3788 }
3789 }
3790 //add the items that started colliding this time to the last colliders list.
3791 foreach (uint localID in startedColliders)
3792 {
3793 m_lastColliders.Add(localID);
3794 }
3795 // remove things that ended colliding from the last colliders list
3796 foreach (uint localID in endedColliders)
3797 {
3798 m_lastColliders.Remove(localID);
3799 }
3800
3801 // do event notification
3802 if (startedColliders.Count > 0)
3803 {
3804 ColliderArgs StartCollidingMessage = new ColliderArgs();
3805 List<DetectedObject> colliding = new List<DetectedObject>();
3806 foreach (uint localId in startedColliders)
3807 {
3808 if (localId == 0)
3809 continue;
3810
3811 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3812 string data = "";
3813 if (obj != null)
3814 {
3815 DetectedObject detobj = new DetectedObject();
3816 detobj.keyUUID = obj.UUID;
3817 detobj.nameStr = obj.Name;
3818 detobj.ownerUUID = obj.OwnerID;
3819 detobj.posVector = obj.AbsolutePosition;
3820 detobj.rotQuat = obj.GetWorldRotation();
3821 detobj.velVector = obj.Velocity;
3822 detobj.colliderType = 0;
3823 detobj.groupUUID = obj.GroupID;
3824 colliding.Add(detobj);
3825 }
3826 }
3827
3828 if (colliding.Count > 0)
3829 {
3830 StartCollidingMessage.Colliders = colliding;
3831
3832 foreach (SceneObjectGroup att in GetAttachments())
3833 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3834 }
3835 }
3836
3837 if (endedColliders.Count > 0)
3838 {
3839 ColliderArgs EndCollidingMessage = new ColliderArgs();
3840 List<DetectedObject> colliding = new List<DetectedObject>();
3841 foreach (uint localId in endedColliders)
3842 {
3843 if (localId == 0)
3844 continue;
3845
3846 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3847 string data = "";
3848 if (obj != null)
3849 {
3850 DetectedObject detobj = new DetectedObject();
3851 detobj.keyUUID = obj.UUID;
3852 detobj.nameStr = obj.Name;
3853 detobj.ownerUUID = obj.OwnerID;
3854 detobj.posVector = obj.AbsolutePosition;
3855 detobj.rotQuat = obj.GetWorldRotation();
3856 detobj.velVector = obj.Velocity;
3857 detobj.colliderType = 0;
3858 detobj.groupUUID = obj.GroupID;
3859 colliding.Add(detobj);
3860 }
3861 }
3862
3863 if (colliding.Count > 0)
3864 {
3865 EndCollidingMessage.Colliders = colliding;
3866
3867 foreach (SceneObjectGroup att in GetAttachments())
3868 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3869 }
3870 }
3871
3872 if (thisHitColliders.Count > 0)
3873 {
3874 ColliderArgs CollidingMessage = new ColliderArgs();
3875 List<DetectedObject> colliding = new List<DetectedObject>();
3876 foreach (uint localId in thisHitColliders)
3877 {
3878 if (localId == 0)
3879 continue;
3880
3881 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3882 string data = "";
3883 if (obj != null)
3884 {
3885 DetectedObject detobj = new DetectedObject();
3886 detobj.keyUUID = obj.UUID;
3887 detobj.nameStr = obj.Name;
3888 detobj.ownerUUID = obj.OwnerID;
3889 detobj.posVector = obj.AbsolutePosition;
3890 detobj.rotQuat = obj.GetWorldRotation();
3891 detobj.velVector = obj.Velocity;
3892 detobj.colliderType = 0;
3893 detobj.groupUUID = obj.GroupID;
3894 colliding.Add(detobj);
3895 }
3896 }
3897
3898 if (colliding.Count > 0)
3899 {
3900 CollidingMessage.Colliders = colliding;
3901
3902 lock (m_attachments)
3903 {
3904 foreach (SceneObjectGroup att in m_attachments)
3905 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3906 }
3907 }
3908 }
3909
3392 if (Invulnerable) 3910 if (Invulnerable)
3393 return; 3911 return;
3394 3912
@@ -3460,6 +3978,10 @@ namespace OpenSim.Region.Framework.Scenes
3460 { 3978 {
3461 lock (m_attachments) 3979 lock (m_attachments)
3462 { 3980 {
3981 // This may be true when the attachment comes back
3982 // from serialization after login. Clear it.
3983 gobj.IsDeleted = false;
3984
3463 m_attachments.Add(gobj); 3985 m_attachments.Add(gobj);
3464 } 3986 }
3465 } 3987 }
@@ -3823,5 +4345,39 @@ namespace OpenSim.Region.Framework.Scenes
3823 m_reprioritization_called = false; 4345 m_reprioritization_called = false;
3824 } 4346 }
3825 } 4347 }
4348
4349 private Vector3 Quat2Euler(Quaternion rot){
4350 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4351 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4352 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4353 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4354 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4355 return(new Vector3(x,y,z));
4356 }
4357
4358 private void CheckLandingPoint(ref Vector3 pos)
4359 {
4360 // Never constrain lures
4361 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4362 return;
4363
4364 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4365 return;
4366
4367 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4368
4369 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4370 land.LandData.UserLocation != Vector3.Zero &&
4371 land.LandData.OwnerID != m_uuid &&
4372 (!m_scene.Permissions.IsGod(m_uuid)) &&
4373 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4374 {
4375 float curr = Vector3.Distance(AbsolutePosition, pos);
4376 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4377 pos = land.LandData.UserLocation;
4378 else
4379 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4380 }
4381 }
3826 } 4382 }
3827} 4383}