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.cs653
1 files changed, 470 insertions, 183 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 30eafd7..d76f029 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
127 private Vector3 m_lastPosition; 130 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
131 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
132 private Vector3 m_lastPosition;
133 private Vector3 m_lastWorldPosition;
128 private Quaternion m_lastRotation; 134 private Quaternion m_lastRotation;
129 private Vector3 m_lastVelocity; 135 private Vector3 m_lastVelocity;
130 //private int m_lastTerseSent; 136 //private int m_lastTerseSent;
@@ -134,7 +140,6 @@ namespace OpenSim.Region.Framework.Scenes
134 private Vector3? m_forceToApply; 140 private Vector3? m_forceToApply;
135 private uint m_requestedSitTargetID; 141 private uint m_requestedSitTargetID;
136 private UUID m_requestedSitTargetUUID; 142 private UUID m_requestedSitTargetUUID;
137 public bool SitGround = false;
138 143
139 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 144 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
140 145
@@ -157,7 +162,6 @@ namespace OpenSim.Region.Framework.Scenes
157 private int m_perfMonMS; 162 private int m_perfMonMS;
158 163
159 private bool m_setAlwaysRun; 164 private bool m_setAlwaysRun;
160
161 private bool m_forceFly; 165 private bool m_forceFly;
162 private bool m_flyDisabled; 166 private bool m_flyDisabled;
163 167
@@ -183,7 +187,8 @@ namespace OpenSim.Region.Framework.Scenes
183 protected RegionInfo m_regionInfo; 187 protected RegionInfo m_regionInfo;
184 protected ulong crossingFromRegion; 188 protected ulong crossingFromRegion;
185 189
186 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 190 private readonly Vector3[] Dir_Vectors = new Vector3[11];
191 private bool m_isNudging = false;
187 192
188 // Position of agent's camera in world (region cordinates) 193 // Position of agent's camera in world (region cordinates)
189 protected Vector3 m_CameraCenter; 194 protected Vector3 m_CameraCenter;
@@ -208,6 +213,7 @@ namespace OpenSim.Region.Framework.Scenes
208 private bool m_autopilotMoving; 213 private bool m_autopilotMoving;
209 private Vector3 m_autoPilotTarget; 214 private Vector3 m_autoPilotTarget;
210 private bool m_sitAtAutoTarget; 215 private bool m_sitAtAutoTarget;
216 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
211 217
212 private string m_nextSitAnimation = String.Empty; 218 private string m_nextSitAnimation = String.Empty;
213 219
@@ -218,6 +224,9 @@ namespace OpenSim.Region.Framework.Scenes
218 private bool m_followCamAuto; 224 private bool m_followCamAuto;
219 225
220 private int m_movementUpdateCount; 226 private int m_movementUpdateCount;
227 private int m_lastColCount = -1; //KF: Look for Collision chnages
228 private int m_updateCount = 0; //KF: Update Anims for a while
229 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
221 private const int NumMovementsBetweenRayCast = 5; 230 private const int NumMovementsBetweenRayCast = 5;
222 231
223 private bool CameraConstraintActive; 232 private bool CameraConstraintActive;
@@ -245,7 +254,9 @@ namespace OpenSim.Region.Framework.Scenes
245 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 254 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
246 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 255 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
247 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 256 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
248 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 257 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
258 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
259 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 260 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
250 } 261 }
251 262
@@ -452,7 +463,8 @@ namespace OpenSim.Region.Framework.Scenes
452 get 463 get
453 { 464 {
454 PhysicsActor actor = m_physicsActor; 465 PhysicsActor actor = m_physicsActor;
455 if (actor != null) 466// if (actor != null)
467 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
456 m_pos = actor.Position; 468 m_pos = actor.Position;
457 469
458 return m_parentPosition + m_pos; 470 return m_parentPosition + m_pos;
@@ -473,7 +485,8 @@ namespace OpenSim.Region.Framework.Scenes
473 } 485 }
474 } 486 }
475 487
476 m_pos = value; 488 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
489 m_pos = value;
477 m_parentPosition = Vector3.Zero; 490 m_parentPosition = Vector3.Zero;
478 } 491 }
479 } 492 }
@@ -665,7 +678,7 @@ namespace OpenSim.Region.Framework.Scenes
665 CreateSceneViewer(); 678 CreateSceneViewer();
666 m_animator = new ScenePresenceAnimator(this); 679 m_animator = new ScenePresenceAnimator(this);
667 } 680 }
668 681
669 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 682 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
670 { 683 {
671 m_rootRegionHandle = reginfo.RegionHandle; 684 m_rootRegionHandle = reginfo.RegionHandle;
@@ -697,10 +710,7 @@ namespace OpenSim.Region.Framework.Scenes
697 m_reprioritization_timer.AutoReset = false; 710 m_reprioritization_timer.AutoReset = false;
698 711
699 AdjustKnownSeeds(); 712 AdjustKnownSeeds();
700
701 // TODO: I think, this won't send anything, as we are still a child here...
702 Animator.TrySetMovementAnimation("STAND"); 713 Animator.TrySetMovementAnimation("STAND");
703
704 // we created a new ScenePresence (a new child agent) in a fresh region. 714 // we created a new ScenePresence (a new child agent) in a fresh region.
705 // Request info about all the (root) agents in this region 715 // Request info about all the (root) agents in this region
706 // Note: This won't send data *to* other clients in that region (children don't send) 716 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -756,25 +766,47 @@ namespace OpenSim.Region.Framework.Scenes
756 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 766 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
757 Dir_Vectors[4] = Vector3.UnitZ; //UP 767 Dir_Vectors[4] = Vector3.UnitZ; //UP
758 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 768 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
759 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 769 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
760 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 770 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
761 Dir_Vectors[7] = -Vector3.UnitX; //BACK 771 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
772 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
773 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
762 } 774 }
763 775
764 private Vector3[] GetWalkDirectionVectors() 776 private Vector3[] GetWalkDirectionVectors()
765 { 777 {
766 Vector3[] vector = new Vector3[9]; 778 Vector3[] vector = new Vector3[11];
767 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 779 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
768 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 780 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
769 vector[2] = Vector3.UnitY; //LEFT 781 vector[2] = Vector3.UnitY; //LEFT
770 vector[3] = -Vector3.UnitY; //RIGHT 782 vector[3] = -Vector3.UnitY; //RIGHT
771 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 783 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
772 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 784 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
773 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 785 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
774 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 786 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
775 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 787 vector[8] = Vector3.UnitY; //LEFT_NUDGE
788 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
789 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
776 return vector; 790 return vector;
777 } 791 }
792
793 private bool[] GetDirectionIsNudge()
794 {
795 bool[] isNudge = new bool[11];
796 isNudge[0] = false; //FORWARD
797 isNudge[1] = false; //BACK
798 isNudge[2] = false; //LEFT
799 isNudge[3] = false; //RIGHT
800 isNudge[4] = false; //UP
801 isNudge[5] = false; //DOWN
802 isNudge[6] = true; //FORWARD_NUDGE
803 isNudge[7] = true; //BACK_NUDGE
804 isNudge[8] = true; //LEFT_NUDGE
805 isNudge[9] = true; //RIGHT_NUDGE
806 isNudge[10] = true; //DOWN_Nudge
807 return isNudge;
808 }
809
778 810
779 #endregion 811 #endregion
780 812
@@ -843,6 +875,22 @@ namespace OpenSim.Region.Framework.Scenes
843 { 875 {
844 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 876 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
845 pos.Y = crossedBorder.BorderLine.Z - 1; 877 pos.Y = crossedBorder.BorderLine.Z - 1;
878 }
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 && m_userLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
890 {
891 pos = land.LandData.UserLocation;
892 }
893 }
846 } 894 }
847 895
848 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 896 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
@@ -977,9 +1025,10 @@ namespace OpenSim.Region.Framework.Scenes
977 public void Teleport(Vector3 pos) 1025 public void Teleport(Vector3 pos)
978 { 1026 {
979 bool isFlying = false; 1027 bool isFlying = false;
980 if (m_physicsActor != null)
981 isFlying = m_physicsActor.Flying;
982 1028
1029 if (m_physicsActor != null)
1030 isFlying = m_physicsActor.Flying;
1031
983 RemoveFromPhysicalScene(); 1032 RemoveFromPhysicalScene();
984 Velocity = Vector3.Zero; 1033 Velocity = Vector3.Zero;
985 AbsolutePosition = pos; 1034 AbsolutePosition = pos;
@@ -990,7 +1039,8 @@ namespace OpenSim.Region.Framework.Scenes
990 SetHeight(m_appearance.AvatarHeight); 1039 SetHeight(m_appearance.AvatarHeight);
991 } 1040 }
992 1041
993 SendTerseUpdateToAllClients(); 1042 SendTerseUpdateToAllClients();
1043
994 } 1044 }
995 1045
996 public void TeleportWithMomentum(Vector3 pos) 1046 public void TeleportWithMomentum(Vector3 pos)
@@ -1035,7 +1085,9 @@ namespace OpenSim.Region.Framework.Scenes
1035 { 1085 {
1036 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1086 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1037 } 1087 }
1038 1088
1089 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1090
1039 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1091 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1040 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1092 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1041 } 1093 }
@@ -1220,6 +1272,7 @@ namespace OpenSim.Region.Framework.Scenes
1220 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1272 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1221 1273
1222 m_pos = m_LastFinitePos; 1274 m_pos = m_LastFinitePos;
1275
1223 if (!m_pos.IsFinite()) 1276 if (!m_pos.IsFinite())
1224 { 1277 {
1225 m_pos.X = 127f; 1278 m_pos.X = 127f;
@@ -1286,7 +1339,6 @@ namespace OpenSim.Region.Framework.Scenes
1286 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1339 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1287 } 1340 }
1288 } 1341 }
1289
1290 lock (scriptedcontrols) 1342 lock (scriptedcontrols)
1291 { 1343 {
1292 if (scriptedcontrols.Count > 0) 1344 if (scriptedcontrols.Count > 0)
@@ -1301,12 +1353,8 @@ namespace OpenSim.Region.Framework.Scenes
1301 1353
1302 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1354 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1303 { 1355 {
1304 // TODO: This doesn't prevent the user from walking yet. 1356 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1305 // Setting parent ID would fix this, if we knew what value 1357 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1306 // to use. Or we could add a m_isSitting variable.
1307 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1308 SitGround = true;
1309
1310 } 1358 }
1311 1359
1312 // In the future, these values might need to go global. 1360 // In the future, these values might need to go global.
@@ -1356,6 +1404,11 @@ namespace OpenSim.Region.Framework.Scenes
1356 update_rotation = true; 1404 update_rotation = true;
1357 } 1405 }
1358 1406
1407 //guilty until proven innocent..
1408 bool Nudging = true;
1409 //Basically, if there is at least one non-nudge control then we don't need
1410 //to worry about stopping the avatar
1411
1359 if (m_parentID == 0) 1412 if (m_parentID == 0)
1360 { 1413 {
1361 bool bAllowUpdateMoveToPosition = false; 1414 bool bAllowUpdateMoveToPosition = false;
@@ -1370,9 +1423,12 @@ namespace OpenSim.Region.Framework.Scenes
1370 else 1423 else
1371 dirVectors = Dir_Vectors; 1424 dirVectors = Dir_Vectors;
1372 1425
1373 // The fact that m_movementflag is a byte needs to be fixed 1426 bool[] isNudge = GetDirectionIsNudge();
1374 // it really should be a uint 1427
1375 uint nudgehack = 250; 1428
1429
1430
1431
1376 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1432 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1377 { 1433 {
1378 if (((uint)flags & (uint)DCF) != 0) 1434 if (((uint)flags & (uint)DCF) != 0)
@@ -1382,40 +1438,28 @@ namespace OpenSim.Region.Framework.Scenes
1382 try 1438 try
1383 { 1439 {
1384 agent_control_v3 += dirVectors[i]; 1440 agent_control_v3 += dirVectors[i];
1385 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1441 if (isNudge[i] == false)
1442 {
1443 Nudging = false;
1444 }
1386 } 1445 }
1387 catch (IndexOutOfRangeException) 1446 catch (IndexOutOfRangeException)
1388 { 1447 {
1389 // Why did I get this? 1448 // Why did I get this?
1390 } 1449 }
1391 1450
1392 if ((m_movementflag & (byte)(uint)DCF) == 0) 1451 if ((m_movementflag & (uint)DCF) == 0)
1393 { 1452 {
1394 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1395 {
1396 m_movementflag |= (byte)nudgehack;
1397 }
1398 m_movementflag += (byte)(uint)DCF; 1453 m_movementflag += (byte)(uint)DCF;
1399 update_movementflag = true; 1454 update_movementflag = true;
1400 } 1455 }
1401 } 1456 }
1402 else 1457 else
1403 { 1458 {
1404 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1459 if ((m_movementflag & (uint)DCF) != 0)
1405 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1406 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1407 ) // This or is for Nudge forward
1408 { 1460 {
1409 m_movementflag -= ((byte)(uint)DCF); 1461 m_movementflag -= (byte)(uint)DCF;
1410
1411 update_movementflag = true; 1462 update_movementflag = true;
1412 /*
1413 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1414 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1415 {
1416 m_log.Debug("Removed Hack flag");
1417 }
1418 */
1419 } 1463 }
1420 else 1464 else
1421 { 1465 {
@@ -1424,7 +1468,6 @@ namespace OpenSim.Region.Framework.Scenes
1424 } 1468 }
1425 i++; 1469 i++;
1426 } 1470 }
1427
1428 //Paupaw:Do Proper PID for Autopilot here 1471 //Paupaw:Do Proper PID for Autopilot here
1429 if (bResetMoveToPosition) 1472 if (bResetMoveToPosition)
1430 { 1473 {
@@ -1459,6 +1502,9 @@ namespace OpenSim.Region.Framework.Scenes
1459 // Ignore z component of vector 1502 // Ignore z component of vector
1460 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1503 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1461 LocalVectorToTarget2D.Normalize(); 1504 LocalVectorToTarget2D.Normalize();
1505
1506 //We're not nudging
1507 Nudging = false;
1462 agent_control_v3 += LocalVectorToTarget2D; 1508 agent_control_v3 += LocalVectorToTarget2D;
1463 1509
1464 // update avatar movement flags. the avatar coordinate system is as follows: 1510 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1547,13 +1593,13 @@ namespace OpenSim.Region.Framework.Scenes
1547 // m_log.DebugFormat( 1593 // m_log.DebugFormat(
1548 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1594 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1549 1595
1550 AddNewMovement(agent_control_v3, q); 1596 AddNewMovement(agent_control_v3, q, Nudging);
1551 1597
1552 1598
1553 } 1599 }
1554 } 1600 }
1555 1601
1556 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1602 if (update_movementflag)
1557 Animator.UpdateMovementAnimations(); 1603 Animator.UpdateMovementAnimations();
1558 1604
1559 m_scene.EventManager.TriggerOnClientMovement(this); 1605 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1568,7 +1614,6 @@ namespace OpenSim.Region.Framework.Scenes
1568 m_sitAtAutoTarget = false; 1614 m_sitAtAutoTarget = false;
1569 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1615 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1570 //proxy.PCode = (byte)PCode.ParticleSystem; 1616 //proxy.PCode = (byte)PCode.ParticleSystem;
1571
1572 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1617 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1573 proxyObjectGroup.AttachToScene(m_scene); 1618 proxyObjectGroup.AttachToScene(m_scene);
1574 1619
@@ -1610,7 +1655,7 @@ namespace OpenSim.Region.Framework.Scenes
1610 } 1655 }
1611 m_moveToPositionInProgress = true; 1656 m_moveToPositionInProgress = true;
1612 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1657 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1613 } 1658 }
1614 catch (Exception ex) 1659 catch (Exception ex)
1615 { 1660 {
1616 //Why did I get this error? 1661 //Why did I get this error?
@@ -1632,7 +1677,7 @@ namespace OpenSim.Region.Framework.Scenes
1632 Velocity = Vector3.Zero; 1677 Velocity = Vector3.Zero;
1633 SendFullUpdateToAllClients(); 1678 SendFullUpdateToAllClients();
1634 1679
1635 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1680 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1636 } 1681 }
1637 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1682 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1638 m_requestedSitTargetUUID = UUID.Zero; 1683 m_requestedSitTargetUUID = UUID.Zero;
@@ -1665,55 +1710,84 @@ namespace OpenSim.Region.Framework.Scenes
1665 /// </summary> 1710 /// </summary>
1666 public void StandUp() 1711 public void StandUp()
1667 { 1712 {
1668 if (SitGround)
1669 SitGround = false;
1670
1671 if (m_parentID != 0) 1713 if (m_parentID != 0)
1672 { 1714 {
1673 m_log.Debug("StandupCode Executed");
1674 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1715 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1675 if (part != null) 1716 if (part != null)
1676 { 1717 {
1718 part.TaskInventory.LockItemsForRead(true);
1677 TaskInventoryDictionary taskIDict = part.TaskInventory; 1719 TaskInventoryDictionary taskIDict = part.TaskInventory;
1678 if (taskIDict != null) 1720 if (taskIDict != null)
1679 { 1721 {
1680 lock (taskIDict) 1722 foreach (UUID taskID in taskIDict.Keys)
1681 { 1723 {
1682 foreach (UUID taskID in taskIDict.Keys) 1724 UnRegisterControlEventsToScript(LocalId, taskID);
1683 { 1725 taskIDict[taskID].PermsMask &= ~(
1684 UnRegisterControlEventsToScript(LocalId, taskID); 1726 2048 | //PERMISSION_CONTROL_CAMERA
1685 taskIDict[taskID].PermsMask &= ~( 1727 4); // PERMISSION_TAKE_CONTROLS
1686 2048 | //PERMISSION_CONTROL_CAMERA
1687 4); // PERMISSION_TAKE_CONTROLS
1688 }
1689 } 1728 }
1690
1691 } 1729 }
1730 part.TaskInventory.LockItemsForRead(false);
1692 // Reset sit target. 1731 // Reset sit target.
1693 if (part.GetAvatarOnSitTarget() == UUID) 1732 if (part.GetAvatarOnSitTarget() == UUID)
1694 part.SetAvatarOnSitTarget(UUID.Zero); 1733 part.SetAvatarOnSitTarget(UUID.Zero);
1695
1696 m_parentPosition = part.GetWorldPosition(); 1734 m_parentPosition = part.GetWorldPosition();
1697 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1735 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1698 } 1736 }
1699 1737 // part.GetWorldRotation() is the rotation of the object being sat on
1700 if (m_physicsActor == null) 1738 // Rotation is the sittiing Av's rotation
1701 { 1739
1702 AddToPhysicalScene(false); 1740 Quaternion partRot;
1741// if (part.LinkNum == 1)
1742// { // Root prim of linkset
1743// partRot = part.ParentGroup.RootPart.RotationOffset;
1744// }
1745// else
1746// { // single or child prim
1747
1748// }
1749 if (part == null) //CW: Part may be gone. llDie() for example.
1750 {
1751 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1752 }
1753 else
1754 {
1755 partRot = part.GetWorldRotation();
1703 } 1756 }
1704 1757
1705 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1758 Quaternion partIRot = Quaternion.Inverse(partRot);
1706 m_parentPosition = Vector3.Zero; 1759
1760 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1761 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1707 1762
1708 m_parentID = 0; 1763
1764 if (m_physicsActor == null)
1765 {
1766 AddToPhysicalScene(false);
1767 }
1768 //CW: If the part isn't null then we can set the current position
1769 if (part != null)
1770 {
1771 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1772 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1773 part.IsOccupied = false;
1774 }
1775 else
1776 {
1777 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1778 AbsolutePosition = m_lastWorldPosition;
1779 }
1780
1781 m_parentPosition = Vector3.Zero;
1782 m_parentID = 0;
1709 SendFullUpdateToAllClients(); 1783 SendFullUpdateToAllClients();
1710 m_requestedSitTargetID = 0; 1784 m_requestedSitTargetID = 0;
1785
1711 if ((m_physicsActor != null) && (m_avHeight > 0)) 1786 if ((m_physicsActor != null) && (m_avHeight > 0))
1712 { 1787 {
1713 SetHeight(m_avHeight); 1788 SetHeight(m_avHeight);
1714 } 1789 }
1715 } 1790 }
1716
1717 Animator.TrySetMovementAnimation("STAND"); 1791 Animator.TrySetMovementAnimation("STAND");
1718 } 1792 }
1719 1793
@@ -1744,13 +1818,9 @@ namespace OpenSim.Region.Framework.Scenes
1744 Vector3 avSitOffSet = part.SitTargetPosition; 1818 Vector3 avSitOffSet = part.SitTargetPosition;
1745 Quaternion avSitOrientation = part.SitTargetOrientation; 1819 Quaternion avSitOrientation = part.SitTargetOrientation;
1746 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1820 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1747 1821 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1748 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1822 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1749 bool SitTargetisSet = 1823 if (SitTargetisSet && !SitTargetOccupied)
1750 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1751 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1752
1753 if (SitTargetisSet && SitTargetUnOccupied)
1754 { 1824 {
1755 //switch the target to this prim 1825 //switch the target to this prim
1756 return part; 1826 return part;
@@ -1764,84 +1834,153 @@ namespace OpenSim.Region.Framework.Scenes
1764 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1834 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1765 { 1835 {
1766 bool autopilot = true; 1836 bool autopilot = true;
1837 Vector3 autopilotTarget = new Vector3();
1838 Quaternion sitOrientation = Quaternion.Identity;
1767 Vector3 pos = new Vector3(); 1839 Vector3 pos = new Vector3();
1768 Quaternion sitOrientation = pSitOrientation;
1769 Vector3 cameraEyeOffset = Vector3.Zero; 1840 Vector3 cameraEyeOffset = Vector3.Zero;
1770 Vector3 cameraAtOffset = Vector3.Zero; 1841 Vector3 cameraAtOffset = Vector3.Zero;
1771 bool forceMouselook = false; 1842 bool forceMouselook = false;
1772 1843
1773 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1844 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1774 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1845 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1775 if (part != null) 1846 if (part == null) return;
1776 { 1847
1777 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1848 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1778 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1849 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1779 1850
1780 // Is a sit target available? 1851 // part is the prim to sit on
1781 Vector3 avSitOffSet = part.SitTargetPosition; 1852 // offset is the world-ref vector distance from that prim center to the click-spot
1782 Quaternion avSitOrientation = part.SitTargetOrientation; 1853 // UUID is the UUID of the Avatar doing the clicking
1783 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1854
1784 1855 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1785 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1856
1786 bool SitTargetisSet = 1857 // Is a sit target available?
1787 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1858 Vector3 avSitOffSet = part.SitTargetPosition;
1788 ( 1859 Quaternion avSitOrientation = part.SitTargetOrientation;
1789 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1860
1790 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1861 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1791 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1862 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1792 ) 1863 Quaternion partRot;
1793 )); 1864// if (part.LinkNum == 1)
1794 1865// { // Root prim of linkset
1795 if (SitTargetisSet && SitTargetUnOccupied) 1866// partRot = part.ParentGroup.RootPart.RotationOffset;
1796 { 1867// }
1797 part.SetAvatarOnSitTarget(UUID); 1868// else
1798 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1869// { // single or child prim
1799 sitOrientation = avSitOrientation; 1870 partRot = part.GetWorldRotation();
1800 autopilot = false; 1871// }
1801 } 1872 Quaternion partIRot = Quaternion.Inverse(partRot);
1802 1873//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1803 pos = part.AbsolutePosition + offset; 1874 // Sit analysis rewritten by KF 091125
1804 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1875 if (SitTargetisSet) // scipted sit
1805 //{ 1876 {
1806 // offset = pos; 1877 if (!part.IsOccupied)
1807 //autopilot = false; 1878 {
1808 //} 1879//Console.WriteLine("Scripted, unoccupied");
1809 if (m_physicsActor != null) 1880 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1810 { 1881 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1811 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1882 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1812 // We can remove the physicsActor until they stand up. 1883 autopilot = false; // Jump direct to scripted llSitPos()
1813 m_sitAvatarHeight = m_physicsActor.Size.Z; 1884 }
1814 1885 else
1815 if (autopilot) 1886 {
1816 { 1887//Console.WriteLine("Scripted, occupied");
1817 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1888 return;
1818 { 1889 }
1819 autopilot = false; 1890 }
1891 else // Not Scripted
1892 {
1893 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1894 {
1895 // large prim & offset, ignore if other Avs sitting
1896// offset.Z -= 0.05f;
1897 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1898 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1899
1900//Console.WriteLine(" offset ={0}", offset);
1901//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1902//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1903
1904 }
1905 else // small offset
1906 {
1907//Console.WriteLine("Small offset");
1908 if (!part.IsOccupied)
1909 {
1910 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1911 autopilotTarget = part.AbsolutePosition;
1912//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1913 }
1914 else return; // occupied small
1915 } // end large/small
1916 } // end Scripted/not
1917 cameraAtOffset = part.GetCameraAtOffset();
1918 cameraEyeOffset = part.GetCameraEyeOffset();
1919 forceMouselook = part.GetForceMouselook();
1920 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1921 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1820 1922
1821 RemoveFromPhysicalScene(); 1923 if (m_physicsActor != null)
1822 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1924 {
1823 } 1925 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1824 } 1926 // We can remove the physicsActor until they stand up.
1825 else 1927 m_sitAvatarHeight = m_physicsActor.Size.Z;
1928 if (autopilot)
1929 { // its not a scripted sit
1930// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1931 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1826 { 1932 {
1933 autopilot = false; // close enough
1934 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1935 Not using the part's position because returning the AV to the last known standing
1936 position is likely to be more friendly, isn't it? */
1827 RemoveFromPhysicalScene(); 1937 RemoveFromPhysicalScene();
1828 } 1938 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1939 } // else the autopilot will get us close
1940 }
1941 else
1942 { // its a scripted sit
1943 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1944 I *am* using the part's position this time because we have no real idea how far away
1945 the avatar is from the sit target. */
1946 RemoveFromPhysicalScene();
1829 } 1947 }
1830
1831 cameraAtOffset = part.GetCameraAtOffset();
1832 cameraEyeOffset = part.GetCameraEyeOffset();
1833 forceMouselook = part.GetForceMouselook();
1834 } 1948 }
1835 1949 else return; // physactor is null!
1836 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1950
1837 m_requestedSitTargetUUID = targetID; 1951 Vector3 offsetr; // = offset * partIRot;
1952 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1953 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1954 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1955 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1956 offsetr = offset * partIRot;
1957//
1958 // else
1959 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1960 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1961 // (offset * partRot);
1962 // }
1963
1964//Console.WriteLine(" ");
1965//Console.WriteLine("link number ={0}", part.LinkNum);
1966//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1967//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1968//Console.WriteLine("Click offst ={0}", offset);
1969//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1970//Console.WriteLine("offsetr ={0}", offsetr);
1971//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1972//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1973
1974 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1975 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1838 // This calls HandleAgentSit twice, once from here, and the client calls 1976 // This calls HandleAgentSit twice, once from here, and the client calls
1839 // HandleAgentSit itself after it gets to the location 1977 // HandleAgentSit itself after it gets to the location
1840 // It doesn't get to the location until we've moved them there though 1978 // It doesn't get to the location until we've moved them there though
1841 // which happens in HandleAgentSit :P 1979 // which happens in HandleAgentSit :P
1842 m_autopilotMoving = autopilot; 1980 m_autopilotMoving = autopilot;
1843 m_autoPilotTarget = pos; 1981 m_autoPilotTarget = autopilotTarget;
1844 m_sitAtAutoTarget = autopilot; 1982 m_sitAtAutoTarget = autopilot;
1983 m_initialSitTarget = autopilotTarget;
1845 if (!autopilot) 1984 if (!autopilot)
1846 HandleAgentSit(remoteClient, UUID); 1985 HandleAgentSit(remoteClient, UUID);
1847 } 1986 }
@@ -2136,31 +2275,66 @@ namespace OpenSim.Region.Framework.Scenes
2136 { 2275 {
2137 if (part != null) 2276 if (part != null)
2138 { 2277 {
2278//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2139 if (part.GetAvatarOnSitTarget() == UUID) 2279 if (part.GetAvatarOnSitTarget() == UUID)
2140 { 2280 {
2281//Console.WriteLine("Scripted Sit");
2282 // Scripted sit
2141 Vector3 sitTargetPos = part.SitTargetPosition; 2283 Vector3 sitTargetPos = part.SitTargetPosition;
2142 Quaternion sitTargetOrient = part.SitTargetOrientation; 2284 Quaternion sitTargetOrient = part.SitTargetOrientation;
2143
2144 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2145 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2146
2147 //Quaternion result = (sitTargetOrient * vq) * nq;
2148
2149 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2285 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2150 m_pos += SIT_TARGET_ADJUSTMENT; 2286 m_pos += SIT_TARGET_ADJUSTMENT;
2151 m_bodyRot = sitTargetOrient; 2287 m_bodyRot = sitTargetOrient;
2152 //Rotation = sitTargetOrient;
2153 m_parentPosition = part.AbsolutePosition; 2288 m_parentPosition = part.AbsolutePosition;
2154 2289 part.IsOccupied = true;
2155 //SendTerseUpdateToAllClients(); 2290Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2156 } 2291 }
2157 else 2292 else
2158 { 2293 {
2159 m_pos -= part.AbsolutePosition; 2294 // if m_avUnscriptedSitPos is zero then Av sits above center
2295 // Else Av sits at m_avUnscriptedSitPos
2296
2297 // Non-scripted sit by Kitto Flora 21Nov09
2298 // Calculate angle of line from prim to Av
2299 Quaternion partIRot;
2300// if (part.LinkNum == 1)
2301// { // Root prim of linkset
2302// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2303// }
2304// else
2305// { // single or child prim
2306 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2307// }
2308 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2309 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2310 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2311 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2312 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2313 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2314 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2315 // Av sits at world euler <0,0, z>, translated by part rotation
2316 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2317
2160 m_parentPosition = part.AbsolutePosition; 2318 m_parentPosition = part.AbsolutePosition;
2161 } 2319 part.IsOccupied = true;
2320 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2321 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2322 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2323 m_avUnscriptedSitPos; // adds click offset, if any
2324 //Set up raytrace to find top surface of prim
2325 Vector3 size = part.Scale;
2326 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2327 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2328 Vector3 down = new Vector3(0f, 0f, -1f);
2329//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2330 m_scene.PhysicsScene.RaycastWorld(
2331 start, // Vector3 position,
2332 down, // Vector3 direction,
2333 mag, // float length,
2334 SitAltitudeCallback); // retMethod
2335 } // end scripted/not
2162 } 2336 }
2163 else 2337 else // no Av
2164 { 2338 {
2165 return; 2339 return;
2166 } 2340 }
@@ -2172,11 +2346,36 @@ namespace OpenSim.Region.Framework.Scenes
2172 2346
2173 Animator.TrySetMovementAnimation(sitAnimation); 2347 Animator.TrySetMovementAnimation(sitAnimation);
2174 SendFullUpdateToAllClients(); 2348 SendFullUpdateToAllClients();
2175 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2176 // So we're also sending a terse update (which has avatar rotation)
2177 // [Update] We do now.
2178 //SendTerseUpdateToAllClients();
2179 } 2349 }
2350
2351 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2352 {
2353 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2354 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2355 if(hitYN)
2356 {
2357 // m_pos = Av offset from prim center to make look like on center
2358 // m_parentPosition = Actual center pos of prim
2359 // collisionPoint = spot on prim where we want to sit
2360 // collisionPoint.Z = global sit surface height
2361 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2362 Quaternion partIRot;
2363// if (part.LinkNum == 1)
2364/// { // Root prim of linkset
2365// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2366// }
2367// else
2368// { // single or child prim
2369 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2370// }
2371 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2372 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2373//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2374 m_pos += offset;
2375// ControllingClient.SendClearFollowCamProperties(part.UUID);
2376
2377 }
2378 } // End SitAltitudeCallback KF.
2180 2379
2181 /// <summary> 2380 /// <summary>
2182 /// Event handler for the 'Always run' setting on the client 2381 /// Event handler for the 'Always run' setting on the client
@@ -2206,7 +2405,7 @@ namespace OpenSim.Region.Framework.Scenes
2206 /// </summary> 2405 /// </summary>
2207 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2406 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2208 /// <param name="rotation">The direction in which this avatar should now face. 2407 /// <param name="rotation">The direction in which this avatar should now face.
2209 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2408 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2210 { 2409 {
2211 if (m_isChildAgent) 2410 if (m_isChildAgent)
2212 { 2411 {
@@ -2247,10 +2446,11 @@ namespace OpenSim.Region.Framework.Scenes
2247 Rotation = rotation; 2446 Rotation = rotation;
2248 Vector3 direc = vec * rotation; 2447 Vector3 direc = vec * rotation;
2249 direc.Normalize(); 2448 direc.Normalize();
2449 PhysicsActor actor = m_physicsActor;
2450 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2250 2451
2251 direc *= 0.03f * 128f * m_speedModifier; 2452 direc *= 0.03f * 128f * m_speedModifier;
2252 2453
2253 PhysicsActor actor = m_physicsActor;
2254 if (actor != null) 2454 if (actor != null)
2255 { 2455 {
2256 if (actor.Flying) 2456 if (actor.Flying)
@@ -2272,18 +2472,25 @@ namespace OpenSim.Region.Framework.Scenes
2272 { 2472 {
2273 if (direc.Z > 2.0f) 2473 if (direc.Z > 2.0f)
2274 { 2474 {
2275 direc.Z *= 3.0f; 2475 if(m_animator.m_animTickJump == -1)
2276 2476 {
2277 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2477 direc.Z *= 3.0f; // jump
2278 Animator.TrySetMovementAnimation("PREJUMP"); 2478 }
2279 Animator.TrySetMovementAnimation("JUMP"); 2479 else
2480 {
2481 direc.Z *= 0.1f; // prejump
2482 }
2483 /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2484 Animator.TrySetMovementAnimation("PREJUMP");
2485 Animator.TrySetMovementAnimation("JUMP");
2486 */
2280 } 2487 }
2281 } 2488 }
2282 } 2489 }
2283 2490
2284 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2491 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2285 m_forceToApply = direc; 2492 m_forceToApply = direc;
2286 2493 m_isNudging = Nudging;
2287 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2494 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2288 } 2495 }
2289 2496
@@ -2298,7 +2505,7 @@ namespace OpenSim.Region.Framework.Scenes
2298 const float POSITION_TOLERANCE = 0.05f; 2505 const float POSITION_TOLERANCE = 0.05f;
2299 //const int TIME_MS_TOLERANCE = 3000; 2506 //const int TIME_MS_TOLERANCE = 3000;
2300 2507
2301 SendPrimUpdates(); 2508
2302 2509
2303 if (m_newCoarseLocations) 2510 if (m_newCoarseLocations)
2304 { 2511 {
@@ -2334,6 +2541,9 @@ namespace OpenSim.Region.Framework.Scenes
2334 CheckForBorderCrossing(); 2541 CheckForBorderCrossing();
2335 CheckForSignificantMovement(); // sends update to the modules. 2542 CheckForSignificantMovement(); // sends update to the modules.
2336 } 2543 }
2544
2545 //Sending prim updates AFTER the avatar terse updates are sent
2546 SendPrimUpdates();
2337 } 2547 }
2338 2548
2339 #endregion 2549 #endregion
@@ -3150,6 +3360,7 @@ namespace OpenSim.Region.Framework.Scenes
3150 m_callbackURI = cAgent.CallbackURI; 3360 m_callbackURI = cAgent.CallbackURI;
3151 3361
3152 m_pos = cAgent.Position; 3362 m_pos = cAgent.Position;
3363
3153 m_velocity = cAgent.Velocity; 3364 m_velocity = cAgent.Velocity;
3154 m_CameraCenter = cAgent.Center; 3365 m_CameraCenter = cAgent.Center;
3155 //m_avHeight = cAgent.Size.Z; 3366 //m_avHeight = cAgent.Size.Z;
@@ -3238,14 +3449,25 @@ namespace OpenSim.Region.Framework.Scenes
3238 { 3449 {
3239 if (m_forceToApply.HasValue) 3450 if (m_forceToApply.HasValue)
3240 { 3451 {
3241 Vector3 force = m_forceToApply.Value;
3242 3452
3453 Vector3 force = m_forceToApply.Value;
3243 m_updateflag = true; 3454 m_updateflag = true;
3244// movementvector = force;
3245 Velocity = force; 3455 Velocity = force;
3246 3456
3247 m_forceToApply = null; 3457 m_forceToApply = null;
3248 } 3458 }
3459 else
3460 {
3461 if (m_isNudging)
3462 {
3463 Vector3 force = Vector3.Zero;
3464
3465 m_updateflag = true;
3466 Velocity = force;
3467 m_isNudging = false;
3468 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3469 }
3470 }
3249 } 3471 }
3250 3472
3251 public override void SetText(string text, Vector3 color, double alpha) 3473 public override void SetText(string text, Vector3 color, double alpha)
@@ -3296,18 +3518,29 @@ namespace OpenSim.Region.Framework.Scenes
3296 { 3518 {
3297 if (e == null) 3519 if (e == null)
3298 return; 3520 return;
3299 3521
3300 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3522 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3301 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3302 // as of this comment the interval is set in AddToPhysicalScene 3523 // as of this comment the interval is set in AddToPhysicalScene
3303 if (Animator!=null) 3524 if (Animator!=null)
3304 Animator.UpdateMovementAnimations(); 3525 {
3526 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3527 { // else its will lock out other animation changes, like ground sit.
3528 Animator.UpdateMovementAnimations();
3529 m_updateCount--;
3530 }
3531 }
3305 3532
3306 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3533 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3307 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3534 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3308 3535
3309 CollisionPlane = Vector4.UnitW; 3536 CollisionPlane = Vector4.UnitW;
3310 3537
3538 if (m_lastColCount != coldata.Count)
3539 {
3540 m_updateCount = UPDATE_COUNT;
3541 m_lastColCount = coldata.Count;
3542 }
3543
3311 if (coldata.Count != 0 && Animator != null) 3544 if (coldata.Count != 0 && Animator != null)
3312 { 3545 {
3313 switch (Animator.CurrentMovementAnimation) 3546 switch (Animator.CurrentMovementAnimation)
@@ -3742,6 +3975,32 @@ namespace OpenSim.Region.Framework.Scenes
3742 return; 3975 return;
3743 } 3976 }
3744 3977
3978 XmlDocument doc = new XmlDocument();
3979 string stateData = String.Empty;
3980
3981 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
3982 if (attServ != null)
3983 {
3984 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
3985 stateData = attServ.Get(ControllingClient.AgentId.ToString());
3986 doc.LoadXml(stateData);
3987 }
3988
3989 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
3990
3991 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
3992 if (nodes.Count > 0)
3993 {
3994 foreach (XmlNode n in nodes)
3995 {
3996 XmlElement elem = (XmlElement)n;
3997 string itemID = elem.GetAttribute("ItemID");
3998 string xml = elem.InnerXml;
3999
4000 itemData[new UUID(itemID)] = xml;
4001 }
4002 }
4003
3745 List<int> attPoints = m_appearance.GetAttachedPoints(); 4004 List<int> attPoints = m_appearance.GetAttachedPoints();
3746 foreach (int p in attPoints) 4005 foreach (int p in attPoints)
3747 { 4006 {
@@ -3761,9 +4020,26 @@ namespace OpenSim.Region.Framework.Scenes
3761 4020
3762 try 4021 try
3763 { 4022 {
3764 // Rez from inventory 4023 string xmlData;
3765 UUID asset 4024 XmlDocument d = new XmlDocument();
3766 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4025 UUID asset;
4026 if (itemData.TryGetValue(itemID, out xmlData))
4027 {
4028 d.LoadXml(xmlData);
4029 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4030
4031 // Rez from inventory
4032 asset
4033 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4034
4035 }
4036 else
4037 {
4038 // Rez from inventory (with a null doc to let
4039 // CHANGED_OWNER happen)
4040 asset
4041 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4042 }
3767 4043
3768 m_log.InfoFormat( 4044 m_log.InfoFormat(
3769 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", 4045 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
@@ -3914,5 +4190,16 @@ namespace OpenSim.Region.Framework.Scenes
3914 m_reprioritization_called = false; 4190 m_reprioritization_called = false;
3915 } 4191 }
3916 } 4192 }
4193
4194 private Vector3 Quat2Euler(Quaternion rot){
4195 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4196 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4197 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4198 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4199 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4200 return(new Vector3(x,y,z));
4201 }
4202
4203
3917 } 4204 }
3918} 4205}