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.cs593
1 files changed, 417 insertions, 176 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 8a633b5..a187844 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -123,8 +125,11 @@ namespace OpenSim.Region.Framework.Scenes
123 public Vector3 lastKnownAllowedPosition; 125 public Vector3 lastKnownAllowedPosition;
124 public bool sentMessageAboutRestrictedParcelFlyingDown; 126 public bool sentMessageAboutRestrictedParcelFlyingDown;
125 public Vector4 CollisionPlane = Vector4.UnitW; 127 public Vector4 CollisionPlane = Vector4.UnitW;
126 128
129 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
130 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
127 private Vector3 m_lastPosition; 131 private Vector3 m_lastPosition;
132 private Vector3 m_lastWorldPosition;
128 private Quaternion m_lastRotation; 133 private Quaternion m_lastRotation;
129 private Vector3 m_lastVelocity; 134 private Vector3 m_lastVelocity;
130 //private int m_lastTerseSent; 135 //private int m_lastTerseSent;
@@ -134,7 +139,6 @@ namespace OpenSim.Region.Framework.Scenes
134 private Vector3? m_forceToApply; 139 private Vector3? m_forceToApply;
135 private uint m_requestedSitTargetID; 140 private uint m_requestedSitTargetID;
136 private UUID m_requestedSitTargetUUID; 141 private UUID m_requestedSitTargetUUID;
137 public bool SitGround = false;
138 142
139 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 143 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
140 144
@@ -156,7 +160,6 @@ namespace OpenSim.Region.Framework.Scenes
156 private int m_perfMonMS; 160 private int m_perfMonMS;
157 161
158 private bool m_setAlwaysRun; 162 private bool m_setAlwaysRun;
159
160 private bool m_forceFly; 163 private bool m_forceFly;
161 private bool m_flyDisabled; 164 private bool m_flyDisabled;
162 165
@@ -182,7 +185,8 @@ namespace OpenSim.Region.Framework.Scenes
182 protected RegionInfo m_regionInfo; 185 protected RegionInfo m_regionInfo;
183 protected ulong crossingFromRegion; 186 protected ulong crossingFromRegion;
184 187
185 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 188 private readonly Vector3[] Dir_Vectors = new Vector3[11];
189 private bool m_isNudging = false;
186 190
187 // Position of agent's camera in world (region cordinates) 191 // Position of agent's camera in world (region cordinates)
188 protected Vector3 m_CameraCenter; 192 protected Vector3 m_CameraCenter;
@@ -207,6 +211,7 @@ namespace OpenSim.Region.Framework.Scenes
207 private bool m_autopilotMoving; 211 private bool m_autopilotMoving;
208 private Vector3 m_autoPilotTarget; 212 private Vector3 m_autoPilotTarget;
209 private bool m_sitAtAutoTarget; 213 private bool m_sitAtAutoTarget;
214 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
210 215
211 private string m_nextSitAnimation = String.Empty; 216 private string m_nextSitAnimation = String.Empty;
212 217
@@ -217,6 +222,9 @@ namespace OpenSim.Region.Framework.Scenes
217 private bool m_followCamAuto; 222 private bool m_followCamAuto;
218 223
219 private int m_movementUpdateCount; 224 private int m_movementUpdateCount;
225 private int m_lastColCount = -1; //KF: Look for Collision chnages
226 private int m_updateCount = 0; //KF: Update Anims for a while
227 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
220 228
221 private const int NumMovementsBetweenRayCast = 5; 229 private const int NumMovementsBetweenRayCast = 5;
222 230
@@ -245,7 +253,9 @@ namespace OpenSim.Region.Framework.Scenes
245 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 253 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
246 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 254 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
247 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 255 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
248 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 256 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
257 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
258 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 259 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
250 } 260 }
251 261
@@ -445,8 +455,9 @@ namespace OpenSim.Region.Framework.Scenes
445 get 455 get
446 { 456 {
447 PhysicsActor actor = m_physicsActor; 457 PhysicsActor actor = m_physicsActor;
448 if (actor != null) 458// if (actor != null)
449 m_pos = actor.Position; 459 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
460 m_pos = actor.Position;
450 461
451 return m_parentPosition + m_pos; 462 return m_parentPosition + m_pos;
452 } 463 }
@@ -466,7 +477,8 @@ namespace OpenSim.Region.Framework.Scenes
466 } 477 }
467 } 478 }
468 479
469 m_pos = value; 480 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
481 m_pos = value;
470 m_parentPosition = Vector3.Zero; 482 m_parentPosition = Vector3.Zero;
471 } 483 }
472 } 484 }
@@ -653,7 +665,7 @@ namespace OpenSim.Region.Framework.Scenes
653 CreateSceneViewer(); 665 CreateSceneViewer();
654 m_animator = new ScenePresenceAnimator(this); 666 m_animator = new ScenePresenceAnimator(this);
655 } 667 }
656 668
657 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 669 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
658 { 670 {
659 m_rootRegionHandle = reginfo.RegionHandle; 671 m_rootRegionHandle = reginfo.RegionHandle;
@@ -680,10 +692,7 @@ namespace OpenSim.Region.Framework.Scenes
680 m_reprioritization_timer.AutoReset = false; 692 m_reprioritization_timer.AutoReset = false;
681 693
682 AdjustKnownSeeds(); 694 AdjustKnownSeeds();
683
684 // TODO: I think, this won't send anything, as we are still a child here...
685 Animator.TrySetMovementAnimation("STAND"); 695 Animator.TrySetMovementAnimation("STAND");
686
687 // we created a new ScenePresence (a new child agent) in a fresh region. 696 // we created a new ScenePresence (a new child agent) in a fresh region.
688 // Request info about all the (root) agents in this region 697 // Request info about all the (root) agents in this region
689 // Note: This won't send data *to* other clients in that region (children don't send) 698 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -739,25 +748,47 @@ namespace OpenSim.Region.Framework.Scenes
739 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 748 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
740 Dir_Vectors[4] = Vector3.UnitZ; //UP 749 Dir_Vectors[4] = Vector3.UnitZ; //UP
741 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 750 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
742 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 751 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
743 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 752 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
744 Dir_Vectors[7] = -Vector3.UnitX; //BACK 753 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
754 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
755 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
745 } 756 }
746 757
747 private Vector3[] GetWalkDirectionVectors() 758 private Vector3[] GetWalkDirectionVectors()
748 { 759 {
749 Vector3[] vector = new Vector3[9]; 760 Vector3[] vector = new Vector3[11];
750 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 761 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
751 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 762 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
752 vector[2] = Vector3.UnitY; //LEFT 763 vector[2] = Vector3.UnitY; //LEFT
753 vector[3] = -Vector3.UnitY; //RIGHT 764 vector[3] = -Vector3.UnitY; //RIGHT
754 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 765 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
755 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 766 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
756 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 767 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
757 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 768 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
758 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 769 vector[8] = Vector3.UnitY; //LEFT_NUDGE
770 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
771 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
759 return vector; 772 return vector;
760 } 773 }
774
775 private bool[] GetDirectionIsNudge()
776 {
777 bool[] isNudge = new bool[11];
778 isNudge[0] = false; //FORWARD
779 isNudge[1] = false; //BACK
780 isNudge[2] = false; //LEFT
781 isNudge[3] = false; //RIGHT
782 isNudge[4] = false; //UP
783 isNudge[5] = false; //DOWN
784 isNudge[6] = true; //FORWARD_NUDGE
785 isNudge[7] = true; //BACK_NUDGE
786 isNudge[8] = true; //LEFT_NUDGE
787 isNudge[9] = true; //RIGHT_NUDGE
788 isNudge[10] = true; //DOWN_Nudge
789 return isNudge;
790 }
791
761 792
762 #endregion 793 #endregion
763 794
@@ -828,6 +859,21 @@ namespace OpenSim.Region.Framework.Scenes
828 pos.Y = crossedBorder.BorderLine.Z - 1; 859 pos.Y = crossedBorder.BorderLine.Z - 1;
829 } 860 }
830 861
862 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
863 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
864 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
865 if (KnownChildRegionHandles.Count == 0)
866 {
867 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
868 if (land != null)
869 {
870 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
871 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godlevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
872 {
873 pos = land.LandData.UserLocation;
874 }
875 }
876 }
831 877
832 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 878 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
833 { 879 {
@@ -988,9 +1034,10 @@ namespace OpenSim.Region.Framework.Scenes
988 public void Teleport(Vector3 pos) 1034 public void Teleport(Vector3 pos)
989 { 1035 {
990 bool isFlying = false; 1036 bool isFlying = false;
1037
991 if (m_physicsActor != null) 1038 if (m_physicsActor != null)
992 isFlying = m_physicsActor.Flying; 1039 isFlying = m_physicsActor.Flying;
993 1040
994 RemoveFromPhysicalScene(); 1041 RemoveFromPhysicalScene();
995 Velocity = Vector3.Zero; 1042 Velocity = Vector3.Zero;
996 AbsolutePosition = pos; 1043 AbsolutePosition = pos;
@@ -1002,6 +1049,7 @@ namespace OpenSim.Region.Framework.Scenes
1002 } 1049 }
1003 1050
1004 SendTerseUpdateToAllClients(); 1051 SendTerseUpdateToAllClients();
1052
1005 } 1053 }
1006 1054
1007 public void TeleportWithMomentum(Vector3 pos) 1055 public void TeleportWithMomentum(Vector3 pos)
@@ -1046,7 +1094,9 @@ namespace OpenSim.Region.Framework.Scenes
1046 { 1094 {
1047 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1095 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1048 } 1096 }
1049 1097
1098 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1099
1050 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1100 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1051 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1101 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1052 } 1102 }
@@ -1280,7 +1330,6 @@ namespace OpenSim.Region.Framework.Scenes
1280 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1330 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1281 } 1331 }
1282 } 1332 }
1283
1284 lock (scriptedcontrols) 1333 lock (scriptedcontrols)
1285 { 1334 {
1286 if (scriptedcontrols.Count > 0) 1335 if (scriptedcontrols.Count > 0)
@@ -1295,12 +1344,8 @@ namespace OpenSim.Region.Framework.Scenes
1295 1344
1296 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1345 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1297 { 1346 {
1298 // TODO: This doesn't prevent the user from walking yet. 1347 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1299 // Setting parent ID would fix this, if we knew what value 1348 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1300 // to use. Or we could add a m_isSitting variable.
1301 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1302 SitGround = true;
1303
1304 } 1349 }
1305 1350
1306 // In the future, these values might need to go global. 1351 // In the future, these values might need to go global.
@@ -1350,6 +1395,11 @@ namespace OpenSim.Region.Framework.Scenes
1350 update_rotation = true; 1395 update_rotation = true;
1351 } 1396 }
1352 1397
1398 //guilty until proven innocent..
1399 bool Nudging = true;
1400 //Basically, if there is at least one non-nudge control then we don't need
1401 //to worry about stopping the avatar
1402
1353 if (m_parentID == 0) 1403 if (m_parentID == 0)
1354 { 1404 {
1355 bool bAllowUpdateMoveToPosition = false; 1405 bool bAllowUpdateMoveToPosition = false;
@@ -1364,9 +1414,12 @@ namespace OpenSim.Region.Framework.Scenes
1364 else 1414 else
1365 dirVectors = Dir_Vectors; 1415 dirVectors = Dir_Vectors;
1366 1416
1367 // The fact that m_movementflag is a byte needs to be fixed 1417 bool[] isNudge = GetDirectionIsNudge();
1368 // it really should be a uint 1418
1369 uint nudgehack = 250; 1419
1420
1421
1422
1370 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1423 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1371 { 1424 {
1372 if (((uint)flags & (uint)DCF) != 0) 1425 if (((uint)flags & (uint)DCF) != 0)
@@ -1376,40 +1429,28 @@ namespace OpenSim.Region.Framework.Scenes
1376 try 1429 try
1377 { 1430 {
1378 agent_control_v3 += dirVectors[i]; 1431 agent_control_v3 += dirVectors[i];
1379 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1432 if (isNudge[i] == false)
1433 {
1434 Nudging = false;
1435 }
1380 } 1436 }
1381 catch (IndexOutOfRangeException) 1437 catch (IndexOutOfRangeException)
1382 { 1438 {
1383 // Why did I get this? 1439 // Why did I get this?
1384 } 1440 }
1385 1441
1386 if ((m_movementflag & (byte)(uint)DCF) == 0) 1442 if ((m_movementflag & (uint)DCF) == 0)
1387 { 1443 {
1388 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1389 {
1390 m_movementflag |= (byte)nudgehack;
1391 }
1392 m_movementflag += (byte)(uint)DCF; 1444 m_movementflag += (byte)(uint)DCF;
1393 update_movementflag = true; 1445 update_movementflag = true;
1394 } 1446 }
1395 } 1447 }
1396 else 1448 else
1397 { 1449 {
1398 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1450 if ((m_movementflag & (uint)DCF) != 0)
1399 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1400 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1401 ) // This or is for Nudge forward
1402 { 1451 {
1403 m_movementflag -= ((byte)(uint)DCF); 1452 m_movementflag -= (byte)(uint)DCF;
1404
1405 update_movementflag = true; 1453 update_movementflag = true;
1406 /*
1407 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1408 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1409 {
1410 m_log.Debug("Removed Hack flag");
1411 }
1412 */
1413 } 1454 }
1414 else 1455 else
1415 { 1456 {
@@ -1418,7 +1459,6 @@ namespace OpenSim.Region.Framework.Scenes
1418 } 1459 }
1419 i++; 1460 i++;
1420 } 1461 }
1421
1422 //Paupaw:Do Proper PID for Autopilot here 1462 //Paupaw:Do Proper PID for Autopilot here
1423 if (bResetMoveToPosition) 1463 if (bResetMoveToPosition)
1424 { 1464 {
@@ -1453,6 +1493,9 @@ namespace OpenSim.Region.Framework.Scenes
1453 // Ignore z component of vector 1493 // Ignore z component of vector
1454 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1494 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1455 LocalVectorToTarget2D.Normalize(); 1495 LocalVectorToTarget2D.Normalize();
1496
1497 //We're not nudging
1498 Nudging = false;
1456 agent_control_v3 += LocalVectorToTarget2D; 1499 agent_control_v3 += LocalVectorToTarget2D;
1457 1500
1458 // update avatar movement flags. the avatar coordinate system is as follows: 1501 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1541,13 +1584,13 @@ namespace OpenSim.Region.Framework.Scenes
1541 // m_log.DebugFormat( 1584 // m_log.DebugFormat(
1542 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1585 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1543 1586
1544 AddNewMovement(agent_control_v3, q); 1587 AddNewMovement(agent_control_v3, q, Nudging);
1545 1588
1546 1589
1547 } 1590 }
1548 } 1591 }
1549 1592
1550 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1593 if (update_movementflag)
1551 Animator.UpdateMovementAnimations(); 1594 Animator.UpdateMovementAnimations();
1552 1595
1553 m_scene.EventManager.TriggerOnClientMovement(this); 1596 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1562,7 +1605,6 @@ namespace OpenSim.Region.Framework.Scenes
1562 m_sitAtAutoTarget = false; 1605 m_sitAtAutoTarget = false;
1563 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1606 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1564 //proxy.PCode = (byte)PCode.ParticleSystem; 1607 //proxy.PCode = (byte)PCode.ParticleSystem;
1565
1566 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1608 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1567 proxyObjectGroup.AttachToScene(m_scene); 1609 proxyObjectGroup.AttachToScene(m_scene);
1568 1610
@@ -1604,7 +1646,7 @@ namespace OpenSim.Region.Framework.Scenes
1604 } 1646 }
1605 m_moveToPositionInProgress = true; 1647 m_moveToPositionInProgress = true;
1606 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1648 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1607 } 1649 }
1608 catch (Exception ex) 1650 catch (Exception ex)
1609 { 1651 {
1610 //Why did I get this error? 1652 //Why did I get this error?
@@ -1626,7 +1668,7 @@ namespace OpenSim.Region.Framework.Scenes
1626 Velocity = Vector3.Zero; 1668 Velocity = Vector3.Zero;
1627 SendFullUpdateToAllClients(); 1669 SendFullUpdateToAllClients();
1628 1670
1629 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1671 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1630 } 1672 }
1631 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1673 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1632 m_requestedSitTargetUUID = UUID.Zero; 1674 m_requestedSitTargetUUID = UUID.Zero;
@@ -1659,55 +1701,84 @@ namespace OpenSim.Region.Framework.Scenes
1659 /// </summary> 1701 /// </summary>
1660 public void StandUp() 1702 public void StandUp()
1661 { 1703 {
1662 if (SitGround)
1663 SitGround = false;
1664
1665 if (m_parentID != 0) 1704 if (m_parentID != 0)
1666 { 1705 {
1667 m_log.Debug("StandupCode Executed");
1668 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1706 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1669 if (part != null) 1707 if (part != null)
1670 { 1708 {
1709 part.TaskInventory.LockItemsForRead(true);
1671 TaskInventoryDictionary taskIDict = part.TaskInventory; 1710 TaskInventoryDictionary taskIDict = part.TaskInventory;
1672 if (taskIDict != null) 1711 if (taskIDict != null)
1673 { 1712 {
1674 lock (taskIDict) 1713 foreach (UUID taskID in taskIDict.Keys)
1675 { 1714 {
1676 foreach (UUID taskID in taskIDict.Keys) 1715 UnRegisterControlEventsToScript(LocalId, taskID);
1677 { 1716 taskIDict[taskID].PermsMask &= ~(
1678 UnRegisterControlEventsToScript(LocalId, taskID); 1717 2048 | //PERMISSION_CONTROL_CAMERA
1679 taskIDict[taskID].PermsMask &= ~( 1718 4); // PERMISSION_TAKE_CONTROLS
1680 2048 | //PERMISSION_CONTROL_CAMERA
1681 4); // PERMISSION_TAKE_CONTROLS
1682 }
1683 } 1719 }
1684
1685 } 1720 }
1721 part.TaskInventory.LockItemsForRead(false);
1686 // Reset sit target. 1722 // Reset sit target.
1687 if (part.GetAvatarOnSitTarget() == UUID) 1723 if (part.GetAvatarOnSitTarget() == UUID)
1688 part.SetAvatarOnSitTarget(UUID.Zero); 1724 part.SetAvatarOnSitTarget(UUID.Zero);
1689
1690 m_parentPosition = part.GetWorldPosition(); 1725 m_parentPosition = part.GetWorldPosition();
1691 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1726 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1692 } 1727 }
1728 // part.GetWorldRotation() is the rotation of the object being sat on
1729 // Rotation is the sittiing Av's rotation
1730
1731 Quaternion partRot;
1732// if (part.LinkNum == 1)
1733// { // Root prim of linkset
1734// partRot = part.ParentGroup.RootPart.RotationOffset;
1735// }
1736// else
1737// { // single or child prim
1738
1739// }
1740 if (part == null) //CW: Part may be gone. llDie() for example.
1741 {
1742 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1743 }
1744 else
1745 {
1746 partRot = part.GetWorldRotation();
1747 }
1748
1749 Quaternion partIRot = Quaternion.Inverse(partRot);
1750
1751 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1752 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1693 1753
1754
1694 if (m_physicsActor == null) 1755 if (m_physicsActor == null)
1695 { 1756 {
1696 AddToPhysicalScene(false); 1757 AddToPhysicalScene(false);
1697 } 1758 }
1698 1759 //CW: If the part isn't null then we can set the current position
1699 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1760 if (part != null)
1700 m_parentPosition = Vector3.Zero; 1761 {
1701 1762 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1702 m_parentID = 0; 1763 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1764 part.IsOccupied = false;
1765 }
1766 else
1767 {
1768 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1769 AbsolutePosition = m_lastWorldPosition;
1770 }
1771
1772 m_parentPosition = Vector3.Zero;
1773 m_parentID = 0;
1703 SendFullUpdateToAllClients(); 1774 SendFullUpdateToAllClients();
1704 m_requestedSitTargetID = 0; 1775 m_requestedSitTargetID = 0;
1776
1705 if ((m_physicsActor != null) && (m_avHeight > 0)) 1777 if ((m_physicsActor != null) && (m_avHeight > 0))
1706 { 1778 {
1707 SetHeight(m_avHeight); 1779 SetHeight(m_avHeight);
1708 } 1780 }
1709 } 1781 }
1710
1711 Animator.TrySetMovementAnimation("STAND"); 1782 Animator.TrySetMovementAnimation("STAND");
1712 } 1783 }
1713 1784
@@ -1738,13 +1809,9 @@ namespace OpenSim.Region.Framework.Scenes
1738 Vector3 avSitOffSet = part.SitTargetPosition; 1809 Vector3 avSitOffSet = part.SitTargetPosition;
1739 Quaternion avSitOrientation = part.SitTargetOrientation; 1810 Quaternion avSitOrientation = part.SitTargetOrientation;
1740 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1811 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1741 1812 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1742 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1813 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1743 bool SitTargetisSet = 1814 if (SitTargetisSet && !SitTargetOccupied)
1744 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1745 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1746
1747 if (SitTargetisSet && SitTargetUnOccupied)
1748 { 1815 {
1749 //switch the target to this prim 1816 //switch the target to this prim
1750 return part; 1817 return part;
@@ -1758,84 +1825,152 @@ namespace OpenSim.Region.Framework.Scenes
1758 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1825 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1759 { 1826 {
1760 bool autopilot = true; 1827 bool autopilot = true;
1828 Vector3 autopilotTarget = new Vector3();
1829 Quaternion sitOrientation = Quaternion.Identity;
1761 Vector3 pos = new Vector3(); 1830 Vector3 pos = new Vector3();
1762 Quaternion sitOrientation = pSitOrientation;
1763 Vector3 cameraEyeOffset = Vector3.Zero; 1831 Vector3 cameraEyeOffset = Vector3.Zero;
1764 Vector3 cameraAtOffset = Vector3.Zero; 1832 Vector3 cameraAtOffset = Vector3.Zero;
1765 bool forceMouselook = false; 1833 bool forceMouselook = false;
1766 1834
1767 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1835 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1768 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1836 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1769 if (part != null) 1837 if (part == null) return;
1770 { 1838
1771 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1839 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1772 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1840 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1773 1841
1774 // Is a sit target available? 1842 // part is the prim to sit on
1775 Vector3 avSitOffSet = part.SitTargetPosition; 1843 // offset is the world-ref vector distance from that prim center to the click-spot
1776 Quaternion avSitOrientation = part.SitTargetOrientation; 1844 // UUID is the UUID of the Avatar doing the clicking
1777 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1845
1778 1846 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1779 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1847
1780 bool SitTargetisSet = 1848 // Is a sit target available?
1781 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1849 Vector3 avSitOffSet = part.SitTargetPosition;
1782 ( 1850 Quaternion avSitOrientation = part.SitTargetOrientation;
1783 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1851
1784 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1852 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1785 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1853 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1786 ) 1854 Quaternion partRot;
1787 )); 1855// if (part.LinkNum == 1)
1788 1856// { // Root prim of linkset
1789 if (SitTargetisSet && SitTargetUnOccupied) 1857// partRot = part.ParentGroup.RootPart.RotationOffset;
1790 { 1858// }
1791 part.SetAvatarOnSitTarget(UUID); 1859// else
1792 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1860// { // single or child prim
1793 sitOrientation = avSitOrientation; 1861 partRot = part.GetWorldRotation();
1794 autopilot = false; 1862// }
1795 } 1863 Quaternion partIRot = Quaternion.Inverse(partRot);
1796 1864//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1797 pos = part.AbsolutePosition + offset; 1865 // Sit analysis rewritten by KF 091125
1798 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1866 if (SitTargetisSet) // scipted sit
1799 //{ 1867 {
1800 // offset = pos; 1868 if (!part.IsOccupied)
1801 //autopilot = false; 1869 {
1802 //} 1870//Console.WriteLine("Scripted, unoccupied");
1803 if (m_physicsActor != null) 1871 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1804 { 1872 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1805 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1873 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1806 // We can remove the physicsActor until they stand up. 1874 autopilot = false; // Jump direct to scripted llSitPos()
1807 m_sitAvatarHeight = m_physicsActor.Size.Z; 1875 }
1808 1876 else
1809 if (autopilot) 1877 {
1810 { 1878//Console.WriteLine("Scripted, occupied");
1811 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1879 return;
1812 { 1880 }
1813 autopilot = false; 1881 }
1882 else // Not Scripted
1883 {
1884 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1885 {
1886 // large prim & offset, ignore if other Avs sitting
1887// offset.Z -= 0.05f;
1888 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1889 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1890
1891//Console.WriteLine(" offset ={0}", offset);
1892//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1893//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1894
1895 }
1896 else // small offset
1897 {
1898//Console.WriteLine("Small offset");
1899 if (!part.IsOccupied)
1900 {
1901 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1902 autopilotTarget = part.AbsolutePosition;
1903 }
1904 else return; // occupied small
1905 } // end large/small
1906 } // end Scripted/not
1907 cameraAtOffset = part.GetCameraAtOffset();
1908 cameraEyeOffset = part.GetCameraEyeOffset();
1909 forceMouselook = part.GetForceMouselook();
1910 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1911 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1814 1912
1815 RemoveFromPhysicalScene(); 1913 if (m_physicsActor != null)
1816 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1914 {
1817 } 1915 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1818 } 1916 // We can remove the physicsActor until they stand up.
1819 else 1917 m_sitAvatarHeight = m_physicsActor.Size.Z;
1918 if (autopilot)
1919 { // its not a scripted sit
1920// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1921 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1820 { 1922 {
1923 autopilot = false; // close enough
1924 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1925 Not using the part's position because returning the AV to the last known standing
1926 position is likely to be more friendly, isn't it? */
1821 RemoveFromPhysicalScene(); 1927 RemoveFromPhysicalScene();
1822 } 1928 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1929 } // else the autopilot will get us close
1930 }
1931 else
1932 { // its a scripted sit
1933 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1934 I *am* using the part's position this time because we have no real idea how far away
1935 the avatar is from the sit target. */
1936 RemoveFromPhysicalScene();
1823 } 1937 }
1824
1825 cameraAtOffset = part.GetCameraAtOffset();
1826 cameraEyeOffset = part.GetCameraEyeOffset();
1827 forceMouselook = part.GetForceMouselook();
1828 } 1938 }
1829 1939 else return; // physactor is null!
1830 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1940
1831 m_requestedSitTargetUUID = targetID; 1941 Vector3 offsetr; // = offset * partIRot;
1942 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1943 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1944 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1945 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1946 offsetr = offset * partIRot;
1947//
1948 // else
1949 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1950 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1951 // (offset * partRot);
1952 // }
1953
1954//Console.WriteLine(" ");
1955//Console.WriteLine("link number ={0}", part.LinkNum);
1956//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1957//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1958//Console.WriteLine("Click offst ={0}", offset);
1959//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1960//Console.WriteLine("offsetr ={0}", offsetr);
1961//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1962//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1963
1964 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1965 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1832 // This calls HandleAgentSit twice, once from here, and the client calls 1966 // This calls HandleAgentSit twice, once from here, and the client calls
1833 // HandleAgentSit itself after it gets to the location 1967 // HandleAgentSit itself after it gets to the location
1834 // It doesn't get to the location until we've moved them there though 1968 // It doesn't get to the location until we've moved them there though
1835 // which happens in HandleAgentSit :P 1969 // which happens in HandleAgentSit :P
1836 m_autopilotMoving = autopilot; 1970 m_autopilotMoving = autopilot;
1837 m_autoPilotTarget = pos; 1971 m_autoPilotTarget = autopilotTarget;
1838 m_sitAtAutoTarget = autopilot; 1972 m_sitAtAutoTarget = autopilot;
1973 m_initialSitTarget = autopilotTarget;
1839 if (!autopilot) 1974 if (!autopilot)
1840 HandleAgentSit(remoteClient, UUID); 1975 HandleAgentSit(remoteClient, UUID);
1841 } 1976 }
@@ -2130,31 +2265,65 @@ namespace OpenSim.Region.Framework.Scenes
2130 { 2265 {
2131 if (part != null) 2266 if (part != null)
2132 { 2267 {
2268//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2133 if (part.GetAvatarOnSitTarget() == UUID) 2269 if (part.GetAvatarOnSitTarget() == UUID)
2134 { 2270 {
2271//Console.WriteLine("Scripted Sit");
2272 // Scripted sit
2135 Vector3 sitTargetPos = part.SitTargetPosition; 2273 Vector3 sitTargetPos = part.SitTargetPosition;
2136 Quaternion sitTargetOrient = part.SitTargetOrientation; 2274 Quaternion sitTargetOrient = part.SitTargetOrientation;
2137
2138 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2139 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2140
2141 //Quaternion result = (sitTargetOrient * vq) * nq;
2142
2143 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2275 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2144 m_pos += SIT_TARGET_ADJUSTMENT; 2276 m_pos += SIT_TARGET_ADJUSTMENT;
2145 m_bodyRot = sitTargetOrient; 2277 m_bodyRot = sitTargetOrient;
2146 //Rotation = sitTargetOrient;
2147 m_parentPosition = part.AbsolutePosition; 2278 m_parentPosition = part.AbsolutePosition;
2148 2279 part.IsOccupied = true;
2149 //SendTerseUpdateToAllClients();
2150 } 2280 }
2151 else 2281 else
2152 { 2282 {
2153 m_pos -= part.AbsolutePosition; 2283 // if m_avUnscriptedSitPos is zero then Av sits above center
2284 // Else Av sits at m_avUnscriptedSitPos
2285
2286 // Non-scripted sit by Kitto Flora 21Nov09
2287 // Calculate angle of line from prim to Av
2288 Quaternion partIRot;
2289// if (part.LinkNum == 1)
2290// { // Root prim of linkset
2291// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2292// }
2293// else
2294// { // single or child prim
2295 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2296// }
2297 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2298 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2299 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2300 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2301 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2302 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2303 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2304 // Av sits at world euler <0,0, z>, translated by part rotation
2305 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2306
2154 m_parentPosition = part.AbsolutePosition; 2307 m_parentPosition = part.AbsolutePosition;
2155 } 2308 part.IsOccupied = true;
2309 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2310 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2311 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2312 m_avUnscriptedSitPos; // adds click offset, if any
2313 //Set up raytrace to find top surface of prim
2314 Vector3 size = part.Scale;
2315 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2316 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2317 Vector3 down = new Vector3(0f, 0f, -1f);
2318//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2319 m_scene.PhysicsScene.RaycastWorld(
2320 start, // Vector3 position,
2321 down, // Vector3 direction,
2322 mag, // float length,
2323 SitAltitudeCallback); // retMethod
2324 } // end scripted/not
2156 } 2325 }
2157 else 2326 else // no Av
2158 { 2327 {
2159 return; 2328 return;
2160 } 2329 }
@@ -2166,11 +2335,39 @@ namespace OpenSim.Region.Framework.Scenes
2166 2335
2167 Animator.TrySetMovementAnimation(sitAnimation); 2336 Animator.TrySetMovementAnimation(sitAnimation);
2168 SendFullUpdateToAllClients(); 2337 SendFullUpdateToAllClients();
2169 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2170 // So we're also sending a terse update (which has avatar rotation)
2171 // [Update] We do now.
2172 //SendTerseUpdateToAllClients();
2173 } 2338 }
2339
2340 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2341 {
2342 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2343 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2344 if(hitYN)
2345 {
2346 // m_pos = Av offset from prim center to make look like on center
2347 // m_parentPosition = Actual center pos of prim
2348 // collisionPoint = spot on prim where we want to sit
2349 // collisionPoint.Z = global sit surface height
2350 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2351 Quaternion partIRot;
2352// if (part.LinkNum == 1)
2353/// { // Root prim of linkset
2354// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2355// }
2356// else
2357// { // single or child prim
2358 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2359// }
2360 if (m_initialSitTarget != null)
2361 {
2362 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2363 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2364 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2365 m_pos += offset;
2366 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2367 }
2368
2369 }
2370 } // End SitAltitudeCallback KF.
2174 2371
2175 /// <summary> 2372 /// <summary>
2176 /// Event handler for the 'Always run' setting on the client 2373 /// Event handler for the 'Always run' setting on the client
@@ -2200,7 +2397,7 @@ namespace OpenSim.Region.Framework.Scenes
2200 /// </summary> 2397 /// </summary>
2201 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2398 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2202 /// <param name="rotation">The direction in which this avatar should now face. 2399 /// <param name="rotation">The direction in which this avatar should now face.
2203 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2400 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2204 { 2401 {
2205 if (m_isChildAgent) 2402 if (m_isChildAgent)
2206 { 2403 {
@@ -2238,10 +2435,11 @@ namespace OpenSim.Region.Framework.Scenes
2238 Rotation = rotation; 2435 Rotation = rotation;
2239 Vector3 direc = vec * rotation; 2436 Vector3 direc = vec * rotation;
2240 direc.Normalize(); 2437 direc.Normalize();
2438 PhysicsActor actor = m_physicsActor;
2439 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2241 2440
2242 direc *= 0.03f * 128f * m_speedModifier; 2441 direc *= 0.03f * 128f * m_speedModifier;
2243 2442
2244 PhysicsActor actor = m_physicsActor;
2245 if (actor != null) 2443 if (actor != null)
2246 { 2444 {
2247 if (actor.Flying) 2445 if (actor.Flying)
@@ -2263,18 +2461,25 @@ namespace OpenSim.Region.Framework.Scenes
2263 { 2461 {
2264 if (direc.Z > 2.0f) 2462 if (direc.Z > 2.0f)
2265 { 2463 {
2266 direc.Z *= 3.0f; 2464 if(m_animator.m_animTickJump == -1)
2267 2465 {
2268 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2466 direc.Z *= 3.0f; // jump
2269 Animator.TrySetMovementAnimation("PREJUMP"); 2467 }
2270 Animator.TrySetMovementAnimation("JUMP"); 2468 else
2469 {
2470 direc.Z *= 0.1f; // prejump
2471 }
2472 /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2473 Animator.TrySetMovementAnimation("PREJUMP");
2474 Animator.TrySetMovementAnimation("JUMP");
2475 */
2271 } 2476 }
2272 } 2477 }
2273 } 2478 }
2274 2479
2275 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2480 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2276 m_forceToApply = direc; 2481 m_forceToApply = direc;
2277 2482 m_isNudging = Nudging;
2278 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2483 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2279 } 2484 }
2280 2485
@@ -2289,7 +2494,7 @@ namespace OpenSim.Region.Framework.Scenes
2289 const float POSITION_TOLERANCE = 0.05f; 2494 const float POSITION_TOLERANCE = 0.05f;
2290 //const int TIME_MS_TOLERANCE = 3000; 2495 //const int TIME_MS_TOLERANCE = 3000;
2291 2496
2292 SendPrimUpdates(); 2497
2293 2498
2294 if (m_newCoarseLocations) 2499 if (m_newCoarseLocations)
2295 { 2500 {
@@ -2325,6 +2530,9 @@ namespace OpenSim.Region.Framework.Scenes
2325 CheckForBorderCrossing(); 2530 CheckForBorderCrossing();
2326 CheckForSignificantMovement(); // sends update to the modules. 2531 CheckForSignificantMovement(); // sends update to the modules.
2327 } 2532 }
2533
2534 //Sending prim updates AFTER the avatar terse updates are sent
2535 SendPrimUpdates();
2328 } 2536 }
2329 2537
2330 #endregion 2538 #endregion
@@ -3225,14 +3433,25 @@ namespace OpenSim.Region.Framework.Scenes
3225 { 3433 {
3226 if (m_forceToApply.HasValue) 3434 if (m_forceToApply.HasValue)
3227 { 3435 {
3228 Vector3 force = m_forceToApply.Value;
3229 3436
3437 Vector3 force = m_forceToApply.Value;
3230 m_updateflag = true; 3438 m_updateflag = true;
3231// movementvector = force;
3232 Velocity = force; 3439 Velocity = force;
3233 3440
3234 m_forceToApply = null; 3441 m_forceToApply = null;
3235 } 3442 }
3443 else
3444 {
3445 if (m_isNudging)
3446 {
3447 Vector3 force = Vector3.Zero;
3448
3449 m_updateflag = true;
3450 Velocity = force;
3451 m_isNudging = false;
3452 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3453 }
3454 }
3236 } 3455 }
3237 3456
3238 public override void SetText(string text, Vector3 color, double alpha) 3457 public override void SetText(string text, Vector3 color, double alpha)
@@ -3283,18 +3502,29 @@ namespace OpenSim.Region.Framework.Scenes
3283 { 3502 {
3284 if (e == null) 3503 if (e == null)
3285 return; 3504 return;
3286 3505
3287 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3506 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3288 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3289 // as of this comment the interval is set in AddToPhysicalScene 3507 // as of this comment the interval is set in AddToPhysicalScene
3290 if (Animator!=null) 3508 if (Animator!=null)
3291 Animator.UpdateMovementAnimations(); 3509 {
3510 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3511 { // else its will lock out other animation changes, like ground sit.
3512 Animator.UpdateMovementAnimations();
3513 m_updateCount--;
3514 }
3515 }
3292 3516
3293 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3517 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3294 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3518 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3295 3519
3296 CollisionPlane = Vector4.UnitW; 3520 CollisionPlane = Vector4.UnitW;
3297 3521
3522 if (m_lastColCount != coldata.Count)
3523 {
3524 m_updateCount = UPDATE_COUNT;
3525 m_lastColCount = coldata.Count;
3526 }
3527
3298 if (coldata.Count != 0 && Animator != null) 3528 if (coldata.Count != 0 && Animator != null)
3299 { 3529 {
3300 switch (Animator.CurrentMovementAnimation) 3530 switch (Animator.CurrentMovementAnimation)
@@ -3933,5 +4163,16 @@ namespace OpenSim.Region.Framework.Scenes
3933 m_reprioritization_called = false; 4163 m_reprioritization_called = false;
3934 } 4164 }
3935 } 4165 }
4166
4167 private Vector3 Quat2Euler(Quaternion rot){
4168 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4169 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4170 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4171 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4172 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4173 return(new Vector3(x,y,z));
4174 }
4175
4176
3936 } 4177 }
3937} 4178}