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