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.cs882
1 files changed, 712 insertions, 170 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 2b7966b..712ec70 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("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] 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.
@@ -118,6 +121,7 @@ namespace OpenSim.Region.Framework.Scenes
118 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 121 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
119 /// necessary. 122 /// necessary.
120 /// </remarks> 123 /// </remarks>
124
121 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 125 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
122 126
123 public Object AttachmentsSyncLock { get; private set; } 127 public Object AttachmentsSyncLock { get; private set; }
@@ -131,8 +135,11 @@ namespace OpenSim.Region.Framework.Scenes
131 public Vector3 lastKnownAllowedPosition; 135 public Vector3 lastKnownAllowedPosition;
132 public bool sentMessageAboutRestrictedParcelFlyingDown; 136 public bool sentMessageAboutRestrictedParcelFlyingDown;
133 public Vector4 CollisionPlane = Vector4.UnitW; 137 public Vector4 CollisionPlane = Vector4.UnitW;
134 138
139 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
140 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
135 private Vector3 m_lastPosition; 141 private Vector3 m_lastPosition;
142 private Vector3 m_lastWorldPosition;
136 private Quaternion m_lastRotation; 143 private Quaternion m_lastRotation;
137 private Vector3 m_lastVelocity; 144 private Vector3 m_lastVelocity;
138 //private int m_lastTerseSent; 145 //private int m_lastTerseSent;
@@ -140,6 +147,11 @@ namespace OpenSim.Region.Framework.Scenes
140 private bool m_updateflag; 147 private bool m_updateflag;
141 private byte m_movementflag; 148 private byte m_movementflag;
142 private Vector3? m_forceToApply; 149 private Vector3? m_forceToApply;
150 private int m_userFlags;
151 public int UserFlags
152 {
153 get { return m_userFlags; }
154 }
143 private TeleportFlags m_teleportFlags; 155 private TeleportFlags m_teleportFlags;
144 public TeleportFlags TeleportFlags 156 public TeleportFlags TeleportFlags
145 { 157 {
@@ -170,9 +182,10 @@ namespace OpenSim.Region.Framework.Scenes
170 private int m_perfMonMS; 182 private int m_perfMonMS;
171 183
172 private bool m_setAlwaysRun; 184 private bool m_setAlwaysRun;
173
174 private bool m_forceFly; 185 private bool m_forceFly;
175 private bool m_flyDisabled; 186 private bool m_flyDisabled;
187 private bool m_flyingOld; // add for fly velocity control
188 public bool m_wasFlying; // add for fly velocity control
176 189
177 private float m_speedModifier = 1.0f; 190 private float m_speedModifier = 1.0f;
178 191
@@ -190,7 +203,8 @@ namespace OpenSim.Region.Framework.Scenes
190 203
191 protected ulong crossingFromRegion; 204 protected ulong crossingFromRegion;
192 205
193 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 206 private readonly Vector3[] Dir_Vectors = new Vector3[11];
207 private bool m_isNudging = false;
194 208
195 // Position of agent's camera in world (region cordinates) 209 // Position of agent's camera in world (region cordinates)
196 protected Vector3 m_CameraCenter; 210 protected Vector3 m_CameraCenter;
@@ -215,17 +229,25 @@ namespace OpenSim.Region.Framework.Scenes
215 private bool m_autopilotMoving; 229 private bool m_autopilotMoving;
216 private Vector3 m_autoPilotTarget; 230 private Vector3 m_autoPilotTarget;
217 private bool m_sitAtAutoTarget; 231 private bool m_sitAtAutoTarget;
232 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
218 233
219 private string m_nextSitAnimation = String.Empty; 234 private string m_nextSitAnimation = String.Empty;
220 235
221 //PauPaw:Proper PID Controler for autopilot************ 236 //PauPaw:Proper PID Controler for autopilot************
222 public bool MovingToTarget { get; private set; } 237 public bool MovingToTarget { get; private set; }
223 public Vector3 MoveToPositionTarget { get; private set; } 238 public Vector3 MoveToPositionTarget { get; private set; }
239 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
224 240
225 private bool m_followCamAuto; 241 private bool m_followCamAuto;
226 242
227 private int m_movementUpdateCount; 243 private int m_movementUpdateCount;
244 private int m_lastColCount = -1; //KF: Look for Collision chnages
245 private int m_updateCount = 0; //KF: Update Anims for a while
246 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
228 private const int NumMovementsBetweenRayCast = 5; 247 private const int NumMovementsBetweenRayCast = 5;
248 private List<uint> m_lastColliders = new List<uint>();
249
250 private object m_syncRoot = new Object();
229 251
230 private bool CameraConstraintActive; 252 private bool CameraConstraintActive;
231 //private int m_moveToPositionStateStatus; 253 //private int m_moveToPositionStateStatus;
@@ -262,7 +284,9 @@ namespace OpenSim.Region.Framework.Scenes
262 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 284 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
263 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 285 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
264 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 286 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
265 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 287 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
288 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
289 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
266 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 290 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
267 } 291 }
268 292
@@ -466,8 +490,9 @@ namespace OpenSim.Region.Framework.Scenes
466 get 490 get
467 { 491 {
468 PhysicsActor actor = m_physicsActor; 492 PhysicsActor actor = m_physicsActor;
469 if (actor != null) 493// if (actor != null)
470 { 494 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
495 {
471 m_pos = actor.Position; 496 m_pos = actor.Position;
472 } 497 }
473 else 498 else
@@ -490,7 +515,7 @@ namespace OpenSim.Region.Framework.Scenes
490 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 515 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
491 if (part != null) 516 if (part != null)
492 { 517 {
493 return m_parentPosition + (m_pos * part.GetWorldRotation()); 518 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
494 } 519 }
495 else 520 else
496 { 521 {
@@ -517,7 +542,9 @@ namespace OpenSim.Region.Framework.Scenes
517 } 542 }
518 } 543 }
519 544
520 m_pos = value; 545// Changed this to update unconditionally to make npose work
546// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
547 m_pos = value;
521 m_parentPosition = Vector3.Zero; 548 m_parentPosition = Vector3.Zero;
522 549
523// m_log.DebugFormat( 550// m_log.DebugFormat(
@@ -568,10 +595,39 @@ namespace OpenSim.Region.Framework.Scenes
568 } 595 }
569 } 596 }
570 597
598 public Quaternion OffsetRotation
599 {
600 get { return m_offsetRotation; }
601 set { m_offsetRotation = value; }
602 }
603
571 public Quaternion Rotation 604 public Quaternion Rotation
572 { 605 {
573 get { return m_bodyRot; } 606 get {
574 set { m_bodyRot = value; } 607 if (m_parentID != 0)
608 {
609 if (m_offsetRotation != null)
610 {
611 return m_offsetRotation;
612 }
613 else
614 {
615 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
616 }
617
618 }
619 else
620 {
621 return m_bodyRot;
622 }
623 }
624 set {
625 m_bodyRot = value;
626 if (m_parentID != 0)
627 {
628 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
629 }
630 }
575 } 631 }
576 632
577 public Quaternion PreviousRotation 633 public Quaternion PreviousRotation
@@ -596,11 +652,21 @@ namespace OpenSim.Region.Framework.Scenes
596 652
597 private uint m_parentID; 653 private uint m_parentID;
598 654
655
656 private UUID m_linkedPrim;
657
599 public uint ParentID 658 public uint ParentID
600 { 659 {
601 get { return m_parentID; } 660 get { return m_parentID; }
602 set { m_parentID = value; } 661 set { m_parentID = value; }
603 } 662 }
663
664 public UUID LinkedPrim
665 {
666 get { return m_linkedPrim; }
667 set { m_linkedPrim = value; }
668 }
669
604 public float Health 670 public float Health
605 { 671 {
606 get { return m_health; } 672 get { return m_health; }
@@ -736,6 +802,7 @@ namespace OpenSim.Region.Framework.Scenes
736 m_localId = m_scene.AllocateLocalId(); 802 m_localId = m_scene.AllocateLocalId();
737 803
738 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 804 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
805 m_userFlags = account.UserFlags;
739 806
740 if (account != null) 807 if (account != null)
741 m_userLevel = account.UserLevel; 808 m_userLevel = account.UserLevel;
@@ -754,10 +821,7 @@ namespace OpenSim.Region.Framework.Scenes
754 m_reprioritization_timer.AutoReset = false; 821 m_reprioritization_timer.AutoReset = false;
755 822
756 AdjustKnownSeeds(); 823 AdjustKnownSeeds();
757
758 // TODO: I think, this won't send anything, as we are still a child here...
759 Animator.TrySetMovementAnimation("STAND"); 824 Animator.TrySetMovementAnimation("STAND");
760
761 // we created a new ScenePresence (a new child agent) in a fresh region. 825 // we created a new ScenePresence (a new child agent) in a fresh region.
762 // Request info about all the (root) agents in this region 826 // Request info about all the (root) agents in this region
763 // Note: This won't send data *to* other clients in that region (children don't send) 827 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -798,25 +862,47 @@ namespace OpenSim.Region.Framework.Scenes
798 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 862 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
799 Dir_Vectors[4] = Vector3.UnitZ; //UP 863 Dir_Vectors[4] = Vector3.UnitZ; //UP
800 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 864 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
801 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 865 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
802 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 866 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
803 Dir_Vectors[7] = -Vector3.UnitX; //BACK 867 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
868 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
869 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
804 } 870 }
805 871
806 private Vector3[] GetWalkDirectionVectors() 872 private Vector3[] GetWalkDirectionVectors()
807 { 873 {
808 Vector3[] vector = new Vector3[9]; 874 Vector3[] vector = new Vector3[11];
809 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 875 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
810 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 876 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
811 vector[2] = Vector3.UnitY; //LEFT 877 vector[2] = Vector3.UnitY; //LEFT
812 vector[3] = -Vector3.UnitY; //RIGHT 878 vector[3] = -Vector3.UnitY; //RIGHT
813 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 879 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
814 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 880 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
815 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 881 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
816 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 882 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
817 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 883 vector[8] = Vector3.UnitY; //LEFT_NUDGE
884 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
885 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
818 return vector; 886 return vector;
819 } 887 }
888
889 private bool[] GetDirectionIsNudge()
890 {
891 bool[] isNudge = new bool[11];
892 isNudge[0] = false; //FORWARD
893 isNudge[1] = false; //BACK
894 isNudge[2] = false; //LEFT
895 isNudge[3] = false; //RIGHT
896 isNudge[4] = false; //UP
897 isNudge[5] = false; //DOWN
898 isNudge[6] = true; //FORWARD_NUDGE
899 isNudge[7] = true; //BACK_NUDGE
900 isNudge[8] = true; //LEFT_NUDGE
901 isNudge[9] = true; //RIGHT_NUDGE
902 isNudge[10] = true; //DOWN_Nudge
903 return isNudge;
904 }
905
820 906
821 #endregion 907 #endregion
822 908
@@ -881,6 +967,62 @@ namespace OpenSim.Region.Framework.Scenes
881 pos.Y = crossedBorder.BorderLine.Z - 1; 967 pos.Y = crossedBorder.BorderLine.Z - 1;
882 } 968 }
883 969
970 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
971 if (land != null)
972 {
973 // If we come in via login, landmark or map, we want to
974 // honor landing points. If we come in via Lure, we want
975 // to ignore them.
976 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
977 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
978 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
979 {
980 // Don't restrict gods, estate managers, or land owners to
981 // the TP point. This behaviour mimics agni.
982 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
983 land.LandData.UserLocation != Vector3.Zero &&
984 GodLevel < 200 &&
985 ((land.LandData.OwnerID != m_uuid &&
986 (!m_scene.Permissions.IsGod(m_uuid)) &&
987 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
988 {
989 pos = land.LandData.UserLocation;
990 }
991 }
992
993 land.SendLandUpdateToClient(ControllingClient);
994 }
995
996 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
997 {
998 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
999
1000 if (pos.X < 0)
1001 {
1002 emergencyPos.X = (int)Constants.RegionSize + pos.X;
1003 if (!(pos.Y < 0))
1004 emergencyPos.Y = pos.Y;
1005 if (!(pos.Z < 0))
1006 emergencyPos.Z = pos.Z;
1007 }
1008 if (pos.Y < 0)
1009 {
1010 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
1011 if (!(pos.X < 0))
1012 emergencyPos.X = pos.X;
1013 if (!(pos.Z < 0))
1014 emergencyPos.Z = pos.Z;
1015 }
1016 if (pos.Z < 0)
1017 {
1018 emergencyPos.Z = 128;
1019 if (!(pos.Y < 0))
1020 emergencyPos.Y = pos.Y;
1021 if (!(pos.X < 0))
1022 emergencyPos.X = pos.X;
1023 }
1024 }
1025
884 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1026 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
885 { 1027 {
886 m_log.WarnFormat( 1028 m_log.WarnFormat(
@@ -1013,16 +1155,21 @@ namespace OpenSim.Region.Framework.Scenes
1013 /// <summary> 1155 /// <summary>
1014 /// Removes physics plugin scene representation of this agent if it exists. 1156 /// Removes physics plugin scene representation of this agent if it exists.
1015 /// </summary> 1157 /// </summary>
1016 private void RemoveFromPhysicalScene() 1158 public void RemoveFromPhysicalScene()
1017 { 1159 {
1018 if (PhysicsActor != null) 1160 if (PhysicsActor != null)
1019 { 1161 {
1020 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1162 try
1021 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1163 {
1022 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1164 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1023 m_physicsActor.UnSubscribeEvents(); 1165 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1024 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1166 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1025 PhysicsActor = null; 1167 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1168 m_physicsActor.UnSubscribeEvents();
1169 PhysicsActor = null;
1170 }
1171 catch
1172 { }
1026 } 1173 }
1027 } 1174 }
1028 1175
@@ -1033,15 +1180,18 @@ namespace OpenSim.Region.Framework.Scenes
1033 public void Teleport(Vector3 pos) 1180 public void Teleport(Vector3 pos)
1034 { 1181 {
1035 bool isFlying = false; 1182 bool isFlying = false;
1183
1036 if (m_physicsActor != null) 1184 if (m_physicsActor != null)
1037 isFlying = m_physicsActor.Flying; 1185 isFlying = m_physicsActor.Flying;
1038 1186
1039 RemoveFromPhysicalScene(); 1187 RemoveFromPhysicalScene();
1040 Velocity = Vector3.Zero; 1188 Velocity = Vector3.Zero;
1189 CheckLandingPoint(ref pos);
1041 AbsolutePosition = pos; 1190 AbsolutePosition = pos;
1042 AddToPhysicalScene(isFlying); 1191 AddToPhysicalScene(isFlying);
1043 1192
1044 SendTerseUpdateToAllClients(); 1193 SendTerseUpdateToAllClients();
1194
1045 } 1195 }
1046 1196
1047 public void TeleportWithMomentum(Vector3 pos) 1197 public void TeleportWithMomentum(Vector3 pos)
@@ -1051,6 +1201,7 @@ namespace OpenSim.Region.Framework.Scenes
1051 isFlying = m_physicsActor.Flying; 1201 isFlying = m_physicsActor.Flying;
1052 1202
1053 RemoveFromPhysicalScene(); 1203 RemoveFromPhysicalScene();
1204 CheckLandingPoint(ref pos);
1054 AbsolutePosition = pos; 1205 AbsolutePosition = pos;
1055 AddToPhysicalScene(isFlying); 1206 AddToPhysicalScene(isFlying);
1056 1207
@@ -1226,11 +1377,12 @@ namespace OpenSim.Region.Framework.Scenes
1226 /// <summary> 1377 /// <summary>
1227 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1378 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1228 /// </summary> 1379 /// </summary>
1380 /// <summary>
1381 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1382 /// </summary>
1229 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1383 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1230 { 1384 {
1231// m_log.DebugFormat( 1385 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1232// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1233// Scene.RegionInfo.RegionName, remoteClient.Name);
1234 1386
1235 //if (m_isChildAgent) 1387 //if (m_isChildAgent)
1236 //{ 1388 //{
@@ -1426,12 +1578,12 @@ namespace OpenSim.Region.Framework.Scenes
1426 1578
1427 if ((m_movementflag & (byte)(uint)DCF) == 0) 1579 if ((m_movementflag & (byte)(uint)DCF) == 0)
1428 { 1580 {
1429 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1581 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1430 { 1582 {
1431 m_movementflag |= (byte)nudgehack; 1583 m_movementflag |= (byte)nudgehack;
1432 } 1584 }
1433 1585
1434// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF); 1586 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF);
1435 m_movementflag += (byte)(uint)DCF; 1587 m_movementflag += (byte)(uint)DCF;
1436 update_movementflag = true; 1588 update_movementflag = true;
1437 } 1589 }
@@ -1439,11 +1591,11 @@ namespace OpenSim.Region.Framework.Scenes
1439 else 1591 else
1440 { 1592 {
1441 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1593 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1442 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1594 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1443 && ((m_movementflag & (byte)nudgehack) == nudgehack)) 1595 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1444 ) // This or is for Nudge forward 1596 ) // This or is for Nudge forward
1445 { 1597 {
1446// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF); 1598 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1447 m_movementflag -= ((byte)(uint)DCF); 1599 m_movementflag -= ((byte)(uint)DCF);
1448 update_movementflag = true; 1600 update_movementflag = true;
1449 1601
@@ -1508,21 +1660,21 @@ namespace OpenSim.Region.Framework.Scenes
1508 // which occurs later in the main scene loop 1660 // which occurs later in the main scene loop
1509 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1661 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1510 { 1662 {
1511// m_log.DebugFormat( 1663 // m_log.DebugFormat(
1512// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1664 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1513// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1665 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1514 1666
1515 AddNewMovement(agent_control_v3); 1667 AddNewMovement(agent_control_v3);
1516 } 1668 }
1517// else 1669 // else
1518// { 1670 // {
1519// if (!update_movementflag) 1671 // if (!update_movementflag)
1520// { 1672 // {
1521// m_log.DebugFormat( 1673 // m_log.DebugFormat(
1522// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1674 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1523// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1675 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1524// } 1676 // }
1525// } 1677 // }
1526 1678
1527 if (update_movementflag && m_parentID == 0) 1679 if (update_movementflag && m_parentID == 0)
1528 Animator.UpdateMovementAnimations(); 1680 Animator.UpdateMovementAnimations();
@@ -1543,20 +1695,20 @@ namespace OpenSim.Region.Framework.Scenes
1543 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1695 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1544 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1696 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1545 { 1697 {
1546// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1698 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1547 1699
1548 bool updated = false; 1700 bool updated = false;
1549 1701
1550// m_log.DebugFormat( 1702 // m_log.DebugFormat(
1551// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1703 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1552// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1704 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1553 1705
1554 if (!m_autopilotMoving) 1706 if (!m_autopilotMoving)
1555 { 1707 {
1556 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1708 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1557// m_log.DebugFormat( 1709 // m_log.DebugFormat(
1558// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1710 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1559// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1711 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1560 1712
1561 // Check the error term of the current position in relation to the target position 1713 // Check the error term of the current position in relation to the target position
1562 if (distanceToTarget <= 1) 1714 if (distanceToTarget <= 1)
@@ -1579,7 +1731,7 @@ namespace OpenSim.Region.Framework.Scenes
1579 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1731 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1580 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1732 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1581 // Ignore z component of vector 1733 // Ignore z component of vector
1582// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1734 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1583 LocalVectorToTarget3D.Normalize(); 1735 LocalVectorToTarget3D.Normalize();
1584 1736
1585 // update avatar movement flags. the avatar coordinate system is as follows: 1737 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1645,9 +1797,9 @@ namespace OpenSim.Region.Framework.Scenes
1645 updated = true; 1797 updated = true;
1646 } 1798 }
1647 1799
1648// m_log.DebugFormat( 1800 // m_log.DebugFormat(
1649// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1801 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1650// LocalVectorToTarget3D, agent_control_v3, Name); 1802 // LocalVectorToTarget3D, agent_control_v3, Name);
1651 1803
1652 agent_control_v3 += LocalVectorToTarget3D; 1804 agent_control_v3 += LocalVectorToTarget3D;
1653 } 1805 }
@@ -1749,7 +1901,7 @@ namespace OpenSim.Region.Framework.Scenes
1749 Velocity = Vector3.Zero; 1901 Velocity = Vector3.Zero;
1750 SendAvatarDataToAllAgents(); 1902 SendAvatarDataToAllAgents();
1751 1903
1752 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1904 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1753 } 1905 }
1754 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1906 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1755 m_requestedSitTargetUUID = UUID.Zero; 1907 m_requestedSitTargetUUID = UUID.Zero;
@@ -1786,25 +1938,22 @@ namespace OpenSim.Region.Framework.Scenes
1786 1938
1787 if (m_parentID != 0) 1939 if (m_parentID != 0)
1788 { 1940 {
1789 m_log.Debug("StandupCode Executed"); 1941 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1790 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1791 if (part != null) 1942 if (part != null)
1792 { 1943 {
1944 part.TaskInventory.LockItemsForRead(true);
1793 TaskInventoryDictionary taskIDict = part.TaskInventory; 1945 TaskInventoryDictionary taskIDict = part.TaskInventory;
1794 if (taskIDict != null) 1946 if (taskIDict != null)
1795 { 1947 {
1796 lock (taskIDict) 1948 foreach (UUID taskID in taskIDict.Keys)
1797 { 1949 {
1798 foreach (UUID taskID in taskIDict.Keys) 1950 UnRegisterControlEventsToScript(LocalId, taskID);
1799 { 1951 taskIDict[taskID].PermsMask &= ~(
1800 UnRegisterControlEventsToScript(LocalId, taskID); 1952 2048 | //PERMISSION_CONTROL_CAMERA
1801 taskIDict[taskID].PermsMask &= ~( 1953 4); // PERMISSION_TAKE_CONTROLS
1802 2048 | //PERMISSION_CONTROL_CAMERA
1803 4); // PERMISSION_TAKE_CONTROLS
1804 }
1805 } 1954 }
1806
1807 } 1955 }
1956 part.TaskInventory.LockItemsForRead(false);
1808 // Reset sit target. 1957 // Reset sit target.
1809 if (part.GetAvatarOnSitTarget() == UUID) 1958 if (part.GetAvatarOnSitTarget() == UUID)
1810 part.SitTargetAvatar = UUID.Zero; 1959 part.SitTargetAvatar = UUID.Zero;
@@ -1813,20 +1962,58 @@ namespace OpenSim.Region.Framework.Scenes
1813 m_parentPosition = part.GetWorldPosition(); 1962 m_parentPosition = part.GetWorldPosition();
1814 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1963 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1815 } 1964 }
1965 // part.GetWorldRotation() is the rotation of the object being sat on
1966 // Rotation is the sittiing Av's rotation
1967
1968 Quaternion partRot;
1969// if (part.LinkNum == 1)
1970// { // Root prim of linkset
1971// partRot = part.ParentGroup.RootPart.RotationOffset;
1972// }
1973// else
1974// { // single or child prim
1975
1976// }
1977 if (part == null) //CW: Part may be gone. llDie() for example.
1978 {
1979 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1980 }
1981 else
1982 {
1983 partRot = part.GetWorldRotation();
1984 }
1816 1985
1986 Quaternion partIRot = Quaternion.Inverse(partRot);
1987
1988 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1989 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1990
1991
1817 if (m_physicsActor == null) 1992 if (m_physicsActor == null)
1818 { 1993 {
1819 AddToPhysicalScene(false); 1994 AddToPhysicalScene(false);
1820 } 1995 }
1821 1996 //CW: If the part isn't null then we can set the current position
1822 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1997 if (part != null)
1823 m_parentPosition = Vector3.Zero; 1998 {
1824 1999 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1825 m_parentID = 0; 2000 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2001 part.IsOccupied = false;
2002 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2003 }
2004 else
2005 {
2006 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2007 AbsolutePosition = m_lastWorldPosition;
2008 }
2009
2010 m_parentPosition = Vector3.Zero;
2011 m_parentID = 0;
2012 m_linkedPrim = UUID.Zero;
2013 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1826 SendAvatarDataToAllAgents(); 2014 SendAvatarDataToAllAgents();
1827 m_requestedSitTargetID = 0; 2015 m_requestedSitTargetID = 0;
1828 } 2016 }
1829
1830 Animator.TrySetMovementAnimation("STAND"); 2017 Animator.TrySetMovementAnimation("STAND");
1831 } 2018 }
1832 2019
@@ -1857,13 +2044,9 @@ namespace OpenSim.Region.Framework.Scenes
1857 Vector3 avSitOffSet = part.SitTargetPosition; 2044 Vector3 avSitOffSet = part.SitTargetPosition;
1858 Quaternion avSitOrientation = part.SitTargetOrientation; 2045 Quaternion avSitOrientation = part.SitTargetOrientation;
1859 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2046 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1860 2047 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1861 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2048 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1862 bool SitTargetisSet = 2049 if (SitTargetisSet && !SitTargetOccupied)
1863 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1864 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1865
1866 if (SitTargetisSet && SitTargetUnOccupied)
1867 { 2050 {
1868 //switch the target to this prim 2051 //switch the target to this prim
1869 return part; 2052 return part;
@@ -1877,85 +2060,168 @@ namespace OpenSim.Region.Framework.Scenes
1877 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2060 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1878 { 2061 {
1879 bool autopilot = true; 2062 bool autopilot = true;
2063 Vector3 autopilotTarget = new Vector3();
2064 Quaternion sitOrientation = Quaternion.Identity;
1880 Vector3 pos = new Vector3(); 2065 Vector3 pos = new Vector3();
1881 Quaternion sitOrientation = pSitOrientation;
1882 Vector3 cameraEyeOffset = Vector3.Zero; 2066 Vector3 cameraEyeOffset = Vector3.Zero;
1883 Vector3 cameraAtOffset = Vector3.Zero; 2067 Vector3 cameraAtOffset = Vector3.Zero;
1884 bool forceMouselook = false; 2068 bool forceMouselook = false;
1885 2069
1886 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2070 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1887 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2071 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1888 if (part != null) 2072 if (part == null) return;
2073
2074 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2075 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2076
2077 // part is the prim to sit on
2078 // offset is the world-ref vector distance from that prim center to the click-spot
2079 // UUID is the UUID of the Avatar doing the clicking
2080
2081 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2082
2083 // Is a sit target available?
2084 Vector3 avSitOffSet = part.SitTargetPosition;
2085 Quaternion avSitOrientation = part.SitTargetOrientation;
2086
2087 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2088 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2089 Quaternion partRot;
2090// if (part.LinkNum == 1)
2091// { // Root prim of linkset
2092// partRot = part.ParentGroup.RootPart.RotationOffset;
2093// }
2094// else
2095// { // single or child prim
2096 partRot = part.GetWorldRotation();
2097// }
2098 Quaternion partIRot = Quaternion.Inverse(partRot);
2099//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2100 // Sit analysis rewritten by KF 091125
2101 if (SitTargetisSet) // scipted sit
1889 { 2102 {
1890 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2103 if (!part.IsOccupied)
1891 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2104 {
1892 2105//Console.WriteLine("Scripted, unoccupied");
1893 // Is a sit target available? 2106 part.SitTargetAvatar = UUID; // set that Av will be on it
1894 Vector3 avSitOffSet = part.SitTargetPosition; 2107 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1895 Quaternion avSitOrientation = part.SitTargetOrientation; 2108
1896 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2109 Quaternion nrot = avSitOrientation;
1897 2110 if (!part.IsRoot)
1898 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1899 bool SitTargetisSet =
1900 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1901 (
1902 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1903 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1904 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1905 )
1906 ));
1907
1908 if (SitTargetisSet && SitTargetUnOccupied)
1909 {
1910 part.SitTargetAvatar = UUID;
1911 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1912 sitOrientation = avSitOrientation;
1913 autopilot = false;
1914 }
1915 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1916
1917 pos = part.AbsolutePosition + offset;
1918 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1919 //{
1920 // offset = pos;
1921 //autopilot = false;
1922 //}
1923 if (m_physicsActor != null)
1924 {
1925 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1926 // We can remove the physicsActor until they stand up.
1927 m_sitAvatarHeight = m_physicsActor.Size.Z;
1928
1929 if (autopilot)
1930 { 2111 {
1931 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2112 nrot = part.RotationOffset * avSitOrientation;
1932 {
1933 autopilot = false;
1934
1935 RemoveFromPhysicalScene();
1936 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1937 }
1938 } 2113 }
1939 else 2114 sitOrientation = nrot; // Change rotatione to the scripted one
2115 OffsetRotation = nrot;
2116 autopilot = false; // Jump direct to scripted llSitPos()
2117 }
2118 else
2119 {
2120//Console.WriteLine("Scripted, occupied");
2121 return;
2122 }
2123 }
2124 else // Not Scripted
2125 {
2126 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
2127 {
2128 // large prim & offset, ignore if other Avs sitting
2129// offset.Z -= 0.05f;
2130 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2131 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2132
2133//Console.WriteLine(" offset ={0}", offset);
2134//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2135//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2136
2137 }
2138 else // small offset
2139 {
2140//Console.WriteLine("Small offset");
2141 if (!part.IsOccupied)
2142 {
2143 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2144 autopilotTarget = part.AbsolutePosition;
2145//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2146 }
2147 else return; // occupied small
2148 } // end large/small
2149 } // end Scripted/not
2150
2151 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2152
2153 cameraAtOffset = part.GetCameraAtOffset();
2154 cameraEyeOffset = part.GetCameraEyeOffset();
2155 forceMouselook = part.GetForceMouselook();
2156 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2157 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2158
2159 if (m_physicsActor != null)
2160 {
2161 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2162 // We can remove the physicsActor until they stand up.
2163 m_sitAvatarHeight = m_physicsActor.Size.Z;
2164 if (autopilot)
2165 { // its not a scripted sit
2166// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2167 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1940 { 2168 {
2169 autopilot = false; // close enough
2170 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2171 Not using the part's position because returning the AV to the last known standing
2172 position is likely to be more friendly, isn't it? */
1941 RemoveFromPhysicalScene(); 2173 RemoveFromPhysicalScene();
1942 } 2174 Velocity = Vector3.Zero;
2175 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2176 } // else the autopilot will get us close
2177 }
2178 else
2179 { // its a scripted sit
2180 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2181 I *am* using the part's position this time because we have no real idea how far away
2182 the avatar is from the sit target. */
2183 RemoveFromPhysicalScene();
2184 Velocity = Vector3.Zero;
1943 } 2185 }
1944
1945 cameraAtOffset = part.GetCameraAtOffset();
1946 cameraEyeOffset = part.GetCameraEyeOffset();
1947 forceMouselook = part.GetForceMouselook();
1948 } 2186 }
1949 2187 else return; // physactor is null!
1950 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2188
1951 m_requestedSitTargetUUID = targetID; 2189 Vector3 offsetr; // = offset * partIRot;
2190 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2191 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2192 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2193 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2194 //offsetr = offset * partIRot;
2195//
2196 // }
2197 // else
2198 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2199 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2200 // (offset * partRot);
2201 // }
2202
2203//Console.WriteLine(" ");
2204//Console.WriteLine("link number ={0}", part.LinkNum);
2205//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2206//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2207//Console.WriteLine("Click offst ={0}", offset);
2208//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2209//Console.WriteLine("offsetr ={0}", offsetr);
2210//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2211//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2212
2213 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2214 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2215
2216 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1952 // This calls HandleAgentSit twice, once from here, and the client calls 2217 // This calls HandleAgentSit twice, once from here, and the client calls
1953 // HandleAgentSit itself after it gets to the location 2218 // HandleAgentSit itself after it gets to the location
1954 // It doesn't get to the location until we've moved them there though 2219 // It doesn't get to the location until we've moved them there though
1955 // which happens in HandleAgentSit :P 2220 // which happens in HandleAgentSit :P
1956 m_autopilotMoving = autopilot; 2221 m_autopilotMoving = autopilot;
1957 m_autoPilotTarget = pos; 2222 m_autoPilotTarget = autopilotTarget;
1958 m_sitAtAutoTarget = autopilot; 2223 m_sitAtAutoTarget = autopilot;
2224 m_initialSitTarget = autopilotTarget;
1959 if (!autopilot) 2225 if (!autopilot)
1960 HandleAgentSit(remoteClient, UUID); 2226 HandleAgentSit(remoteClient, UUID);
1961 } 2227 }
@@ -2220,47 +2486,130 @@ namespace OpenSim.Region.Framework.Scenes
2220 { 2486 {
2221 if (part != null) 2487 if (part != null)
2222 { 2488 {
2489//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2223 if (part.GetAvatarOnSitTarget() == UUID) 2490 if (part.GetAvatarOnSitTarget() == UUID)
2224 { 2491 {
2492//Console.WriteLine("Scripted Sit");
2493 // Scripted sit
2225 Vector3 sitTargetPos = part.SitTargetPosition; 2494 Vector3 sitTargetPos = part.SitTargetPosition;
2226 Quaternion sitTargetOrient = part.SitTargetOrientation; 2495 Quaternion sitTargetOrient = part.SitTargetOrientation;
2227
2228 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2229 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2230
2231 //Quaternion result = (sitTargetOrient * vq) * nq;
2232
2233 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2496 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2234 m_pos += SIT_TARGET_ADJUSTMENT; 2497 m_pos += SIT_TARGET_ADJUSTMENT;
2498 if (!part.IsRoot)
2499 {
2500 m_pos *= part.RotationOffset;
2501 }
2235 m_bodyRot = sitTargetOrient; 2502 m_bodyRot = sitTargetOrient;
2236 //Rotation = sitTargetOrient;
2237 m_parentPosition = part.AbsolutePosition; 2503 m_parentPosition = part.AbsolutePosition;
2238 2504 part.IsOccupied = true;
2239 //SendTerseUpdateToAllClients(); 2505 part.ParentGroup.AddAvatar(agentID);
2240 } 2506 }
2241 else 2507 else
2242 { 2508 {
2243 m_pos -= part.AbsolutePosition; 2509 // if m_avUnscriptedSitPos is zero then Av sits above center
2510 // Else Av sits at m_avUnscriptedSitPos
2511
2512 // Non-scripted sit by Kitto Flora 21Nov09
2513 // Calculate angle of line from prim to Av
2514 Quaternion partIRot;
2515// if (part.LinkNum == 1)
2516// { // Root prim of linkset
2517// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2518// }
2519// else
2520// { // single or child prim
2521 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2522// }
2523 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2524 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2525 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2526 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2527 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2528 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2529 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2530 // Av sits at world euler <0,0, z>, translated by part rotation
2531 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2532
2244 m_parentPosition = part.AbsolutePosition; 2533 m_parentPosition = part.AbsolutePosition;
2245 } 2534 part.IsOccupied = true;
2535 part.ParentGroup.AddAvatar(agentID);
2536 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2537 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2538 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2539 m_avUnscriptedSitPos; // adds click offset, if any
2540 //Set up raytrace to find top surface of prim
2541 Vector3 size = part.Scale;
2542 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2543 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2544 Vector3 down = new Vector3(0f, 0f, -1f);
2545//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2546 m_scene.PhysicsScene.RaycastWorld(
2547 start, // Vector3 position,
2548 down, // Vector3 direction,
2549 mag, // float length,
2550 SitAltitudeCallback); // retMethod
2551 } // end scripted/not
2246 } 2552 }
2247 else 2553 else // no Av
2248 { 2554 {
2249 return; 2555 return;
2250 } 2556 }
2251 } 2557 }
2252 m_parentID = m_requestedSitTargetID;
2253 2558
2559 //We want our offsets to reference the root prim, not the child we may have sat on
2560 if (!part.IsRoot)
2561 {
2562 m_parentID = part.ParentGroup.RootPart.LocalId;
2563 m_pos += part.OffsetPosition;
2564 }
2565 else
2566 {
2567 m_parentID = m_requestedSitTargetID;
2568 }
2569
2570 m_linkedPrim = part.UUID;
2571 if (part.GetAvatarOnSitTarget() != UUID)
2572 {
2573 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2574 }
2254 Velocity = Vector3.Zero; 2575 Velocity = Vector3.Zero;
2255 RemoveFromPhysicalScene(); 2576 RemoveFromPhysicalScene();
2256
2257 Animator.TrySetMovementAnimation(sitAnimation); 2577 Animator.TrySetMovementAnimation(sitAnimation);
2258 SendAvatarDataToAllAgents(); 2578 SendAvatarDataToAllAgents();
2259 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2260 // So we're also sending a terse update (which has avatar rotation)
2261 // [Update] We do now.
2262 //SendTerseUpdateToAllClients(); 2579 //SendTerseUpdateToAllClients();
2263 } 2580 }
2581
2582 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2583 {
2584 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2585 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2586 if(hitYN)
2587 {
2588 // m_pos = Av offset from prim center to make look like on center
2589 // m_parentPosition = Actual center pos of prim
2590 // collisionPoint = spot on prim where we want to sit
2591 // collisionPoint.Z = global sit surface height
2592 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2593 Quaternion partIRot;
2594// if (part.LinkNum == 1)
2595/// { // Root prim of linkset
2596// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2597// }
2598// else
2599// { // single or child prim
2600 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2601// }
2602 if (m_initialSitTarget != null)
2603 {
2604 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2605 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2606 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2607 m_pos += offset;
2608 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2609 }
2610
2611 }
2612 } // End SitAltitudeCallback KF.
2264 2613
2265 /// <summary> 2614 /// <summary>
2266 /// Event handler for the 'Always run' setting on the client 2615 /// Event handler for the 'Always run' setting on the client
@@ -2380,6 +2729,9 @@ namespace OpenSim.Region.Framework.Scenes
2380 2729
2381 CheckForSignificantMovement(); // sends update to the modules. 2730 CheckForSignificantMovement(); // sends update to the modules.
2382 } 2731 }
2732
2733 //Sending prim updates AFTER the avatar terse updates are sent
2734 SendPrimUpdates();
2383 } 2735 }
2384 2736
2385 #endregion 2737 #endregion
@@ -3189,6 +3541,7 @@ namespace OpenSim.Region.Framework.Scenes
3189 m_callbackURI = cAgent.CallbackURI; 3541 m_callbackURI = cAgent.CallbackURI;
3190 3542
3191 m_pos = cAgent.Position; 3543 m_pos = cAgent.Position;
3544
3192 m_velocity = cAgent.Velocity; 3545 m_velocity = cAgent.Velocity;
3193 m_CameraCenter = cAgent.Center; 3546 m_CameraCenter = cAgent.Center;
3194 m_CameraAtAxis = cAgent.AtAxis; 3547 m_CameraAtAxis = cAgent.AtAxis;
@@ -3301,10 +3654,8 @@ namespace OpenSim.Region.Framework.Scenes
3301 3654
3302 Vector3 pVec = AbsolutePosition; 3655 Vector3 pVec = AbsolutePosition;
3303 3656
3304 // Old bug where the height was in centimeters instead of meters 3657 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3305 m_physicsActor = scene.AddAvatar(LocalId, Firstname + "." + Lastname, pVec,
3306 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3658 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3307
3308 scene.AddPhysicsActorTaint(m_physicsActor); 3659 scene.AddPhysicsActorTaint(m_physicsActor);
3309 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3660 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3310 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3661 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3330,18 +3681,29 @@ namespace OpenSim.Region.Framework.Scenes
3330 { 3681 {
3331 if (e == null) 3682 if (e == null)
3332 return; 3683 return;
3333 3684
3334 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3685 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3335 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3336 // as of this comment the interval is set in AddToPhysicalScene 3686 // as of this comment the interval is set in AddToPhysicalScene
3337 if (Animator != null) 3687 if (Animator!=null)
3338 Animator.UpdateMovementAnimations(); 3688 {
3689 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3690 { // else its will lock out other animation changes, like ground sit.
3691 Animator.UpdateMovementAnimations();
3692 m_updateCount--;
3693 }
3694 }
3339 3695
3340 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3696 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3341 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3697 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3342 3698
3343 CollisionPlane = Vector4.UnitW; 3699 CollisionPlane = Vector4.UnitW;
3344 3700
3701 if (m_lastColCount != coldata.Count)
3702 {
3703 m_updateCount = UPDATE_COUNT;
3704 m_lastColCount = coldata.Count;
3705 }
3706
3345 if (coldata.Count != 0 && Animator != null) 3707 if (coldata.Count != 0 && Animator != null)
3346 { 3708 {
3347 switch (Animator.CurrentMovementAnimation) 3709 switch (Animator.CurrentMovementAnimation)
@@ -3371,6 +3733,148 @@ namespace OpenSim.Region.Framework.Scenes
3371 } 3733 }
3372 } 3734 }
3373 3735
3736 List<uint> thisHitColliders = new List<uint>();
3737 List<uint> endedColliders = new List<uint>();
3738 List<uint> startedColliders = new List<uint>();
3739
3740 foreach (uint localid in coldata.Keys)
3741 {
3742 thisHitColliders.Add(localid);
3743 if (!m_lastColliders.Contains(localid))
3744 {
3745 startedColliders.Add(localid);
3746 }
3747 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3748 }
3749
3750 // calculate things that ended colliding
3751 foreach (uint localID in m_lastColliders)
3752 {
3753 if (!thisHitColliders.Contains(localID))
3754 {
3755 endedColliders.Add(localID);
3756 }
3757 }
3758 //add the items that started colliding this time to the last colliders list.
3759 foreach (uint localID in startedColliders)
3760 {
3761 m_lastColliders.Add(localID);
3762 }
3763 // remove things that ended colliding from the last colliders list
3764 foreach (uint localID in endedColliders)
3765 {
3766 m_lastColliders.Remove(localID);
3767 }
3768
3769 // do event notification
3770 if (startedColliders.Count > 0)
3771 {
3772 ColliderArgs StartCollidingMessage = new ColliderArgs();
3773 List<DetectedObject> colliding = new List<DetectedObject>();
3774 foreach (uint localId in startedColliders)
3775 {
3776 if (localId == 0)
3777 continue;
3778
3779 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3780 string data = "";
3781 if (obj != null)
3782 {
3783 DetectedObject detobj = new DetectedObject();
3784 detobj.keyUUID = obj.UUID;
3785 detobj.nameStr = obj.Name;
3786 detobj.ownerUUID = obj.OwnerID;
3787 detobj.posVector = obj.AbsolutePosition;
3788 detobj.rotQuat = obj.GetWorldRotation();
3789 detobj.velVector = obj.Velocity;
3790 detobj.colliderType = 0;
3791 detobj.groupUUID = obj.GroupID;
3792 colliding.Add(detobj);
3793 }
3794 }
3795
3796 if (colliding.Count > 0)
3797 {
3798 StartCollidingMessage.Colliders = colliding;
3799
3800 foreach (SceneObjectGroup att in GetAttachments())
3801 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3802 }
3803 }
3804
3805 if (endedColliders.Count > 0)
3806 {
3807 ColliderArgs EndCollidingMessage = new ColliderArgs();
3808 List<DetectedObject> colliding = new List<DetectedObject>();
3809 foreach (uint localId in endedColliders)
3810 {
3811 if (localId == 0)
3812 continue;
3813
3814 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3815 string data = "";
3816 if (obj != null)
3817 {
3818 DetectedObject detobj = new DetectedObject();
3819 detobj.keyUUID = obj.UUID;
3820 detobj.nameStr = obj.Name;
3821 detobj.ownerUUID = obj.OwnerID;
3822 detobj.posVector = obj.AbsolutePosition;
3823 detobj.rotQuat = obj.GetWorldRotation();
3824 detobj.velVector = obj.Velocity;
3825 detobj.colliderType = 0;
3826 detobj.groupUUID = obj.GroupID;
3827 colliding.Add(detobj);
3828 }
3829 }
3830
3831 if (colliding.Count > 0)
3832 {
3833 EndCollidingMessage.Colliders = colliding;
3834
3835 foreach (SceneObjectGroup att in GetAttachments())
3836 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3837 }
3838 }
3839
3840 if (thisHitColliders.Count > 0)
3841 {
3842 ColliderArgs CollidingMessage = new ColliderArgs();
3843 List<DetectedObject> colliding = new List<DetectedObject>();
3844 foreach (uint localId in thisHitColliders)
3845 {
3846 if (localId == 0)
3847 continue;
3848
3849 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3850 string data = "";
3851 if (obj != null)
3852 {
3853 DetectedObject detobj = new DetectedObject();
3854 detobj.keyUUID = obj.UUID;
3855 detobj.nameStr = obj.Name;
3856 detobj.ownerUUID = obj.OwnerID;
3857 detobj.posVector = obj.AbsolutePosition;
3858 detobj.rotQuat = obj.GetWorldRotation();
3859 detobj.velVector = obj.Velocity;
3860 detobj.colliderType = 0;
3861 detobj.groupUUID = obj.GroupID;
3862 colliding.Add(detobj);
3863 }
3864 }
3865
3866 if (colliding.Count > 0)
3867 {
3868 CollidingMessage.Colliders = colliding;
3869
3870 lock (m_attachments)
3871 {
3872 foreach (SceneObjectGroup att in m_attachments)
3873 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3874 }
3875 }
3876 }
3877
3374 if (m_invulnerable) 3878 if (m_invulnerable)
3375 return; 3879 return;
3376 3880
@@ -3444,6 +3948,10 @@ namespace OpenSim.Region.Framework.Scenes
3444 { 3948 {
3445 lock (m_attachments) 3949 lock (m_attachments)
3446 { 3950 {
3951 // This may be true when the attachment comes back
3952 // from serialization after login. Clear it.
3953 gobj.IsDeleted = false;
3954
3447 m_attachments.Add(gobj); 3955 m_attachments.Add(gobj);
3448 } 3956 }
3449 } 3957 }
@@ -3807,5 +4315,39 @@ namespace OpenSim.Region.Framework.Scenes
3807 m_reprioritization_called = false; 4315 m_reprioritization_called = false;
3808 } 4316 }
3809 } 4317 }
4318
4319 private Vector3 Quat2Euler(Quaternion rot){
4320 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4321 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4322 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4323 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4324 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4325 return(new Vector3(x,y,z));
4326 }
4327
4328 private void CheckLandingPoint(ref Vector3 pos)
4329 {
4330 // Never constrain lures
4331 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4332 return;
4333
4334 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4335 return;
4336
4337 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4338
4339 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4340 land.LandData.UserLocation != Vector3.Zero &&
4341 land.LandData.OwnerID != m_uuid &&
4342 (!m_scene.Permissions.IsGod(m_uuid)) &&
4343 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4344 {
4345 float curr = Vector3.Distance(AbsolutePosition, pos);
4346 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4347 pos = land.LandData.UserLocation;
4348 else
4349 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4350 }
4351 }
3810 } 4352 }
3811} \ No newline at end of file 4353}