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.cs570
1 files changed, 400 insertions, 170 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 465e916..9dbe332 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
@@ -182,7 +185,8 @@ namespace OpenSim.Region.Framework.Scenes
182 protected RegionInfo m_regionInfo; 185 protected RegionInfo m_regionInfo;
183 protected ulong crossingFromRegion; 186 protected ulong crossingFromRegion;
184 187
185 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 188 private readonly Vector3[] Dir_Vectors = new Vector3[11];
189 private bool m_isNudging = false;
186 190
187 // Position of agent's camera in world (region cordinates) 191 // Position of agent's camera in world (region cordinates)
188 protected Vector3 m_CameraCenter; 192 protected Vector3 m_CameraCenter;
@@ -207,6 +211,7 @@ namespace OpenSim.Region.Framework.Scenes
207 private bool m_autopilotMoving; 211 private bool m_autopilotMoving;
208 private Vector3 m_autoPilotTarget; 212 private Vector3 m_autoPilotTarget;
209 private bool m_sitAtAutoTarget; 213 private bool m_sitAtAutoTarget;
214 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
210 215
211 private string m_nextSitAnimation = String.Empty; 216 private string m_nextSitAnimation = String.Empty;
212 217
@@ -217,6 +222,9 @@ namespace OpenSim.Region.Framework.Scenes
217 private bool m_followCamAuto; 222 private bool m_followCamAuto;
218 223
219 private int m_movementUpdateCount; 224 private int m_movementUpdateCount;
225 private int m_lastColCount = -1; //KF: Look for Collision chnages
226 private int m_updateCount = 0; //KF: Update Anims for a while
227 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
220 228
221 private const int NumMovementsBetweenRayCast = 5; 229 private const int NumMovementsBetweenRayCast = 5;
222 230
@@ -245,7 +253,9 @@ namespace OpenSim.Region.Framework.Scenes
245 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 253 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
246 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 254 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
247 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 255 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
248 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 256 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
257 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
258 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 259 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
250 } 260 }
251 261
@@ -682,10 +692,7 @@ namespace OpenSim.Region.Framework.Scenes
682 m_reprioritization_timer.AutoReset = false; 692 m_reprioritization_timer.AutoReset = false;
683 693
684 AdjustKnownSeeds(); 694 AdjustKnownSeeds();
685
686 // TODO: I think, this won't send anything, as we are still a child here...
687 Animator.TrySetMovementAnimation("STAND"); 695 Animator.TrySetMovementAnimation("STAND");
688
689 // we created a new ScenePresence (a new child agent) in a fresh region. 696 // we created a new ScenePresence (a new child agent) in a fresh region.
690 // Request info about all the (root) agents in this region 697 // Request info about all the (root) agents in this region
691 // Note: This won't send data *to* other clients in that region (children don't send) 698 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -741,25 +748,47 @@ namespace OpenSim.Region.Framework.Scenes
741 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 748 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
742 Dir_Vectors[4] = Vector3.UnitZ; //UP 749 Dir_Vectors[4] = Vector3.UnitZ; //UP
743 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 750 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
744 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 751 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
745 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 752 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
746 Dir_Vectors[7] = -Vector3.UnitX; //BACK 753 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
754 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
755 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
747 } 756 }
748 757
749 private Vector3[] GetWalkDirectionVectors() 758 private Vector3[] GetWalkDirectionVectors()
750 { 759 {
751 Vector3[] vector = new Vector3[9]; 760 Vector3[] vector = new Vector3[11];
752 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 761 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
753 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 762 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
754 vector[2] = Vector3.UnitY; //LEFT 763 vector[2] = Vector3.UnitY; //LEFT
755 vector[3] = -Vector3.UnitY; //RIGHT 764 vector[3] = -Vector3.UnitY; //RIGHT
756 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 765 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
757 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 766 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
758 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 767 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
759 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 768 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
760 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 769 vector[8] = Vector3.UnitY; //LEFT_NUDGE
770 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
771 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
761 return vector; 772 return vector;
762 } 773 }
774
775 private bool[] GetDirectionIsNudge()
776 {
777 bool[] isNudge = new bool[11];
778 isNudge[0] = false; //FORWARD
779 isNudge[1] = false; //BACK
780 isNudge[2] = false; //LEFT
781 isNudge[3] = false; //RIGHT
782 isNudge[4] = false; //UP
783 isNudge[5] = false; //DOWN
784 isNudge[6] = true; //FORWARD_NUDGE
785 isNudge[7] = true; //BACK_NUDGE
786 isNudge[8] = true; //LEFT_NUDGE
787 isNudge[9] = true; //RIGHT_NUDGE
788 isNudge[10] = true; //DOWN_Nudge
789 return isNudge;
790 }
791
763 792
764 #endregion 793 #endregion
765 794
@@ -828,6 +857,22 @@ namespace OpenSim.Region.Framework.Scenes
828 { 857 {
829 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 858 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
830 pos.Y = crossedBorder.BorderLine.Z - 1; 859 pos.Y = crossedBorder.BorderLine.Z - 1;
860 }
861
862 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
863 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
864 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
865 if (KnownChildRegionHandles.Count == 0)
866 {
867 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
868 if (land != null)
869 {
870 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
871 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)
872 {
873 pos = land.LandData.UserLocation;
874 }
875 }
831 } 876 }
832 877
833 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 878 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
@@ -964,9 +1009,10 @@ namespace OpenSim.Region.Framework.Scenes
964 public void Teleport(Vector3 pos) 1009 public void Teleport(Vector3 pos)
965 { 1010 {
966 bool isFlying = false; 1011 bool isFlying = false;
967 if (m_physicsActor != null)
968 isFlying = m_physicsActor.Flying;
969 1012
1013 if (m_physicsActor != null)
1014 isFlying = m_physicsActor.Flying;
1015
970 RemoveFromPhysicalScene(); 1016 RemoveFromPhysicalScene();
971 Velocity = Vector3.Zero; 1017 Velocity = Vector3.Zero;
972 AbsolutePosition = pos; 1018 AbsolutePosition = pos;
@@ -977,7 +1023,8 @@ namespace OpenSim.Region.Framework.Scenes
977 SetHeight(m_appearance.AvatarHeight); 1023 SetHeight(m_appearance.AvatarHeight);
978 } 1024 }
979 1025
980 SendTerseUpdateToAllClients(); 1026 SendTerseUpdateToAllClients();
1027
981 } 1028 }
982 1029
983 public void TeleportWithMomentum(Vector3 pos) 1030 public void TeleportWithMomentum(Vector3 pos)
@@ -1022,7 +1069,9 @@ namespace OpenSim.Region.Framework.Scenes
1022 { 1069 {
1023 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1070 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1024 } 1071 }
1025 1072
1073 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1074
1026 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1075 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1027 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1076 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1028 } 1077 }
@@ -1273,7 +1322,6 @@ namespace OpenSim.Region.Framework.Scenes
1273 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1322 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1274 } 1323 }
1275 } 1324 }
1276
1277 lock (scriptedcontrols) 1325 lock (scriptedcontrols)
1278 { 1326 {
1279 if (scriptedcontrols.Count > 0) 1327 if (scriptedcontrols.Count > 0)
@@ -1288,12 +1336,8 @@ namespace OpenSim.Region.Framework.Scenes
1288 1336
1289 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1337 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1290 { 1338 {
1291 // TODO: This doesn't prevent the user from walking yet. 1339 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1292 // Setting parent ID would fix this, if we knew what value 1340 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1293 // to use. Or we could add a m_isSitting variable.
1294 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1295 SitGround = true;
1296
1297 } 1341 }
1298 1342
1299 // In the future, these values might need to go global. 1343 // In the future, these values might need to go global.
@@ -1343,6 +1387,11 @@ namespace OpenSim.Region.Framework.Scenes
1343 update_rotation = true; 1387 update_rotation = true;
1344 } 1388 }
1345 1389
1390 //guilty until proven innocent..
1391 bool Nudging = true;
1392 //Basically, if there is at least one non-nudge control then we don't need
1393 //to worry about stopping the avatar
1394
1346 if (m_parentID == 0) 1395 if (m_parentID == 0)
1347 { 1396 {
1348 bool bAllowUpdateMoveToPosition = false; 1397 bool bAllowUpdateMoveToPosition = false;
@@ -1357,9 +1406,12 @@ namespace OpenSim.Region.Framework.Scenes
1357 else 1406 else
1358 dirVectors = Dir_Vectors; 1407 dirVectors = Dir_Vectors;
1359 1408
1360 // The fact that m_movementflag is a byte needs to be fixed 1409 bool[] isNudge = GetDirectionIsNudge();
1361 // it really should be a uint 1410
1362 uint nudgehack = 250; 1411
1412
1413
1414
1363 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1415 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1364 { 1416 {
1365 if (((uint)flags & (uint)DCF) != 0) 1417 if (((uint)flags & (uint)DCF) != 0)
@@ -1369,40 +1421,28 @@ namespace OpenSim.Region.Framework.Scenes
1369 try 1421 try
1370 { 1422 {
1371 agent_control_v3 += dirVectors[i]; 1423 agent_control_v3 += dirVectors[i];
1372 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1424 if (isNudge[i] == false)
1425 {
1426 Nudging = false;
1427 }
1373 } 1428 }
1374 catch (IndexOutOfRangeException) 1429 catch (IndexOutOfRangeException)
1375 { 1430 {
1376 // Why did I get this? 1431 // Why did I get this?
1377 } 1432 }
1378 1433
1379 if ((m_movementflag & (byte)(uint)DCF) == 0) 1434 if ((m_movementflag & (uint)DCF) == 0)
1380 { 1435 {
1381 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1382 {
1383 m_movementflag |= (byte)nudgehack;
1384 }
1385 m_movementflag += (byte)(uint)DCF; 1436 m_movementflag += (byte)(uint)DCF;
1386 update_movementflag = true; 1437 update_movementflag = true;
1387 } 1438 }
1388 } 1439 }
1389 else 1440 else
1390 { 1441 {
1391 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1442 if ((m_movementflag & (uint)DCF) != 0)
1392 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1393 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1394 ) // This or is for Nudge forward
1395 { 1443 {
1396 m_movementflag -= ((byte)(uint)DCF); 1444 m_movementflag -= (byte)(uint)DCF;
1397
1398 update_movementflag = true; 1445 update_movementflag = true;
1399 /*
1400 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1401 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1402 {
1403 m_log.Debug("Removed Hack flag");
1404 }
1405 */
1406 } 1446 }
1407 else 1447 else
1408 { 1448 {
@@ -1446,6 +1486,9 @@ namespace OpenSim.Region.Framework.Scenes
1446 // Ignore z component of vector 1486 // Ignore z component of vector
1447 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1487 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1448 LocalVectorToTarget2D.Normalize(); 1488 LocalVectorToTarget2D.Normalize();
1489
1490 //We're not nudging
1491 Nudging = false;
1449 agent_control_v3 += LocalVectorToTarget2D; 1492 agent_control_v3 += LocalVectorToTarget2D;
1450 1493
1451 // update avatar movement flags. the avatar coordinate system is as follows: 1494 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1534,13 +1577,13 @@ namespace OpenSim.Region.Framework.Scenes
1534 // m_log.DebugFormat( 1577 // m_log.DebugFormat(
1535 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1578 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1536 1579
1537 AddNewMovement(agent_control_v3, q); 1580 AddNewMovement(agent_control_v3, q, Nudging);
1538 1581
1539 1582
1540 } 1583 }
1541 } 1584 }
1542 1585
1543 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1586 if (update_movementflag)
1544 Animator.UpdateMovementAnimations(); 1587 Animator.UpdateMovementAnimations();
1545 1588
1546 m_scene.EventManager.TriggerOnClientMovement(this); 1589 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1555,7 +1598,6 @@ namespace OpenSim.Region.Framework.Scenes
1555 m_sitAtAutoTarget = false; 1598 m_sitAtAutoTarget = false;
1556 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1599 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1557 //proxy.PCode = (byte)PCode.ParticleSystem; 1600 //proxy.PCode = (byte)PCode.ParticleSystem;
1558
1559 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1601 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1560 proxyObjectGroup.AttachToScene(m_scene); 1602 proxyObjectGroup.AttachToScene(m_scene);
1561 1603
@@ -1597,7 +1639,7 @@ namespace OpenSim.Region.Framework.Scenes
1597 } 1639 }
1598 m_moveToPositionInProgress = true; 1640 m_moveToPositionInProgress = true;
1599 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1641 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1600 } 1642 }
1601 catch (Exception ex) 1643 catch (Exception ex)
1602 { 1644 {
1603 //Why did I get this error? 1645 //Why did I get this error?
@@ -1619,7 +1661,7 @@ namespace OpenSim.Region.Framework.Scenes
1619 Velocity = Vector3.Zero; 1661 Velocity = Vector3.Zero;
1620 SendFullUpdateToAllClients(); 1662 SendFullUpdateToAllClients();
1621 1663
1622 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1664 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1623 } 1665 }
1624 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1666 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1625 m_requestedSitTargetUUID = UUID.Zero; 1667 m_requestedSitTargetUUID = UUID.Zero;
@@ -1652,55 +1694,84 @@ namespace OpenSim.Region.Framework.Scenes
1652 /// </summary> 1694 /// </summary>
1653 public void StandUp() 1695 public void StandUp()
1654 { 1696 {
1655 if (SitGround)
1656 SitGround = false;
1657
1658 if (m_parentID != 0) 1697 if (m_parentID != 0)
1659 { 1698 {
1660 m_log.Debug("StandupCode Executed");
1661 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1699 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1662 if (part != null) 1700 if (part != null)
1663 { 1701 {
1702 part.TaskInventory.LockItemsForRead(true);
1664 TaskInventoryDictionary taskIDict = part.TaskInventory; 1703 TaskInventoryDictionary taskIDict = part.TaskInventory;
1665 if (taskIDict != null) 1704 if (taskIDict != null)
1666 { 1705 {
1667 lock (taskIDict) 1706 foreach (UUID taskID in taskIDict.Keys)
1668 { 1707 {
1669 foreach (UUID taskID in taskIDict.Keys) 1708 UnRegisterControlEventsToScript(LocalId, taskID);
1670 { 1709 taskIDict[taskID].PermsMask &= ~(
1671 UnRegisterControlEventsToScript(LocalId, taskID); 1710 2048 | //PERMISSION_CONTROL_CAMERA
1672 taskIDict[taskID].PermsMask &= ~( 1711 4); // PERMISSION_TAKE_CONTROLS
1673 2048 | //PERMISSION_CONTROL_CAMERA
1674 4); // PERMISSION_TAKE_CONTROLS
1675 }
1676 } 1712 }
1677
1678 } 1713 }
1714 part.TaskInventory.LockItemsForRead(false);
1679 // Reset sit target. 1715 // Reset sit target.
1680 if (part.GetAvatarOnSitTarget() == UUID) 1716 if (part.GetAvatarOnSitTarget() == UUID)
1681 part.SetAvatarOnSitTarget(UUID.Zero); 1717 part.SetAvatarOnSitTarget(UUID.Zero);
1682
1683 m_parentPosition = part.GetWorldPosition(); 1718 m_parentPosition = part.GetWorldPosition();
1684 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1719 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1685 } 1720 }
1686 1721 // part.GetWorldRotation() is the rotation of the object being sat on
1687 if (m_physicsActor == null) 1722 // Rotation is the sittiing Av's rotation
1688 { 1723
1689 AddToPhysicalScene(false); 1724 Quaternion partRot;
1725// if (part.LinkNum == 1)
1726// { // Root prim of linkset
1727// partRot = part.ParentGroup.RootPart.RotationOffset;
1728// }
1729// else
1730// { // single or child prim
1731
1732// }
1733 if (part == null) //CW: Part may be gone. llDie() for example.
1734 {
1735 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1736 }
1737 else
1738 {
1739 partRot = part.GetWorldRotation();
1690 } 1740 }
1691 1741
1692 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1742 Quaternion partIRot = Quaternion.Inverse(partRot);
1693 m_parentPosition = Vector3.Zero;
1694 1743
1695 m_parentID = 0; 1744 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1745 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1746
1747
1748 if (m_physicsActor == null)
1749 {
1750 AddToPhysicalScene(false);
1751 }
1752 //CW: If the part isn't null then we can set the current position
1753 if (part != null)
1754 {
1755 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1756 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1757 part.IsOccupied = false;
1758 }
1759 else
1760 {
1761 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1762 AbsolutePosition = m_lastWorldPosition;
1763 }
1764
1765 m_parentPosition = Vector3.Zero;
1766 m_parentID = 0;
1696 SendFullUpdateToAllClients(); 1767 SendFullUpdateToAllClients();
1697 m_requestedSitTargetID = 0; 1768 m_requestedSitTargetID = 0;
1769
1698 if ((m_physicsActor != null) && (m_avHeight > 0)) 1770 if ((m_physicsActor != null) && (m_avHeight > 0))
1699 { 1771 {
1700 SetHeight(m_avHeight); 1772 SetHeight(m_avHeight);
1701 } 1773 }
1702 } 1774 }
1703
1704 Animator.TrySetMovementAnimation("STAND"); 1775 Animator.TrySetMovementAnimation("STAND");
1705 } 1776 }
1706 1777
@@ -1731,13 +1802,9 @@ namespace OpenSim.Region.Framework.Scenes
1731 Vector3 avSitOffSet = part.SitTargetPosition; 1802 Vector3 avSitOffSet = part.SitTargetPosition;
1732 Quaternion avSitOrientation = part.SitTargetOrientation; 1803 Quaternion avSitOrientation = part.SitTargetOrientation;
1733 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1804 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1734 1805 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1735 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1806 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1736 bool SitTargetisSet = 1807 if (SitTargetisSet && !SitTargetOccupied)
1737 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1738 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1739
1740 if (SitTargetisSet && SitTargetUnOccupied)
1741 { 1808 {
1742 //switch the target to this prim 1809 //switch the target to this prim
1743 return part; 1810 return part;
@@ -1751,84 +1818,152 @@ namespace OpenSim.Region.Framework.Scenes
1751 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1818 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1752 { 1819 {
1753 bool autopilot = true; 1820 bool autopilot = true;
1821 Vector3 autopilotTarget = new Vector3();
1822 Quaternion sitOrientation = Quaternion.Identity;
1754 Vector3 pos = new Vector3(); 1823 Vector3 pos = new Vector3();
1755 Quaternion sitOrientation = pSitOrientation;
1756 Vector3 cameraEyeOffset = Vector3.Zero; 1824 Vector3 cameraEyeOffset = Vector3.Zero;
1757 Vector3 cameraAtOffset = Vector3.Zero; 1825 Vector3 cameraAtOffset = Vector3.Zero;
1758 bool forceMouselook = false; 1826 bool forceMouselook = false;
1759 1827
1760 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1828 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1761 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1829 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1762 if (part != null) 1830 if (part == null) return;
1763 { 1831
1764 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1832 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1765 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1833 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1766 1834
1767 // Is a sit target available? 1835 // part is the prim to sit on
1768 Vector3 avSitOffSet = part.SitTargetPosition; 1836 // offset is the world-ref vector distance from that prim center to the click-spot
1769 Quaternion avSitOrientation = part.SitTargetOrientation; 1837 // UUID is the UUID of the Avatar doing the clicking
1770 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1838
1771 1839 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1772 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1840
1773 bool SitTargetisSet = 1841 // Is a sit target available?
1774 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1842 Vector3 avSitOffSet = part.SitTargetPosition;
1775 ( 1843 Quaternion avSitOrientation = part.SitTargetOrientation;
1776 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1844
1777 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1845 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1778 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1846 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1779 ) 1847 Quaternion partRot;
1780 )); 1848// if (part.LinkNum == 1)
1781 1849// { // Root prim of linkset
1782 if (SitTargetisSet && SitTargetUnOccupied) 1850// partRot = part.ParentGroup.RootPart.RotationOffset;
1783 { 1851// }
1784 part.SetAvatarOnSitTarget(UUID); 1852// else
1785 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1853// { // single or child prim
1786 sitOrientation = avSitOrientation; 1854 partRot = part.GetWorldRotation();
1787 autopilot = false; 1855// }
1788 } 1856 Quaternion partIRot = Quaternion.Inverse(partRot);
1789 1857//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1790 pos = part.AbsolutePosition + offset; 1858 // Sit analysis rewritten by KF 091125
1791 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1859 if (SitTargetisSet) // scipted sit
1792 //{ 1860 {
1793 // offset = pos; 1861 if (!part.IsOccupied)
1794 //autopilot = false; 1862 {
1795 //} 1863//Console.WriteLine("Scripted, unoccupied");
1796 if (m_physicsActor != null) 1864 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1797 { 1865 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1798 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1866 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1799 // We can remove the physicsActor until they stand up. 1867 autopilot = false; // Jump direct to scripted llSitPos()
1800 m_sitAvatarHeight = m_physicsActor.Size.Z; 1868 }
1801 1869 else
1802 if (autopilot) 1870 {
1803 { 1871//Console.WriteLine("Scripted, occupied");
1804 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1872 return;
1805 { 1873 }
1806 autopilot = false; 1874 }
1875 else // Not Scripted
1876 {
1877 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1878 {
1879 // large prim & offset, ignore if other Avs sitting
1880// offset.Z -= 0.05f;
1881 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1882 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1883
1884//Console.WriteLine(" offset ={0}", offset);
1885//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1886//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1887
1888 }
1889 else // small offset
1890 {
1891//Console.WriteLine("Small offset");
1892 if (!part.IsOccupied)
1893 {
1894 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1895 autopilotTarget = part.AbsolutePosition;
1896 }
1897 else return; // occupied small
1898 } // end large/small
1899 } // end Scripted/not
1900 cameraAtOffset = part.GetCameraAtOffset();
1901 cameraEyeOffset = part.GetCameraEyeOffset();
1902 forceMouselook = part.GetForceMouselook();
1903 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1904 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1807 1905
1808 RemoveFromPhysicalScene(); 1906 if (m_physicsActor != null)
1809 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1907 {
1810 } 1908 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1811 } 1909 // We can remove the physicsActor until they stand up.
1812 else 1910 m_sitAvatarHeight = m_physicsActor.Size.Z;
1911 if (autopilot)
1912 { // its not a scripted sit
1913// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1914 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1813 { 1915 {
1916 autopilot = false; // close enough
1917 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1918 Not using the part's position because returning the AV to the last known standing
1919 position is likely to be more friendly, isn't it? */
1814 RemoveFromPhysicalScene(); 1920 RemoveFromPhysicalScene();
1815 } 1921 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1922 } // else the autopilot will get us close
1923 }
1924 else
1925 { // its a scripted sit
1926 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1927 I *am* using the part's position this time because we have no real idea how far away
1928 the avatar is from the sit target. */
1929 RemoveFromPhysicalScene();
1816 } 1930 }
1817
1818 cameraAtOffset = part.GetCameraAtOffset();
1819 cameraEyeOffset = part.GetCameraEyeOffset();
1820 forceMouselook = part.GetForceMouselook();
1821 } 1931 }
1822 1932 else return; // physactor is null!
1823 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1933
1824 m_requestedSitTargetUUID = targetID; 1934 Vector3 offsetr; // = offset * partIRot;
1935 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1936 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1937 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1938 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1939 offsetr = offset * partIRot;
1940//
1941 // else
1942 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1943 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1944 // (offset * partRot);
1945 // }
1946
1947//Console.WriteLine(" ");
1948//Console.WriteLine("link number ={0}", part.LinkNum);
1949//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1950//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1951//Console.WriteLine("Click offst ={0}", offset);
1952//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1953//Console.WriteLine("offsetr ={0}", offsetr);
1954//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1955//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1956
1957 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1958 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1825 // This calls HandleAgentSit twice, once from here, and the client calls 1959 // This calls HandleAgentSit twice, once from here, and the client calls
1826 // HandleAgentSit itself after it gets to the location 1960 // HandleAgentSit itself after it gets to the location
1827 // It doesn't get to the location until we've moved them there though 1961 // It doesn't get to the location until we've moved them there though
1828 // which happens in HandleAgentSit :P 1962 // which happens in HandleAgentSit :P
1829 m_autopilotMoving = autopilot; 1963 m_autopilotMoving = autopilot;
1830 m_autoPilotTarget = pos; 1964 m_autoPilotTarget = autopilotTarget;
1831 m_sitAtAutoTarget = autopilot; 1965 m_sitAtAutoTarget = autopilot;
1966 m_initialSitTarget = autopilotTarget;
1832 if (!autopilot) 1967 if (!autopilot)
1833 HandleAgentSit(remoteClient, UUID); 1968 HandleAgentSit(remoteClient, UUID);
1834 } 1969 }
@@ -2123,31 +2258,65 @@ namespace OpenSim.Region.Framework.Scenes
2123 { 2258 {
2124 if (part != null) 2259 if (part != null)
2125 { 2260 {
2261//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2126 if (part.GetAvatarOnSitTarget() == UUID) 2262 if (part.GetAvatarOnSitTarget() == UUID)
2127 { 2263 {
2264//Console.WriteLine("Scripted Sit");
2265 // Scripted sit
2128 Vector3 sitTargetPos = part.SitTargetPosition; 2266 Vector3 sitTargetPos = part.SitTargetPosition;
2129 Quaternion sitTargetOrient = part.SitTargetOrientation; 2267 Quaternion sitTargetOrient = part.SitTargetOrientation;
2130
2131 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2132 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2133
2134 //Quaternion result = (sitTargetOrient * vq) * nq;
2135
2136 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2268 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2137 m_pos += SIT_TARGET_ADJUSTMENT; 2269 m_pos += SIT_TARGET_ADJUSTMENT;
2138 m_bodyRot = sitTargetOrient; 2270 m_bodyRot = sitTargetOrient;
2139 //Rotation = sitTargetOrient;
2140 m_parentPosition = part.AbsolutePosition; 2271 m_parentPosition = part.AbsolutePosition;
2141 2272 part.IsOccupied = true;
2142 //SendTerseUpdateToAllClients();
2143 } 2273 }
2144 else 2274 else
2145 { 2275 {
2146 m_pos -= part.AbsolutePosition; 2276 // if m_avUnscriptedSitPos is zero then Av sits above center
2277 // Else Av sits at m_avUnscriptedSitPos
2278
2279 // Non-scripted sit by Kitto Flora 21Nov09
2280 // Calculate angle of line from prim to Av
2281 Quaternion partIRot;
2282// if (part.LinkNum == 1)
2283// { // Root prim of linkset
2284// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2285// }
2286// else
2287// { // single or child prim
2288 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2289// }
2290 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2291 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2292 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2293 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2294 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2295 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2296 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2297 // Av sits at world euler <0,0, z>, translated by part rotation
2298 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2299
2147 m_parentPosition = part.AbsolutePosition; 2300 m_parentPosition = part.AbsolutePosition;
2148 } 2301 part.IsOccupied = true;
2302 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2303 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2304 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2305 m_avUnscriptedSitPos; // adds click offset, if any
2306 //Set up raytrace to find top surface of prim
2307 Vector3 size = part.Scale;
2308 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2309 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2310 Vector3 down = new Vector3(0f, 0f, -1f);
2311//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2312 m_scene.PhysicsScene.RaycastWorld(
2313 start, // Vector3 position,
2314 down, // Vector3 direction,
2315 mag, // float length,
2316 SitAltitudeCallback); // retMethod
2317 } // end scripted/not
2149 } 2318 }
2150 else 2319 else // no Av
2151 { 2320 {
2152 return; 2321 return;
2153 } 2322 }
@@ -2159,11 +2328,36 @@ namespace OpenSim.Region.Framework.Scenes
2159 2328
2160 Animator.TrySetMovementAnimation(sitAnimation); 2329 Animator.TrySetMovementAnimation(sitAnimation);
2161 SendFullUpdateToAllClients(); 2330 SendFullUpdateToAllClients();
2162 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2163 // So we're also sending a terse update (which has avatar rotation)
2164 // [Update] We do now.
2165 //SendTerseUpdateToAllClients();
2166 } 2331 }
2332
2333 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2334 {
2335 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2336 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2337 if(hitYN)
2338 {
2339 // m_pos = Av offset from prim center to make look like on center
2340 // m_parentPosition = Actual center pos of prim
2341 // collisionPoint = spot on prim where we want to sit
2342 // collisionPoint.Z = global sit surface height
2343 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2344 Quaternion partIRot;
2345// if (part.LinkNum == 1)
2346/// { // Root prim of linkset
2347// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2348// }
2349// else
2350// { // single or child prim
2351 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2352// }
2353 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2354 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2355//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2356 m_pos += offset;
2357// ControllingClient.SendClearFollowCamProperties(part.UUID);
2358
2359 }
2360 } // End SitAltitudeCallback KF.
2167 2361
2168 /// <summary> 2362 /// <summary>
2169 /// Event handler for the 'Always run' setting on the client 2363 /// Event handler for the 'Always run' setting on the client
@@ -2193,7 +2387,7 @@ namespace OpenSim.Region.Framework.Scenes
2193 /// </summary> 2387 /// </summary>
2194 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2388 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2195 /// <param name="rotation">The direction in which this avatar should now face. 2389 /// <param name="rotation">The direction in which this avatar should now face.
2196 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2390 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2197 { 2391 {
2198 if (m_isChildAgent) 2392 if (m_isChildAgent)
2199 { 2393 {
@@ -2270,7 +2464,7 @@ namespace OpenSim.Region.Framework.Scenes
2270 2464
2271 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2465 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2272 m_forceToApply = direc; 2466 m_forceToApply = direc;
2273 2467 m_isNudging = Nudging;
2274 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2468 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2275 } 2469 }
2276 2470
@@ -2285,7 +2479,7 @@ namespace OpenSim.Region.Framework.Scenes
2285 const float POSITION_TOLERANCE = 0.05f; 2479 const float POSITION_TOLERANCE = 0.05f;
2286 //const int TIME_MS_TOLERANCE = 3000; 2480 //const int TIME_MS_TOLERANCE = 3000;
2287 2481
2288 SendPrimUpdates(); 2482
2289 2483
2290 if (m_newCoarseLocations) 2484 if (m_newCoarseLocations)
2291 { 2485 {
@@ -2321,6 +2515,9 @@ namespace OpenSim.Region.Framework.Scenes
2321 CheckForBorderCrossing(); 2515 CheckForBorderCrossing();
2322 CheckForSignificantMovement(); // sends update to the modules. 2516 CheckForSignificantMovement(); // sends update to the modules.
2323 } 2517 }
2518
2519 //Sending prim updates AFTER the avatar terse updates are sent
2520 SendPrimUpdates();
2324 } 2521 }
2325 2522
2326 #endregion 2523 #endregion
@@ -3230,14 +3427,25 @@ namespace OpenSim.Region.Framework.Scenes
3230 { 3427 {
3231 if (m_forceToApply.HasValue) 3428 if (m_forceToApply.HasValue)
3232 { 3429 {
3233 Vector3 force = m_forceToApply.Value;
3234 3430
3431 Vector3 force = m_forceToApply.Value;
3235 m_updateflag = true; 3432 m_updateflag = true;
3236// movementvector = force;
3237 Velocity = force; 3433 Velocity = force;
3238 3434
3239 m_forceToApply = null; 3435 m_forceToApply = null;
3240 } 3436 }
3437 else
3438 {
3439 if (m_isNudging)
3440 {
3441 Vector3 force = Vector3.Zero;
3442
3443 m_updateflag = true;
3444 Velocity = force;
3445 m_isNudging = false;
3446 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3447 }
3448 }
3241 } 3449 }
3242 3450
3243 public override void SetText(string text, Vector3 color, double alpha) 3451 public override void SetText(string text, Vector3 color, double alpha)
@@ -3288,18 +3496,29 @@ namespace OpenSim.Region.Framework.Scenes
3288 { 3496 {
3289 if (e == null) 3497 if (e == null)
3290 return; 3498 return;
3291 3499
3292 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3500 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3293 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3294 // as of this comment the interval is set in AddToPhysicalScene 3501 // as of this comment the interval is set in AddToPhysicalScene
3295 if (Animator!=null) 3502 if (Animator!=null)
3296 Animator.UpdateMovementAnimations(); 3503 {
3504 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3505 { // else its will lock out other animation changes, like ground sit.
3506 Animator.UpdateMovementAnimations();
3507 m_updateCount--;
3508 }
3509 }
3297 3510
3298 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3511 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3299 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3512 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3300 3513
3301 CollisionPlane = Vector4.UnitW; 3514 CollisionPlane = Vector4.UnitW;
3302 3515
3516 if (m_lastColCount != coldata.Count)
3517 {
3518 m_updateCount = UPDATE_COUNT;
3519 m_lastColCount = coldata.Count;
3520 }
3521
3303 if (coldata.Count != 0 && Animator != null) 3522 if (coldata.Count != 0 && Animator != null)
3304 { 3523 {
3305 switch (Animator.CurrentMovementAnimation) 3524 switch (Animator.CurrentMovementAnimation)
@@ -3906,5 +4125,16 @@ namespace OpenSim.Region.Framework.Scenes
3906 m_reprioritization_called = false; 4125 m_reprioritization_called = false;
3907 } 4126 }
3908 } 4127 }
4128
4129 private Vector3 Quat2Euler(Quaternion rot){
4130 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4131 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4132 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4133 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4134 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4135 return(new Vector3(x,y,z));
4136 }
4137
4138
3909 } 4139 }
3910} 4140}