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.cs677
1 files changed, 505 insertions, 172 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index c1e835e..b6f67f7 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
@@ -181,7 +186,8 @@ namespace OpenSim.Region.Framework.Scenes
181 protected RegionInfo m_regionInfo; 186 protected RegionInfo m_regionInfo;
182 protected ulong crossingFromRegion; 187 protected ulong crossingFromRegion;
183 188
184 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 189 private readonly Vector3[] Dir_Vectors = new Vector3[11];
190 private bool m_isNudging = false;
185 191
186 // Position of agent's camera in world (region cordinates) 192 // Position of agent's camera in world (region cordinates)
187 protected Vector3 m_CameraCenter; 193 protected Vector3 m_CameraCenter;
@@ -206,6 +212,7 @@ namespace OpenSim.Region.Framework.Scenes
206 private bool m_autopilotMoving; 212 private bool m_autopilotMoving;
207 private Vector3 m_autoPilotTarget; 213 private Vector3 m_autoPilotTarget;
208 private bool m_sitAtAutoTarget; 214 private bool m_sitAtAutoTarget;
215 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
209 216
210 private string m_nextSitAnimation = String.Empty; 217 private string m_nextSitAnimation = String.Empty;
211 218
@@ -216,6 +223,9 @@ namespace OpenSim.Region.Framework.Scenes
216 private bool m_followCamAuto; 223 private bool m_followCamAuto;
217 224
218 private int m_movementUpdateCount; 225 private int m_movementUpdateCount;
226 private int m_lastColCount = -1; //KF: Look for Collision chnages
227 private int m_updateCount = 0; //KF: Update Anims for a while
228 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
219 private const int NumMovementsBetweenRayCast = 5; 229 private const int NumMovementsBetweenRayCast = 5;
220 230
221 private bool CameraConstraintActive; 231 private bool CameraConstraintActive;
@@ -243,7 +253,9 @@ namespace OpenSim.Region.Framework.Scenes
243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 253 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 254 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 255 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
246 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 256 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
257 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
258 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
247 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 259 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
248 } 260 }
249 261
@@ -450,7 +462,8 @@ namespace OpenSim.Region.Framework.Scenes
450 get 462 get
451 { 463 {
452 PhysicsActor actor = m_physicsActor; 464 PhysicsActor actor = m_physicsActor;
453 if (actor != null) 465// if (actor != null)
466 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
454 m_pos = actor.Position; 467 m_pos = actor.Position;
455 468
456 return m_parentPosition + m_pos; 469 return m_parentPosition + m_pos;
@@ -471,7 +484,8 @@ namespace OpenSim.Region.Framework.Scenes
471 } 484 }
472 } 485 }
473 486
474 m_pos = value; 487 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
488 m_pos = value;
475 m_parentPosition = Vector3.Zero; 489 m_parentPosition = Vector3.Zero;
476 } 490 }
477 } 491 }
@@ -669,7 +683,7 @@ namespace OpenSim.Region.Framework.Scenes
669 CreateSceneViewer(); 683 CreateSceneViewer();
670 m_animator = new ScenePresenceAnimator(this); 684 m_animator = new ScenePresenceAnimator(this);
671 } 685 }
672 686
673 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 687 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
674 { 688 {
675 m_rootRegionHandle = reginfo.RegionHandle; 689 m_rootRegionHandle = reginfo.RegionHandle;
@@ -701,16 +715,16 @@ namespace OpenSim.Region.Framework.Scenes
701 m_reprioritization_timer.AutoReset = false; 715 m_reprioritization_timer.AutoReset = false;
702 716
703 AdjustKnownSeeds(); 717 AdjustKnownSeeds();
704
705 // TODO: I think, this won't send anything, as we are still a child here...
706 Animator.TrySetMovementAnimation("STAND"); 718 Animator.TrySetMovementAnimation("STAND");
707
708 // we created a new ScenePresence (a new child agent) in a fresh region. 719 // we created a new ScenePresence (a new child agent) in a fresh region.
709 // Request info about all the (root) agents in this region 720 // Request info about all the (root) agents in this region
710 // Note: This won't send data *to* other clients in that region (children don't send) 721 // Note: This won't send data *to* other clients in that region (children don't send)
711 SendInitialFullUpdateToAllClients(); 722 SendInitialFullUpdateToAllClients();
712
713 RegisterToEvents(); 723 RegisterToEvents();
724 if (m_controllingClient != null)
725 {
726 m_controllingClient.ProcessPendingPackets();
727 }
714 SetDirectionVectors(); 728 SetDirectionVectors();
715 } 729 }
716 730
@@ -760,25 +774,47 @@ namespace OpenSim.Region.Framework.Scenes
760 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 774 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
761 Dir_Vectors[4] = Vector3.UnitZ; //UP 775 Dir_Vectors[4] = Vector3.UnitZ; //UP
762 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 776 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
763 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 777 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
764 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 778 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
765 Dir_Vectors[7] = -Vector3.UnitX; //BACK 779 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
780 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
781 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
766 } 782 }
767 783
768 private Vector3[] GetWalkDirectionVectors() 784 private Vector3[] GetWalkDirectionVectors()
769 { 785 {
770 Vector3[] vector = new Vector3[9]; 786 Vector3[] vector = new Vector3[11];
771 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 787 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
772 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 788 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
773 vector[2] = Vector3.UnitY; //LEFT 789 vector[2] = Vector3.UnitY; //LEFT
774 vector[3] = -Vector3.UnitY; //RIGHT 790 vector[3] = -Vector3.UnitY; //RIGHT
775 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 791 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
776 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 792 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
777 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 793 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
778 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 794 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
779 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 795 vector[8] = Vector3.UnitY; //LEFT_NUDGE
796 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
797 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
780 return vector; 798 return vector;
781 } 799 }
800
801 private bool[] GetDirectionIsNudge()
802 {
803 bool[] isNudge = new bool[11];
804 isNudge[0] = false; //FORWARD
805 isNudge[1] = false; //BACK
806 isNudge[2] = false; //LEFT
807 isNudge[3] = false; //RIGHT
808 isNudge[4] = false; //UP
809 isNudge[5] = false; //DOWN
810 isNudge[6] = true; //FORWARD_NUDGE
811 isNudge[7] = true; //BACK_NUDGE
812 isNudge[8] = true; //LEFT_NUDGE
813 isNudge[9] = true; //RIGHT_NUDGE
814 isNudge[10] = true; //DOWN_Nudge
815 return isNudge;
816 }
817
782 818
783 #endregion 819 #endregion
784 820
@@ -821,7 +857,6 @@ namespace OpenSim.Region.Framework.Scenes
821 m_grouptitle = gm.GetGroupTitle(m_uuid); 857 m_grouptitle = gm.GetGroupTitle(m_uuid);
822 858
823 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; 859 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle;
824
825 m_scene.SetRootAgentScene(m_uuid); 860 m_scene.SetRootAgentScene(m_uuid);
826 861
827 // Moved this from SendInitialData to ensure that m_appearance is initialized 862 // Moved this from SendInitialData to ensure that m_appearance is initialized
@@ -840,6 +875,52 @@ namespace OpenSim.Region.Framework.Scenes
840 pos.Y = crossedBorder.BorderLine.Z - 1; 875 pos.Y = crossedBorder.BorderLine.Z - 1;
841 } 876 }
842 877
878 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
879 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
880 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
881 if (KnownChildRegionHandles.Count == 0)
882 {
883 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
884 if (land != null)
885 {
886 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
887 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)
888 {
889 pos = land.LandData.UserLocation;
890 }
891 }
892 }
893
894 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
895 {
896 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
897
898 if (pos.X < 0)
899 {
900 emergencyPos.X = (int)Constants.RegionSize + pos.X;
901 if (!(pos.Y < 0))
902 emergencyPos.Y = pos.Y;
903 if (!(pos.Z < 0))
904 emergencyPos.Z = pos.Z;
905 }
906 if (pos.Y < 0)
907 {
908 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
909 if (!(pos.X < 0))
910 emergencyPos.X = pos.X;
911 if (!(pos.Z < 0))
912 emergencyPos.Z = pos.Z;
913 }
914 if (pos.Z < 0)
915 {
916 emergencyPos.Z = 128;
917 if (!(pos.Y < 0))
918 emergencyPos.Y = pos.Y;
919 if (!(pos.X < 0))
920 emergencyPos.X = pos.X;
921 }
922 }
923
843 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 924 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
844 { 925 {
845 m_log.WarnFormat( 926 m_log.WarnFormat(
@@ -972,9 +1053,10 @@ namespace OpenSim.Region.Framework.Scenes
972 public void Teleport(Vector3 pos) 1053 public void Teleport(Vector3 pos)
973 { 1054 {
974 bool isFlying = false; 1055 bool isFlying = false;
1056
975 if (m_physicsActor != null) 1057 if (m_physicsActor != null)
976 isFlying = m_physicsActor.Flying; 1058 isFlying = m_physicsActor.Flying;
977 1059
978 RemoveFromPhysicalScene(); 1060 RemoveFromPhysicalScene();
979 Velocity = Vector3.Zero; 1061 Velocity = Vector3.Zero;
980 AbsolutePosition = pos; 1062 AbsolutePosition = pos;
@@ -986,6 +1068,7 @@ namespace OpenSim.Region.Framework.Scenes
986 } 1068 }
987 1069
988 SendTerseUpdateToAllClients(); 1070 SendTerseUpdateToAllClients();
1071
989 } 1072 }
990 1073
991 public void TeleportWithMomentum(Vector3 pos) 1074 public void TeleportWithMomentum(Vector3 pos)
@@ -1099,7 +1182,6 @@ namespace OpenSim.Region.Framework.Scenes
1099 pos.Z = ground + 1.5f; 1182 pos.Z = ground + 1.5f;
1100 AbsolutePosition = pos; 1183 AbsolutePosition = pos;
1101 } 1184 }
1102
1103 m_isChildAgent = false; 1185 m_isChildAgent = false;
1104 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1186 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1105 MakeRootAgent(AbsolutePosition, m_flying); 1187 MakeRootAgent(AbsolutePosition, m_flying);
@@ -1198,6 +1280,7 @@ namespace OpenSim.Region.Framework.Scenes
1198 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1280 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1199 1281
1200 m_pos = m_LastFinitePos; 1282 m_pos = m_LastFinitePos;
1283
1201 if (!m_pos.IsFinite()) 1284 if (!m_pos.IsFinite())
1202 { 1285 {
1203 m_pos.X = 127f; 1286 m_pos.X = 127f;
@@ -1264,7 +1347,6 @@ namespace OpenSim.Region.Framework.Scenes
1264 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1347 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1265 } 1348 }
1266 } 1349 }
1267
1268 lock (scriptedcontrols) 1350 lock (scriptedcontrols)
1269 { 1351 {
1270 if (scriptedcontrols.Count > 0) 1352 if (scriptedcontrols.Count > 0)
@@ -1279,6 +1361,9 @@ namespace OpenSim.Region.Framework.Scenes
1279 1361
1280 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1362 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1281 { 1363 {
1364 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1365 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1366
1282 // TODO: This doesn't prevent the user from walking yet. 1367 // TODO: This doesn't prevent the user from walking yet.
1283 // Setting parent ID would fix this, if we knew what value 1368 // Setting parent ID would fix this, if we knew what value
1284 // to use. Or we could add a m_isSitting variable. 1369 // to use. Or we could add a m_isSitting variable.
@@ -1333,6 +1418,11 @@ namespace OpenSim.Region.Framework.Scenes
1333 update_rotation = true; 1418 update_rotation = true;
1334 } 1419 }
1335 1420
1421 //guilty until proven innocent..
1422 bool Nudging = true;
1423 //Basically, if there is at least one non-nudge control then we don't need
1424 //to worry about stopping the avatar
1425
1336 if (m_parentID == 0) 1426 if (m_parentID == 0)
1337 { 1427 {
1338 bool bAllowUpdateMoveToPosition = false; 1428 bool bAllowUpdateMoveToPosition = false;
@@ -1347,9 +1437,12 @@ namespace OpenSim.Region.Framework.Scenes
1347 else 1437 else
1348 dirVectors = Dir_Vectors; 1438 dirVectors = Dir_Vectors;
1349 1439
1350 // The fact that m_movementflag is a byte needs to be fixed 1440 bool[] isNudge = GetDirectionIsNudge();
1351 // it really should be a uint 1441
1352 uint nudgehack = 250; 1442
1443
1444
1445
1353 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1446 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1354 { 1447 {
1355 if (((uint)flags & (uint)DCF) != 0) 1448 if (((uint)flags & (uint)DCF) != 0)
@@ -1359,40 +1452,28 @@ namespace OpenSim.Region.Framework.Scenes
1359 try 1452 try
1360 { 1453 {
1361 agent_control_v3 += dirVectors[i]; 1454 agent_control_v3 += dirVectors[i];
1362 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1455 if (isNudge[i] == false)
1456 {
1457 Nudging = false;
1458 }
1363 } 1459 }
1364 catch (IndexOutOfRangeException) 1460 catch (IndexOutOfRangeException)
1365 { 1461 {
1366 // Why did I get this? 1462 // Why did I get this?
1367 } 1463 }
1368 1464
1369 if ((m_movementflag & (byte)(uint)DCF) == 0) 1465 if ((m_movementflag & (uint)DCF) == 0)
1370 { 1466 {
1371 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1372 {
1373 m_movementflag |= (byte)nudgehack;
1374 }
1375 m_movementflag += (byte)(uint)DCF; 1467 m_movementflag += (byte)(uint)DCF;
1376 update_movementflag = true; 1468 update_movementflag = true;
1377 } 1469 }
1378 } 1470 }
1379 else 1471 else
1380 { 1472 {
1381 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1473 if ((m_movementflag & (uint)DCF) != 0)
1382 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1383 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1384 ) // This or is for Nudge forward
1385 { 1474 {
1386 m_movementflag -= ((byte)(uint)DCF); 1475 m_movementflag -= (byte)(uint)DCF;
1387
1388 update_movementflag = true; 1476 update_movementflag = true;
1389 /*
1390 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1391 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1392 {
1393 m_log.Debug("Removed Hack flag");
1394 }
1395 */
1396 } 1477 }
1397 else 1478 else
1398 { 1479 {
@@ -1401,7 +1482,6 @@ namespace OpenSim.Region.Framework.Scenes
1401 } 1482 }
1402 i++; 1483 i++;
1403 } 1484 }
1404
1405 //Paupaw:Do Proper PID for Autopilot here 1485 //Paupaw:Do Proper PID for Autopilot here
1406 if (bResetMoveToPosition) 1486 if (bResetMoveToPosition)
1407 { 1487 {
@@ -1436,6 +1516,9 @@ namespace OpenSim.Region.Framework.Scenes
1436 // Ignore z component of vector 1516 // Ignore z component of vector
1437 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1517 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1438 LocalVectorToTarget2D.Normalize(); 1518 LocalVectorToTarget2D.Normalize();
1519
1520 //We're not nudging
1521 Nudging = false;
1439 agent_control_v3 += LocalVectorToTarget2D; 1522 agent_control_v3 += LocalVectorToTarget2D;
1440 1523
1441 // update avatar movement flags. the avatar coordinate system is as follows: 1524 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1524,13 +1607,13 @@ namespace OpenSim.Region.Framework.Scenes
1524 // m_log.DebugFormat( 1607 // m_log.DebugFormat(
1525 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1608 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1526 1609
1527 AddNewMovement(agent_control_v3, q); 1610 AddNewMovement(agent_control_v3, q, Nudging);
1528 1611
1529 1612
1530 } 1613 }
1531 } 1614 }
1532 1615
1533 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1616 if (update_movementflag && !SitGround)
1534 Animator.UpdateMovementAnimations(); 1617 Animator.UpdateMovementAnimations();
1535 1618
1536 m_scene.EventManager.TriggerOnClientMovement(this); 1619 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1545,7 +1628,6 @@ namespace OpenSim.Region.Framework.Scenes
1545 m_sitAtAutoTarget = false; 1628 m_sitAtAutoTarget = false;
1546 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1629 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1547 //proxy.PCode = (byte)PCode.ParticleSystem; 1630 //proxy.PCode = (byte)PCode.ParticleSystem;
1548
1549 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1631 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1550 proxyObjectGroup.AttachToScene(m_scene); 1632 proxyObjectGroup.AttachToScene(m_scene);
1551 1633
@@ -1587,7 +1669,7 @@ namespace OpenSim.Region.Framework.Scenes
1587 } 1669 }
1588 m_moveToPositionInProgress = true; 1670 m_moveToPositionInProgress = true;
1589 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1671 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1590 } 1672 }
1591 catch (Exception ex) 1673 catch (Exception ex)
1592 { 1674 {
1593 //Why did I get this error? 1675 //Why did I get this error?
@@ -1609,7 +1691,7 @@ namespace OpenSim.Region.Framework.Scenes
1609 Velocity = Vector3.Zero; 1691 Velocity = Vector3.Zero;
1610 SendFullUpdateToAllClients(); 1692 SendFullUpdateToAllClients();
1611 1693
1612 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1694 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1613 } 1695 }
1614 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1696 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1615 m_requestedSitTargetUUID = UUID.Zero; 1697 m_requestedSitTargetUUID = UUID.Zero;
@@ -1646,50 +1728,82 @@ namespace OpenSim.Region.Framework.Scenes
1646 1728
1647 if (m_parentID != 0) 1729 if (m_parentID != 0)
1648 { 1730 {
1649 m_log.Debug("StandupCode Executed");
1650 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1731 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1651 if (part != null) 1732 if (part != null)
1652 { 1733 {
1734 part.TaskInventory.LockItemsForRead(true);
1653 TaskInventoryDictionary taskIDict = part.TaskInventory; 1735 TaskInventoryDictionary taskIDict = part.TaskInventory;
1654 if (taskIDict != null) 1736 if (taskIDict != null)
1655 { 1737 {
1656 lock (taskIDict) 1738 foreach (UUID taskID in taskIDict.Keys)
1657 { 1739 {
1658 foreach (UUID taskID in taskIDict.Keys) 1740 UnRegisterControlEventsToScript(LocalId, taskID);
1659 { 1741 taskIDict[taskID].PermsMask &= ~(
1660 UnRegisterControlEventsToScript(LocalId, taskID); 1742 2048 | //PERMISSION_CONTROL_CAMERA
1661 taskIDict[taskID].PermsMask &= ~( 1743 4); // PERMISSION_TAKE_CONTROLS
1662 2048 | //PERMISSION_CONTROL_CAMERA
1663 4); // PERMISSION_TAKE_CONTROLS
1664 }
1665 } 1744 }
1666
1667 } 1745 }
1746 part.TaskInventory.LockItemsForRead(false);
1668 // Reset sit target. 1747 // Reset sit target.
1669 if (part.GetAvatarOnSitTarget() == UUID) 1748 if (part.GetAvatarOnSitTarget() == UUID)
1670 part.SetAvatarOnSitTarget(UUID.Zero); 1749 part.SetAvatarOnSitTarget(UUID.Zero);
1671
1672 m_parentPosition = part.GetWorldPosition(); 1750 m_parentPosition = part.GetWorldPosition();
1673 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1751 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1674 } 1752 }
1753 // part.GetWorldRotation() is the rotation of the object being sat on
1754 // Rotation is the sittiing Av's rotation
1675 1755
1676 if (m_physicsActor == null) 1756 Quaternion partRot;
1757// if (part.LinkNum == 1)
1758// { // Root prim of linkset
1759// partRot = part.ParentGroup.RootPart.RotationOffset;
1760// }
1761// else
1762// { // single or child prim
1763
1764// }
1765 if (part == null) //CW: Part may be gone. llDie() for example.
1677 { 1766 {
1678 AddToPhysicalScene(false); 1767 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1768 }
1769 else
1770 {
1771 partRot = part.GetWorldRotation();
1679 } 1772 }
1680 1773
1681 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1774 Quaternion partIRot = Quaternion.Inverse(partRot);
1682 m_parentPosition = Vector3.Zero;
1683 1775
1684 m_parentID = 0; 1776 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1777 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1778
1779
1780 if (m_physicsActor == null)
1781 {
1782 AddToPhysicalScene(false);
1783 }
1784 //CW: If the part isn't null then we can set the current position
1785 if (part != null)
1786 {
1787 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1788 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1789 part.IsOccupied = false;
1790 }
1791 else
1792 {
1793 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1794 AbsolutePosition = m_lastWorldPosition;
1795 }
1796
1797 m_parentPosition = Vector3.Zero;
1798 m_parentID = 0;
1685 SendFullUpdateToAllClients(); 1799 SendFullUpdateToAllClients();
1686 m_requestedSitTargetID = 0; 1800 m_requestedSitTargetID = 0;
1801
1687 if ((m_physicsActor != null) && (m_avHeight > 0)) 1802 if ((m_physicsActor != null) && (m_avHeight > 0))
1688 { 1803 {
1689 SetHeight(m_avHeight); 1804 SetHeight(m_avHeight);
1690 } 1805 }
1691 } 1806 }
1692
1693 Animator.TrySetMovementAnimation("STAND"); 1807 Animator.TrySetMovementAnimation("STAND");
1694 } 1808 }
1695 1809
@@ -1720,13 +1834,9 @@ namespace OpenSim.Region.Framework.Scenes
1720 Vector3 avSitOffSet = part.SitTargetPosition; 1834 Vector3 avSitOffSet = part.SitTargetPosition;
1721 Quaternion avSitOrientation = part.SitTargetOrientation; 1835 Quaternion avSitOrientation = part.SitTargetOrientation;
1722 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1836 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1723 1837 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1724 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1838 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1725 bool SitTargetisSet = 1839 if (SitTargetisSet && !SitTargetOccupied)
1726 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1727 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1728
1729 if (SitTargetisSet && SitTargetUnOccupied)
1730 { 1840 {
1731 //switch the target to this prim 1841 //switch the target to this prim
1732 return part; 1842 return part;
@@ -1740,84 +1850,153 @@ namespace OpenSim.Region.Framework.Scenes
1740 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1850 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1741 { 1851 {
1742 bool autopilot = true; 1852 bool autopilot = true;
1853 Vector3 autopilotTarget = new Vector3();
1854 Quaternion sitOrientation = Quaternion.Identity;
1743 Vector3 pos = new Vector3(); 1855 Vector3 pos = new Vector3();
1744 Quaternion sitOrientation = pSitOrientation;
1745 Vector3 cameraEyeOffset = Vector3.Zero; 1856 Vector3 cameraEyeOffset = Vector3.Zero;
1746 Vector3 cameraAtOffset = Vector3.Zero; 1857 Vector3 cameraAtOffset = Vector3.Zero;
1747 bool forceMouselook = false; 1858 bool forceMouselook = false;
1748 1859
1749 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1860 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1750 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1861 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1751 if (part != null) 1862 if (part == null) return;
1752 { 1863
1753 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1864 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1754 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1865 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1755 1866
1756 // Is a sit target available? 1867 // part is the prim to sit on
1757 Vector3 avSitOffSet = part.SitTargetPosition; 1868 // offset is the world-ref vector distance from that prim center to the click-spot
1758 Quaternion avSitOrientation = part.SitTargetOrientation; 1869 // UUID is the UUID of the Avatar doing the clicking
1759 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1870
1760 1871 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1761 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1872
1762 bool SitTargetisSet = 1873 // Is a sit target available?
1763 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1874 Vector3 avSitOffSet = part.SitTargetPosition;
1764 ( 1875 Quaternion avSitOrientation = part.SitTargetOrientation;
1765 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1876
1766 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1877 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1767 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1878 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1768 ) 1879 Quaternion partRot;
1769 )); 1880// if (part.LinkNum == 1)
1770 1881// { // Root prim of linkset
1771 if (SitTargetisSet && SitTargetUnOccupied) 1882// partRot = part.ParentGroup.RootPart.RotationOffset;
1772 { 1883// }
1773 part.SetAvatarOnSitTarget(UUID); 1884// else
1774 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1885// { // single or child prim
1775 sitOrientation = avSitOrientation; 1886 partRot = part.GetWorldRotation();
1776 autopilot = false; 1887// }
1777 } 1888 Quaternion partIRot = Quaternion.Inverse(partRot);
1778 1889//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1779 pos = part.AbsolutePosition + offset; 1890 // Sit analysis rewritten by KF 091125
1780 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1891 if (SitTargetisSet) // scipted sit
1781 //{ 1892 {
1782 // offset = pos; 1893 if (!part.IsOccupied)
1783 //autopilot = false; 1894 {
1784 //} 1895//Console.WriteLine("Scripted, unoccupied");
1785 if (m_physicsActor != null) 1896 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1786 { 1897 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1787 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1898 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1788 // We can remove the physicsActor until they stand up. 1899 autopilot = false; // Jump direct to scripted llSitPos()
1789 m_sitAvatarHeight = m_physicsActor.Size.Z; 1900 }
1790 1901 else
1791 if (autopilot) 1902 {
1792 { 1903//Console.WriteLine("Scripted, occupied");
1793 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1904 return;
1794 { 1905 }
1795 autopilot = false; 1906 }
1907 else // Not Scripted
1908 {
1909 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1910 {
1911 // large prim & offset, ignore if other Avs sitting
1912// offset.Z -= 0.05f;
1913 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1914 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1915
1916//Console.WriteLine(" offset ={0}", offset);
1917//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1918//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1919
1920 }
1921 else // small offset
1922 {
1923//Console.WriteLine("Small offset");
1924 if (!part.IsOccupied)
1925 {
1926 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1927 autopilotTarget = part.AbsolutePosition;
1928//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1929 }
1930 else return; // occupied small
1931 } // end large/small
1932 } // end Scripted/not
1933 cameraAtOffset = part.GetCameraAtOffset();
1934 cameraEyeOffset = part.GetCameraEyeOffset();
1935 forceMouselook = part.GetForceMouselook();
1936 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1937 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1796 1938
1797 RemoveFromPhysicalScene(); 1939 if (m_physicsActor != null)
1798 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1940 {
1799 } 1941 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1800 } 1942 // We can remove the physicsActor until they stand up.
1801 else 1943 m_sitAvatarHeight = m_physicsActor.Size.Z;
1944 if (autopilot)
1945 { // its not a scripted sit
1946// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1947 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1802 { 1948 {
1949 autopilot = false; // close enough
1950 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1951 Not using the part's position because returning the AV to the last known standing
1952 position is likely to be more friendly, isn't it? */
1803 RemoveFromPhysicalScene(); 1953 RemoveFromPhysicalScene();
1804 } 1954 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1955 } // else the autopilot will get us close
1956 }
1957 else
1958 { // its a scripted sit
1959 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1960 I *am* using the part's position this time because we have no real idea how far away
1961 the avatar is from the sit target. */
1962 RemoveFromPhysicalScene();
1805 } 1963 }
1806
1807 cameraAtOffset = part.GetCameraAtOffset();
1808 cameraEyeOffset = part.GetCameraEyeOffset();
1809 forceMouselook = part.GetForceMouselook();
1810 } 1964 }
1811 1965 else return; // physactor is null!
1812 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1966
1813 m_requestedSitTargetUUID = targetID; 1967 Vector3 offsetr; // = offset * partIRot;
1968 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1969 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1970 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1971 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1972 offsetr = offset * partIRot;
1973//
1974 // else
1975 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1976 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1977 // (offset * partRot);
1978 // }
1979
1980//Console.WriteLine(" ");
1981//Console.WriteLine("link number ={0}", part.LinkNum);
1982//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1983//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1984//Console.WriteLine("Click offst ={0}", offset);
1985//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1986//Console.WriteLine("offsetr ={0}", offsetr);
1987//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1988//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1989
1990 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1991 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1814 // This calls HandleAgentSit twice, once from here, and the client calls 1992 // This calls HandleAgentSit twice, once from here, and the client calls
1815 // HandleAgentSit itself after it gets to the location 1993 // HandleAgentSit itself after it gets to the location
1816 // It doesn't get to the location until we've moved them there though 1994 // It doesn't get to the location until we've moved them there though
1817 // which happens in HandleAgentSit :P 1995 // which happens in HandleAgentSit :P
1818 m_autopilotMoving = autopilot; 1996 m_autopilotMoving = autopilot;
1819 m_autoPilotTarget = pos; 1997 m_autoPilotTarget = autopilotTarget;
1820 m_sitAtAutoTarget = autopilot; 1998 m_sitAtAutoTarget = autopilot;
1999 m_initialSitTarget = autopilotTarget;
1821 if (!autopilot) 2000 if (!autopilot)
1822 HandleAgentSit(remoteClient, UUID); 2001 HandleAgentSit(remoteClient, UUID);
1823 } 2002 }
@@ -2112,31 +2291,66 @@ namespace OpenSim.Region.Framework.Scenes
2112 { 2291 {
2113 if (part != null) 2292 if (part != null)
2114 { 2293 {
2294//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2115 if (part.GetAvatarOnSitTarget() == UUID) 2295 if (part.GetAvatarOnSitTarget() == UUID)
2116 { 2296 {
2297//Console.WriteLine("Scripted Sit");
2298 // Scripted sit
2117 Vector3 sitTargetPos = part.SitTargetPosition; 2299 Vector3 sitTargetPos = part.SitTargetPosition;
2118 Quaternion sitTargetOrient = part.SitTargetOrientation; 2300 Quaternion sitTargetOrient = part.SitTargetOrientation;
2119
2120 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2121 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2122
2123 //Quaternion result = (sitTargetOrient * vq) * nq;
2124
2125 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2301 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2126 m_pos += SIT_TARGET_ADJUSTMENT; 2302 m_pos += SIT_TARGET_ADJUSTMENT;
2127 m_bodyRot = sitTargetOrient; 2303 m_bodyRot = sitTargetOrient;
2128 //Rotation = sitTargetOrient;
2129 m_parentPosition = part.AbsolutePosition; 2304 m_parentPosition = part.AbsolutePosition;
2130 2305 part.IsOccupied = true;
2131 //SendTerseUpdateToAllClients(); 2306Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2132 } 2307 }
2133 else 2308 else
2134 { 2309 {
2135 m_pos -= part.AbsolutePosition; 2310 // if m_avUnscriptedSitPos is zero then Av sits above center
2311 // Else Av sits at m_avUnscriptedSitPos
2312
2313 // Non-scripted sit by Kitto Flora 21Nov09
2314 // Calculate angle of line from prim to Av
2315 Quaternion partIRot;
2316// if (part.LinkNum == 1)
2317// { // Root prim of linkset
2318// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2319// }
2320// else
2321// { // single or child prim
2322 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2323// }
2324 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2325 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2326 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2327 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2328 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2329 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2330 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2331 // Av sits at world euler <0,0, z>, translated by part rotation
2332 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2333
2136 m_parentPosition = part.AbsolutePosition; 2334 m_parentPosition = part.AbsolutePosition;
2137 } 2335 part.IsOccupied = true;
2138 } 2336 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2139 else 2337 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2338 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2339 m_avUnscriptedSitPos; // adds click offset, if any
2340 //Set up raytrace to find top surface of prim
2341 Vector3 size = part.Scale;
2342 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2343 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2344 Vector3 down = new Vector3(0f, 0f, -1f);
2345//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2346 m_scene.PhysicsScene.RaycastWorld(
2347 start, // Vector3 position,
2348 down, // Vector3 direction,
2349 mag, // float length,
2350 SitAltitudeCallback); // retMethod
2351 } // end scripted/not
2352 }
2353 else // no Av
2140 { 2354 {
2141 return; 2355 return;
2142 } 2356 }
@@ -2148,11 +2362,39 @@ namespace OpenSim.Region.Framework.Scenes
2148 2362
2149 Animator.TrySetMovementAnimation(sitAnimation); 2363 Animator.TrySetMovementAnimation(sitAnimation);
2150 SendFullUpdateToAllClients(); 2364 SendFullUpdateToAllClients();
2151 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2152 // So we're also sending a terse update (which has avatar rotation)
2153 // [Update] We do now.
2154 //SendTerseUpdateToAllClients();
2155 } 2365 }
2366
2367 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2368 {
2369 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2370 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2371 if(hitYN)
2372 {
2373 // m_pos = Av offset from prim center to make look like on center
2374 // m_parentPosition = Actual center pos of prim
2375 // collisionPoint = spot on prim where we want to sit
2376 // collisionPoint.Z = global sit surface height
2377 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2378 Quaternion partIRot;
2379// if (part.LinkNum == 1)
2380/// { // Root prim of linkset
2381// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2382// }
2383// else
2384// { // single or child prim
2385 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2386// }
2387 if (m_initialSitTarget != null)
2388 {
2389 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2390 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2391 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2392 m_pos += offset;
2393 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2394 }
2395
2396 }
2397 } // End SitAltitudeCallback KF.
2156 2398
2157 /// <summary> 2399 /// <summary>
2158 /// Event handler for the 'Always run' setting on the client 2400 /// Event handler for the 'Always run' setting on the client
@@ -2182,7 +2424,7 @@ namespace OpenSim.Region.Framework.Scenes
2182 /// </summary> 2424 /// </summary>
2183 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2425 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2184 /// <param name="rotation">The direction in which this avatar should now face. 2426 /// <param name="rotation">The direction in which this avatar should now face.
2185 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2427 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2186 { 2428 {
2187 if (m_isChildAgent) 2429 if (m_isChildAgent)
2188 { 2430 {
@@ -2223,10 +2465,11 @@ namespace OpenSim.Region.Framework.Scenes
2223 Rotation = rotation; 2465 Rotation = rotation;
2224 Vector3 direc = vec * rotation; 2466 Vector3 direc = vec * rotation;
2225 direc.Normalize(); 2467 direc.Normalize();
2468 PhysicsActor actor = m_physicsActor;
2469 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2226 2470
2227 direc *= 0.03f * 128f * m_speedModifier; 2471 direc *= 0.03f * 128f * m_speedModifier;
2228 2472
2229 PhysicsActor actor = m_physicsActor;
2230 if (actor != null) 2473 if (actor != null)
2231 { 2474 {
2232 if (actor.Flying) 2475 if (actor.Flying)
@@ -2248,18 +2491,25 @@ namespace OpenSim.Region.Framework.Scenes
2248 { 2491 {
2249 if (direc.Z > 2.0f) 2492 if (direc.Z > 2.0f)
2250 { 2493 {
2251 direc.Z *= 3.0f; 2494 if(m_animator.m_animTickJump == -1)
2252 2495 {
2253 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2496 direc.Z *= 3.0f; // jump
2254 Animator.TrySetMovementAnimation("PREJUMP"); 2497 }
2255 Animator.TrySetMovementAnimation("JUMP"); 2498 else
2499 {
2500 direc.Z *= 0.1f; // prejump
2501 }
2502 /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2503 Animator.TrySetMovementAnimation("PREJUMP");
2504 Animator.TrySetMovementAnimation("JUMP");
2505 */
2256 } 2506 }
2257 } 2507 }
2258 } 2508 }
2259 2509
2260 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2510 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2261 m_forceToApply = direc; 2511 m_forceToApply = direc;
2262 2512 m_isNudging = Nudging;
2263 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2513 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2264 } 2514 }
2265 2515
@@ -2274,7 +2524,7 @@ namespace OpenSim.Region.Framework.Scenes
2274 const float POSITION_TOLERANCE = 0.05f; 2524 const float POSITION_TOLERANCE = 0.05f;
2275 //const int TIME_MS_TOLERANCE = 3000; 2525 //const int TIME_MS_TOLERANCE = 3000;
2276 2526
2277 SendPrimUpdates(); 2527
2278 2528
2279 if (m_isChildAgent == false) 2529 if (m_isChildAgent == false)
2280 { 2530 {
@@ -2304,6 +2554,9 @@ namespace OpenSim.Region.Framework.Scenes
2304 CheckForBorderCrossing(); 2554 CheckForBorderCrossing();
2305 CheckForSignificantMovement(); // sends update to the modules. 2555 CheckForSignificantMovement(); // sends update to the modules.
2306 } 2556 }
2557
2558 //Sending prim updates AFTER the avatar terse updates are sent
2559 SendPrimUpdates();
2307 } 2560 }
2308 2561
2309 #endregion 2562 #endregion
@@ -3076,6 +3329,7 @@ namespace OpenSim.Region.Framework.Scenes
3076 m_callbackURI = cAgent.CallbackURI; 3329 m_callbackURI = cAgent.CallbackURI;
3077 3330
3078 m_pos = cAgent.Position; 3331 m_pos = cAgent.Position;
3332
3079 m_velocity = cAgent.Velocity; 3333 m_velocity = cAgent.Velocity;
3080 m_CameraCenter = cAgent.Center; 3334 m_CameraCenter = cAgent.Center;
3081 //m_avHeight = cAgent.Size.Z; 3335 //m_avHeight = cAgent.Size.Z;
@@ -3164,14 +3418,25 @@ namespace OpenSim.Region.Framework.Scenes
3164 { 3418 {
3165 if (m_forceToApply.HasValue) 3419 if (m_forceToApply.HasValue)
3166 { 3420 {
3167 Vector3 force = m_forceToApply.Value;
3168 3421
3422 Vector3 force = m_forceToApply.Value;
3169 m_updateflag = true; 3423 m_updateflag = true;
3170// movementvector = force;
3171 Velocity = force; 3424 Velocity = force;
3172 3425
3173 m_forceToApply = null; 3426 m_forceToApply = null;
3174 } 3427 }
3428 else
3429 {
3430 if (m_isNudging)
3431 {
3432 Vector3 force = Vector3.Zero;
3433
3434 m_updateflag = true;
3435 Velocity = force;
3436 m_isNudging = false;
3437 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3438 }
3439 }
3175 } 3440 }
3176 3441
3177 public override void SetText(string text, Vector3 color, double alpha) 3442 public override void SetText(string text, Vector3 color, double alpha)
@@ -3222,18 +3487,29 @@ namespace OpenSim.Region.Framework.Scenes
3222 { 3487 {
3223 if (e == null) 3488 if (e == null)
3224 return; 3489 return;
3225 3490
3226 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3491 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3227 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3228 // as of this comment the interval is set in AddToPhysicalScene 3492 // as of this comment the interval is set in AddToPhysicalScene
3229 if (Animator!=null) 3493 if (Animator!=null)
3230 Animator.UpdateMovementAnimations(); 3494 {
3495 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3496 { // else its will lock out other animation changes, like ground sit.
3497 Animator.UpdateMovementAnimations();
3498 m_updateCount--;
3499 }
3500 }
3231 3501
3232 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3502 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3233 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3503 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3234 3504
3235 CollisionPlane = Vector4.UnitW; 3505 CollisionPlane = Vector4.UnitW;
3236 3506
3507 if (m_lastColCount != coldata.Count)
3508 {
3509 m_updateCount = UPDATE_COUNT;
3510 m_lastColCount = coldata.Count;
3511 }
3512
3237 if (coldata.Count != 0 && Animator != null) 3513 if (coldata.Count != 0 && Animator != null)
3238 { 3514 {
3239 switch (Animator.CurrentMovementAnimation) 3515 switch (Animator.CurrentMovementAnimation)
@@ -3437,7 +3713,10 @@ namespace OpenSim.Region.Framework.Scenes
3437 m_scene = scene; 3713 m_scene = scene;
3438 3714
3439 RegisterToEvents(); 3715 RegisterToEvents();
3440 3716 if (m_controllingClient != null)
3717 {
3718 m_controllingClient.ProcessPendingPackets();
3719 }
3441 /* 3720 /*
3442 AbsolutePosition = client.StartPos; 3721 AbsolutePosition = client.StartPos;
3443 3722
@@ -3668,6 +3947,32 @@ namespace OpenSim.Region.Framework.Scenes
3668 return; 3947 return;
3669 } 3948 }
3670 3949
3950 XmlDocument doc = new XmlDocument();
3951 string stateData = String.Empty;
3952
3953 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
3954 if (attServ != null)
3955 {
3956 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
3957 stateData = attServ.Get(ControllingClient.AgentId.ToString());
3958 doc.LoadXml(stateData);
3959 }
3960
3961 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
3962
3963 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
3964 if (nodes.Count > 0)
3965 {
3966 foreach (XmlNode n in nodes)
3967 {
3968 XmlElement elem = (XmlElement)n;
3969 string itemID = elem.GetAttribute("ItemID");
3970 string xml = elem.InnerXml;
3971
3972 itemData[new UUID(itemID)] = xml;
3973 }
3974 }
3975
3671 List<int> attPoints = m_appearance.GetAttachedPoints(); 3976 List<int> attPoints = m_appearance.GetAttachedPoints();
3672 foreach (int p in attPoints) 3977 foreach (int p in attPoints)
3673 { 3978 {
@@ -3687,9 +3992,26 @@ namespace OpenSim.Region.Framework.Scenes
3687 3992
3688 try 3993 try
3689 { 3994 {
3690 // Rez from inventory 3995 string xmlData;
3691 UUID asset 3996 XmlDocument d = new XmlDocument();
3692 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 3997 UUID asset;
3998 if (itemData.TryGetValue(itemID, out xmlData))
3999 {
4000 d.LoadXml(xmlData);
4001 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4002
4003 // Rez from inventory
4004 asset
4005 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4006
4007 }
4008 else
4009 {
4010 // Rez from inventory (with a null doc to let
4011 // CHANGED_OWNER happen)
4012 asset
4013 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4014 }
3693 4015
3694 m_log.InfoFormat( 4016 m_log.InfoFormat(
3695 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", 4017 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
@@ -3726,5 +4048,16 @@ namespace OpenSim.Region.Framework.Scenes
3726 m_reprioritization_called = false; 4048 m_reprioritization_called = false;
3727 } 4049 }
3728 } 4050 }
4051
4052 private Vector3 Quat2Euler(Quaternion rot){
4053 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4054 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4055 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4056 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4057 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4058 return(new Vector3(x,y,z));
4059 }
4060
4061
3729 } 4062 }
3730} 4063}