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