aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs577
1 files changed, 403 insertions, 174 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index cd39cab..f1555f7 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.
@@ -1307,6 +1350,11 @@ namespace OpenSim.Region.Framework.Scenes
1307 update_rotation = true; 1350 update_rotation = true;
1308 } 1351 }
1309 1352
1353 //guilty until proven innocent..
1354 bool Nudging = true;
1355 //Basically, if there is at least one non-nudge control then we don't need
1356 //to worry about stopping the avatar
1357
1310 if (m_parentID == 0) 1358 if (m_parentID == 0)
1311 { 1359 {
1312 bool bAllowUpdateMoveToPosition = false; 1360 bool bAllowUpdateMoveToPosition = false;
@@ -1321,9 +1369,12 @@ namespace OpenSim.Region.Framework.Scenes
1321 else 1369 else
1322 dirVectors = Dir_Vectors; 1370 dirVectors = Dir_Vectors;
1323 1371
1324 // The fact that m_movementflag is a byte needs to be fixed 1372 bool[] isNudge = GetDirectionIsNudge();
1325 // it really should be a uint 1373
1326 uint nudgehack = 250; 1374
1375
1376
1377
1327 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1378 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1328 { 1379 {
1329 if (((uint)flags & (uint)DCF) != 0) 1380 if (((uint)flags & (uint)DCF) != 0)
@@ -1333,40 +1384,28 @@ namespace OpenSim.Region.Framework.Scenes
1333 try 1384 try
1334 { 1385 {
1335 agent_control_v3 += dirVectors[i]; 1386 agent_control_v3 += dirVectors[i];
1336 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1387 if (isNudge[i] == false)
1388 {
1389 Nudging = false;
1390 }
1337 } 1391 }
1338 catch (IndexOutOfRangeException) 1392 catch (IndexOutOfRangeException)
1339 { 1393 {
1340 // Why did I get this? 1394 // Why did I get this?
1341 } 1395 }
1342 1396
1343 if ((m_movementflag & (byte)(uint)DCF) == 0) 1397 if ((m_movementflag & (uint)DCF) == 0)
1344 { 1398 {
1345 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1346 {
1347 m_movementflag |= (byte)nudgehack;
1348 }
1349 m_movementflag += (byte)(uint)DCF; 1399 m_movementflag += (byte)(uint)DCF;
1350 update_movementflag = true; 1400 update_movementflag = true;
1351 } 1401 }
1352 } 1402 }
1353 else 1403 else
1354 { 1404 {
1355 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1405 if ((m_movementflag & (uint)DCF) != 0)
1356 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1357 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1358 ) // This or is for Nudge forward
1359 { 1406 {
1360 m_movementflag -= ((byte)(uint)DCF); 1407 m_movementflag -= (byte)(uint)DCF;
1361
1362 update_movementflag = true; 1408 update_movementflag = true;
1363 /*
1364 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1365 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1366 {
1367 m_log.Debug("Removed Hack flag");
1368 }
1369 */
1370 } 1409 }
1371 else 1410 else
1372 { 1411 {
@@ -1410,6 +1449,9 @@ namespace OpenSim.Region.Framework.Scenes
1410 // Ignore z component of vector 1449 // Ignore z component of vector
1411 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1450 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1412 LocalVectorToTarget2D.Normalize(); 1451 LocalVectorToTarget2D.Normalize();
1452
1453 //We're not nudging
1454 Nudging = false;
1413 agent_control_v3 += LocalVectorToTarget2D; 1455 agent_control_v3 += LocalVectorToTarget2D;
1414 1456
1415 // update avatar movement flags. the avatar coordinate system is as follows: 1457 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1498,13 +1540,13 @@ namespace OpenSim.Region.Framework.Scenes
1498 // m_log.DebugFormat( 1540 // m_log.DebugFormat(
1499 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1541 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1500 1542
1501 AddNewMovement(agent_control_v3, q); 1543 AddNewMovement(agent_control_v3, q, Nudging);
1502 1544
1503 1545
1504 } 1546 }
1505 } 1547 }
1506 1548
1507 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1549 if (update_movementflag)
1508 Animator.UpdateMovementAnimations(); 1550 Animator.UpdateMovementAnimations();
1509 1551
1510 m_scene.EventManager.TriggerOnClientMovement(this); 1552 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1519,7 +1561,6 @@ namespace OpenSim.Region.Framework.Scenes
1519 m_sitAtAutoTarget = false; 1561 m_sitAtAutoTarget = false;
1520 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1562 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1521 //proxy.PCode = (byte)PCode.ParticleSystem; 1563 //proxy.PCode = (byte)PCode.ParticleSystem;
1522
1523 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1564 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1524 proxyObjectGroup.AttachToScene(m_scene); 1565 proxyObjectGroup.AttachToScene(m_scene);
1525 1566
@@ -1561,7 +1602,7 @@ namespace OpenSim.Region.Framework.Scenes
1561 } 1602 }
1562 m_moveToPositionInProgress = true; 1603 m_moveToPositionInProgress = true;
1563 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1604 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1564 } 1605 }
1565 catch (Exception ex) 1606 catch (Exception ex)
1566 { 1607 {
1567 //Why did I get this error? 1608 //Why did I get this error?
@@ -1583,7 +1624,7 @@ namespace OpenSim.Region.Framework.Scenes
1583 Velocity = Vector3.Zero; 1624 Velocity = Vector3.Zero;
1584 SendFullUpdateToAllClients(); 1625 SendFullUpdateToAllClients();
1585 1626
1586 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1627 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1587 } 1628 }
1588 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1629 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1589 m_requestedSitTargetUUID = UUID.Zero; 1630 m_requestedSitTargetUUID = UUID.Zero;
@@ -1616,55 +1657,84 @@ namespace OpenSim.Region.Framework.Scenes
1616 /// </summary> 1657 /// </summary>
1617 public void StandUp() 1658 public void StandUp()
1618 { 1659 {
1619 if (SitGround)
1620 SitGround = false;
1621
1622 if (m_parentID != 0) 1660 if (m_parentID != 0)
1623 { 1661 {
1624 m_log.Debug("StandupCode Executed");
1625 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1662 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1626 if (part != null) 1663 if (part != null)
1627 { 1664 {
1665 part.TaskInventory.LockItemsForRead(true);
1628 TaskInventoryDictionary taskIDict = part.TaskInventory; 1666 TaskInventoryDictionary taskIDict = part.TaskInventory;
1629 if (taskIDict != null) 1667 if (taskIDict != null)
1630 { 1668 {
1631 lock (taskIDict) 1669 foreach (UUID taskID in taskIDict.Keys)
1632 { 1670 {
1633 foreach (UUID taskID in taskIDict.Keys) 1671 UnRegisterControlEventsToScript(LocalId, taskID);
1634 { 1672 taskIDict[taskID].PermsMask &= ~(
1635 UnRegisterControlEventsToScript(LocalId, taskID); 1673 2048 | //PERMISSION_CONTROL_CAMERA
1636 taskIDict[taskID].PermsMask &= ~( 1674 4); // PERMISSION_TAKE_CONTROLS
1637 2048 | //PERMISSION_CONTROL_CAMERA
1638 4); // PERMISSION_TAKE_CONTROLS
1639 }
1640 } 1675 }
1641
1642 } 1676 }
1677 part.TaskInventory.LockItemsForRead(false);
1643 // Reset sit target. 1678 // Reset sit target.
1644 if (part.GetAvatarOnSitTarget() == UUID) 1679 if (part.GetAvatarOnSitTarget() == UUID)
1645 part.SetAvatarOnSitTarget(UUID.Zero); 1680 part.SetAvatarOnSitTarget(UUID.Zero);
1646
1647 m_parentPosition = part.GetWorldPosition(); 1681 m_parentPosition = part.GetWorldPosition();
1648 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1682 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1649 } 1683 }
1650 1684 // part.GetWorldRotation() is the rotation of the object being sat on
1651 if (m_physicsActor == null) 1685 // Rotation is the sittiing Av's rotation
1652 { 1686
1653 AddToPhysicalScene(false); 1687 Quaternion partRot;
1688// if (part.LinkNum == 1)
1689// { // Root prim of linkset
1690// partRot = part.ParentGroup.RootPart.RotationOffset;
1691// }
1692// else
1693// { // single or child prim
1694
1695// }
1696 if (part == null) //CW: Part may be gone. llDie() for example.
1697 {
1698 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1699 }
1700 else
1701 {
1702 partRot = part.GetWorldRotation();
1703 }
1704
1705 Quaternion partIRot = Quaternion.Inverse(partRot);
1706
1707 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1708 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1709
1710
1711 if (m_physicsActor == null)
1712 {
1713 AddToPhysicalScene(false);
1714 }
1715 //CW: If the part isn't null then we can set the current position
1716 if (part != null)
1717 {
1718 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1719 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1720 part.IsOccupied = false;
1721 }
1722 else
1723 {
1724 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1725 AbsolutePosition = m_lastWorldPosition;
1654 } 1726 }
1655 1727
1656 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1728 m_parentPosition = Vector3.Zero;
1657 m_parentPosition = Vector3.Zero; 1729 m_parentID = 0;
1658
1659 m_parentID = 0;
1660 SendFullUpdateToAllClients(); 1730 SendFullUpdateToAllClients();
1661 m_requestedSitTargetID = 0; 1731 m_requestedSitTargetID = 0;
1732
1662 if ((m_physicsActor != null) && (m_avHeight > 0)) 1733 if ((m_physicsActor != null) && (m_avHeight > 0))
1663 { 1734 {
1664 SetHeight(m_avHeight); 1735 SetHeight(m_avHeight);
1665 } 1736 }
1666 } 1737 }
1667
1668 Animator.TrySetMovementAnimation("STAND"); 1738 Animator.TrySetMovementAnimation("STAND");
1669 } 1739 }
1670 1740
@@ -1695,13 +1765,9 @@ namespace OpenSim.Region.Framework.Scenes
1695 Vector3 avSitOffSet = part.SitTargetPosition; 1765 Vector3 avSitOffSet = part.SitTargetPosition;
1696 Quaternion avSitOrientation = part.SitTargetOrientation; 1766 Quaternion avSitOrientation = part.SitTargetOrientation;
1697 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1767 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1698 1768 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1699 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1769 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1700 bool SitTargetisSet = 1770 if (SitTargetisSet && !SitTargetOccupied)
1701 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1702 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1703
1704 if (SitTargetisSet && SitTargetUnOccupied)
1705 { 1771 {
1706 //switch the target to this prim 1772 //switch the target to this prim
1707 return part; 1773 return part;
@@ -1715,84 +1781,152 @@ namespace OpenSim.Region.Framework.Scenes
1715 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1781 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1716 { 1782 {
1717 bool autopilot = true; 1783 bool autopilot = true;
1784 Vector3 autopilotTarget = new Vector3();
1785 Quaternion sitOrientation = Quaternion.Identity;
1718 Vector3 pos = new Vector3(); 1786 Vector3 pos = new Vector3();
1719 Quaternion sitOrientation = pSitOrientation;
1720 Vector3 cameraEyeOffset = Vector3.Zero; 1787 Vector3 cameraEyeOffset = Vector3.Zero;
1721 Vector3 cameraAtOffset = Vector3.Zero; 1788 Vector3 cameraAtOffset = Vector3.Zero;
1722 bool forceMouselook = false; 1789 bool forceMouselook = false;
1723 1790
1724 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1791 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1725 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1792 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1726 if (part != null) 1793 if (part == null) return;
1727 { 1794
1728 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1795 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1729 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1796 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1730 1797
1731 // Is a sit target available? 1798 // part is the prim to sit on
1732 Vector3 avSitOffSet = part.SitTargetPosition; 1799 // offset is the world-ref vector distance from that prim center to the click-spot
1733 Quaternion avSitOrientation = part.SitTargetOrientation; 1800 // UUID is the UUID of the Avatar doing the clicking
1734 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1801
1735 1802 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1736 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1803
1737 bool SitTargetisSet = 1804 // Is a sit target available?
1738 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1805 Vector3 avSitOffSet = part.SitTargetPosition;
1739 ( 1806 Quaternion avSitOrientation = part.SitTargetOrientation;
1740 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1807
1741 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1808 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1742 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1809 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1743 ) 1810 Quaternion partRot;
1744 )); 1811// if (part.LinkNum == 1)
1745 1812// { // Root prim of linkset
1746 if (SitTargetisSet && SitTargetUnOccupied) 1813// partRot = part.ParentGroup.RootPart.RotationOffset;
1747 { 1814// }
1748 part.SetAvatarOnSitTarget(UUID); 1815// else
1749 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1816// { // single or child prim
1750 sitOrientation = avSitOrientation; 1817 partRot = part.GetWorldRotation();
1751 autopilot = false; 1818// }
1752 } 1819 Quaternion partIRot = Quaternion.Inverse(partRot);
1753 1820//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1754 pos = part.AbsolutePosition + offset; 1821 // Sit analysis rewritten by KF 091125
1755 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1822 if (SitTargetisSet) // scipted sit
1756 //{ 1823 {
1757 // offset = pos; 1824 if (!part.IsOccupied)
1758 //autopilot = false; 1825 {
1759 //} 1826//Console.WriteLine("Scripted, unoccupied");
1760 if (m_physicsActor != null) 1827 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1761 { 1828 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1762 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1829 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1763 // We can remove the physicsActor until they stand up. 1830 autopilot = false; // Jump direct to scripted llSitPos()
1764 m_sitAvatarHeight = m_physicsActor.Size.Z; 1831 }
1765 1832 else
1766 if (autopilot) 1833 {
1767 { 1834//Console.WriteLine("Scripted, occupied");
1768 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1835 return;
1769 { 1836 }
1770 autopilot = false; 1837 }
1838 else // Not Scripted
1839 {
1840 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1841 {
1842 // large prim & offset, ignore if other Avs sitting
1843// offset.Z -= 0.05f;
1844 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1845 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1846
1847//Console.WriteLine(" offset ={0}", offset);
1848//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1849//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1850
1851 }
1852 else // small offset
1853 {
1854//Console.WriteLine("Small offset");
1855 if (!part.IsOccupied)
1856 {
1857 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1858 autopilotTarget = part.AbsolutePosition;
1859 }
1860 else return; // occupied small
1861 } // end large/small
1862 } // end Scripted/not
1863 cameraAtOffset = part.GetCameraAtOffset();
1864 cameraEyeOffset = part.GetCameraEyeOffset();
1865 forceMouselook = part.GetForceMouselook();
1866 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1867 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1771 1868
1772 RemoveFromPhysicalScene(); 1869 if (m_physicsActor != null)
1773 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1870 {
1774 } 1871 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1775 } 1872 // We can remove the physicsActor until they stand up.
1776 else 1873 m_sitAvatarHeight = m_physicsActor.Size.Z;
1874 if (autopilot)
1875 { // its not a scripted sit
1876// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1877 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1777 { 1878 {
1879 autopilot = false; // close enough
1880 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1881 Not using the part's position because returning the AV to the last known standing
1882 position is likely to be more friendly, isn't it? */
1778 RemoveFromPhysicalScene(); 1883 RemoveFromPhysicalScene();
1779 } 1884 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1885 } // else the autopilot will get us close
1886 }
1887 else
1888 { // its a scripted sit
1889 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1890 I *am* using the part's position this time because we have no real idea how far away
1891 the avatar is from the sit target. */
1892 RemoveFromPhysicalScene();
1780 } 1893 }
1781
1782 cameraAtOffset = part.GetCameraAtOffset();
1783 cameraEyeOffset = part.GetCameraEyeOffset();
1784 forceMouselook = part.GetForceMouselook();
1785 } 1894 }
1786 1895 else return; // physactor is null!
1787 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1896
1788 m_requestedSitTargetUUID = targetID; 1897 Vector3 offsetr; // = offset * partIRot;
1898 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1899 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1900 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1901 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1902 offsetr = offset * partIRot;
1903//
1904 // else
1905 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1906 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1907 // (offset * partRot);
1908 // }
1909
1910//Console.WriteLine(" ");
1911//Console.WriteLine("link number ={0}", part.LinkNum);
1912//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1913//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1914//Console.WriteLine("Click offst ={0}", offset);
1915//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1916//Console.WriteLine("offsetr ={0}", offsetr);
1917//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1918//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1919
1920 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1921 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1789 // This calls HandleAgentSit twice, once from here, and the client calls 1922 // This calls HandleAgentSit twice, once from here, and the client calls
1790 // HandleAgentSit itself after it gets to the location 1923 // HandleAgentSit itself after it gets to the location
1791 // It doesn't get to the location until we've moved them there though 1924 // It doesn't get to the location until we've moved them there though
1792 // which happens in HandleAgentSit :P 1925 // which happens in HandleAgentSit :P
1793 m_autopilotMoving = autopilot; 1926 m_autopilotMoving = autopilot;
1794 m_autoPilotTarget = pos; 1927 m_autoPilotTarget = autopilotTarget;
1795 m_sitAtAutoTarget = autopilot; 1928 m_sitAtAutoTarget = autopilot;
1929 m_initialSitTarget = autopilotTarget;
1796 if (!autopilot) 1930 if (!autopilot)
1797 HandleAgentSit(remoteClient, UUID); 1931 HandleAgentSit(remoteClient, UUID);
1798 } 1932 }
@@ -2087,31 +2221,65 @@ namespace OpenSim.Region.Framework.Scenes
2087 { 2221 {
2088 if (part != null) 2222 if (part != null)
2089 { 2223 {
2224//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2090 if (part.GetAvatarOnSitTarget() == UUID) 2225 if (part.GetAvatarOnSitTarget() == UUID)
2091 { 2226 {
2227//Console.WriteLine("Scripted Sit");
2228 // Scripted sit
2092 Vector3 sitTargetPos = part.SitTargetPosition; 2229 Vector3 sitTargetPos = part.SitTargetPosition;
2093 Quaternion sitTargetOrient = part.SitTargetOrientation; 2230 Quaternion sitTargetOrient = part.SitTargetOrientation;
2094
2095 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2096 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2097
2098 //Quaternion result = (sitTargetOrient * vq) * nq;
2099
2100 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2231 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2101 m_pos += SIT_TARGET_ADJUSTMENT; 2232 m_pos += SIT_TARGET_ADJUSTMENT;
2102 m_bodyRot = sitTargetOrient; 2233 m_bodyRot = sitTargetOrient;
2103 //Rotation = sitTargetOrient;
2104 m_parentPosition = part.AbsolutePosition; 2234 m_parentPosition = part.AbsolutePosition;
2105 2235 part.IsOccupied = true;
2106 //SendTerseUpdateToAllClients();
2107 } 2236 }
2108 else 2237 else
2109 { 2238 {
2110 m_pos -= part.AbsolutePosition; 2239 // if m_avUnscriptedSitPos is zero then Av sits above center
2240 // Else Av sits at m_avUnscriptedSitPos
2241
2242 // Non-scripted sit by Kitto Flora 21Nov09
2243 // Calculate angle of line from prim to Av
2244 Quaternion partIRot;
2245// if (part.LinkNum == 1)
2246// { // Root prim of linkset
2247// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2248// }
2249// else
2250// { // single or child prim
2251 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2252// }
2253 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2254 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2255 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2256 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2257 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2258 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2259 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2260 // Av sits at world euler <0,0, z>, translated by part rotation
2261 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2262
2111 m_parentPosition = part.AbsolutePosition; 2263 m_parentPosition = part.AbsolutePosition;
2112 } 2264 part.IsOccupied = true;
2113 } 2265 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2114 else 2266 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2267 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2268 m_avUnscriptedSitPos; // adds click offset, if any
2269 //Set up raytrace to find top surface of prim
2270 Vector3 size = part.Scale;
2271 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2272 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2273 Vector3 down = new Vector3(0f, 0f, -1f);
2274//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2275 m_scene.PhysicsScene.RaycastWorld(
2276 start, // Vector3 position,
2277 down, // Vector3 direction,
2278 mag, // float length,
2279 SitAltitudeCallback); // retMethod
2280 } // end scripted/not
2281 }
2282 else // no Av
2115 { 2283 {
2116 return; 2284 return;
2117 } 2285 }
@@ -2123,11 +2291,36 @@ namespace OpenSim.Region.Framework.Scenes
2123 2291
2124 Animator.TrySetMovementAnimation(sitAnimation); 2292 Animator.TrySetMovementAnimation(sitAnimation);
2125 SendFullUpdateToAllClients(); 2293 SendFullUpdateToAllClients();
2126 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2127 // So we're also sending a terse update (which has avatar rotation)
2128 // [Update] We do now.
2129 //SendTerseUpdateToAllClients();
2130 } 2294 }
2295
2296 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2297 {
2298 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2299 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2300 if(hitYN)
2301 {
2302 // m_pos = Av offset from prim center to make look like on center
2303 // m_parentPosition = Actual center pos of prim
2304 // collisionPoint = spot on prim where we want to sit
2305 // collisionPoint.Z = global sit surface height
2306 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2307 Quaternion partIRot;
2308// if (part.LinkNum == 1)
2309/// { // Root prim of linkset
2310// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2311// }
2312// else
2313// { // single or child prim
2314 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2315// }
2316 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2317 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2318//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2319 m_pos += offset;
2320// ControllingClient.SendClearFollowCamProperties(part.UUID);
2321
2322 }
2323 } // End SitAltitudeCallback KF.
2131 2324
2132 /// <summary> 2325 /// <summary>
2133 /// Event handler for the 'Always run' setting on the client 2326 /// Event handler for the 'Always run' setting on the client
@@ -2157,7 +2350,7 @@ namespace OpenSim.Region.Framework.Scenes
2157 /// </summary> 2350 /// </summary>
2158 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2351 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2159 /// <param name="rotation">The direction in which this avatar should now face. 2352 /// <param name="rotation">The direction in which this avatar should now face.
2160 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2353 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2161 { 2354 {
2162 if (m_isChildAgent) 2355 if (m_isChildAgent)
2163 { 2356 {
@@ -2231,7 +2424,7 @@ namespace OpenSim.Region.Framework.Scenes
2231 2424
2232 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2425 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2233 m_forceToApply = direc; 2426 m_forceToApply = direc;
2234 2427 m_isNudging = Nudging;
2235 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2428 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2236 } 2429 }
2237 2430
@@ -2246,7 +2439,7 @@ namespace OpenSim.Region.Framework.Scenes
2246 const float POSITION_TOLERANCE = 0.05f; 2439 const float POSITION_TOLERANCE = 0.05f;
2247 //const int TIME_MS_TOLERANCE = 3000; 2440 //const int TIME_MS_TOLERANCE = 3000;
2248 2441
2249 SendPrimUpdates(); 2442
2250 2443
2251 if (m_newCoarseLocations) 2444 if (m_newCoarseLocations)
2252 { 2445 {
@@ -2282,6 +2475,9 @@ namespace OpenSim.Region.Framework.Scenes
2282 CheckForBorderCrossing(); 2475 CheckForBorderCrossing();
2283 CheckForSignificantMovement(); // sends update to the modules. 2476 CheckForSignificantMovement(); // sends update to the modules.
2284 } 2477 }
2478
2479 //Sending prim updates AFTER the avatar terse updates are sent
2480 SendPrimUpdates();
2285 } 2481 }
2286 2482
2287 #endregion 2483 #endregion
@@ -3141,14 +3337,25 @@ namespace OpenSim.Region.Framework.Scenes
3141 { 3337 {
3142 if (m_forceToApply.HasValue) 3338 if (m_forceToApply.HasValue)
3143 { 3339 {
3144 Vector3 force = m_forceToApply.Value;
3145 3340
3341 Vector3 force = m_forceToApply.Value;
3146 m_updateflag = true; 3342 m_updateflag = true;
3147// movementvector = force;
3148 Velocity = force; 3343 Velocity = force;
3149 3344
3150 m_forceToApply = null; 3345 m_forceToApply = null;
3151 } 3346 }
3347 else
3348 {
3349 if (m_isNudging)
3350 {
3351 Vector3 force = Vector3.Zero;
3352
3353 m_updateflag = true;
3354 Velocity = force;
3355 m_isNudging = false;
3356 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3357 }
3358 }
3152 } 3359 }
3153 3360
3154 public override void SetText(string text, Vector3 color, double alpha) 3361 public override void SetText(string text, Vector3 color, double alpha)
@@ -3200,18 +3407,29 @@ namespace OpenSim.Region.Framework.Scenes
3200 { 3407 {
3201 if (e == null) 3408 if (e == null)
3202 return; 3409 return;
3203 3410
3204 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3411 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3205 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3206 // as of this comment the interval is set in AddToPhysicalScene 3412 // as of this comment the interval is set in AddToPhysicalScene
3207 if (Animator!=null) 3413 if (Animator!=null)
3208 Animator.UpdateMovementAnimations(); 3414 {
3415 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3416 { // else its will lock out other animation changes, like ground sit.
3417 Animator.UpdateMovementAnimations();
3418 m_updateCount--;
3419 }
3420 }
3209 3421
3210 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3422 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3211 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3423 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3212 3424
3213 CollisionPlane = Vector4.UnitW; 3425 CollisionPlane = Vector4.UnitW;
3214 3426
3427 if (m_lastColCount != coldata.Count)
3428 {
3429 m_updateCount = UPDATE_COUNT;
3430 m_lastColCount = coldata.Count;
3431 }
3432
3215 if (coldata.Count != 0 && Animator != null) 3433 if (coldata.Count != 0 && Animator != null)
3216 { 3434 {
3217 switch (Animator.CurrentMovementAnimation) 3435 switch (Animator.CurrentMovementAnimation)
@@ -3855,5 +4073,16 @@ namespace OpenSim.Region.Framework.Scenes
3855 m_reprioritization_called = false; 4073 m_reprioritization_called = false;
3856 } 4074 }
3857 } 4075 }
4076
4077 private Vector3 Quat2Euler(Quaternion rot){
4078 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4079 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4080 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4081 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4082 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4083 return(new Vector3(x,y,z));
4084 }
4085
4086
3858 } 4087 }
3859} 4088}