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.cs630
1 files changed, 455 insertions, 175 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fb66fcd..f649dfe 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 string m_Viewer = String.Empty; 230 private string m_Viewer = String.Empty;
222 231
223 private const int NumMovementsBetweenRayCast = 5; 232 private const int NumMovementsBetweenRayCast = 5;
@@ -247,7 +256,9 @@ namespace OpenSim.Region.Framework.Scenes
247 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 256 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
248 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 257 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
249 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 258 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
250 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 259 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
260 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
261 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
251 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 262 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
252 } 263 }
253 264
@@ -454,7 +465,8 @@ namespace OpenSim.Region.Framework.Scenes
454 get 465 get
455 { 466 {
456 PhysicsActor actor = m_physicsActor; 467 PhysicsActor actor = m_physicsActor;
457 if (actor != null) 468// if (actor != null)
469 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
458 m_pos = actor.Position; 470 m_pos = actor.Position;
459 471
460 return m_parentPosition + m_pos; 472 return m_parentPosition + m_pos;
@@ -475,7 +487,8 @@ namespace OpenSim.Region.Framework.Scenes
475 } 487 }
476 } 488 }
477 489
478 m_pos = value; 490 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
491 m_pos = value;
479 m_parentPosition = Vector3.Zero; 492 m_parentPosition = Vector3.Zero;
480 } 493 }
481 } 494 }
@@ -700,10 +713,7 @@ namespace OpenSim.Region.Framework.Scenes
700 m_reprioritization_timer.AutoReset = false; 713 m_reprioritization_timer.AutoReset = false;
701 714
702 AdjustKnownSeeds(); 715 AdjustKnownSeeds();
703
704 // TODO: I think, this won't send anything, as we are still a child here...
705 Animator.TrySetMovementAnimation("STAND"); 716 Animator.TrySetMovementAnimation("STAND");
706
707 // we created a new ScenePresence (a new child agent) in a fresh region. 717 // we created a new ScenePresence (a new child agent) in a fresh region.
708 // Request info about all the (root) agents in this region 718 // Request info about all the (root) agents in this region
709 // Note: This won't send data *to* other clients in that region (children don't send) 719 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -759,25 +769,47 @@ namespace OpenSim.Region.Framework.Scenes
759 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 769 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
760 Dir_Vectors[4] = Vector3.UnitZ; //UP 770 Dir_Vectors[4] = Vector3.UnitZ; //UP
761 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 771 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
762 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 772 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
763 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 773 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
764 Dir_Vectors[7] = -Vector3.UnitX; //BACK 774 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
775 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
776 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
765 } 777 }
766 778
767 private Vector3[] GetWalkDirectionVectors() 779 private Vector3[] GetWalkDirectionVectors()
768 { 780 {
769 Vector3[] vector = new Vector3[9]; 781 Vector3[] vector = new Vector3[11];
770 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 782 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
771 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 783 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
772 vector[2] = Vector3.UnitY; //LEFT 784 vector[2] = Vector3.UnitY; //LEFT
773 vector[3] = -Vector3.UnitY; //RIGHT 785 vector[3] = -Vector3.UnitY; //RIGHT
774 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 786 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
775 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 787 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
776 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 788 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
777 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 789 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
778 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 790 vector[8] = Vector3.UnitY; //LEFT_NUDGE
791 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
792 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
779 return vector; 793 return vector;
780 } 794 }
795
796 private bool[] GetDirectionIsNudge()
797 {
798 bool[] isNudge = new bool[11];
799 isNudge[0] = false; //FORWARD
800 isNudge[1] = false; //BACK
801 isNudge[2] = false; //LEFT
802 isNudge[3] = false; //RIGHT
803 isNudge[4] = false; //UP
804 isNudge[5] = false; //DOWN
805 isNudge[6] = true; //FORWARD_NUDGE
806 isNudge[7] = true; //BACK_NUDGE
807 isNudge[8] = true; //LEFT_NUDGE
808 isNudge[9] = true; //RIGHT_NUDGE
809 isNudge[10] = true; //DOWN_Nudge
810 return isNudge;
811 }
812
781 813
782 #endregion 814 #endregion
783 815
@@ -846,6 +878,22 @@ namespace OpenSim.Region.Framework.Scenes
846 { 878 {
847 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 879 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
848 pos.Y = crossedBorder.BorderLine.Z - 1; 880 pos.Y = crossedBorder.BorderLine.Z - 1;
881 }
882
883 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
884 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
885 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
886 if (KnownChildRegionHandles.Count == 0)
887 {
888 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
889 if (land != null)
890 {
891 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
892 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)
893 {
894 pos = land.LandData.UserLocation;
895 }
896 }
849 } 897 }
850 898
851 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 899 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
@@ -980,9 +1028,10 @@ namespace OpenSim.Region.Framework.Scenes
980 public void Teleport(Vector3 pos) 1028 public void Teleport(Vector3 pos)
981 { 1029 {
982 bool isFlying = false; 1030 bool isFlying = false;
983 if (m_physicsActor != null)
984 isFlying = m_physicsActor.Flying;
985 1031
1032 if (m_physicsActor != null)
1033 isFlying = m_physicsActor.Flying;
1034
986 RemoveFromPhysicalScene(); 1035 RemoveFromPhysicalScene();
987 Velocity = Vector3.Zero; 1036 Velocity = Vector3.Zero;
988 AbsolutePosition = pos; 1037 AbsolutePosition = pos;
@@ -993,7 +1042,8 @@ namespace OpenSim.Region.Framework.Scenes
993 SetHeight(m_appearance.AvatarHeight); 1042 SetHeight(m_appearance.AvatarHeight);
994 } 1043 }
995 1044
996 SendTerseUpdateToAllClients(); 1045 SendTerseUpdateToAllClients();
1046
997 } 1047 }
998 1048
999 public void TeleportWithMomentum(Vector3 pos) 1049 public void TeleportWithMomentum(Vector3 pos)
@@ -1038,7 +1088,9 @@ namespace OpenSim.Region.Framework.Scenes
1038 { 1088 {
1039 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1089 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1040 } 1090 }
1041 1091
1092 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1093
1042 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1094 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1043 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1095 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1044 } 1096 }
@@ -1223,6 +1275,7 @@ namespace OpenSim.Region.Framework.Scenes
1223 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1275 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1224 1276
1225 m_pos = m_LastFinitePos; 1277 m_pos = m_LastFinitePos;
1278
1226 if (!m_pos.IsFinite()) 1279 if (!m_pos.IsFinite())
1227 { 1280 {
1228 m_pos.X = 127f; 1281 m_pos.X = 127f;
@@ -1289,7 +1342,6 @@ namespace OpenSim.Region.Framework.Scenes
1289 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1342 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1290 } 1343 }
1291 } 1344 }
1292
1293 lock (scriptedcontrols) 1345 lock (scriptedcontrols)
1294 { 1346 {
1295 if (scriptedcontrols.Count > 0) 1347 if (scriptedcontrols.Count > 0)
@@ -1304,12 +1356,8 @@ namespace OpenSim.Region.Framework.Scenes
1304 1356
1305 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1357 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1306 { 1358 {
1307 // TODO: This doesn't prevent the user from walking yet. 1359 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1308 // Setting parent ID would fix this, if we knew what value 1360 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1309 // to use. Or we could add a m_isSitting variable.
1310 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1311 SitGround = true;
1312
1313 } 1361 }
1314 1362
1315 // In the future, these values might need to go global. 1363 // In the future, these values might need to go global.
@@ -1359,6 +1407,11 @@ namespace OpenSim.Region.Framework.Scenes
1359 update_rotation = true; 1407 update_rotation = true;
1360 } 1408 }
1361 1409
1410 //guilty until proven innocent..
1411 bool Nudging = true;
1412 //Basically, if there is at least one non-nudge control then we don't need
1413 //to worry about stopping the avatar
1414
1362 if (m_parentID == 0) 1415 if (m_parentID == 0)
1363 { 1416 {
1364 bool bAllowUpdateMoveToPosition = false; 1417 bool bAllowUpdateMoveToPosition = false;
@@ -1373,9 +1426,12 @@ namespace OpenSim.Region.Framework.Scenes
1373 else 1426 else
1374 dirVectors = Dir_Vectors; 1427 dirVectors = Dir_Vectors;
1375 1428
1376 // The fact that m_movementflag is a byte needs to be fixed 1429 bool[] isNudge = GetDirectionIsNudge();
1377 // it really should be a uint 1430
1378 uint nudgehack = 250; 1431
1432
1433
1434
1379 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1435 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1380 { 1436 {
1381 if (((uint)flags & (uint)DCF) != 0) 1437 if (((uint)flags & (uint)DCF) != 0)
@@ -1385,40 +1441,28 @@ namespace OpenSim.Region.Framework.Scenes
1385 try 1441 try
1386 { 1442 {
1387 agent_control_v3 += dirVectors[i]; 1443 agent_control_v3 += dirVectors[i];
1388 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1444 if (isNudge[i] == false)
1445 {
1446 Nudging = false;
1447 }
1389 } 1448 }
1390 catch (IndexOutOfRangeException) 1449 catch (IndexOutOfRangeException)
1391 { 1450 {
1392 // Why did I get this? 1451 // Why did I get this?
1393 } 1452 }
1394 1453
1395 if ((m_movementflag & (byte)(uint)DCF) == 0) 1454 if ((m_movementflag & (uint)DCF) == 0)
1396 { 1455 {
1397 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1398 {
1399 m_movementflag |= (byte)nudgehack;
1400 }
1401 m_movementflag += (byte)(uint)DCF; 1456 m_movementflag += (byte)(uint)DCF;
1402 update_movementflag = true; 1457 update_movementflag = true;
1403 } 1458 }
1404 } 1459 }
1405 else 1460 else
1406 { 1461 {
1407 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1462 if ((m_movementflag & (uint)DCF) != 0)
1408 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1409 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1410 ) // This or is for Nudge forward
1411 { 1463 {
1412 m_movementflag -= ((byte)(uint)DCF); 1464 m_movementflag -= (byte)(uint)DCF;
1413
1414 update_movementflag = true; 1465 update_movementflag = true;
1415 /*
1416 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1417 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1418 {
1419 m_log.Debug("Removed Hack flag");
1420 }
1421 */
1422 } 1466 }
1423 else 1467 else
1424 { 1468 {
@@ -1462,6 +1506,9 @@ namespace OpenSim.Region.Framework.Scenes
1462 // Ignore z component of vector 1506 // Ignore z component of vector
1463 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1507 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1464 LocalVectorToTarget2D.Normalize(); 1508 LocalVectorToTarget2D.Normalize();
1509
1510 //We're not nudging
1511 Nudging = false;
1465 agent_control_v3 += LocalVectorToTarget2D; 1512 agent_control_v3 += LocalVectorToTarget2D;
1466 1513
1467 // update avatar movement flags. the avatar coordinate system is as follows: 1514 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1550,13 +1597,13 @@ namespace OpenSim.Region.Framework.Scenes
1550 // m_log.DebugFormat( 1597 // m_log.DebugFormat(
1551 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1598 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1552 1599
1553 AddNewMovement(agent_control_v3, q); 1600 AddNewMovement(agent_control_v3, q, Nudging);
1554 1601
1555 1602
1556 } 1603 }
1557 } 1604 }
1558 1605
1559 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1606 if (update_movementflag)
1560 Animator.UpdateMovementAnimations(); 1607 Animator.UpdateMovementAnimations();
1561 1608
1562 m_scene.EventManager.TriggerOnClientMovement(this); 1609 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1571,7 +1618,6 @@ namespace OpenSim.Region.Framework.Scenes
1571 m_sitAtAutoTarget = false; 1618 m_sitAtAutoTarget = false;
1572 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1619 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1573 //proxy.PCode = (byte)PCode.ParticleSystem; 1620 //proxy.PCode = (byte)PCode.ParticleSystem;
1574
1575 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1621 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1576 proxyObjectGroup.AttachToScene(m_scene); 1622 proxyObjectGroup.AttachToScene(m_scene);
1577 1623
@@ -1613,7 +1659,7 @@ namespace OpenSim.Region.Framework.Scenes
1613 } 1659 }
1614 m_moveToPositionInProgress = true; 1660 m_moveToPositionInProgress = true;
1615 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1661 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1616 } 1662 }
1617 catch (Exception ex) 1663 catch (Exception ex)
1618 { 1664 {
1619 //Why did I get this error? 1665 //Why did I get this error?
@@ -1635,7 +1681,7 @@ namespace OpenSim.Region.Framework.Scenes
1635 Velocity = Vector3.Zero; 1681 Velocity = Vector3.Zero;
1636 SendFullUpdateToAllClients(); 1682 SendFullUpdateToAllClients();
1637 1683
1638 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1684 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1639 } 1685 }
1640 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1686 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1641 m_requestedSitTargetUUID = UUID.Zero; 1687 m_requestedSitTargetUUID = UUID.Zero;
@@ -1668,55 +1714,84 @@ namespace OpenSim.Region.Framework.Scenes
1668 /// </summary> 1714 /// </summary>
1669 public void StandUp() 1715 public void StandUp()
1670 { 1716 {
1671 if (SitGround)
1672 SitGround = false;
1673
1674 if (m_parentID != 0) 1717 if (m_parentID != 0)
1675 { 1718 {
1676 m_log.Debug("StandupCode Executed");
1677 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1719 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1678 if (part != null) 1720 if (part != null)
1679 { 1721 {
1722 part.TaskInventory.LockItemsForRead(true);
1680 TaskInventoryDictionary taskIDict = part.TaskInventory; 1723 TaskInventoryDictionary taskIDict = part.TaskInventory;
1681 if (taskIDict != null) 1724 if (taskIDict != null)
1682 { 1725 {
1683 lock (taskIDict) 1726 foreach (UUID taskID in taskIDict.Keys)
1684 { 1727 {
1685 foreach (UUID taskID in taskIDict.Keys) 1728 UnRegisterControlEventsToScript(LocalId, taskID);
1686 { 1729 taskIDict[taskID].PermsMask &= ~(
1687 UnRegisterControlEventsToScript(LocalId, taskID); 1730 2048 | //PERMISSION_CONTROL_CAMERA
1688 taskIDict[taskID].PermsMask &= ~( 1731 4); // PERMISSION_TAKE_CONTROLS
1689 2048 | //PERMISSION_CONTROL_CAMERA
1690 4); // PERMISSION_TAKE_CONTROLS
1691 }
1692 } 1732 }
1693
1694 } 1733 }
1734 part.TaskInventory.LockItemsForRead(false);
1695 // Reset sit target. 1735 // Reset sit target.
1696 if (part.GetAvatarOnSitTarget() == UUID) 1736 if (part.GetAvatarOnSitTarget() == UUID)
1697 part.SetAvatarOnSitTarget(UUID.Zero); 1737 part.SetAvatarOnSitTarget(UUID.Zero);
1698
1699 m_parentPosition = part.GetWorldPosition(); 1738 m_parentPosition = part.GetWorldPosition();
1700 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1739 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1701 } 1740 }
1702 1741 // part.GetWorldRotation() is the rotation of the object being sat on
1703 if (m_physicsActor == null) 1742 // Rotation is the sittiing Av's rotation
1704 { 1743
1705 AddToPhysicalScene(false); 1744 Quaternion partRot;
1745// if (part.LinkNum == 1)
1746// { // Root prim of linkset
1747// partRot = part.ParentGroup.RootPart.RotationOffset;
1748// }
1749// else
1750// { // single or child prim
1751
1752// }
1753 if (part == null) //CW: Part may be gone. llDie() for example.
1754 {
1755 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1756 }
1757 else
1758 {
1759 partRot = part.GetWorldRotation();
1706 } 1760 }
1707 1761
1708 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1762 Quaternion partIRot = Quaternion.Inverse(partRot);
1709 m_parentPosition = Vector3.Zero;
1710 1763
1711 m_parentID = 0; 1764 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1765 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1766
1767
1768 if (m_physicsActor == null)
1769 {
1770 AddToPhysicalScene(false);
1771 }
1772 //CW: If the part isn't null then we can set the current position
1773 if (part != null)
1774 {
1775 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1776 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1777 part.IsOccupied = false;
1778 }
1779 else
1780 {
1781 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1782 AbsolutePosition = m_lastWorldPosition;
1783 }
1784
1785 m_parentPosition = Vector3.Zero;
1786 m_parentID = 0;
1712 SendFullUpdateToAllClients(); 1787 SendFullUpdateToAllClients();
1713 m_requestedSitTargetID = 0; 1788 m_requestedSitTargetID = 0;
1789
1714 if ((m_physicsActor != null) && (m_avHeight > 0)) 1790 if ((m_physicsActor != null) && (m_avHeight > 0))
1715 { 1791 {
1716 SetHeight(m_avHeight); 1792 SetHeight(m_avHeight);
1717 } 1793 }
1718 } 1794 }
1719
1720 Animator.TrySetMovementAnimation("STAND"); 1795 Animator.TrySetMovementAnimation("STAND");
1721 } 1796 }
1722 1797
@@ -1747,13 +1822,9 @@ namespace OpenSim.Region.Framework.Scenes
1747 Vector3 avSitOffSet = part.SitTargetPosition; 1822 Vector3 avSitOffSet = part.SitTargetPosition;
1748 Quaternion avSitOrientation = part.SitTargetOrientation; 1823 Quaternion avSitOrientation = part.SitTargetOrientation;
1749 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1824 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1750 1825 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1751 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1826 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1752 bool SitTargetisSet = 1827 if (SitTargetisSet && !SitTargetOccupied)
1753 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1754 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1755
1756 if (SitTargetisSet && SitTargetUnOccupied)
1757 { 1828 {
1758 //switch the target to this prim 1829 //switch the target to this prim
1759 return part; 1830 return part;
@@ -1767,84 +1838,153 @@ namespace OpenSim.Region.Framework.Scenes
1767 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1838 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1768 { 1839 {
1769 bool autopilot = true; 1840 bool autopilot = true;
1841 Vector3 autopilotTarget = new Vector3();
1842 Quaternion sitOrientation = Quaternion.Identity;
1770 Vector3 pos = new Vector3(); 1843 Vector3 pos = new Vector3();
1771 Quaternion sitOrientation = pSitOrientation;
1772 Vector3 cameraEyeOffset = Vector3.Zero; 1844 Vector3 cameraEyeOffset = Vector3.Zero;
1773 Vector3 cameraAtOffset = Vector3.Zero; 1845 Vector3 cameraAtOffset = Vector3.Zero;
1774 bool forceMouselook = false; 1846 bool forceMouselook = false;
1775 1847
1776 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1848 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1777 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1849 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1778 if (part != null) 1850 if (part == null) return;
1779 { 1851
1780 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1852 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1781 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1853 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1782 1854
1783 // Is a sit target available? 1855 // part is the prim to sit on
1784 Vector3 avSitOffSet = part.SitTargetPosition; 1856 // offset is the world-ref vector distance from that prim center to the click-spot
1785 Quaternion avSitOrientation = part.SitTargetOrientation; 1857 // UUID is the UUID of the Avatar doing the clicking
1786 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1858
1787 1859 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1788 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1860
1789 bool SitTargetisSet = 1861 // Is a sit target available?
1790 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1862 Vector3 avSitOffSet = part.SitTargetPosition;
1791 ( 1863 Quaternion avSitOrientation = part.SitTargetOrientation;
1792 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1864
1793 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1865 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1794 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1866 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1795 ) 1867 Quaternion partRot;
1796 )); 1868// if (part.LinkNum == 1)
1797 1869// { // Root prim of linkset
1798 if (SitTargetisSet && SitTargetUnOccupied) 1870// partRot = part.ParentGroup.RootPart.RotationOffset;
1799 { 1871// }
1800 part.SetAvatarOnSitTarget(UUID); 1872// else
1801 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1873// { // single or child prim
1802 sitOrientation = avSitOrientation; 1874 partRot = part.GetWorldRotation();
1803 autopilot = false; 1875// }
1804 } 1876 Quaternion partIRot = Quaternion.Inverse(partRot);
1805 1877//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1806 pos = part.AbsolutePosition + offset; 1878 // Sit analysis rewritten by KF 091125
1807 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1879 if (SitTargetisSet) // scipted sit
1808 //{ 1880 {
1809 // offset = pos; 1881 if (!part.IsOccupied)
1810 //autopilot = false; 1882 {
1811 //} 1883//Console.WriteLine("Scripted, unoccupied");
1812 if (m_physicsActor != null) 1884 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1813 { 1885 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1814 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1886 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1815 // We can remove the physicsActor until they stand up. 1887 autopilot = false; // Jump direct to scripted llSitPos()
1816 m_sitAvatarHeight = m_physicsActor.Size.Z; 1888 }
1817 1889 else
1818 if (autopilot) 1890 {
1819 { 1891//Console.WriteLine("Scripted, occupied");
1820 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1892 return;
1821 { 1893 }
1822 autopilot = false; 1894 }
1895 else // Not Scripted
1896 {
1897 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1898 {
1899 // large prim & offset, ignore if other Avs sitting
1900// offset.Z -= 0.05f;
1901 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1902 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1903
1904//Console.WriteLine(" offset ={0}", offset);
1905//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1906//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1907
1908 }
1909 else // small offset
1910 {
1911//Console.WriteLine("Small offset");
1912 if (!part.IsOccupied)
1913 {
1914 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1915 autopilotTarget = part.AbsolutePosition;
1916//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1917 }
1918 else return; // occupied small
1919 } // end large/small
1920 } // end Scripted/not
1921 cameraAtOffset = part.GetCameraAtOffset();
1922 cameraEyeOffset = part.GetCameraEyeOffset();
1923 forceMouselook = part.GetForceMouselook();
1924 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1925 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1823 1926
1824 RemoveFromPhysicalScene(); 1927 if (m_physicsActor != null)
1825 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1928 {
1826 } 1929 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1827 } 1930 // We can remove the physicsActor until they stand up.
1828 else 1931 m_sitAvatarHeight = m_physicsActor.Size.Z;
1932 if (autopilot)
1933 { // its not a scripted sit
1934// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1935 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1829 { 1936 {
1937 autopilot = false; // close enough
1938 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1939 Not using the part's position because returning the AV to the last known standing
1940 position is likely to be more friendly, isn't it? */
1830 RemoveFromPhysicalScene(); 1941 RemoveFromPhysicalScene();
1831 } 1942 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1943 } // else the autopilot will get us close
1944 }
1945 else
1946 { // its a scripted sit
1947 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1948 I *am* using the part's position this time because we have no real idea how far away
1949 the avatar is from the sit target. */
1950 RemoveFromPhysicalScene();
1832 } 1951 }
1833
1834 cameraAtOffset = part.GetCameraAtOffset();
1835 cameraEyeOffset = part.GetCameraEyeOffset();
1836 forceMouselook = part.GetForceMouselook();
1837 } 1952 }
1838 1953 else return; // physactor is null!
1839 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1954
1840 m_requestedSitTargetUUID = targetID; 1955 Vector3 offsetr; // = offset * partIRot;
1956 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1957 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1958 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1959 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1960 offsetr = offset * partIRot;
1961//
1962 // else
1963 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1964 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1965 // (offset * partRot);
1966 // }
1967
1968//Console.WriteLine(" ");
1969//Console.WriteLine("link number ={0}", part.LinkNum);
1970//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1971//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1972//Console.WriteLine("Click offst ={0}", offset);
1973//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1974//Console.WriteLine("offsetr ={0}", offsetr);
1975//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1976//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1977
1978 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1979 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1841 // This calls HandleAgentSit twice, once from here, and the client calls 1980 // This calls HandleAgentSit twice, once from here, and the client calls
1842 // HandleAgentSit itself after it gets to the location 1981 // HandleAgentSit itself after it gets to the location
1843 // It doesn't get to the location until we've moved them there though 1982 // It doesn't get to the location until we've moved them there though
1844 // which happens in HandleAgentSit :P 1983 // which happens in HandleAgentSit :P
1845 m_autopilotMoving = autopilot; 1984 m_autopilotMoving = autopilot;
1846 m_autoPilotTarget = pos; 1985 m_autoPilotTarget = autopilotTarget;
1847 m_sitAtAutoTarget = autopilot; 1986 m_sitAtAutoTarget = autopilot;
1987 m_initialSitTarget = autopilotTarget;
1848 if (!autopilot) 1988 if (!autopilot)
1849 HandleAgentSit(remoteClient, UUID); 1989 HandleAgentSit(remoteClient, UUID);
1850 } 1990 }
@@ -2139,31 +2279,66 @@ namespace OpenSim.Region.Framework.Scenes
2139 { 2279 {
2140 if (part != null) 2280 if (part != null)
2141 { 2281 {
2282//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2142 if (part.GetAvatarOnSitTarget() == UUID) 2283 if (part.GetAvatarOnSitTarget() == UUID)
2143 { 2284 {
2285//Console.WriteLine("Scripted Sit");
2286 // Scripted sit
2144 Vector3 sitTargetPos = part.SitTargetPosition; 2287 Vector3 sitTargetPos = part.SitTargetPosition;
2145 Quaternion sitTargetOrient = part.SitTargetOrientation; 2288 Quaternion sitTargetOrient = part.SitTargetOrientation;
2146
2147 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2148 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2149
2150 //Quaternion result = (sitTargetOrient * vq) * nq;
2151
2152 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2289 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2153 m_pos += SIT_TARGET_ADJUSTMENT; 2290 m_pos += SIT_TARGET_ADJUSTMENT;
2154 m_bodyRot = sitTargetOrient; 2291 m_bodyRot = sitTargetOrient;
2155 //Rotation = sitTargetOrient;
2156 m_parentPosition = part.AbsolutePosition; 2292 m_parentPosition = part.AbsolutePosition;
2157 2293 part.IsOccupied = true;
2158 //SendTerseUpdateToAllClients(); 2294Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2159 } 2295 }
2160 else 2296 else
2161 { 2297 {
2162 m_pos -= part.AbsolutePosition; 2298 // if m_avUnscriptedSitPos is zero then Av sits above center
2299 // Else Av sits at m_avUnscriptedSitPos
2300
2301 // Non-scripted sit by Kitto Flora 21Nov09
2302 // Calculate angle of line from prim to Av
2303 Quaternion partIRot;
2304// if (part.LinkNum == 1)
2305// { // Root prim of linkset
2306// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2307// }
2308// else
2309// { // single or child prim
2310 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2311// }
2312 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2313 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2314 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2315 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2316 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2317 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2318 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2319 // Av sits at world euler <0,0, z>, translated by part rotation
2320 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2321
2163 m_parentPosition = part.AbsolutePosition; 2322 m_parentPosition = part.AbsolutePosition;
2164 } 2323 part.IsOccupied = true;
2324 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2325 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2326 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2327 m_avUnscriptedSitPos; // adds click offset, if any
2328 //Set up raytrace to find top surface of prim
2329 Vector3 size = part.Scale;
2330 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2331 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2332 Vector3 down = new Vector3(0f, 0f, -1f);
2333//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2334 m_scene.PhysicsScene.RaycastWorld(
2335 start, // Vector3 position,
2336 down, // Vector3 direction,
2337 mag, // float length,
2338 SitAltitudeCallback); // retMethod
2339 } // end scripted/not
2165 } 2340 }
2166 else 2341 else // no Av
2167 { 2342 {
2168 return; 2343 return;
2169 } 2344 }
@@ -2175,11 +2350,36 @@ namespace OpenSim.Region.Framework.Scenes
2175 2350
2176 Animator.TrySetMovementAnimation(sitAnimation); 2351 Animator.TrySetMovementAnimation(sitAnimation);
2177 SendFullUpdateToAllClients(); 2352 SendFullUpdateToAllClients();
2178 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2179 // So we're also sending a terse update (which has avatar rotation)
2180 // [Update] We do now.
2181 //SendTerseUpdateToAllClients();
2182 } 2353 }
2354
2355 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2356 {
2357 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2358 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2359 if(hitYN)
2360 {
2361 // m_pos = Av offset from prim center to make look like on center
2362 // m_parentPosition = Actual center pos of prim
2363 // collisionPoint = spot on prim where we want to sit
2364 // collisionPoint.Z = global sit surface height
2365 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2366 Quaternion partIRot;
2367// if (part.LinkNum == 1)
2368/// { // Root prim of linkset
2369// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2370// }
2371// else
2372// { // single or child prim
2373 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2374// }
2375 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2376 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2377//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2378 m_pos += offset;
2379// ControllingClient.SendClearFollowCamProperties(part.UUID);
2380
2381 }
2382 } // End SitAltitudeCallback KF.
2183 2383
2184 /// <summary> 2384 /// <summary>
2185 /// Event handler for the 'Always run' setting on the client 2385 /// Event handler for the 'Always run' setting on the client
@@ -2209,7 +2409,7 @@ namespace OpenSim.Region.Framework.Scenes
2209 /// </summary> 2409 /// </summary>
2210 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2410 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2211 /// <param name="rotation">The direction in which this avatar should now face. 2411 /// <param name="rotation">The direction in which this avatar should now face.
2212 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2412 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2213 { 2413 {
2214 if (m_isChildAgent) 2414 if (m_isChildAgent)
2215 { 2415 {
@@ -2286,7 +2486,7 @@ namespace OpenSim.Region.Framework.Scenes
2286 2486
2287 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2487 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2288 m_forceToApply = direc; 2488 m_forceToApply = direc;
2289 2489 m_isNudging = Nudging;
2290 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2490 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2291 } 2491 }
2292 2492
@@ -2301,7 +2501,7 @@ namespace OpenSim.Region.Framework.Scenes
2301 const float POSITION_TOLERANCE = 0.05f; 2501 const float POSITION_TOLERANCE = 0.05f;
2302 //const int TIME_MS_TOLERANCE = 3000; 2502 //const int TIME_MS_TOLERANCE = 3000;
2303 2503
2304 SendPrimUpdates(); 2504
2305 2505
2306 if (m_newCoarseLocations) 2506 if (m_newCoarseLocations)
2307 { 2507 {
@@ -2337,6 +2537,9 @@ namespace OpenSim.Region.Framework.Scenes
2337 CheckForBorderCrossing(); 2537 CheckForBorderCrossing();
2338 CheckForSignificantMovement(); // sends update to the modules. 2538 CheckForSignificantMovement(); // sends update to the modules.
2339 } 2539 }
2540
2541 //Sending prim updates AFTER the avatar terse updates are sent
2542 SendPrimUpdates();
2340 } 2543 }
2341 2544
2342 #endregion 2545 #endregion
@@ -3153,6 +3356,7 @@ namespace OpenSim.Region.Framework.Scenes
3153 m_callbackURI = cAgent.CallbackURI; 3356 m_callbackURI = cAgent.CallbackURI;
3154 3357
3155 m_pos = cAgent.Position; 3358 m_pos = cAgent.Position;
3359
3156 m_velocity = cAgent.Velocity; 3360 m_velocity = cAgent.Velocity;
3157 m_CameraCenter = cAgent.Center; 3361 m_CameraCenter = cAgent.Center;
3158 //m_avHeight = cAgent.Size.Z; 3362 //m_avHeight = cAgent.Size.Z;
@@ -3241,14 +3445,25 @@ namespace OpenSim.Region.Framework.Scenes
3241 { 3445 {
3242 if (m_forceToApply.HasValue) 3446 if (m_forceToApply.HasValue)
3243 { 3447 {
3244 Vector3 force = m_forceToApply.Value;
3245 3448
3449 Vector3 force = m_forceToApply.Value;
3246 m_updateflag = true; 3450 m_updateflag = true;
3247// movementvector = force;
3248 Velocity = force; 3451 Velocity = force;
3249 3452
3250 m_forceToApply = null; 3453 m_forceToApply = null;
3251 } 3454 }
3455 else
3456 {
3457 if (m_isNudging)
3458 {
3459 Vector3 force = Vector3.Zero;
3460
3461 m_updateflag = true;
3462 Velocity = force;
3463 m_isNudging = false;
3464 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3465 }
3466 }
3252 } 3467 }
3253 3468
3254 public override void SetText(string text, Vector3 color, double alpha) 3469 public override void SetText(string text, Vector3 color, double alpha)
@@ -3299,18 +3514,29 @@ namespace OpenSim.Region.Framework.Scenes
3299 { 3514 {
3300 if (e == null) 3515 if (e == null)
3301 return; 3516 return;
3302 3517
3303 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3518 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3304 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3305 // as of this comment the interval is set in AddToPhysicalScene 3519 // as of this comment the interval is set in AddToPhysicalScene
3306 if (Animator!=null) 3520 if (Animator!=null)
3307 Animator.UpdateMovementAnimations(); 3521 {
3522 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3523 { // else its will lock out other animation changes, like ground sit.
3524 Animator.UpdateMovementAnimations();
3525 m_updateCount--;
3526 }
3527 }
3308 3528
3309 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3529 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3310 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3530 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3311 3531
3312 CollisionPlane = Vector4.UnitW; 3532 CollisionPlane = Vector4.UnitW;
3313 3533
3534 if (m_lastColCount != coldata.Count)
3535 {
3536 m_updateCount = UPDATE_COUNT;
3537 m_lastColCount = coldata.Count;
3538 }
3539
3314 if (coldata.Count != 0 && Animator != null) 3540 if (coldata.Count != 0 && Animator != null)
3315 { 3541 {
3316 switch (Animator.CurrentMovementAnimation) 3542 switch (Animator.CurrentMovementAnimation)
@@ -3745,6 +3971,32 @@ namespace OpenSim.Region.Framework.Scenes
3745 return; 3971 return;
3746 } 3972 }
3747 3973
3974 XmlDocument doc = new XmlDocument();
3975 string stateData = String.Empty;
3976
3977 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
3978 if (attServ != null)
3979 {
3980 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
3981 stateData = attServ.Get(ControllingClient.AgentId.ToString());
3982 doc.LoadXml(stateData);
3983 }
3984
3985 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
3986
3987 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
3988 if (nodes.Count > 0)
3989 {
3990 foreach (XmlNode n in nodes)
3991 {
3992 XmlElement elem = (XmlElement)n;
3993 string itemID = elem.GetAttribute("ItemID");
3994 string xml = elem.InnerXml;
3995
3996 itemData[new UUID(itemID)] = xml;
3997 }
3998 }
3999
3748 List<int> attPoints = m_appearance.GetAttachedPoints(); 4000 List<int> attPoints = m_appearance.GetAttachedPoints();
3749 foreach (int p in attPoints) 4001 foreach (int p in attPoints)
3750 { 4002 {
@@ -3764,9 +4016,26 @@ namespace OpenSim.Region.Framework.Scenes
3764 4016
3765 try 4017 try
3766 { 4018 {
3767 // Rez from inventory 4019 string xmlData;
3768 UUID asset 4020 XmlDocument d = new XmlDocument();
3769 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4021 UUID asset;
4022 if (itemData.TryGetValue(itemID, out xmlData))
4023 {
4024 d.LoadXml(xmlData);
4025 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4026
4027 // Rez from inventory
4028 asset
4029 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4030
4031 }
4032 else
4033 {
4034 // Rez from inventory (with a null doc to let
4035 // CHANGED_OWNER happen)
4036 asset
4037 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4038 }
3770 4039
3771 m_log.InfoFormat( 4040 m_log.InfoFormat(
3772 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", 4041 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
@@ -3917,5 +4186,16 @@ namespace OpenSim.Region.Framework.Scenes
3917 m_reprioritization_called = false; 4186 m_reprioritization_called = false;
3918 } 4187 }
3919 } 4188 }
4189
4190 private Vector3 Quat2Euler(Quaternion rot){
4191 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4192 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4193 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4194 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4195 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4196 return(new Vector3(x,y,z));
4197 }
4198
4199
3920 } 4200 }
3921} 4201}