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.cs571
1 files changed, 400 insertions, 171 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index f83a4d2..453523a 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,9 +857,24 @@ 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
834 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 878 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
835 { 879 {
836 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 880 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -990,9 +1034,10 @@ namespace OpenSim.Region.Framework.Scenes
990 public void Teleport(Vector3 pos) 1034 public void Teleport(Vector3 pos)
991 { 1035 {
992 bool isFlying = false; 1036 bool isFlying = false;
993 if (m_physicsActor != null)
994 isFlying = m_physicsActor.Flying;
995 1037
1038 if (m_physicsActor != null)
1039 isFlying = m_physicsActor.Flying;
1040
996 RemoveFromPhysicalScene(); 1041 RemoveFromPhysicalScene();
997 Velocity = Vector3.Zero; 1042 Velocity = Vector3.Zero;
998 AbsolutePosition = pos; 1043 AbsolutePosition = pos;
@@ -1003,7 +1048,8 @@ namespace OpenSim.Region.Framework.Scenes
1003 SetHeight(m_appearance.AvatarHeight); 1048 SetHeight(m_appearance.AvatarHeight);
1004 } 1049 }
1005 1050
1006 SendTerseUpdateToAllClients(); 1051 SendTerseUpdateToAllClients();
1052
1007 } 1053 }
1008 1054
1009 public void TeleportWithMomentum(Vector3 pos) 1055 public void TeleportWithMomentum(Vector3 pos)
@@ -1048,7 +1094,9 @@ namespace OpenSim.Region.Framework.Scenes
1048 { 1094 {
1049 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1095 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1050 } 1096 }
1051 1097
1098 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1099
1052 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1100 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1053 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1101 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1054 } 1102 }
@@ -1299,7 +1347,6 @@ namespace OpenSim.Region.Framework.Scenes
1299 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1347 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1300 } 1348 }
1301 } 1349 }
1302
1303 lock (scriptedcontrols) 1350 lock (scriptedcontrols)
1304 { 1351 {
1305 if (scriptedcontrols.Count > 0) 1352 if (scriptedcontrols.Count > 0)
@@ -1314,12 +1361,8 @@ namespace OpenSim.Region.Framework.Scenes
1314 1361
1315 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1362 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1316 { 1363 {
1317 // TODO: This doesn't prevent the user from walking yet. 1364 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1318 // Setting parent ID would fix this, if we knew what value 1365 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1319 // to use. Or we could add a m_isSitting variable.
1320 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1321 SitGround = true;
1322
1323 } 1366 }
1324 1367
1325 // In the future, these values might need to go global. 1368 // In the future, these values might need to go global.
@@ -1369,6 +1412,11 @@ namespace OpenSim.Region.Framework.Scenes
1369 update_rotation = true; 1412 update_rotation = true;
1370 } 1413 }
1371 1414
1415 //guilty until proven innocent..
1416 bool Nudging = true;
1417 //Basically, if there is at least one non-nudge control then we don't need
1418 //to worry about stopping the avatar
1419
1372 if (m_parentID == 0) 1420 if (m_parentID == 0)
1373 { 1421 {
1374 bool bAllowUpdateMoveToPosition = false; 1422 bool bAllowUpdateMoveToPosition = false;
@@ -1383,9 +1431,12 @@ namespace OpenSim.Region.Framework.Scenes
1383 else 1431 else
1384 dirVectors = Dir_Vectors; 1432 dirVectors = Dir_Vectors;
1385 1433
1386 // The fact that m_movementflag is a byte needs to be fixed 1434 bool[] isNudge = GetDirectionIsNudge();
1387 // it really should be a uint 1435
1388 uint nudgehack = 250; 1436
1437
1438
1439
1389 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1440 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1390 { 1441 {
1391 if (((uint)flags & (uint)DCF) != 0) 1442 if (((uint)flags & (uint)DCF) != 0)
@@ -1395,40 +1446,28 @@ namespace OpenSim.Region.Framework.Scenes
1395 try 1446 try
1396 { 1447 {
1397 agent_control_v3 += dirVectors[i]; 1448 agent_control_v3 += dirVectors[i];
1398 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1449 if (isNudge[i] == false)
1450 {
1451 Nudging = false;
1452 }
1399 } 1453 }
1400 catch (IndexOutOfRangeException) 1454 catch (IndexOutOfRangeException)
1401 { 1455 {
1402 // Why did I get this? 1456 // Why did I get this?
1403 } 1457 }
1404 1458
1405 if ((m_movementflag & (byte)(uint)DCF) == 0) 1459 if ((m_movementflag & (uint)DCF) == 0)
1406 { 1460 {
1407 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1408 {
1409 m_movementflag |= (byte)nudgehack;
1410 }
1411 m_movementflag += (byte)(uint)DCF; 1461 m_movementflag += (byte)(uint)DCF;
1412 update_movementflag = true; 1462 update_movementflag = true;
1413 } 1463 }
1414 } 1464 }
1415 else 1465 else
1416 { 1466 {
1417 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1467 if ((m_movementflag & (uint)DCF) != 0)
1418 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1419 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1420 ) // This or is for Nudge forward
1421 { 1468 {
1422 m_movementflag -= ((byte)(uint)DCF); 1469 m_movementflag -= (byte)(uint)DCF;
1423
1424 update_movementflag = true; 1470 update_movementflag = true;
1425 /*
1426 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1427 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1428 {
1429 m_log.Debug("Removed Hack flag");
1430 }
1431 */
1432 } 1471 }
1433 else 1472 else
1434 { 1473 {
@@ -1472,6 +1511,9 @@ namespace OpenSim.Region.Framework.Scenes
1472 // Ignore z component of vector 1511 // Ignore z component of vector
1473 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1512 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1474 LocalVectorToTarget2D.Normalize(); 1513 LocalVectorToTarget2D.Normalize();
1514
1515 //We're not nudging
1516 Nudging = false;
1475 agent_control_v3 += LocalVectorToTarget2D; 1517 agent_control_v3 += LocalVectorToTarget2D;
1476 1518
1477 // update avatar movement flags. the avatar coordinate system is as follows: 1519 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1560,13 +1602,13 @@ namespace OpenSim.Region.Framework.Scenes
1560 // m_log.DebugFormat( 1602 // m_log.DebugFormat(
1561 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1603 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1562 1604
1563 AddNewMovement(agent_control_v3, q); 1605 AddNewMovement(agent_control_v3, q, Nudging);
1564 1606
1565 1607
1566 } 1608 }
1567 } 1609 }
1568 1610
1569 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1611 if (update_movementflag)
1570 Animator.UpdateMovementAnimations(); 1612 Animator.UpdateMovementAnimations();
1571 1613
1572 m_scene.EventManager.TriggerOnClientMovement(this); 1614 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1581,7 +1623,6 @@ namespace OpenSim.Region.Framework.Scenes
1581 m_sitAtAutoTarget = false; 1623 m_sitAtAutoTarget = false;
1582 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1624 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1583 //proxy.PCode = (byte)PCode.ParticleSystem; 1625 //proxy.PCode = (byte)PCode.ParticleSystem;
1584
1585 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1626 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1586 proxyObjectGroup.AttachToScene(m_scene); 1627 proxyObjectGroup.AttachToScene(m_scene);
1587 1628
@@ -1623,7 +1664,7 @@ namespace OpenSim.Region.Framework.Scenes
1623 } 1664 }
1624 m_moveToPositionInProgress = true; 1665 m_moveToPositionInProgress = true;
1625 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1666 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1626 } 1667 }
1627 catch (Exception ex) 1668 catch (Exception ex)
1628 { 1669 {
1629 //Why did I get this error? 1670 //Why did I get this error?
@@ -1645,7 +1686,7 @@ namespace OpenSim.Region.Framework.Scenes
1645 Velocity = Vector3.Zero; 1686 Velocity = Vector3.Zero;
1646 SendFullUpdateToAllClients(); 1687 SendFullUpdateToAllClients();
1647 1688
1648 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1689 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1649 } 1690 }
1650 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1691 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1651 m_requestedSitTargetUUID = UUID.Zero; 1692 m_requestedSitTargetUUID = UUID.Zero;
@@ -1678,55 +1719,84 @@ namespace OpenSim.Region.Framework.Scenes
1678 /// </summary> 1719 /// </summary>
1679 public void StandUp() 1720 public void StandUp()
1680 { 1721 {
1681 if (SitGround)
1682 SitGround = false;
1683
1684 if (m_parentID != 0) 1722 if (m_parentID != 0)
1685 { 1723 {
1686 m_log.Debug("StandupCode Executed");
1687 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1724 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1688 if (part != null) 1725 if (part != null)
1689 { 1726 {
1727 part.TaskInventory.LockItemsForRead(true);
1690 TaskInventoryDictionary taskIDict = part.TaskInventory; 1728 TaskInventoryDictionary taskIDict = part.TaskInventory;
1691 if (taskIDict != null) 1729 if (taskIDict != null)
1692 { 1730 {
1693 lock (taskIDict) 1731 foreach (UUID taskID in taskIDict.Keys)
1694 { 1732 {
1695 foreach (UUID taskID in taskIDict.Keys) 1733 UnRegisterControlEventsToScript(LocalId, taskID);
1696 { 1734 taskIDict[taskID].PermsMask &= ~(
1697 UnRegisterControlEventsToScript(LocalId, taskID); 1735 2048 | //PERMISSION_CONTROL_CAMERA
1698 taskIDict[taskID].PermsMask &= ~( 1736 4); // PERMISSION_TAKE_CONTROLS
1699 2048 | //PERMISSION_CONTROL_CAMERA
1700 4); // PERMISSION_TAKE_CONTROLS
1701 }
1702 } 1737 }
1703
1704 } 1738 }
1739 part.TaskInventory.LockItemsForRead(false);
1705 // Reset sit target. 1740 // Reset sit target.
1706 if (part.GetAvatarOnSitTarget() == UUID) 1741 if (part.GetAvatarOnSitTarget() == UUID)
1707 part.SetAvatarOnSitTarget(UUID.Zero); 1742 part.SetAvatarOnSitTarget(UUID.Zero);
1708
1709 m_parentPosition = part.GetWorldPosition(); 1743 m_parentPosition = part.GetWorldPosition();
1710 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1744 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1711 } 1745 }
1712 1746 // part.GetWorldRotation() is the rotation of the object being sat on
1713 if (m_physicsActor == null) 1747 // Rotation is the sittiing Av's rotation
1714 { 1748
1715 AddToPhysicalScene(false); 1749 Quaternion partRot;
1750// if (part.LinkNum == 1)
1751// { // Root prim of linkset
1752// partRot = part.ParentGroup.RootPart.RotationOffset;
1753// }
1754// else
1755// { // single or child prim
1756
1757// }
1758 if (part == null) //CW: Part may be gone. llDie() for example.
1759 {
1760 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1761 }
1762 else
1763 {
1764 partRot = part.GetWorldRotation();
1716 } 1765 }
1717 1766
1718 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1767 Quaternion partIRot = Quaternion.Inverse(partRot);
1719 m_parentPosition = Vector3.Zero; 1768
1769 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1770 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1720 1771
1721 m_parentID = 0; 1772
1773 if (m_physicsActor == null)
1774 {
1775 AddToPhysicalScene(false);
1776 }
1777 //CW: If the part isn't null then we can set the current position
1778 if (part != null)
1779 {
1780 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1781 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1782 part.IsOccupied = false;
1783 }
1784 else
1785 {
1786 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1787 AbsolutePosition = m_lastWorldPosition;
1788 }
1789
1790 m_parentPosition = Vector3.Zero;
1791 m_parentID = 0;
1722 SendFullUpdateToAllClients(); 1792 SendFullUpdateToAllClients();
1723 m_requestedSitTargetID = 0; 1793 m_requestedSitTargetID = 0;
1794
1724 if ((m_physicsActor != null) && (m_avHeight > 0)) 1795 if ((m_physicsActor != null) && (m_avHeight > 0))
1725 { 1796 {
1726 SetHeight(m_avHeight); 1797 SetHeight(m_avHeight);
1727 } 1798 }
1728 } 1799 }
1729
1730 Animator.TrySetMovementAnimation("STAND"); 1800 Animator.TrySetMovementAnimation("STAND");
1731 } 1801 }
1732 1802
@@ -1757,13 +1827,9 @@ namespace OpenSim.Region.Framework.Scenes
1757 Vector3 avSitOffSet = part.SitTargetPosition; 1827 Vector3 avSitOffSet = part.SitTargetPosition;
1758 Quaternion avSitOrientation = part.SitTargetOrientation; 1828 Quaternion avSitOrientation = part.SitTargetOrientation;
1759 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1829 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1760 1830 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1761 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1831 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1762 bool SitTargetisSet = 1832 if (SitTargetisSet && !SitTargetOccupied)
1763 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1764 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1765
1766 if (SitTargetisSet && SitTargetUnOccupied)
1767 { 1833 {
1768 //switch the target to this prim 1834 //switch the target to this prim
1769 return part; 1835 return part;
@@ -1777,84 +1843,152 @@ namespace OpenSim.Region.Framework.Scenes
1777 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1843 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1778 { 1844 {
1779 bool autopilot = true; 1845 bool autopilot = true;
1846 Vector3 autopilotTarget = new Vector3();
1847 Quaternion sitOrientation = Quaternion.Identity;
1780 Vector3 pos = new Vector3(); 1848 Vector3 pos = new Vector3();
1781 Quaternion sitOrientation = pSitOrientation;
1782 Vector3 cameraEyeOffset = Vector3.Zero; 1849 Vector3 cameraEyeOffset = Vector3.Zero;
1783 Vector3 cameraAtOffset = Vector3.Zero; 1850 Vector3 cameraAtOffset = Vector3.Zero;
1784 bool forceMouselook = false; 1851 bool forceMouselook = false;
1785 1852
1786 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1853 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1787 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1854 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1788 if (part != null) 1855 if (part == null) return;
1789 { 1856
1790 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1857 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1791 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1858 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1792 1859
1793 // Is a sit target available? 1860 // part is the prim to sit on
1794 Vector3 avSitOffSet = part.SitTargetPosition; 1861 // offset is the world-ref vector distance from that prim center to the click-spot
1795 Quaternion avSitOrientation = part.SitTargetOrientation; 1862 // UUID is the UUID of the Avatar doing the clicking
1796 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1863
1797 1864 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1798 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1865
1799 bool SitTargetisSet = 1866 // Is a sit target available?
1800 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1867 Vector3 avSitOffSet = part.SitTargetPosition;
1801 ( 1868 Quaternion avSitOrientation = part.SitTargetOrientation;
1802 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1869
1803 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1870 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1804 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1871 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1805 ) 1872 Quaternion partRot;
1806 )); 1873// if (part.LinkNum == 1)
1807 1874// { // Root prim of linkset
1808 if (SitTargetisSet && SitTargetUnOccupied) 1875// partRot = part.ParentGroup.RootPart.RotationOffset;
1809 { 1876// }
1810 part.SetAvatarOnSitTarget(UUID); 1877// else
1811 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1878// { // single or child prim
1812 sitOrientation = avSitOrientation; 1879 partRot = part.GetWorldRotation();
1813 autopilot = false; 1880// }
1814 } 1881 Quaternion partIRot = Quaternion.Inverse(partRot);
1815 1882//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1816 pos = part.AbsolutePosition + offset; 1883 // Sit analysis rewritten by KF 091125
1817 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1884 if (SitTargetisSet) // scipted sit
1818 //{ 1885 {
1819 // offset = pos; 1886 if (!part.IsOccupied)
1820 //autopilot = false; 1887 {
1821 //} 1888//Console.WriteLine("Scripted, unoccupied");
1822 if (m_physicsActor != null) 1889 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1823 { 1890 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1824 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1891 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1825 // We can remove the physicsActor until they stand up. 1892 autopilot = false; // Jump direct to scripted llSitPos()
1826 m_sitAvatarHeight = m_physicsActor.Size.Z; 1893 }
1827 1894 else
1828 if (autopilot) 1895 {
1829 { 1896//Console.WriteLine("Scripted, occupied");
1830 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1897 return;
1831 { 1898 }
1832 autopilot = false; 1899 }
1900 else // Not Scripted
1901 {
1902 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1903 {
1904 // large prim & offset, ignore if other Avs sitting
1905// offset.Z -= 0.05f;
1906 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1907 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1908
1909//Console.WriteLine(" offset ={0}", offset);
1910//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1911//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1912
1913 }
1914 else // small offset
1915 {
1916//Console.WriteLine("Small offset");
1917 if (!part.IsOccupied)
1918 {
1919 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1920 autopilotTarget = part.AbsolutePosition;
1921 }
1922 else return; // occupied small
1923 } // end large/small
1924 } // end Scripted/not
1925 cameraAtOffset = part.GetCameraAtOffset();
1926 cameraEyeOffset = part.GetCameraEyeOffset();
1927 forceMouselook = part.GetForceMouselook();
1928 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1929 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1833 1930
1834 RemoveFromPhysicalScene(); 1931 if (m_physicsActor != null)
1835 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1932 {
1836 } 1933 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1837 } 1934 // We can remove the physicsActor until they stand up.
1838 else 1935 m_sitAvatarHeight = m_physicsActor.Size.Z;
1936 if (autopilot)
1937 { // its not a scripted sit
1938// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1939 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1839 { 1940 {
1941 autopilot = false; // close enough
1942 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1943 Not using the part's position because returning the AV to the last known standing
1944 position is likely to be more friendly, isn't it? */
1840 RemoveFromPhysicalScene(); 1945 RemoveFromPhysicalScene();
1841 } 1946 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1947 } // else the autopilot will get us close
1948 }
1949 else
1950 { // its a scripted sit
1951 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1952 I *am* using the part's position this time because we have no real idea how far away
1953 the avatar is from the sit target. */
1954 RemoveFromPhysicalScene();
1842 } 1955 }
1843
1844 cameraAtOffset = part.GetCameraAtOffset();
1845 cameraEyeOffset = part.GetCameraEyeOffset();
1846 forceMouselook = part.GetForceMouselook();
1847 } 1956 }
1848 1957 else return; // physactor is null!
1849 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1958
1850 m_requestedSitTargetUUID = targetID; 1959 Vector3 offsetr; // = offset * partIRot;
1960 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1961 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1962 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1963 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1964 offsetr = offset * partIRot;
1965//
1966 // else
1967 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1968 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1969 // (offset * partRot);
1970 // }
1971
1972//Console.WriteLine(" ");
1973//Console.WriteLine("link number ={0}", part.LinkNum);
1974//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1975//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1976//Console.WriteLine("Click offst ={0}", offset);
1977//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1978//Console.WriteLine("offsetr ={0}", offsetr);
1979//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1980//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1981
1982 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1983 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1851 // This calls HandleAgentSit twice, once from here, and the client calls 1984 // This calls HandleAgentSit twice, once from here, and the client calls
1852 // HandleAgentSit itself after it gets to the location 1985 // HandleAgentSit itself after it gets to the location
1853 // It doesn't get to the location until we've moved them there though 1986 // It doesn't get to the location until we've moved them there though
1854 // which happens in HandleAgentSit :P 1987 // which happens in HandleAgentSit :P
1855 m_autopilotMoving = autopilot; 1988 m_autopilotMoving = autopilot;
1856 m_autoPilotTarget = pos; 1989 m_autoPilotTarget = autopilotTarget;
1857 m_sitAtAutoTarget = autopilot; 1990 m_sitAtAutoTarget = autopilot;
1991 m_initialSitTarget = autopilotTarget;
1858 if (!autopilot) 1992 if (!autopilot)
1859 HandleAgentSit(remoteClient, UUID); 1993 HandleAgentSit(remoteClient, UUID);
1860 } 1994 }
@@ -2149,31 +2283,65 @@ namespace OpenSim.Region.Framework.Scenes
2149 { 2283 {
2150 if (part != null) 2284 if (part != null)
2151 { 2285 {
2286//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2152 if (part.GetAvatarOnSitTarget() == UUID) 2287 if (part.GetAvatarOnSitTarget() == UUID)
2153 { 2288 {
2289//Console.WriteLine("Scripted Sit");
2290 // Scripted sit
2154 Vector3 sitTargetPos = part.SitTargetPosition; 2291 Vector3 sitTargetPos = part.SitTargetPosition;
2155 Quaternion sitTargetOrient = part.SitTargetOrientation; 2292 Quaternion sitTargetOrient = part.SitTargetOrientation;
2156
2157 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2158 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2159
2160 //Quaternion result = (sitTargetOrient * vq) * nq;
2161
2162 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2293 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2163 m_pos += SIT_TARGET_ADJUSTMENT; 2294 m_pos += SIT_TARGET_ADJUSTMENT;
2164 m_bodyRot = sitTargetOrient; 2295 m_bodyRot = sitTargetOrient;
2165 //Rotation = sitTargetOrient;
2166 m_parentPosition = part.AbsolutePosition; 2296 m_parentPosition = part.AbsolutePosition;
2167 2297 part.IsOccupied = true;
2168 //SendTerseUpdateToAllClients();
2169 } 2298 }
2170 else 2299 else
2171 { 2300 {
2172 m_pos -= part.AbsolutePosition; 2301 // if m_avUnscriptedSitPos is zero then Av sits above center
2302 // Else Av sits at m_avUnscriptedSitPos
2303
2304 // Non-scripted sit by Kitto Flora 21Nov09
2305 // Calculate angle of line from prim to Av
2306 Quaternion partIRot;
2307// if (part.LinkNum == 1)
2308// { // Root prim of linkset
2309// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2310// }
2311// else
2312// { // single or child prim
2313 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2314// }
2315 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2316 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2317 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2318 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2319 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2320 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2321 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2322 // Av sits at world euler <0,0, z>, translated by part rotation
2323 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2324
2173 m_parentPosition = part.AbsolutePosition; 2325 m_parentPosition = part.AbsolutePosition;
2174 } 2326 part.IsOccupied = true;
2327 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2328 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2329 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2330 m_avUnscriptedSitPos; // adds click offset, if any
2331 //Set up raytrace to find top surface of prim
2332 Vector3 size = part.Scale;
2333 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2334 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2335 Vector3 down = new Vector3(0f, 0f, -1f);
2336//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2337 m_scene.PhysicsScene.RaycastWorld(
2338 start, // Vector3 position,
2339 down, // Vector3 direction,
2340 mag, // float length,
2341 SitAltitudeCallback); // retMethod
2342 } // end scripted/not
2175 } 2343 }
2176 else 2344 else // no Av
2177 { 2345 {
2178 return; 2346 return;
2179 } 2347 }
@@ -2185,11 +2353,36 @@ namespace OpenSim.Region.Framework.Scenes
2185 2353
2186 Animator.TrySetMovementAnimation(sitAnimation); 2354 Animator.TrySetMovementAnimation(sitAnimation);
2187 SendFullUpdateToAllClients(); 2355 SendFullUpdateToAllClients();
2188 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2189 // So we're also sending a terse update (which has avatar rotation)
2190 // [Update] We do now.
2191 //SendTerseUpdateToAllClients();
2192 } 2356 }
2357
2358 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2359 {
2360 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2361 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2362 if(hitYN)
2363 {
2364 // m_pos = Av offset from prim center to make look like on center
2365 // m_parentPosition = Actual center pos of prim
2366 // collisionPoint = spot on prim where we want to sit
2367 // collisionPoint.Z = global sit surface height
2368 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2369 Quaternion partIRot;
2370// if (part.LinkNum == 1)
2371/// { // Root prim of linkset
2372// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2373// }
2374// else
2375// { // single or child prim
2376 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2377// }
2378 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2379 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2380//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2381 m_pos += offset;
2382// ControllingClient.SendClearFollowCamProperties(part.UUID);
2383
2384 }
2385 } // End SitAltitudeCallback KF.
2193 2386
2194 /// <summary> 2387 /// <summary>
2195 /// Event handler for the 'Always run' setting on the client 2388 /// Event handler for the 'Always run' setting on the client
@@ -2219,7 +2412,7 @@ namespace OpenSim.Region.Framework.Scenes
2219 /// </summary> 2412 /// </summary>
2220 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2413 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2221 /// <param name="rotation">The direction in which this avatar should now face. 2414 /// <param name="rotation">The direction in which this avatar should now face.
2222 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2415 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2223 { 2416 {
2224 if (m_isChildAgent) 2417 if (m_isChildAgent)
2225 { 2418 {
@@ -2296,7 +2489,7 @@ namespace OpenSim.Region.Framework.Scenes
2296 2489
2297 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2490 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2298 m_forceToApply = direc; 2491 m_forceToApply = direc;
2299 2492 m_isNudging = Nudging;
2300 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2493 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2301 } 2494 }
2302 2495
@@ -2311,7 +2504,7 @@ namespace OpenSim.Region.Framework.Scenes
2311 const float POSITION_TOLERANCE = 0.05f; 2504 const float POSITION_TOLERANCE = 0.05f;
2312 //const int TIME_MS_TOLERANCE = 3000; 2505 //const int TIME_MS_TOLERANCE = 3000;
2313 2506
2314 SendPrimUpdates(); 2507
2315 2508
2316 if (m_newCoarseLocations) 2509 if (m_newCoarseLocations)
2317 { 2510 {
@@ -2347,6 +2540,9 @@ namespace OpenSim.Region.Framework.Scenes
2347 CheckForBorderCrossing(); 2540 CheckForBorderCrossing();
2348 CheckForSignificantMovement(); // sends update to the modules. 2541 CheckForSignificantMovement(); // sends update to the modules.
2349 } 2542 }
2543
2544 //Sending prim updates AFTER the avatar terse updates are sent
2545 SendPrimUpdates();
2350 } 2546 }
2351 2547
2352 #endregion 2548 #endregion
@@ -3251,14 +3447,25 @@ namespace OpenSim.Region.Framework.Scenes
3251 { 3447 {
3252 if (m_forceToApply.HasValue) 3448 if (m_forceToApply.HasValue)
3253 { 3449 {
3254 Vector3 force = m_forceToApply.Value;
3255 3450
3451 Vector3 force = m_forceToApply.Value;
3256 m_updateflag = true; 3452 m_updateflag = true;
3257// movementvector = force;
3258 Velocity = force; 3453 Velocity = force;
3259 3454
3260 m_forceToApply = null; 3455 m_forceToApply = null;
3261 } 3456 }
3457 else
3458 {
3459 if (m_isNudging)
3460 {
3461 Vector3 force = Vector3.Zero;
3462
3463 m_updateflag = true;
3464 Velocity = force;
3465 m_isNudging = false;
3466 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3467 }
3468 }
3262 } 3469 }
3263 3470
3264 public override void SetText(string text, Vector3 color, double alpha) 3471 public override void SetText(string text, Vector3 color, double alpha)
@@ -3309,18 +3516,29 @@ namespace OpenSim.Region.Framework.Scenes
3309 { 3516 {
3310 if (e == null) 3517 if (e == null)
3311 return; 3518 return;
3312 3519
3313 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3520 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3314 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3315 // as of this comment the interval is set in AddToPhysicalScene 3521 // as of this comment the interval is set in AddToPhysicalScene
3316 if (Animator!=null) 3522 if (Animator!=null)
3317 Animator.UpdateMovementAnimations(); 3523 {
3524 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3525 { // else its will lock out other animation changes, like ground sit.
3526 Animator.UpdateMovementAnimations();
3527 m_updateCount--;
3528 }
3529 }
3318 3530
3319 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3531 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3320 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3532 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3321 3533
3322 CollisionPlane = Vector4.UnitW; 3534 CollisionPlane = Vector4.UnitW;
3323 3535
3536 if (m_lastColCount != coldata.Count)
3537 {
3538 m_updateCount = UPDATE_COUNT;
3539 m_lastColCount = coldata.Count;
3540 }
3541
3324 if (coldata.Count != 0 && Animator != null) 3542 if (coldata.Count != 0 && Animator != null)
3325 { 3543 {
3326 switch (Animator.CurrentMovementAnimation) 3544 switch (Animator.CurrentMovementAnimation)
@@ -3927,5 +4145,16 @@ namespace OpenSim.Region.Framework.Scenes
3927 m_reprioritization_called = false; 4145 m_reprioritization_called = false;
3928 } 4146 }
3929 } 4147 }
4148
4149 private Vector3 Quat2Euler(Quaternion rot){
4150 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4151 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4152 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4153 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4154 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4155 return(new Vector3(x,y,z));
4156 }
4157
4158
3930 } 4159 }
3931} 4160}