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.cs907
1 files changed, 727 insertions, 180 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 1d77b06..aa1c15e 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 {
@@ -159,6 +171,9 @@ namespace OpenSim.Region.Framework.Scenes
159 private Vector3 m_lastChildAgentUpdatePosition; 171 private Vector3 m_lastChildAgentUpdatePosition;
160 private Vector3 m_lastChildAgentUpdateCamPosition; 172 private Vector3 m_lastChildAgentUpdateCamPosition;
161 173
174 private bool m_flyingOld; // add for fly velocity control
175 public bool m_wasFlying; // add for fly velocity control
176
162 private const int LAND_VELOCITYMAG_MAX = 12; 177 private const int LAND_VELOCITYMAG_MAX = 12;
163 178
164 public bool IsRestrictedToRegion; 179 public bool IsRestrictedToRegion;
@@ -169,7 +184,7 @@ namespace OpenSim.Region.Framework.Scenes
169 184
170 protected ulong crossingFromRegion; 185 protected ulong crossingFromRegion;
171 186
172 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 187 private readonly Vector3[] Dir_Vectors = new Vector3[11];
173 188
174 189
175 protected Timer m_reprioritization_timer; 190 protected Timer m_reprioritization_timer;
@@ -184,12 +199,14 @@ namespace OpenSim.Region.Framework.Scenes
184 private bool m_autopilotMoving; 199 private bool m_autopilotMoving;
185 private Vector3 m_autoPilotTarget; 200 private Vector3 m_autoPilotTarget;
186 private bool m_sitAtAutoTarget; 201 private bool m_sitAtAutoTarget;
202 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
187 203
188 private string m_nextSitAnimation = String.Empty; 204 private string m_nextSitAnimation = String.Empty;
189 205
190 //PauPaw:Proper PID Controler for autopilot************ 206 //PauPaw:Proper PID Controler for autopilot************
191 public bool MovingToTarget { get; private set; } 207 public bool MovingToTarget { get; private set; }
192 public Vector3 MoveToPositionTarget { get; private set; } 208 public Vector3 MoveToPositionTarget { get; private set; }
209 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
193 210
194 /// <summary> 211 /// <summary>
195 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying). 212 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying).
@@ -199,7 +216,13 @@ namespace OpenSim.Region.Framework.Scenes
199 private bool m_followCamAuto; 216 private bool m_followCamAuto;
200 217
201 private int m_movementUpdateCount; 218 private int m_movementUpdateCount;
219 private int m_lastColCount = -1; //KF: Look for Collision chnages
220 private int m_updateCount = 0; //KF: Update Anims for a while
221 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
202 private const int NumMovementsBetweenRayCast = 5; 222 private const int NumMovementsBetweenRayCast = 5;
223 private List<uint> m_lastColliders = new List<uint>();
224
225 private object m_syncRoot = new Object();
203 226
204 private bool CameraConstraintActive; 227 private bool CameraConstraintActive;
205 //private int m_moveToPositionStateStatus; 228 //private int m_moveToPositionStateStatus;
@@ -240,7 +263,9 @@ namespace OpenSim.Region.Framework.Scenes
240 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 263 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
241 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 264 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
242 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 265 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
243 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 266 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
267 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
268 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
244 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 269 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
245 } 270 }
246 271
@@ -476,9 +501,11 @@ namespace OpenSim.Region.Framework.Scenes
476 { 501 {
477 get 502 get
478 { 503 {
479 if (PhysicsActor != null) 504 PhysicsActor actor = m_physicsActor;
480 { 505// if (actor != null)
481 m_pos = PhysicsActor.Position; 506 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
507 {
508 m_pos = actor.Position;
482 509
483// m_log.DebugFormat( 510// m_log.DebugFormat(
484// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!", 511// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!",
@@ -504,7 +531,7 @@ namespace OpenSim.Region.Framework.Scenes
504 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 531 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
505 if (part != null) 532 if (part != null)
506 { 533 {
507 return ParentPosition + (m_pos * part.GetWorldRotation()); 534 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
508 } 535 }
509 else 536 else
510 { 537 {
@@ -529,8 +556,10 @@ namespace OpenSim.Region.Framework.Scenes
529 } 556 }
530 } 557 }
531 558
532 m_pos = value; 559// Changed this to update unconditionally to make npose work
533 ParentPosition = Vector3.Zero; 560// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
561 m_pos = value;
562 m_parentPosition = Vector3.Zero;
534 563
535// m_log.DebugFormat( 564// m_log.DebugFormat(
536// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 565// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
@@ -587,15 +616,39 @@ namespace OpenSim.Region.Framework.Scenes
587 } 616 }
588 } 617 }
589 618
619 public Quaternion OffsetRotation
620 {
621 get { return m_offsetRotation; }
622 set { m_offsetRotation = value; }
623 }
590 private Quaternion m_bodyRot = Quaternion.Identity; 624 private Quaternion m_bodyRot = Quaternion.Identity;
591 625
592 public Quaternion Rotation 626 public Quaternion Rotation
593 { 627 {
594 get { return m_bodyRot; } 628 get {
595 set 629 if (m_parentID != 0)
596 { 630 {
631 if (m_offsetRotation != null)
632 {
633 return m_offsetRotation;
634 }
635 else
636 {
637 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
638 }
639
640 }
641 else
642 {
643 return m_bodyRot;
644 }
645 }
646 set {
597 m_bodyRot = value; 647 m_bodyRot = value;
598// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 648 if (m_parentID != 0)
649 {
650 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
651 }
599 } 652 }
600 } 653 }
601 654
@@ -613,12 +666,15 @@ namespace OpenSim.Region.Framework.Scenes
613 set { m_isChildAgent = value; } 666 set { m_isChildAgent = value; }
614 } 667 }
615 668
669 private uint m_parentID;
670
671
616 public uint ParentID 672 public uint ParentID
617 { 673 {
618 get { return m_parentID; } 674 get { return m_parentID; }
619 set { m_parentID = value; } 675 set { m_parentID = value; }
620 } 676 }
621 private uint m_parentID; 677
622 678
623 public float Health 679 public float Health
624 { 680 {
@@ -751,6 +807,7 @@ namespace OpenSim.Region.Framework.Scenes
751 m_localId = m_scene.AllocateLocalId(); 807 m_localId = m_scene.AllocateLocalId();
752 808
753 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 809 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
810 m_userFlags = account.UserFlags;
754 811
755 if (account != null) 812 if (account != null)
756 UserLevel = account.UserLevel; 813 UserLevel = account.UserLevel;
@@ -769,10 +826,7 @@ namespace OpenSim.Region.Framework.Scenes
769 m_reprioritization_timer.AutoReset = false; 826 m_reprioritization_timer.AutoReset = false;
770 827
771 AdjustKnownSeeds(); 828 AdjustKnownSeeds();
772
773 // TODO: I think, this won't send anything, as we are still a child here...
774 Animator.TrySetMovementAnimation("STAND"); 829 Animator.TrySetMovementAnimation("STAND");
775
776 // we created a new ScenePresence (a new child agent) in a fresh region. 830 // we created a new ScenePresence (a new child agent) in a fresh region.
777 // Request info about all the (root) agents in this region 831 // Request info about all the (root) agents in this region
778 // Note: This won't send data *to* other clients in that region (children don't send) 832 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -813,26 +867,30 @@ namespace OpenSim.Region.Framework.Scenes
813 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 867 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
814 Dir_Vectors[4] = Vector3.UnitZ; //UP 868 Dir_Vectors[4] = Vector3.UnitZ; //UP
815 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 869 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
816 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 870 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
817 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 871 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
818 Dir_Vectors[7] = -Vector3.UnitX; //BACK 872 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
873 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
874 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
819 } 875 }
820 876
821 private Vector3[] GetWalkDirectionVectors() 877 private Vector3[] GetWalkDirectionVectors()
822 { 878 {
823 Vector3[] vector = new Vector3[9]; 879 Vector3[] vector = new Vector3[11];
824 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z); //FORWARD 880 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
825 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK 881 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
826 vector[2] = Vector3.UnitY; //LEFT 882 vector[2] = Vector3.UnitY; //LEFT
827 vector[3] = -Vector3.UnitY; //RIGHT 883 vector[3] = -Vector3.UnitY; //RIGHT
828 vector[4] = new Vector3(CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 884 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
829 vector[5] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 885 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
830 vector[8] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 886 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
831 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z) * 2); //FORWARD Nudge 887 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
832 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK Nudge 888 vector[8] = Vector3.UnitY; //LEFT_NUDGE
889 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
890 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
833 return vector; 891 return vector;
834 } 892 }
835 893
836 #endregion 894 #endregion
837 895
838 public uint GenerateClientFlags(UUID ObjectID) 896 public uint GenerateClientFlags(UUID ObjectID)
@@ -847,6 +905,8 @@ namespace OpenSim.Region.Framework.Scenes
847 /// </summary> 905 /// </summary>
848 public void SendPrimUpdates() 906 public void SendPrimUpdates()
849 { 907 {
908 m_sceneViewer.SendPrimUpdates();
909
850 SceneViewer.SendPrimUpdates(); 910 SceneViewer.SendPrimUpdates();
851 } 911 }
852 912
@@ -892,6 +952,62 @@ namespace OpenSim.Region.Framework.Scenes
892 pos.Y = crossedBorder.BorderLine.Z - 1; 952 pos.Y = crossedBorder.BorderLine.Z - 1;
893 } 953 }
894 954
955 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
956 if (land != null)
957 {
958 // If we come in via login, landmark or map, we want to
959 // honor landing points. If we come in via Lure, we want
960 // to ignore them.
961 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
962 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
963 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
964 {
965 // Don't restrict gods, estate managers, or land owners to
966 // the TP point. This behaviour mimics agni.
967 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
968 land.LandData.UserLocation != Vector3.Zero &&
969 GodLevel < 200 &&
970 ((land.LandData.OwnerID != m_uuid &&
971 (!m_scene.Permissions.IsGod(m_uuid)) &&
972 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
973 {
974 pos = land.LandData.UserLocation;
975 }
976 }
977
978 land.SendLandUpdateToClient(ControllingClient);
979 }
980
981 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
982 {
983 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
984
985 if (pos.X < 0)
986 {
987 emergencyPos.X = (int)Constants.RegionSize + pos.X;
988 if (!(pos.Y < 0))
989 emergencyPos.Y = pos.Y;
990 if (!(pos.Z < 0))
991 emergencyPos.Z = pos.Z;
992 }
993 if (pos.Y < 0)
994 {
995 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
996 if (!(pos.X < 0))
997 emergencyPos.X = pos.X;
998 if (!(pos.Z < 0))
999 emergencyPos.Z = pos.Z;
1000 }
1001 if (pos.Z < 0)
1002 {
1003 emergencyPos.Z = 128;
1004 if (!(pos.Y < 0))
1005 emergencyPos.Y = pos.Y;
1006 if (!(pos.X < 0))
1007 emergencyPos.X = pos.X;
1008 }
1009 }
1010
895 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1011 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
896 { 1012 {
897 m_log.WarnFormat( 1013 m_log.WarnFormat(
@@ -1024,16 +1140,21 @@ namespace OpenSim.Region.Framework.Scenes
1024 /// <summary> 1140 /// <summary>
1025 /// Removes physics plugin scene representation of this agent if it exists. 1141 /// Removes physics plugin scene representation of this agent if it exists.
1026 /// </summary> 1142 /// </summary>
1027 private void RemoveFromPhysicalScene() 1143 public void RemoveFromPhysicalScene()
1028 { 1144 {
1029 if (PhysicsActor != null) 1145 if (PhysicsActor != null)
1030 { 1146 {
1031 PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1147 try
1032 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1148 {
1033 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1149 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1034 PhysicsActor.UnSubscribeEvents(); 1150 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1035 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1151 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1036 PhysicsActor = null; 1152 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1153 m_physicsActor.UnSubscribeEvents();
1154 PhysicsActor = null;
1155 }
1156 catch
1157 { }
1037 } 1158 }
1038 } 1159 }
1039 1160
@@ -1049,10 +1170,12 @@ namespace OpenSim.Region.Framework.Scenes
1049 1170
1050 RemoveFromPhysicalScene(); 1171 RemoveFromPhysicalScene();
1051 Velocity = Vector3.Zero; 1172 Velocity = Vector3.Zero;
1173 CheckLandingPoint(ref pos);
1052 AbsolutePosition = pos; 1174 AbsolutePosition = pos;
1053 AddToPhysicalScene(isFlying); 1175 AddToPhysicalScene(isFlying);
1054 1176
1055 SendTerseUpdateToAllClients(); 1177 SendTerseUpdateToAllClients();
1178
1056 } 1179 }
1057 1180
1058 public void TeleportWithMomentum(Vector3 pos) 1181 public void TeleportWithMomentum(Vector3 pos)
@@ -1062,6 +1185,7 @@ namespace OpenSim.Region.Framework.Scenes
1062 isFlying = PhysicsActor.Flying; 1185 isFlying = PhysicsActor.Flying;
1063 1186
1064 RemoveFromPhysicalScene(); 1187 RemoveFromPhysicalScene();
1188 CheckLandingPoint(ref pos);
1065 AbsolutePosition = pos; 1189 AbsolutePosition = pos;
1066 AddToPhysicalScene(isFlying); 1190 AddToPhysicalScene(isFlying);
1067 1191
@@ -1269,11 +1393,12 @@ namespace OpenSim.Region.Framework.Scenes
1269 /// <summary> 1393 /// <summary>
1270 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1394 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1271 /// </summary> 1395 /// </summary>
1396 /// <summary>
1397 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1398 /// </summary>
1272 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1399 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1273 { 1400 {
1274// m_log.DebugFormat( 1401 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1275// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1276// Scene.RegionInfo.RegionName, remoteClient.Name);
1277 1402
1278 //if (IsChildAgent) 1403 //if (IsChildAgent)
1279 //{ 1404 //{
@@ -1348,6 +1473,10 @@ namespace OpenSim.Region.Framework.Scenes
1348 1473
1349 #endregion Inputs 1474 #endregion Inputs
1350 1475
1476 // Make anims work for client side autopilot
1477 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
1478 m_updateCount = UPDATE_COUNT;
1479
1351 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) 1480 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
1352 { 1481 {
1353 StandUp(); 1482 StandUp();
@@ -1378,6 +1507,9 @@ namespace OpenSim.Region.Framework.Scenes
1378 1507
1379 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1508 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1380 { 1509 {
1510 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1511 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1512
1381 // TODO: This doesn't prevent the user from walking yet. 1513 // TODO: This doesn't prevent the user from walking yet.
1382 // Setting parent ID would fix this, if we knew what value 1514 // Setting parent ID would fix this, if we knew what value
1383 // to use. Or we could add a m_isSitting variable. 1515 // to use. Or we could add a m_isSitting variable.
@@ -1467,7 +1599,7 @@ namespace OpenSim.Region.Framework.Scenes
1467 1599
1468 if ((MovementFlag & (byte)(uint)DCF) == 0) 1600 if ((MovementFlag & (byte)(uint)DCF) == 0)
1469 { 1601 {
1470 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1602 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1471 { 1603 {
1472 MovementFlag |= (byte)nudgehack; 1604 MovementFlag |= (byte)nudgehack;
1473 } 1605 }
@@ -1479,13 +1611,13 @@ namespace OpenSim.Region.Framework.Scenes
1479 } 1611 }
1480 else 1612 else
1481 { 1613 {
1482 if ((MovementFlag & (byte)(uint)DCF) != 0 || 1614 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1483 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1615 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1484 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1616 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1485 ) // This or is for Nudge forward 1617 ) // This or is for Nudge forward
1486 { 1618 {
1487// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1619 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1488 MovementFlag -= ((byte)(uint)DCF); 1620 m_movementflag -= ((byte)(uint)DCF);
1489 update_movementflag = true; 1621 update_movementflag = true;
1490 1622
1491 /* 1623 /*
@@ -1546,21 +1678,21 @@ namespace OpenSim.Region.Framework.Scenes
1546 // which occurs later in the main scene loop 1678 // which occurs later in the main scene loop
1547 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1679 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1548 { 1680 {
1549// m_log.DebugFormat( 1681 // m_log.DebugFormat(
1550// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1682 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1551// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1683 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1552 1684
1553 AddNewMovement(agent_control_v3); 1685 AddNewMovement(agent_control_v3);
1554 } 1686 }
1555// else 1687 // else
1556// { 1688 // {
1557// if (!update_movementflag) 1689 // if (!update_movementflag)
1558// { 1690 // {
1559// m_log.DebugFormat( 1691 // m_log.DebugFormat(
1560// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1692 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1561// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1693 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1562// } 1694 // }
1563// } 1695 // }
1564 1696
1565 if (update_movementflag && ParentID == 0) 1697 if (update_movementflag && ParentID == 0)
1566 Animator.UpdateMovementAnimations(); 1698 Animator.UpdateMovementAnimations();
@@ -1579,20 +1711,20 @@ namespace OpenSim.Region.Framework.Scenes
1579 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1711 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1580 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1712 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1581 { 1713 {
1582// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1714 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1583 1715
1584 bool updated = false; 1716 bool updated = false;
1585 1717
1586// m_log.DebugFormat( 1718 // m_log.DebugFormat(
1587// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1719 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1588// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1720 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1589 1721
1590 if (!m_autopilotMoving) 1722 if (!m_autopilotMoving)
1591 { 1723 {
1592 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1724 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1593// m_log.DebugFormat( 1725 // m_log.DebugFormat(
1594// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1726 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1595// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1727 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1596 1728
1597 // Check the error term of the current position in relation to the target position 1729 // Check the error term of the current position in relation to the target position
1598 if (distanceToTarget <= 1) 1730 if (distanceToTarget <= 1)
@@ -1615,7 +1747,7 @@ namespace OpenSim.Region.Framework.Scenes
1615 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1747 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1616 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1748 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1617 // Ignore z component of vector 1749 // Ignore z component of vector
1618// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1750 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1619 LocalVectorToTarget3D.Normalize(); 1751 LocalVectorToTarget3D.Normalize();
1620 1752
1621 // update avatar movement flags. the avatar coordinate system is as follows: 1753 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1681,9 +1813,9 @@ namespace OpenSim.Region.Framework.Scenes
1681 updated = true; 1813 updated = true;
1682 } 1814 }
1683 1815
1684// m_log.DebugFormat( 1816 // m_log.DebugFormat(
1685// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1817 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1686// LocalVectorToTarget3D, agent_control_v3, Name); 1818 // LocalVectorToTarget3D, agent_control_v3, Name);
1687 1819
1688 agent_control_v3 += LocalVectorToTarget3D; 1820 agent_control_v3 += LocalVectorToTarget3D;
1689 } 1821 }
@@ -1712,9 +1844,12 @@ namespace OpenSim.Region.Framework.Scenes
1712 /// </param> 1844 /// </param>
1713 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget) 1845 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget)
1714 { 1846 {
1715 m_log.DebugFormat( 1847 if (SitGround)
1716 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", 1848 StandUp();
1717 Name, pos, m_scene.RegionInfo.RegionName); 1849
1850// m_log.DebugFormat(
1851// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1852// Name, pos, m_scene.RegionInfo.RegionName);
1718 1853
1719 if (pos.X < 0 || pos.X >= Constants.RegionSize 1854 if (pos.X < 0 || pos.X >= Constants.RegionSize
1720 || pos.Y < 0 || pos.Y >= Constants.RegionSize 1855 || pos.Y < 0 || pos.Y >= Constants.RegionSize
@@ -1740,9 +1875,9 @@ namespace OpenSim.Region.Framework.Scenes
1740 if (pos.Z - terrainHeight < 0.2) 1875 if (pos.Z - terrainHeight < 0.2)
1741 pos.Z = terrainHeight; 1876 pos.Z = terrainHeight;
1742 1877
1743 m_log.DebugFormat( 1878// m_log.DebugFormat(
1744 "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", 1879// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
1745 Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); 1880// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
1746 1881
1747 if (noFly) 1882 if (noFly)
1748 PhysicsActor.Flying = false; 1883 PhysicsActor.Flying = false;
@@ -1778,7 +1913,7 @@ namespace OpenSim.Region.Framework.Scenes
1778 /// </summary> 1913 /// </summary>
1779 public void ResetMoveToTarget() 1914 public void ResetMoveToTarget()
1780 { 1915 {
1781 m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 1916// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1782 1917
1783 MovingToTarget = false; 1918 MovingToTarget = false;
1784 MoveToPositionTarget = Vector3.Zero; 1919 MoveToPositionTarget = Vector3.Zero;
@@ -1804,7 +1939,7 @@ namespace OpenSim.Region.Framework.Scenes
1804 Velocity = Vector3.Zero; 1939 Velocity = Vector3.Zero;
1805 SendAvatarDataToAllAgents(); 1940 SendAvatarDataToAllAgents();
1806 1941
1807 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1942 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1808 } 1943 }
1809 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1944 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1810 m_requestedSitTargetUUID = UUID.Zero; 1945 m_requestedSitTargetUUID = UUID.Zero;
@@ -1841,24 +1976,22 @@ namespace OpenSim.Region.Framework.Scenes
1841 1976
1842 if (ParentID != 0) 1977 if (ParentID != 0)
1843 { 1978 {
1844 m_log.Debug("StandupCode Executed"); 1979 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1845 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
1846 if (part != null) 1980 if (part != null)
1847 { 1981 {
1982 part.TaskInventory.LockItemsForRead(true);
1848 TaskInventoryDictionary taskIDict = part.TaskInventory; 1983 TaskInventoryDictionary taskIDict = part.TaskInventory;
1849 if (taskIDict != null) 1984 if (taskIDict != null)
1850 { 1985 {
1851 lock (taskIDict) 1986 foreach (UUID taskID in taskIDict.Keys)
1852 { 1987 {
1853 foreach (UUID taskID in taskIDict.Keys) 1988 UnRegisterControlEventsToScript(LocalId, taskID);
1854 { 1989 taskIDict[taskID].PermsMask &= ~(
1855 UnRegisterControlEventsToScript(LocalId, taskID); 1990 2048 | //PERMISSION_CONTROL_CAMERA
1856 taskIDict[taskID].PermsMask &= ~( 1991 4); // PERMISSION_TAKE_CONTROLS
1857 2048 | //PERMISSION_CONTROL_CAMERA
1858 4); // PERMISSION_TAKE_CONTROLS
1859 }
1860 } 1992 }
1861 } 1993 }
1994 part.TaskInventory.LockItemsForRead(false);
1862 1995
1863 // Reset sit target. 1996 // Reset sit target.
1864 if (part.SitTargetAvatar == UUID) 1997 if (part.SitTargetAvatar == UUID)
@@ -1869,21 +2002,59 @@ namespace OpenSim.Region.Framework.Scenes
1869 ParentPosition = part.GetWorldPosition(); 2002 ParentPosition = part.GetWorldPosition();
1870 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2003 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1871 } 2004 }
1872 2005 // part.GetWorldRotation() is the rotation of the object being sat on
1873 if (PhysicsActor == null) 2006 // Rotation is the sittiing Av's rotation
2007
2008 Quaternion partRot;
2009// if (part.LinkNum == 1)
2010// { // Root prim of linkset
2011// partRot = part.ParentGroup.RootPart.RotationOffset;
2012// }
2013// else
2014// { // single or child prim
2015
2016// }
2017 if (part == null) //CW: Part may be gone. llDie() for example.
1874 { 2018 {
1875 AddToPhysicalScene(false); 2019 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
2020 }
2021 else
2022 {
2023 partRot = part.GetWorldRotation();
1876 } 2024 }
1877 2025
1878 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2026 Quaternion partIRot = Quaternion.Inverse(partRot);
1879 ParentPosition = Vector3.Zero;
1880 2027
1881 ParentID = 0; 2028 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
2029 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
2030
2031
2032 if (m_physicsActor == null)
2033 {
2034 AddToPhysicalScene(false);
2035 }
2036 //CW: If the part isn't null then we can set the current position
2037 if (part != null)
2038 {
2039 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
2040 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2041 part.IsOccupied = false;
2042 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2043 }
2044 else
2045 {
2046 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2047 AbsolutePosition = m_lastWorldPosition;
2048 }
2049
2050 m_parentPosition = Vector3.Zero;
2051 m_parentID = 0;
2052 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1882 SendAvatarDataToAllAgents(); 2053 SendAvatarDataToAllAgents();
1883 m_requestedSitTargetID = 0; 2054 m_requestedSitTargetID = 0;
1884 } 2055 }
1885 2056
1886 Animator.TrySetMovementAnimation("STAND"); 2057 Animator.UpdateMovementAnimations();
1887 } 2058 }
1888 2059
1889 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) 2060 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -1915,9 +2086,7 @@ namespace OpenSim.Region.Framework.Scenes
1915 UUID avOnTargetAlready = part.SitTargetAvatar; 2086 UUID avOnTargetAlready = part.SitTargetAvatar;
1916 2087
1917 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2088 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1918 bool SitTargetisSet = 2089 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1919 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1920 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1921 2090
1922 if (SitTargetisSet && SitTargetUnOccupied) 2091 if (SitTargetisSet && SitTargetUnOccupied)
1923 { 2092 {
@@ -1933,87 +2102,168 @@ namespace OpenSim.Region.Framework.Scenes
1933 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2102 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1934 { 2103 {
1935 bool autopilot = true; 2104 bool autopilot = true;
2105 Vector3 autopilotTarget = new Vector3();
2106 Quaternion sitOrientation = Quaternion.Identity;
1936 Vector3 pos = new Vector3(); 2107 Vector3 pos = new Vector3();
1937 Quaternion sitOrientation = pSitOrientation;
1938 Vector3 cameraEyeOffset = Vector3.Zero; 2108 Vector3 cameraEyeOffset = Vector3.Zero;
1939 Vector3 cameraAtOffset = Vector3.Zero; 2109 Vector3 cameraAtOffset = Vector3.Zero;
1940 bool forceMouselook = false; 2110 bool forceMouselook = false;
1941 2111
1942 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2112 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1943 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2113 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1944 if (part != null) 2114 if (part == null) return;
2115
2116 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2117 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2118
2119 // part is the prim to sit on
2120 // offset is the world-ref vector distance from that prim center to the click-spot
2121 // UUID is the UUID of the Avatar doing the clicking
2122
2123 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2124
2125 // Is a sit target available?
2126 Vector3 avSitOffSet = part.SitTargetPosition;
2127 Quaternion avSitOrientation = part.SitTargetOrientation;
2128
2129 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2130 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2131 Quaternion partRot;
2132// if (part.LinkNum == 1)
2133// { // Root prim of linkset
2134// partRot = part.ParentGroup.RootPart.RotationOffset;
2135// }
2136// else
2137// { // single or child prim
2138 partRot = part.GetWorldRotation();
2139// }
2140 Quaternion partIRot = Quaternion.Inverse(partRot);
2141//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2142 // Sit analysis rewritten by KF 091125
2143 if (SitTargetisSet) // scipted sit
1945 { 2144 {
1946 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2145 if (!part.IsOccupied)
1947 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2146 {
1948 2147//Console.WriteLine("Scripted, unoccupied");
1949 // Is a sit target available? 2148 part.SitTargetAvatar = UUID; // set that Av will be on it
1950 Vector3 avSitOffSet = part.SitTargetPosition; 2149 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1951 Quaternion avSitOrientation = part.SitTargetOrientation; 2150
1952 UUID avOnTargetAlready = part.SitTargetAvatar; 2151 Quaternion nrot = avSitOrientation;
1953 2152 if (!part.IsRoot)
1954 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1955 bool SitTargetisSet =
1956 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1957 (
1958 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1959 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1960 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1961 )
1962 ));
1963
1964// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
1965
1966 if (SitTargetisSet && SitTargetUnOccupied)
1967 {
1968 part.SitTargetAvatar = UUID;
1969 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1970 sitOrientation = avSitOrientation;
1971 autopilot = false;
1972 }
1973 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1974
1975 pos = part.AbsolutePosition + offset;
1976 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1977 //{
1978 // offset = pos;
1979 //autopilot = false;
1980 //}
1981 if (PhysicsActor != null)
1982 {
1983 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1984 // We can remove the physicsActor until they stand up.
1985 m_sitAvatarHeight = PhysicsActor.Size.Z;
1986
1987 if (autopilot)
1988 { 2153 {
1989 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2154 nrot = part.RotationOffset * avSitOrientation;
1990 {
1991 autopilot = false;
1992
1993 RemoveFromPhysicalScene();
1994 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1995 }
1996 } 2155 }
1997 else 2156 sitOrientation = nrot; // Change rotatione to the scripted one
2157 OffsetRotation = nrot;
2158 autopilot = false; // Jump direct to scripted llSitPos()
2159 }
2160 else
2161 {
2162//Console.WriteLine("Scripted, occupied");
2163 return;
2164 }
2165 }
2166 else // Not Scripted
2167 {
2168 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
2169 {
2170 // large prim & offset, ignore if other Avs sitting
2171// offset.Z -= 0.05f;
2172 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2173 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2174
2175//Console.WriteLine(" offset ={0}", offset);
2176//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2177//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2178
2179 }
2180 else // small offset
2181 {
2182//Console.WriteLine("Small offset");
2183 if (!part.IsOccupied)
2184 {
2185 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2186 autopilotTarget = part.AbsolutePosition;
2187//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2188 }
2189 else return; // occupied small
2190 } // end large/small
2191 } // end Scripted/not
2192
2193 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2194
2195 cameraAtOffset = part.GetCameraAtOffset();
2196 cameraEyeOffset = part.GetCameraEyeOffset();
2197 forceMouselook = part.GetForceMouselook();
2198 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2199 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2200
2201 if (m_physicsActor != null)
2202 {
2203 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2204 // We can remove the physicsActor until they stand up.
2205 m_sitAvatarHeight = m_physicsActor.Size.Z;
2206 if (autopilot)
2207 { // its not a scripted sit
2208// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2209 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1998 { 2210 {
2211 autopilot = false; // close enough
2212 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2213 Not using the part's position because returning the AV to the last known standing
2214 position is likely to be more friendly, isn't it? */
1999 RemoveFromPhysicalScene(); 2215 RemoveFromPhysicalScene();
2000 } 2216 Velocity = Vector3.Zero;
2217 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2218 } // else the autopilot will get us close
2219 }
2220 else
2221 { // its a scripted sit
2222 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2223 I *am* using the part's position this time because we have no real idea how far away
2224 the avatar is from the sit target. */
2225 RemoveFromPhysicalScene();
2226 Velocity = Vector3.Zero;
2001 } 2227 }
2002
2003 cameraAtOffset = part.GetCameraAtOffset();
2004 cameraEyeOffset = part.GetCameraEyeOffset();
2005 forceMouselook = part.GetForceMouselook();
2006 } 2228 }
2007 2229 else return; // physactor is null!
2008 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2230
2009 m_requestedSitTargetUUID = targetID; 2231 Vector3 offsetr; // = offset * partIRot;
2232 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2233 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2234 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2235 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2236 //offsetr = offset * partIRot;
2237//
2238 // }
2239 // else
2240 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2241 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2242 // (offset * partRot);
2243 // }
2244
2245//Console.WriteLine(" ");
2246//Console.WriteLine("link number ={0}", part.LinkNum);
2247//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2248//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2249//Console.WriteLine("Click offst ={0}", offset);
2250//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2251//Console.WriteLine("offsetr ={0}", offsetr);
2252//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2253//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2254
2255 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2256 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2257
2258 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
2010 // This calls HandleAgentSit twice, once from here, and the client calls 2259 // This calls HandleAgentSit twice, once from here, and the client calls
2011 // HandleAgentSit itself after it gets to the location 2260 // HandleAgentSit itself after it gets to the location
2012 // It doesn't get to the location until we've moved them there though 2261 // It doesn't get to the location until we've moved them there though
2013 // which happens in HandleAgentSit :P 2262 // which happens in HandleAgentSit :P
2014 m_autopilotMoving = autopilot; 2263 m_autopilotMoving = autopilot;
2015 m_autoPilotTarget = pos; 2264 m_autoPilotTarget = autopilotTarget;
2016 m_sitAtAutoTarget = autopilot; 2265 m_sitAtAutoTarget = autopilot;
2266 m_initialSitTarget = autopilotTarget;
2017 if (!autopilot) 2267 if (!autopilot)
2018 HandleAgentSit(remoteClient, UUID); 2268 HandleAgentSit(remoteClient, UUID);
2019 } 2269 }
@@ -2279,45 +2529,127 @@ namespace OpenSim.Region.Framework.Scenes
2279 { 2529 {
2280 if (part.SitTargetAvatar == UUID) 2530 if (part.SitTargetAvatar == UUID)
2281 { 2531 {
2532//Console.WriteLine("Scripted Sit");
2533 // Scripted sit
2282 Vector3 sitTargetPos = part.SitTargetPosition; 2534 Vector3 sitTargetPos = part.SitTargetPosition;
2283 Quaternion sitTargetOrient = part.SitTargetOrientation; 2535 Quaternion sitTargetOrient = part.SitTargetOrientation;
2284
2285 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2286 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2287
2288 //Quaternion result = (sitTargetOrient * vq) * nq;
2289
2290 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2536 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2291 m_pos += SIT_TARGET_ADJUSTMENT; 2537 m_pos += SIT_TARGET_ADJUSTMENT;
2292 Rotation = sitTargetOrient; 2538 if (!part.IsRoot)
2293 //Rotation = sitTargetOrient; 2539 {
2294 ParentPosition = part.AbsolutePosition; 2540 m_pos *= part.RotationOffset;
2295 2541 }
2296 //SendTerseUpdateToAllClients(); 2542 m_bodyRot = sitTargetOrient;
2543 m_parentPosition = part.AbsolutePosition;
2544 part.IsOccupied = true;
2545 part.ParentGroup.AddAvatar(agentID);
2297 } 2546 }
2298 else 2547 else
2299 { 2548 {
2300 m_pos -= part.AbsolutePosition; 2549 // if m_avUnscriptedSitPos is zero then Av sits above center
2301 ParentPosition = part.AbsolutePosition; 2550 // Else Av sits at m_avUnscriptedSitPos
2302 } 2551
2552 // Non-scripted sit by Kitto Flora 21Nov09
2553 // Calculate angle of line from prim to Av
2554 Quaternion partIRot;
2555// if (part.LinkNum == 1)
2556// { // Root prim of linkset
2557// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2558// }
2559// else
2560// { // single or child prim
2561 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2562// }
2563 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2564 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2565 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2566 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2567 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2568 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2569 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2570 // Av sits at world euler <0,0, z>, translated by part rotation
2571 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2572
2573 m_parentPosition = part.AbsolutePosition;
2574 part.IsOccupied = true;
2575 part.ParentGroup.AddAvatar(agentID);
2576 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2577 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2578 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2579 m_avUnscriptedSitPos; // adds click offset, if any
2580 //Set up raytrace to find top surface of prim
2581 Vector3 size = part.Scale;
2582 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2583 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2584 Vector3 down = new Vector3(0f, 0f, -1f);
2585//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2586 m_scene.PhysicsScene.RaycastWorld(
2587 start, // Vector3 position,
2588 down, // Vector3 direction,
2589 mag, // float length,
2590 SitAltitudeCallback); // retMethod
2591 } // end scripted/not
2303 } 2592 }
2304 else 2593 else // no Av
2305 { 2594 {
2306 return; 2595 return;
2307 } 2596 }
2308 } 2597 }
2309 ParentID = m_requestedSitTargetID; 2598 ParentID = m_requestedSitTargetID;
2310 2599
2600 //We want our offsets to reference the root prim, not the child we may have sat on
2601 if (!part.IsRoot)
2602 {
2603 m_parentID = part.ParentGroup.RootPart.LocalId;
2604 m_pos += part.OffsetPosition;
2605 }
2606 else
2607 {
2608 m_parentID = m_requestedSitTargetID;
2609 }
2610
2611 if (part.SitTargetAvatar != UUID)
2612 {
2613 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2614 }
2311 Velocity = Vector3.Zero; 2615 Velocity = Vector3.Zero;
2312 RemoveFromPhysicalScene(); 2616 RemoveFromPhysicalScene();
2313
2314 Animator.TrySetMovementAnimation(sitAnimation); 2617 Animator.TrySetMovementAnimation(sitAnimation);
2315 SendAvatarDataToAllAgents(); 2618 SendAvatarDataToAllAgents();
2316 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2317 // So we're also sending a terse update (which has avatar rotation)
2318 // [Update] We do now.
2319 //SendTerseUpdateToAllClients(); 2619 //SendTerseUpdateToAllClients();
2320 } 2620 }
2621
2622 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2623 {
2624 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2625 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2626 if(hitYN)
2627 {
2628 // m_pos = Av offset from prim center to make look like on center
2629 // m_parentPosition = Actual center pos of prim
2630 // collisionPoint = spot on prim where we want to sit
2631 // collisionPoint.Z = global sit surface height
2632 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2633 Quaternion partIRot;
2634// if (part.LinkNum == 1)
2635/// { // Root prim of linkset
2636// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2637// }
2638// else
2639// { // single or child prim
2640 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2641// }
2642 if (m_initialSitTarget != null)
2643 {
2644 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2645 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2646 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2647 m_pos += offset;
2648 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2649 }
2650
2651 }
2652 } // End SitAltitudeCallback KF.
2321 2653
2322 /// <summary> 2654 /// <summary>
2323 /// Event handler for the 'Always run' setting on the client 2655 /// Event handler for the 'Always run' setting on the client
@@ -2347,6 +2679,19 @@ namespace OpenSim.Region.Framework.Scenes
2347 Vector3 direc = vec * Rotation; 2679 Vector3 direc = vec * Rotation;
2348 direc.Normalize(); 2680 direc.Normalize();
2349 2681
2682 if (PhysicsActor.Flying != m_flyingOld) // add for fly velocity control
2683 {
2684 m_flyingOld = PhysicsActor.Flying; // add for fly velocity control
2685 if (!PhysicsActor.Flying)
2686 m_wasFlying = true; // add for fly velocity control
2687 }
2688
2689 if (PhysicsActor.IsColliding == true)
2690 m_wasFlying = false; // add for fly velocity control
2691
2692 if ((vec.Z == 0f) && !PhysicsActor.Flying)
2693 direc.Z = 0f; // Prevent camera WASD up.
2694
2350 direc *= 0.03f * 128f * SpeedModifier; 2695 direc *= 0.03f * 128f * SpeedModifier;
2351 2696
2352 if (PhysicsActor != null) 2697 if (PhysicsActor != null)
@@ -2365,6 +2710,10 @@ namespace OpenSim.Region.Framework.Scenes
2365 // m_log.Info("[AGENT]: Stop Flying"); 2710 // m_log.Info("[AGENT]: Stop Flying");
2366 //} 2711 //}
2367 } 2712 }
2713 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2714 {
2715 direc *= 0.0f;
2716 }
2368 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding) 2717 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding)
2369 { 2718 {
2370 if (direc.Z > 2.0f) 2719 if (direc.Z > 2.0f)
@@ -2425,6 +2774,9 @@ namespace OpenSim.Region.Framework.Scenes
2425 2774
2426 CheckForSignificantMovement(); // sends update to the modules. 2775 CheckForSignificantMovement(); // sends update to the modules.
2427 } 2776 }
2777
2778 //Sending prim updates AFTER the avatar terse updates are sent
2779 SendPrimUpdates();
2428 } 2780 }
2429 2781
2430 #endregion 2782 #endregion
@@ -3145,6 +3497,7 @@ namespace OpenSim.Region.Framework.Scenes
3145 m_callbackURI = cAgent.CallbackURI; 3497 m_callbackURI = cAgent.CallbackURI;
3146 3498
3147 m_pos = cAgent.Position; 3499 m_pos = cAgent.Position;
3500
3148 m_velocity = cAgent.Velocity; 3501 m_velocity = cAgent.Velocity;
3149 CameraPosition = cAgent.Center; 3502 CameraPosition = cAgent.Center;
3150 CameraAtAxis = cAgent.AtAxis; 3503 CameraAtAxis = cAgent.AtAxis;
@@ -3291,14 +3644,28 @@ namespace OpenSim.Region.Framework.Scenes
3291 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3644 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
3292 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( 3645 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
3293 // as of this comment the interval is set in AddToPhysicalScene 3646 // as of this comment the interval is set in AddToPhysicalScene
3294 if (Animator != null) 3647 if (Animator!=null)
3295 Animator.UpdateMovementAnimations(); 3648 {
3649 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3650 { // else its will lock out other animation changes, like ground sit.
3651 Animator.UpdateMovementAnimations();
3652 m_updateCount--;
3653 }
3654 }
3296 3655
3297 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3656 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3298 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3657 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3299 3658
3300 CollisionPlane = Vector4.UnitW; 3659 CollisionPlane = Vector4.UnitW;
3301 3660
3661 // No collisions at all means we may be flying. Update always
3662 // to make falling work
3663 if (m_lastColCount != coldata.Count || coldata.Count == 0)
3664 {
3665 m_updateCount = UPDATE_COUNT;
3666 m_lastColCount = coldata.Count;
3667 }
3668
3302 if (coldata.Count != 0 && Animator != null) 3669 if (coldata.Count != 0 && Animator != null)
3303 { 3670 {
3304 switch (Animator.CurrentMovementAnimation) 3671 switch (Animator.CurrentMovementAnimation)
@@ -3328,6 +3695,148 @@ namespace OpenSim.Region.Framework.Scenes
3328 } 3695 }
3329 } 3696 }
3330 3697
3698 List<uint> thisHitColliders = new List<uint>();
3699 List<uint> endedColliders = new List<uint>();
3700 List<uint> startedColliders = new List<uint>();
3701
3702 foreach (uint localid in coldata.Keys)
3703 {
3704 thisHitColliders.Add(localid);
3705 if (!m_lastColliders.Contains(localid))
3706 {
3707 startedColliders.Add(localid);
3708 }
3709 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3710 }
3711
3712 // calculate things that ended colliding
3713 foreach (uint localID in m_lastColliders)
3714 {
3715 if (!thisHitColliders.Contains(localID))
3716 {
3717 endedColliders.Add(localID);
3718 }
3719 }
3720 //add the items that started colliding this time to the last colliders list.
3721 foreach (uint localID in startedColliders)
3722 {
3723 m_lastColliders.Add(localID);
3724 }
3725 // remove things that ended colliding from the last colliders list
3726 foreach (uint localID in endedColliders)
3727 {
3728 m_lastColliders.Remove(localID);
3729 }
3730
3731 // do event notification
3732 if (startedColliders.Count > 0)
3733 {
3734 ColliderArgs StartCollidingMessage = new ColliderArgs();
3735 List<DetectedObject> colliding = new List<DetectedObject>();
3736 foreach (uint localId in startedColliders)
3737 {
3738 if (localId == 0)
3739 continue;
3740
3741 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3742 string data = "";
3743 if (obj != null)
3744 {
3745 DetectedObject detobj = new DetectedObject();
3746 detobj.keyUUID = obj.UUID;
3747 detobj.nameStr = obj.Name;
3748 detobj.ownerUUID = obj.OwnerID;
3749 detobj.posVector = obj.AbsolutePosition;
3750 detobj.rotQuat = obj.GetWorldRotation();
3751 detobj.velVector = obj.Velocity;
3752 detobj.colliderType = 0;
3753 detobj.groupUUID = obj.GroupID;
3754 colliding.Add(detobj);
3755 }
3756 }
3757
3758 if (colliding.Count > 0)
3759 {
3760 StartCollidingMessage.Colliders = colliding;
3761
3762 foreach (SceneObjectGroup att in GetAttachments())
3763 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3764 }
3765 }
3766
3767 if (endedColliders.Count > 0)
3768 {
3769 ColliderArgs EndCollidingMessage = new ColliderArgs();
3770 List<DetectedObject> colliding = new List<DetectedObject>();
3771 foreach (uint localId in endedColliders)
3772 {
3773 if (localId == 0)
3774 continue;
3775
3776 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3777 string data = "";
3778 if (obj != null)
3779 {
3780 DetectedObject detobj = new DetectedObject();
3781 detobj.keyUUID = obj.UUID;
3782 detobj.nameStr = obj.Name;
3783 detobj.ownerUUID = obj.OwnerID;
3784 detobj.posVector = obj.AbsolutePosition;
3785 detobj.rotQuat = obj.GetWorldRotation();
3786 detobj.velVector = obj.Velocity;
3787 detobj.colliderType = 0;
3788 detobj.groupUUID = obj.GroupID;
3789 colliding.Add(detobj);
3790 }
3791 }
3792
3793 if (colliding.Count > 0)
3794 {
3795 EndCollidingMessage.Colliders = colliding;
3796
3797 foreach (SceneObjectGroup att in GetAttachments())
3798 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3799 }
3800 }
3801
3802 if (thisHitColliders.Count > 0)
3803 {
3804 ColliderArgs CollidingMessage = new ColliderArgs();
3805 List<DetectedObject> colliding = new List<DetectedObject>();
3806 foreach (uint localId in thisHitColliders)
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 CollidingMessage.Colliders = colliding;
3831
3832 lock (m_attachments)
3833 {
3834 foreach (SceneObjectGroup att in m_attachments)
3835 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3836 }
3837 }
3838 }
3839
3331 if (Invulnerable) 3840 if (Invulnerable)
3332 return; 3841 return;
3333 3842
@@ -3399,6 +3908,10 @@ namespace OpenSim.Region.Framework.Scenes
3399 { 3908 {
3400 lock (m_attachments) 3909 lock (m_attachments)
3401 { 3910 {
3911 // This may be true when the attachment comes back
3912 // from serialization after login. Clear it.
3913 gobj.IsDeleted = false;
3914
3402 m_attachments.Add(gobj); 3915 m_attachments.Add(gobj);
3403 } 3916 }
3404 } 3917 }
@@ -3762,5 +4275,39 @@ namespace OpenSim.Region.Framework.Scenes
3762 m_reprioritization_called = false; 4275 m_reprioritization_called = false;
3763 } 4276 }
3764 } 4277 }
4278
4279 private Vector3 Quat2Euler(Quaternion rot){
4280 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4281 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4282 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4283 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4284 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4285 return(new Vector3(x,y,z));
4286 }
4287
4288 private void CheckLandingPoint(ref Vector3 pos)
4289 {
4290 // Never constrain lures
4291 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4292 return;
4293
4294 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4295 return;
4296
4297 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4298
4299 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4300 land.LandData.UserLocation != Vector3.Zero &&
4301 land.LandData.OwnerID != m_uuid &&
4302 (!m_scene.Permissions.IsGod(m_uuid)) &&
4303 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4304 {
4305 float curr = Vector3.Distance(AbsolutePosition, pos);
4306 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4307 pos = land.LandData.UserLocation;
4308 else
4309 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4310 }
4311 }
3765 } 4312 }
3766} 4313}