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.cs577
1 files changed, 403 insertions, 174 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 6b95624..1b7ca8b 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
@@ -156,7 +160,6 @@ namespace OpenSim.Region.Framework.Scenes
156 private int m_perfMonMS; 160 private int m_perfMonMS;
157 161
158 private bool m_setAlwaysRun; 162 private bool m_setAlwaysRun;
159
160 private bool m_forceFly; 163 private bool m_forceFly;
161 private bool m_flyDisabled; 164 private bool m_flyDisabled;
162 165
@@ -180,7 +183,8 @@ namespace OpenSim.Region.Framework.Scenes
180 protected RegionInfo m_regionInfo; 183 protected RegionInfo m_regionInfo;
181 protected ulong crossingFromRegion; 184 protected ulong crossingFromRegion;
182 185
183 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 186 private readonly Vector3[] Dir_Vectors = new Vector3[11];
187 private bool m_isNudging = false;
184 188
185 // Position of agent's camera in world (region cordinates) 189 // Position of agent's camera in world (region cordinates)
186 protected Vector3 m_CameraCenter; 190 protected Vector3 m_CameraCenter;
@@ -205,6 +209,7 @@ namespace OpenSim.Region.Framework.Scenes
205 private bool m_autopilotMoving; 209 private bool m_autopilotMoving;
206 private Vector3 m_autoPilotTarget; 210 private Vector3 m_autoPilotTarget;
207 private bool m_sitAtAutoTarget; 211 private bool m_sitAtAutoTarget;
212 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
208 213
209 private string m_nextSitAnimation = String.Empty; 214 private string m_nextSitAnimation = String.Empty;
210 215
@@ -215,6 +220,9 @@ namespace OpenSim.Region.Framework.Scenes
215 private bool m_followCamAuto; 220 private bool m_followCamAuto;
216 221
217 private int m_movementUpdateCount; 222 private int m_movementUpdateCount;
223 private int m_lastColCount = -1; //KF: Look for Collision chnages
224 private int m_updateCount = 0; //KF: Update Anims for a while
225 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
218 226
219 private const int NumMovementsBetweenRayCast = 5; 227 private const int NumMovementsBetweenRayCast = 5;
220 228
@@ -243,7 +251,9 @@ namespace OpenSim.Region.Framework.Scenes
243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 251 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 252 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 253 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
246 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 254 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
255 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
256 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
247 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 257 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
248 } 258 }
249 259
@@ -672,10 +682,7 @@ namespace OpenSim.Region.Framework.Scenes
672 m_reprioritization_timer.AutoReset = false; 682 m_reprioritization_timer.AutoReset = false;
673 683
674 AdjustKnownSeeds(); 684 AdjustKnownSeeds();
675
676 // TODO: I think, this won't send anything, as we are still a child here...
677 Animator.TrySetMovementAnimation("STAND"); 685 Animator.TrySetMovementAnimation("STAND");
678
679 // we created a new ScenePresence (a new child agent) in a fresh region. 686 // we created a new ScenePresence (a new child agent) in a fresh region.
680 // Request info about all the (root) agents in this region 687 // Request info about all the (root) agents in this region
681 // Note: This won't send data *to* other clients in that region (children don't send) 688 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -731,25 +738,47 @@ namespace OpenSim.Region.Framework.Scenes
731 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 738 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
732 Dir_Vectors[4] = Vector3.UnitZ; //UP 739 Dir_Vectors[4] = Vector3.UnitZ; //UP
733 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 740 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
734 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 741 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
735 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 742 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
736 Dir_Vectors[7] = -Vector3.UnitX; //BACK 743 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
744 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
745 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
737 } 746 }
738 747
739 private Vector3[] GetWalkDirectionVectors() 748 private Vector3[] GetWalkDirectionVectors()
740 { 749 {
741 Vector3[] vector = new Vector3[9]; 750 Vector3[] vector = new Vector3[11];
742 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 751 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
743 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 752 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
744 vector[2] = Vector3.UnitY; //LEFT 753 vector[2] = Vector3.UnitY; //LEFT
745 vector[3] = -Vector3.UnitY; //RIGHT 754 vector[3] = -Vector3.UnitY; //RIGHT
746 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 755 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
747 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 756 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
748 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 757 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
749 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 758 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
750 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 759 vector[8] = Vector3.UnitY; //LEFT_NUDGE
760 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
761 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
751 return vector; 762 return vector;
752 } 763 }
764
765 private bool[] GetDirectionIsNudge()
766 {
767 bool[] isNudge = new bool[11];
768 isNudge[0] = false; //FORWARD
769 isNudge[1] = false; //BACK
770 isNudge[2] = false; //LEFT
771 isNudge[3] = false; //RIGHT
772 isNudge[4] = false; //UP
773 isNudge[5] = false; //DOWN
774 isNudge[6] = true; //FORWARD_NUDGE
775 isNudge[7] = true; //BACK_NUDGE
776 isNudge[8] = true; //LEFT_NUDGE
777 isNudge[9] = true; //RIGHT_NUDGE
778 isNudge[10] = true; //DOWN_Nudge
779 return isNudge;
780 }
781
753 782
754 #endregion 783 #endregion
755 784
@@ -818,9 +847,24 @@ namespace OpenSim.Region.Framework.Scenes
818 { 847 {
819 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 848 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
820 pos.Y = crossedBorder.BorderLine.Z - 1; 849 pos.Y = crossedBorder.BorderLine.Z - 1;
850 }
851
852 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
853 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
854 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
855 if (KnownChildRegionHandles.Count == 0)
856 {
857 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
858 if (land != null)
859 {
860 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
861 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godlevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
862 {
863 pos = land.LandData.UserLocation;
864 }
865 }
821 } 866 }
822 867
823
824 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 868 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
825 { 869 {
826 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 870 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -955,9 +999,10 @@ namespace OpenSim.Region.Framework.Scenes
955 public void Teleport(Vector3 pos) 999 public void Teleport(Vector3 pos)
956 { 1000 {
957 bool isFlying = false; 1001 bool isFlying = false;
958 if (m_physicsActor != null)
959 isFlying = m_physicsActor.Flying;
960 1002
1003 if (m_physicsActor != null)
1004 isFlying = m_physicsActor.Flying;
1005
961 RemoveFromPhysicalScene(); 1006 RemoveFromPhysicalScene();
962 Velocity = Vector3.Zero; 1007 Velocity = Vector3.Zero;
963 AbsolutePosition = pos; 1008 AbsolutePosition = pos;
@@ -968,7 +1013,8 @@ namespace OpenSim.Region.Framework.Scenes
968 SetHeight(m_appearance.AvatarHeight); 1013 SetHeight(m_appearance.AvatarHeight);
969 } 1014 }
970 1015
971 SendTerseUpdateToAllClients(); 1016 SendTerseUpdateToAllClients();
1017
972 } 1018 }
973 1019
974 public void TeleportWithMomentum(Vector3 pos) 1020 public void TeleportWithMomentum(Vector3 pos)
@@ -1013,7 +1059,9 @@ namespace OpenSim.Region.Framework.Scenes
1013 { 1059 {
1014 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1060 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1015 } 1061 }
1016 1062
1063 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1064
1017 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1065 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1018 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1066 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1019 } 1067 }
@@ -1247,7 +1295,6 @@ namespace OpenSim.Region.Framework.Scenes
1247 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1295 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1248 } 1296 }
1249 } 1297 }
1250
1251 lock (scriptedcontrols) 1298 lock (scriptedcontrols)
1252 { 1299 {
1253 if (scriptedcontrols.Count > 0) 1300 if (scriptedcontrols.Count > 0)
@@ -1262,12 +1309,8 @@ namespace OpenSim.Region.Framework.Scenes
1262 1309
1263 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1310 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1264 { 1311 {
1265 // TODO: This doesn't prevent the user from walking yet. 1312 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1266 // Setting parent ID would fix this, if we knew what value 1313 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1267 // to use. Or we could add a m_isSitting variable.
1268 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1269 SitGround = true;
1270
1271 } 1314 }
1272 1315
1273 // In the future, these values might need to go global. 1316 // In the future, these values might need to go global.
@@ -1317,6 +1360,11 @@ namespace OpenSim.Region.Framework.Scenes
1317 update_rotation = true; 1360 update_rotation = true;
1318 } 1361 }
1319 1362
1363 //guilty until proven innocent..
1364 bool Nudging = true;
1365 //Basically, if there is at least one non-nudge control then we don't need
1366 //to worry about stopping the avatar
1367
1320 if (m_parentID == 0) 1368 if (m_parentID == 0)
1321 { 1369 {
1322 bool bAllowUpdateMoveToPosition = false; 1370 bool bAllowUpdateMoveToPosition = false;
@@ -1331,9 +1379,12 @@ namespace OpenSim.Region.Framework.Scenes
1331 else 1379 else
1332 dirVectors = Dir_Vectors; 1380 dirVectors = Dir_Vectors;
1333 1381
1334 // The fact that m_movementflag is a byte needs to be fixed 1382 bool[] isNudge = GetDirectionIsNudge();
1335 // it really should be a uint 1383
1336 uint nudgehack = 250; 1384
1385
1386
1387
1337 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1388 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1338 { 1389 {
1339 if (((uint)flags & (uint)DCF) != 0) 1390 if (((uint)flags & (uint)DCF) != 0)
@@ -1343,40 +1394,28 @@ namespace OpenSim.Region.Framework.Scenes
1343 try 1394 try
1344 { 1395 {
1345 agent_control_v3 += dirVectors[i]; 1396 agent_control_v3 += dirVectors[i];
1346 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1397 if (isNudge[i] == false)
1398 {
1399 Nudging = false;
1400 }
1347 } 1401 }
1348 catch (IndexOutOfRangeException) 1402 catch (IndexOutOfRangeException)
1349 { 1403 {
1350 // Why did I get this? 1404 // Why did I get this?
1351 } 1405 }
1352 1406
1353 if ((m_movementflag & (byte)(uint)DCF) == 0) 1407 if ((m_movementflag & (uint)DCF) == 0)
1354 { 1408 {
1355 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1356 {
1357 m_movementflag |= (byte)nudgehack;
1358 }
1359 m_movementflag += (byte)(uint)DCF; 1409 m_movementflag += (byte)(uint)DCF;
1360 update_movementflag = true; 1410 update_movementflag = true;
1361 } 1411 }
1362 } 1412 }
1363 else 1413 else
1364 { 1414 {
1365 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1415 if ((m_movementflag & (uint)DCF) != 0)
1366 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1367 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1368 ) // This or is for Nudge forward
1369 { 1416 {
1370 m_movementflag -= ((byte)(uint)DCF); 1417 m_movementflag -= (byte)(uint)DCF;
1371
1372 update_movementflag = true; 1418 update_movementflag = true;
1373 /*
1374 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1375 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1376 {
1377 m_log.Debug("Removed Hack flag");
1378 }
1379 */
1380 } 1419 }
1381 else 1420 else
1382 { 1421 {
@@ -1420,6 +1459,9 @@ namespace OpenSim.Region.Framework.Scenes
1420 // Ignore z component of vector 1459 // Ignore z component of vector
1421 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1460 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1422 LocalVectorToTarget2D.Normalize(); 1461 LocalVectorToTarget2D.Normalize();
1462
1463 //We're not nudging
1464 Nudging = false;
1423 agent_control_v3 += LocalVectorToTarget2D; 1465 agent_control_v3 += LocalVectorToTarget2D;
1424 1466
1425 // update avatar movement flags. the avatar coordinate system is as follows: 1467 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1508,13 +1550,13 @@ namespace OpenSim.Region.Framework.Scenes
1508 // m_log.DebugFormat( 1550 // m_log.DebugFormat(
1509 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1551 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1510 1552
1511 AddNewMovement(agent_control_v3, q); 1553 AddNewMovement(agent_control_v3, q, Nudging);
1512 1554
1513 1555
1514 } 1556 }
1515 } 1557 }
1516 1558
1517 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1559 if (update_movementflag)
1518 Animator.UpdateMovementAnimations(); 1560 Animator.UpdateMovementAnimations();
1519 1561
1520 m_scene.EventManager.TriggerOnClientMovement(this); 1562 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1529,7 +1571,6 @@ namespace OpenSim.Region.Framework.Scenes
1529 m_sitAtAutoTarget = false; 1571 m_sitAtAutoTarget = false;
1530 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1572 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1531 //proxy.PCode = (byte)PCode.ParticleSystem; 1573 //proxy.PCode = (byte)PCode.ParticleSystem;
1532
1533 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1574 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1534 proxyObjectGroup.AttachToScene(m_scene); 1575 proxyObjectGroup.AttachToScene(m_scene);
1535 1576
@@ -1571,7 +1612,7 @@ namespace OpenSim.Region.Framework.Scenes
1571 } 1612 }
1572 m_moveToPositionInProgress = true; 1613 m_moveToPositionInProgress = true;
1573 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1614 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1574 } 1615 }
1575 catch (Exception ex) 1616 catch (Exception ex)
1576 { 1617 {
1577 //Why did I get this error? 1618 //Why did I get this error?
@@ -1593,7 +1634,7 @@ namespace OpenSim.Region.Framework.Scenes
1593 Velocity = Vector3.Zero; 1634 Velocity = Vector3.Zero;
1594 SendFullUpdateToAllClients(); 1635 SendFullUpdateToAllClients();
1595 1636
1596 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1637 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1597 } 1638 }
1598 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1639 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1599 m_requestedSitTargetUUID = UUID.Zero; 1640 m_requestedSitTargetUUID = UUID.Zero;
@@ -1626,55 +1667,84 @@ namespace OpenSim.Region.Framework.Scenes
1626 /// </summary> 1667 /// </summary>
1627 public void StandUp() 1668 public void StandUp()
1628 { 1669 {
1629 if (SitGround)
1630 SitGround = false;
1631
1632 if (m_parentID != 0) 1670 if (m_parentID != 0)
1633 { 1671 {
1634 m_log.Debug("StandupCode Executed");
1635 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1672 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1636 if (part != null) 1673 if (part != null)
1637 { 1674 {
1675 part.TaskInventory.LockItemsForRead(true);
1638 TaskInventoryDictionary taskIDict = part.TaskInventory; 1676 TaskInventoryDictionary taskIDict = part.TaskInventory;
1639 if (taskIDict != null) 1677 if (taskIDict != null)
1640 { 1678 {
1641 lock (taskIDict) 1679 foreach (UUID taskID in taskIDict.Keys)
1642 { 1680 {
1643 foreach (UUID taskID in taskIDict.Keys) 1681 UnRegisterControlEventsToScript(LocalId, taskID);
1644 { 1682 taskIDict[taskID].PermsMask &= ~(
1645 UnRegisterControlEventsToScript(LocalId, taskID); 1683 2048 | //PERMISSION_CONTROL_CAMERA
1646 taskIDict[taskID].PermsMask &= ~( 1684 4); // PERMISSION_TAKE_CONTROLS
1647 2048 | //PERMISSION_CONTROL_CAMERA
1648 4); // PERMISSION_TAKE_CONTROLS
1649 }
1650 } 1685 }
1651
1652 } 1686 }
1687 part.TaskInventory.LockItemsForRead(false);
1653 // Reset sit target. 1688 // Reset sit target.
1654 if (part.GetAvatarOnSitTarget() == UUID) 1689 if (part.GetAvatarOnSitTarget() == UUID)
1655 part.SetAvatarOnSitTarget(UUID.Zero); 1690 part.SetAvatarOnSitTarget(UUID.Zero);
1656
1657 m_parentPosition = part.GetWorldPosition(); 1691 m_parentPosition = part.GetWorldPosition();
1658 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1692 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1659 } 1693 }
1660 1694 // part.GetWorldRotation() is the rotation of the object being sat on
1661 if (m_physicsActor == null) 1695 // Rotation is the sittiing Av's rotation
1662 { 1696
1663 AddToPhysicalScene(false); 1697 Quaternion partRot;
1698// if (part.LinkNum == 1)
1699// { // Root prim of linkset
1700// partRot = part.ParentGroup.RootPart.RotationOffset;
1701// }
1702// else
1703// { // single or child prim
1704
1705// }
1706 if (part == null) //CW: Part may be gone. llDie() for example.
1707 {
1708 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1709 }
1710 else
1711 {
1712 partRot = part.GetWorldRotation();
1713 }
1714
1715 Quaternion partIRot = Quaternion.Inverse(partRot);
1716
1717 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1718 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1719
1720
1721 if (m_physicsActor == null)
1722 {
1723 AddToPhysicalScene(false);
1724 }
1725 //CW: If the part isn't null then we can set the current position
1726 if (part != null)
1727 {
1728 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1729 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1730 part.IsOccupied = false;
1731 }
1732 else
1733 {
1734 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1735 AbsolutePosition = m_lastWorldPosition;
1664 } 1736 }
1665 1737
1666 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1738 m_parentPosition = Vector3.Zero;
1667 m_parentPosition = Vector3.Zero; 1739 m_parentID = 0;
1668
1669 m_parentID = 0;
1670 SendFullUpdateToAllClients(); 1740 SendFullUpdateToAllClients();
1671 m_requestedSitTargetID = 0; 1741 m_requestedSitTargetID = 0;
1742
1672 if ((m_physicsActor != null) && (m_avHeight > 0)) 1743 if ((m_physicsActor != null) && (m_avHeight > 0))
1673 { 1744 {
1674 SetHeight(m_avHeight); 1745 SetHeight(m_avHeight);
1675 } 1746 }
1676 } 1747 }
1677
1678 Animator.TrySetMovementAnimation("STAND"); 1748 Animator.TrySetMovementAnimation("STAND");
1679 } 1749 }
1680 1750
@@ -1705,13 +1775,9 @@ namespace OpenSim.Region.Framework.Scenes
1705 Vector3 avSitOffSet = part.SitTargetPosition; 1775 Vector3 avSitOffSet = part.SitTargetPosition;
1706 Quaternion avSitOrientation = part.SitTargetOrientation; 1776 Quaternion avSitOrientation = part.SitTargetOrientation;
1707 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1777 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1708 1778 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1709 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1779 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1710 bool SitTargetisSet = 1780 if (SitTargetisSet && !SitTargetOccupied)
1711 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1712 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1713
1714 if (SitTargetisSet && SitTargetUnOccupied)
1715 { 1781 {
1716 //switch the target to this prim 1782 //switch the target to this prim
1717 return part; 1783 return part;
@@ -1725,84 +1791,152 @@ namespace OpenSim.Region.Framework.Scenes
1725 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1791 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1726 { 1792 {
1727 bool autopilot = true; 1793 bool autopilot = true;
1794 Vector3 autopilotTarget = new Vector3();
1795 Quaternion sitOrientation = Quaternion.Identity;
1728 Vector3 pos = new Vector3(); 1796 Vector3 pos = new Vector3();
1729 Quaternion sitOrientation = pSitOrientation;
1730 Vector3 cameraEyeOffset = Vector3.Zero; 1797 Vector3 cameraEyeOffset = Vector3.Zero;
1731 Vector3 cameraAtOffset = Vector3.Zero; 1798 Vector3 cameraAtOffset = Vector3.Zero;
1732 bool forceMouselook = false; 1799 bool forceMouselook = false;
1733 1800
1734 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1801 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1735 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1802 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1736 if (part != null) 1803 if (part == null) return;
1737 { 1804
1738 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1805 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1739 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1806 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1740 1807
1741 // Is a sit target available? 1808 // part is the prim to sit on
1742 Vector3 avSitOffSet = part.SitTargetPosition; 1809 // offset is the world-ref vector distance from that prim center to the click-spot
1743 Quaternion avSitOrientation = part.SitTargetOrientation; 1810 // UUID is the UUID of the Avatar doing the clicking
1744 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1811
1745 1812 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1746 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1813
1747 bool SitTargetisSet = 1814 // Is a sit target available?
1748 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1815 Vector3 avSitOffSet = part.SitTargetPosition;
1749 ( 1816 Quaternion avSitOrientation = part.SitTargetOrientation;
1750 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1817
1751 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1818 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1752 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1819 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1753 ) 1820 Quaternion partRot;
1754 )); 1821// if (part.LinkNum == 1)
1755 1822// { // Root prim of linkset
1756 if (SitTargetisSet && SitTargetUnOccupied) 1823// partRot = part.ParentGroup.RootPart.RotationOffset;
1757 { 1824// }
1758 part.SetAvatarOnSitTarget(UUID); 1825// else
1759 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1826// { // single or child prim
1760 sitOrientation = avSitOrientation; 1827 partRot = part.GetWorldRotation();
1761 autopilot = false; 1828// }
1762 } 1829 Quaternion partIRot = Quaternion.Inverse(partRot);
1763 1830//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1764 pos = part.AbsolutePosition + offset; 1831 // Sit analysis rewritten by KF 091125
1765 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1832 if (SitTargetisSet) // scipted sit
1766 //{ 1833 {
1767 // offset = pos; 1834 if (!part.IsOccupied)
1768 //autopilot = false; 1835 {
1769 //} 1836//Console.WriteLine("Scripted, unoccupied");
1770 if (m_physicsActor != null) 1837 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1771 { 1838 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1772 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1839 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1773 // We can remove the physicsActor until they stand up. 1840 autopilot = false; // Jump direct to scripted llSitPos()
1774 m_sitAvatarHeight = m_physicsActor.Size.Z; 1841 }
1775 1842 else
1776 if (autopilot) 1843 {
1777 { 1844//Console.WriteLine("Scripted, occupied");
1778 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1845 return;
1779 { 1846 }
1780 autopilot = false; 1847 }
1848 else // Not Scripted
1849 {
1850 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1851 {
1852 // large prim & offset, ignore if other Avs sitting
1853// offset.Z -= 0.05f;
1854 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1855 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1856
1857//Console.WriteLine(" offset ={0}", offset);
1858//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1859//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1860
1861 }
1862 else // small offset
1863 {
1864//Console.WriteLine("Small offset");
1865 if (!part.IsOccupied)
1866 {
1867 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1868 autopilotTarget = part.AbsolutePosition;
1869 }
1870 else return; // occupied small
1871 } // end large/small
1872 } // end Scripted/not
1873 cameraAtOffset = part.GetCameraAtOffset();
1874 cameraEyeOffset = part.GetCameraEyeOffset();
1875 forceMouselook = part.GetForceMouselook();
1876 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1877 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1781 1878
1782 RemoveFromPhysicalScene(); 1879 if (m_physicsActor != null)
1783 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1880 {
1784 } 1881 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1785 } 1882 // We can remove the physicsActor until they stand up.
1786 else 1883 m_sitAvatarHeight = m_physicsActor.Size.Z;
1884 if (autopilot)
1885 { // its not a scripted sit
1886// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1887 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1787 { 1888 {
1889 autopilot = false; // close enough
1890 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1891 Not using the part's position because returning the AV to the last known standing
1892 position is likely to be more friendly, isn't it? */
1788 RemoveFromPhysicalScene(); 1893 RemoveFromPhysicalScene();
1789 } 1894 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1895 } // else the autopilot will get us close
1896 }
1897 else
1898 { // its a scripted sit
1899 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1900 I *am* using the part's position this time because we have no real idea how far away
1901 the avatar is from the sit target. */
1902 RemoveFromPhysicalScene();
1790 } 1903 }
1791
1792 cameraAtOffset = part.GetCameraAtOffset();
1793 cameraEyeOffset = part.GetCameraEyeOffset();
1794 forceMouselook = part.GetForceMouselook();
1795 } 1904 }
1796 1905 else return; // physactor is null!
1797 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1906
1798 m_requestedSitTargetUUID = targetID; 1907 Vector3 offsetr; // = offset * partIRot;
1908 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1909 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1910 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1911 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1912 offsetr = offset * partIRot;
1913//
1914 // else
1915 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1916 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1917 // (offset * partRot);
1918 // }
1919
1920//Console.WriteLine(" ");
1921//Console.WriteLine("link number ={0}", part.LinkNum);
1922//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1923//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1924//Console.WriteLine("Click offst ={0}", offset);
1925//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1926//Console.WriteLine("offsetr ={0}", offsetr);
1927//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1928//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1929
1930 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1931 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1799 // This calls HandleAgentSit twice, once from here, and the client calls 1932 // This calls HandleAgentSit twice, once from here, and the client calls
1800 // HandleAgentSit itself after it gets to the location 1933 // HandleAgentSit itself after it gets to the location
1801 // It doesn't get to the location until we've moved them there though 1934 // It doesn't get to the location until we've moved them there though
1802 // which happens in HandleAgentSit :P 1935 // which happens in HandleAgentSit :P
1803 m_autopilotMoving = autopilot; 1936 m_autopilotMoving = autopilot;
1804 m_autoPilotTarget = pos; 1937 m_autoPilotTarget = autopilotTarget;
1805 m_sitAtAutoTarget = autopilot; 1938 m_sitAtAutoTarget = autopilot;
1939 m_initialSitTarget = autopilotTarget;
1806 if (!autopilot) 1940 if (!autopilot)
1807 HandleAgentSit(remoteClient, UUID); 1941 HandleAgentSit(remoteClient, UUID);
1808 } 1942 }
@@ -2097,31 +2231,65 @@ namespace OpenSim.Region.Framework.Scenes
2097 { 2231 {
2098 if (part != null) 2232 if (part != null)
2099 { 2233 {
2234//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2100 if (part.GetAvatarOnSitTarget() == UUID) 2235 if (part.GetAvatarOnSitTarget() == UUID)
2101 { 2236 {
2237//Console.WriteLine("Scripted Sit");
2238 // Scripted sit
2102 Vector3 sitTargetPos = part.SitTargetPosition; 2239 Vector3 sitTargetPos = part.SitTargetPosition;
2103 Quaternion sitTargetOrient = part.SitTargetOrientation; 2240 Quaternion sitTargetOrient = part.SitTargetOrientation;
2104
2105 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2106 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2107
2108 //Quaternion result = (sitTargetOrient * vq) * nq;
2109
2110 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2241 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2111 m_pos += SIT_TARGET_ADJUSTMENT; 2242 m_pos += SIT_TARGET_ADJUSTMENT;
2112 m_bodyRot = sitTargetOrient; 2243 m_bodyRot = sitTargetOrient;
2113 //Rotation = sitTargetOrient;
2114 m_parentPosition = part.AbsolutePosition; 2244 m_parentPosition = part.AbsolutePosition;
2115 2245 part.IsOccupied = true;
2116 //SendTerseUpdateToAllClients();
2117 } 2246 }
2118 else 2247 else
2119 { 2248 {
2120 m_pos -= part.AbsolutePosition; 2249 // if m_avUnscriptedSitPos is zero then Av sits above center
2250 // Else Av sits at m_avUnscriptedSitPos
2251
2252 // Non-scripted sit by Kitto Flora 21Nov09
2253 // Calculate angle of line from prim to Av
2254 Quaternion partIRot;
2255// if (part.LinkNum == 1)
2256// { // Root prim of linkset
2257// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2258// }
2259// else
2260// { // single or child prim
2261 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2262// }
2263 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2264 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2265 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2266 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2267 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2268 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2269 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2270 // Av sits at world euler <0,0, z>, translated by part rotation
2271 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2272
2121 m_parentPosition = part.AbsolutePosition; 2273 m_parentPosition = part.AbsolutePosition;
2122 } 2274 part.IsOccupied = true;
2123 } 2275 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2124 else 2276 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2277 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2278 m_avUnscriptedSitPos; // adds click offset, if any
2279 //Set up raytrace to find top surface of prim
2280 Vector3 size = part.Scale;
2281 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2282 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2283 Vector3 down = new Vector3(0f, 0f, -1f);
2284//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2285 m_scene.PhysicsScene.RaycastWorld(
2286 start, // Vector3 position,
2287 down, // Vector3 direction,
2288 mag, // float length,
2289 SitAltitudeCallback); // retMethod
2290 } // end scripted/not
2291 }
2292 else // no Av
2125 { 2293 {
2126 return; 2294 return;
2127 } 2295 }
@@ -2133,11 +2301,36 @@ namespace OpenSim.Region.Framework.Scenes
2133 2301
2134 Animator.TrySetMovementAnimation(sitAnimation); 2302 Animator.TrySetMovementAnimation(sitAnimation);
2135 SendFullUpdateToAllClients(); 2303 SendFullUpdateToAllClients();
2136 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2137 // So we're also sending a terse update (which has avatar rotation)
2138 // [Update] We do now.
2139 //SendTerseUpdateToAllClients();
2140 } 2304 }
2305
2306 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2307 {
2308 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2309 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2310 if(hitYN)
2311 {
2312 // m_pos = Av offset from prim center to make look like on center
2313 // m_parentPosition = Actual center pos of prim
2314 // collisionPoint = spot on prim where we want to sit
2315 // collisionPoint.Z = global sit surface height
2316 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2317 Quaternion partIRot;
2318// if (part.LinkNum == 1)
2319/// { // Root prim of linkset
2320// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2321// }
2322// else
2323// { // single or child prim
2324 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2325// }
2326 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2327 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2328//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2329 m_pos += offset;
2330// ControllingClient.SendClearFollowCamProperties(part.UUID);
2331
2332 }
2333 } // End SitAltitudeCallback KF.
2141 2334
2142 /// <summary> 2335 /// <summary>
2143 /// Event handler for the 'Always run' setting on the client 2336 /// Event handler for the 'Always run' setting on the client
@@ -2167,7 +2360,7 @@ namespace OpenSim.Region.Framework.Scenes
2167 /// </summary> 2360 /// </summary>
2168 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2361 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2169 /// <param name="rotation">The direction in which this avatar should now face. 2362 /// <param name="rotation">The direction in which this avatar should now face.
2170 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2363 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2171 { 2364 {
2172 if (m_isChildAgent) 2365 if (m_isChildAgent)
2173 { 2366 {
@@ -2241,7 +2434,7 @@ namespace OpenSim.Region.Framework.Scenes
2241 2434
2242 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2435 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2243 m_forceToApply = direc; 2436 m_forceToApply = direc;
2244 2437 m_isNudging = Nudging;
2245 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2438 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2246 } 2439 }
2247 2440
@@ -2256,7 +2449,7 @@ namespace OpenSim.Region.Framework.Scenes
2256 const float POSITION_TOLERANCE = 0.05f; 2449 const float POSITION_TOLERANCE = 0.05f;
2257 //const int TIME_MS_TOLERANCE = 3000; 2450 //const int TIME_MS_TOLERANCE = 3000;
2258 2451
2259 SendPrimUpdates(); 2452
2260 2453
2261 if (m_newCoarseLocations) 2454 if (m_newCoarseLocations)
2262 { 2455 {
@@ -2292,6 +2485,9 @@ namespace OpenSim.Region.Framework.Scenes
2292 CheckForBorderCrossing(); 2485 CheckForBorderCrossing();
2293 CheckForSignificantMovement(); // sends update to the modules. 2486 CheckForSignificantMovement(); // sends update to the modules.
2294 } 2487 }
2488
2489 //Sending prim updates AFTER the avatar terse updates are sent
2490 SendPrimUpdates();
2295 } 2491 }
2296 2492
2297 #endregion 2493 #endregion
@@ -3151,14 +3347,25 @@ namespace OpenSim.Region.Framework.Scenes
3151 { 3347 {
3152 if (m_forceToApply.HasValue) 3348 if (m_forceToApply.HasValue)
3153 { 3349 {
3154 Vector3 force = m_forceToApply.Value;
3155 3350
3351 Vector3 force = m_forceToApply.Value;
3156 m_updateflag = true; 3352 m_updateflag = true;
3157// movementvector = force;
3158 Velocity = force; 3353 Velocity = force;
3159 3354
3160 m_forceToApply = null; 3355 m_forceToApply = null;
3161 } 3356 }
3357 else
3358 {
3359 if (m_isNudging)
3360 {
3361 Vector3 force = Vector3.Zero;
3362
3363 m_updateflag = true;
3364 Velocity = force;
3365 m_isNudging = false;
3366 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3367 }
3368 }
3162 } 3369 }
3163 3370
3164 public override void SetText(string text, Vector3 color, double alpha) 3371 public override void SetText(string text, Vector3 color, double alpha)
@@ -3209,18 +3416,29 @@ namespace OpenSim.Region.Framework.Scenes
3209 { 3416 {
3210 if (e == null) 3417 if (e == null)
3211 return; 3418 return;
3212 3419
3213 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3420 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3214 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3215 // as of this comment the interval is set in AddToPhysicalScene 3421 // as of this comment the interval is set in AddToPhysicalScene
3216 if (Animator!=null) 3422 if (Animator!=null)
3217 Animator.UpdateMovementAnimations(); 3423 {
3424 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3425 { // else its will lock out other animation changes, like ground sit.
3426 Animator.UpdateMovementAnimations();
3427 m_updateCount--;
3428 }
3429 }
3218 3430
3219 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3431 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3220 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3432 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3221 3433
3222 CollisionPlane = Vector4.UnitW; 3434 CollisionPlane = Vector4.UnitW;
3223 3435
3436 if (m_lastColCount != coldata.Count)
3437 {
3438 m_updateCount = UPDATE_COUNT;
3439 m_lastColCount = coldata.Count;
3440 }
3441
3224 if (coldata.Count != 0 && Animator != null) 3442 if (coldata.Count != 0 && Animator != null)
3225 { 3443 {
3226 switch (Animator.CurrentMovementAnimation) 3444 switch (Animator.CurrentMovementAnimation)
@@ -3857,5 +4075,16 @@ namespace OpenSim.Region.Framework.Scenes
3857 m_reprioritization_called = false; 4075 m_reprioritization_called = false;
3858 } 4076 }
3859 } 4077 }
4078
4079 private Vector3 Quat2Euler(Quaternion rot){
4080 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4081 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4082 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4083 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4084 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4085 return(new Vector3(x,y,z));
4086 }
4087
4088
3860 } 4089 }
3861} 4090}