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.cs913
1 files changed, 730 insertions, 183 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index e961bdd..bd94902 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 public 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 public 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
@@ -479,9 +504,11 @@ namespace OpenSim.Region.Framework.Scenes
479 { 504 {
480 get 505 get
481 { 506 {
482 if (PhysicsActor != null) 507 PhysicsActor actor = m_physicsActor;
483 { 508// if (actor != null)
484 m_pos = PhysicsActor.Position; 509 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
510 {
511 m_pos = actor.Position;
485 512
486// m_log.DebugFormat( 513// m_log.DebugFormat(
487// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!", 514// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!",
@@ -507,7 +534,7 @@ namespace OpenSim.Region.Framework.Scenes
507 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 534 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
508 if (part != null) 535 if (part != null)
509 { 536 {
510 return ParentPosition + (m_pos * part.GetWorldRotation()); 537 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
511 } 538 }
512 else 539 else
513 { 540 {
@@ -532,8 +559,10 @@ namespace OpenSim.Region.Framework.Scenes
532 } 559 }
533 } 560 }
534 561
535 m_pos = value; 562// Changed this to update unconditionally to make npose work
536 ParentPosition = Vector3.Zero; 563// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
564 m_pos = value;
565 m_parentPosition = Vector3.Zero;
537 566
538// m_log.DebugFormat( 567// m_log.DebugFormat(
539// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 568// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
@@ -590,15 +619,39 @@ namespace OpenSim.Region.Framework.Scenes
590 } 619 }
591 } 620 }
592 621
622 public Quaternion OffsetRotation
623 {
624 get { return m_offsetRotation; }
625 set { m_offsetRotation = value; }
626 }
593 private Quaternion m_bodyRot = Quaternion.Identity; 627 private Quaternion m_bodyRot = Quaternion.Identity;
594 628
595 public Quaternion Rotation 629 public Quaternion Rotation
596 { 630 {
597 get { return m_bodyRot; } 631 get {
598 set 632 if (m_parentID != 0)
599 { 633 {
634 if (m_offsetRotation != null)
635 {
636 return m_offsetRotation;
637 }
638 else
639 {
640 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
641 }
642
643 }
644 else
645 {
646 return m_bodyRot;
647 }
648 }
649 set {
600 m_bodyRot = value; 650 m_bodyRot = value;
601// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 651 if (m_parentID != 0)
652 {
653 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
654 }
602 } 655 }
603 } 656 }
604 657
@@ -616,12 +669,15 @@ namespace OpenSim.Region.Framework.Scenes
616 set { m_isChildAgent = value; } 669 set { m_isChildAgent = value; }
617 } 670 }
618 671
672 private uint m_parentID;
673
674
619 public uint ParentID 675 public uint ParentID
620 { 676 {
621 get { return m_parentID; } 677 get { return m_parentID; }
622 set { m_parentID = value; } 678 set { m_parentID = value; }
623 } 679 }
624 private uint m_parentID; 680
625 681
626 public float Health 682 public float Health
627 { 683 {
@@ -754,6 +810,7 @@ namespace OpenSim.Region.Framework.Scenes
754 m_localId = m_scene.AllocateLocalId(); 810 m_localId = m_scene.AllocateLocalId();
755 811
756 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 812 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
813 m_userFlags = account.UserFlags;
757 814
758 if (account != null) 815 if (account != null)
759 UserLevel = account.UserLevel; 816 UserLevel = account.UserLevel;
@@ -772,10 +829,7 @@ namespace OpenSim.Region.Framework.Scenes
772 m_reprioritization_timer.AutoReset = false; 829 m_reprioritization_timer.AutoReset = false;
773 830
774 AdjustKnownSeeds(); 831 AdjustKnownSeeds();
775
776 // TODO: I think, this won't send anything, as we are still a child here...
777 Animator.TrySetMovementAnimation("STAND"); 832 Animator.TrySetMovementAnimation("STAND");
778
779 // we created a new ScenePresence (a new child agent) in a fresh region. 833 // we created a new ScenePresence (a new child agent) in a fresh region.
780 // Request info about all the (root) agents in this region 834 // Request info about all the (root) agents in this region
781 // Note: This won't send data *to* other clients in that region (children don't send) 835 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -816,26 +870,30 @@ namespace OpenSim.Region.Framework.Scenes
816 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 870 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
817 Dir_Vectors[4] = Vector3.UnitZ; //UP 871 Dir_Vectors[4] = Vector3.UnitZ; //UP
818 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 872 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
819 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 873 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
820 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 874 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
821 Dir_Vectors[7] = -Vector3.UnitX; //BACK 875 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
876 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
877 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
822 } 878 }
823 879
824 private Vector3[] GetWalkDirectionVectors() 880 private Vector3[] GetWalkDirectionVectors()
825 { 881 {
826 Vector3[] vector = new Vector3[9]; 882 Vector3[] vector = new Vector3[11];
827 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z); //FORWARD 883 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
828 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK 884 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
829 vector[2] = Vector3.UnitY; //LEFT 885 vector[2] = Vector3.UnitY; //LEFT
830 vector[3] = -Vector3.UnitY; //RIGHT 886 vector[3] = -Vector3.UnitY; //RIGHT
831 vector[4] = new Vector3(CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 887 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
832 vector[5] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 888 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
833 vector[8] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 889 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
834 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z) * 2); //FORWARD Nudge 890 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
835 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK Nudge 891 vector[8] = Vector3.UnitY; //LEFT_NUDGE
892 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
893 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
836 return vector; 894 return vector;
837 } 895 }
838 896
839 #endregion 897 #endregion
840 898
841 public uint GenerateClientFlags(UUID ObjectID) 899 public uint GenerateClientFlags(UUID ObjectID)
@@ -850,6 +908,8 @@ namespace OpenSim.Region.Framework.Scenes
850 /// </summary> 908 /// </summary>
851 public void SendPrimUpdates() 909 public void SendPrimUpdates()
852 { 910 {
911 m_sceneViewer.SendPrimUpdates();
912
853 SceneViewer.SendPrimUpdates(); 913 SceneViewer.SendPrimUpdates();
854 } 914 }
855 915
@@ -895,6 +955,62 @@ namespace OpenSim.Region.Framework.Scenes
895 pos.Y = crossedBorder.BorderLine.Z - 1; 955 pos.Y = crossedBorder.BorderLine.Z - 1;
896 } 956 }
897 957
958 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
959 if (land != null)
960 {
961 // If we come in via login, landmark or map, we want to
962 // honor landing points. If we come in via Lure, we want
963 // to ignore them.
964 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
965 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
966 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
967 {
968 // Don't restrict gods, estate managers, or land owners to
969 // the TP point. This behaviour mimics agni.
970 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
971 land.LandData.UserLocation != Vector3.Zero &&
972 GodLevel < 200 &&
973 ((land.LandData.OwnerID != m_uuid &&
974 (!m_scene.Permissions.IsGod(m_uuid)) &&
975 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
976 {
977 pos = land.LandData.UserLocation;
978 }
979 }
980
981 land.SendLandUpdateToClient(ControllingClient);
982 }
983
984 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
985 {
986 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
987
988 if (pos.X < 0)
989 {
990 emergencyPos.X = (int)Constants.RegionSize + pos.X;
991 if (!(pos.Y < 0))
992 emergencyPos.Y = pos.Y;
993 if (!(pos.Z < 0))
994 emergencyPos.Z = pos.Z;
995 }
996 if (pos.Y < 0)
997 {
998 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
999 if (!(pos.X < 0))
1000 emergencyPos.X = pos.X;
1001 if (!(pos.Z < 0))
1002 emergencyPos.Z = pos.Z;
1003 }
1004 if (pos.Z < 0)
1005 {
1006 emergencyPos.Z = 128;
1007 if (!(pos.Y < 0))
1008 emergencyPos.Y = pos.Y;
1009 if (!(pos.X < 0))
1010 emergencyPos.X = pos.X;
1011 }
1012 }
1013
898 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1014 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
899 { 1015 {
900 m_log.WarnFormat( 1016 m_log.WarnFormat(
@@ -1027,16 +1143,21 @@ namespace OpenSim.Region.Framework.Scenes
1027 /// <summary> 1143 /// <summary>
1028 /// Removes physics plugin scene representation of this agent if it exists. 1144 /// Removes physics plugin scene representation of this agent if it exists.
1029 /// </summary> 1145 /// </summary>
1030 private void RemoveFromPhysicalScene() 1146 public void RemoveFromPhysicalScene()
1031 { 1147 {
1032 if (PhysicsActor != null) 1148 if (PhysicsActor != null)
1033 { 1149 {
1034 PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1150 try
1035 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1151 {
1036 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1152 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1037 PhysicsActor.UnSubscribeEvents(); 1153 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1038 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1154 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1039 PhysicsActor = null; 1155 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1156 m_physicsActor.UnSubscribeEvents();
1157 PhysicsActor = null;
1158 }
1159 catch
1160 { }
1040 } 1161 }
1041 } 1162 }
1042 1163
@@ -1052,10 +1173,12 @@ namespace OpenSim.Region.Framework.Scenes
1052 1173
1053 RemoveFromPhysicalScene(); 1174 RemoveFromPhysicalScene();
1054 Velocity = Vector3.Zero; 1175 Velocity = Vector3.Zero;
1176 CheckLandingPoint(ref pos);
1055 AbsolutePosition = pos; 1177 AbsolutePosition = pos;
1056 AddToPhysicalScene(isFlying); 1178 AddToPhysicalScene(isFlying);
1057 1179
1058 SendTerseUpdateToAllClients(); 1180 SendTerseUpdateToAllClients();
1181
1059 } 1182 }
1060 1183
1061 public void TeleportWithMomentum(Vector3 pos) 1184 public void TeleportWithMomentum(Vector3 pos)
@@ -1065,6 +1188,7 @@ namespace OpenSim.Region.Framework.Scenes
1065 isFlying = PhysicsActor.Flying; 1188 isFlying = PhysicsActor.Flying;
1066 1189
1067 RemoveFromPhysicalScene(); 1190 RemoveFromPhysicalScene();
1191 CheckLandingPoint(ref pos);
1068 AbsolutePosition = pos; 1192 AbsolutePosition = pos;
1069 AddToPhysicalScene(isFlying); 1193 AddToPhysicalScene(isFlying);
1070 1194
@@ -1272,11 +1396,12 @@ namespace OpenSim.Region.Framework.Scenes
1272 /// <summary> 1396 /// <summary>
1273 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1397 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1274 /// </summary> 1398 /// </summary>
1399 /// <summary>
1400 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1401 /// </summary>
1275 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1402 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1276 { 1403 {
1277// m_log.DebugFormat( 1404 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1278// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1279// Scene.RegionInfo.RegionName, remoteClient.Name);
1280 1405
1281 //if (IsChildAgent) 1406 //if (IsChildAgent)
1282 //{ 1407 //{
@@ -1351,6 +1476,10 @@ namespace OpenSim.Region.Framework.Scenes
1351 1476
1352 #endregion Inputs 1477 #endregion Inputs
1353 1478
1479 // Make anims work for client side autopilot
1480 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
1481 m_updateCount = UPDATE_COUNT;
1482
1354 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) 1483 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
1355 { 1484 {
1356 StandUp(); 1485 StandUp();
@@ -1381,6 +1510,9 @@ namespace OpenSim.Region.Framework.Scenes
1381 1510
1382 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1511 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1383 { 1512 {
1513 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1514 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1515
1384 // TODO: This doesn't prevent the user from walking yet. 1516 // TODO: This doesn't prevent the user from walking yet.
1385 // Setting parent ID would fix this, if we knew what value 1517 // Setting parent ID would fix this, if we knew what value
1386 // to use. Or we could add a m_isSitting variable. 1518 // to use. Or we could add a m_isSitting variable.
@@ -1470,7 +1602,7 @@ namespace OpenSim.Region.Framework.Scenes
1470 1602
1471 if ((MovementFlag & (byte)(uint)DCF) == 0) 1603 if ((MovementFlag & (byte)(uint)DCF) == 0)
1472 { 1604 {
1473 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1605 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1474 { 1606 {
1475 MovementFlag |= (byte)nudgehack; 1607 MovementFlag |= (byte)nudgehack;
1476 } 1608 }
@@ -1482,13 +1614,13 @@ namespace OpenSim.Region.Framework.Scenes
1482 } 1614 }
1483 else 1615 else
1484 { 1616 {
1485 if ((MovementFlag & (byte)(uint)DCF) != 0 || 1617 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1486 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1618 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1487 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1619 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1488 ) // This or is for Nudge forward 1620 ) // This or is for Nudge forward
1489 { 1621 {
1490// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1622 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1491 MovementFlag -= ((byte)(uint)DCF); 1623 m_movementflag -= ((byte)(uint)DCF);
1492 update_movementflag = true; 1624 update_movementflag = true;
1493 1625
1494 /* 1626 /*
@@ -1549,21 +1681,21 @@ namespace OpenSim.Region.Framework.Scenes
1549 // which occurs later in the main scene loop 1681 // which occurs later in the main scene loop
1550 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1682 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1551 { 1683 {
1552// m_log.DebugFormat( 1684 // m_log.DebugFormat(
1553// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1685 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1554// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1686 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1555 1687
1556 AddNewMovement(agent_control_v3); 1688 AddNewMovement(agent_control_v3);
1557 } 1689 }
1558// else 1690 // else
1559// { 1691 // {
1560// if (!update_movementflag) 1692 // if (!update_movementflag)
1561// { 1693 // {
1562// m_log.DebugFormat( 1694 // m_log.DebugFormat(
1563// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1695 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1564// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1696 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1565// } 1697 // }
1566// } 1698 // }
1567 1699
1568 if (update_movementflag && ParentID == 0) 1700 if (update_movementflag && ParentID == 0)
1569 Animator.UpdateMovementAnimations(); 1701 Animator.UpdateMovementAnimations();
@@ -1582,20 +1714,20 @@ namespace OpenSim.Region.Framework.Scenes
1582 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1714 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1583 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1715 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1584 { 1716 {
1585// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1717 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1586 1718
1587 bool updated = false; 1719 bool updated = false;
1588 1720
1589// m_log.DebugFormat( 1721 // m_log.DebugFormat(
1590// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1722 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1591// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1723 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1592 1724
1593 if (!m_autopilotMoving) 1725 if (!m_autopilotMoving)
1594 { 1726 {
1595 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1727 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1596// m_log.DebugFormat( 1728 // m_log.DebugFormat(
1597// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1729 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1598// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1730 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1599 1731
1600 // Check the error term of the current position in relation to the target position 1732 // Check the error term of the current position in relation to the target position
1601 if (distanceToTarget <= 1) 1733 if (distanceToTarget <= 1)
@@ -1618,7 +1750,7 @@ namespace OpenSim.Region.Framework.Scenes
1618 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1750 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1619 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1751 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1620 // Ignore z component of vector 1752 // Ignore z component of vector
1621// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1753 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1622 LocalVectorToTarget3D.Normalize(); 1754 LocalVectorToTarget3D.Normalize();
1623 1755
1624 // update avatar movement flags. the avatar coordinate system is as follows: 1756 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1684,9 +1816,9 @@ namespace OpenSim.Region.Framework.Scenes
1684 updated = true; 1816 updated = true;
1685 } 1817 }
1686 1818
1687// m_log.DebugFormat( 1819 // m_log.DebugFormat(
1688// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1820 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1689// LocalVectorToTarget3D, agent_control_v3, Name); 1821 // LocalVectorToTarget3D, agent_control_v3, Name);
1690 1822
1691 agent_control_v3 += LocalVectorToTarget3D; 1823 agent_control_v3 += LocalVectorToTarget3D;
1692 } 1824 }
@@ -1715,9 +1847,12 @@ namespace OpenSim.Region.Framework.Scenes
1715 /// </param> 1847 /// </param>
1716 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget) 1848 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget)
1717 { 1849 {
1718 m_log.DebugFormat( 1850 if (SitGround)
1719 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", 1851 StandUp();
1720 Name, pos, m_scene.RegionInfo.RegionName); 1852
1853// m_log.DebugFormat(
1854// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1855// Name, pos, m_scene.RegionInfo.RegionName);
1721 1856
1722 if (pos.X < 0 || pos.X >= Constants.RegionSize 1857 if (pos.X < 0 || pos.X >= Constants.RegionSize
1723 || pos.Y < 0 || pos.Y >= Constants.RegionSize 1858 || pos.Y < 0 || pos.Y >= Constants.RegionSize
@@ -1743,9 +1878,9 @@ namespace OpenSim.Region.Framework.Scenes
1743 if (pos.Z - terrainHeight < 0.2) 1878 if (pos.Z - terrainHeight < 0.2)
1744 pos.Z = terrainHeight; 1879 pos.Z = terrainHeight;
1745 1880
1746 m_log.DebugFormat( 1881// m_log.DebugFormat(
1747 "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", 1882// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
1748 Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); 1883// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
1749 1884
1750 if (noFly) 1885 if (noFly)
1751 PhysicsActor.Flying = false; 1886 PhysicsActor.Flying = false;
@@ -1781,7 +1916,7 @@ namespace OpenSim.Region.Framework.Scenes
1781 /// </summary> 1916 /// </summary>
1782 public void ResetMoveToTarget() 1917 public void ResetMoveToTarget()
1783 { 1918 {
1784 m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 1919// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1785 1920
1786 MovingToTarget = false; 1921 MovingToTarget = false;
1787 MoveToPositionTarget = Vector3.Zero; 1922 MoveToPositionTarget = Vector3.Zero;
@@ -1807,7 +1942,7 @@ namespace OpenSim.Region.Framework.Scenes
1807 Velocity = Vector3.Zero; 1942 Velocity = Vector3.Zero;
1808 SendAvatarDataToAllAgents(); 1943 SendAvatarDataToAllAgents();
1809 1944
1810 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1945 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1811 } 1946 }
1812 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1947 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1813 m_requestedSitTargetUUID = UUID.Zero; 1948 m_requestedSitTargetUUID = UUID.Zero;
@@ -1844,24 +1979,22 @@ namespace OpenSim.Region.Framework.Scenes
1844 1979
1845 if (ParentID != 0) 1980 if (ParentID != 0)
1846 { 1981 {
1847 m_log.Debug("StandupCode Executed"); 1982 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1848 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
1849 if (part != null) 1983 if (part != null)
1850 { 1984 {
1985 part.TaskInventory.LockItemsForRead(true);
1851 TaskInventoryDictionary taskIDict = part.TaskInventory; 1986 TaskInventoryDictionary taskIDict = part.TaskInventory;
1852 if (taskIDict != null) 1987 if (taskIDict != null)
1853 { 1988 {
1854 lock (taskIDict) 1989 foreach (UUID taskID in taskIDict.Keys)
1855 { 1990 {
1856 foreach (UUID taskID in taskIDict.Keys) 1991 UnRegisterControlEventsToScript(LocalId, taskID);
1857 { 1992 taskIDict[taskID].PermsMask &= ~(
1858 UnRegisterControlEventsToScript(LocalId, taskID); 1993 2048 | //PERMISSION_CONTROL_CAMERA
1859 taskIDict[taskID].PermsMask &= ~( 1994 4); // PERMISSION_TAKE_CONTROLS
1860 2048 | //PERMISSION_CONTROL_CAMERA
1861 4); // PERMISSION_TAKE_CONTROLS
1862 }
1863 } 1995 }
1864 } 1996 }
1997 part.TaskInventory.LockItemsForRead(false);
1865 1998
1866 // Reset sit target. 1999 // Reset sit target.
1867 if (part.SitTargetAvatar == UUID) 2000 if (part.SitTargetAvatar == UUID)
@@ -1870,16 +2003,54 @@ namespace OpenSim.Region.Framework.Scenes
1870 ParentPosition = part.GetWorldPosition(); 2003 ParentPosition = part.GetWorldPosition();
1871 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2004 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1872 } 2005 }
1873 2006 // part.GetWorldRotation() is the rotation of the object being sat on
1874 if (PhysicsActor == null) 2007 // Rotation is the sittiing Av's rotation
2008
2009 Quaternion partRot;
2010// if (part.LinkNum == 1)
2011// { // Root prim of linkset
2012// partRot = part.ParentGroup.RootPart.RotationOffset;
2013// }
2014// else
2015// { // single or child prim
2016
2017// }
2018 if (part == null) //CW: Part may be gone. llDie() for example.
1875 { 2019 {
1876 AddToPhysicalScene(false); 2020 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1877 } 2021 }
2022 else
2023 {
2024 partRot = part.GetWorldRotation();
2025 }
2026
2027 Quaternion partIRot = Quaternion.Inverse(partRot);
1878 2028
1879 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 2029 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1880 ParentPosition = Vector3.Zero; 2030 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1881 2031
1882 ParentID = 0; 2032
2033 if (m_physicsActor == null)
2034 {
2035 AddToPhysicalScene(false);
2036 }
2037 //CW: If the part isn't null then we can set the current position
2038 if (part != null)
2039 {
2040 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
2041 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2042 part.IsOccupied = false;
2043 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2044 }
2045 else
2046 {
2047 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2048 AbsolutePosition = m_lastWorldPosition;
2049 }
2050
2051 m_parentPosition = Vector3.Zero;
2052 m_parentID = 0;
2053 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1883 SendAvatarDataToAllAgents(); 2054 SendAvatarDataToAllAgents();
1884 m_requestedSitTargetID = 0; 2055 m_requestedSitTargetID = 0;
1885 2056
@@ -1887,7 +2058,7 @@ namespace OpenSim.Region.Framework.Scenes
1887 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2058 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1888 } 2059 }
1889 2060
1890 Animator.TrySetMovementAnimation("STAND"); 2061 Animator.UpdateMovementAnimations();
1891 } 2062 }
1892 2063
1893 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) 2064 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -1918,8 +2089,8 @@ namespace OpenSim.Region.Framework.Scenes
1918 Quaternion avSitOrientation = part.SitTargetOrientation; 2089 Quaternion avSitOrientation = part.SitTargetOrientation;
1919 UUID avOnTargetAlready = part.SitTargetAvatar; 2090 UUID avOnTargetAlready = part.SitTargetAvatar;
1920 2091
1921 bool SitTargetUnOccupied = avOnTargetAlready == UUID.Zero; 2092 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1922 bool SitTargetisSet = avSitOffset != Vector3.Zero || avSitOrientation != Quaternion.Identity; 2093 bool SitTargetisSet = (Vector3.Zero != avSitOffset); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1923 2094
1924 if (SitTargetisSet && SitTargetUnOccupied) 2095 if (SitTargetisSet && SitTargetUnOccupied)
1925 { 2096 {
@@ -1935,87 +2106,167 @@ namespace OpenSim.Region.Framework.Scenes
1935 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2106 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1936 { 2107 {
1937 bool autopilot = true; 2108 bool autopilot = true;
2109 Vector3 autopilotTarget = new Vector3();
2110 Quaternion sitOrientation = Quaternion.Identity;
1938 Vector3 pos = new Vector3(); 2111 Vector3 pos = new Vector3();
1939 Quaternion sitOrientation = pSitOrientation;
1940 Vector3 cameraEyeOffset = Vector3.Zero; 2112 Vector3 cameraEyeOffset = Vector3.Zero;
1941 Vector3 cameraAtOffset = Vector3.Zero; 2113 Vector3 cameraAtOffset = Vector3.Zero;
1942 bool forceMouselook = false; 2114 bool forceMouselook = false;
1943 2115
1944 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2116 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1945 if (part != null) 2117 if (part == null) return;
2118
2119 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2120 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2121
2122 // part is the prim to sit on
2123 // offset is the world-ref vector distance from that prim center to the click-spot
2124 // UUID is the UUID of the Avatar doing the clicking
2125
2126 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2127
2128 // Is a sit target available?
2129 Vector3 avSitOffSet = part.SitTargetPosition;
2130 Quaternion avSitOrientation = part.SitTargetOrientation;
2131
2132 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2133 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2134 Quaternion partRot;
2135// if (part.LinkNum == 1)
2136// { // Root prim of linkset
2137// partRot = part.ParentGroup.RootPart.RotationOffset;
2138// }
2139// else
2140// { // single or child prim
2141 partRot = part.GetWorldRotation();
2142// }
2143 Quaternion partIRot = Quaternion.Inverse(partRot);
2144//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2145 // Sit analysis rewritten by KF 091125
2146 if (SitTargetisSet) // scipted sit
1946 { 2147 {
1947 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2148 if (!part.IsOccupied)
1948 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2149 {
1949 2150//Console.WriteLine("Scripted, unoccupied");
1950 // Is a sit target available? 2151 part.SitTargetAvatar = UUID; // set that Av will be on it
1951 Vector3 avSitOffSet = part.SitTargetPosition; 2152 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1952 Quaternion avSitOrientation = part.SitTargetOrientation; 2153
1953 UUID avOnTargetAlready = part.SitTargetAvatar; 2154 Quaternion nrot = avSitOrientation;
1954 2155 if (!part.IsRoot)
1955 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1956 bool SitTargetisSet =
1957 (!(avSitOffSet == Vector3.Zero &&
1958 (
1959 avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
1960 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1961 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1962 )
1963 ));
1964
1965// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
1966
1967 if (SitTargetisSet && SitTargetUnOccupied)
1968 {
1969 part.SitTargetAvatar = UUID;
1970 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1971 sitOrientation = avSitOrientation;
1972 autopilot = false;
1973 }
1974 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1975
1976 pos = part.AbsolutePosition + offset;
1977 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1978 //{
1979 // offset = pos;
1980 //autopilot = false;
1981 //}
1982 if (PhysicsActor != null)
1983 {
1984 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1985 // We can remove the physicsActor until they stand up.
1986 m_sitAvatarHeight = PhysicsActor.Size.Z;
1987
1988 if (autopilot)
1989 { 2156 {
1990 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2157 nrot = part.RotationOffset * avSitOrientation;
1991 {
1992 autopilot = false;
1993
1994 RemoveFromPhysicalScene();
1995 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1996 }
1997 } 2158 }
1998 else 2159 sitOrientation = nrot; // Change rotatione to the scripted one
2160 OffsetRotation = nrot;
2161 autopilot = false; // Jump direct to scripted llSitPos()
2162 }
2163 else
2164 {
2165//Console.WriteLine("Scripted, occupied");
2166 return;
2167 }
2168 }
2169 else // Not Scripted
2170 {
2171 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
2172 {
2173 // large prim & offset, ignore if other Avs sitting
2174// offset.Z -= 0.05f;
2175 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2176 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2177
2178//Console.WriteLine(" offset ={0}", offset);
2179//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2180//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2181
2182 }
2183 else // small offset
2184 {
2185//Console.WriteLine("Small offset");
2186 if (!part.IsOccupied)
2187 {
2188 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2189 autopilotTarget = part.AbsolutePosition;
2190//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2191 }
2192 else return; // occupied small
2193 } // end large/small
2194 } // end Scripted/not
2195
2196 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2197
2198 cameraAtOffset = part.GetCameraAtOffset();
2199 cameraEyeOffset = part.GetCameraEyeOffset();
2200 forceMouselook = part.GetForceMouselook();
2201 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2202 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2203
2204 if (m_physicsActor != null)
2205 {
2206 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2207 // We can remove the physicsActor until they stand up.
2208 m_sitAvatarHeight = m_physicsActor.Size.Z;
2209 if (autopilot)
2210 { // its not a scripted sit
2211// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2212 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1999 { 2213 {
2214 autopilot = false; // close enough
2215 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2216 Not using the part's position because returning the AV to the last known standing
2217 position is likely to be more friendly, isn't it? */
2000 RemoveFromPhysicalScene(); 2218 RemoveFromPhysicalScene();
2001 } 2219 Velocity = Vector3.Zero;
2220 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2221 } // else the autopilot will get us close
2222 }
2223 else
2224 { // its a scripted sit
2225 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2226 I *am* using the part's position this time because we have no real idea how far away
2227 the avatar is from the sit target. */
2228 RemoveFromPhysicalScene();
2229 Velocity = Vector3.Zero;
2002 } 2230 }
2003
2004 cameraAtOffset = part.GetCameraAtOffset();
2005 cameraEyeOffset = part.GetCameraEyeOffset();
2006 forceMouselook = part.GetForceMouselook();
2007 } 2231 }
2008 2232 else return; // physactor is null!
2009 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2233
2010 m_requestedSitTargetUUID = targetID; 2234 Vector3 offsetr; // = offset * partIRot;
2011 2235 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2236 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2237 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2238 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2239 //offsetr = offset * partIRot;
2240//
2241 // }
2242 // else
2243 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2244 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2245 // (offset * partRot);
2246 // }
2247
2248//Console.WriteLine(" ");
2249//Console.WriteLine("link number ={0}", part.LinkNum);
2250//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2251//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2252//Console.WriteLine("Click offst ={0}", offset);
2253//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2254//Console.WriteLine("offsetr ={0}", offsetr);
2255//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2256//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2257
2258 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2259 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2260
2261 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
2012 // This calls HandleAgentSit twice, once from here, and the client calls 2262 // This calls HandleAgentSit twice, once from here, and the client calls
2013 // HandleAgentSit itself after it gets to the location 2263 // HandleAgentSit itself after it gets to the location
2014 // It doesn't get to the location until we've moved them there though 2264 // It doesn't get to the location until we've moved them there though
2015 // which happens in HandleAgentSit :P 2265 // which happens in HandleAgentSit :P
2016 m_autopilotMoving = autopilot; 2266 m_autopilotMoving = autopilot;
2017 m_autoPilotTarget = pos; 2267 m_autoPilotTarget = autopilotTarget;
2018 m_sitAtAutoTarget = autopilot; 2268 m_sitAtAutoTarget = autopilot;
2269 m_initialSitTarget = autopilotTarget;
2019 if (!autopilot) 2270 if (!autopilot)
2020 HandleAgentSit(remoteClient, UUID); 2271 HandleAgentSit(remoteClient, UUID);
2021 } 2272 }
@@ -2281,33 +2532,68 @@ namespace OpenSim.Region.Framework.Scenes
2281 { 2532 {
2282 if (part.SitTargetAvatar == UUID) 2533 if (part.SitTargetAvatar == UUID)
2283 { 2534 {
2535//Console.WriteLine("Scripted Sit");
2536 // Scripted sit
2284 Vector3 sitTargetPos = part.SitTargetPosition; 2537 Vector3 sitTargetPos = part.SitTargetPosition;
2285 Quaternion sitTargetOrient = part.SitTargetOrientation; 2538 Quaternion sitTargetOrient = part.SitTargetOrientation;
2286 2539 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2287// m_log.DebugFormat( 2540 m_pos += SIT_TARGET_ADJUSTMENT;
2288// "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}", 2541 if (!part.IsRoot)
2289// Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId); 2542 {
2290 2543 m_pos *= part.RotationOffset;
2291 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0); 2544 }
2292 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w); 2545 m_bodyRot = sitTargetOrient;
2293 2546 m_parentPosition = part.AbsolutePosition;
2294 //Quaternion result = (sitTargetOrient * vq) * nq; 2547 part.IsOccupied = true;
2295 2548 part.ParentGroup.AddAvatar(agentID);
2296 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT;
2297 Rotation = sitTargetOrient;
2298 ParentPosition = part.AbsolutePosition;
2299 } 2549 }
2300 else 2550 else
2301 { 2551 {
2302 m_pos -= part.AbsolutePosition; 2552 // if m_avUnscriptedSitPos is zero then Av sits above center
2303 ParentPosition = part.AbsolutePosition; 2553 // Else Av sits at m_avUnscriptedSitPos
2304 2554
2305// m_log.DebugFormat( 2555 // Non-scripted sit by Kitto Flora 21Nov09
2306// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2556 // Calculate angle of line from prim to Av
2307// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); 2557 Quaternion partIRot;
2308 } 2558// if (part.LinkNum == 1)
2559// { // Root prim of linkset
2560// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2561// }
2562// else
2563// { // single or child prim
2564 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2565// }
2566 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2567 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2568 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2569 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2570 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2571 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2572 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2573 // Av sits at world euler <0,0, z>, translated by part rotation
2574 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2575
2576 m_parentPosition = part.AbsolutePosition;
2577 part.IsOccupied = true;
2578 part.ParentGroup.AddAvatar(agentID);
2579 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2580 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2581 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2582 m_avUnscriptedSitPos; // adds click offset, if any
2583 //Set up raytrace to find top surface of prim
2584 Vector3 size = part.Scale;
2585 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2586 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2587 Vector3 down = new Vector3(0f, 0f, -1f);
2588//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2589 m_scene.PhysicsScene.RaycastWorld(
2590 start, // Vector3 position,
2591 down, // Vector3 direction,
2592 mag, // float length,
2593 SitAltitudeCallback); // retMethod
2594 } // end scripted/not
2309 } 2595 }
2310 else 2596 else // no Av
2311 { 2597 {
2312 return; 2598 return;
2313 } 2599 }
@@ -2315,12 +2601,58 @@ namespace OpenSim.Region.Framework.Scenes
2315 2601
2316 ParentID = m_requestedSitTargetID; 2602 ParentID = m_requestedSitTargetID;
2317 2603
2604 //We want our offsets to reference the root prim, not the child we may have sat on
2605 if (!part.IsRoot)
2606 {
2607 m_parentID = part.ParentGroup.RootPart.LocalId;
2608 m_pos += part.OffsetPosition;
2609 }
2610 else
2611 {
2612 m_parentID = m_requestedSitTargetID;
2613 }
2614
2615 if (part.SitTargetAvatar != UUID)
2616 {
2617 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2618 }
2318 Velocity = Vector3.Zero; 2619 Velocity = Vector3.Zero;
2319 RemoveFromPhysicalScene(); 2620 RemoveFromPhysicalScene();
2320
2321 Animator.TrySetMovementAnimation(sitAnimation); 2621 Animator.TrySetMovementAnimation(sitAnimation);
2322 SendAvatarDataToAllAgents(); 2622 SendAvatarDataToAllAgents();
2323 } 2623 }
2624
2625 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2626 {
2627 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2628 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2629 if(hitYN)
2630 {
2631 // m_pos = Av offset from prim center to make look like on center
2632 // m_parentPosition = Actual center pos of prim
2633 // collisionPoint = spot on prim where we want to sit
2634 // collisionPoint.Z = global sit surface height
2635 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2636 Quaternion partIRot;
2637// if (part.LinkNum == 1)
2638/// { // Root prim of linkset
2639// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2640// }
2641// else
2642// { // single or child prim
2643 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2644// }
2645 if (m_initialSitTarget != null)
2646 {
2647 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2648 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2649 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2650 m_pos += offset;
2651 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2652 }
2653
2654 }
2655 } // End SitAltitudeCallback KF.
2324 2656
2325 /// <summary> 2657 /// <summary>
2326 /// Event handler for the 'Always run' setting on the client 2658 /// Event handler for the 'Always run' setting on the client
@@ -2350,6 +2682,19 @@ namespace OpenSim.Region.Framework.Scenes
2350 Vector3 direc = vec * Rotation; 2682 Vector3 direc = vec * Rotation;
2351 direc.Normalize(); 2683 direc.Normalize();
2352 2684
2685 if (PhysicsActor.Flying != m_flyingOld) // add for fly velocity control
2686 {
2687 m_flyingOld = PhysicsActor.Flying; // add for fly velocity control
2688 if (!PhysicsActor.Flying)
2689 m_wasFlying = true; // add for fly velocity control
2690 }
2691
2692 if (PhysicsActor.IsColliding == true)
2693 m_wasFlying = false; // add for fly velocity control
2694
2695 if ((vec.Z == 0f) && !PhysicsActor.Flying)
2696 direc.Z = 0f; // Prevent camera WASD up.
2697
2353 direc *= 0.03f * 128f * SpeedModifier; 2698 direc *= 0.03f * 128f * SpeedModifier;
2354 2699
2355 if (PhysicsActor != null) 2700 if (PhysicsActor != null)
@@ -2368,6 +2713,10 @@ namespace OpenSim.Region.Framework.Scenes
2368 // m_log.Info("[AGENT]: Stop Flying"); 2713 // m_log.Info("[AGENT]: Stop Flying");
2369 //} 2714 //}
2370 } 2715 }
2716 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2717 {
2718 direc *= 0.0f;
2719 }
2371 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding) 2720 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding)
2372 { 2721 {
2373 if (direc.Z > 2.0f) 2722 if (direc.Z > 2.0f)
@@ -2428,6 +2777,9 @@ namespace OpenSim.Region.Framework.Scenes
2428 2777
2429 CheckForSignificantMovement(); // sends update to the modules. 2778 CheckForSignificantMovement(); // sends update to the modules.
2430 } 2779 }
2780
2781 //Sending prim updates AFTER the avatar terse updates are sent
2782 SendPrimUpdates();
2431 } 2783 }
2432 2784
2433 #endregion 2785 #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}