aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs679
1 files changed, 507 insertions, 172 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 45375b0..e3bbe8a 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Xml;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using System.Timers; 32using System.Timers;
@@ -73,7 +74,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 74// {
74// m_log.Debug("[ScenePresence] Destructor called"); 75// m_log.Debug("[ScenePresence] Destructor called");
75// } 76// }
76 77
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 78 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 79
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 80 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +90,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 90 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 91 /// issue #1716
91 /// </summary> 92 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 93// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
94 // Value revised by KF 091121 by comparison with SL.
95 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 96
94 public UUID currentParcelUUID = UUID.Zero; 97 public UUID currentParcelUUID = UUID.Zero;
95 98
@@ -123,8 +126,11 @@ namespace OpenSim.Region.Framework.Scenes
123 public Vector3 lastKnownAllowedPosition; 126 public Vector3 lastKnownAllowedPosition;
124 public bool sentMessageAboutRestrictedParcelFlyingDown; 127 public bool sentMessageAboutRestrictedParcelFlyingDown;
125 public Vector4 CollisionPlane = Vector4.UnitW; 128 public Vector4 CollisionPlane = Vector4.UnitW;
126 129
130 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
131 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
127 private Vector3 m_lastPosition; 132 private Vector3 m_lastPosition;
133 private Vector3 m_lastWorldPosition;
128 private Quaternion m_lastRotation; 134 private Quaternion m_lastRotation;
129 private Vector3 m_lastVelocity; 135 private Vector3 m_lastVelocity;
130 //private int m_lastTerseSent; 136 //private int m_lastTerseSent;
@@ -157,7 +163,6 @@ namespace OpenSim.Region.Framework.Scenes
157 private int m_perfMonMS; 163 private int m_perfMonMS;
158 164
159 private bool m_setAlwaysRun; 165 private bool m_setAlwaysRun;
160
161 private bool m_forceFly; 166 private bool m_forceFly;
162 private bool m_flyDisabled; 167 private bool m_flyDisabled;
163 168
@@ -183,7 +188,8 @@ namespace OpenSim.Region.Framework.Scenes
183 protected RegionInfo m_regionInfo; 188 protected RegionInfo m_regionInfo;
184 protected ulong crossingFromRegion; 189 protected ulong crossingFromRegion;
185 190
186 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 191 private readonly Vector3[] Dir_Vectors = new Vector3[11];
192 private bool m_isNudging = false;
187 193
188 // Position of agent's camera in world (region cordinates) 194 // Position of agent's camera in world (region cordinates)
189 protected Vector3 m_CameraCenter; 195 protected Vector3 m_CameraCenter;
@@ -208,6 +214,7 @@ namespace OpenSim.Region.Framework.Scenes
208 private bool m_autopilotMoving; 214 private bool m_autopilotMoving;
209 private Vector3 m_autoPilotTarget; 215 private Vector3 m_autoPilotTarget;
210 private bool m_sitAtAutoTarget; 216 private bool m_sitAtAutoTarget;
217 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
211 218
212 private string m_nextSitAnimation = String.Empty; 219 private string m_nextSitAnimation = String.Empty;
213 220
@@ -218,6 +225,9 @@ namespace OpenSim.Region.Framework.Scenes
218 private bool m_followCamAuto; 225 private bool m_followCamAuto;
219 226
220 private int m_movementUpdateCount; 227 private int m_movementUpdateCount;
228 private int m_lastColCount = -1; //KF: Look for Collision chnages
229 private int m_updateCount = 0; //KF: Update Anims for a while
230 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
221 private const int NumMovementsBetweenRayCast = 5; 231 private const int NumMovementsBetweenRayCast = 5;
222 232
223 private bool CameraConstraintActive; 233 private bool CameraConstraintActive;
@@ -245,7 +255,9 @@ namespace OpenSim.Region.Framework.Scenes
245 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 255 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
246 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 256 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
247 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 257 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
248 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 258 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
259 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
260 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 261 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
250 } 262 }
251 263
@@ -452,7 +464,8 @@ namespace OpenSim.Region.Framework.Scenes
452 get 464 get
453 { 465 {
454 PhysicsActor actor = m_physicsActor; 466 PhysicsActor actor = m_physicsActor;
455 if (actor != null) 467// if (actor != null)
468 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
456 m_pos = actor.Position; 469 m_pos = actor.Position;
457 470
458 return m_parentPosition + m_pos; 471 return m_parentPosition + m_pos;
@@ -473,7 +486,8 @@ namespace OpenSim.Region.Framework.Scenes
473 } 486 }
474 } 487 }
475 488
476 m_pos = value; 489 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
490 m_pos = value;
477 m_parentPosition = Vector3.Zero; 491 m_parentPosition = Vector3.Zero;
478 } 492 }
479 } 493 }
@@ -671,7 +685,7 @@ namespace OpenSim.Region.Framework.Scenes
671 CreateSceneViewer(); 685 CreateSceneViewer();
672 m_animator = new ScenePresenceAnimator(this); 686 m_animator = new ScenePresenceAnimator(this);
673 } 687 }
674 688
675 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 689 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
676 { 690 {
677 m_rootRegionHandle = reginfo.RegionHandle; 691 m_rootRegionHandle = reginfo.RegionHandle;
@@ -703,16 +717,16 @@ namespace OpenSim.Region.Framework.Scenes
703 m_reprioritization_timer.AutoReset = false; 717 m_reprioritization_timer.AutoReset = false;
704 718
705 AdjustKnownSeeds(); 719 AdjustKnownSeeds();
706
707 // TODO: I think, this won't send anything, as we are still a child here...
708 Animator.TrySetMovementAnimation("STAND"); 720 Animator.TrySetMovementAnimation("STAND");
709
710 // we created a new ScenePresence (a new child agent) in a fresh region. 721 // we created a new ScenePresence (a new child agent) in a fresh region.
711 // Request info about all the (root) agents in this region 722 // Request info about all the (root) agents in this region
712 // Note: This won't send data *to* other clients in that region (children don't send) 723 // Note: This won't send data *to* other clients in that region (children don't send)
713 SendInitialFullUpdateToAllClients(); 724 SendInitialFullUpdateToAllClients();
714
715 RegisterToEvents(); 725 RegisterToEvents();
726 if (m_controllingClient != null)
727 {
728 m_controllingClient.ProcessPendingPackets();
729 }
716 SetDirectionVectors(); 730 SetDirectionVectors();
717 } 731 }
718 732
@@ -762,25 +776,47 @@ namespace OpenSim.Region.Framework.Scenes
762 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 776 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
763 Dir_Vectors[4] = Vector3.UnitZ; //UP 777 Dir_Vectors[4] = Vector3.UnitZ; //UP
764 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 778 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
765 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 779 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
766 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 780 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
767 Dir_Vectors[7] = -Vector3.UnitX; //BACK 781 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
782 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
783 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
768 } 784 }
769 785
770 private Vector3[] GetWalkDirectionVectors() 786 private Vector3[] GetWalkDirectionVectors()
771 { 787 {
772 Vector3[] vector = new Vector3[9]; 788 Vector3[] vector = new Vector3[11];
773 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 789 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
774 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 790 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
775 vector[2] = Vector3.UnitY; //LEFT 791 vector[2] = Vector3.UnitY; //LEFT
776 vector[3] = -Vector3.UnitY; //RIGHT 792 vector[3] = -Vector3.UnitY; //RIGHT
777 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 793 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
778 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 794 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
779 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 795 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
780 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 796 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
781 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 797 vector[8] = Vector3.UnitY; //LEFT_NUDGE
798 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
799 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
782 return vector; 800 return vector;
783 } 801 }
802
803 private bool[] GetDirectionIsNudge()
804 {
805 bool[] isNudge = new bool[11];
806 isNudge[0] = false; //FORWARD
807 isNudge[1] = false; //BACK
808 isNudge[2] = false; //LEFT
809 isNudge[3] = false; //RIGHT
810 isNudge[4] = false; //UP
811 isNudge[5] = false; //DOWN
812 isNudge[6] = true; //FORWARD_NUDGE
813 isNudge[7] = true; //BACK_NUDGE
814 isNudge[8] = true; //LEFT_NUDGE
815 isNudge[9] = true; //RIGHT_NUDGE
816 isNudge[10] = true; //DOWN_Nudge
817 return isNudge;
818 }
819
784 820
785 #endregion 821 #endregion
786 822
@@ -823,7 +859,6 @@ namespace OpenSim.Region.Framework.Scenes
823 m_grouptitle = gm.GetGroupTitle(m_uuid); 859 m_grouptitle = gm.GetGroupTitle(m_uuid);
824 860
825 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; 861 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle;
826
827 m_scene.SetRootAgentScene(m_uuid); 862 m_scene.SetRootAgentScene(m_uuid);
828 863
829 // Moved this from SendInitialData to ensure that m_appearance is initialized 864 // Moved this from SendInitialData to ensure that m_appearance is initialized
@@ -842,6 +877,52 @@ namespace OpenSim.Region.Framework.Scenes
842 pos.Y = crossedBorder.BorderLine.Z - 1; 877 pos.Y = crossedBorder.BorderLine.Z - 1;
843 } 878 }
844 879
880 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
881 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
882 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
883 if (KnownChildRegionHandles.Count == 0)
884 {
885 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
886 if (land != null)
887 {
888 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
889 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)
890 {
891 pos = land.LandData.UserLocation;
892 }
893 }
894 }
895
896 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
897 {
898 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
899
900 if (pos.X < 0)
901 {
902 emergencyPos.X = (int)Constants.RegionSize + pos.X;
903 if (!(pos.Y < 0))
904 emergencyPos.Y = pos.Y;
905 if (!(pos.Z < 0))
906 emergencyPos.Z = pos.Z;
907 }
908 if (pos.Y < 0)
909 {
910 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
911 if (!(pos.X < 0))
912 emergencyPos.X = pos.X;
913 if (!(pos.Z < 0))
914 emergencyPos.Z = pos.Z;
915 }
916 if (pos.Z < 0)
917 {
918 emergencyPos.Z = 128;
919 if (!(pos.Y < 0))
920 emergencyPos.Y = pos.Y;
921 if (!(pos.X < 0))
922 emergencyPos.X = pos.X;
923 }
924 }
925
845 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 926 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
846 { 927 {
847 m_log.WarnFormat( 928 m_log.WarnFormat(
@@ -974,9 +1055,10 @@ namespace OpenSim.Region.Framework.Scenes
974 public void Teleport(Vector3 pos) 1055 public void Teleport(Vector3 pos)
975 { 1056 {
976 bool isFlying = false; 1057 bool isFlying = false;
1058
977 if (m_physicsActor != null) 1059 if (m_physicsActor != null)
978 isFlying = m_physicsActor.Flying; 1060 isFlying = m_physicsActor.Flying;
979 1061
980 RemoveFromPhysicalScene(); 1062 RemoveFromPhysicalScene();
981 Velocity = Vector3.Zero; 1063 Velocity = Vector3.Zero;
982 AbsolutePosition = pos; 1064 AbsolutePosition = pos;
@@ -988,6 +1070,7 @@ namespace OpenSim.Region.Framework.Scenes
988 } 1070 }
989 1071
990 SendTerseUpdateToAllClients(); 1072 SendTerseUpdateToAllClients();
1073
991 } 1074 }
992 1075
993 public void TeleportWithMomentum(Vector3 pos) 1076 public void TeleportWithMomentum(Vector3 pos)
@@ -1032,7 +1115,9 @@ namespace OpenSim.Region.Framework.Scenes
1032 { 1115 {
1033 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1116 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1034 } 1117 }
1035 1118
1119 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1120
1036 ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position); 1121 ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position);
1037 //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1122 //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1038 // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1123 // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
@@ -1119,7 +1204,6 @@ namespace OpenSim.Region.Framework.Scenes
1119 pos.Z = ground + 1.5f; 1204 pos.Z = ground + 1.5f;
1120 AbsolutePosition = pos; 1205 AbsolutePosition = pos;
1121 } 1206 }
1122
1123 m_isChildAgent = false; 1207 m_isChildAgent = false;
1124 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1208 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1125 MakeRootAgent(AbsolutePosition, m_flying); 1209 MakeRootAgent(AbsolutePosition, m_flying);
@@ -1218,6 +1302,7 @@ namespace OpenSim.Region.Framework.Scenes
1218 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1302 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1219 1303
1220 m_pos = m_LastFinitePos; 1304 m_pos = m_LastFinitePos;
1305
1221 if (!m_pos.IsFinite()) 1306 if (!m_pos.IsFinite())
1222 { 1307 {
1223 m_pos.X = 127f; 1308 m_pos.X = 127f;
@@ -1284,7 +1369,6 @@ namespace OpenSim.Region.Framework.Scenes
1284 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1369 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1285 } 1370 }
1286 } 1371 }
1287
1288 lock (scriptedcontrols) 1372 lock (scriptedcontrols)
1289 { 1373 {
1290 if (scriptedcontrols.Count > 0) 1374 if (scriptedcontrols.Count > 0)
@@ -1299,6 +1383,9 @@ namespace OpenSim.Region.Framework.Scenes
1299 1383
1300 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1384 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1301 { 1385 {
1386 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1387 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1388
1302 // TODO: This doesn't prevent the user from walking yet. 1389 // TODO: This doesn't prevent the user from walking yet.
1303 // Setting parent ID would fix this, if we knew what value 1390 // Setting parent ID would fix this, if we knew what value
1304 // to use. Or we could add a m_isSitting variable. 1391 // to use. Or we could add a m_isSitting variable.
@@ -1353,6 +1440,11 @@ namespace OpenSim.Region.Framework.Scenes
1353 update_rotation = true; 1440 update_rotation = true;
1354 } 1441 }
1355 1442
1443 //guilty until proven innocent..
1444 bool Nudging = true;
1445 //Basically, if there is at least one non-nudge control then we don't need
1446 //to worry about stopping the avatar
1447
1356 if (m_parentID == 0) 1448 if (m_parentID == 0)
1357 { 1449 {
1358 bool bAllowUpdateMoveToPosition = false; 1450 bool bAllowUpdateMoveToPosition = false;
@@ -1367,9 +1459,12 @@ namespace OpenSim.Region.Framework.Scenes
1367 else 1459 else
1368 dirVectors = Dir_Vectors; 1460 dirVectors = Dir_Vectors;
1369 1461
1370 // The fact that m_movementflag is a byte needs to be fixed 1462 bool[] isNudge = GetDirectionIsNudge();
1371 // it really should be a uint 1463
1372 uint nudgehack = 250; 1464
1465
1466
1467
1373 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1468 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1374 { 1469 {
1375 if (((uint)flags & (uint)DCF) != 0) 1470 if (((uint)flags & (uint)DCF) != 0)
@@ -1379,40 +1474,28 @@ namespace OpenSim.Region.Framework.Scenes
1379 try 1474 try
1380 { 1475 {
1381 agent_control_v3 += dirVectors[i]; 1476 agent_control_v3 += dirVectors[i];
1382 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1477 if (isNudge[i] == false)
1478 {
1479 Nudging = false;
1480 }
1383 } 1481 }
1384 catch (IndexOutOfRangeException) 1482 catch (IndexOutOfRangeException)
1385 { 1483 {
1386 // Why did I get this? 1484 // Why did I get this?
1387 } 1485 }
1388 1486
1389 if ((m_movementflag & (byte)(uint)DCF) == 0) 1487 if ((m_movementflag & (uint)DCF) == 0)
1390 { 1488 {
1391 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1392 {
1393 m_movementflag |= (byte)nudgehack;
1394 }
1395 m_movementflag += (byte)(uint)DCF; 1489 m_movementflag += (byte)(uint)DCF;
1396 update_movementflag = true; 1490 update_movementflag = true;
1397 } 1491 }
1398 } 1492 }
1399 else 1493 else
1400 { 1494 {
1401 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1495 if ((m_movementflag & (uint)DCF) != 0)
1402 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1403 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1404 ) // This or is for Nudge forward
1405 { 1496 {
1406 m_movementflag -= ((byte)(uint)DCF); 1497 m_movementflag -= (byte)(uint)DCF;
1407
1408 update_movementflag = true; 1498 update_movementflag = true;
1409 /*
1410 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1411 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1412 {
1413 m_log.Debug("Removed Hack flag");
1414 }
1415 */
1416 } 1499 }
1417 else 1500 else
1418 { 1501 {
@@ -1421,7 +1504,6 @@ namespace OpenSim.Region.Framework.Scenes
1421 } 1504 }
1422 i++; 1505 i++;
1423 } 1506 }
1424
1425 //Paupaw:Do Proper PID for Autopilot here 1507 //Paupaw:Do Proper PID for Autopilot here
1426 if (bResetMoveToPosition) 1508 if (bResetMoveToPosition)
1427 { 1509 {
@@ -1456,6 +1538,9 @@ namespace OpenSim.Region.Framework.Scenes
1456 // Ignore z component of vector 1538 // Ignore z component of vector
1457 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1539 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1458 LocalVectorToTarget2D.Normalize(); 1540 LocalVectorToTarget2D.Normalize();
1541
1542 //We're not nudging
1543 Nudging = false;
1459 agent_control_v3 += LocalVectorToTarget2D; 1544 agent_control_v3 += LocalVectorToTarget2D;
1460 1545
1461 // update avatar movement flags. the avatar coordinate system is as follows: 1546 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1544,13 +1629,13 @@ namespace OpenSim.Region.Framework.Scenes
1544 // m_log.DebugFormat( 1629 // m_log.DebugFormat(
1545 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1630 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1546 1631
1547 AddNewMovement(agent_control_v3, q); 1632 AddNewMovement(agent_control_v3, q, Nudging);
1548 1633
1549 1634
1550 } 1635 }
1551 } 1636 }
1552 1637
1553 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1638 if (update_movementflag && !SitGround)
1554 Animator.UpdateMovementAnimations(); 1639 Animator.UpdateMovementAnimations();
1555 1640
1556 m_scene.EventManager.TriggerOnClientMovement(this); 1641 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1565,7 +1650,6 @@ namespace OpenSim.Region.Framework.Scenes
1565 m_sitAtAutoTarget = false; 1650 m_sitAtAutoTarget = false;
1566 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1651 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1567 //proxy.PCode = (byte)PCode.ParticleSystem; 1652 //proxy.PCode = (byte)PCode.ParticleSystem;
1568
1569 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1653 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1570 proxyObjectGroup.AttachToScene(m_scene); 1654 proxyObjectGroup.AttachToScene(m_scene);
1571 1655
@@ -1607,7 +1691,7 @@ namespace OpenSim.Region.Framework.Scenes
1607 } 1691 }
1608 m_moveToPositionInProgress = true; 1692 m_moveToPositionInProgress = true;
1609 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1693 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1610 } 1694 }
1611 catch (Exception ex) 1695 catch (Exception ex)
1612 { 1696 {
1613 //Why did I get this error? 1697 //Why did I get this error?
@@ -1629,7 +1713,7 @@ namespace OpenSim.Region.Framework.Scenes
1629 Velocity = Vector3.Zero; 1713 Velocity = Vector3.Zero;
1630 SendFullUpdateToAllClients(); 1714 SendFullUpdateToAllClients();
1631 1715
1632 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1716 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1633 } 1717 }
1634 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1718 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1635 m_requestedSitTargetUUID = UUID.Zero; 1719 m_requestedSitTargetUUID = UUID.Zero;
@@ -1666,50 +1750,82 @@ namespace OpenSim.Region.Framework.Scenes
1666 1750
1667 if (m_parentID != 0) 1751 if (m_parentID != 0)
1668 { 1752 {
1669 m_log.Debug("StandupCode Executed");
1670 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1753 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1671 if (part != null) 1754 if (part != null)
1672 { 1755 {
1756 part.TaskInventory.LockItemsForRead(true);
1673 TaskInventoryDictionary taskIDict = part.TaskInventory; 1757 TaskInventoryDictionary taskIDict = part.TaskInventory;
1674 if (taskIDict != null) 1758 if (taskIDict != null)
1675 { 1759 {
1676 lock (taskIDict) 1760 foreach (UUID taskID in taskIDict.Keys)
1677 { 1761 {
1678 foreach (UUID taskID in taskIDict.Keys) 1762 UnRegisterControlEventsToScript(LocalId, taskID);
1679 { 1763 taskIDict[taskID].PermsMask &= ~(
1680 UnRegisterControlEventsToScript(LocalId, taskID); 1764 2048 | //PERMISSION_CONTROL_CAMERA
1681 taskIDict[taskID].PermsMask &= ~( 1765 4); // PERMISSION_TAKE_CONTROLS
1682 2048 | //PERMISSION_CONTROL_CAMERA
1683 4); // PERMISSION_TAKE_CONTROLS
1684 }
1685 } 1766 }
1686
1687 } 1767 }
1768 part.TaskInventory.LockItemsForRead(false);
1688 // Reset sit target. 1769 // Reset sit target.
1689 if (part.GetAvatarOnSitTarget() == UUID) 1770 if (part.GetAvatarOnSitTarget() == UUID)
1690 part.SetAvatarOnSitTarget(UUID.Zero); 1771 part.SetAvatarOnSitTarget(UUID.Zero);
1691
1692 m_parentPosition = part.GetWorldPosition(); 1772 m_parentPosition = part.GetWorldPosition();
1693 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1773 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1694 } 1774 }
1775 // part.GetWorldRotation() is the rotation of the object being sat on
1776 // Rotation is the sittiing Av's rotation
1777
1778 Quaternion partRot;
1779// if (part.LinkNum == 1)
1780// { // Root prim of linkset
1781// partRot = part.ParentGroup.RootPart.RotationOffset;
1782// }
1783// else
1784// { // single or child prim
1785
1786// }
1787 if (part == null) //CW: Part may be gone. llDie() for example.
1788 {
1789 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1790 }
1791 else
1792 {
1793 partRot = part.GetWorldRotation();
1794 }
1695 1795
1796 Quaternion partIRot = Quaternion.Inverse(partRot);
1797
1798 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1799 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1800
1801
1696 if (m_physicsActor == null) 1802 if (m_physicsActor == null)
1697 { 1803 {
1698 AddToPhysicalScene(false); 1804 AddToPhysicalScene(false);
1699 } 1805 }
1700 1806 //CW: If the part isn't null then we can set the current position
1701 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1807 if (part != null)
1702 m_parentPosition = Vector3.Zero; 1808 {
1703 1809 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1704 m_parentID = 0; 1810 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1811 part.IsOccupied = false;
1812 }
1813 else
1814 {
1815 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1816 AbsolutePosition = m_lastWorldPosition;
1817 }
1818
1819 m_parentPosition = Vector3.Zero;
1820 m_parentID = 0;
1705 SendFullUpdateToAllClients(); 1821 SendFullUpdateToAllClients();
1706 m_requestedSitTargetID = 0; 1822 m_requestedSitTargetID = 0;
1823
1707 if ((m_physicsActor != null) && (m_avHeight > 0)) 1824 if ((m_physicsActor != null) && (m_avHeight > 0))
1708 { 1825 {
1709 SetHeight(m_avHeight); 1826 SetHeight(m_avHeight);
1710 } 1827 }
1711 } 1828 }
1712
1713 Animator.TrySetMovementAnimation("STAND"); 1829 Animator.TrySetMovementAnimation("STAND");
1714 } 1830 }
1715 1831
@@ -1740,13 +1856,9 @@ namespace OpenSim.Region.Framework.Scenes
1740 Vector3 avSitOffSet = part.SitTargetPosition; 1856 Vector3 avSitOffSet = part.SitTargetPosition;
1741 Quaternion avSitOrientation = part.SitTargetOrientation; 1857 Quaternion avSitOrientation = part.SitTargetOrientation;
1742 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1858 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1743 1859 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1744 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1860 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1745 bool SitTargetisSet = 1861 if (SitTargetisSet && !SitTargetOccupied)
1746 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1747 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1748
1749 if (SitTargetisSet && SitTargetUnOccupied)
1750 { 1862 {
1751 //switch the target to this prim 1863 //switch the target to this prim
1752 return part; 1864 return part;
@@ -1760,84 +1872,153 @@ namespace OpenSim.Region.Framework.Scenes
1760 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1872 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1761 { 1873 {
1762 bool autopilot = true; 1874 bool autopilot = true;
1875 Vector3 autopilotTarget = new Vector3();
1876 Quaternion sitOrientation = Quaternion.Identity;
1763 Vector3 pos = new Vector3(); 1877 Vector3 pos = new Vector3();
1764 Quaternion sitOrientation = pSitOrientation;
1765 Vector3 cameraEyeOffset = Vector3.Zero; 1878 Vector3 cameraEyeOffset = Vector3.Zero;
1766 Vector3 cameraAtOffset = Vector3.Zero; 1879 Vector3 cameraAtOffset = Vector3.Zero;
1767 bool forceMouselook = false; 1880 bool forceMouselook = false;
1768 1881
1769 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1882 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1770 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1883 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1771 if (part != null) 1884 if (part == null) return;
1772 { 1885
1773 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1886 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1774 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1887 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1775 1888
1776 // Is a sit target available? 1889 // part is the prim to sit on
1777 Vector3 avSitOffSet = part.SitTargetPosition; 1890 // offset is the world-ref vector distance from that prim center to the click-spot
1778 Quaternion avSitOrientation = part.SitTargetOrientation; 1891 // UUID is the UUID of the Avatar doing the clicking
1779 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1892
1780 1893 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1781 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1894
1782 bool SitTargetisSet = 1895 // Is a sit target available?
1783 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1896 Vector3 avSitOffSet = part.SitTargetPosition;
1784 ( 1897 Quaternion avSitOrientation = part.SitTargetOrientation;
1785 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1898
1786 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1899 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1787 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1900 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1788 ) 1901 Quaternion partRot;
1789 )); 1902// if (part.LinkNum == 1)
1790 1903// { // Root prim of linkset
1791 if (SitTargetisSet && SitTargetUnOccupied) 1904// partRot = part.ParentGroup.RootPart.RotationOffset;
1792 { 1905// }
1793 part.SetAvatarOnSitTarget(UUID); 1906// else
1794 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1907// { // single or child prim
1795 sitOrientation = avSitOrientation; 1908 partRot = part.GetWorldRotation();
1796 autopilot = false; 1909// }
1797 } 1910 Quaternion partIRot = Quaternion.Inverse(partRot);
1798 1911//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1799 pos = part.AbsolutePosition + offset; 1912 // Sit analysis rewritten by KF 091125
1800 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1913 if (SitTargetisSet) // scipted sit
1801 //{ 1914 {
1802 // offset = pos; 1915 if (!part.IsOccupied)
1803 //autopilot = false; 1916 {
1804 //} 1917//Console.WriteLine("Scripted, unoccupied");
1805 if (m_physicsActor != null) 1918 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1806 { 1919 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1807 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1920 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1808 // We can remove the physicsActor until they stand up. 1921 autopilot = false; // Jump direct to scripted llSitPos()
1809 m_sitAvatarHeight = m_physicsActor.Size.Z; 1922 }
1810 1923 else
1811 if (autopilot) 1924 {
1812 { 1925//Console.WriteLine("Scripted, occupied");
1813 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1926 return;
1814 { 1927 }
1815 autopilot = false; 1928 }
1929 else // Not Scripted
1930 {
1931 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1932 {
1933 // large prim & offset, ignore if other Avs sitting
1934// offset.Z -= 0.05f;
1935 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1936 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1937
1938//Console.WriteLine(" offset ={0}", offset);
1939//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1940//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1941
1942 }
1943 else // small offset
1944 {
1945//Console.WriteLine("Small offset");
1946 if (!part.IsOccupied)
1947 {
1948 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1949 autopilotTarget = part.AbsolutePosition;
1950//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1951 }
1952 else return; // occupied small
1953 } // end large/small
1954 } // end Scripted/not
1955 cameraAtOffset = part.GetCameraAtOffset();
1956 cameraEyeOffset = part.GetCameraEyeOffset();
1957 forceMouselook = part.GetForceMouselook();
1958 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1959 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1816 1960
1817 RemoveFromPhysicalScene(); 1961 if (m_physicsActor != null)
1818 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1962 {
1819 } 1963 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1820 } 1964 // We can remove the physicsActor until they stand up.
1821 else 1965 m_sitAvatarHeight = m_physicsActor.Size.Z;
1966 if (autopilot)
1967 { // its not a scripted sit
1968// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1969 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1822 { 1970 {
1971 autopilot = false; // close enough
1972 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1973 Not using the part's position because returning the AV to the last known standing
1974 position is likely to be more friendly, isn't it? */
1823 RemoveFromPhysicalScene(); 1975 RemoveFromPhysicalScene();
1824 } 1976 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1977 } // else the autopilot will get us close
1978 }
1979 else
1980 { // its a scripted sit
1981 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1982 I *am* using the part's position this time because we have no real idea how far away
1983 the avatar is from the sit target. */
1984 RemoveFromPhysicalScene();
1825 } 1985 }
1826
1827 cameraAtOffset = part.GetCameraAtOffset();
1828 cameraEyeOffset = part.GetCameraEyeOffset();
1829 forceMouselook = part.GetForceMouselook();
1830 } 1986 }
1831 1987 else return; // physactor is null!
1832 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1988
1833 m_requestedSitTargetUUID = targetID; 1989 Vector3 offsetr; // = offset * partIRot;
1990 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1991 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1992 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1993 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1994 offsetr = offset * partIRot;
1995//
1996 // else
1997 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1998 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1999 // (offset * partRot);
2000 // }
2001
2002//Console.WriteLine(" ");
2003//Console.WriteLine("link number ={0}", part.LinkNum);
2004//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2005//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2006//Console.WriteLine("Click offst ={0}", offset);
2007//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2008//Console.WriteLine("offsetr ={0}", offsetr);
2009//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2010//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2011
2012 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2013 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1834 // This calls HandleAgentSit twice, once from here, and the client calls 2014 // This calls HandleAgentSit twice, once from here, and the client calls
1835 // HandleAgentSit itself after it gets to the location 2015 // HandleAgentSit itself after it gets to the location
1836 // It doesn't get to the location until we've moved them there though 2016 // It doesn't get to the location until we've moved them there though
1837 // which happens in HandleAgentSit :P 2017 // which happens in HandleAgentSit :P
1838 m_autopilotMoving = autopilot; 2018 m_autopilotMoving = autopilot;
1839 m_autoPilotTarget = pos; 2019 m_autoPilotTarget = autopilotTarget;
1840 m_sitAtAutoTarget = autopilot; 2020 m_sitAtAutoTarget = autopilot;
2021 m_initialSitTarget = autopilotTarget;
1841 if (!autopilot) 2022 if (!autopilot)
1842 HandleAgentSit(remoteClient, UUID); 2023 HandleAgentSit(remoteClient, UUID);
1843 } 2024 }
@@ -2132,31 +2313,66 @@ namespace OpenSim.Region.Framework.Scenes
2132 { 2313 {
2133 if (part != null) 2314 if (part != null)
2134 { 2315 {
2316//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2135 if (part.GetAvatarOnSitTarget() == UUID) 2317 if (part.GetAvatarOnSitTarget() == UUID)
2136 { 2318 {
2319//Console.WriteLine("Scripted Sit");
2320 // Scripted sit
2137 Vector3 sitTargetPos = part.SitTargetPosition; 2321 Vector3 sitTargetPos = part.SitTargetPosition;
2138 Quaternion sitTargetOrient = part.SitTargetOrientation; 2322 Quaternion sitTargetOrient = part.SitTargetOrientation;
2139
2140 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2141 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2142
2143 //Quaternion result = (sitTargetOrient * vq) * nq;
2144
2145 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2323 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2146 m_pos += SIT_TARGET_ADJUSTMENT; 2324 m_pos += SIT_TARGET_ADJUSTMENT;
2147 m_bodyRot = sitTargetOrient; 2325 m_bodyRot = sitTargetOrient;
2148 //Rotation = sitTargetOrient;
2149 m_parentPosition = part.AbsolutePosition; 2326 m_parentPosition = part.AbsolutePosition;
2150 2327 part.IsOccupied = true;
2151 //SendTerseUpdateToAllClients(); 2328Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2152 } 2329 }
2153 else 2330 else
2154 { 2331 {
2155 m_pos -= part.AbsolutePosition; 2332 // if m_avUnscriptedSitPos is zero then Av sits above center
2333 // Else Av sits at m_avUnscriptedSitPos
2334
2335 // Non-scripted sit by Kitto Flora 21Nov09
2336 // Calculate angle of line from prim to Av
2337 Quaternion partIRot;
2338// if (part.LinkNum == 1)
2339// { // Root prim of linkset
2340// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2341// }
2342// else
2343// { // single or child prim
2344 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2345// }
2346 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2347 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2348 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2349 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2350 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2351 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2352 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2353 // Av sits at world euler <0,0, z>, translated by part rotation
2354 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2355
2156 m_parentPosition = part.AbsolutePosition; 2356 m_parentPosition = part.AbsolutePosition;
2157 } 2357 part.IsOccupied = true;
2358 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2359 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2360 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2361 m_avUnscriptedSitPos; // adds click offset, if any
2362 //Set up raytrace to find top surface of prim
2363 Vector3 size = part.Scale;
2364 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2365 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2366 Vector3 down = new Vector3(0f, 0f, -1f);
2367//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2368 m_scene.PhysicsScene.RaycastWorld(
2369 start, // Vector3 position,
2370 down, // Vector3 direction,
2371 mag, // float length,
2372 SitAltitudeCallback); // retMethod
2373 } // end scripted/not
2158 } 2374 }
2159 else 2375 else // no Av
2160 { 2376 {
2161 return; 2377 return;
2162 } 2378 }
@@ -2168,11 +2384,39 @@ namespace OpenSim.Region.Framework.Scenes
2168 2384
2169 Animator.TrySetMovementAnimation(sitAnimation); 2385 Animator.TrySetMovementAnimation(sitAnimation);
2170 SendFullUpdateToAllClients(); 2386 SendFullUpdateToAllClients();
2171 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2172 // So we're also sending a terse update (which has avatar rotation)
2173 // [Update] We do now.
2174 //SendTerseUpdateToAllClients();
2175 } 2387 }
2388
2389 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2390 {
2391 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2392 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2393 if(hitYN)
2394 {
2395 // m_pos = Av offset from prim center to make look like on center
2396 // m_parentPosition = Actual center pos of prim
2397 // collisionPoint = spot on prim where we want to sit
2398 // collisionPoint.Z = global sit surface height
2399 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2400 Quaternion partIRot;
2401// if (part.LinkNum == 1)
2402/// { // Root prim of linkset
2403// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2404// }
2405// else
2406// { // single or child prim
2407 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2408// }
2409 if (m_initialSitTarget != null)
2410 {
2411 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2412 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2413 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2414 m_pos += offset;
2415 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2416 }
2417
2418 }
2419 } // End SitAltitudeCallback KF.
2176 2420
2177 /// <summary> 2421 /// <summary>
2178 /// Event handler for the 'Always run' setting on the client 2422 /// Event handler for the 'Always run' setting on the client
@@ -2202,7 +2446,7 @@ namespace OpenSim.Region.Framework.Scenes
2202 /// </summary> 2446 /// </summary>
2203 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2447 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2204 /// <param name="rotation">The direction in which this avatar should now face. 2448 /// <param name="rotation">The direction in which this avatar should now face.
2205 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2449 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2206 { 2450 {
2207 if (m_isChildAgent) 2451 if (m_isChildAgent)
2208 { 2452 {
@@ -2243,10 +2487,11 @@ namespace OpenSim.Region.Framework.Scenes
2243 Rotation = rotation; 2487 Rotation = rotation;
2244 Vector3 direc = vec * rotation; 2488 Vector3 direc = vec * rotation;
2245 direc.Normalize(); 2489 direc.Normalize();
2490 PhysicsActor actor = m_physicsActor;
2491 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2246 2492
2247 direc *= 0.03f * 128f * m_speedModifier; 2493 direc *= 0.03f * 128f * m_speedModifier;
2248 2494
2249 PhysicsActor actor = m_physicsActor;
2250 if (actor != null) 2495 if (actor != null)
2251 { 2496 {
2252 if (actor.Flying) 2497 if (actor.Flying)
@@ -2268,18 +2513,25 @@ namespace OpenSim.Region.Framework.Scenes
2268 { 2513 {
2269 if (direc.Z > 2.0f) 2514 if (direc.Z > 2.0f)
2270 { 2515 {
2271 direc.Z *= 3.0f; 2516 if(m_animator.m_animTickJump == -1)
2272 2517 {
2273 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2518 direc.Z *= 3.0f; // jump
2274 Animator.TrySetMovementAnimation("PREJUMP"); 2519 }
2275 Animator.TrySetMovementAnimation("JUMP"); 2520 else
2521 {
2522 direc.Z *= 0.1f; // prejump
2523 }
2524 /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2525 Animator.TrySetMovementAnimation("PREJUMP");
2526 Animator.TrySetMovementAnimation("JUMP");
2527 */
2276 } 2528 }
2277 } 2529 }
2278 } 2530 }
2279 2531
2280 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2532 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2281 m_forceToApply = direc; 2533 m_forceToApply = direc;
2282 2534 m_isNudging = Nudging;
2283 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2535 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2284 } 2536 }
2285 2537
@@ -2294,7 +2546,7 @@ namespace OpenSim.Region.Framework.Scenes
2294 const float POSITION_TOLERANCE = 0.05f; 2546 const float POSITION_TOLERANCE = 0.05f;
2295 //const int TIME_MS_TOLERANCE = 3000; 2547 //const int TIME_MS_TOLERANCE = 3000;
2296 2548
2297 SendPrimUpdates(); 2549
2298 2550
2299 if (m_newCoarseLocations) 2551 if (m_newCoarseLocations)
2300 { 2552 {
@@ -2330,6 +2582,9 @@ namespace OpenSim.Region.Framework.Scenes
2330 CheckForBorderCrossing(); 2582 CheckForBorderCrossing();
2331 CheckForSignificantMovement(); // sends update to the modules. 2583 CheckForSignificantMovement(); // sends update to the modules.
2332 } 2584 }
2585
2586 //Sending prim updates AFTER the avatar terse updates are sent
2587 SendPrimUpdates();
2333 } 2588 }
2334 2589
2335 #endregion 2590 #endregion
@@ -3140,6 +3395,7 @@ namespace OpenSim.Region.Framework.Scenes
3140 m_callbackURI = cAgent.CallbackURI; 3395 m_callbackURI = cAgent.CallbackURI;
3141 3396
3142 m_pos = cAgent.Position; 3397 m_pos = cAgent.Position;
3398
3143 m_velocity = cAgent.Velocity; 3399 m_velocity = cAgent.Velocity;
3144 m_CameraCenter = cAgent.Center; 3400 m_CameraCenter = cAgent.Center;
3145 //m_avHeight = cAgent.Size.Z; 3401 //m_avHeight = cAgent.Size.Z;
@@ -3228,14 +3484,25 @@ namespace OpenSim.Region.Framework.Scenes
3228 { 3484 {
3229 if (m_forceToApply.HasValue) 3485 if (m_forceToApply.HasValue)
3230 { 3486 {
3231 Vector3 force = m_forceToApply.Value;
3232 3487
3488 Vector3 force = m_forceToApply.Value;
3233 m_updateflag = true; 3489 m_updateflag = true;
3234// movementvector = force;
3235 Velocity = force; 3490 Velocity = force;
3236 3491
3237 m_forceToApply = null; 3492 m_forceToApply = null;
3238 } 3493 }
3494 else
3495 {
3496 if (m_isNudging)
3497 {
3498 Vector3 force = Vector3.Zero;
3499
3500 m_updateflag = true;
3501 Velocity = force;
3502 m_isNudging = false;
3503 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3504 }
3505 }
3239 } 3506 }
3240 3507
3241 public override void SetText(string text, Vector3 color, double alpha) 3508 public override void SetText(string text, Vector3 color, double alpha)
@@ -3286,18 +3553,29 @@ namespace OpenSim.Region.Framework.Scenes
3286 { 3553 {
3287 if (e == null) 3554 if (e == null)
3288 return; 3555 return;
3289 3556
3290 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3557 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3291 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3292 // as of this comment the interval is set in AddToPhysicalScene 3558 // as of this comment the interval is set in AddToPhysicalScene
3293 if (Animator!=null) 3559 if (Animator!=null)
3294 Animator.UpdateMovementAnimations(); 3560 {
3561 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3562 { // else its will lock out other animation changes, like ground sit.
3563 Animator.UpdateMovementAnimations();
3564 m_updateCount--;
3565 }
3566 }
3295 3567
3296 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3568 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3297 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3569 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3298 3570
3299 CollisionPlane = Vector4.UnitW; 3571 CollisionPlane = Vector4.UnitW;
3300 3572
3573 if (m_lastColCount != coldata.Count)
3574 {
3575 m_updateCount = UPDATE_COUNT;
3576 m_lastColCount = coldata.Count;
3577 }
3578
3301 if (coldata.Count != 0 && Animator != null) 3579 if (coldata.Count != 0 && Animator != null)
3302 { 3580 {
3303 switch (Animator.CurrentMovementAnimation) 3581 switch (Animator.CurrentMovementAnimation)
@@ -3501,7 +3779,10 @@ namespace OpenSim.Region.Framework.Scenes
3501 m_scene = scene; 3779 m_scene = scene;
3502 3780
3503 RegisterToEvents(); 3781 RegisterToEvents();
3504 3782 if (m_controllingClient != null)
3783 {
3784 m_controllingClient.ProcessPendingPackets();
3785 }
3505 /* 3786 /*
3506 AbsolutePosition = client.StartPos; 3787 AbsolutePosition = client.StartPos;
3507 3788
@@ -3732,6 +4013,32 @@ namespace OpenSim.Region.Framework.Scenes
3732 return; 4013 return;
3733 } 4014 }
3734 4015
4016 XmlDocument doc = new XmlDocument();
4017 string stateData = String.Empty;
4018
4019 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4020 if (attServ != null)
4021 {
4022 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4023 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4024 doc.LoadXml(stateData);
4025 }
4026
4027 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4028
4029 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4030 if (nodes.Count > 0)
4031 {
4032 foreach (XmlNode n in nodes)
4033 {
4034 XmlElement elem = (XmlElement)n;
4035 string itemID = elem.GetAttribute("ItemID");
4036 string xml = elem.InnerXml;
4037
4038 itemData[new UUID(itemID)] = xml;
4039 }
4040 }
4041
3735 List<int> attPoints = m_appearance.GetAttachedPoints(); 4042 List<int> attPoints = m_appearance.GetAttachedPoints();
3736 foreach (int p in attPoints) 4043 foreach (int p in attPoints)
3737 { 4044 {
@@ -3751,9 +4058,26 @@ namespace OpenSim.Region.Framework.Scenes
3751 4058
3752 try 4059 try
3753 { 4060 {
3754 // Rez from inventory 4061 string xmlData;
3755 UUID asset 4062 XmlDocument d = new XmlDocument();
3756 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4063 UUID asset;
4064 if (itemData.TryGetValue(itemID, out xmlData))
4065 {
4066 d.LoadXml(xmlData);
4067 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4068
4069 // Rez from inventory
4070 asset
4071 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4072
4073 }
4074 else
4075 {
4076 // Rez from inventory (with a null doc to let
4077 // CHANGED_OWNER happen)
4078 asset
4079 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4080 }
3757 4081
3758 m_log.InfoFormat( 4082 m_log.InfoFormat(
3759 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", 4083 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
@@ -3790,5 +4114,16 @@ namespace OpenSim.Region.Framework.Scenes
3790 m_reprioritization_called = false; 4114 m_reprioritization_called = false;
3791 } 4115 }
3792 } 4116 }
4117
4118 private Vector3 Quat2Euler(Quaternion rot){
4119 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4120 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4121 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4122 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4123 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4124 return(new Vector3(x,y,z));
4125 }
4126
4127
3793 } 4128 }
3794} 4129}