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