aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs920
1 files changed, 738 insertions, 182 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 972e7fc..bdfad40 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
@@ -617,11 +670,21 @@ namespace OpenSim.Region.Framework.Scenes
617 670
618 private uint m_parentID; 671 private uint m_parentID;
619 672
673
674 private UUID m_linkedPrim;
675
620 public uint ParentID 676 public uint ParentID
621 { 677 {
622 get { return m_parentID; } 678 get { return m_parentID; }
623 set { m_parentID = value; } 679 set { m_parentID = value; }
624 } 680 }
681
682 public UUID LinkedPrim
683 {
684 get { return m_linkedPrim; }
685 set { m_linkedPrim = value; }
686 }
687
625 public float Health 688 public float Health
626 { 689 {
627 get { return m_health; } 690 get { return m_health; }
@@ -753,6 +816,7 @@ namespace OpenSim.Region.Framework.Scenes
753 m_localId = m_scene.AllocateLocalId(); 816 m_localId = m_scene.AllocateLocalId();
754 817
755 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 818 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
819 m_userFlags = account.UserFlags;
756 820
757 if (account != null) 821 if (account != null)
758 UserLevel = account.UserLevel; 822 UserLevel = account.UserLevel;
@@ -771,10 +835,7 @@ namespace OpenSim.Region.Framework.Scenes
771 m_reprioritization_timer.AutoReset = false; 835 m_reprioritization_timer.AutoReset = false;
772 836
773 AdjustKnownSeeds(); 837 AdjustKnownSeeds();
774
775 // TODO: I think, this won't send anything, as we are still a child here...
776 Animator.TrySetMovementAnimation("STAND"); 838 Animator.TrySetMovementAnimation("STAND");
777
778 // we created a new ScenePresence (a new child agent) in a fresh region. 839 // we created a new ScenePresence (a new child agent) in a fresh region.
779 // Request info about all the (root) agents in this region 840 // 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) 841 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -815,26 +876,30 @@ namespace OpenSim.Region.Framework.Scenes
815 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 876 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
816 Dir_Vectors[4] = Vector3.UnitZ; //UP 877 Dir_Vectors[4] = Vector3.UnitZ; //UP
817 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 878 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
818 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 879 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
819 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 880 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
820 Dir_Vectors[7] = -Vector3.UnitX; //BACK 881 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
882 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
883 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
821 } 884 }
822 885
823 private Vector3[] GetWalkDirectionVectors() 886 private Vector3[] GetWalkDirectionVectors()
824 { 887 {
825 Vector3[] vector = new Vector3[9]; 888 Vector3[] vector = new Vector3[11];
826 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z); //FORWARD 889 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
827 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK 890 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
828 vector[2] = Vector3.UnitY; //LEFT 891 vector[2] = Vector3.UnitY; //LEFT
829 vector[3] = -Vector3.UnitY; //RIGHT 892 vector[3] = -Vector3.UnitY; //RIGHT
830 vector[4] = new Vector3(CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 893 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
831 vector[5] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 894 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 895 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 896 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 897 vector[8] = Vector3.UnitY; //LEFT_NUDGE
898 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
899 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
835 return vector; 900 return vector;
836 } 901 }
837 902
838 #endregion 903 #endregion
839 904
840 public uint GenerateClientFlags(UUID ObjectID) 905 public uint GenerateClientFlags(UUID ObjectID)
@@ -849,6 +914,8 @@ namespace OpenSim.Region.Framework.Scenes
849 /// </summary> 914 /// </summary>
850 public void SendPrimUpdates() 915 public void SendPrimUpdates()
851 { 916 {
917 m_sceneViewer.SendPrimUpdates();
918
852 SceneViewer.SendPrimUpdates(); 919 SceneViewer.SendPrimUpdates();
853 } 920 }
854 921
@@ -894,6 +961,62 @@ namespace OpenSim.Region.Framework.Scenes
894 pos.Y = crossedBorder.BorderLine.Z - 1; 961 pos.Y = crossedBorder.BorderLine.Z - 1;
895 } 962 }
896 963
964 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
965 if (land != null)
966 {
967 // If we come in via login, landmark or map, we want to
968 // honor landing points. If we come in via Lure, we want
969 // to ignore them.
970 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
971 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
972 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
973 {
974 // Don't restrict gods, estate managers, or land owners to
975 // the TP point. This behaviour mimics agni.
976 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
977 land.LandData.UserLocation != Vector3.Zero &&
978 GodLevel < 200 &&
979 ((land.LandData.OwnerID != m_uuid &&
980 (!m_scene.Permissions.IsGod(m_uuid)) &&
981 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
982 {
983 pos = land.LandData.UserLocation;
984 }
985 }
986
987 land.SendLandUpdateToClient(ControllingClient);
988 }
989
990 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
991 {
992 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
993
994 if (pos.X < 0)
995 {
996 emergencyPos.X = (int)Constants.RegionSize + pos.X;
997 if (!(pos.Y < 0))
998 emergencyPos.Y = pos.Y;
999 if (!(pos.Z < 0))
1000 emergencyPos.Z = pos.Z;
1001 }
1002 if (pos.Y < 0)
1003 {
1004 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
1005 if (!(pos.X < 0))
1006 emergencyPos.X = pos.X;
1007 if (!(pos.Z < 0))
1008 emergencyPos.Z = pos.Z;
1009 }
1010 if (pos.Z < 0)
1011 {
1012 emergencyPos.Z = 128;
1013 if (!(pos.Y < 0))
1014 emergencyPos.Y = pos.Y;
1015 if (!(pos.X < 0))
1016 emergencyPos.X = pos.X;
1017 }
1018 }
1019
897 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1020 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
898 { 1021 {
899 m_log.WarnFormat( 1022 m_log.WarnFormat(
@@ -1026,16 +1149,21 @@ namespace OpenSim.Region.Framework.Scenes
1026 /// <summary> 1149 /// <summary>
1027 /// Removes physics plugin scene representation of this agent if it exists. 1150 /// Removes physics plugin scene representation of this agent if it exists.
1028 /// </summary> 1151 /// </summary>
1029 private void RemoveFromPhysicalScene() 1152 public void RemoveFromPhysicalScene()
1030 { 1153 {
1031 if (PhysicsActor != null) 1154 if (PhysicsActor != null)
1032 { 1155 {
1033 PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1156 try
1034 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1157 {
1035 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1158 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1036 PhysicsActor.UnSubscribeEvents(); 1159 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1037 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1160 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1038 PhysicsActor = null; 1161 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1162 m_physicsActor.UnSubscribeEvents();
1163 PhysicsActor = null;
1164 }
1165 catch
1166 { }
1039 } 1167 }
1040 } 1168 }
1041 1169
@@ -1051,10 +1179,12 @@ namespace OpenSim.Region.Framework.Scenes
1051 1179
1052 RemoveFromPhysicalScene(); 1180 RemoveFromPhysicalScene();
1053 Velocity = Vector3.Zero; 1181 Velocity = Vector3.Zero;
1182 CheckLandingPoint(ref pos);
1054 AbsolutePosition = pos; 1183 AbsolutePosition = pos;
1055 AddToPhysicalScene(isFlying); 1184 AddToPhysicalScene(isFlying);
1056 1185
1057 SendTerseUpdateToAllClients(); 1186 SendTerseUpdateToAllClients();
1187
1058 } 1188 }
1059 1189
1060 public void TeleportWithMomentum(Vector3 pos) 1190 public void TeleportWithMomentum(Vector3 pos)
@@ -1064,6 +1194,7 @@ namespace OpenSim.Region.Framework.Scenes
1064 isFlying = PhysicsActor.Flying; 1194 isFlying = PhysicsActor.Flying;
1065 1195
1066 RemoveFromPhysicalScene(); 1196 RemoveFromPhysicalScene();
1197 CheckLandingPoint(ref pos);
1067 AbsolutePosition = pos; 1198 AbsolutePosition = pos;
1068 AddToPhysicalScene(isFlying); 1199 AddToPhysicalScene(isFlying);
1069 1200
@@ -1271,11 +1402,12 @@ namespace OpenSim.Region.Framework.Scenes
1271 /// <summary> 1402 /// <summary>
1272 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1403 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1273 /// </summary> 1404 /// </summary>
1405 /// <summary>
1406 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1407 /// </summary>
1274 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1408 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1275 { 1409 {
1276// m_log.DebugFormat( 1410 // 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 1411
1280 //if (IsChildAgent) 1412 //if (IsChildAgent)
1281 //{ 1413 //{
@@ -1350,6 +1482,10 @@ namespace OpenSim.Region.Framework.Scenes
1350 1482
1351 #endregion Inputs 1483 #endregion Inputs
1352 1484
1485 // Make anims work for client side autopilot
1486 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
1487 m_updateCount = UPDATE_COUNT;
1488
1353 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) 1489 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
1354 { 1490 {
1355 StandUp(); 1491 StandUp();
@@ -1380,6 +1516,9 @@ namespace OpenSim.Region.Framework.Scenes
1380 1516
1381 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1517 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1382 { 1518 {
1519 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1520 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1521
1383 // TODO: This doesn't prevent the user from walking yet. 1522 // TODO: This doesn't prevent the user from walking yet.
1384 // Setting parent ID would fix this, if we knew what value 1523 // Setting parent ID would fix this, if we knew what value
1385 // to use. Or we could add a m_isSitting variable. 1524 // to use. Or we could add a m_isSitting variable.
@@ -1469,7 +1608,7 @@ namespace OpenSim.Region.Framework.Scenes
1469 1608
1470 if ((MovementFlag & (byte)(uint)DCF) == 0) 1609 if ((MovementFlag & (byte)(uint)DCF) == 0)
1471 { 1610 {
1472 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1611 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1473 { 1612 {
1474 MovementFlag |= (byte)nudgehack; 1613 MovementFlag |= (byte)nudgehack;
1475 } 1614 }
@@ -1481,13 +1620,13 @@ namespace OpenSim.Region.Framework.Scenes
1481 } 1620 }
1482 else 1621 else
1483 { 1622 {
1484 if ((MovementFlag & (byte)(uint)DCF) != 0 || 1623 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1485 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1624 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1486 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1625 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1487 ) // This or is for Nudge forward 1626 ) // This or is for Nudge forward
1488 { 1627 {
1489// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1628 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1490 MovementFlag -= ((byte)(uint)DCF); 1629 m_movementflag -= ((byte)(uint)DCF);
1491 update_movementflag = true; 1630 update_movementflag = true;
1492 1631
1493 /* 1632 /*
@@ -1548,21 +1687,21 @@ namespace OpenSim.Region.Framework.Scenes
1548 // which occurs later in the main scene loop 1687 // which occurs later in the main scene loop
1549 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1688 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1550 { 1689 {
1551// m_log.DebugFormat( 1690 // m_log.DebugFormat(
1552// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1691 // "[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); 1692 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1554 1693
1555 AddNewMovement(agent_control_v3); 1694 AddNewMovement(agent_control_v3);
1556 } 1695 }
1557// else 1696 // else
1558// { 1697 // {
1559// if (!update_movementflag) 1698 // if (!update_movementflag)
1560// { 1699 // {
1561// m_log.DebugFormat( 1700 // m_log.DebugFormat(
1562// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1701 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1563// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1702 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1564// } 1703 // }
1565// } 1704 // }
1566 1705
1567 if (update_movementflag && ParentID == 0) 1706 if (update_movementflag && ParentID == 0)
1568 Animator.UpdateMovementAnimations(); 1707 Animator.UpdateMovementAnimations();
@@ -1581,20 +1720,20 @@ namespace OpenSim.Region.Framework.Scenes
1581 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1720 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1582 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1721 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1583 { 1722 {
1584// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1723 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1585 1724
1586 bool updated = false; 1725 bool updated = false;
1587 1726
1588// m_log.DebugFormat( 1727 // m_log.DebugFormat(
1589// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1728 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1590// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1729 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1591 1730
1592 if (!m_autopilotMoving) 1731 if (!m_autopilotMoving)
1593 { 1732 {
1594 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1733 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1595// m_log.DebugFormat( 1734 // m_log.DebugFormat(
1596// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1735 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1597// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1736 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1598 1737
1599 // Check the error term of the current position in relation to the target position 1738 // Check the error term of the current position in relation to the target position
1600 if (distanceToTarget <= 1) 1739 if (distanceToTarget <= 1)
@@ -1617,7 +1756,7 @@ namespace OpenSim.Region.Framework.Scenes
1617 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1756 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1618 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1757 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1619 // Ignore z component of vector 1758 // Ignore z component of vector
1620// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1759 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1621 LocalVectorToTarget3D.Normalize(); 1760 LocalVectorToTarget3D.Normalize();
1622 1761
1623 // update avatar movement flags. the avatar coordinate system is as follows: 1762 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1683,9 +1822,9 @@ namespace OpenSim.Region.Framework.Scenes
1683 updated = true; 1822 updated = true;
1684 } 1823 }
1685 1824
1686// m_log.DebugFormat( 1825 // m_log.DebugFormat(
1687// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1826 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1688// LocalVectorToTarget3D, agent_control_v3, Name); 1827 // LocalVectorToTarget3D, agent_control_v3, Name);
1689 1828
1690 agent_control_v3 += LocalVectorToTarget3D; 1829 agent_control_v3 += LocalVectorToTarget3D;
1691 } 1830 }
@@ -1714,9 +1853,12 @@ namespace OpenSim.Region.Framework.Scenes
1714 /// </param> 1853 /// </param>
1715 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget) 1854 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget)
1716 { 1855 {
1717 m_log.DebugFormat( 1856 if (SitGround)
1718 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", 1857 StandUp();
1719 Name, pos, m_scene.RegionInfo.RegionName); 1858
1859// m_log.DebugFormat(
1860// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1861// Name, pos, m_scene.RegionInfo.RegionName);
1720 1862
1721 if (pos.X < 0 || pos.X >= Constants.RegionSize 1863 if (pos.X < 0 || pos.X >= Constants.RegionSize
1722 || pos.Y < 0 || pos.Y >= Constants.RegionSize 1864 || pos.Y < 0 || pos.Y >= Constants.RegionSize
@@ -1742,9 +1884,9 @@ namespace OpenSim.Region.Framework.Scenes
1742 if (pos.Z - terrainHeight < 0.2) 1884 if (pos.Z - terrainHeight < 0.2)
1743 pos.Z = terrainHeight; 1885 pos.Z = terrainHeight;
1744 1886
1745 m_log.DebugFormat( 1887// m_log.DebugFormat(
1746 "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", 1888// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
1747 Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); 1889// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
1748 1890
1749 if (noFly) 1891 if (noFly)
1750 PhysicsActor.Flying = false; 1892 PhysicsActor.Flying = false;
@@ -1780,7 +1922,7 @@ namespace OpenSim.Region.Framework.Scenes
1780 /// </summary> 1922 /// </summary>
1781 public void ResetMoveToTarget() 1923 public void ResetMoveToTarget()
1782 { 1924 {
1783 m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 1925// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1784 1926
1785 MovingToTarget = false; 1927 MovingToTarget = false;
1786 MoveToPositionTarget = Vector3.Zero; 1928 MoveToPositionTarget = Vector3.Zero;
@@ -1806,7 +1948,7 @@ namespace OpenSim.Region.Framework.Scenes
1806 Velocity = Vector3.Zero; 1948 Velocity = Vector3.Zero;
1807 SendAvatarDataToAllAgents(); 1949 SendAvatarDataToAllAgents();
1808 1950
1809 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1951 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1810 } 1952 }
1811 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1953 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1812 m_requestedSitTargetUUID = UUID.Zero; 1954 m_requestedSitTargetUUID = UUID.Zero;
@@ -1843,25 +1985,22 @@ namespace OpenSim.Region.Framework.Scenes
1843 1985
1844 if (ParentID != 0) 1986 if (ParentID != 0)
1845 { 1987 {
1846 m_log.Debug("StandupCode Executed"); 1988 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1847 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
1848 if (part != null) 1989 if (part != null)
1849 { 1990 {
1991 part.TaskInventory.LockItemsForRead(true);
1850 TaskInventoryDictionary taskIDict = part.TaskInventory; 1992 TaskInventoryDictionary taskIDict = part.TaskInventory;
1851 if (taskIDict != null) 1993 if (taskIDict != null)
1852 { 1994 {
1853 lock (taskIDict) 1995 foreach (UUID taskID in taskIDict.Keys)
1854 { 1996 {
1855 foreach (UUID taskID in taskIDict.Keys) 1997 UnRegisterControlEventsToScript(LocalId, taskID);
1856 { 1998 taskIDict[taskID].PermsMask &= ~(
1857 UnRegisterControlEventsToScript(LocalId, taskID); 1999 2048 | //PERMISSION_CONTROL_CAMERA
1858 taskIDict[taskID].PermsMask &= ~( 2000 4); // PERMISSION_TAKE_CONTROLS
1859 2048 | //PERMISSION_CONTROL_CAMERA
1860 4); // PERMISSION_TAKE_CONTROLS
1861 }
1862 } 2001 }
1863
1864 } 2002 }
2003 part.TaskInventory.LockItemsForRead(false);
1865 // Reset sit target. 2004 // Reset sit target.
1866 if (part.GetAvatarOnSitTarget() == UUID) 2005 if (part.GetAvatarOnSitTarget() == UUID)
1867 part.SitTargetAvatar = UUID.Zero; 2006 part.SitTargetAvatar = UUID.Zero;
@@ -1870,21 +2009,60 @@ namespace OpenSim.Region.Framework.Scenes
1870 ParentPosition = part.GetWorldPosition(); 2009 ParentPosition = part.GetWorldPosition();
1871 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2010 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1872 } 2011 }
1873 2012 // part.GetWorldRotation() is the rotation of the object being sat on
1874 if (PhysicsActor == null) 2013 // Rotation is the sittiing Av's rotation
2014
2015 Quaternion partRot;
2016// if (part.LinkNum == 1)
2017// { // Root prim of linkset
2018// partRot = part.ParentGroup.RootPart.RotationOffset;
2019// }
2020// else
2021// { // single or child prim
2022
2023// }
2024 if (part == null) //CW: Part may be gone. llDie() for example.
1875 { 2025 {
1876 AddToPhysicalScene(false); 2026 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
2027 }
2028 else
2029 {
2030 partRot = part.GetWorldRotation();
1877 } 2031 }
1878 2032
1879 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2033 Quaternion partIRot = Quaternion.Inverse(partRot);
1880 ParentPosition = Vector3.Zero;
1881 2034
1882 ParentID = 0; 2035 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
2036 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
2037
2038
2039 if (m_physicsActor == null)
2040 {
2041 AddToPhysicalScene(false);
2042 }
2043 //CW: If the part isn't null then we can set the current position
2044 if (part != null)
2045 {
2046 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
2047 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2048 part.IsOccupied = false;
2049 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2050 }
2051 else
2052 {
2053 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2054 AbsolutePosition = m_lastWorldPosition;
2055 }
2056
2057 m_parentPosition = Vector3.Zero;
2058 m_parentID = 0;
2059 m_linkedPrim = UUID.Zero;
2060 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1883 SendAvatarDataToAllAgents(); 2061 SendAvatarDataToAllAgents();
1884 m_requestedSitTargetID = 0; 2062 m_requestedSitTargetID = 0;
1885 } 2063 }
1886 2064
1887 Animator.TrySetMovementAnimation("STAND"); 2065 Animator.UpdateMovementAnimations();
1888 } 2066 }
1889 2067
1890 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) 2068 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -1914,13 +2092,9 @@ namespace OpenSim.Region.Framework.Scenes
1914 Vector3 avSitOffSet = part.SitTargetPosition; 2092 Vector3 avSitOffSet = part.SitTargetPosition;
1915 Quaternion avSitOrientation = part.SitTargetOrientation; 2093 Quaternion avSitOrientation = part.SitTargetOrientation;
1916 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2094 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1917 2095 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1918 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2096 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1919 bool SitTargetisSet = 2097 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 { 2098 {
1925 //switch the target to this prim 2099 //switch the target to this prim
1926 return part; 2100 return part;
@@ -1934,85 +2108,168 @@ namespace OpenSim.Region.Framework.Scenes
1934 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2108 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1935 { 2109 {
1936 bool autopilot = true; 2110 bool autopilot = true;
2111 Vector3 autopilotTarget = new Vector3();
2112 Quaternion sitOrientation = Quaternion.Identity;
1937 Vector3 pos = new Vector3(); 2113 Vector3 pos = new Vector3();
1938 Quaternion sitOrientation = pSitOrientation;
1939 Vector3 cameraEyeOffset = Vector3.Zero; 2114 Vector3 cameraEyeOffset = Vector3.Zero;
1940 Vector3 cameraAtOffset = Vector3.Zero; 2115 Vector3 cameraAtOffset = Vector3.Zero;
1941 bool forceMouselook = false; 2116 bool forceMouselook = false;
1942 2117
1943 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2118 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1944 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2119 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1945 if (part != null) 2120 if (part == null) return;
2121
2122 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2123 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2124
2125 // part is the prim to sit on
2126 // offset is the world-ref vector distance from that prim center to the click-spot
2127 // UUID is the UUID of the Avatar doing the clicking
2128
2129 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2130
2131 // Is a sit target available?
2132 Vector3 avSitOffSet = part.SitTargetPosition;
2133 Quaternion avSitOrientation = part.SitTargetOrientation;
2134
2135 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2136 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2137 Quaternion partRot;
2138// if (part.LinkNum == 1)
2139// { // Root prim of linkset
2140// partRot = part.ParentGroup.RootPart.RotationOffset;
2141// }
2142// else
2143// { // single or child prim
2144 partRot = part.GetWorldRotation();
2145// }
2146 Quaternion partIRot = Quaternion.Inverse(partRot);
2147//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2148 // Sit analysis rewritten by KF 091125
2149 if (SitTargetisSet) // scipted sit
1946 { 2150 {
1947 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2151 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 2152 {
1949 2153//Console.WriteLine("Scripted, unoccupied");
1950 // Is a sit target available? 2154 part.SitTargetAvatar = UUID; // set that Av will be on it
1951 Vector3 avSitOffSet = part.SitTargetPosition; 2155 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1952 Quaternion avSitOrientation = part.SitTargetOrientation; 2156
1953 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2157 Quaternion nrot = avSitOrientation;
1954 2158 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 if (SitTargetisSet && SitTargetUnOccupied)
1966 {
1967 part.SitTargetAvatar = UUID;
1968 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1969 sitOrientation = avSitOrientation;
1970 autopilot = false;
1971 }
1972 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1973
1974 pos = part.AbsolutePosition + offset;
1975 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1976 //{
1977 // offset = pos;
1978 //autopilot = false;
1979 //}
1980 if (PhysicsActor != null)
1981 {
1982 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1983 // We can remove the physicsActor until they stand up.
1984 m_sitAvatarHeight = PhysicsActor.Size.Z;
1985
1986 if (autopilot)
1987 { 2159 {
1988 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2160 nrot = part.RotationOffset * avSitOrientation;
1989 {
1990 autopilot = false;
1991
1992 RemoveFromPhysicalScene();
1993 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1994 }
1995 } 2161 }
1996 else 2162 sitOrientation = nrot; // Change rotatione to the scripted one
2163 OffsetRotation = nrot;
2164 autopilot = false; // Jump direct to scripted llSitPos()
2165 }
2166 else
2167 {
2168//Console.WriteLine("Scripted, occupied");
2169 return;
2170 }
2171 }
2172 else // Not Scripted
2173 {
2174 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
2175 {
2176 // large prim & offset, ignore if other Avs sitting
2177// offset.Z -= 0.05f;
2178 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2179 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2180
2181//Console.WriteLine(" offset ={0}", offset);
2182//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2183//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2184
2185 }
2186 else // small offset
2187 {
2188//Console.WriteLine("Small offset");
2189 if (!part.IsOccupied)
2190 {
2191 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2192 autopilotTarget = part.AbsolutePosition;
2193//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2194 }
2195 else return; // occupied small
2196 } // end large/small
2197 } // end Scripted/not
2198
2199 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2200
2201 cameraAtOffset = part.GetCameraAtOffset();
2202 cameraEyeOffset = part.GetCameraEyeOffset();
2203 forceMouselook = part.GetForceMouselook();
2204 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2205 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2206
2207 if (m_physicsActor != null)
2208 {
2209 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2210 // We can remove the physicsActor until they stand up.
2211 m_sitAvatarHeight = m_physicsActor.Size.Z;
2212 if (autopilot)
2213 { // its not a scripted sit
2214// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2215 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1997 { 2216 {
2217 autopilot = false; // close enough
2218 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2219 Not using the part's position because returning the AV to the last known standing
2220 position is likely to be more friendly, isn't it? */
1998 RemoveFromPhysicalScene(); 2221 RemoveFromPhysicalScene();
1999 } 2222 Velocity = Vector3.Zero;
2223 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2224 } // else the autopilot will get us close
2225 }
2226 else
2227 { // its a scripted sit
2228 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2229 I *am* using the part's position this time because we have no real idea how far away
2230 the avatar is from the sit target. */
2231 RemoveFromPhysicalScene();
2232 Velocity = Vector3.Zero;
2000 } 2233 }
2001
2002 cameraAtOffset = part.GetCameraAtOffset();
2003 cameraEyeOffset = part.GetCameraEyeOffset();
2004 forceMouselook = part.GetForceMouselook();
2005 } 2234 }
2006 2235 else return; // physactor is null!
2007 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2236
2008 m_requestedSitTargetUUID = targetID; 2237 Vector3 offsetr; // = offset * partIRot;
2238 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2239 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2240 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2241 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2242 //offsetr = offset * partIRot;
2243//
2244 // }
2245 // else
2246 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2247 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2248 // (offset * partRot);
2249 // }
2250
2251//Console.WriteLine(" ");
2252//Console.WriteLine("link number ={0}", part.LinkNum);
2253//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2254//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2255//Console.WriteLine("Click offst ={0}", offset);
2256//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2257//Console.WriteLine("offsetr ={0}", offsetr);
2258//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2259//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2260
2261 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2262 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2263
2264 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
2009 // This calls HandleAgentSit twice, once from here, and the client calls 2265 // This calls HandleAgentSit twice, once from here, and the client calls
2010 // HandleAgentSit itself after it gets to the location 2266 // HandleAgentSit itself after it gets to the location
2011 // It doesn't get to the location until we've moved them there though 2267 // It doesn't get to the location until we've moved them there though
2012 // which happens in HandleAgentSit :P 2268 // which happens in HandleAgentSit :P
2013 m_autopilotMoving = autopilot; 2269 m_autopilotMoving = autopilot;
2014 m_autoPilotTarget = pos; 2270 m_autoPilotTarget = autopilotTarget;
2015 m_sitAtAutoTarget = autopilot; 2271 m_sitAtAutoTarget = autopilot;
2272 m_initialSitTarget = autopilotTarget;
2016 if (!autopilot) 2273 if (!autopilot)
2017 HandleAgentSit(remoteClient, UUID); 2274 HandleAgentSit(remoteClient, UUID);
2018 } 2275 }
@@ -2277,47 +2534,131 @@ namespace OpenSim.Region.Framework.Scenes
2277 { 2534 {
2278 if (part != null) 2535 if (part != null)
2279 { 2536 {
2537//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2280 if (part.GetAvatarOnSitTarget() == UUID) 2538 if (part.GetAvatarOnSitTarget() == UUID)
2281 { 2539 {
2540//Console.WriteLine("Scripted Sit");
2541 // Scripted sit
2282 Vector3 sitTargetPos = part.SitTargetPosition; 2542 Vector3 sitTargetPos = part.SitTargetPosition;
2283 Quaternion sitTargetOrient = part.SitTargetOrientation; 2543 Quaternion sitTargetOrient = part.SitTargetOrientation;
2284
2285 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2286 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2287
2288 //Quaternion result = (sitTargetOrient * vq) * nq;
2289
2290 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2544 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2291 m_pos += SIT_TARGET_ADJUSTMENT; 2545 m_pos += SIT_TARGET_ADJUSTMENT;
2292 Rotation = sitTargetOrient; 2546 if (!part.IsRoot)
2293 //Rotation = sitTargetOrient; 2547 {
2294 ParentPosition = part.AbsolutePosition; 2548 m_pos *= part.RotationOffset;
2295 2549 }
2296 //SendTerseUpdateToAllClients(); 2550 m_bodyRot = sitTargetOrient;
2551 m_parentPosition = part.AbsolutePosition;
2552 part.IsOccupied = true;
2553 part.ParentGroup.AddAvatar(agentID);
2297 } 2554 }
2298 else 2555 else
2299 { 2556 {
2300 m_pos -= part.AbsolutePosition; 2557 // if m_avUnscriptedSitPos is zero then Av sits above center
2301 ParentPosition = part.AbsolutePosition; 2558 // Else Av sits at m_avUnscriptedSitPos
2302 } 2559
2560 // Non-scripted sit by Kitto Flora 21Nov09
2561 // Calculate angle of line from prim to Av
2562 Quaternion partIRot;
2563// if (part.LinkNum == 1)
2564// { // Root prim of linkset
2565// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2566// }
2567// else
2568// { // single or child prim
2569 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2570// }
2571 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2572 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2573 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2574 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2575 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2576 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2577 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2578 // Av sits at world euler <0,0, z>, translated by part rotation
2579 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2580
2581 m_parentPosition = part.AbsolutePosition;
2582 part.IsOccupied = true;
2583 part.ParentGroup.AddAvatar(agentID);
2584 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2585 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2586 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2587 m_avUnscriptedSitPos; // adds click offset, if any
2588 //Set up raytrace to find top surface of prim
2589 Vector3 size = part.Scale;
2590 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2591 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2592 Vector3 down = new Vector3(0f, 0f, -1f);
2593//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2594 m_scene.PhysicsScene.RaycastWorld(
2595 start, // Vector3 position,
2596 down, // Vector3 direction,
2597 mag, // float length,
2598 SitAltitudeCallback); // retMethod
2599 } // end scripted/not
2303 } 2600 }
2304 else 2601 else // no Av
2305 { 2602 {
2306 return; 2603 return;
2307 } 2604 }
2308 } 2605 }
2309 ParentID = m_requestedSitTargetID; 2606 ParentID = m_requestedSitTargetID;
2310 2607
2608 //We want our offsets to reference the root prim, not the child we may have sat on
2609 if (!part.IsRoot)
2610 {
2611 m_parentID = part.ParentGroup.RootPart.LocalId;
2612 m_pos += part.OffsetPosition;
2613 }
2614 else
2615 {
2616 m_parentID = m_requestedSitTargetID;
2617 }
2618
2619 m_linkedPrim = part.UUID;
2620 if (part.GetAvatarOnSitTarget() != UUID)
2621 {
2622 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2623 }
2311 Velocity = Vector3.Zero; 2624 Velocity = Vector3.Zero;
2312 RemoveFromPhysicalScene(); 2625 RemoveFromPhysicalScene();
2313
2314 Animator.TrySetMovementAnimation(sitAnimation); 2626 Animator.TrySetMovementAnimation(sitAnimation);
2315 SendAvatarDataToAllAgents(); 2627 SendAvatarDataToAllAgents();
2316 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2317 // So we're also sending a terse update (which has avatar rotation)
2318 // [Update] We do now.
2319 //SendTerseUpdateToAllClients(); 2628 //SendTerseUpdateToAllClients();
2320 } 2629 }
2630
2631 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2632 {
2633 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2634 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2635 if(hitYN)
2636 {
2637 // m_pos = Av offset from prim center to make look like on center
2638 // m_parentPosition = Actual center pos of prim
2639 // collisionPoint = spot on prim where we want to sit
2640 // collisionPoint.Z = global sit surface height
2641 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2642 Quaternion partIRot;
2643// if (part.LinkNum == 1)
2644/// { // Root prim of linkset
2645// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2646// }
2647// else
2648// { // single or child prim
2649 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2650// }
2651 if (m_initialSitTarget != null)
2652 {
2653 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2654 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2655 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2656 m_pos += offset;
2657 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2658 }
2659
2660 }
2661 } // End SitAltitudeCallback KF.
2321 2662
2322 /// <summary> 2663 /// <summary>
2323 /// Event handler for the 'Always run' setting on the client 2664 /// Event handler for the 'Always run' setting on the client
@@ -2347,6 +2688,19 @@ namespace OpenSim.Region.Framework.Scenes
2347 Vector3 direc = vec * Rotation; 2688 Vector3 direc = vec * Rotation;
2348 direc.Normalize(); 2689 direc.Normalize();
2349 2690
2691 if (PhysicsActor.Flying != m_flyingOld) // add for fly velocity control
2692 {
2693 m_flyingOld = PhysicsActor.Flying; // add for fly velocity control
2694 if (!PhysicsActor.Flying)
2695 m_wasFlying = true; // add for fly velocity control
2696 }
2697
2698 if (PhysicsActor.IsColliding == true)
2699 m_wasFlying = false; // add for fly velocity control
2700
2701 if ((vec.Z == 0f) && !PhysicsActor.Flying)
2702 direc.Z = 0f; // Prevent camera WASD up.
2703
2350 direc *= 0.03f * 128f * SpeedModifier; 2704 direc *= 0.03f * 128f * SpeedModifier;
2351 2705
2352 if (PhysicsActor != null) 2706 if (PhysicsActor != null)
@@ -2365,6 +2719,10 @@ namespace OpenSim.Region.Framework.Scenes
2365 // m_log.Info("[AGENT]: Stop Flying"); 2719 // m_log.Info("[AGENT]: Stop Flying");
2366 //} 2720 //}
2367 } 2721 }
2722 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2723 {
2724 direc *= 0.0f;
2725 }
2368 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding) 2726 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding)
2369 { 2727 {
2370 if (direc.Z > 2.0f) 2728 if (direc.Z > 2.0f)
@@ -2425,6 +2783,9 @@ namespace OpenSim.Region.Framework.Scenes
2425 2783
2426 CheckForSignificantMovement(); // sends update to the modules. 2784 CheckForSignificantMovement(); // sends update to the modules.
2427 } 2785 }
2786
2787 //Sending prim updates AFTER the avatar terse updates are sent
2788 SendPrimUpdates();
2428 } 2789 }
2429 2790
2430 #endregion 2791 #endregion
@@ -3196,6 +3557,7 @@ namespace OpenSim.Region.Framework.Scenes
3196 m_callbackURI = cAgent.CallbackURI; 3557 m_callbackURI = cAgent.CallbackURI;
3197 3558
3198 m_pos = cAgent.Position; 3559 m_pos = cAgent.Position;
3560
3199 m_velocity = cAgent.Velocity; 3561 m_velocity = cAgent.Velocity;
3200 CameraPosition = cAgent.Center; 3562 CameraPosition = cAgent.Center;
3201 CameraAtAxis = cAgent.AtAxis; 3563 CameraAtAxis = cAgent.AtAxis;
@@ -3345,14 +3707,28 @@ namespace OpenSim.Region.Framework.Scenes
3345 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3707 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
3346 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( 3708 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
3347 // as of this comment the interval is set in AddToPhysicalScene 3709 // as of this comment the interval is set in AddToPhysicalScene
3348 if (Animator != null) 3710 if (Animator!=null)
3349 Animator.UpdateMovementAnimations(); 3711 {
3712 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3713 { // else its will lock out other animation changes, like ground sit.
3714 Animator.UpdateMovementAnimations();
3715 m_updateCount--;
3716 }
3717 }
3350 3718
3351 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3719 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3352 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3720 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3353 3721
3354 CollisionPlane = Vector4.UnitW; 3722 CollisionPlane = Vector4.UnitW;
3355 3723
3724 // No collisions at all means we may be flying. Update always
3725 // to make falling work
3726 if (m_lastColCount != coldata.Count || coldata.Count == 0)
3727 {
3728 m_updateCount = UPDATE_COUNT;
3729 m_lastColCount = coldata.Count;
3730 }
3731
3356 if (coldata.Count != 0 && Animator != null) 3732 if (coldata.Count != 0 && Animator != null)
3357 { 3733 {
3358 switch (Animator.CurrentMovementAnimation) 3734 switch (Animator.CurrentMovementAnimation)
@@ -3382,6 +3758,148 @@ namespace OpenSim.Region.Framework.Scenes
3382 } 3758 }
3383 } 3759 }
3384 3760
3761 List<uint> thisHitColliders = new List<uint>();
3762 List<uint> endedColliders = new List<uint>();
3763 List<uint> startedColliders = new List<uint>();
3764
3765 foreach (uint localid in coldata.Keys)
3766 {
3767 thisHitColliders.Add(localid);
3768 if (!m_lastColliders.Contains(localid))
3769 {
3770 startedColliders.Add(localid);
3771 }
3772 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3773 }
3774
3775 // calculate things that ended colliding
3776 foreach (uint localID in m_lastColliders)
3777 {
3778 if (!thisHitColliders.Contains(localID))
3779 {
3780 endedColliders.Add(localID);
3781 }
3782 }
3783 //add the items that started colliding this time to the last colliders list.
3784 foreach (uint localID in startedColliders)
3785 {
3786 m_lastColliders.Add(localID);
3787 }
3788 // remove things that ended colliding from the last colliders list
3789 foreach (uint localID in endedColliders)
3790 {
3791 m_lastColliders.Remove(localID);
3792 }
3793
3794 // do event notification
3795 if (startedColliders.Count > 0)
3796 {
3797 ColliderArgs StartCollidingMessage = new ColliderArgs();
3798 List<DetectedObject> colliding = new List<DetectedObject>();
3799 foreach (uint localId in startedColliders)
3800 {
3801 if (localId == 0)
3802 continue;
3803
3804 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3805 string data = "";
3806 if (obj != null)
3807 {
3808 DetectedObject detobj = new DetectedObject();
3809 detobj.keyUUID = obj.UUID;
3810 detobj.nameStr = obj.Name;
3811 detobj.ownerUUID = obj.OwnerID;
3812 detobj.posVector = obj.AbsolutePosition;
3813 detobj.rotQuat = obj.GetWorldRotation();
3814 detobj.velVector = obj.Velocity;
3815 detobj.colliderType = 0;
3816 detobj.groupUUID = obj.GroupID;
3817 colliding.Add(detobj);
3818 }
3819 }
3820
3821 if (colliding.Count > 0)
3822 {
3823 StartCollidingMessage.Colliders = colliding;
3824
3825 foreach (SceneObjectGroup att in GetAttachments())
3826 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3827 }
3828 }
3829
3830 if (endedColliders.Count > 0)
3831 {
3832 ColliderArgs EndCollidingMessage = new ColliderArgs();
3833 List<DetectedObject> colliding = new List<DetectedObject>();
3834 foreach (uint localId in endedColliders)
3835 {
3836 if (localId == 0)
3837 continue;
3838
3839 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3840 string data = "";
3841 if (obj != null)
3842 {
3843 DetectedObject detobj = new DetectedObject();
3844 detobj.keyUUID = obj.UUID;
3845 detobj.nameStr = obj.Name;
3846 detobj.ownerUUID = obj.OwnerID;
3847 detobj.posVector = obj.AbsolutePosition;
3848 detobj.rotQuat = obj.GetWorldRotation();
3849 detobj.velVector = obj.Velocity;
3850 detobj.colliderType = 0;
3851 detobj.groupUUID = obj.GroupID;
3852 colliding.Add(detobj);
3853 }
3854 }
3855
3856 if (colliding.Count > 0)
3857 {
3858 EndCollidingMessage.Colliders = colliding;
3859
3860 foreach (SceneObjectGroup att in GetAttachments())
3861 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3862 }
3863 }
3864
3865 if (thisHitColliders.Count > 0)
3866 {
3867 ColliderArgs CollidingMessage = new ColliderArgs();
3868 List<DetectedObject> colliding = new List<DetectedObject>();
3869 foreach (uint localId in thisHitColliders)
3870 {
3871 if (localId == 0)
3872 continue;
3873
3874 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3875 string data = "";
3876 if (obj != null)
3877 {
3878 DetectedObject detobj = new DetectedObject();
3879 detobj.keyUUID = obj.UUID;
3880 detobj.nameStr = obj.Name;
3881 detobj.ownerUUID = obj.OwnerID;
3882 detobj.posVector = obj.AbsolutePosition;
3883 detobj.rotQuat = obj.GetWorldRotation();
3884 detobj.velVector = obj.Velocity;
3885 detobj.colliderType = 0;
3886 detobj.groupUUID = obj.GroupID;
3887 colliding.Add(detobj);
3888 }
3889 }
3890
3891 if (colliding.Count > 0)
3892 {
3893 CollidingMessage.Colliders = colliding;
3894
3895 lock (m_attachments)
3896 {
3897 foreach (SceneObjectGroup att in m_attachments)
3898 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3899 }
3900 }
3901 }
3902
3385 if (Invulnerable) 3903 if (Invulnerable)
3386 return; 3904 return;
3387 3905
@@ -3453,6 +3971,10 @@ namespace OpenSim.Region.Framework.Scenes
3453 { 3971 {
3454 lock (m_attachments) 3972 lock (m_attachments)
3455 { 3973 {
3974 // This may be true when the attachment comes back
3975 // from serialization after login. Clear it.
3976 gobj.IsDeleted = false;
3977
3456 m_attachments.Add(gobj); 3978 m_attachments.Add(gobj);
3457 } 3979 }
3458 } 3980 }
@@ -3816,5 +4338,39 @@ namespace OpenSim.Region.Framework.Scenes
3816 m_reprioritization_called = false; 4338 m_reprioritization_called = false;
3817 } 4339 }
3818 } 4340 }
4341
4342 private Vector3 Quat2Euler(Quaternion rot){
4343 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4344 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4345 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4346 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4347 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4348 return(new Vector3(x,y,z));
4349 }
4350
4351 private void CheckLandingPoint(ref Vector3 pos)
4352 {
4353 // Never constrain lures
4354 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4355 return;
4356
4357 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4358 return;
4359
4360 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4361
4362 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4363 land.LandData.UserLocation != Vector3.Zero &&
4364 land.LandData.OwnerID != m_uuid &&
4365 (!m_scene.Permissions.IsGod(m_uuid)) &&
4366 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4367 {
4368 float curr = Vector3.Distance(AbsolutePosition, pos);
4369 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4370 pos = land.LandData.UserLocation;
4371 else
4372 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4373 }
4374 }
3819 } 4375 }
3820} 4376}