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.cs685
1 files changed, 513 insertions, 172 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 6c119c2..d4fc6cd 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,9 +462,18 @@ 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
469 // If we're sitting, we need to update our position
470 if (m_parentID != 0)
471 {
472 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
473 if (part != null)
474 m_parentPosition = part.AbsolutePosition;
475 }
476
456 return m_parentPosition + m_pos; 477 return m_parentPosition + m_pos;
457 } 478 }
458 set 479 set
@@ -471,7 +492,8 @@ namespace OpenSim.Region.Framework.Scenes
471 } 492 }
472 } 493 }
473 494
474 m_pos = value; 495 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
496 m_pos = value;
475 m_parentPosition = Vector3.Zero; 497 m_parentPosition = Vector3.Zero;
476 } 498 }
477 } 499 }
@@ -669,7 +691,7 @@ namespace OpenSim.Region.Framework.Scenes
669 CreateSceneViewer(); 691 CreateSceneViewer();
670 m_animator = new ScenePresenceAnimator(this); 692 m_animator = new ScenePresenceAnimator(this);
671 } 693 }
672 694
673 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 695 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
674 { 696 {
675 m_rootRegionHandle = reginfo.RegionHandle; 697 m_rootRegionHandle = reginfo.RegionHandle;
@@ -701,16 +723,16 @@ namespace OpenSim.Region.Framework.Scenes
701 m_reprioritization_timer.AutoReset = false; 723 m_reprioritization_timer.AutoReset = false;
702 724
703 AdjustKnownSeeds(); 725 AdjustKnownSeeds();
704
705 // TODO: I think, this won't send anything, as we are still a child here...
706 Animator.TrySetMovementAnimation("STAND"); 726 Animator.TrySetMovementAnimation("STAND");
707
708 // we created a new ScenePresence (a new child agent) in a fresh region. 727 // we created a new ScenePresence (a new child agent) in a fresh region.
709 // Request info about all the (root) agents in this region 728 // 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) 729 // Note: This won't send data *to* other clients in that region (children don't send)
711 SendInitialFullUpdateToAllClients(); 730 SendInitialFullUpdateToAllClients();
712
713 RegisterToEvents(); 731 RegisterToEvents();
732 if (m_controllingClient != null)
733 {
734 m_controllingClient.ProcessPendingPackets();
735 }
714 SetDirectionVectors(); 736 SetDirectionVectors();
715 } 737 }
716 738
@@ -760,25 +782,47 @@ namespace OpenSim.Region.Framework.Scenes
760 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 782 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
761 Dir_Vectors[4] = Vector3.UnitZ; //UP 783 Dir_Vectors[4] = Vector3.UnitZ; //UP
762 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 784 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
763 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 785 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
764 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 786 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
765 Dir_Vectors[7] = -Vector3.UnitX; //BACK 787 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
788 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
789 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
766 } 790 }
767 791
768 private Vector3[] GetWalkDirectionVectors() 792 private Vector3[] GetWalkDirectionVectors()
769 { 793 {
770 Vector3[] vector = new Vector3[9]; 794 Vector3[] vector = new Vector3[11];
771 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 795 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 796 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
773 vector[2] = Vector3.UnitY; //LEFT 797 vector[2] = Vector3.UnitY; //LEFT
774 vector[3] = -Vector3.UnitY; //RIGHT 798 vector[3] = -Vector3.UnitY; //RIGHT
775 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 799 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 800 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 801 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 802 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 803 vector[8] = Vector3.UnitY; //LEFT_NUDGE
804 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
805 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
780 return vector; 806 return vector;
781 } 807 }
808
809 private bool[] GetDirectionIsNudge()
810 {
811 bool[] isNudge = new bool[11];
812 isNudge[0] = false; //FORWARD
813 isNudge[1] = false; //BACK
814 isNudge[2] = false; //LEFT
815 isNudge[3] = false; //RIGHT
816 isNudge[4] = false; //UP
817 isNudge[5] = false; //DOWN
818 isNudge[6] = true; //FORWARD_NUDGE
819 isNudge[7] = true; //BACK_NUDGE
820 isNudge[8] = true; //LEFT_NUDGE
821 isNudge[9] = true; //RIGHT_NUDGE
822 isNudge[10] = true; //DOWN_Nudge
823 return isNudge;
824 }
825
782 826
783 #endregion 827 #endregion
784 828
@@ -821,7 +865,6 @@ namespace OpenSim.Region.Framework.Scenes
821 m_grouptitle = gm.GetGroupTitle(m_uuid); 865 m_grouptitle = gm.GetGroupTitle(m_uuid);
822 866
823 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; 867 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle;
824
825 m_scene.SetRootAgentScene(m_uuid); 868 m_scene.SetRootAgentScene(m_uuid);
826 869
827 // Moved this from SendInitialData to ensure that m_appearance is initialized 870 // Moved this from SendInitialData to ensure that m_appearance is initialized
@@ -840,6 +883,52 @@ namespace OpenSim.Region.Framework.Scenes
840 pos.Y = crossedBorder.BorderLine.Z - 1; 883 pos.Y = crossedBorder.BorderLine.Z - 1;
841 } 884 }
842 885
886 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
887 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
888 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
889 if (KnownChildRegionHandles.Count == 0)
890 {
891 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
892 if (land != null)
893 {
894 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
895 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)
896 {
897 pos = land.LandData.UserLocation;
898 }
899 }
900 }
901
902 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
903 {
904 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
905
906 if (pos.X < 0)
907 {
908 emergencyPos.X = (int)Constants.RegionSize + pos.X;
909 if (!(pos.Y < 0))
910 emergencyPos.Y = pos.Y;
911 if (!(pos.Z < 0))
912 emergencyPos.Z = pos.Z;
913 }
914 if (pos.Y < 0)
915 {
916 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
917 if (!(pos.X < 0))
918 emergencyPos.X = pos.X;
919 if (!(pos.Z < 0))
920 emergencyPos.Z = pos.Z;
921 }
922 if (pos.Z < 0)
923 {
924 emergencyPos.Z = 128;
925 if (!(pos.Y < 0))
926 emergencyPos.Y = pos.Y;
927 if (!(pos.X < 0))
928 emergencyPos.X = pos.X;
929 }
930 }
931
843 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 932 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
844 { 933 {
845 m_log.WarnFormat( 934 m_log.WarnFormat(
@@ -972,9 +1061,10 @@ namespace OpenSim.Region.Framework.Scenes
972 public void Teleport(Vector3 pos) 1061 public void Teleport(Vector3 pos)
973 { 1062 {
974 bool isFlying = false; 1063 bool isFlying = false;
1064
975 if (m_physicsActor != null) 1065 if (m_physicsActor != null)
976 isFlying = m_physicsActor.Flying; 1066 isFlying = m_physicsActor.Flying;
977 1067
978 RemoveFromPhysicalScene(); 1068 RemoveFromPhysicalScene();
979 Velocity = Vector3.Zero; 1069 Velocity = Vector3.Zero;
980 AbsolutePosition = pos; 1070 AbsolutePosition = pos;
@@ -986,6 +1076,7 @@ namespace OpenSim.Region.Framework.Scenes
986 } 1076 }
987 1077
988 SendTerseUpdateToAllClients(); 1078 SendTerseUpdateToAllClients();
1079
989 } 1080 }
990 1081
991 public void TeleportWithMomentum(Vector3 pos) 1082 public void TeleportWithMomentum(Vector3 pos)
@@ -1099,7 +1190,6 @@ namespace OpenSim.Region.Framework.Scenes
1099 pos.Z = ground + 1.5f; 1190 pos.Z = ground + 1.5f;
1100 AbsolutePosition = pos; 1191 AbsolutePosition = pos;
1101 } 1192 }
1102
1103 m_isChildAgent = false; 1193 m_isChildAgent = false;
1104 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1194 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1105 MakeRootAgent(AbsolutePosition, m_flying); 1195 MakeRootAgent(AbsolutePosition, m_flying);
@@ -1198,6 +1288,7 @@ namespace OpenSim.Region.Framework.Scenes
1198 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1288 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1199 1289
1200 m_pos = m_LastFinitePos; 1290 m_pos = m_LastFinitePos;
1291
1201 if (!m_pos.IsFinite()) 1292 if (!m_pos.IsFinite())
1202 { 1293 {
1203 m_pos.X = 127f; 1294 m_pos.X = 127f;
@@ -1264,7 +1355,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); 1355 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1265 } 1356 }
1266 } 1357 }
1267
1268 lock (scriptedcontrols) 1358 lock (scriptedcontrols)
1269 { 1359 {
1270 if (scriptedcontrols.Count > 0) 1360 if (scriptedcontrols.Count > 0)
@@ -1279,6 +1369,9 @@ namespace OpenSim.Region.Framework.Scenes
1279 1369
1280 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1370 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1281 { 1371 {
1372 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1373 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1374
1282 // TODO: This doesn't prevent the user from walking yet. 1375 // TODO: This doesn't prevent the user from walking yet.
1283 // Setting parent ID would fix this, if we knew what value 1376 // Setting parent ID would fix this, if we knew what value
1284 // to use. Or we could add a m_isSitting variable. 1377 // to use. Or we could add a m_isSitting variable.
@@ -1333,6 +1426,11 @@ namespace OpenSim.Region.Framework.Scenes
1333 update_rotation = true; 1426 update_rotation = true;
1334 } 1427 }
1335 1428
1429 //guilty until proven innocent..
1430 bool Nudging = true;
1431 //Basically, if there is at least one non-nudge control then we don't need
1432 //to worry about stopping the avatar
1433
1336 if (m_parentID == 0) 1434 if (m_parentID == 0)
1337 { 1435 {
1338 bool bAllowUpdateMoveToPosition = false; 1436 bool bAllowUpdateMoveToPosition = false;
@@ -1347,9 +1445,12 @@ namespace OpenSim.Region.Framework.Scenes
1347 else 1445 else
1348 dirVectors = Dir_Vectors; 1446 dirVectors = Dir_Vectors;
1349 1447
1350 // The fact that m_movementflag is a byte needs to be fixed 1448 bool[] isNudge = GetDirectionIsNudge();
1351 // it really should be a uint 1449
1352 uint nudgehack = 250; 1450
1451
1452
1453
1353 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1454 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1354 { 1455 {
1355 if (((uint)flags & (uint)DCF) != 0) 1456 if (((uint)flags & (uint)DCF) != 0)
@@ -1359,40 +1460,28 @@ namespace OpenSim.Region.Framework.Scenes
1359 try 1460 try
1360 { 1461 {
1361 agent_control_v3 += dirVectors[i]; 1462 agent_control_v3 += dirVectors[i];
1362 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1463 if (isNudge[i] == false)
1464 {
1465 Nudging = false;
1466 }
1363 } 1467 }
1364 catch (IndexOutOfRangeException) 1468 catch (IndexOutOfRangeException)
1365 { 1469 {
1366 // Why did I get this? 1470 // Why did I get this?
1367 } 1471 }
1368 1472
1369 if ((m_movementflag & (byte)(uint)DCF) == 0) 1473 if ((m_movementflag & (uint)DCF) == 0)
1370 { 1474 {
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; 1475 m_movementflag += (byte)(uint)DCF;
1376 update_movementflag = true; 1476 update_movementflag = true;
1377 } 1477 }
1378 } 1478 }
1379 else 1479 else
1380 { 1480 {
1381 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1481 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 { 1482 {
1386 m_movementflag -= ((byte)(uint)DCF); 1483 m_movementflag -= (byte)(uint)DCF;
1387
1388 update_movementflag = true; 1484 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 } 1485 }
1397 else 1486 else
1398 { 1487 {
@@ -1401,7 +1490,6 @@ namespace OpenSim.Region.Framework.Scenes
1401 } 1490 }
1402 i++; 1491 i++;
1403 } 1492 }
1404
1405 //Paupaw:Do Proper PID for Autopilot here 1493 //Paupaw:Do Proper PID for Autopilot here
1406 if (bResetMoveToPosition) 1494 if (bResetMoveToPosition)
1407 { 1495 {
@@ -1436,6 +1524,9 @@ namespace OpenSim.Region.Framework.Scenes
1436 // Ignore z component of vector 1524 // Ignore z component of vector
1437 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1525 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1438 LocalVectorToTarget2D.Normalize(); 1526 LocalVectorToTarget2D.Normalize();
1527
1528 //We're not nudging
1529 Nudging = false;
1439 agent_control_v3 += LocalVectorToTarget2D; 1530 agent_control_v3 += LocalVectorToTarget2D;
1440 1531
1441 // update avatar movement flags. the avatar coordinate system is as follows: 1532 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1524,13 +1615,13 @@ namespace OpenSim.Region.Framework.Scenes
1524 // m_log.DebugFormat( 1615 // m_log.DebugFormat(
1525 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1616 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1526 1617
1527 AddNewMovement(agent_control_v3, q); 1618 AddNewMovement(agent_control_v3, q, Nudging);
1528 1619
1529 1620
1530 } 1621 }
1531 } 1622 }
1532 1623
1533 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1624 if (update_movementflag && !SitGround)
1534 Animator.UpdateMovementAnimations(); 1625 Animator.UpdateMovementAnimations();
1535 1626
1536 m_scene.EventManager.TriggerOnClientMovement(this); 1627 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1545,7 +1636,6 @@ namespace OpenSim.Region.Framework.Scenes
1545 m_sitAtAutoTarget = false; 1636 m_sitAtAutoTarget = false;
1546 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1637 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1547 //proxy.PCode = (byte)PCode.ParticleSystem; 1638 //proxy.PCode = (byte)PCode.ParticleSystem;
1548
1549 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1639 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1550 proxyObjectGroup.AttachToScene(m_scene); 1640 proxyObjectGroup.AttachToScene(m_scene);
1551 1641
@@ -1587,7 +1677,7 @@ namespace OpenSim.Region.Framework.Scenes
1587 } 1677 }
1588 m_moveToPositionInProgress = true; 1678 m_moveToPositionInProgress = true;
1589 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1679 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1590 } 1680 }
1591 catch (Exception ex) 1681 catch (Exception ex)
1592 { 1682 {
1593 //Why did I get this error? 1683 //Why did I get this error?
@@ -1609,7 +1699,7 @@ namespace OpenSim.Region.Framework.Scenes
1609 Velocity = Vector3.Zero; 1699 Velocity = Vector3.Zero;
1610 SendFullUpdateToAllClients(); 1700 SendFullUpdateToAllClients();
1611 1701
1612 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1702 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1613 } 1703 }
1614 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1704 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1615 m_requestedSitTargetUUID = UUID.Zero; 1705 m_requestedSitTargetUUID = UUID.Zero;
@@ -1646,50 +1736,82 @@ namespace OpenSim.Region.Framework.Scenes
1646 1736
1647 if (m_parentID != 0) 1737 if (m_parentID != 0)
1648 { 1738 {
1649 m_log.Debug("StandupCode Executed");
1650 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1739 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1651 if (part != null) 1740 if (part != null)
1652 { 1741 {
1742 part.TaskInventory.LockItemsForRead(true);
1653 TaskInventoryDictionary taskIDict = part.TaskInventory; 1743 TaskInventoryDictionary taskIDict = part.TaskInventory;
1654 if (taskIDict != null) 1744 if (taskIDict != null)
1655 { 1745 {
1656 lock (taskIDict) 1746 foreach (UUID taskID in taskIDict.Keys)
1657 { 1747 {
1658 foreach (UUID taskID in taskIDict.Keys) 1748 UnRegisterControlEventsToScript(LocalId, taskID);
1659 { 1749 taskIDict[taskID].PermsMask &= ~(
1660 UnRegisterControlEventsToScript(LocalId, taskID); 1750 2048 | //PERMISSION_CONTROL_CAMERA
1661 taskIDict[taskID].PermsMask &= ~( 1751 4); // PERMISSION_TAKE_CONTROLS
1662 2048 | //PERMISSION_CONTROL_CAMERA
1663 4); // PERMISSION_TAKE_CONTROLS
1664 }
1665 } 1752 }
1666
1667 } 1753 }
1754 part.TaskInventory.LockItemsForRead(false);
1668 // Reset sit target. 1755 // Reset sit target.
1669 if (part.GetAvatarOnSitTarget() == UUID) 1756 if (part.GetAvatarOnSitTarget() == UUID)
1670 part.SetAvatarOnSitTarget(UUID.Zero); 1757 part.SetAvatarOnSitTarget(UUID.Zero);
1671
1672 m_parentPosition = part.GetWorldPosition(); 1758 m_parentPosition = part.GetWorldPosition();
1673 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1759 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1674 } 1760 }
1761 // part.GetWorldRotation() is the rotation of the object being sat on
1762 // Rotation is the sittiing Av's rotation
1675 1763
1676 if (m_physicsActor == null) 1764 Quaternion partRot;
1765// if (part.LinkNum == 1)
1766// { // Root prim of linkset
1767// partRot = part.ParentGroup.RootPart.RotationOffset;
1768// }
1769// else
1770// { // single or child prim
1771
1772// }
1773 if (part == null) //CW: Part may be gone. llDie() for example.
1677 { 1774 {
1678 AddToPhysicalScene(false); 1775 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1776 }
1777 else
1778 {
1779 partRot = part.GetWorldRotation();
1679 } 1780 }
1680 1781
1681 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1782 Quaternion partIRot = Quaternion.Inverse(partRot);
1682 m_parentPosition = Vector3.Zero; 1783
1784 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1785 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1683 1786
1684 m_parentID = 0; 1787
1788 if (m_physicsActor == null)
1789 {
1790 AddToPhysicalScene(false);
1791 }
1792 //CW: If the part isn't null then we can set the current position
1793 if (part != null)
1794 {
1795 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1796 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1797 part.IsOccupied = false;
1798 }
1799 else
1800 {
1801 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1802 AbsolutePosition = m_lastWorldPosition;
1803 }
1804
1805 m_parentPosition = Vector3.Zero;
1806 m_parentID = 0;
1685 SendFullUpdateToAllClients(); 1807 SendFullUpdateToAllClients();
1686 m_requestedSitTargetID = 0; 1808 m_requestedSitTargetID = 0;
1809
1687 if ((m_physicsActor != null) && (m_avHeight > 0)) 1810 if ((m_physicsActor != null) && (m_avHeight > 0))
1688 { 1811 {
1689 SetHeight(m_avHeight); 1812 SetHeight(m_avHeight);
1690 } 1813 }
1691 } 1814 }
1692
1693 Animator.TrySetMovementAnimation("STAND"); 1815 Animator.TrySetMovementAnimation("STAND");
1694 } 1816 }
1695 1817
@@ -1720,13 +1842,9 @@ namespace OpenSim.Region.Framework.Scenes
1720 Vector3 avSitOffSet = part.SitTargetPosition; 1842 Vector3 avSitOffSet = part.SitTargetPosition;
1721 Quaternion avSitOrientation = part.SitTargetOrientation; 1843 Quaternion avSitOrientation = part.SitTargetOrientation;
1722 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1844 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1723 1845 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1724 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1846 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1725 bool SitTargetisSet = 1847 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 { 1848 {
1731 //switch the target to this prim 1849 //switch the target to this prim
1732 return part; 1850 return part;
@@ -1740,84 +1858,153 @@ namespace OpenSim.Region.Framework.Scenes
1740 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1858 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1741 { 1859 {
1742 bool autopilot = true; 1860 bool autopilot = true;
1861 Vector3 autopilotTarget = new Vector3();
1862 Quaternion sitOrientation = Quaternion.Identity;
1743 Vector3 pos = new Vector3(); 1863 Vector3 pos = new Vector3();
1744 Quaternion sitOrientation = pSitOrientation;
1745 Vector3 cameraEyeOffset = Vector3.Zero; 1864 Vector3 cameraEyeOffset = Vector3.Zero;
1746 Vector3 cameraAtOffset = Vector3.Zero; 1865 Vector3 cameraAtOffset = Vector3.Zero;
1747 bool forceMouselook = false; 1866 bool forceMouselook = false;
1748 1867
1749 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1868 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1750 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1869 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1751 if (part != null) 1870 if (part == null) return;
1752 { 1871
1753 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1872 // 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 1873 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1755 1874
1756 // Is a sit target available? 1875 // part is the prim to sit on
1757 Vector3 avSitOffSet = part.SitTargetPosition; 1876 // offset is the world-ref vector distance from that prim center to the click-spot
1758 Quaternion avSitOrientation = part.SitTargetOrientation; 1877 // UUID is the UUID of the Avatar doing the clicking
1759 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1878
1760 1879 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1761 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1880
1762 bool SitTargetisSet = 1881 // Is a sit target available?
1763 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1882 Vector3 avSitOffSet = part.SitTargetPosition;
1764 ( 1883 Quaternion avSitOrientation = part.SitTargetOrientation;
1765 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1884
1766 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1885 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 1886 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1768 ) 1887 Quaternion partRot;
1769 )); 1888// if (part.LinkNum == 1)
1770 1889// { // Root prim of linkset
1771 if (SitTargetisSet && SitTargetUnOccupied) 1890// partRot = part.ParentGroup.RootPart.RotationOffset;
1772 { 1891// }
1773 part.SetAvatarOnSitTarget(UUID); 1892// else
1774 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1893// { // single or child prim
1775 sitOrientation = avSitOrientation; 1894 partRot = part.GetWorldRotation();
1776 autopilot = false; 1895// }
1777 } 1896 Quaternion partIRot = Quaternion.Inverse(partRot);
1778 1897//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1779 pos = part.AbsolutePosition + offset; 1898 // Sit analysis rewritten by KF 091125
1780 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1899 if (SitTargetisSet) // scipted sit
1781 //{ 1900 {
1782 // offset = pos; 1901 if (!part.IsOccupied)
1783 //autopilot = false; 1902 {
1784 //} 1903//Console.WriteLine("Scripted, unoccupied");
1785 if (m_physicsActor != null) 1904 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1786 { 1905 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 1906 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1788 // We can remove the physicsActor until they stand up. 1907 autopilot = false; // Jump direct to scripted llSitPos()
1789 m_sitAvatarHeight = m_physicsActor.Size.Z; 1908 }
1790 1909 else
1791 if (autopilot) 1910 {
1792 { 1911//Console.WriteLine("Scripted, occupied");
1793 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1912 return;
1794 { 1913 }
1795 autopilot = false; 1914 }
1915 else // Not Scripted
1916 {
1917 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1918 {
1919 // large prim & offset, ignore if other Avs sitting
1920// offset.Z -= 0.05f;
1921 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1922 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1923
1924//Console.WriteLine(" offset ={0}", offset);
1925//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1926//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1927
1928 }
1929 else // small offset
1930 {
1931//Console.WriteLine("Small offset");
1932 if (!part.IsOccupied)
1933 {
1934 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1935 autopilotTarget = part.AbsolutePosition;
1936//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1937 }
1938 else return; // occupied small
1939 } // end large/small
1940 } // end Scripted/not
1941 cameraAtOffset = part.GetCameraAtOffset();
1942 cameraEyeOffset = part.GetCameraEyeOffset();
1943 forceMouselook = part.GetForceMouselook();
1944 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1945 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1796 1946
1797 RemoveFromPhysicalScene(); 1947 if (m_physicsActor != null)
1798 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1948 {
1799 } 1949 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1800 } 1950 // We can remove the physicsActor until they stand up.
1801 else 1951 m_sitAvatarHeight = m_physicsActor.Size.Z;
1952 if (autopilot)
1953 { // its not a scripted sit
1954// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1955 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1802 { 1956 {
1957 autopilot = false; // close enough
1958 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1959 Not using the part's position because returning the AV to the last known standing
1960 position is likely to be more friendly, isn't it? */
1803 RemoveFromPhysicalScene(); 1961 RemoveFromPhysicalScene();
1804 } 1962 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1963 } // else the autopilot will get us close
1964 }
1965 else
1966 { // its a scripted sit
1967 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1968 I *am* using the part's position this time because we have no real idea how far away
1969 the avatar is from the sit target. */
1970 RemoveFromPhysicalScene();
1805 } 1971 }
1806
1807 cameraAtOffset = part.GetCameraAtOffset();
1808 cameraEyeOffset = part.GetCameraEyeOffset();
1809 forceMouselook = part.GetForceMouselook();
1810 } 1972 }
1811 1973 else return; // physactor is null!
1812 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1974
1813 m_requestedSitTargetUUID = targetID; 1975 Vector3 offsetr; // = offset * partIRot;
1976 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1977 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1978 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1979 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1980 offsetr = offset * partIRot;
1981//
1982 // else
1983 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1984 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1985 // (offset * partRot);
1986 // }
1987
1988//Console.WriteLine(" ");
1989//Console.WriteLine("link number ={0}", part.LinkNum);
1990//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1991//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1992//Console.WriteLine("Click offst ={0}", offset);
1993//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1994//Console.WriteLine("offsetr ={0}", offsetr);
1995//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1996//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1997
1998 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1999 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1814 // This calls HandleAgentSit twice, once from here, and the client calls 2000 // This calls HandleAgentSit twice, once from here, and the client calls
1815 // HandleAgentSit itself after it gets to the location 2001 // HandleAgentSit itself after it gets to the location
1816 // It doesn't get to the location until we've moved them there though 2002 // It doesn't get to the location until we've moved them there though
1817 // which happens in HandleAgentSit :P 2003 // which happens in HandleAgentSit :P
1818 m_autopilotMoving = autopilot; 2004 m_autopilotMoving = autopilot;
1819 m_autoPilotTarget = pos; 2005 m_autoPilotTarget = autopilotTarget;
1820 m_sitAtAutoTarget = autopilot; 2006 m_sitAtAutoTarget = autopilot;
2007 m_initialSitTarget = autopilotTarget;
1821 if (!autopilot) 2008 if (!autopilot)
1822 HandleAgentSit(remoteClient, UUID); 2009 HandleAgentSit(remoteClient, UUID);
1823 } 2010 }
@@ -2112,31 +2299,66 @@ namespace OpenSim.Region.Framework.Scenes
2112 { 2299 {
2113 if (part != null) 2300 if (part != null)
2114 { 2301 {
2302//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2115 if (part.GetAvatarOnSitTarget() == UUID) 2303 if (part.GetAvatarOnSitTarget() == UUID)
2116 { 2304 {
2305//Console.WriteLine("Scripted Sit");
2306 // Scripted sit
2117 Vector3 sitTargetPos = part.SitTargetPosition; 2307 Vector3 sitTargetPos = part.SitTargetPosition;
2118 Quaternion sitTargetOrient = part.SitTargetOrientation; 2308 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); 2309 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2126 m_pos += SIT_TARGET_ADJUSTMENT; 2310 m_pos += SIT_TARGET_ADJUSTMENT;
2127 m_bodyRot = sitTargetOrient; 2311 m_bodyRot = sitTargetOrient;
2128 //Rotation = sitTargetOrient;
2129 m_parentPosition = part.AbsolutePosition; 2312 m_parentPosition = part.AbsolutePosition;
2130 2313 part.IsOccupied = true;
2131 //SendTerseUpdateToAllClients(); 2314Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2132 } 2315 }
2133 else 2316 else
2134 { 2317 {
2135 m_pos -= part.AbsolutePosition; 2318 // if m_avUnscriptedSitPos is zero then Av sits above center
2319 // Else Av sits at m_avUnscriptedSitPos
2320
2321 // Non-scripted sit by Kitto Flora 21Nov09
2322 // Calculate angle of line from prim to Av
2323 Quaternion partIRot;
2324// if (part.LinkNum == 1)
2325// { // Root prim of linkset
2326// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2327// }
2328// else
2329// { // single or child prim
2330 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2331// }
2332 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2333 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2334 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2335 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2336 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2337 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2338 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2339 // Av sits at world euler <0,0, z>, translated by part rotation
2340 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2341
2136 m_parentPosition = part.AbsolutePosition; 2342 m_parentPosition = part.AbsolutePosition;
2137 } 2343 part.IsOccupied = true;
2138 } 2344 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2139 else 2345 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2346 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2347 m_avUnscriptedSitPos; // adds click offset, if any
2348 //Set up raytrace to find top surface of prim
2349 Vector3 size = part.Scale;
2350 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2351 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2352 Vector3 down = new Vector3(0f, 0f, -1f);
2353//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2354 m_scene.PhysicsScene.RaycastWorld(
2355 start, // Vector3 position,
2356 down, // Vector3 direction,
2357 mag, // float length,
2358 SitAltitudeCallback); // retMethod
2359 } // end scripted/not
2360 }
2361 else // no Av
2140 { 2362 {
2141 return; 2363 return;
2142 } 2364 }
@@ -2148,11 +2370,39 @@ namespace OpenSim.Region.Framework.Scenes
2148 2370
2149 Animator.TrySetMovementAnimation(sitAnimation); 2371 Animator.TrySetMovementAnimation(sitAnimation);
2150 SendFullUpdateToAllClients(); 2372 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 } 2373 }
2374
2375 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2376 {
2377 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2378 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2379 if(hitYN)
2380 {
2381 // m_pos = Av offset from prim center to make look like on center
2382 // m_parentPosition = Actual center pos of prim
2383 // collisionPoint = spot on prim where we want to sit
2384 // collisionPoint.Z = global sit surface height
2385 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2386 Quaternion partIRot;
2387// if (part.LinkNum == 1)
2388/// { // Root prim of linkset
2389// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2390// }
2391// else
2392// { // single or child prim
2393 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2394// }
2395 if (m_initialSitTarget != null)
2396 {
2397 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2398 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2399 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2400 m_pos += offset;
2401 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2402 }
2403
2404 }
2405 } // End SitAltitudeCallback KF.
2156 2406
2157 /// <summary> 2407 /// <summary>
2158 /// Event handler for the 'Always run' setting on the client 2408 /// Event handler for the 'Always run' setting on the client
@@ -2182,7 +2432,7 @@ namespace OpenSim.Region.Framework.Scenes
2182 /// </summary> 2432 /// </summary>
2183 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2433 /// <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. 2434 /// <param name="rotation">The direction in which this avatar should now face.
2185 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2435 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2186 { 2436 {
2187 if (m_isChildAgent) 2437 if (m_isChildAgent)
2188 { 2438 {
@@ -2223,10 +2473,11 @@ namespace OpenSim.Region.Framework.Scenes
2223 Rotation = rotation; 2473 Rotation = rotation;
2224 Vector3 direc = vec * rotation; 2474 Vector3 direc = vec * rotation;
2225 direc.Normalize(); 2475 direc.Normalize();
2476 PhysicsActor actor = m_physicsActor;
2477 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2226 2478
2227 direc *= 0.03f * 128f * m_speedModifier; 2479 direc *= 0.03f * 128f * m_speedModifier;
2228 2480
2229 PhysicsActor actor = m_physicsActor;
2230 if (actor != null) 2481 if (actor != null)
2231 { 2482 {
2232 if (actor.Flying) 2483 if (actor.Flying)
@@ -2248,18 +2499,25 @@ namespace OpenSim.Region.Framework.Scenes
2248 { 2499 {
2249 if (direc.Z > 2.0f) 2500 if (direc.Z > 2.0f)
2250 { 2501 {
2251 direc.Z *= 3.0f; 2502 if(m_animator.m_animTickJump == -1)
2252 2503 {
2253 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2504 direc.Z *= 3.0f; // jump
2254 Animator.TrySetMovementAnimation("PREJUMP"); 2505 }
2255 Animator.TrySetMovementAnimation("JUMP"); 2506 else
2507 {
2508 direc.Z *= 0.1f; // prejump
2509 }
2510 /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2511 Animator.TrySetMovementAnimation("PREJUMP");
2512 Animator.TrySetMovementAnimation("JUMP");
2513 */
2256 } 2514 }
2257 } 2515 }
2258 } 2516 }
2259 2517
2260 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2518 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2261 m_forceToApply = direc; 2519 m_forceToApply = direc;
2262 2520 m_isNudging = Nudging;
2263 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2521 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2264 } 2522 }
2265 2523
@@ -2274,7 +2532,7 @@ namespace OpenSim.Region.Framework.Scenes
2274 const float POSITION_TOLERANCE = 0.05f; 2532 const float POSITION_TOLERANCE = 0.05f;
2275 //const int TIME_MS_TOLERANCE = 3000; 2533 //const int TIME_MS_TOLERANCE = 3000;
2276 2534
2277 SendPrimUpdates(); 2535
2278 2536
2279 if (m_isChildAgent == false) 2537 if (m_isChildAgent == false)
2280 { 2538 {
@@ -2304,6 +2562,9 @@ namespace OpenSim.Region.Framework.Scenes
2304 CheckForBorderCrossing(); 2562 CheckForBorderCrossing();
2305 CheckForSignificantMovement(); // sends update to the modules. 2563 CheckForSignificantMovement(); // sends update to the modules.
2306 } 2564 }
2565
2566 //Sending prim updates AFTER the avatar terse updates are sent
2567 SendPrimUpdates();
2307 } 2568 }
2308 2569
2309 #endregion 2570 #endregion
@@ -3076,6 +3337,7 @@ namespace OpenSim.Region.Framework.Scenes
3076 m_callbackURI = cAgent.CallbackURI; 3337 m_callbackURI = cAgent.CallbackURI;
3077 3338
3078 m_pos = cAgent.Position; 3339 m_pos = cAgent.Position;
3340
3079 m_velocity = cAgent.Velocity; 3341 m_velocity = cAgent.Velocity;
3080 m_CameraCenter = cAgent.Center; 3342 m_CameraCenter = cAgent.Center;
3081 //m_avHeight = cAgent.Size.Z; 3343 //m_avHeight = cAgent.Size.Z;
@@ -3165,14 +3427,25 @@ namespace OpenSim.Region.Framework.Scenes
3165 { 3427 {
3166 if (m_forceToApply.HasValue) 3428 if (m_forceToApply.HasValue)
3167 { 3429 {
3168 Vector3 force = m_forceToApply.Value;
3169 3430
3431 Vector3 force = m_forceToApply.Value;
3170 m_updateflag = true; 3432 m_updateflag = true;
3171// movementvector = force;
3172 Velocity = force; 3433 Velocity = force;
3173 3434
3174 m_forceToApply = null; 3435 m_forceToApply = null;
3175 } 3436 }
3437 else
3438 {
3439 if (m_isNudging)
3440 {
3441 Vector3 force = Vector3.Zero;
3442
3443 m_updateflag = true;
3444 Velocity = force;
3445 m_isNudging = false;
3446 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3447 }
3448 }
3176 } 3449 }
3177 3450
3178 public override void SetText(string text, Vector3 color, double alpha) 3451 public override void SetText(string text, Vector3 color, double alpha)
@@ -3223,18 +3496,29 @@ namespace OpenSim.Region.Framework.Scenes
3223 { 3496 {
3224 if (e == null) 3497 if (e == null)
3225 return; 3498 return;
3226 3499
3227 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3500 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3228 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3229 // as of this comment the interval is set in AddToPhysicalScene 3501 // as of this comment the interval is set in AddToPhysicalScene
3230 if (Animator!=null) 3502 if (Animator!=null)
3231 Animator.UpdateMovementAnimations(); 3503 {
3504 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3505 { // else its will lock out other animation changes, like ground sit.
3506 Animator.UpdateMovementAnimations();
3507 m_updateCount--;
3508 }
3509 }
3232 3510
3233 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3511 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3234 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3512 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3235 3513
3236 CollisionPlane = Vector4.UnitW; 3514 CollisionPlane = Vector4.UnitW;
3237 3515
3516 if (m_lastColCount != coldata.Count)
3517 {
3518 m_updateCount = UPDATE_COUNT;
3519 m_lastColCount = coldata.Count;
3520 }
3521
3238 if (coldata.Count != 0 && Animator != null) 3522 if (coldata.Count != 0 && Animator != null)
3239 { 3523 {
3240 switch (Animator.CurrentMovementAnimation) 3524 switch (Animator.CurrentMovementAnimation)
@@ -3438,7 +3722,10 @@ namespace OpenSim.Region.Framework.Scenes
3438 m_scene = scene; 3722 m_scene = scene;
3439 3723
3440 RegisterToEvents(); 3724 RegisterToEvents();
3441 3725 if (m_controllingClient != null)
3726 {
3727 m_controllingClient.ProcessPendingPackets();
3728 }
3442 /* 3729 /*
3443 AbsolutePosition = client.StartPos; 3730 AbsolutePosition = client.StartPos;
3444 3731
@@ -3669,6 +3956,32 @@ namespace OpenSim.Region.Framework.Scenes
3669 return; 3956 return;
3670 } 3957 }
3671 3958
3959 XmlDocument doc = new XmlDocument();
3960 string stateData = String.Empty;
3961
3962 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
3963 if (attServ != null)
3964 {
3965 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
3966 stateData = attServ.Get(ControllingClient.AgentId.ToString());
3967 doc.LoadXml(stateData);
3968 }
3969
3970 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
3971
3972 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
3973 if (nodes.Count > 0)
3974 {
3975 foreach (XmlNode n in nodes)
3976 {
3977 XmlElement elem = (XmlElement)n;
3978 string itemID = elem.GetAttribute("ItemID");
3979 string xml = elem.InnerXml;
3980
3981 itemData[new UUID(itemID)] = xml;
3982 }
3983 }
3984
3672 List<int> attPoints = m_appearance.GetAttachedPoints(); 3985 List<int> attPoints = m_appearance.GetAttachedPoints();
3673 foreach (int p in attPoints) 3986 foreach (int p in attPoints)
3674 { 3987 {
@@ -3688,9 +4001,26 @@ namespace OpenSim.Region.Framework.Scenes
3688 4001
3689 try 4002 try
3690 { 4003 {
3691 // Rez from inventory 4004 string xmlData;
3692 UUID asset 4005 XmlDocument d = new XmlDocument();
3693 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4006 UUID asset;
4007 if (itemData.TryGetValue(itemID, out xmlData))
4008 {
4009 d.LoadXml(xmlData);
4010 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4011
4012 // Rez from inventory
4013 asset
4014 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4015
4016 }
4017 else
4018 {
4019 // Rez from inventory (with a null doc to let
4020 // CHANGED_OWNER happen)
4021 asset
4022 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4023 }
3694 4024
3695 m_log.InfoFormat( 4025 m_log.InfoFormat(
3696 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", 4026 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
@@ -3727,5 +4057,16 @@ namespace OpenSim.Region.Framework.Scenes
3727 m_reprioritization_called = false; 4057 m_reprioritization_called = false;
3728 } 4058 }
3729 } 4059 }
4060
4061 private Vector3 Quat2Euler(Quaternion rot){
4062 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4063 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4064 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4065 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4066 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4067 return(new Vector3(x,y,z));
4068 }
4069
4070
3730 } 4071 }
3731} 4072}