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