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.cs915
1 files changed, 730 insertions, 185 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index dd1a29d..bb65322 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,25 +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
1864 } 1995 }
1996 part.TaskInventory.LockItemsForRead(false);
1865 // Reset sit target. 1997 // Reset sit target.
1866 if (part.GetAvatarOnSitTarget() == UUID) 1998 if (part.GetAvatarOnSitTarget() == UUID)
1867 part.SitTargetAvatar = UUID.Zero; 1999 part.SitTargetAvatar = UUID.Zero;
@@ -1870,21 +2002,59 @@ namespace OpenSim.Region.Framework.Scenes
1870 ParentPosition = part.GetWorldPosition(); 2002 ParentPosition = part.GetWorldPosition();
1871 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2003 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1872 } 2004 }
1873 2005 // part.GetWorldRotation() is the rotation of the object being sat on
1874 if (PhysicsActor == null) 2006 // Rotation is the sittiing Av's rotation
2007
2008 Quaternion partRot;
2009// if (part.LinkNum == 1)
2010// { // Root prim of linkset
2011// partRot = part.ParentGroup.RootPart.RotationOffset;
2012// }
2013// else
2014// { // single or child prim
2015
2016// }
2017 if (part == null) //CW: Part may be gone. llDie() for example.
1875 { 2018 {
1876 AddToPhysicalScene(false); 2019 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1877 } 2020 }
2021 else
2022 {
2023 partRot = part.GetWorldRotation();
2024 }
2025
2026 Quaternion partIRot = Quaternion.Inverse(partRot);
1878 2027
1879 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2028 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1880 ParentPosition = Vector3.Zero; 2029 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1881 2030
1882 ParentID = 0; 2031
2032 if (m_physicsActor == null)
2033 {
2034 AddToPhysicalScene(false);
2035 }
2036 //CW: If the part isn't null then we can set the current position
2037 if (part != null)
2038 {
2039 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
2040 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2041 part.IsOccupied = false;
2042 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2043 }
2044 else
2045 {
2046 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2047 AbsolutePosition = m_lastWorldPosition;
2048 }
2049
2050 m_parentPosition = Vector3.Zero;
2051 m_parentID = 0;
2052 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1883 SendAvatarDataToAllAgents(); 2053 SendAvatarDataToAllAgents();
1884 m_requestedSitTargetID = 0; 2054 m_requestedSitTargetID = 0;
1885 } 2055 }
1886 2056
1887 Animator.TrySetMovementAnimation("STAND"); 2057 Animator.UpdateMovementAnimations();
1888 } 2058 }
1889 2059
1890 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) 2060 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -1914,13 +2084,9 @@ namespace OpenSim.Region.Framework.Scenes
1914 Vector3 avSitOffSet = part.SitTargetPosition; 2084 Vector3 avSitOffSet = part.SitTargetPosition;
1915 Quaternion avSitOrientation = part.SitTargetOrientation; 2085 Quaternion avSitOrientation = part.SitTargetOrientation;
1916 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2086 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1917 2087 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1918 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2088 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1919 bool SitTargetisSet = 2089 if (SitTargetisSet && !SitTargetOccupied)
1920 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1921 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1922
1923 if (SitTargetisSet && SitTargetUnOccupied)
1924 { 2090 {
1925 //switch the target to this prim 2091 //switch the target to this prim
1926 return part; 2092 return part;
@@ -1934,87 +2100,168 @@ namespace OpenSim.Region.Framework.Scenes
1934 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2100 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1935 { 2101 {
1936 bool autopilot = true; 2102 bool autopilot = true;
2103 Vector3 autopilotTarget = new Vector3();
2104 Quaternion sitOrientation = Quaternion.Identity;
1937 Vector3 pos = new Vector3(); 2105 Vector3 pos = new Vector3();
1938 Quaternion sitOrientation = pSitOrientation;
1939 Vector3 cameraEyeOffset = Vector3.Zero; 2106 Vector3 cameraEyeOffset = Vector3.Zero;
1940 Vector3 cameraAtOffset = Vector3.Zero; 2107 Vector3 cameraAtOffset = Vector3.Zero;
1941 bool forceMouselook = false; 2108 bool forceMouselook = false;
1942 2109
1943 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2110 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1944 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2111 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1945 if (part != null) 2112 if (part == null) return;
2113
2114 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2115 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2116
2117 // part is the prim to sit on
2118 // offset is the world-ref vector distance from that prim center to the click-spot
2119 // UUID is the UUID of the Avatar doing the clicking
2120
2121 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2122
2123 // Is a sit target available?
2124 Vector3 avSitOffSet = part.SitTargetPosition;
2125 Quaternion avSitOrientation = part.SitTargetOrientation;
2126
2127 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2128 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2129 Quaternion partRot;
2130// if (part.LinkNum == 1)
2131// { // Root prim of linkset
2132// partRot = part.ParentGroup.RootPart.RotationOffset;
2133// }
2134// else
2135// { // single or child prim
2136 partRot = part.GetWorldRotation();
2137// }
2138 Quaternion partIRot = Quaternion.Inverse(partRot);
2139//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2140 // Sit analysis rewritten by KF 091125
2141 if (SitTargetisSet) // scipted sit
1946 { 2142 {
1947 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2143 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 2144 {
1949 2145//Console.WriteLine("Scripted, unoccupied");
1950 // Is a sit target available? 2146 part.SitTargetAvatar = UUID; // set that Av will be on it
1951 Vector3 avSitOffSet = part.SitTargetPosition; 2147 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1952 Quaternion avSitOrientation = part.SitTargetOrientation; 2148
1953 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2149 Quaternion nrot = avSitOrientation;
1954 2150 if (!part.IsRoot)
1955 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1956 bool SitTargetisSet =
1957 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1958 (
1959 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // 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 { 2151 {
1990 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2152 nrot = part.RotationOffset * avSitOrientation;
1991 {
1992 autopilot = false;
1993
1994 RemoveFromPhysicalScene();
1995 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1996 }
1997 } 2153 }
1998 else 2154 sitOrientation = nrot; // Change rotatione to the scripted one
2155 OffsetRotation = nrot;
2156 autopilot = false; // Jump direct to scripted llSitPos()
2157 }
2158 else
2159 {
2160//Console.WriteLine("Scripted, occupied");
2161 return;
2162 }
2163 }
2164 else // Not Scripted
2165 {
2166 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
2167 {
2168 // large prim & offset, ignore if other Avs sitting
2169// offset.Z -= 0.05f;
2170 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2171 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2172
2173//Console.WriteLine(" offset ={0}", offset);
2174//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2175//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2176
2177 }
2178 else // small offset
2179 {
2180//Console.WriteLine("Small offset");
2181 if (!part.IsOccupied)
2182 {
2183 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2184 autopilotTarget = part.AbsolutePosition;
2185//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2186 }
2187 else return; // occupied small
2188 } // end large/small
2189 } // end Scripted/not
2190
2191 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2192
2193 cameraAtOffset = part.GetCameraAtOffset();
2194 cameraEyeOffset = part.GetCameraEyeOffset();
2195 forceMouselook = part.GetForceMouselook();
2196 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2197 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2198
2199 if (m_physicsActor != null)
2200 {
2201 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2202 // We can remove the physicsActor until they stand up.
2203 m_sitAvatarHeight = m_physicsActor.Size.Z;
2204 if (autopilot)
2205 { // its not a scripted sit
2206// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2207 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1999 { 2208 {
2209 autopilot = false; // close enough
2210 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2211 Not using the part's position because returning the AV to the last known standing
2212 position is likely to be more friendly, isn't it? */
2000 RemoveFromPhysicalScene(); 2213 RemoveFromPhysicalScene();
2001 } 2214 Velocity = Vector3.Zero;
2215 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2216 } // else the autopilot will get us close
2217 }
2218 else
2219 { // its a scripted sit
2220 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2221 I *am* using the part's position this time because we have no real idea how far away
2222 the avatar is from the sit target. */
2223 RemoveFromPhysicalScene();
2224 Velocity = Vector3.Zero;
2002 } 2225 }
2003
2004 cameraAtOffset = part.GetCameraAtOffset();
2005 cameraEyeOffset = part.GetCameraEyeOffset();
2006 forceMouselook = part.GetForceMouselook();
2007 } 2226 }
2008 2227 else return; // physactor is null!
2009 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2228
2010 m_requestedSitTargetUUID = targetID; 2229 Vector3 offsetr; // = offset * partIRot;
2230 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2231 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2232 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2233 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2234 //offsetr = offset * partIRot;
2235//
2236 // }
2237 // else
2238 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2239 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2240 // (offset * partRot);
2241 // }
2242
2243//Console.WriteLine(" ");
2244//Console.WriteLine("link number ={0}", part.LinkNum);
2245//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2246//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2247//Console.WriteLine("Click offst ={0}", offset);
2248//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2249//Console.WriteLine("offsetr ={0}", offsetr);
2250//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2251//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2252
2253 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2254 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2255
2256 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
2011 // This calls HandleAgentSit twice, once from here, and the client calls 2257 // This calls HandleAgentSit twice, once from here, and the client calls
2012 // HandleAgentSit itself after it gets to the location 2258 // HandleAgentSit itself after it gets to the location
2013 // It doesn't get to the location until we've moved them there though 2259 // It doesn't get to the location until we've moved them there though
2014 // which happens in HandleAgentSit :P 2260 // which happens in HandleAgentSit :P
2015 m_autopilotMoving = autopilot; 2261 m_autopilotMoving = autopilot;
2016 m_autoPilotTarget = pos; 2262 m_autoPilotTarget = autopilotTarget;
2017 m_sitAtAutoTarget = autopilot; 2263 m_sitAtAutoTarget = autopilot;
2264 m_initialSitTarget = autopilotTarget;
2018 if (!autopilot) 2265 if (!autopilot)
2019 HandleAgentSit(remoteClient, UUID); 2266 HandleAgentSit(remoteClient, UUID);
2020 } 2267 }
@@ -2278,47 +2525,130 @@ namespace OpenSim.Region.Framework.Scenes
2278 { 2525 {
2279 if (part != null) 2526 if (part != null)
2280 { 2527 {
2528//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2281 if (part.GetAvatarOnSitTarget() == UUID) 2529 if (part.GetAvatarOnSitTarget() == UUID)
2282 { 2530 {
2531//Console.WriteLine("Scripted Sit");
2532 // Scripted sit
2283 Vector3 sitTargetPos = part.SitTargetPosition; 2533 Vector3 sitTargetPos = part.SitTargetPosition;
2284 Quaternion sitTargetOrient = part.SitTargetOrientation; 2534 Quaternion sitTargetOrient = part.SitTargetOrientation;
2285
2286 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2287 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2288
2289 //Quaternion result = (sitTargetOrient * vq) * nq;
2290
2291 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2535 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2292 m_pos += SIT_TARGET_ADJUSTMENT; 2536 m_pos += SIT_TARGET_ADJUSTMENT;
2293 Rotation = sitTargetOrient; 2537 if (!part.IsRoot)
2294 //Rotation = sitTargetOrient; 2538 {
2295 ParentPosition = part.AbsolutePosition; 2539 m_pos *= part.RotationOffset;
2296 2540 }
2297 //SendTerseUpdateToAllClients(); 2541 m_bodyRot = sitTargetOrient;
2542 m_parentPosition = part.AbsolutePosition;
2543 part.IsOccupied = true;
2544 part.ParentGroup.AddAvatar(agentID);
2298 } 2545 }
2299 else 2546 else
2300 { 2547 {
2301 m_pos -= part.AbsolutePosition; 2548 // if m_avUnscriptedSitPos is zero then Av sits above center
2302 ParentPosition = part.AbsolutePosition; 2549 // Else Av sits at m_avUnscriptedSitPos
2303 } 2550
2551 // Non-scripted sit by Kitto Flora 21Nov09
2552 // Calculate angle of line from prim to Av
2553 Quaternion partIRot;
2554// if (part.LinkNum == 1)
2555// { // Root prim of linkset
2556// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2557// }
2558// else
2559// { // single or child prim
2560 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2561// }
2562 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2563 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2564 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2565 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2566 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2567 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2568 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2569 // Av sits at world euler <0,0, z>, translated by part rotation
2570 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2571
2572 m_parentPosition = part.AbsolutePosition;
2573 part.IsOccupied = true;
2574 part.ParentGroup.AddAvatar(agentID);
2575 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2576 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2577 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2578 m_avUnscriptedSitPos; // adds click offset, if any
2579 //Set up raytrace to find top surface of prim
2580 Vector3 size = part.Scale;
2581 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2582 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2583 Vector3 down = new Vector3(0f, 0f, -1f);
2584//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2585 m_scene.PhysicsScene.RaycastWorld(
2586 start, // Vector3 position,
2587 down, // Vector3 direction,
2588 mag, // float length,
2589 SitAltitudeCallback); // retMethod
2590 } // end scripted/not
2304 } 2591 }
2305 else 2592 else // no Av
2306 { 2593 {
2307 return; 2594 return;
2308 } 2595 }
2309 } 2596 }
2310 ParentID = m_requestedSitTargetID; 2597 ParentID = m_requestedSitTargetID;
2311 2598
2599 //We want our offsets to reference the root prim, not the child we may have sat on
2600 if (!part.IsRoot)
2601 {
2602 m_parentID = part.ParentGroup.RootPart.LocalId;
2603 m_pos += part.OffsetPosition;
2604 }
2605 else
2606 {
2607 m_parentID = m_requestedSitTargetID;
2608 }
2609
2610 if (part.GetAvatarOnSitTarget() != UUID)
2611 {
2612 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2613 }
2312 Velocity = Vector3.Zero; 2614 Velocity = Vector3.Zero;
2313 RemoveFromPhysicalScene(); 2615 RemoveFromPhysicalScene();
2314
2315 Animator.TrySetMovementAnimation(sitAnimation); 2616 Animator.TrySetMovementAnimation(sitAnimation);
2316 SendAvatarDataToAllAgents(); 2617 SendAvatarDataToAllAgents();
2317 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2318 // So we're also sending a terse update (which has avatar rotation)
2319 // [Update] We do now.
2320 //SendTerseUpdateToAllClients(); 2618 //SendTerseUpdateToAllClients();
2321 } 2619 }
2620
2621 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2622 {
2623 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2624 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2625 if(hitYN)
2626 {
2627 // m_pos = Av offset from prim center to make look like on center
2628 // m_parentPosition = Actual center pos of prim
2629 // collisionPoint = spot on prim where we want to sit
2630 // collisionPoint.Z = global sit surface height
2631 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2632 Quaternion partIRot;
2633// if (part.LinkNum == 1)
2634/// { // Root prim of linkset
2635// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2636// }
2637// else
2638// { // single or child prim
2639 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2640// }
2641 if (m_initialSitTarget != null)
2642 {
2643 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2644 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2645 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2646 m_pos += offset;
2647 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2648 }
2649
2650 }
2651 } // End SitAltitudeCallback KF.
2322 2652
2323 /// <summary> 2653 /// <summary>
2324 /// Event handler for the 'Always run' setting on the client 2654 /// Event handler for the 'Always run' setting on the client
@@ -2348,6 +2678,19 @@ namespace OpenSim.Region.Framework.Scenes
2348 Vector3 direc = vec * Rotation; 2678 Vector3 direc = vec * Rotation;
2349 direc.Normalize(); 2679 direc.Normalize();
2350 2680
2681 if (PhysicsActor.Flying != m_flyingOld) // add for fly velocity control
2682 {
2683 m_flyingOld = PhysicsActor.Flying; // add for fly velocity control
2684 if (!PhysicsActor.Flying)
2685 m_wasFlying = true; // add for fly velocity control
2686 }
2687
2688 if (PhysicsActor.IsColliding == true)
2689 m_wasFlying = false; // add for fly velocity control
2690
2691 if ((vec.Z == 0f) && !PhysicsActor.Flying)
2692 direc.Z = 0f; // Prevent camera WASD up.
2693
2351 direc *= 0.03f * 128f * SpeedModifier; 2694 direc *= 0.03f * 128f * SpeedModifier;
2352 2695
2353 if (PhysicsActor != null) 2696 if (PhysicsActor != null)
@@ -2366,6 +2709,10 @@ namespace OpenSim.Region.Framework.Scenes
2366 // m_log.Info("[AGENT]: Stop Flying"); 2709 // m_log.Info("[AGENT]: Stop Flying");
2367 //} 2710 //}
2368 } 2711 }
2712 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2713 {
2714 direc *= 0.0f;
2715 }
2369 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding) 2716 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding)
2370 { 2717 {
2371 if (direc.Z > 2.0f) 2718 if (direc.Z > 2.0f)
@@ -2426,6 +2773,9 @@ namespace OpenSim.Region.Framework.Scenes
2426 2773
2427 CheckForSignificantMovement(); // sends update to the modules. 2774 CheckForSignificantMovement(); // sends update to the modules.
2428 } 2775 }
2776
2777 //Sending prim updates AFTER the avatar terse updates are sent
2778 SendPrimUpdates();
2429 } 2779 }
2430 2780
2431 #endregion 2781 #endregion
@@ -3197,6 +3547,7 @@ namespace OpenSim.Region.Framework.Scenes
3197 m_callbackURI = cAgent.CallbackURI; 3547 m_callbackURI = cAgent.CallbackURI;
3198 3548
3199 m_pos = cAgent.Position; 3549 m_pos = cAgent.Position;
3550
3200 m_velocity = cAgent.Velocity; 3551 m_velocity = cAgent.Velocity;
3201 CameraPosition = cAgent.Center; 3552 CameraPosition = cAgent.Center;
3202 CameraAtAxis = cAgent.AtAxis; 3553 CameraAtAxis = cAgent.AtAxis;
@@ -3346,14 +3697,28 @@ namespace OpenSim.Region.Framework.Scenes
3346 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3697 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
3347 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( 3698 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
3348 // as of this comment the interval is set in AddToPhysicalScene 3699 // as of this comment the interval is set in AddToPhysicalScene
3349 if (Animator != null) 3700 if (Animator!=null)
3350 Animator.UpdateMovementAnimations(); 3701 {
3702 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3703 { // else its will lock out other animation changes, like ground sit.
3704 Animator.UpdateMovementAnimations();
3705 m_updateCount--;
3706 }
3707 }
3351 3708
3352 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3709 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3353 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3710 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3354 3711
3355 CollisionPlane = Vector4.UnitW; 3712 CollisionPlane = Vector4.UnitW;
3356 3713
3714 // No collisions at all means we may be flying. Update always
3715 // to make falling work
3716 if (m_lastColCount != coldata.Count || coldata.Count == 0)
3717 {
3718 m_updateCount = UPDATE_COUNT;
3719 m_lastColCount = coldata.Count;
3720 }
3721
3357 if (coldata.Count != 0 && Animator != null) 3722 if (coldata.Count != 0 && Animator != null)
3358 { 3723 {
3359 switch (Animator.CurrentMovementAnimation) 3724 switch (Animator.CurrentMovementAnimation)
@@ -3383,6 +3748,148 @@ namespace OpenSim.Region.Framework.Scenes
3383 } 3748 }
3384 } 3749 }
3385 3750
3751 List<uint> thisHitColliders = new List<uint>();
3752 List<uint> endedColliders = new List<uint>();
3753 List<uint> startedColliders = new List<uint>();
3754
3755 foreach (uint localid in coldata.Keys)
3756 {
3757 thisHitColliders.Add(localid);
3758 if (!m_lastColliders.Contains(localid))
3759 {
3760 startedColliders.Add(localid);
3761 }
3762 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3763 }
3764
3765 // calculate things that ended colliding
3766 foreach (uint localID in m_lastColliders)
3767 {
3768 if (!thisHitColliders.Contains(localID))
3769 {
3770 endedColliders.Add(localID);
3771 }
3772 }
3773 //add the items that started colliding this time to the last colliders list.
3774 foreach (uint localID in startedColliders)
3775 {
3776 m_lastColliders.Add(localID);
3777 }
3778 // remove things that ended colliding from the last colliders list
3779 foreach (uint localID in endedColliders)
3780 {
3781 m_lastColliders.Remove(localID);
3782 }
3783
3784 // do event notification
3785 if (startedColliders.Count > 0)
3786 {
3787 ColliderArgs StartCollidingMessage = new ColliderArgs();
3788 List<DetectedObject> colliding = new List<DetectedObject>();
3789 foreach (uint localId in startedColliders)
3790 {
3791 if (localId == 0)
3792 continue;
3793
3794 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3795 string data = "";
3796 if (obj != null)
3797 {
3798 DetectedObject detobj = new DetectedObject();
3799 detobj.keyUUID = obj.UUID;
3800 detobj.nameStr = obj.Name;
3801 detobj.ownerUUID = obj.OwnerID;
3802 detobj.posVector = obj.AbsolutePosition;
3803 detobj.rotQuat = obj.GetWorldRotation();
3804 detobj.velVector = obj.Velocity;
3805 detobj.colliderType = 0;
3806 detobj.groupUUID = obj.GroupID;
3807 colliding.Add(detobj);
3808 }
3809 }
3810
3811 if (colliding.Count > 0)
3812 {
3813 StartCollidingMessage.Colliders = colliding;
3814
3815 foreach (SceneObjectGroup att in GetAttachments())
3816 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3817 }
3818 }
3819
3820 if (endedColliders.Count > 0)
3821 {
3822 ColliderArgs EndCollidingMessage = new ColliderArgs();
3823 List<DetectedObject> colliding = new List<DetectedObject>();
3824 foreach (uint localId in endedColliders)
3825 {
3826 if (localId == 0)
3827 continue;
3828
3829 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3830 string data = "";
3831 if (obj != null)
3832 {
3833 DetectedObject detobj = new DetectedObject();
3834 detobj.keyUUID = obj.UUID;
3835 detobj.nameStr = obj.Name;
3836 detobj.ownerUUID = obj.OwnerID;
3837 detobj.posVector = obj.AbsolutePosition;
3838 detobj.rotQuat = obj.GetWorldRotation();
3839 detobj.velVector = obj.Velocity;
3840 detobj.colliderType = 0;
3841 detobj.groupUUID = obj.GroupID;
3842 colliding.Add(detobj);
3843 }
3844 }
3845
3846 if (colliding.Count > 0)
3847 {
3848 EndCollidingMessage.Colliders = colliding;
3849
3850 foreach (SceneObjectGroup att in GetAttachments())
3851 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3852 }
3853 }
3854
3855 if (thisHitColliders.Count > 0)
3856 {
3857 ColliderArgs CollidingMessage = new ColliderArgs();
3858 List<DetectedObject> colliding = new List<DetectedObject>();
3859 foreach (uint localId in thisHitColliders)
3860 {
3861 if (localId == 0)
3862 continue;
3863
3864 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3865 string data = "";
3866 if (obj != null)
3867 {
3868 DetectedObject detobj = new DetectedObject();
3869 detobj.keyUUID = obj.UUID;
3870 detobj.nameStr = obj.Name;
3871 detobj.ownerUUID = obj.OwnerID;
3872 detobj.posVector = obj.AbsolutePosition;
3873 detobj.rotQuat = obj.GetWorldRotation();
3874 detobj.velVector = obj.Velocity;
3875 detobj.colliderType = 0;
3876 detobj.groupUUID = obj.GroupID;
3877 colliding.Add(detobj);
3878 }
3879 }
3880
3881 if (colliding.Count > 0)
3882 {
3883 CollidingMessage.Colliders = colliding;
3884
3885 lock (m_attachments)
3886 {
3887 foreach (SceneObjectGroup att in m_attachments)
3888 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3889 }
3890 }
3891 }
3892
3386 if (Invulnerable) 3893 if (Invulnerable)
3387 return; 3894 return;
3388 3895
@@ -3454,6 +3961,10 @@ namespace OpenSim.Region.Framework.Scenes
3454 { 3961 {
3455 lock (m_attachments) 3962 lock (m_attachments)
3456 { 3963 {
3964 // This may be true when the attachment comes back
3965 // from serialization after login. Clear it.
3966 gobj.IsDeleted = false;
3967
3457 m_attachments.Add(gobj); 3968 m_attachments.Add(gobj);
3458 } 3969 }
3459 } 3970 }
@@ -3817,5 +4328,39 @@ namespace OpenSim.Region.Framework.Scenes
3817 m_reprioritization_called = false; 4328 m_reprioritization_called = false;
3818 } 4329 }
3819 } 4330 }
4331
4332 private Vector3 Quat2Euler(Quaternion rot){
4333 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4334 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4335 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4336 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4337 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4338 return(new Vector3(x,y,z));
4339 }
4340
4341 private void CheckLandingPoint(ref Vector3 pos)
4342 {
4343 // Never constrain lures
4344 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4345 return;
4346
4347 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4348 return;
4349
4350 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4351
4352 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4353 land.LandData.UserLocation != Vector3.Zero &&
4354 land.LandData.OwnerID != m_uuid &&
4355 (!m_scene.Permissions.IsGod(m_uuid)) &&
4356 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4357 {
4358 float curr = Vector3.Distance(AbsolutePosition, pos);
4359 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4360 pos = land.LandData.UserLocation;
4361 else
4362 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4363 }
4364 }
3820 } 4365 }
3821} 4366}