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 3efb45f..562232c 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 230
222 private const int NumMovementsBetweenRayCast = 5; 231 private const int NumMovementsBetweenRayCast = 5;
223 232
@@ -246,7 +255,9 @@ namespace OpenSim.Region.Framework.Scenes
246 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 255 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
247 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 256 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
248 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 257 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
249 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 258 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
259 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
260 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
250 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 261 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
251 } 262 }
252 263
@@ -453,7 +464,8 @@ namespace OpenSim.Region.Framework.Scenes
453 get 464 get
454 { 465 {
455 PhysicsActor actor = m_physicsActor; 466 PhysicsActor actor = m_physicsActor;
456 if (actor != null) 467// if (actor != null)
468 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
457 m_pos = actor.Position; 469 m_pos = actor.Position;
458 470
459 return m_parentPosition + m_pos; 471 return m_parentPosition + m_pos;
@@ -474,7 +486,8 @@ namespace OpenSim.Region.Framework.Scenes
474 } 486 }
475 } 487 }
476 488
477 m_pos = value; 489 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
490 m_pos = value;
478 m_parentPosition = Vector3.Zero; 491 m_parentPosition = Vector3.Zero;
479 } 492 }
480 } 493 }
@@ -693,10 +706,7 @@ namespace OpenSim.Region.Framework.Scenes
693 m_reprioritization_timer.AutoReset = false; 706 m_reprioritization_timer.AutoReset = false;
694 707
695 AdjustKnownSeeds(); 708 AdjustKnownSeeds();
696
697 // TODO: I think, this won't send anything, as we are still a child here...
698 Animator.TrySetMovementAnimation("STAND"); 709 Animator.TrySetMovementAnimation("STAND");
699
700 // we created a new ScenePresence (a new child agent) in a fresh region. 710 // we created a new ScenePresence (a new child agent) in a fresh region.
701 // Request info about all the (root) agents in this region 711 // Request info about all the (root) agents in this region
702 // Note: This won't send data *to* other clients in that region (children don't send) 712 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -752,25 +762,47 @@ namespace OpenSim.Region.Framework.Scenes
752 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 762 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
753 Dir_Vectors[4] = Vector3.UnitZ; //UP 763 Dir_Vectors[4] = Vector3.UnitZ; //UP
754 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 764 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
755 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 765 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
756 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 766 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
757 Dir_Vectors[7] = -Vector3.UnitX; //BACK 767 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
768 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
769 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
758 } 770 }
759 771
760 private Vector3[] GetWalkDirectionVectors() 772 private Vector3[] GetWalkDirectionVectors()
761 { 773 {
762 Vector3[] vector = new Vector3[9]; 774 Vector3[] vector = new Vector3[11];
763 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 775 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
764 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 776 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
765 vector[2] = Vector3.UnitY; //LEFT 777 vector[2] = Vector3.UnitY; //LEFT
766 vector[3] = -Vector3.UnitY; //RIGHT 778 vector[3] = -Vector3.UnitY; //RIGHT
767 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 779 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
768 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 780 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
769 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 781 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
770 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 782 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
771 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 783 vector[8] = Vector3.UnitY; //LEFT_NUDGE
784 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
785 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
772 return vector; 786 return vector;
773 } 787 }
788
789 private bool[] GetDirectionIsNudge()
790 {
791 bool[] isNudge = new bool[11];
792 isNudge[0] = false; //FORWARD
793 isNudge[1] = false; //BACK
794 isNudge[2] = false; //LEFT
795 isNudge[3] = false; //RIGHT
796 isNudge[4] = false; //UP
797 isNudge[5] = false; //DOWN
798 isNudge[6] = true; //FORWARD_NUDGE
799 isNudge[7] = true; //BACK_NUDGE
800 isNudge[8] = true; //LEFT_NUDGE
801 isNudge[9] = true; //RIGHT_NUDGE
802 isNudge[10] = true; //DOWN_Nudge
803 return isNudge;
804 }
805
774 806
775 #endregion 807 #endregion
776 808
@@ -839,6 +871,22 @@ namespace OpenSim.Region.Framework.Scenes
839 { 871 {
840 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 872 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
841 pos.Y = crossedBorder.BorderLine.Z - 1; 873 pos.Y = crossedBorder.BorderLine.Z - 1;
874 }
875
876 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
877 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
878 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
879 if (KnownChildRegionHandles.Count == 0)
880 {
881 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
882 if (land != null)
883 {
884 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
885 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)
886 {
887 pos = land.LandData.UserLocation;
888 }
889 }
842 } 890 }
843 891
844 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 892 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
@@ -973,9 +1021,10 @@ namespace OpenSim.Region.Framework.Scenes
973 public void Teleport(Vector3 pos) 1021 public void Teleport(Vector3 pos)
974 { 1022 {
975 bool isFlying = false; 1023 bool isFlying = false;
976 if (m_physicsActor != null)
977 isFlying = m_physicsActor.Flying;
978 1024
1025 if (m_physicsActor != null)
1026 isFlying = m_physicsActor.Flying;
1027
979 RemoveFromPhysicalScene(); 1028 RemoveFromPhysicalScene();
980 Velocity = Vector3.Zero; 1029 Velocity = Vector3.Zero;
981 AbsolutePosition = pos; 1030 AbsolutePosition = pos;
@@ -986,7 +1035,8 @@ namespace OpenSim.Region.Framework.Scenes
986 SetHeight(m_appearance.AvatarHeight); 1035 SetHeight(m_appearance.AvatarHeight);
987 } 1036 }
988 1037
989 SendTerseUpdateToAllClients(); 1038 SendTerseUpdateToAllClients();
1039
990 } 1040 }
991 1041
992 public void TeleportWithMomentum(Vector3 pos) 1042 public void TeleportWithMomentum(Vector3 pos)
@@ -1031,7 +1081,9 @@ namespace OpenSim.Region.Framework.Scenes
1031 { 1081 {
1032 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1082 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1033 } 1083 }
1034 1084
1085 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1086
1035 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1087 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1036 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1088 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1037 } 1089 }
@@ -1216,6 +1268,7 @@ namespace OpenSim.Region.Framework.Scenes
1216 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1268 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1217 1269
1218 m_pos = m_LastFinitePos; 1270 m_pos = m_LastFinitePos;
1271
1219 if (!m_pos.IsFinite()) 1272 if (!m_pos.IsFinite())
1220 { 1273 {
1221 m_pos.X = 127f; 1274 m_pos.X = 127f;
@@ -1282,7 +1335,6 @@ namespace OpenSim.Region.Framework.Scenes
1282 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1335 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1283 } 1336 }
1284 } 1337 }
1285
1286 lock (scriptedcontrols) 1338 lock (scriptedcontrols)
1287 { 1339 {
1288 if (scriptedcontrols.Count > 0) 1340 if (scriptedcontrols.Count > 0)
@@ -1297,12 +1349,8 @@ namespace OpenSim.Region.Framework.Scenes
1297 1349
1298 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1350 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1299 { 1351 {
1300 // TODO: This doesn't prevent the user from walking yet. 1352 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1301 // Setting parent ID would fix this, if we knew what value 1353 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1302 // to use. Or we could add a m_isSitting variable.
1303 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1304 SitGround = true;
1305
1306 } 1354 }
1307 1355
1308 // In the future, these values might need to go global. 1356 // In the future, these values might need to go global.
@@ -1352,6 +1400,11 @@ namespace OpenSim.Region.Framework.Scenes
1352 update_rotation = true; 1400 update_rotation = true;
1353 } 1401 }
1354 1402
1403 //guilty until proven innocent..
1404 bool Nudging = true;
1405 //Basically, if there is at least one non-nudge control then we don't need
1406 //to worry about stopping the avatar
1407
1355 if (m_parentID == 0) 1408 if (m_parentID == 0)
1356 { 1409 {
1357 bool bAllowUpdateMoveToPosition = false; 1410 bool bAllowUpdateMoveToPosition = false;
@@ -1366,9 +1419,12 @@ namespace OpenSim.Region.Framework.Scenes
1366 else 1419 else
1367 dirVectors = Dir_Vectors; 1420 dirVectors = Dir_Vectors;
1368 1421
1369 // The fact that m_movementflag is a byte needs to be fixed 1422 bool[] isNudge = GetDirectionIsNudge();
1370 // it really should be a uint 1423
1371 uint nudgehack = 250; 1424
1425
1426
1427
1372 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1428 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1373 { 1429 {
1374 if (((uint)flags & (uint)DCF) != 0) 1430 if (((uint)flags & (uint)DCF) != 0)
@@ -1378,40 +1434,28 @@ namespace OpenSim.Region.Framework.Scenes
1378 try 1434 try
1379 { 1435 {
1380 agent_control_v3 += dirVectors[i]; 1436 agent_control_v3 += dirVectors[i];
1381 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1437 if (isNudge[i] == false)
1438 {
1439 Nudging = false;
1440 }
1382 } 1441 }
1383 catch (IndexOutOfRangeException) 1442 catch (IndexOutOfRangeException)
1384 { 1443 {
1385 // Why did I get this? 1444 // Why did I get this?
1386 } 1445 }
1387 1446
1388 if ((m_movementflag & (byte)(uint)DCF) == 0) 1447 if ((m_movementflag & (uint)DCF) == 0)
1389 { 1448 {
1390 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1391 {
1392 m_movementflag |= (byte)nudgehack;
1393 }
1394 m_movementflag += (byte)(uint)DCF; 1449 m_movementflag += (byte)(uint)DCF;
1395 update_movementflag = true; 1450 update_movementflag = true;
1396 } 1451 }
1397 } 1452 }
1398 else 1453 else
1399 { 1454 {
1400 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1455 if ((m_movementflag & (uint)DCF) != 0)
1401 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1402 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1403 ) // This or is for Nudge forward
1404 { 1456 {
1405 m_movementflag -= ((byte)(uint)DCF); 1457 m_movementflag -= (byte)(uint)DCF;
1406
1407 update_movementflag = true; 1458 update_movementflag = true;
1408 /*
1409 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1410 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1411 {
1412 m_log.Debug("Removed Hack flag");
1413 }
1414 */
1415 } 1459 }
1416 else 1460 else
1417 { 1461 {
@@ -1455,6 +1499,9 @@ namespace OpenSim.Region.Framework.Scenes
1455 // Ignore z component of vector 1499 // Ignore z component of vector
1456 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1500 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1457 LocalVectorToTarget2D.Normalize(); 1501 LocalVectorToTarget2D.Normalize();
1502
1503 //We're not nudging
1504 Nudging = false;
1458 agent_control_v3 += LocalVectorToTarget2D; 1505 agent_control_v3 += LocalVectorToTarget2D;
1459 1506
1460 // update avatar movement flags. the avatar coordinate system is as follows: 1507 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1543,13 +1590,13 @@ namespace OpenSim.Region.Framework.Scenes
1543 // m_log.DebugFormat( 1590 // m_log.DebugFormat(
1544 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1591 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1545 1592
1546 AddNewMovement(agent_control_v3, q); 1593 AddNewMovement(agent_control_v3, q, Nudging);
1547 1594
1548 1595
1549 } 1596 }
1550 } 1597 }
1551 1598
1552 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1599 if (update_movementflag)
1553 Animator.UpdateMovementAnimations(); 1600 Animator.UpdateMovementAnimations();
1554 1601
1555 m_scene.EventManager.TriggerOnClientMovement(this); 1602 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1564,7 +1611,6 @@ namespace OpenSim.Region.Framework.Scenes
1564 m_sitAtAutoTarget = false; 1611 m_sitAtAutoTarget = false;
1565 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1612 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1566 //proxy.PCode = (byte)PCode.ParticleSystem; 1613 //proxy.PCode = (byte)PCode.ParticleSystem;
1567
1568 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1614 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1569 proxyObjectGroup.AttachToScene(m_scene); 1615 proxyObjectGroup.AttachToScene(m_scene);
1570 1616
@@ -1606,7 +1652,7 @@ namespace OpenSim.Region.Framework.Scenes
1606 } 1652 }
1607 m_moveToPositionInProgress = true; 1653 m_moveToPositionInProgress = true;
1608 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1654 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1609 } 1655 }
1610 catch (Exception ex) 1656 catch (Exception ex)
1611 { 1657 {
1612 //Why did I get this error? 1658 //Why did I get this error?
@@ -1628,7 +1674,7 @@ namespace OpenSim.Region.Framework.Scenes
1628 Velocity = Vector3.Zero; 1674 Velocity = Vector3.Zero;
1629 SendFullUpdateToAllClients(); 1675 SendFullUpdateToAllClients();
1630 1676
1631 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1677 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1632 } 1678 }
1633 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1679 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1634 m_requestedSitTargetUUID = UUID.Zero; 1680 m_requestedSitTargetUUID = UUID.Zero;
@@ -1661,55 +1707,84 @@ namespace OpenSim.Region.Framework.Scenes
1661 /// </summary> 1707 /// </summary>
1662 public void StandUp() 1708 public void StandUp()
1663 { 1709 {
1664 if (SitGround)
1665 SitGround = false;
1666
1667 if (m_parentID != 0) 1710 if (m_parentID != 0)
1668 { 1711 {
1669 m_log.Debug("StandupCode Executed");
1670 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1712 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1671 if (part != null) 1713 if (part != null)
1672 { 1714 {
1715 part.TaskInventory.LockItemsForRead(true);
1673 TaskInventoryDictionary taskIDict = part.TaskInventory; 1716 TaskInventoryDictionary taskIDict = part.TaskInventory;
1674 if (taskIDict != null) 1717 if (taskIDict != null)
1675 { 1718 {
1676 lock (taskIDict) 1719 foreach (UUID taskID in taskIDict.Keys)
1677 { 1720 {
1678 foreach (UUID taskID in taskIDict.Keys) 1721 UnRegisterControlEventsToScript(LocalId, taskID);
1679 { 1722 taskIDict[taskID].PermsMask &= ~(
1680 UnRegisterControlEventsToScript(LocalId, taskID); 1723 2048 | //PERMISSION_CONTROL_CAMERA
1681 taskIDict[taskID].PermsMask &= ~( 1724 4); // PERMISSION_TAKE_CONTROLS
1682 2048 | //PERMISSION_CONTROL_CAMERA
1683 4); // PERMISSION_TAKE_CONTROLS
1684 }
1685 } 1725 }
1686
1687 } 1726 }
1727 part.TaskInventory.LockItemsForRead(false);
1688 // Reset sit target. 1728 // Reset sit target.
1689 if (part.GetAvatarOnSitTarget() == UUID) 1729 if (part.GetAvatarOnSitTarget() == UUID)
1690 part.SetAvatarOnSitTarget(UUID.Zero); 1730 part.SetAvatarOnSitTarget(UUID.Zero);
1691
1692 m_parentPosition = part.GetWorldPosition(); 1731 m_parentPosition = part.GetWorldPosition();
1693 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1732 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1694 } 1733 }
1695 1734 // part.GetWorldRotation() is the rotation of the object being sat on
1696 if (m_physicsActor == null) 1735 // Rotation is the sittiing Av's rotation
1697 { 1736
1698 AddToPhysicalScene(false); 1737 Quaternion partRot;
1738// if (part.LinkNum == 1)
1739// { // Root prim of linkset
1740// partRot = part.ParentGroup.RootPart.RotationOffset;
1741// }
1742// else
1743// { // single or child prim
1744
1745// }
1746 if (part == null) //CW: Part may be gone. llDie() for example.
1747 {
1748 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1749 }
1750 else
1751 {
1752 partRot = part.GetWorldRotation();
1699 } 1753 }
1700 1754
1701 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1755 Quaternion partIRot = Quaternion.Inverse(partRot);
1702 m_parentPosition = Vector3.Zero;
1703 1756
1704 m_parentID = 0; 1757 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1758 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1759
1760
1761 if (m_physicsActor == null)
1762 {
1763 AddToPhysicalScene(false);
1764 }
1765 //CW: If the part isn't null then we can set the current position
1766 if (part != null)
1767 {
1768 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1769 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1770 part.IsOccupied = false;
1771 }
1772 else
1773 {
1774 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1775 AbsolutePosition = m_lastWorldPosition;
1776 }
1777
1778 m_parentPosition = Vector3.Zero;
1779 m_parentID = 0;
1705 SendFullUpdateToAllClients(); 1780 SendFullUpdateToAllClients();
1706 m_requestedSitTargetID = 0; 1781 m_requestedSitTargetID = 0;
1782
1707 if ((m_physicsActor != null) && (m_avHeight > 0)) 1783 if ((m_physicsActor != null) && (m_avHeight > 0))
1708 { 1784 {
1709 SetHeight(m_avHeight); 1785 SetHeight(m_avHeight);
1710 } 1786 }
1711 } 1787 }
1712
1713 Animator.TrySetMovementAnimation("STAND"); 1788 Animator.TrySetMovementAnimation("STAND");
1714 } 1789 }
1715 1790
@@ -1740,13 +1815,9 @@ namespace OpenSim.Region.Framework.Scenes
1740 Vector3 avSitOffSet = part.SitTargetPosition; 1815 Vector3 avSitOffSet = part.SitTargetPosition;
1741 Quaternion avSitOrientation = part.SitTargetOrientation; 1816 Quaternion avSitOrientation = part.SitTargetOrientation;
1742 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1817 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1743 1818 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1744 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1819 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1745 bool SitTargetisSet = 1820 if (SitTargetisSet && !SitTargetOccupied)
1746 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1747 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1748
1749 if (SitTargetisSet && SitTargetUnOccupied)
1750 { 1821 {
1751 //switch the target to this prim 1822 //switch the target to this prim
1752 return part; 1823 return part;
@@ -1760,84 +1831,153 @@ namespace OpenSim.Region.Framework.Scenes
1760 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1831 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1761 { 1832 {
1762 bool autopilot = true; 1833 bool autopilot = true;
1834 Vector3 autopilotTarget = new Vector3();
1835 Quaternion sitOrientation = Quaternion.Identity;
1763 Vector3 pos = new Vector3(); 1836 Vector3 pos = new Vector3();
1764 Quaternion sitOrientation = pSitOrientation;
1765 Vector3 cameraEyeOffset = Vector3.Zero; 1837 Vector3 cameraEyeOffset = Vector3.Zero;
1766 Vector3 cameraAtOffset = Vector3.Zero; 1838 Vector3 cameraAtOffset = Vector3.Zero;
1767 bool forceMouselook = false; 1839 bool forceMouselook = false;
1768 1840
1769 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1841 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1770 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1842 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1771 if (part != null) 1843 if (part == null) return;
1772 { 1844
1773 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1845 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1774 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1846 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1775 1847
1776 // Is a sit target available? 1848 // part is the prim to sit on
1777 Vector3 avSitOffSet = part.SitTargetPosition; 1849 // offset is the world-ref vector distance from that prim center to the click-spot
1778 Quaternion avSitOrientation = part.SitTargetOrientation; 1850 // UUID is the UUID of the Avatar doing the clicking
1779 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1851
1780 1852 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1781 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1853
1782 bool SitTargetisSet = 1854 // Is a sit target available?
1783 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1855 Vector3 avSitOffSet = part.SitTargetPosition;
1784 ( 1856 Quaternion avSitOrientation = part.SitTargetOrientation;
1785 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1857
1786 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1858 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1787 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1859 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1788 ) 1860 Quaternion partRot;
1789 )); 1861// if (part.LinkNum == 1)
1790 1862// { // Root prim of linkset
1791 if (SitTargetisSet && SitTargetUnOccupied) 1863// partRot = part.ParentGroup.RootPart.RotationOffset;
1792 { 1864// }
1793 part.SetAvatarOnSitTarget(UUID); 1865// else
1794 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1866// { // single or child prim
1795 sitOrientation = avSitOrientation; 1867 partRot = part.GetWorldRotation();
1796 autopilot = false; 1868// }
1797 } 1869 Quaternion partIRot = Quaternion.Inverse(partRot);
1798 1870//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1799 pos = part.AbsolutePosition + offset; 1871 // Sit analysis rewritten by KF 091125
1800 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1872 if (SitTargetisSet) // scipted sit
1801 //{ 1873 {
1802 // offset = pos; 1874 if (!part.IsOccupied)
1803 //autopilot = false; 1875 {
1804 //} 1876//Console.WriteLine("Scripted, unoccupied");
1805 if (m_physicsActor != null) 1877 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1806 { 1878 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1807 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1879 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1808 // We can remove the physicsActor until they stand up. 1880 autopilot = false; // Jump direct to scripted llSitPos()
1809 m_sitAvatarHeight = m_physicsActor.Size.Z; 1881 }
1810 1882 else
1811 if (autopilot) 1883 {
1812 { 1884//Console.WriteLine("Scripted, occupied");
1813 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1885 return;
1814 { 1886 }
1815 autopilot = false; 1887 }
1888 else // Not Scripted
1889 {
1890 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1891 {
1892 // large prim & offset, ignore if other Avs sitting
1893// offset.Z -= 0.05f;
1894 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1895 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1896
1897//Console.WriteLine(" offset ={0}", offset);
1898//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1899//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1900
1901 }
1902 else // small offset
1903 {
1904//Console.WriteLine("Small offset");
1905 if (!part.IsOccupied)
1906 {
1907 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1908 autopilotTarget = part.AbsolutePosition;
1909//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1910 }
1911 else return; // occupied small
1912 } // end large/small
1913 } // end Scripted/not
1914 cameraAtOffset = part.GetCameraAtOffset();
1915 cameraEyeOffset = part.GetCameraEyeOffset();
1916 forceMouselook = part.GetForceMouselook();
1917 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1918 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1816 1919
1817 RemoveFromPhysicalScene(); 1920 if (m_physicsActor != null)
1818 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1921 {
1819 } 1922 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1820 } 1923 // We can remove the physicsActor until they stand up.
1821 else 1924 m_sitAvatarHeight = m_physicsActor.Size.Z;
1925 if (autopilot)
1926 { // its not a scripted sit
1927// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1928 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1822 { 1929 {
1930 autopilot = false; // close enough
1931 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1932 Not using the part's position because returning the AV to the last known standing
1933 position is likely to be more friendly, isn't it? */
1823 RemoveFromPhysicalScene(); 1934 RemoveFromPhysicalScene();
1824 } 1935 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1936 } // else the autopilot will get us close
1937 }
1938 else
1939 { // its a scripted sit
1940 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1941 I *am* using the part's position this time because we have no real idea how far away
1942 the avatar is from the sit target. */
1943 RemoveFromPhysicalScene();
1825 } 1944 }
1826
1827 cameraAtOffset = part.GetCameraAtOffset();
1828 cameraEyeOffset = part.GetCameraEyeOffset();
1829 forceMouselook = part.GetForceMouselook();
1830 } 1945 }
1831 1946 else return; // physactor is null!
1832 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1947
1833 m_requestedSitTargetUUID = targetID; 1948 Vector3 offsetr; // = offset * partIRot;
1949 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1950 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1951 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1952 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1953 offsetr = offset * partIRot;
1954//
1955 // else
1956 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1957 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1958 // (offset * partRot);
1959 // }
1960
1961//Console.WriteLine(" ");
1962//Console.WriteLine("link number ={0}", part.LinkNum);
1963//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1964//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1965//Console.WriteLine("Click offst ={0}", offset);
1966//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1967//Console.WriteLine("offsetr ={0}", offsetr);
1968//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1969//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1970
1971 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1972 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1834 // This calls HandleAgentSit twice, once from here, and the client calls 1973 // This calls HandleAgentSit twice, once from here, and the client calls
1835 // HandleAgentSit itself after it gets to the location 1974 // HandleAgentSit itself after it gets to the location
1836 // It doesn't get to the location until we've moved them there though 1975 // It doesn't get to the location until we've moved them there though
1837 // which happens in HandleAgentSit :P 1976 // which happens in HandleAgentSit :P
1838 m_autopilotMoving = autopilot; 1977 m_autopilotMoving = autopilot;
1839 m_autoPilotTarget = pos; 1978 m_autoPilotTarget = autopilotTarget;
1840 m_sitAtAutoTarget = autopilot; 1979 m_sitAtAutoTarget = autopilot;
1980 m_initialSitTarget = autopilotTarget;
1841 if (!autopilot) 1981 if (!autopilot)
1842 HandleAgentSit(remoteClient, UUID); 1982 HandleAgentSit(remoteClient, UUID);
1843 } 1983 }
@@ -2132,31 +2272,66 @@ namespace OpenSim.Region.Framework.Scenes
2132 { 2272 {
2133 if (part != null) 2273 if (part != null)
2134 { 2274 {
2275//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2135 if (part.GetAvatarOnSitTarget() == UUID) 2276 if (part.GetAvatarOnSitTarget() == UUID)
2136 { 2277 {
2278//Console.WriteLine("Scripted Sit");
2279 // Scripted sit
2137 Vector3 sitTargetPos = part.SitTargetPosition; 2280 Vector3 sitTargetPos = part.SitTargetPosition;
2138 Quaternion sitTargetOrient = part.SitTargetOrientation; 2281 Quaternion sitTargetOrient = part.SitTargetOrientation;
2139
2140 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2141 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2142
2143 //Quaternion result = (sitTargetOrient * vq) * nq;
2144
2145 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2282 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2146 m_pos += SIT_TARGET_ADJUSTMENT; 2283 m_pos += SIT_TARGET_ADJUSTMENT;
2147 m_bodyRot = sitTargetOrient; 2284 m_bodyRot = sitTargetOrient;
2148 //Rotation = sitTargetOrient;
2149 m_parentPosition = part.AbsolutePosition; 2285 m_parentPosition = part.AbsolutePosition;
2150 2286 part.IsOccupied = true;
2151 //SendTerseUpdateToAllClients(); 2287Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2152 } 2288 }
2153 else 2289 else
2154 { 2290 {
2155 m_pos -= part.AbsolutePosition; 2291 // if m_avUnscriptedSitPos is zero then Av sits above center
2292 // Else Av sits at m_avUnscriptedSitPos
2293
2294 // Non-scripted sit by Kitto Flora 21Nov09
2295 // Calculate angle of line from prim to Av
2296 Quaternion partIRot;
2297// if (part.LinkNum == 1)
2298// { // Root prim of linkset
2299// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2300// }
2301// else
2302// { // single or child prim
2303 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2304// }
2305 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2306 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2307 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2308 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2309 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2310 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2311 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2312 // Av sits at world euler <0,0, z>, translated by part rotation
2313 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2314
2156 m_parentPosition = part.AbsolutePosition; 2315 m_parentPosition = part.AbsolutePosition;
2157 } 2316 part.IsOccupied = true;
2317 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2318 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2319 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2320 m_avUnscriptedSitPos; // adds click offset, if any
2321 //Set up raytrace to find top surface of prim
2322 Vector3 size = part.Scale;
2323 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2324 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2325 Vector3 down = new Vector3(0f, 0f, -1f);
2326//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2327 m_scene.PhysicsScene.RaycastWorld(
2328 start, // Vector3 position,
2329 down, // Vector3 direction,
2330 mag, // float length,
2331 SitAltitudeCallback); // retMethod
2332 } // end scripted/not
2158 } 2333 }
2159 else 2334 else // no Av
2160 { 2335 {
2161 return; 2336 return;
2162 } 2337 }
@@ -2168,11 +2343,36 @@ namespace OpenSim.Region.Framework.Scenes
2168 2343
2169 Animator.TrySetMovementAnimation(sitAnimation); 2344 Animator.TrySetMovementAnimation(sitAnimation);
2170 SendFullUpdateToAllClients(); 2345 SendFullUpdateToAllClients();
2171 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2172 // So we're also sending a terse update (which has avatar rotation)
2173 // [Update] We do now.
2174 //SendTerseUpdateToAllClients();
2175 } 2346 }
2347
2348 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2349 {
2350 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2351 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2352 if(hitYN)
2353 {
2354 // m_pos = Av offset from prim center to make look like on center
2355 // m_parentPosition = Actual center pos of prim
2356 // collisionPoint = spot on prim where we want to sit
2357 // collisionPoint.Z = global sit surface height
2358 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2359 Quaternion partIRot;
2360// if (part.LinkNum == 1)
2361/// { // Root prim of linkset
2362// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2363// }
2364// else
2365// { // single or child prim
2366 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2367// }
2368 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2369 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2370//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2371 m_pos += offset;
2372// ControllingClient.SendClearFollowCamProperties(part.UUID);
2373
2374 }
2375 } // End SitAltitudeCallback KF.
2176 2376
2177 /// <summary> 2377 /// <summary>
2178 /// Event handler for the 'Always run' setting on the client 2378 /// Event handler for the 'Always run' setting on the client
@@ -2202,7 +2402,7 @@ namespace OpenSim.Region.Framework.Scenes
2202 /// </summary> 2402 /// </summary>
2203 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2403 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2204 /// <param name="rotation">The direction in which this avatar should now face. 2404 /// <param name="rotation">The direction in which this avatar should now face.
2205 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2405 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2206 { 2406 {
2207 if (m_isChildAgent) 2407 if (m_isChildAgent)
2208 { 2408 {
@@ -2279,7 +2479,7 @@ namespace OpenSim.Region.Framework.Scenes
2279 2479
2280 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2480 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2281 m_forceToApply = direc; 2481 m_forceToApply = direc;
2282 2482 m_isNudging = Nudging;
2283 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2483 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2284 } 2484 }
2285 2485
@@ -2294,7 +2494,7 @@ namespace OpenSim.Region.Framework.Scenes
2294 const float POSITION_TOLERANCE = 0.05f; 2494 const float POSITION_TOLERANCE = 0.05f;
2295 //const int TIME_MS_TOLERANCE = 3000; 2495 //const int TIME_MS_TOLERANCE = 3000;
2296 2496
2297 SendPrimUpdates(); 2497
2298 2498
2299 if (m_newCoarseLocations) 2499 if (m_newCoarseLocations)
2300 { 2500 {
@@ -2330,6 +2530,9 @@ namespace OpenSim.Region.Framework.Scenes
2330 CheckForBorderCrossing(); 2530 CheckForBorderCrossing();
2331 CheckForSignificantMovement(); // sends update to the modules. 2531 CheckForSignificantMovement(); // sends update to the modules.
2332 } 2532 }
2533
2534 //Sending prim updates AFTER the avatar terse updates are sent
2535 SendPrimUpdates();
2333 } 2536 }
2334 2537
2335 #endregion 2538 #endregion
@@ -3146,6 +3349,7 @@ namespace OpenSim.Region.Framework.Scenes
3146 m_callbackURI = cAgent.CallbackURI; 3349 m_callbackURI = cAgent.CallbackURI;
3147 3350
3148 m_pos = cAgent.Position; 3351 m_pos = cAgent.Position;
3352
3149 m_velocity = cAgent.Velocity; 3353 m_velocity = cAgent.Velocity;
3150 m_CameraCenter = cAgent.Center; 3354 m_CameraCenter = cAgent.Center;
3151 //m_avHeight = cAgent.Size.Z; 3355 //m_avHeight = cAgent.Size.Z;
@@ -3234,14 +3438,25 @@ namespace OpenSim.Region.Framework.Scenes
3234 { 3438 {
3235 if (m_forceToApply.HasValue) 3439 if (m_forceToApply.HasValue)
3236 { 3440 {
3237 Vector3 force = m_forceToApply.Value;
3238 3441
3442 Vector3 force = m_forceToApply.Value;
3239 m_updateflag = true; 3443 m_updateflag = true;
3240// movementvector = force;
3241 Velocity = force; 3444 Velocity = force;
3242 3445
3243 m_forceToApply = null; 3446 m_forceToApply = null;
3244 } 3447 }
3448 else
3449 {
3450 if (m_isNudging)
3451 {
3452 Vector3 force = Vector3.Zero;
3453
3454 m_updateflag = true;
3455 Velocity = force;
3456 m_isNudging = false;
3457 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3458 }
3459 }
3245 } 3460 }
3246 3461
3247 public override void SetText(string text, Vector3 color, double alpha) 3462 public override void SetText(string text, Vector3 color, double alpha)
@@ -3292,18 +3507,29 @@ namespace OpenSim.Region.Framework.Scenes
3292 { 3507 {
3293 if (e == null) 3508 if (e == null)
3294 return; 3509 return;
3295 3510
3296 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3511 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3297 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3298 // as of this comment the interval is set in AddToPhysicalScene 3512 // as of this comment the interval is set in AddToPhysicalScene
3299 if (Animator!=null) 3513 if (Animator!=null)
3300 Animator.UpdateMovementAnimations(); 3514 {
3515 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3516 { // else its will lock out other animation changes, like ground sit.
3517 Animator.UpdateMovementAnimations();
3518 m_updateCount--;
3519 }
3520 }
3301 3521
3302 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3522 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3303 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3523 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3304 3524
3305 CollisionPlane = Vector4.UnitW; 3525 CollisionPlane = Vector4.UnitW;
3306 3526
3527 if (m_lastColCount != coldata.Count)
3528 {
3529 m_updateCount = UPDATE_COUNT;
3530 m_lastColCount = coldata.Count;
3531 }
3532
3307 if (coldata.Count != 0 && Animator != null) 3533 if (coldata.Count != 0 && Animator != null)
3308 { 3534 {
3309 switch (Animator.CurrentMovementAnimation) 3535 switch (Animator.CurrentMovementAnimation)
@@ -3738,6 +3964,32 @@ namespace OpenSim.Region.Framework.Scenes
3738 return; 3964 return;
3739 } 3965 }
3740 3966
3967 XmlDocument doc = new XmlDocument();
3968 string stateData = String.Empty;
3969
3970 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
3971 if (attServ != null)
3972 {
3973 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
3974 stateData = attServ.Get(ControllingClient.AgentId.ToString());
3975 doc.LoadXml(stateData);
3976 }
3977
3978 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
3979
3980 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
3981 if (nodes.Count > 0)
3982 {
3983 foreach (XmlNode n in nodes)
3984 {
3985 XmlElement elem = (XmlElement)n;
3986 string itemID = elem.GetAttribute("ItemID");
3987 string xml = elem.InnerXml;
3988
3989 itemData[new UUID(itemID)] = xml;
3990 }
3991 }
3992
3741 List<int> attPoints = m_appearance.GetAttachedPoints(); 3993 List<int> attPoints = m_appearance.GetAttachedPoints();
3742 foreach (int p in attPoints) 3994 foreach (int p in attPoints)
3743 { 3995 {
@@ -3757,9 +4009,26 @@ namespace OpenSim.Region.Framework.Scenes
3757 4009
3758 try 4010 try
3759 { 4011 {
3760 // Rez from inventory 4012 string xmlData;
3761 UUID asset 4013 XmlDocument d = new XmlDocument();
3762 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4014 UUID asset;
4015 if (itemData.TryGetValue(itemID, out xmlData))
4016 {
4017 d.LoadXml(xmlData);
4018 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4019
4020 // Rez from inventory
4021 asset
4022 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4023
4024 }
4025 else
4026 {
4027 // Rez from inventory (with a null doc to let
4028 // CHANGED_OWNER happen)
4029 asset
4030 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4031 }
3763 4032
3764 m_log.InfoFormat( 4033 m_log.InfoFormat(
3765 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", 4034 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
@@ -3910,5 +4179,16 @@ namespace OpenSim.Region.Framework.Scenes
3910 m_reprioritization_called = false; 4179 m_reprioritization_called = false;
3911 } 4180 }
3912 } 4181 }
4182
4183 private Vector3 Quat2Euler(Quaternion rot){
4184 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4185 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4186 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4187 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4188 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4189 return(new Vector3(x,y,z));
4190 }
4191
4192
3913 } 4193 }
3914} 4194}