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.cs681
1 files changed, 508 insertions, 173 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 15b9446..8cd3ac6 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)
@@ -1030,7 +1113,9 @@ namespace OpenSim.Region.Framework.Scenes
1030 { 1113 {
1031 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1114 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1032 } 1115 }
1033 1116
1117 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1118
1034 ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position); 1119 ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position);
1035 //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1120 //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1036 // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1121 // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
@@ -1117,7 +1202,6 @@ namespace OpenSim.Region.Framework.Scenes
1117 pos.Z = ground + 1.5f; 1202 pos.Z = ground + 1.5f;
1118 AbsolutePosition = pos; 1203 AbsolutePosition = pos;
1119 } 1204 }
1120
1121 m_isChildAgent = false; 1205 m_isChildAgent = false;
1122 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1206 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1123 MakeRootAgent(AbsolutePosition, m_flying); 1207 MakeRootAgent(AbsolutePosition, m_flying);
@@ -1216,6 +1300,7 @@ namespace OpenSim.Region.Framework.Scenes
1216 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1300 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1217 1301
1218 m_pos = m_LastFinitePos; 1302 m_pos = m_LastFinitePos;
1303
1219 if (!m_pos.IsFinite()) 1304 if (!m_pos.IsFinite())
1220 { 1305 {
1221 m_pos.X = 127f; 1306 m_pos.X = 127f;
@@ -1282,7 +1367,6 @@ namespace OpenSim.Region.Framework.Scenes
1282 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1367 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1283 } 1368 }
1284 } 1369 }
1285
1286 lock (scriptedcontrols) 1370 lock (scriptedcontrols)
1287 { 1371 {
1288 if (scriptedcontrols.Count > 0) 1372 if (scriptedcontrols.Count > 0)
@@ -1297,6 +1381,9 @@ namespace OpenSim.Region.Framework.Scenes
1297 1381
1298 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1382 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1299 { 1383 {
1384 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1385 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1386
1300 // TODO: This doesn't prevent the user from walking yet. 1387 // TODO: This doesn't prevent the user from walking yet.
1301 // Setting parent ID would fix this, if we knew what value 1388 // Setting parent ID would fix this, if we knew what value
1302 // to use. Or we could add a m_isSitting variable. 1389 // to use. Or we could add a m_isSitting variable.
@@ -1351,6 +1438,11 @@ namespace OpenSim.Region.Framework.Scenes
1351 update_rotation = true; 1438 update_rotation = true;
1352 } 1439 }
1353 1440
1441 //guilty until proven innocent..
1442 bool Nudging = true;
1443 //Basically, if there is at least one non-nudge control then we don't need
1444 //to worry about stopping the avatar
1445
1354 if (m_parentID == 0) 1446 if (m_parentID == 0)
1355 { 1447 {
1356 bool bAllowUpdateMoveToPosition = false; 1448 bool bAllowUpdateMoveToPosition = false;
@@ -1365,9 +1457,12 @@ namespace OpenSim.Region.Framework.Scenes
1365 else 1457 else
1366 dirVectors = Dir_Vectors; 1458 dirVectors = Dir_Vectors;
1367 1459
1368 // The fact that m_movementflag is a byte needs to be fixed 1460 bool[] isNudge = GetDirectionIsNudge();
1369 // it really should be a uint 1461
1370 uint nudgehack = 250; 1462
1463
1464
1465
1371 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1466 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1372 { 1467 {
1373 if (((uint)flags & (uint)DCF) != 0) 1468 if (((uint)flags & (uint)DCF) != 0)
@@ -1377,40 +1472,28 @@ namespace OpenSim.Region.Framework.Scenes
1377 try 1472 try
1378 { 1473 {
1379 agent_control_v3 += dirVectors[i]; 1474 agent_control_v3 += dirVectors[i];
1380 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1475 if (isNudge[i] == false)
1476 {
1477 Nudging = false;
1478 }
1381 } 1479 }
1382 catch (IndexOutOfRangeException) 1480 catch (IndexOutOfRangeException)
1383 { 1481 {
1384 // Why did I get this? 1482 // Why did I get this?
1385 } 1483 }
1386 1484
1387 if ((m_movementflag & (byte)(uint)DCF) == 0) 1485 if ((m_movementflag & (uint)DCF) == 0)
1388 { 1486 {
1389 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1390 {
1391 m_movementflag |= (byte)nudgehack;
1392 }
1393 m_movementflag += (byte)(uint)DCF; 1487 m_movementflag += (byte)(uint)DCF;
1394 update_movementflag = true; 1488 update_movementflag = true;
1395 } 1489 }
1396 } 1490 }
1397 else 1491 else
1398 { 1492 {
1399 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1493 if ((m_movementflag & (uint)DCF) != 0)
1400 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1401 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1402 ) // This or is for Nudge forward
1403 { 1494 {
1404 m_movementflag -= ((byte)(uint)DCF); 1495 m_movementflag -= (byte)(uint)DCF;
1405
1406 update_movementflag = true; 1496 update_movementflag = true;
1407 /*
1408 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1409 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1410 {
1411 m_log.Debug("Removed Hack flag");
1412 }
1413 */
1414 } 1497 }
1415 else 1498 else
1416 { 1499 {
@@ -1419,7 +1502,6 @@ namespace OpenSim.Region.Framework.Scenes
1419 } 1502 }
1420 i++; 1503 i++;
1421 } 1504 }
1422
1423 //Paupaw:Do Proper PID for Autopilot here 1505 //Paupaw:Do Proper PID for Autopilot here
1424 if (bResetMoveToPosition) 1506 if (bResetMoveToPosition)
1425 { 1507 {
@@ -1454,6 +1536,9 @@ namespace OpenSim.Region.Framework.Scenes
1454 // Ignore z component of vector 1536 // Ignore z component of vector
1455 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1537 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1456 LocalVectorToTarget2D.Normalize(); 1538 LocalVectorToTarget2D.Normalize();
1539
1540 //We're not nudging
1541 Nudging = false;
1457 agent_control_v3 += LocalVectorToTarget2D; 1542 agent_control_v3 += LocalVectorToTarget2D;
1458 1543
1459 // update avatar movement flags. the avatar coordinate system is as follows: 1544 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1542,13 +1627,13 @@ namespace OpenSim.Region.Framework.Scenes
1542 // m_log.DebugFormat( 1627 // m_log.DebugFormat(
1543 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1628 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1544 1629
1545 AddNewMovement(agent_control_v3, q); 1630 AddNewMovement(agent_control_v3, q, Nudging);
1546 1631
1547 1632
1548 } 1633 }
1549 } 1634 }
1550 1635
1551 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1636 if (update_movementflag && !SitGround)
1552 Animator.UpdateMovementAnimations(); 1637 Animator.UpdateMovementAnimations();
1553 1638
1554 m_scene.EventManager.TriggerOnClientMovement(this); 1639 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1563,7 +1648,6 @@ namespace OpenSim.Region.Framework.Scenes
1563 m_sitAtAutoTarget = false; 1648 m_sitAtAutoTarget = false;
1564 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1649 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1565 //proxy.PCode = (byte)PCode.ParticleSystem; 1650 //proxy.PCode = (byte)PCode.ParticleSystem;
1566
1567 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1651 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1568 proxyObjectGroup.AttachToScene(m_scene); 1652 proxyObjectGroup.AttachToScene(m_scene);
1569 1653
@@ -1605,7 +1689,7 @@ namespace OpenSim.Region.Framework.Scenes
1605 } 1689 }
1606 m_moveToPositionInProgress = true; 1690 m_moveToPositionInProgress = true;
1607 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1691 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1608 } 1692 }
1609 catch (Exception ex) 1693 catch (Exception ex)
1610 { 1694 {
1611 //Why did I get this error? 1695 //Why did I get this error?
@@ -1627,7 +1711,7 @@ namespace OpenSim.Region.Framework.Scenes
1627 Velocity = Vector3.Zero; 1711 Velocity = Vector3.Zero;
1628 SendFullUpdateToAllClients(); 1712 SendFullUpdateToAllClients();
1629 1713
1630 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1714 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1631 } 1715 }
1632 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1716 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1633 m_requestedSitTargetUUID = UUID.Zero; 1717 m_requestedSitTargetUUID = UUID.Zero;
@@ -1664,50 +1748,82 @@ namespace OpenSim.Region.Framework.Scenes
1664 1748
1665 if (m_parentID != 0) 1749 if (m_parentID != 0)
1666 { 1750 {
1667 m_log.Debug("StandupCode Executed");
1668 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1751 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1669 if (part != null) 1752 if (part != null)
1670 { 1753 {
1754 part.TaskInventory.LockItemsForRead(true);
1671 TaskInventoryDictionary taskIDict = part.TaskInventory; 1755 TaskInventoryDictionary taskIDict = part.TaskInventory;
1672 if (taskIDict != null) 1756 if (taskIDict != null)
1673 { 1757 {
1674 lock (taskIDict) 1758 foreach (UUID taskID in taskIDict.Keys)
1675 { 1759 {
1676 foreach (UUID taskID in taskIDict.Keys) 1760 UnRegisterControlEventsToScript(LocalId, taskID);
1677 { 1761 taskIDict[taskID].PermsMask &= ~(
1678 UnRegisterControlEventsToScript(LocalId, taskID); 1762 2048 | //PERMISSION_CONTROL_CAMERA
1679 taskIDict[taskID].PermsMask &= ~( 1763 4); // PERMISSION_TAKE_CONTROLS
1680 2048 | //PERMISSION_CONTROL_CAMERA
1681 4); // PERMISSION_TAKE_CONTROLS
1682 }
1683 } 1764 }
1684
1685 } 1765 }
1766 part.TaskInventory.LockItemsForRead(false);
1686 // Reset sit target. 1767 // Reset sit target.
1687 if (part.GetAvatarOnSitTarget() == UUID) 1768 if (part.GetAvatarOnSitTarget() == UUID)
1688 part.SetAvatarOnSitTarget(UUID.Zero); 1769 part.SetAvatarOnSitTarget(UUID.Zero);
1689
1690 m_parentPosition = part.GetWorldPosition(); 1770 m_parentPosition = part.GetWorldPosition();
1691 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1771 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1692 } 1772 }
1773 // part.GetWorldRotation() is the rotation of the object being sat on
1774 // Rotation is the sittiing Av's rotation
1693 1775
1694 if (m_physicsActor == null) 1776 Quaternion partRot;
1777// if (part.LinkNum == 1)
1778// { // Root prim of linkset
1779// partRot = part.ParentGroup.RootPart.RotationOffset;
1780// }
1781// else
1782// { // single or child prim
1783
1784// }
1785 if (part == null) //CW: Part may be gone. llDie() for example.
1695 { 1786 {
1696 AddToPhysicalScene(false); 1787 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1788 }
1789 else
1790 {
1791 partRot = part.GetWorldRotation();
1697 } 1792 }
1698 1793
1699 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1794 Quaternion partIRot = Quaternion.Inverse(partRot);
1700 m_parentPosition = Vector3.Zero; 1795
1796 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1797 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1701 1798
1702 m_parentID = 0; 1799
1800 if (m_physicsActor == null)
1801 {
1802 AddToPhysicalScene(false);
1803 }
1804 //CW: If the part isn't null then we can set the current position
1805 if (part != null)
1806 {
1807 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1808 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1809 part.IsOccupied = false;
1810 }
1811 else
1812 {
1813 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1814 AbsolutePosition = m_lastWorldPosition;
1815 }
1816
1817 m_parentPosition = Vector3.Zero;
1818 m_parentID = 0;
1703 SendFullUpdateToAllClients(); 1819 SendFullUpdateToAllClients();
1704 m_requestedSitTargetID = 0; 1820 m_requestedSitTargetID = 0;
1821
1705 if ((m_physicsActor != null) && (m_avHeight > 0)) 1822 if ((m_physicsActor != null) && (m_avHeight > 0))
1706 { 1823 {
1707 SetHeight(m_avHeight); 1824 SetHeight(m_avHeight);
1708 } 1825 }
1709 } 1826 }
1710
1711 Animator.TrySetMovementAnimation("STAND"); 1827 Animator.TrySetMovementAnimation("STAND");
1712 } 1828 }
1713 1829
@@ -1738,13 +1854,9 @@ namespace OpenSim.Region.Framework.Scenes
1738 Vector3 avSitOffSet = part.SitTargetPosition; 1854 Vector3 avSitOffSet = part.SitTargetPosition;
1739 Quaternion avSitOrientation = part.SitTargetOrientation; 1855 Quaternion avSitOrientation = part.SitTargetOrientation;
1740 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1856 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1741 1857 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1742 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1858 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1743 bool SitTargetisSet = 1859 if (SitTargetisSet && !SitTargetOccupied)
1744 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1745 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1746
1747 if (SitTargetisSet && SitTargetUnOccupied)
1748 { 1860 {
1749 //switch the target to this prim 1861 //switch the target to this prim
1750 return part; 1862 return part;
@@ -1758,84 +1870,153 @@ namespace OpenSim.Region.Framework.Scenes
1758 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1870 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1759 { 1871 {
1760 bool autopilot = true; 1872 bool autopilot = true;
1873 Vector3 autopilotTarget = new Vector3();
1874 Quaternion sitOrientation = Quaternion.Identity;
1761 Vector3 pos = new Vector3(); 1875 Vector3 pos = new Vector3();
1762 Quaternion sitOrientation = pSitOrientation;
1763 Vector3 cameraEyeOffset = Vector3.Zero; 1876 Vector3 cameraEyeOffset = Vector3.Zero;
1764 Vector3 cameraAtOffset = Vector3.Zero; 1877 Vector3 cameraAtOffset = Vector3.Zero;
1765 bool forceMouselook = false; 1878 bool forceMouselook = false;
1766 1879
1767 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1880 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1768 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1881 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1769 if (part != null) 1882 if (part == null) return;
1770 { 1883
1771 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1884 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1772 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1885 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1773 1886
1774 // Is a sit target available? 1887 // part is the prim to sit on
1775 Vector3 avSitOffSet = part.SitTargetPosition; 1888 // offset is the world-ref vector distance from that prim center to the click-spot
1776 Quaternion avSitOrientation = part.SitTargetOrientation; 1889 // UUID is the UUID of the Avatar doing the clicking
1777 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1890
1778 1891 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1779 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1892
1780 bool SitTargetisSet = 1893 // Is a sit target available?
1781 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1894 Vector3 avSitOffSet = part.SitTargetPosition;
1782 ( 1895 Quaternion avSitOrientation = part.SitTargetOrientation;
1783 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1896
1784 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1897 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1785 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1898 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1786 ) 1899 Quaternion partRot;
1787 )); 1900// if (part.LinkNum == 1)
1788 1901// { // Root prim of linkset
1789 if (SitTargetisSet && SitTargetUnOccupied) 1902// partRot = part.ParentGroup.RootPart.RotationOffset;
1790 { 1903// }
1791 part.SetAvatarOnSitTarget(UUID); 1904// else
1792 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1905// { // single or child prim
1793 sitOrientation = avSitOrientation; 1906 partRot = part.GetWorldRotation();
1794 autopilot = false; 1907// }
1795 } 1908 Quaternion partIRot = Quaternion.Inverse(partRot);
1796 1909//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1797 pos = part.AbsolutePosition + offset; 1910 // Sit analysis rewritten by KF 091125
1798 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1911 if (SitTargetisSet) // scipted sit
1799 //{ 1912 {
1800 // offset = pos; 1913 if (!part.IsOccupied)
1801 //autopilot = false; 1914 {
1802 //} 1915//Console.WriteLine("Scripted, unoccupied");
1803 if (m_physicsActor != null) 1916 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1804 { 1917 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1805 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1918 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1806 // We can remove the physicsActor until they stand up. 1919 autopilot = false; // Jump direct to scripted llSitPos()
1807 m_sitAvatarHeight = m_physicsActor.Size.Z; 1920 }
1808 1921 else
1809 if (autopilot) 1922 {
1810 { 1923//Console.WriteLine("Scripted, occupied");
1811 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1924 return;
1812 { 1925 }
1813 autopilot = false; 1926 }
1927 else // Not Scripted
1928 {
1929 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1930 {
1931 // large prim & offset, ignore if other Avs sitting
1932// offset.Z -= 0.05f;
1933 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1934 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1935
1936//Console.WriteLine(" offset ={0}", offset);
1937//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1938//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1939
1940 }
1941 else // small offset
1942 {
1943//Console.WriteLine("Small offset");
1944 if (!part.IsOccupied)
1945 {
1946 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1947 autopilotTarget = part.AbsolutePosition;
1948//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1949 }
1950 else return; // occupied small
1951 } // end large/small
1952 } // end Scripted/not
1953 cameraAtOffset = part.GetCameraAtOffset();
1954 cameraEyeOffset = part.GetCameraEyeOffset();
1955 forceMouselook = part.GetForceMouselook();
1956 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1957 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1814 1958
1815 RemoveFromPhysicalScene(); 1959 if (m_physicsActor != null)
1816 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1960 {
1817 } 1961 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1818 } 1962 // We can remove the physicsActor until they stand up.
1819 else 1963 m_sitAvatarHeight = m_physicsActor.Size.Z;
1964 if (autopilot)
1965 { // its not a scripted sit
1966// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1967 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1820 { 1968 {
1969 autopilot = false; // close enough
1970 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1971 Not using the part's position because returning the AV to the last known standing
1972 position is likely to be more friendly, isn't it? */
1821 RemoveFromPhysicalScene(); 1973 RemoveFromPhysicalScene();
1822 } 1974 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1975 } // else the autopilot will get us close
1976 }
1977 else
1978 { // its a scripted sit
1979 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1980 I *am* using the part's position this time because we have no real idea how far away
1981 the avatar is from the sit target. */
1982 RemoveFromPhysicalScene();
1823 } 1983 }
1824
1825 cameraAtOffset = part.GetCameraAtOffset();
1826 cameraEyeOffset = part.GetCameraEyeOffset();
1827 forceMouselook = part.GetForceMouselook();
1828 } 1984 }
1829 1985 else return; // physactor is null!
1830 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1986
1831 m_requestedSitTargetUUID = targetID; 1987 Vector3 offsetr; // = offset * partIRot;
1988 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1989 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1990 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1991 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1992 offsetr = offset * partIRot;
1993//
1994 // else
1995 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1996 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1997 // (offset * partRot);
1998 // }
1999
2000//Console.WriteLine(" ");
2001//Console.WriteLine("link number ={0}", part.LinkNum);
2002//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2003//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2004//Console.WriteLine("Click offst ={0}", offset);
2005//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2006//Console.WriteLine("offsetr ={0}", offsetr);
2007//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2008//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2009
2010 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2011 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1832 // This calls HandleAgentSit twice, once from here, and the client calls 2012 // This calls HandleAgentSit twice, once from here, and the client calls
1833 // HandleAgentSit itself after it gets to the location 2013 // HandleAgentSit itself after it gets to the location
1834 // It doesn't get to the location until we've moved them there though 2014 // It doesn't get to the location until we've moved them there though
1835 // which happens in HandleAgentSit :P 2015 // which happens in HandleAgentSit :P
1836 m_autopilotMoving = autopilot; 2016 m_autopilotMoving = autopilot;
1837 m_autoPilotTarget = pos; 2017 m_autoPilotTarget = autopilotTarget;
1838 m_sitAtAutoTarget = autopilot; 2018 m_sitAtAutoTarget = autopilot;
2019 m_initialSitTarget = autopilotTarget;
1839 if (!autopilot) 2020 if (!autopilot)
1840 HandleAgentSit(remoteClient, UUID); 2021 HandleAgentSit(remoteClient, UUID);
1841 } 2022 }
@@ -2130,31 +2311,66 @@ namespace OpenSim.Region.Framework.Scenes
2130 { 2311 {
2131 if (part != null) 2312 if (part != null)
2132 { 2313 {
2314//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2133 if (part.GetAvatarOnSitTarget() == UUID) 2315 if (part.GetAvatarOnSitTarget() == UUID)
2134 { 2316 {
2317//Console.WriteLine("Scripted Sit");
2318 // Scripted sit
2135 Vector3 sitTargetPos = part.SitTargetPosition; 2319 Vector3 sitTargetPos = part.SitTargetPosition;
2136 Quaternion sitTargetOrient = part.SitTargetOrientation; 2320 Quaternion sitTargetOrient = part.SitTargetOrientation;
2137
2138 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2139 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2140
2141 //Quaternion result = (sitTargetOrient * vq) * nq;
2142
2143 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2321 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2144 m_pos += SIT_TARGET_ADJUSTMENT; 2322 m_pos += SIT_TARGET_ADJUSTMENT;
2145 m_bodyRot = sitTargetOrient; 2323 m_bodyRot = sitTargetOrient;
2146 //Rotation = sitTargetOrient;
2147 m_parentPosition = part.AbsolutePosition; 2324 m_parentPosition = part.AbsolutePosition;
2148 2325 part.IsOccupied = true;
2149 //SendTerseUpdateToAllClients(); 2326Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2150 } 2327 }
2151 else 2328 else
2152 { 2329 {
2153 m_pos -= part.AbsolutePosition; 2330 // if m_avUnscriptedSitPos is zero then Av sits above center
2331 // Else Av sits at m_avUnscriptedSitPos
2332
2333 // Non-scripted sit by Kitto Flora 21Nov09
2334 // Calculate angle of line from prim to Av
2335 Quaternion partIRot;
2336// if (part.LinkNum == 1)
2337// { // Root prim of linkset
2338// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2339// }
2340// else
2341// { // single or child prim
2342 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2343// }
2344 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2345 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2346 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2347 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2348 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2349 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2350 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2351 // Av sits at world euler <0,0, z>, translated by part rotation
2352 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2353
2154 m_parentPosition = part.AbsolutePosition; 2354 m_parentPosition = part.AbsolutePosition;
2155 } 2355 part.IsOccupied = true;
2156 } 2356 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2157 else 2357 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2358 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2359 m_avUnscriptedSitPos; // adds click offset, if any
2360 //Set up raytrace to find top surface of prim
2361 Vector3 size = part.Scale;
2362 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2363 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2364 Vector3 down = new Vector3(0f, 0f, -1f);
2365//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2366 m_scene.PhysicsScene.RaycastWorld(
2367 start, // Vector3 position,
2368 down, // Vector3 direction,
2369 mag, // float length,
2370 SitAltitudeCallback); // retMethod
2371 } // end scripted/not
2372 }
2373 else // no Av
2158 { 2374 {
2159 return; 2375 return;
2160 } 2376 }
@@ -2166,11 +2382,39 @@ namespace OpenSim.Region.Framework.Scenes
2166 2382
2167 Animator.TrySetMovementAnimation(sitAnimation); 2383 Animator.TrySetMovementAnimation(sitAnimation);
2168 SendFullUpdateToAllClients(); 2384 SendFullUpdateToAllClients();
2169 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2170 // So we're also sending a terse update (which has avatar rotation)
2171 // [Update] We do now.
2172 //SendTerseUpdateToAllClients();
2173 } 2385 }
2386
2387 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2388 {
2389 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2390 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2391 if(hitYN)
2392 {
2393 // m_pos = Av offset from prim center to make look like on center
2394 // m_parentPosition = Actual center pos of prim
2395 // collisionPoint = spot on prim where we want to sit
2396 // collisionPoint.Z = global sit surface height
2397 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2398 Quaternion partIRot;
2399// if (part.LinkNum == 1)
2400/// { // Root prim of linkset
2401// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2402// }
2403// else
2404// { // single or child prim
2405 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2406// }
2407 if (m_initialSitTarget != null)
2408 {
2409 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2410 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2411 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2412 m_pos += offset;
2413 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2414 }
2415
2416 }
2417 } // End SitAltitudeCallback KF.
2174 2418
2175 /// <summary> 2419 /// <summary>
2176 /// Event handler for the 'Always run' setting on the client 2420 /// Event handler for the 'Always run' setting on the client
@@ -2200,7 +2444,7 @@ namespace OpenSim.Region.Framework.Scenes
2200 /// </summary> 2444 /// </summary>
2201 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2445 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2202 /// <param name="rotation">The direction in which this avatar should now face. 2446 /// <param name="rotation">The direction in which this avatar should now face.
2203 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2447 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2204 { 2448 {
2205 if (m_isChildAgent) 2449 if (m_isChildAgent)
2206 { 2450 {
@@ -2241,10 +2485,11 @@ namespace OpenSim.Region.Framework.Scenes
2241 Rotation = rotation; 2485 Rotation = rotation;
2242 Vector3 direc = vec * rotation; 2486 Vector3 direc = vec * rotation;
2243 direc.Normalize(); 2487 direc.Normalize();
2488 PhysicsActor actor = m_physicsActor;
2489 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2244 2490
2245 direc *= 0.03f * 128f * m_speedModifier; 2491 direc *= 0.03f * 128f * m_speedModifier;
2246 2492
2247 PhysicsActor actor = m_physicsActor;
2248 if (actor != null) 2493 if (actor != null)
2249 { 2494 {
2250 if (actor.Flying) 2495 if (actor.Flying)
@@ -2266,18 +2511,25 @@ namespace OpenSim.Region.Framework.Scenes
2266 { 2511 {
2267 if (direc.Z > 2.0f) 2512 if (direc.Z > 2.0f)
2268 { 2513 {
2269 direc.Z *= 3.0f; 2514 if(m_animator.m_animTickJump == -1)
2270 2515 {
2271 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2516 direc.Z *= 3.0f; // jump
2272 Animator.TrySetMovementAnimation("PREJUMP"); 2517 }
2273 Animator.TrySetMovementAnimation("JUMP"); 2518 else
2519 {
2520 direc.Z *= 0.1f; // prejump
2521 }
2522 /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2523 Animator.TrySetMovementAnimation("PREJUMP");
2524 Animator.TrySetMovementAnimation("JUMP");
2525 */
2274 } 2526 }
2275 } 2527 }
2276 } 2528 }
2277 2529
2278 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2530 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2279 m_forceToApply = direc; 2531 m_forceToApply = direc;
2280 2532 m_isNudging = Nudging;
2281 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2533 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2282 } 2534 }
2283 2535
@@ -2292,7 +2544,7 @@ namespace OpenSim.Region.Framework.Scenes
2292 const float POSITION_TOLERANCE = 0.05f; 2544 const float POSITION_TOLERANCE = 0.05f;
2293 //const int TIME_MS_TOLERANCE = 3000; 2545 //const int TIME_MS_TOLERANCE = 3000;
2294 2546
2295 SendPrimUpdates(); 2547
2296 2548
2297 if (m_isChildAgent == false) 2549 if (m_isChildAgent == false)
2298 { 2550 {
@@ -2322,6 +2574,9 @@ namespace OpenSim.Region.Framework.Scenes
2322 CheckForBorderCrossing(); 2574 CheckForBorderCrossing();
2323 CheckForSignificantMovement(); // sends update to the modules. 2575 CheckForSignificantMovement(); // sends update to the modules.
2324 } 2576 }
2577
2578 //Sending prim updates AFTER the avatar terse updates are sent
2579 SendPrimUpdates();
2325 } 2580 }
2326 2581
2327 #endregion 2582 #endregion
@@ -3094,6 +3349,7 @@ namespace OpenSim.Region.Framework.Scenes
3094 m_callbackURI = cAgent.CallbackURI; 3349 m_callbackURI = cAgent.CallbackURI;
3095 3350
3096 m_pos = cAgent.Position; 3351 m_pos = cAgent.Position;
3352
3097 m_velocity = cAgent.Velocity; 3353 m_velocity = cAgent.Velocity;
3098 m_CameraCenter = cAgent.Center; 3354 m_CameraCenter = cAgent.Center;
3099 //m_avHeight = cAgent.Size.Z; 3355 //m_avHeight = cAgent.Size.Z;
@@ -3182,14 +3438,25 @@ namespace OpenSim.Region.Framework.Scenes
3182 { 3438 {
3183 if (m_forceToApply.HasValue) 3439 if (m_forceToApply.HasValue)
3184 { 3440 {
3185 Vector3 force = m_forceToApply.Value;
3186 3441
3442 Vector3 force = m_forceToApply.Value;
3187 m_updateflag = true; 3443 m_updateflag = true;
3188// movementvector = force;
3189 Velocity = force; 3444 Velocity = force;
3190 3445
3191 m_forceToApply = null; 3446 m_forceToApply = null;
3192 } 3447 }
3448 else
3449 {
3450 if (m_isNudging)
3451 {
3452 Vector3 force = Vector3.Zero;
3453
3454 m_updateflag = true;
3455 Velocity = force;
3456 m_isNudging = false;
3457 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3458 }
3459 }
3193 } 3460 }
3194 3461
3195 public override void SetText(string text, Vector3 color, double alpha) 3462 public override void SetText(string text, Vector3 color, double alpha)
@@ -3240,18 +3507,29 @@ namespace OpenSim.Region.Framework.Scenes
3240 { 3507 {
3241 if (e == null) 3508 if (e == null)
3242 return; 3509 return;
3243 3510
3244 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3511 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3245 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3246 // as of this comment the interval is set in AddToPhysicalScene 3512 // as of this comment the interval is set in AddToPhysicalScene
3247 if (Animator!=null) 3513 if (Animator!=null)
3248 Animator.UpdateMovementAnimations(); 3514 {
3515 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3516 { // else its will lock out other animation changes, like ground sit.
3517 Animator.UpdateMovementAnimations();
3518 m_updateCount--;
3519 }
3520 }
3249 3521
3250 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3522 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3251 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3523 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3252 3524
3253 CollisionPlane = Vector4.UnitW; 3525 CollisionPlane = Vector4.UnitW;
3254 3526
3527 if (m_lastColCount != coldata.Count)
3528 {
3529 m_updateCount = UPDATE_COUNT;
3530 m_lastColCount = coldata.Count;
3531 }
3532
3255 if (coldata.Count != 0 && Animator != null) 3533 if (coldata.Count != 0 && Animator != null)
3256 { 3534 {
3257 switch (Animator.CurrentMovementAnimation) 3535 switch (Animator.CurrentMovementAnimation)
@@ -3455,7 +3733,10 @@ namespace OpenSim.Region.Framework.Scenes
3455 m_scene = scene; 3733 m_scene = scene;
3456 3734
3457 RegisterToEvents(); 3735 RegisterToEvents();
3458 3736 if (m_controllingClient != null)
3737 {
3738 m_controllingClient.ProcessPendingPackets();
3739 }
3459 /* 3740 /*
3460 AbsolutePosition = client.StartPos; 3741 AbsolutePosition = client.StartPos;
3461 3742
@@ -3686,6 +3967,32 @@ namespace OpenSim.Region.Framework.Scenes
3686 return; 3967 return;
3687 } 3968 }
3688 3969
3970 XmlDocument doc = new XmlDocument();
3971 string stateData = String.Empty;
3972
3973 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
3974 if (attServ != null)
3975 {
3976 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
3977 stateData = attServ.Get(ControllingClient.AgentId.ToString());
3978 doc.LoadXml(stateData);
3979 }
3980
3981 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
3982
3983 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
3984 if (nodes.Count > 0)
3985 {
3986 foreach (XmlNode n in nodes)
3987 {
3988 XmlElement elem = (XmlElement)n;
3989 string itemID = elem.GetAttribute("ItemID");
3990 string xml = elem.InnerXml;
3991
3992 itemData[new UUID(itemID)] = xml;
3993 }
3994 }
3995
3689 List<int> attPoints = m_appearance.GetAttachedPoints(); 3996 List<int> attPoints = m_appearance.GetAttachedPoints();
3690 foreach (int p in attPoints) 3997 foreach (int p in attPoints)
3691 { 3998 {
@@ -3705,9 +4012,26 @@ namespace OpenSim.Region.Framework.Scenes
3705 4012
3706 try 4013 try
3707 { 4014 {
3708 // Rez from inventory 4015 string xmlData;
3709 UUID asset 4016 XmlDocument d = new XmlDocument();
3710 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4017 UUID asset;
4018 if (itemData.TryGetValue(itemID, out xmlData))
4019 {
4020 d.LoadXml(xmlData);
4021 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4022
4023 // Rez from inventory
4024 asset
4025 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4026
4027 }
4028 else
4029 {
4030 // Rez from inventory (with a null doc to let
4031 // CHANGED_OWNER happen)
4032 asset
4033 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4034 }
3711 4035
3712 m_log.InfoFormat( 4036 m_log.InfoFormat(
3713 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", 4037 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
@@ -3744,5 +4068,16 @@ namespace OpenSim.Region.Framework.Scenes
3744 m_reprioritization_called = false; 4068 m_reprioritization_called = false;
3745 } 4069 }
3746 } 4070 }
4071
4072 private Vector3 Quat2Euler(Quaternion rot){
4073 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4074 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4075 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4076 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4077 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4078 return(new Vector3(x,y,z));
4079 }
4080
4081
3747 } 4082 }
3748} 4083}