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.cs579
1 files changed, 404 insertions, 175 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 8545425..f36c1a9 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
@@ -113,8 +115,11 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 115 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 116 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 117 public Vector4 CollisionPlane = Vector4.UnitW;
116 118
117 private Vector3 m_lastPosition; 119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
121 private Vector3 m_lastPosition;
122 private Vector3 m_lastWorldPosition;
118 private Quaternion m_lastRotation; 123 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 124 private Vector3 m_lastVelocity;
120 //private int m_lastTerseSent; 125 //private int m_lastTerseSent;
@@ -124,7 +129,6 @@ namespace OpenSim.Region.Framework.Scenes
124 private Vector3? m_forceToApply; 129 private Vector3? m_forceToApply;
125 private uint m_requestedSitTargetID; 130 private uint m_requestedSitTargetID;
126 private UUID m_requestedSitTargetUUID; 131 private UUID m_requestedSitTargetUUID;
127 public bool SitGround = false;
128 132
129 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 133 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
130 134
@@ -146,7 +150,6 @@ namespace OpenSim.Region.Framework.Scenes
146 private int m_perfMonMS; 150 private int m_perfMonMS;
147 151
148 private bool m_setAlwaysRun; 152 private bool m_setAlwaysRun;
149
150 private bool m_forceFly; 153 private bool m_forceFly;
151 private bool m_flyDisabled; 154 private bool m_flyDisabled;
152 155
@@ -170,7 +173,8 @@ namespace OpenSim.Region.Framework.Scenes
170 protected RegionInfo m_regionInfo; 173 protected RegionInfo m_regionInfo;
171 protected ulong crossingFromRegion; 174 protected ulong crossingFromRegion;
172 175
173 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 176 private readonly Vector3[] Dir_Vectors = new Vector3[11];
177 private bool m_isNudging = false;
174 178
175 // Position of agent's camera in world (region cordinates) 179 // Position of agent's camera in world (region cordinates)
176 protected Vector3 m_CameraCenter; 180 protected Vector3 m_CameraCenter;
@@ -195,6 +199,7 @@ namespace OpenSim.Region.Framework.Scenes
195 private bool m_autopilotMoving; 199 private bool m_autopilotMoving;
196 private Vector3 m_autoPilotTarget; 200 private Vector3 m_autoPilotTarget;
197 private bool m_sitAtAutoTarget; 201 private bool m_sitAtAutoTarget;
202 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
198 203
199 private string m_nextSitAnimation = String.Empty; 204 private string m_nextSitAnimation = String.Empty;
200 205
@@ -205,6 +210,9 @@ namespace OpenSim.Region.Framework.Scenes
205 private bool m_followCamAuto; 210 private bool m_followCamAuto;
206 211
207 private int m_movementUpdateCount; 212 private int m_movementUpdateCount;
213 private int m_lastColCount = -1; //KF: Look for Collision chnages
214 private int m_updateCount = 0; //KF: Update Anims for a while
215 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
208 216
209 private const int NumMovementsBetweenRayCast = 5; 217 private const int NumMovementsBetweenRayCast = 5;
210 218
@@ -235,7 +243,9 @@ namespace OpenSim.Region.Framework.Scenes
235 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
236 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
237 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
238 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 246 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
247 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
248 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
239 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
240 } 250 }
241 251
@@ -661,10 +671,7 @@ namespace OpenSim.Region.Framework.Scenes
661 671
662 672
663 AdjustKnownSeeds(); 673 AdjustKnownSeeds();
664
665 // TODO: I think, this won't send anything, as we are still a child here...
666 Animator.TrySetMovementAnimation("STAND"); 674 Animator.TrySetMovementAnimation("STAND");
667
668 // we created a new ScenePresence (a new child agent) in a fresh region. 675 // we created a new ScenePresence (a new child agent) in a fresh region.
669 // Request info about all the (root) agents in this region 676 // Request info about all the (root) agents in this region
670 // Note: This won't send data *to* other clients in that region (children don't send) 677 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -720,25 +727,47 @@ namespace OpenSim.Region.Framework.Scenes
720 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 727 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
721 Dir_Vectors[4] = Vector3.UnitZ; //UP 728 Dir_Vectors[4] = Vector3.UnitZ; //UP
722 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 729 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
723 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 730 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
724 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 731 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
725 Dir_Vectors[7] = -Vector3.UnitX; //BACK 732 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
733 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
734 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
726 } 735 }
727 736
728 private Vector3[] GetWalkDirectionVectors() 737 private Vector3[] GetWalkDirectionVectors()
729 { 738 {
730 Vector3[] vector = new Vector3[9]; 739 Vector3[] vector = new Vector3[11];
731 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 740 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
732 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 741 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
733 vector[2] = Vector3.UnitY; //LEFT 742 vector[2] = Vector3.UnitY; //LEFT
734 vector[3] = -Vector3.UnitY; //RIGHT 743 vector[3] = -Vector3.UnitY; //RIGHT
735 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 744 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
736 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 745 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
737 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 746 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
738 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 747 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
739 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 748 vector[8] = Vector3.UnitY; //LEFT_NUDGE
749 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
750 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
740 return vector; 751 return vector;
741 } 752 }
753
754 private bool[] GetDirectionIsNudge()
755 {
756 bool[] isNudge = new bool[11];
757 isNudge[0] = false; //FORWARD
758 isNudge[1] = false; //BACK
759 isNudge[2] = false; //LEFT
760 isNudge[3] = false; //RIGHT
761 isNudge[4] = false; //UP
762 isNudge[5] = false; //DOWN
763 isNudge[6] = true; //FORWARD_NUDGE
764 isNudge[7] = true; //BACK_NUDGE
765 isNudge[8] = true; //LEFT_NUDGE
766 isNudge[9] = true; //RIGHT_NUDGE
767 isNudge[10] = true; //DOWN_Nudge
768 return isNudge;
769 }
770
742 771
743 #endregion 772 #endregion
744 773
@@ -807,9 +836,24 @@ namespace OpenSim.Region.Framework.Scenes
807 { 836 {
808 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 837 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
809 pos.Y = crossedBorder.BorderLine.Z - 1; 838 pos.Y = crossedBorder.BorderLine.Z - 1;
839 }
840
841 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
842 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
843 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
844 if (KnownChildRegionHandles.Count == 0)
845 {
846 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
847 if (land != null)
848 {
849 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
850 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)
851 {
852 pos = land.LandData.UserLocation;
853 }
854 }
810 } 855 }
811 856
812
813 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 857 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
814 { 858 {
815 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 859 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -944,9 +988,10 @@ namespace OpenSim.Region.Framework.Scenes
944 public void Teleport(Vector3 pos) 988 public void Teleport(Vector3 pos)
945 { 989 {
946 bool isFlying = false; 990 bool isFlying = false;
947 if (m_physicsActor != null)
948 isFlying = m_physicsActor.Flying;
949 991
992 if (m_physicsActor != null)
993 isFlying = m_physicsActor.Flying;
994
950 RemoveFromPhysicalScene(); 995 RemoveFromPhysicalScene();
951 Velocity = Vector3.Zero; 996 Velocity = Vector3.Zero;
952 AbsolutePosition = pos; 997 AbsolutePosition = pos;
@@ -957,7 +1002,8 @@ namespace OpenSim.Region.Framework.Scenes
957 SetHeight(m_appearance.AvatarHeight); 1002 SetHeight(m_appearance.AvatarHeight);
958 } 1003 }
959 1004
960 SendTerseUpdateToAllClients(); 1005 SendTerseUpdateToAllClients();
1006
961 } 1007 }
962 1008
963 public void TeleportWithMomentum(Vector3 pos) 1009 public void TeleportWithMomentum(Vector3 pos)
@@ -1002,7 +1048,9 @@ namespace OpenSim.Region.Framework.Scenes
1002 { 1048 {
1003 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1049 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1004 } 1050 }
1005 1051
1052 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1053
1006 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1054 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1007 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1055 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1008 } 1056 }
@@ -1237,7 +1285,6 @@ namespace OpenSim.Region.Framework.Scenes
1237 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1285 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1238 } 1286 }
1239 } 1287 }
1240
1241 lock (scriptedcontrols) 1288 lock (scriptedcontrols)
1242 { 1289 {
1243 if (scriptedcontrols.Count > 0) 1290 if (scriptedcontrols.Count > 0)
@@ -1252,12 +1299,8 @@ namespace OpenSim.Region.Framework.Scenes
1252 1299
1253 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1300 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1254 { 1301 {
1255 // TODO: This doesn't prevent the user from walking yet. 1302 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1256 // Setting parent ID would fix this, if we knew what value 1303 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1257 // to use. Or we could add a m_isSitting variable.
1258 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1259 SitGround = true;
1260
1261 } 1304 }
1262 1305
1263 // In the future, these values might need to go global. 1306 // In the future, these values might need to go global.
@@ -1301,6 +1344,11 @@ namespace OpenSim.Region.Framework.Scenes
1301 update_rotation = true; 1344 update_rotation = true;
1302 } 1345 }
1303 1346
1347 //guilty until proven innocent..
1348 bool Nudging = true;
1349 //Basically, if there is at least one non-nudge control then we don't need
1350 //to worry about stopping the avatar
1351
1304 if (m_parentID == 0) 1352 if (m_parentID == 0)
1305 { 1353 {
1306 bool bAllowUpdateMoveToPosition = false; 1354 bool bAllowUpdateMoveToPosition = false;
@@ -1315,9 +1363,12 @@ namespace OpenSim.Region.Framework.Scenes
1315 else 1363 else
1316 dirVectors = Dir_Vectors; 1364 dirVectors = Dir_Vectors;
1317 1365
1318 // The fact that m_movementflag is a byte needs to be fixed 1366 bool[] isNudge = GetDirectionIsNudge();
1319 // it really should be a uint 1367
1320 uint nudgehack = 250; 1368
1369
1370
1371
1321 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1372 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1322 { 1373 {
1323 if (((uint)flags & (uint)DCF) != 0) 1374 if (((uint)flags & (uint)DCF) != 0)
@@ -1327,40 +1378,28 @@ namespace OpenSim.Region.Framework.Scenes
1327 try 1378 try
1328 { 1379 {
1329 agent_control_v3 += dirVectors[i]; 1380 agent_control_v3 += dirVectors[i];
1330 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1381 if (isNudge[i] == false)
1382 {
1383 Nudging = false;
1384 }
1331 } 1385 }
1332 catch (IndexOutOfRangeException) 1386 catch (IndexOutOfRangeException)
1333 { 1387 {
1334 // Why did I get this? 1388 // Why did I get this?
1335 } 1389 }
1336 1390
1337 if ((m_movementflag & (byte)(uint)DCF) == 0) 1391 if ((m_movementflag & (uint)DCF) == 0)
1338 { 1392 {
1339 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1340 {
1341 m_movementflag |= (byte)nudgehack;
1342 }
1343 m_movementflag += (byte)(uint)DCF; 1393 m_movementflag += (byte)(uint)DCF;
1344 update_movementflag = true; 1394 update_movementflag = true;
1345 } 1395 }
1346 } 1396 }
1347 else 1397 else
1348 { 1398 {
1349 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1399 if ((m_movementflag & (uint)DCF) != 0)
1350 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1351 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1352 ) // This or is for Nudge forward
1353 { 1400 {
1354 m_movementflag -= ((byte)(uint)DCF); 1401 m_movementflag -= (byte)(uint)DCF;
1355
1356 update_movementflag = true; 1402 update_movementflag = true;
1357 /*
1358 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1359 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1360 {
1361 m_log.Debug("Removed Hack flag");
1362 }
1363 */
1364 } 1403 }
1365 else 1404 else
1366 { 1405 {
@@ -1404,6 +1443,9 @@ namespace OpenSim.Region.Framework.Scenes
1404 // Ignore z component of vector 1443 // Ignore z component of vector
1405 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1444 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1406 LocalVectorToTarget2D.Normalize(); 1445 LocalVectorToTarget2D.Normalize();
1446
1447 //We're not nudging
1448 Nudging = false;
1407 agent_control_v3 += LocalVectorToTarget2D; 1449 agent_control_v3 += LocalVectorToTarget2D;
1408 1450
1409 // update avatar movement flags. the avatar coordinate system is as follows: 1451 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1492,13 +1534,13 @@ namespace OpenSim.Region.Framework.Scenes
1492 // m_log.DebugFormat( 1534 // m_log.DebugFormat(
1493 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1535 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1494 1536
1495 AddNewMovement(agent_control_v3, q); 1537 AddNewMovement(agent_control_v3, q, Nudging);
1496 1538
1497 1539
1498 } 1540 }
1499 } 1541 }
1500 1542
1501 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1543 if (update_movementflag)
1502 Animator.UpdateMovementAnimations(); 1544 Animator.UpdateMovementAnimations();
1503 1545
1504 m_scene.EventManager.TriggerOnClientMovement(this); 1546 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1513,7 +1555,6 @@ namespace OpenSim.Region.Framework.Scenes
1513 m_sitAtAutoTarget = false; 1555 m_sitAtAutoTarget = false;
1514 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1556 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1515 //proxy.PCode = (byte)PCode.ParticleSystem; 1557 //proxy.PCode = (byte)PCode.ParticleSystem;
1516
1517 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1558 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1518 proxyObjectGroup.AttachToScene(m_scene); 1559 proxyObjectGroup.AttachToScene(m_scene);
1519 1560
@@ -1555,7 +1596,7 @@ namespace OpenSim.Region.Framework.Scenes
1555 } 1596 }
1556 m_moveToPositionInProgress = true; 1597 m_moveToPositionInProgress = true;
1557 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1598 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1558 } 1599 }
1559 catch (Exception ex) 1600 catch (Exception ex)
1560 { 1601 {
1561 //Why did I get this error? 1602 //Why did I get this error?
@@ -1577,7 +1618,7 @@ namespace OpenSim.Region.Framework.Scenes
1577 Velocity = Vector3.Zero; 1618 Velocity = Vector3.Zero;
1578 SendFullUpdateToAllClients(); 1619 SendFullUpdateToAllClients();
1579 1620
1580 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1621 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1581 } 1622 }
1582 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1623 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1583 m_requestedSitTargetUUID = UUID.Zero; 1624 m_requestedSitTargetUUID = UUID.Zero;
@@ -1610,55 +1651,84 @@ namespace OpenSim.Region.Framework.Scenes
1610 /// </summary> 1651 /// </summary>
1611 public void StandUp() 1652 public void StandUp()
1612 { 1653 {
1613 if (SitGround)
1614 SitGround = false;
1615
1616 if (m_parentID != 0) 1654 if (m_parentID != 0)
1617 { 1655 {
1618 m_log.Debug("StandupCode Executed");
1619 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1656 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1620 if (part != null) 1657 if (part != null)
1621 { 1658 {
1659 part.TaskInventory.LockItemsForRead(true);
1622 TaskInventoryDictionary taskIDict = part.TaskInventory; 1660 TaskInventoryDictionary taskIDict = part.TaskInventory;
1623 if (taskIDict != null) 1661 if (taskIDict != null)
1624 { 1662 {
1625 lock (taskIDict) 1663 foreach (UUID taskID in taskIDict.Keys)
1626 { 1664 {
1627 foreach (UUID taskID in taskIDict.Keys) 1665 UnRegisterControlEventsToScript(LocalId, taskID);
1628 { 1666 taskIDict[taskID].PermsMask &= ~(
1629 UnRegisterControlEventsToScript(LocalId, taskID); 1667 2048 | //PERMISSION_CONTROL_CAMERA
1630 taskIDict[taskID].PermsMask &= ~( 1668 4); // PERMISSION_TAKE_CONTROLS
1631 2048 | //PERMISSION_CONTROL_CAMERA
1632 4); // PERMISSION_TAKE_CONTROLS
1633 }
1634 } 1669 }
1635
1636 } 1670 }
1671 part.TaskInventory.LockItemsForRead(false);
1637 // Reset sit target. 1672 // Reset sit target.
1638 if (part.GetAvatarOnSitTarget() == UUID) 1673 if (part.GetAvatarOnSitTarget() == UUID)
1639 part.SetAvatarOnSitTarget(UUID.Zero); 1674 part.SetAvatarOnSitTarget(UUID.Zero);
1640
1641 m_parentPosition = part.GetWorldPosition(); 1675 m_parentPosition = part.GetWorldPosition();
1642 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1676 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1643 } 1677 }
1644 1678 // part.GetWorldRotation() is the rotation of the object being sat on
1645 if (m_physicsActor == null) 1679 // Rotation is the sittiing Av's rotation
1646 { 1680
1647 AddToPhysicalScene(false); 1681 Quaternion partRot;
1682// if (part.LinkNum == 1)
1683// { // Root prim of linkset
1684// partRot = part.ParentGroup.RootPart.RotationOffset;
1685// }
1686// else
1687// { // single or child prim
1688
1689// }
1690 if (part == null) //CW: Part may be gone. llDie() for example.
1691 {
1692 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1693 }
1694 else
1695 {
1696 partRot = part.GetWorldRotation();
1697 }
1698
1699 Quaternion partIRot = Quaternion.Inverse(partRot);
1700
1701 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1702 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1703
1704
1705 if (m_physicsActor == null)
1706 {
1707 AddToPhysicalScene(false);
1708 }
1709 //CW: If the part isn't null then we can set the current position
1710 if (part != null)
1711 {
1712 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1713 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1714 part.IsOccupied = false;
1715 }
1716 else
1717 {
1718 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1719 AbsolutePosition = m_lastWorldPosition;
1648 } 1720 }
1649 1721
1650 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1722 m_parentPosition = Vector3.Zero;
1651 m_parentPosition = Vector3.Zero; 1723 m_parentID = 0;
1652
1653 m_parentID = 0;
1654 SendFullUpdateToAllClients(); 1724 SendFullUpdateToAllClients();
1655 m_requestedSitTargetID = 0; 1725 m_requestedSitTargetID = 0;
1726
1656 if ((m_physicsActor != null) && (m_avHeight > 0)) 1727 if ((m_physicsActor != null) && (m_avHeight > 0))
1657 { 1728 {
1658 SetHeight(m_avHeight); 1729 SetHeight(m_avHeight);
1659 } 1730 }
1660 } 1731 }
1661
1662 Animator.TrySetMovementAnimation("STAND"); 1732 Animator.TrySetMovementAnimation("STAND");
1663 } 1733 }
1664 1734
@@ -1689,13 +1759,9 @@ namespace OpenSim.Region.Framework.Scenes
1689 Vector3 avSitOffSet = part.SitTargetPosition; 1759 Vector3 avSitOffSet = part.SitTargetPosition;
1690 Quaternion avSitOrientation = part.SitTargetOrientation; 1760 Quaternion avSitOrientation = part.SitTargetOrientation;
1691 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1761 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1692 1762 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1693 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1763 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1694 bool SitTargetisSet = 1764 if (SitTargetisSet && !SitTargetOccupied)
1695 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1696 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1697
1698 if (SitTargetisSet && SitTargetUnOccupied)
1699 { 1765 {
1700 //switch the target to this prim 1766 //switch the target to this prim
1701 return part; 1767 return part;
@@ -1709,84 +1775,152 @@ namespace OpenSim.Region.Framework.Scenes
1709 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1775 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1710 { 1776 {
1711 bool autopilot = true; 1777 bool autopilot = true;
1778 Vector3 autopilotTarget = new Vector3();
1779 Quaternion sitOrientation = Quaternion.Identity;
1712 Vector3 pos = new Vector3(); 1780 Vector3 pos = new Vector3();
1713 Quaternion sitOrientation = pSitOrientation;
1714 Vector3 cameraEyeOffset = Vector3.Zero; 1781 Vector3 cameraEyeOffset = Vector3.Zero;
1715 Vector3 cameraAtOffset = Vector3.Zero; 1782 Vector3 cameraAtOffset = Vector3.Zero;
1716 bool forceMouselook = false; 1783 bool forceMouselook = false;
1717 1784
1718 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1785 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1719 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1786 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1720 if (part != null) 1787 if (part == null) return;
1721 { 1788
1722 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1789 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1723 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1790 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1724 1791
1725 // Is a sit target available? 1792 // part is the prim to sit on
1726 Vector3 avSitOffSet = part.SitTargetPosition; 1793 // offset is the world-ref vector distance from that prim center to the click-spot
1727 Quaternion avSitOrientation = part.SitTargetOrientation; 1794 // UUID is the UUID of the Avatar doing the clicking
1728 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1795
1729 1796 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1730 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1797
1731 bool SitTargetisSet = 1798 // Is a sit target available?
1732 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1799 Vector3 avSitOffSet = part.SitTargetPosition;
1733 ( 1800 Quaternion avSitOrientation = part.SitTargetOrientation;
1734 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1801
1735 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1802 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1736 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1803 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1737 ) 1804 Quaternion partRot;
1738 )); 1805// if (part.LinkNum == 1)
1739 1806// { // Root prim of linkset
1740 if (SitTargetisSet && SitTargetUnOccupied) 1807// partRot = part.ParentGroup.RootPart.RotationOffset;
1741 { 1808// }
1742 part.SetAvatarOnSitTarget(UUID); 1809// else
1743 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1810// { // single or child prim
1744 sitOrientation = avSitOrientation; 1811 partRot = part.GetWorldRotation();
1745 autopilot = false; 1812// }
1746 } 1813 Quaternion partIRot = Quaternion.Inverse(partRot);
1747 1814//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1748 pos = part.AbsolutePosition + offset; 1815 // Sit analysis rewritten by KF 091125
1749 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1816 if (SitTargetisSet) // scipted sit
1750 //{ 1817 {
1751 // offset = pos; 1818 if (!part.IsOccupied)
1752 //autopilot = false; 1819 {
1753 //} 1820//Console.WriteLine("Scripted, unoccupied");
1754 if (m_physicsActor != null) 1821 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1755 { 1822 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1756 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1823 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1757 // We can remove the physicsActor until they stand up. 1824 autopilot = false; // Jump direct to scripted llSitPos()
1758 m_sitAvatarHeight = m_physicsActor.Size.Z; 1825 }
1759 1826 else
1760 if (autopilot) 1827 {
1761 { 1828//Console.WriteLine("Scripted, occupied");
1762 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1829 return;
1763 { 1830 }
1764 autopilot = false; 1831 }
1832 else // Not Scripted
1833 {
1834 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1835 {
1836 // large prim & offset, ignore if other Avs sitting
1837// offset.Z -= 0.05f;
1838 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1839 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1840
1841//Console.WriteLine(" offset ={0}", offset);
1842//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1843//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1844
1845 }
1846 else // small offset
1847 {
1848//Console.WriteLine("Small offset");
1849 if (!part.IsOccupied)
1850 {
1851 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1852 autopilotTarget = part.AbsolutePosition;
1853 }
1854 else return; // occupied small
1855 } // end large/small
1856 } // end Scripted/not
1857 cameraAtOffset = part.GetCameraAtOffset();
1858 cameraEyeOffset = part.GetCameraEyeOffset();
1859 forceMouselook = part.GetForceMouselook();
1860 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1861 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1765 1862
1766 RemoveFromPhysicalScene(); 1863 if (m_physicsActor != null)
1767 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1864 {
1768 } 1865 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1769 } 1866 // We can remove the physicsActor until they stand up.
1770 else 1867 m_sitAvatarHeight = m_physicsActor.Size.Z;
1868 if (autopilot)
1869 { // its not a scripted sit
1870// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1871 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1771 { 1872 {
1873 autopilot = false; // close enough
1874 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1875 Not using the part's position because returning the AV to the last known standing
1876 position is likely to be more friendly, isn't it? */
1772 RemoveFromPhysicalScene(); 1877 RemoveFromPhysicalScene();
1773 } 1878 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1879 } // else the autopilot will get us close
1880 }
1881 else
1882 { // its a scripted sit
1883 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1884 I *am* using the part's position this time because we have no real idea how far away
1885 the avatar is from the sit target. */
1886 RemoveFromPhysicalScene();
1774 } 1887 }
1775
1776 cameraAtOffset = part.GetCameraAtOffset();
1777 cameraEyeOffset = part.GetCameraEyeOffset();
1778 forceMouselook = part.GetForceMouselook();
1779 } 1888 }
1780 1889 else return; // physactor is null!
1781 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1890
1782 m_requestedSitTargetUUID = targetID; 1891 Vector3 offsetr; // = offset * partIRot;
1892 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1893 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1894 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1895 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1896 offsetr = offset * partIRot;
1897//
1898 // else
1899 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1900 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1901 // (offset * partRot);
1902 // }
1903
1904//Console.WriteLine(" ");
1905//Console.WriteLine("link number ={0}", part.LinkNum);
1906//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1907//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1908//Console.WriteLine("Click offst ={0}", offset);
1909//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1910//Console.WriteLine("offsetr ={0}", offsetr);
1911//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1912//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1913
1914 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1915 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1783 // This calls HandleAgentSit twice, once from here, and the client calls 1916 // This calls HandleAgentSit twice, once from here, and the client calls
1784 // HandleAgentSit itself after it gets to the location 1917 // HandleAgentSit itself after it gets to the location
1785 // It doesn't get to the location until we've moved them there though 1918 // It doesn't get to the location until we've moved them there though
1786 // which happens in HandleAgentSit :P 1919 // which happens in HandleAgentSit :P
1787 m_autopilotMoving = autopilot; 1920 m_autopilotMoving = autopilot;
1788 m_autoPilotTarget = pos; 1921 m_autoPilotTarget = autopilotTarget;
1789 m_sitAtAutoTarget = autopilot; 1922 m_sitAtAutoTarget = autopilot;
1923 m_initialSitTarget = autopilotTarget;
1790 if (!autopilot) 1924 if (!autopilot)
1791 HandleAgentSit(remoteClient, UUID); 1925 HandleAgentSit(remoteClient, UUID);
1792 } 1926 }
@@ -2081,31 +2215,65 @@ namespace OpenSim.Region.Framework.Scenes
2081 { 2215 {
2082 if (part != null) 2216 if (part != null)
2083 { 2217 {
2218//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2084 if (part.GetAvatarOnSitTarget() == UUID) 2219 if (part.GetAvatarOnSitTarget() == UUID)
2085 { 2220 {
2221//Console.WriteLine("Scripted Sit");
2222 // Scripted sit
2086 Vector3 sitTargetPos = part.SitTargetPosition; 2223 Vector3 sitTargetPos = part.SitTargetPosition;
2087 Quaternion sitTargetOrient = part.SitTargetOrientation; 2224 Quaternion sitTargetOrient = part.SitTargetOrientation;
2088
2089 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2090 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2091
2092 //Quaternion result = (sitTargetOrient * vq) * nq;
2093
2094 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2225 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2095 m_pos += SIT_TARGET_ADJUSTMENT; 2226 m_pos += SIT_TARGET_ADJUSTMENT;
2096 m_bodyRot = sitTargetOrient; 2227 m_bodyRot = sitTargetOrient;
2097 //Rotation = sitTargetOrient;
2098 m_parentPosition = part.AbsolutePosition; 2228 m_parentPosition = part.AbsolutePosition;
2099 2229 part.IsOccupied = true;
2100 //SendTerseUpdateToAllClients();
2101 } 2230 }
2102 else 2231 else
2103 { 2232 {
2104 m_pos -= part.AbsolutePosition; 2233 // if m_avUnscriptedSitPos is zero then Av sits above center
2234 // Else Av sits at m_avUnscriptedSitPos
2235
2236 // Non-scripted sit by Kitto Flora 21Nov09
2237 // Calculate angle of line from prim to Av
2238 Quaternion partIRot;
2239// if (part.LinkNum == 1)
2240// { // Root prim of linkset
2241// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2242// }
2243// else
2244// { // single or child prim
2245 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2246// }
2247 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2248 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2249 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2250 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2251 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2252 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2253 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2254 // Av sits at world euler <0,0, z>, translated by part rotation
2255 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2256
2105 m_parentPosition = part.AbsolutePosition; 2257 m_parentPosition = part.AbsolutePosition;
2106 } 2258 part.IsOccupied = true;
2107 } 2259 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2108 else 2260 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2261 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2262 m_avUnscriptedSitPos; // adds click offset, if any
2263 //Set up raytrace to find top surface of prim
2264 Vector3 size = part.Scale;
2265 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2266 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2267 Vector3 down = new Vector3(0f, 0f, -1f);
2268//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2269 m_scene.PhysicsScene.RaycastWorld(
2270 start, // Vector3 position,
2271 down, // Vector3 direction,
2272 mag, // float length,
2273 SitAltitudeCallback); // retMethod
2274 } // end scripted/not
2275 }
2276 else // no Av
2109 { 2277 {
2110 return; 2278 return;
2111 } 2279 }
@@ -2117,11 +2285,36 @@ namespace OpenSim.Region.Framework.Scenes
2117 2285
2118 Animator.TrySetMovementAnimation(sitAnimation); 2286 Animator.TrySetMovementAnimation(sitAnimation);
2119 SendFullUpdateToAllClients(); 2287 SendFullUpdateToAllClients();
2120 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2121 // So we're also sending a terse update (which has avatar rotation)
2122 // [Update] We do now.
2123 //SendTerseUpdateToAllClients();
2124 } 2288 }
2289
2290 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2291 {
2292 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2293 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2294 if(hitYN)
2295 {
2296 // m_pos = Av offset from prim center to make look like on center
2297 // m_parentPosition = Actual center pos of prim
2298 // collisionPoint = spot on prim where we want to sit
2299 // collisionPoint.Z = global sit surface height
2300 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2301 Quaternion partIRot;
2302// if (part.LinkNum == 1)
2303/// { // Root prim of linkset
2304// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2305// }
2306// else
2307// { // single or child prim
2308 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2309// }
2310 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2311 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2312//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2313 m_pos += offset;
2314// ControllingClient.SendClearFollowCamProperties(part.UUID);
2315
2316 }
2317 } // End SitAltitudeCallback KF.
2125 2318
2126 /// <summary> 2319 /// <summary>
2127 /// Event handler for the 'Always run' setting on the client 2320 /// Event handler for the 'Always run' setting on the client
@@ -2151,7 +2344,7 @@ namespace OpenSim.Region.Framework.Scenes
2151 /// </summary> 2344 /// </summary>
2152 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2345 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2153 /// <param name="rotation">The direction in which this avatar should now face. 2346 /// <param name="rotation">The direction in which this avatar should now face.
2154 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2347 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2155 { 2348 {
2156 if (m_isChildAgent) 2349 if (m_isChildAgent)
2157 { 2350 {
@@ -2225,7 +2418,7 @@ namespace OpenSim.Region.Framework.Scenes
2225 2418
2226 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2419 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2227 m_forceToApply = direc; 2420 m_forceToApply = direc;
2228 2421 m_isNudging = Nudging;
2229 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2422 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2230 } 2423 }
2231 2424
@@ -2240,7 +2433,7 @@ namespace OpenSim.Region.Framework.Scenes
2240 const float POSITION_TOLERANCE = 0.05f; 2433 const float POSITION_TOLERANCE = 0.05f;
2241 //const int TIME_MS_TOLERANCE = 3000; 2434 //const int TIME_MS_TOLERANCE = 3000;
2242 2435
2243 SendPrimUpdates(); 2436
2244 2437
2245 if (m_newCoarseLocations) 2438 if (m_newCoarseLocations)
2246 { 2439 {
@@ -2276,6 +2469,9 @@ namespace OpenSim.Region.Framework.Scenes
2276 CheckForBorderCrossing(); 2469 CheckForBorderCrossing();
2277 CheckForSignificantMovement(); // sends update to the modules. 2470 CheckForSignificantMovement(); // sends update to the modules.
2278 } 2471 }
2472
2473 //Sending prim updates AFTER the avatar terse updates are sent
2474 SendPrimUpdates();
2279 } 2475 }
2280 2476
2281 #endregion 2477 #endregion
@@ -3129,14 +3325,25 @@ namespace OpenSim.Region.Framework.Scenes
3129 { 3325 {
3130 if (m_forceToApply.HasValue) 3326 if (m_forceToApply.HasValue)
3131 { 3327 {
3132 Vector3 force = m_forceToApply.Value;
3133 3328
3329 Vector3 force = m_forceToApply.Value;
3134 m_updateflag = true; 3330 m_updateflag = true;
3135// movementvector = force;
3136 Velocity = force; 3331 Velocity = force;
3137 3332
3138 m_forceToApply = null; 3333 m_forceToApply = null;
3139 } 3334 }
3335 else
3336 {
3337 if (m_isNudging)
3338 {
3339 Vector3 force = Vector3.Zero;
3340
3341 m_updateflag = true;
3342 Velocity = force;
3343 m_isNudging = false;
3344 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3345 }
3346 }
3140 } 3347 }
3141 3348
3142 public override void SetText(string text, Vector3 color, double alpha) 3349 public override void SetText(string text, Vector3 color, double alpha)
@@ -3188,18 +3395,29 @@ namespace OpenSim.Region.Framework.Scenes
3188 { 3395 {
3189 if (e == null) 3396 if (e == null)
3190 return; 3397 return;
3191 3398
3192 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3399 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3193 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3194 // as of this comment the interval is set in AddToPhysicalScene 3400 // as of this comment the interval is set in AddToPhysicalScene
3195 if (Animator!=null) 3401 if (Animator!=null)
3196 Animator.UpdateMovementAnimations(); 3402 {
3403 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3404 { // else its will lock out other animation changes, like ground sit.
3405 Animator.UpdateMovementAnimations();
3406 m_updateCount--;
3407 }
3408 }
3197 3409
3198 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3410 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3199 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3411 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3200 3412
3201 CollisionPlane = Vector4.UnitW; 3413 CollisionPlane = Vector4.UnitW;
3202 3414
3415 if (m_lastColCount != coldata.Count)
3416 {
3417 m_updateCount = UPDATE_COUNT;
3418 m_lastColCount = coldata.Count;
3419 }
3420
3203 if (coldata.Count != 0 && Animator != null) 3421 if (coldata.Count != 0 && Animator != null)
3204 { 3422 {
3205 switch (Animator.CurrentMovementAnimation) 3423 switch (Animator.CurrentMovementAnimation)
@@ -3847,5 +4065,16 @@ namespace OpenSim.Region.Framework.Scenes
3847 m_reprioritization_called = false; 4065 m_reprioritization_called = false;
3848 } 4066 }
3849 } 4067 }
4068
4069 private Vector3 Quat2Euler(Quaternion rot){
4070 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4071 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4072 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4073 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4074 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4075 return(new Vector3(x,y,z));
4076 }
4077
4078
3850 } 4079 }
3851} \ No newline at end of file 4080}