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.cs679
1 files changed, 507 insertions, 172 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 3964b0b..d7660fd 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;
@@ -73,7 +74,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 74// {
74// m_log.Debug("[ScenePresence] Destructor called"); 75// m_log.Debug("[ScenePresence] Destructor called");
75// } 76// }
76 77
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 78 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 79
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 80 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -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 public UUID currentParcelUUID = UUID.Zero; 97 public UUID currentParcelUUID = UUID.Zero;
95 98
@@ -123,8 +126,11 @@ namespace OpenSim.Region.Framework.Scenes
123 public Vector3 lastKnownAllowedPosition; 126 public Vector3 lastKnownAllowedPosition;
124 public bool sentMessageAboutRestrictedParcelFlyingDown; 127 public bool sentMessageAboutRestrictedParcelFlyingDown;
125 public Vector4 CollisionPlane = Vector4.UnitW; 128 public Vector4 CollisionPlane = Vector4.UnitW;
126 129
130 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
131 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
127 private Vector3 m_lastPosition; 132 private Vector3 m_lastPosition;
133 private Vector3 m_lastWorldPosition;
128 private Quaternion m_lastRotation; 134 private Quaternion m_lastRotation;
129 private Vector3 m_lastVelocity; 135 private Vector3 m_lastVelocity;
130 //private int m_lastTerseSent; 136 //private int m_lastTerseSent;
@@ -157,7 +163,6 @@ namespace OpenSim.Region.Framework.Scenes
157 private int m_perfMonMS; 163 private int m_perfMonMS;
158 164
159 private bool m_setAlwaysRun; 165 private bool m_setAlwaysRun;
160
161 private bool m_forceFly; 166 private bool m_forceFly;
162 private bool m_flyDisabled; 167 private bool m_flyDisabled;
163 168
@@ -183,7 +188,8 @@ namespace OpenSim.Region.Framework.Scenes
183 protected RegionInfo m_regionInfo; 188 protected RegionInfo m_regionInfo;
184 protected ulong crossingFromRegion; 189 protected ulong crossingFromRegion;
185 190
186 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 191 private readonly Vector3[] Dir_Vectors = new Vector3[11];
192 private bool m_isNudging = false;
187 193
188 // Position of agent's camera in world (region cordinates) 194 // Position of agent's camera in world (region cordinates)
189 protected Vector3 m_CameraCenter; 195 protected Vector3 m_CameraCenter;
@@ -208,6 +214,7 @@ namespace OpenSim.Region.Framework.Scenes
208 private bool m_autopilotMoving; 214 private bool m_autopilotMoving;
209 private Vector3 m_autoPilotTarget; 215 private Vector3 m_autoPilotTarget;
210 private bool m_sitAtAutoTarget; 216 private bool m_sitAtAutoTarget;
217 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
211 218
212 private string m_nextSitAnimation = String.Empty; 219 private string m_nextSitAnimation = String.Empty;
213 220
@@ -218,6 +225,9 @@ namespace OpenSim.Region.Framework.Scenes
218 private bool m_followCamAuto; 225 private bool m_followCamAuto;
219 226
220 private int m_movementUpdateCount; 227 private int m_movementUpdateCount;
228 private int m_lastColCount = -1; //KF: Look for Collision chnages
229 private int m_updateCount = 0; //KF: Update Anims for a while
230 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
221 private const int NumMovementsBetweenRayCast = 5; 231 private const int NumMovementsBetweenRayCast = 5;
222 232
223 private bool CameraConstraintActive; 233 private bool CameraConstraintActive;
@@ -245,7 +255,9 @@ namespace OpenSim.Region.Framework.Scenes
245 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 255 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
246 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 256 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
247 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 257 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
248 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 258 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
259 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
260 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 261 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
250 } 262 }
251 263
@@ -452,7 +464,8 @@ namespace OpenSim.Region.Framework.Scenes
452 get 464 get
453 { 465 {
454 PhysicsActor actor = m_physicsActor; 466 PhysicsActor actor = m_physicsActor;
455 if (actor != null) 467// if (actor != null)
468 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
456 m_pos = actor.Position; 469 m_pos = actor.Position;
457 470
458 return m_parentPosition + m_pos; 471 return m_parentPosition + m_pos;
@@ -473,7 +486,8 @@ namespace OpenSim.Region.Framework.Scenes
473 } 486 }
474 } 487 }
475 488
476 m_pos = value; 489 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
490 m_pos = value;
477 m_parentPosition = Vector3.Zero; 491 m_parentPosition = Vector3.Zero;
478 } 492 }
479 } 493 }
@@ -671,7 +685,7 @@ namespace OpenSim.Region.Framework.Scenes
671 CreateSceneViewer(); 685 CreateSceneViewer();
672 m_animator = new ScenePresenceAnimator(this); 686 m_animator = new ScenePresenceAnimator(this);
673 } 687 }
674 688
675 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 689 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
676 { 690 {
677 m_rootRegionHandle = reginfo.RegionHandle; 691 m_rootRegionHandle = reginfo.RegionHandle;
@@ -703,16 +717,16 @@ namespace OpenSim.Region.Framework.Scenes
703 m_reprioritization_timer.AutoReset = false; 717 m_reprioritization_timer.AutoReset = false;
704 718
705 AdjustKnownSeeds(); 719 AdjustKnownSeeds();
706
707 // TODO: I think, this won't send anything, as we are still a child here...
708 Animator.TrySetMovementAnimation("STAND"); 720 Animator.TrySetMovementAnimation("STAND");
709
710 // we created a new ScenePresence (a new child agent) in a fresh region. 721 // we created a new ScenePresence (a new child agent) in a fresh region.
711 // Request info about all the (root) agents in this region 722 // Request info about all the (root) agents in this region
712 // Note: This won't send data *to* other clients in that region (children don't send) 723 // Note: This won't send data *to* other clients in that region (children don't send)
713 SendInitialFullUpdateToAllClients(); 724 SendInitialFullUpdateToAllClients();
714
715 RegisterToEvents(); 725 RegisterToEvents();
726 if (m_controllingClient != null)
727 {
728 m_controllingClient.ProcessPendingPackets();
729 }
716 SetDirectionVectors(); 730 SetDirectionVectors();
717 } 731 }
718 732
@@ -762,25 +776,47 @@ namespace OpenSim.Region.Framework.Scenes
762 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 776 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
763 Dir_Vectors[4] = Vector3.UnitZ; //UP 777 Dir_Vectors[4] = Vector3.UnitZ; //UP
764 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 778 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
765 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 779 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
766 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 780 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
767 Dir_Vectors[7] = -Vector3.UnitX; //BACK 781 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
782 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
783 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
768 } 784 }
769 785
770 private Vector3[] GetWalkDirectionVectors() 786 private Vector3[] GetWalkDirectionVectors()
771 { 787 {
772 Vector3[] vector = new Vector3[9]; 788 Vector3[] vector = new Vector3[11];
773 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 789 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
774 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 790 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
775 vector[2] = Vector3.UnitY; //LEFT 791 vector[2] = Vector3.UnitY; //LEFT
776 vector[3] = -Vector3.UnitY; //RIGHT 792 vector[3] = -Vector3.UnitY; //RIGHT
777 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 793 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
778 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 794 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
779 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 795 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
780 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 796 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
781 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 797 vector[8] = Vector3.UnitY; //LEFT_NUDGE
798 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
799 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
782 return vector; 800 return vector;
783 } 801 }
802
803 private bool[] GetDirectionIsNudge()
804 {
805 bool[] isNudge = new bool[11];
806 isNudge[0] = false; //FORWARD
807 isNudge[1] = false; //BACK
808 isNudge[2] = false; //LEFT
809 isNudge[3] = false; //RIGHT
810 isNudge[4] = false; //UP
811 isNudge[5] = false; //DOWN
812 isNudge[6] = true; //FORWARD_NUDGE
813 isNudge[7] = true; //BACK_NUDGE
814 isNudge[8] = true; //LEFT_NUDGE
815 isNudge[9] = true; //RIGHT_NUDGE
816 isNudge[10] = true; //DOWN_Nudge
817 return isNudge;
818 }
819
784 820
785 #endregion 821 #endregion
786 822
@@ -832,7 +868,6 @@ namespace OpenSim.Region.Framework.Scenes
832 m_grouptitle = gm.GetGroupTitle(m_uuid); 868 m_grouptitle = gm.GetGroupTitle(m_uuid);
833 869
834 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; 870 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle;
835
836 m_scene.SetRootAgentScene(m_uuid); 871 m_scene.SetRootAgentScene(m_uuid);
837 872
838 // Moved this from SendInitialData to ensure that m_appearance is initialized 873 // Moved this from SendInitialData to ensure that m_appearance is initialized
@@ -851,6 +886,52 @@ namespace OpenSim.Region.Framework.Scenes
851 pos.Y = crossedBorder.BorderLine.Z - 1; 886 pos.Y = crossedBorder.BorderLine.Z - 1;
852 } 887 }
853 888
889 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
890 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
891 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
892 if (KnownChildRegionHandles.Count == 0)
893 {
894 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
895 if (land != null)
896 {
897 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
898 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && UserLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
899 {
900 pos = land.LandData.UserLocation;
901 }
902 }
903 }
904
905 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
906 {
907 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
908
909 if (pos.X < 0)
910 {
911 emergencyPos.X = (int)Constants.RegionSize + pos.X;
912 if (!(pos.Y < 0))
913 emergencyPos.Y = pos.Y;
914 if (!(pos.Z < 0))
915 emergencyPos.Z = pos.Z;
916 }
917 if (pos.Y < 0)
918 {
919 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
920 if (!(pos.X < 0))
921 emergencyPos.X = pos.X;
922 if (!(pos.Z < 0))
923 emergencyPos.Z = pos.Z;
924 }
925 if (pos.Z < 0)
926 {
927 emergencyPos.Z = 128;
928 if (!(pos.Y < 0))
929 emergencyPos.Y = pos.Y;
930 if (!(pos.X < 0))
931 emergencyPos.X = pos.X;
932 }
933 }
934
854 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 935 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
855 { 936 {
856 m_log.WarnFormat( 937 m_log.WarnFormat(
@@ -983,9 +1064,10 @@ namespace OpenSim.Region.Framework.Scenes
983 public void Teleport(Vector3 pos) 1064 public void Teleport(Vector3 pos)
984 { 1065 {
985 bool isFlying = false; 1066 bool isFlying = false;
1067
986 if (m_physicsActor != null) 1068 if (m_physicsActor != null)
987 isFlying = m_physicsActor.Flying; 1069 isFlying = m_physicsActor.Flying;
988 1070
989 RemoveFromPhysicalScene(); 1071 RemoveFromPhysicalScene();
990 Velocity = Vector3.Zero; 1072 Velocity = Vector3.Zero;
991 AbsolutePosition = pos; 1073 AbsolutePosition = pos;
@@ -997,6 +1079,7 @@ namespace OpenSim.Region.Framework.Scenes
997 } 1079 }
998 1080
999 SendTerseUpdateToAllClients(); 1081 SendTerseUpdateToAllClients();
1082
1000 } 1083 }
1001 1084
1002 public void TeleportWithMomentum(Vector3 pos) 1085 public void TeleportWithMomentum(Vector3 pos)
@@ -1041,7 +1124,9 @@ namespace OpenSim.Region.Framework.Scenes
1041 { 1124 {
1042 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1125 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1043 } 1126 }
1044 1127
1128 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1129
1045 ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position); 1130 ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position);
1046 //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1131 //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1047 // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1132 // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
@@ -1128,7 +1213,6 @@ namespace OpenSim.Region.Framework.Scenes
1128 pos.Z = ground + 1.5f; 1213 pos.Z = ground + 1.5f;
1129 AbsolutePosition = pos; 1214 AbsolutePosition = pos;
1130 } 1215 }
1131
1132 m_isChildAgent = false; 1216 m_isChildAgent = false;
1133 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1217 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1134 MakeRootAgent(AbsolutePosition, m_flying); 1218 MakeRootAgent(AbsolutePosition, m_flying);
@@ -1227,6 +1311,7 @@ namespace OpenSim.Region.Framework.Scenes
1227 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1311 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1228 1312
1229 m_pos = m_LastFinitePos; 1313 m_pos = m_LastFinitePos;
1314
1230 if (!m_pos.IsFinite()) 1315 if (!m_pos.IsFinite())
1231 { 1316 {
1232 m_pos.X = 127f; 1317 m_pos.X = 127f;
@@ -1293,7 +1378,6 @@ namespace OpenSim.Region.Framework.Scenes
1293 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1378 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1294 } 1379 }
1295 } 1380 }
1296
1297 lock (scriptedcontrols) 1381 lock (scriptedcontrols)
1298 { 1382 {
1299 if (scriptedcontrols.Count > 0) 1383 if (scriptedcontrols.Count > 0)
@@ -1308,6 +1392,9 @@ namespace OpenSim.Region.Framework.Scenes
1308 1392
1309 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1393 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1310 { 1394 {
1395 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1396 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1397
1311 // TODO: This doesn't prevent the user from walking yet. 1398 // TODO: This doesn't prevent the user from walking yet.
1312 // Setting parent ID would fix this, if we knew what value 1399 // Setting parent ID would fix this, if we knew what value
1313 // to use. Or we could add a m_isSitting variable. 1400 // to use. Or we could add a m_isSitting variable.
@@ -1362,6 +1449,11 @@ namespace OpenSim.Region.Framework.Scenes
1362 update_rotation = true; 1449 update_rotation = true;
1363 } 1450 }
1364 1451
1452 //guilty until proven innocent..
1453 bool Nudging = true;
1454 //Basically, if there is at least one non-nudge control then we don't need
1455 //to worry about stopping the avatar
1456
1365 if (m_parentID == 0) 1457 if (m_parentID == 0)
1366 { 1458 {
1367 bool bAllowUpdateMoveToPosition = false; 1459 bool bAllowUpdateMoveToPosition = false;
@@ -1376,9 +1468,12 @@ namespace OpenSim.Region.Framework.Scenes
1376 else 1468 else
1377 dirVectors = Dir_Vectors; 1469 dirVectors = Dir_Vectors;
1378 1470
1379 // The fact that m_movementflag is a byte needs to be fixed 1471 bool[] isNudge = GetDirectionIsNudge();
1380 // it really should be a uint 1472
1381 uint nudgehack = 250; 1473
1474
1475
1476
1382 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1477 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1383 { 1478 {
1384 if (((uint)flags & (uint)DCF) != 0) 1479 if (((uint)flags & (uint)DCF) != 0)
@@ -1388,40 +1483,28 @@ namespace OpenSim.Region.Framework.Scenes
1388 try 1483 try
1389 { 1484 {
1390 agent_control_v3 += dirVectors[i]; 1485 agent_control_v3 += dirVectors[i];
1391 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1486 if (isNudge[i] == false)
1487 {
1488 Nudging = false;
1489 }
1392 } 1490 }
1393 catch (IndexOutOfRangeException) 1491 catch (IndexOutOfRangeException)
1394 { 1492 {
1395 // Why did I get this? 1493 // Why did I get this?
1396 } 1494 }
1397 1495
1398 if ((m_movementflag & (byte)(uint)DCF) == 0) 1496 if ((m_movementflag & (uint)DCF) == 0)
1399 { 1497 {
1400 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1401 {
1402 m_movementflag |= (byte)nudgehack;
1403 }
1404 m_movementflag += (byte)(uint)DCF; 1498 m_movementflag += (byte)(uint)DCF;
1405 update_movementflag = true; 1499 update_movementflag = true;
1406 } 1500 }
1407 } 1501 }
1408 else 1502 else
1409 { 1503 {
1410 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1504 if ((m_movementflag & (uint)DCF) != 0)
1411 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1412 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1413 ) // This or is for Nudge forward
1414 { 1505 {
1415 m_movementflag -= ((byte)(uint)DCF); 1506 m_movementflag -= (byte)(uint)DCF;
1416
1417 update_movementflag = true; 1507 update_movementflag = true;
1418 /*
1419 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1420 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1421 {
1422 m_log.Debug("Removed Hack flag");
1423 }
1424 */
1425 } 1508 }
1426 else 1509 else
1427 { 1510 {
@@ -1430,7 +1513,6 @@ namespace OpenSim.Region.Framework.Scenes
1430 } 1513 }
1431 i++; 1514 i++;
1432 } 1515 }
1433
1434 //Paupaw:Do Proper PID for Autopilot here 1516 //Paupaw:Do Proper PID for Autopilot here
1435 if (bResetMoveToPosition) 1517 if (bResetMoveToPosition)
1436 { 1518 {
@@ -1465,6 +1547,9 @@ namespace OpenSim.Region.Framework.Scenes
1465 // Ignore z component of vector 1547 // Ignore z component of vector
1466 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1548 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1467 LocalVectorToTarget2D.Normalize(); 1549 LocalVectorToTarget2D.Normalize();
1550
1551 //We're not nudging
1552 Nudging = false;
1468 agent_control_v3 += LocalVectorToTarget2D; 1553 agent_control_v3 += LocalVectorToTarget2D;
1469 1554
1470 // update avatar movement flags. the avatar coordinate system is as follows: 1555 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1553,13 +1638,13 @@ namespace OpenSim.Region.Framework.Scenes
1553 // m_log.DebugFormat( 1638 // m_log.DebugFormat(
1554 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1639 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1555 1640
1556 AddNewMovement(agent_control_v3, q); 1641 AddNewMovement(agent_control_v3, q, Nudging);
1557 1642
1558 1643
1559 } 1644 }
1560 } 1645 }
1561 1646
1562 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1647 if (update_movementflag && !SitGround)
1563 Animator.UpdateMovementAnimations(); 1648 Animator.UpdateMovementAnimations();
1564 1649
1565 m_scene.EventManager.TriggerOnClientMovement(this); 1650 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1574,7 +1659,6 @@ namespace OpenSim.Region.Framework.Scenes
1574 m_sitAtAutoTarget = false; 1659 m_sitAtAutoTarget = false;
1575 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1660 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1576 //proxy.PCode = (byte)PCode.ParticleSystem; 1661 //proxy.PCode = (byte)PCode.ParticleSystem;
1577
1578 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1662 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1579 proxyObjectGroup.AttachToScene(m_scene); 1663 proxyObjectGroup.AttachToScene(m_scene);
1580 1664
@@ -1616,7 +1700,7 @@ namespace OpenSim.Region.Framework.Scenes
1616 } 1700 }
1617 m_moveToPositionInProgress = true; 1701 m_moveToPositionInProgress = true;
1618 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1702 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1619 } 1703 }
1620 catch (Exception ex) 1704 catch (Exception ex)
1621 { 1705 {
1622 //Why did I get this error? 1706 //Why did I get this error?
@@ -1638,7 +1722,7 @@ namespace OpenSim.Region.Framework.Scenes
1638 Velocity = Vector3.Zero; 1722 Velocity = Vector3.Zero;
1639 SendFullUpdateToAllClients(); 1723 SendFullUpdateToAllClients();
1640 1724
1641 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1725 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1642 } 1726 }
1643 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1727 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1644 m_requestedSitTargetUUID = UUID.Zero; 1728 m_requestedSitTargetUUID = UUID.Zero;
@@ -1675,50 +1759,82 @@ namespace OpenSim.Region.Framework.Scenes
1675 1759
1676 if (m_parentID != 0) 1760 if (m_parentID != 0)
1677 { 1761 {
1678 m_log.Debug("StandupCode Executed");
1679 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1762 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1680 if (part != null) 1763 if (part != null)
1681 { 1764 {
1765 part.TaskInventory.LockItemsForRead(true);
1682 TaskInventoryDictionary taskIDict = part.TaskInventory; 1766 TaskInventoryDictionary taskIDict = part.TaskInventory;
1683 if (taskIDict != null) 1767 if (taskIDict != null)
1684 { 1768 {
1685 lock (taskIDict) 1769 foreach (UUID taskID in taskIDict.Keys)
1686 { 1770 {
1687 foreach (UUID taskID in taskIDict.Keys) 1771 UnRegisterControlEventsToScript(LocalId, taskID);
1688 { 1772 taskIDict[taskID].PermsMask &= ~(
1689 UnRegisterControlEventsToScript(LocalId, taskID); 1773 2048 | //PERMISSION_CONTROL_CAMERA
1690 taskIDict[taskID].PermsMask &= ~( 1774 4); // PERMISSION_TAKE_CONTROLS
1691 2048 | //PERMISSION_CONTROL_CAMERA
1692 4); // PERMISSION_TAKE_CONTROLS
1693 }
1694 } 1775 }
1695
1696 } 1776 }
1777 part.TaskInventory.LockItemsForRead(false);
1697 // Reset sit target. 1778 // Reset sit target.
1698 if (part.GetAvatarOnSitTarget() == UUID) 1779 if (part.GetAvatarOnSitTarget() == UUID)
1699 part.SetAvatarOnSitTarget(UUID.Zero); 1780 part.SetAvatarOnSitTarget(UUID.Zero);
1700
1701 m_parentPosition = part.GetWorldPosition(); 1781 m_parentPosition = part.GetWorldPosition();
1702 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1782 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1703 } 1783 }
1784 // part.GetWorldRotation() is the rotation of the object being sat on
1785 // Rotation is the sittiing Av's rotation
1786
1787 Quaternion partRot;
1788// if (part.LinkNum == 1)
1789// { // Root prim of linkset
1790// partRot = part.ParentGroup.RootPart.RotationOffset;
1791// }
1792// else
1793// { // single or child prim
1794
1795// }
1796 if (part == null) //CW: Part may be gone. llDie() for example.
1797 {
1798 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1799 }
1800 else
1801 {
1802 partRot = part.GetWorldRotation();
1803 }
1704 1804
1805 Quaternion partIRot = Quaternion.Inverse(partRot);
1806
1807 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1808 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1809
1810
1705 if (m_physicsActor == null) 1811 if (m_physicsActor == null)
1706 { 1812 {
1707 AddToPhysicalScene(false); 1813 AddToPhysicalScene(false);
1708 } 1814 }
1709 1815 //CW: If the part isn't null then we can set the current position
1710 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1816 if (part != null)
1711 m_parentPosition = Vector3.Zero; 1817 {
1712 1818 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1713 m_parentID = 0; 1819 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1820 part.IsOccupied = false;
1821 }
1822 else
1823 {
1824 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1825 AbsolutePosition = m_lastWorldPosition;
1826 }
1827
1828 m_parentPosition = Vector3.Zero;
1829 m_parentID = 0;
1714 SendFullUpdateToAllClients(); 1830 SendFullUpdateToAllClients();
1715 m_requestedSitTargetID = 0; 1831 m_requestedSitTargetID = 0;
1832
1716 if ((m_physicsActor != null) && (m_avHeight > 0)) 1833 if ((m_physicsActor != null) && (m_avHeight > 0))
1717 { 1834 {
1718 SetHeight(m_avHeight); 1835 SetHeight(m_avHeight);
1719 } 1836 }
1720 } 1837 }
1721
1722 Animator.TrySetMovementAnimation("STAND"); 1838 Animator.TrySetMovementAnimation("STAND");
1723 } 1839 }
1724 1840
@@ -1749,13 +1865,9 @@ namespace OpenSim.Region.Framework.Scenes
1749 Vector3 avSitOffSet = part.SitTargetPosition; 1865 Vector3 avSitOffSet = part.SitTargetPosition;
1750 Quaternion avSitOrientation = part.SitTargetOrientation; 1866 Quaternion avSitOrientation = part.SitTargetOrientation;
1751 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1867 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1752 1868 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1753 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1869 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1754 bool SitTargetisSet = 1870 if (SitTargetisSet && !SitTargetOccupied)
1755 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1756 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1757
1758 if (SitTargetisSet && SitTargetUnOccupied)
1759 { 1871 {
1760 //switch the target to this prim 1872 //switch the target to this prim
1761 return part; 1873 return part;
@@ -1769,84 +1881,153 @@ namespace OpenSim.Region.Framework.Scenes
1769 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1881 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1770 { 1882 {
1771 bool autopilot = true; 1883 bool autopilot = true;
1884 Vector3 autopilotTarget = new Vector3();
1885 Quaternion sitOrientation = Quaternion.Identity;
1772 Vector3 pos = new Vector3(); 1886 Vector3 pos = new Vector3();
1773 Quaternion sitOrientation = pSitOrientation;
1774 Vector3 cameraEyeOffset = Vector3.Zero; 1887 Vector3 cameraEyeOffset = Vector3.Zero;
1775 Vector3 cameraAtOffset = Vector3.Zero; 1888 Vector3 cameraAtOffset = Vector3.Zero;
1776 bool forceMouselook = false; 1889 bool forceMouselook = false;
1777 1890
1778 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1891 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1779 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1892 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1780 if (part != null) 1893 if (part == null) return;
1781 { 1894
1782 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1895 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1783 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1896 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1784 1897
1785 // Is a sit target available? 1898 // part is the prim to sit on
1786 Vector3 avSitOffSet = part.SitTargetPosition; 1899 // offset is the world-ref vector distance from that prim center to the click-spot
1787 Quaternion avSitOrientation = part.SitTargetOrientation; 1900 // UUID is the UUID of the Avatar doing the clicking
1788 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1901
1789 1902 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1790 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1903
1791 bool SitTargetisSet = 1904 // Is a sit target available?
1792 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1905 Vector3 avSitOffSet = part.SitTargetPosition;
1793 ( 1906 Quaternion avSitOrientation = part.SitTargetOrientation;
1794 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1907
1795 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1908 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1796 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1909 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1797 ) 1910 Quaternion partRot;
1798 )); 1911// if (part.LinkNum == 1)
1799 1912// { // Root prim of linkset
1800 if (SitTargetisSet && SitTargetUnOccupied) 1913// partRot = part.ParentGroup.RootPart.RotationOffset;
1801 { 1914// }
1802 part.SetAvatarOnSitTarget(UUID); 1915// else
1803 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1916// { // single or child prim
1804 sitOrientation = avSitOrientation; 1917 partRot = part.GetWorldRotation();
1805 autopilot = false; 1918// }
1806 } 1919 Quaternion partIRot = Quaternion.Inverse(partRot);
1807 1920//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1808 pos = part.AbsolutePosition + offset; 1921 // Sit analysis rewritten by KF 091125
1809 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1922 if (SitTargetisSet) // scipted sit
1810 //{ 1923 {
1811 // offset = pos; 1924 if (!part.IsOccupied)
1812 //autopilot = false; 1925 {
1813 //} 1926//Console.WriteLine("Scripted, unoccupied");
1814 if (m_physicsActor != null) 1927 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1815 { 1928 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1816 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1929 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1817 // We can remove the physicsActor until they stand up. 1930 autopilot = false; // Jump direct to scripted llSitPos()
1818 m_sitAvatarHeight = m_physicsActor.Size.Z; 1931 }
1819 1932 else
1820 if (autopilot) 1933 {
1821 { 1934//Console.WriteLine("Scripted, occupied");
1822 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1935 return;
1823 { 1936 }
1824 autopilot = false; 1937 }
1938 else // Not Scripted
1939 {
1940 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1941 {
1942 // large prim & offset, ignore if other Avs sitting
1943// offset.Z -= 0.05f;
1944 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1945 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1946
1947//Console.WriteLine(" offset ={0}", offset);
1948//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1949//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1950
1951 }
1952 else // small offset
1953 {
1954//Console.WriteLine("Small offset");
1955 if (!part.IsOccupied)
1956 {
1957 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1958 autopilotTarget = part.AbsolutePosition;
1959//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1960 }
1961 else return; // occupied small
1962 } // end large/small
1963 } // end Scripted/not
1964 cameraAtOffset = part.GetCameraAtOffset();
1965 cameraEyeOffset = part.GetCameraEyeOffset();
1966 forceMouselook = part.GetForceMouselook();
1967 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1968 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1825 1969
1826 RemoveFromPhysicalScene(); 1970 if (m_physicsActor != null)
1827 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1971 {
1828 } 1972 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1829 } 1973 // We can remove the physicsActor until they stand up.
1830 else 1974 m_sitAvatarHeight = m_physicsActor.Size.Z;
1975 if (autopilot)
1976 { // its not a scripted sit
1977// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1978 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1831 { 1979 {
1980 autopilot = false; // close enough
1981 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1982 Not using the part's position because returning the AV to the last known standing
1983 position is likely to be more friendly, isn't it? */
1832 RemoveFromPhysicalScene(); 1984 RemoveFromPhysicalScene();
1833 } 1985 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1986 } // else the autopilot will get us close
1987 }
1988 else
1989 { // its a scripted sit
1990 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1991 I *am* using the part's position this time because we have no real idea how far away
1992 the avatar is from the sit target. */
1993 RemoveFromPhysicalScene();
1834 } 1994 }
1835
1836 cameraAtOffset = part.GetCameraAtOffset();
1837 cameraEyeOffset = part.GetCameraEyeOffset();
1838 forceMouselook = part.GetForceMouselook();
1839 } 1995 }
1840 1996 else return; // physactor is null!
1841 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1997
1842 m_requestedSitTargetUUID = targetID; 1998 Vector3 offsetr; // = offset * partIRot;
1999 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2000 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2001 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2002 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2003 offsetr = offset * partIRot;
2004//
2005 // else
2006 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2007 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2008 // (offset * partRot);
2009 // }
2010
2011//Console.WriteLine(" ");
2012//Console.WriteLine("link number ={0}", part.LinkNum);
2013//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2014//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2015//Console.WriteLine("Click offst ={0}", offset);
2016//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2017//Console.WriteLine("offsetr ={0}", offsetr);
2018//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2019//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2020
2021 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2022 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1843 // This calls HandleAgentSit twice, once from here, and the client calls 2023 // This calls HandleAgentSit twice, once from here, and the client calls
1844 // HandleAgentSit itself after it gets to the location 2024 // HandleAgentSit itself after it gets to the location
1845 // It doesn't get to the location until we've moved them there though 2025 // It doesn't get to the location until we've moved them there though
1846 // which happens in HandleAgentSit :P 2026 // which happens in HandleAgentSit :P
1847 m_autopilotMoving = autopilot; 2027 m_autopilotMoving = autopilot;
1848 m_autoPilotTarget = pos; 2028 m_autoPilotTarget = autopilotTarget;
1849 m_sitAtAutoTarget = autopilot; 2029 m_sitAtAutoTarget = autopilot;
2030 m_initialSitTarget = autopilotTarget;
1850 if (!autopilot) 2031 if (!autopilot)
1851 HandleAgentSit(remoteClient, UUID); 2032 HandleAgentSit(remoteClient, UUID);
1852 } 2033 }
@@ -2141,31 +2322,66 @@ namespace OpenSim.Region.Framework.Scenes
2141 { 2322 {
2142 if (part != null) 2323 if (part != null)
2143 { 2324 {
2325//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2144 if (part.GetAvatarOnSitTarget() == UUID) 2326 if (part.GetAvatarOnSitTarget() == UUID)
2145 { 2327 {
2328//Console.WriteLine("Scripted Sit");
2329 // Scripted sit
2146 Vector3 sitTargetPos = part.SitTargetPosition; 2330 Vector3 sitTargetPos = part.SitTargetPosition;
2147 Quaternion sitTargetOrient = part.SitTargetOrientation; 2331 Quaternion sitTargetOrient = part.SitTargetOrientation;
2148
2149 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2150 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2151
2152 //Quaternion result = (sitTargetOrient * vq) * nq;
2153
2154 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2332 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2155 m_pos += SIT_TARGET_ADJUSTMENT; 2333 m_pos += SIT_TARGET_ADJUSTMENT;
2156 m_bodyRot = sitTargetOrient; 2334 m_bodyRot = sitTargetOrient;
2157 //Rotation = sitTargetOrient;
2158 m_parentPosition = part.AbsolutePosition; 2335 m_parentPosition = part.AbsolutePosition;
2159 2336 part.IsOccupied = true;
2160 //SendTerseUpdateToAllClients(); 2337Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2161 } 2338 }
2162 else 2339 else
2163 { 2340 {
2164 m_pos -= part.AbsolutePosition; 2341 // if m_avUnscriptedSitPos is zero then Av sits above center
2342 // Else Av sits at m_avUnscriptedSitPos
2343
2344 // Non-scripted sit by Kitto Flora 21Nov09
2345 // Calculate angle of line from prim to Av
2346 Quaternion partIRot;
2347// if (part.LinkNum == 1)
2348// { // Root prim of linkset
2349// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2350// }
2351// else
2352// { // single or child prim
2353 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2354// }
2355 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2356 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2357 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2358 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2359 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2360 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2361 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2362 // Av sits at world euler <0,0, z>, translated by part rotation
2363 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2364
2165 m_parentPosition = part.AbsolutePosition; 2365 m_parentPosition = part.AbsolutePosition;
2166 } 2366 part.IsOccupied = true;
2367 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2368 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2369 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2370 m_avUnscriptedSitPos; // adds click offset, if any
2371 //Set up raytrace to find top surface of prim
2372 Vector3 size = part.Scale;
2373 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2374 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2375 Vector3 down = new Vector3(0f, 0f, -1f);
2376//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2377 m_scene.PhysicsScene.RaycastWorld(
2378 start, // Vector3 position,
2379 down, // Vector3 direction,
2380 mag, // float length,
2381 SitAltitudeCallback); // retMethod
2382 } // end scripted/not
2167 } 2383 }
2168 else 2384 else // no Av
2169 { 2385 {
2170 return; 2386 return;
2171 } 2387 }
@@ -2177,11 +2393,39 @@ namespace OpenSim.Region.Framework.Scenes
2177 2393
2178 Animator.TrySetMovementAnimation(sitAnimation); 2394 Animator.TrySetMovementAnimation(sitAnimation);
2179 SendFullUpdateToAllClients(); 2395 SendFullUpdateToAllClients();
2180 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2181 // So we're also sending a terse update (which has avatar rotation)
2182 // [Update] We do now.
2183 //SendTerseUpdateToAllClients();
2184 } 2396 }
2397
2398 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2399 {
2400 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2401 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2402 if(hitYN)
2403 {
2404 // m_pos = Av offset from prim center to make look like on center
2405 // m_parentPosition = Actual center pos of prim
2406 // collisionPoint = spot on prim where we want to sit
2407 // collisionPoint.Z = global sit surface height
2408 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2409 Quaternion partIRot;
2410// if (part.LinkNum == 1)
2411/// { // Root prim of linkset
2412// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2413// }
2414// else
2415// { // single or child prim
2416 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2417// }
2418 if (m_initialSitTarget != null)
2419 {
2420 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2421 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2422 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2423 m_pos += offset;
2424 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2425 }
2426
2427 }
2428 } // End SitAltitudeCallback KF.
2185 2429
2186 /// <summary> 2430 /// <summary>
2187 /// Event handler for the 'Always run' setting on the client 2431 /// Event handler for the 'Always run' setting on the client
@@ -2211,7 +2455,7 @@ namespace OpenSim.Region.Framework.Scenes
2211 /// </summary> 2455 /// </summary>
2212 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2456 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2213 /// <param name="rotation">The direction in which this avatar should now face. 2457 /// <param name="rotation">The direction in which this avatar should now face.
2214 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2458 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2215 { 2459 {
2216 if (m_isChildAgent) 2460 if (m_isChildAgent)
2217 { 2461 {
@@ -2252,10 +2496,11 @@ namespace OpenSim.Region.Framework.Scenes
2252 Rotation = rotation; 2496 Rotation = rotation;
2253 Vector3 direc = vec * rotation; 2497 Vector3 direc = vec * rotation;
2254 direc.Normalize(); 2498 direc.Normalize();
2499 PhysicsActor actor = m_physicsActor;
2500 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2255 2501
2256 direc *= 0.03f * 128f * m_speedModifier; 2502 direc *= 0.03f * 128f * m_speedModifier;
2257 2503
2258 PhysicsActor actor = m_physicsActor;
2259 if (actor != null) 2504 if (actor != null)
2260 { 2505 {
2261 if (actor.Flying) 2506 if (actor.Flying)
@@ -2277,18 +2522,25 @@ namespace OpenSim.Region.Framework.Scenes
2277 { 2522 {
2278 if (direc.Z > 2.0f) 2523 if (direc.Z > 2.0f)
2279 { 2524 {
2280 direc.Z *= 3.0f; 2525 if(m_animator.m_animTickJump == -1)
2281 2526 {
2282 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2527 direc.Z *= 3.0f; // jump
2283 Animator.TrySetMovementAnimation("PREJUMP"); 2528 }
2284 Animator.TrySetMovementAnimation("JUMP"); 2529 else
2530 {
2531 direc.Z *= 0.1f; // prejump
2532 }
2533 /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2534 Animator.TrySetMovementAnimation("PREJUMP");
2535 Animator.TrySetMovementAnimation("JUMP");
2536 */
2285 } 2537 }
2286 } 2538 }
2287 } 2539 }
2288 2540
2289 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2541 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2290 m_forceToApply = direc; 2542 m_forceToApply = direc;
2291 2543 m_isNudging = Nudging;
2292 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2544 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2293 } 2545 }
2294 2546
@@ -2303,7 +2555,7 @@ namespace OpenSim.Region.Framework.Scenes
2303 const float POSITION_TOLERANCE = 0.05f; 2555 const float POSITION_TOLERANCE = 0.05f;
2304 //const int TIME_MS_TOLERANCE = 3000; 2556 //const int TIME_MS_TOLERANCE = 3000;
2305 2557
2306 SendPrimUpdates(); 2558
2307 2559
2308 if (m_newCoarseLocations) 2560 if (m_newCoarseLocations)
2309 { 2561 {
@@ -2339,6 +2591,9 @@ namespace OpenSim.Region.Framework.Scenes
2339 CheckForBorderCrossing(); 2591 CheckForBorderCrossing();
2340 CheckForSignificantMovement(); // sends update to the modules. 2592 CheckForSignificantMovement(); // sends update to the modules.
2341 } 2593 }
2594
2595 //Sending prim updates AFTER the avatar terse updates are sent
2596 SendPrimUpdates();
2342 } 2597 }
2343 2598
2344 #endregion 2599 #endregion
@@ -3149,6 +3404,7 @@ namespace OpenSim.Region.Framework.Scenes
3149 m_callbackURI = cAgent.CallbackURI; 3404 m_callbackURI = cAgent.CallbackURI;
3150 3405
3151 m_pos = cAgent.Position; 3406 m_pos = cAgent.Position;
3407
3152 m_velocity = cAgent.Velocity; 3408 m_velocity = cAgent.Velocity;
3153 m_CameraCenter = cAgent.Center; 3409 m_CameraCenter = cAgent.Center;
3154 //m_avHeight = cAgent.Size.Z; 3410 //m_avHeight = cAgent.Size.Z;
@@ -3237,14 +3493,25 @@ namespace OpenSim.Region.Framework.Scenes
3237 { 3493 {
3238 if (m_forceToApply.HasValue) 3494 if (m_forceToApply.HasValue)
3239 { 3495 {
3240 Vector3 force = m_forceToApply.Value;
3241 3496
3497 Vector3 force = m_forceToApply.Value;
3242 m_updateflag = true; 3498 m_updateflag = true;
3243// movementvector = force;
3244 Velocity = force; 3499 Velocity = force;
3245 3500
3246 m_forceToApply = null; 3501 m_forceToApply = null;
3247 } 3502 }
3503 else
3504 {
3505 if (m_isNudging)
3506 {
3507 Vector3 force = Vector3.Zero;
3508
3509 m_updateflag = true;
3510 Velocity = force;
3511 m_isNudging = false;
3512 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3513 }
3514 }
3248 } 3515 }
3249 3516
3250 public override void SetText(string text, Vector3 color, double alpha) 3517 public override void SetText(string text, Vector3 color, double alpha)
@@ -3295,18 +3562,29 @@ namespace OpenSim.Region.Framework.Scenes
3295 { 3562 {
3296 if (e == null) 3563 if (e == null)
3297 return; 3564 return;
3298 3565
3299 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3566 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3300 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3301 // as of this comment the interval is set in AddToPhysicalScene 3567 // as of this comment the interval is set in AddToPhysicalScene
3302 if (Animator!=null) 3568 if (Animator!=null)
3303 Animator.UpdateMovementAnimations(); 3569 {
3570 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3571 { // else its will lock out other animation changes, like ground sit.
3572 Animator.UpdateMovementAnimations();
3573 m_updateCount--;
3574 }
3575 }
3304 3576
3305 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3577 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3306 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3578 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3307 3579
3308 CollisionPlane = Vector4.UnitW; 3580 CollisionPlane = Vector4.UnitW;
3309 3581
3582 if (m_lastColCount != coldata.Count)
3583 {
3584 m_updateCount = UPDATE_COUNT;
3585 m_lastColCount = coldata.Count;
3586 }
3587
3310 if (coldata.Count != 0 && Animator != null) 3588 if (coldata.Count != 0 && Animator != null)
3311 { 3589 {
3312 switch (Animator.CurrentMovementAnimation) 3590 switch (Animator.CurrentMovementAnimation)
@@ -3510,7 +3788,10 @@ namespace OpenSim.Region.Framework.Scenes
3510 m_scene = scene; 3788 m_scene = scene;
3511 3789
3512 RegisterToEvents(); 3790 RegisterToEvents();
3513 3791 if (m_controllingClient != null)
3792 {
3793 m_controllingClient.ProcessPendingPackets();
3794 }
3514 /* 3795 /*
3515 AbsolutePosition = client.StartPos; 3796 AbsolutePosition = client.StartPos;
3516 3797
@@ -3741,6 +4022,32 @@ namespace OpenSim.Region.Framework.Scenes
3741 return; 4022 return;
3742 } 4023 }
3743 4024
4025 XmlDocument doc = new XmlDocument();
4026 string stateData = String.Empty;
4027
4028 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4029 if (attServ != null)
4030 {
4031 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4032 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4033 doc.LoadXml(stateData);
4034 }
4035
4036 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4037
4038 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4039 if (nodes.Count > 0)
4040 {
4041 foreach (XmlNode n in nodes)
4042 {
4043 XmlElement elem = (XmlElement)n;
4044 string itemID = elem.GetAttribute("ItemID");
4045 string xml = elem.InnerXml;
4046
4047 itemData[new UUID(itemID)] = xml;
4048 }
4049 }
4050
3744 List<int> attPoints = m_appearance.GetAttachedPoints(); 4051 List<int> attPoints = m_appearance.GetAttachedPoints();
3745 foreach (int p in attPoints) 4052 foreach (int p in attPoints)
3746 { 4053 {
@@ -3760,9 +4067,26 @@ namespace OpenSim.Region.Framework.Scenes
3760 4067
3761 try 4068 try
3762 { 4069 {
3763 // Rez from inventory 4070 string xmlData;
3764 UUID asset 4071 XmlDocument d = new XmlDocument();
3765 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4072 UUID asset;
4073 if (itemData.TryGetValue(itemID, out xmlData))
4074 {
4075 d.LoadXml(xmlData);
4076 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4077
4078 // Rez from inventory
4079 asset
4080 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4081
4082 }
4083 else
4084 {
4085 // Rez from inventory (with a null doc to let
4086 // CHANGED_OWNER happen)
4087 asset
4088 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4089 }
3766 4090
3767 m_log.InfoFormat( 4091 m_log.InfoFormat(
3768 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", 4092 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
@@ -3799,5 +4123,16 @@ namespace OpenSim.Region.Framework.Scenes
3799 m_reprioritization_called = false; 4123 m_reprioritization_called = false;
3800 } 4124 }
3801 } 4125 }
4126
4127 private Vector3 Quat2Euler(Quaternion rot){
4128 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4129 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4130 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4131 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4132 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4133 return(new Vector3(x,y,z));
4134 }
4135
4136
3802 } 4137 }
3803} 4138}