aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs579
1 files changed, 405 insertions, 174 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 4973663..2603fe1 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -123,8 +125,11 @@ namespace OpenSim.Region.Framework.Scenes
123 public Vector3 lastKnownAllowedPosition; 125 public Vector3 lastKnownAllowedPosition;
124 public bool sentMessageAboutRestrictedParcelFlyingDown; 126 public bool sentMessageAboutRestrictedParcelFlyingDown;
125 public Vector4 CollisionPlane = Vector4.UnitW; 127 public Vector4 CollisionPlane = Vector4.UnitW;
126 128
127 private Vector3 m_lastPosition; 129 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
130 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
131 private Vector3 m_lastPosition;
132 private Vector3 m_lastWorldPosition;
128 private Quaternion m_lastRotation; 133 private Quaternion m_lastRotation;
129 private Vector3 m_lastVelocity; 134 private Vector3 m_lastVelocity;
130 //private int m_lastTerseSent; 135 //private int m_lastTerseSent;
@@ -134,7 +139,6 @@ namespace OpenSim.Region.Framework.Scenes
134 private Vector3? m_forceToApply; 139 private Vector3? m_forceToApply;
135 private uint m_requestedSitTargetID; 140 private uint m_requestedSitTargetID;
136 private UUID m_requestedSitTargetUUID; 141 private UUID m_requestedSitTargetUUID;
137 public bool SitGround = false;
138 142
139 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 143 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
140 144
@@ -156,7 +160,6 @@ namespace OpenSim.Region.Framework.Scenes
156 private int m_perfMonMS; 160 private int m_perfMonMS;
157 161
158 private bool m_setAlwaysRun; 162 private bool m_setAlwaysRun;
159
160 private bool m_forceFly; 163 private bool m_forceFly;
161 private bool m_flyDisabled; 164 private bool m_flyDisabled;
162 165
@@ -182,7 +185,8 @@ namespace OpenSim.Region.Framework.Scenes
182 protected RegionInfo m_regionInfo; 185 protected RegionInfo m_regionInfo;
183 protected ulong crossingFromRegion; 186 protected ulong crossingFromRegion;
184 187
185 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 188 private readonly Vector3[] Dir_Vectors = new Vector3[11];
189 private bool m_isNudging = false;
186 190
187 // Position of agent's camera in world (region cordinates) 191 // Position of agent's camera in world (region cordinates)
188 protected Vector3 m_CameraCenter; 192 protected Vector3 m_CameraCenter;
@@ -207,6 +211,7 @@ namespace OpenSim.Region.Framework.Scenes
207 private bool m_autopilotMoving; 211 private bool m_autopilotMoving;
208 private Vector3 m_autoPilotTarget; 212 private Vector3 m_autoPilotTarget;
209 private bool m_sitAtAutoTarget; 213 private bool m_sitAtAutoTarget;
214 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
210 215
211 private string m_nextSitAnimation = String.Empty; 216 private string m_nextSitAnimation = String.Empty;
212 217
@@ -217,6 +222,9 @@ namespace OpenSim.Region.Framework.Scenes
217 private bool m_followCamAuto; 222 private bool m_followCamAuto;
218 223
219 private int m_movementUpdateCount; 224 private int m_movementUpdateCount;
225 private int m_lastColCount = -1; //KF: Look for Collision chnages
226 private int m_updateCount = 0; //KF: Update Anims for a while
227 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
220 228
221 private const int NumMovementsBetweenRayCast = 5; 229 private const int NumMovementsBetweenRayCast = 5;
222 230
@@ -245,7 +253,9 @@ namespace OpenSim.Region.Framework.Scenes
245 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 253 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
246 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 254 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
247 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 255 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
248 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 256 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
257 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
258 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 259 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
250 } 260 }
251 261
@@ -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 }
@@ -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
@@ -826,9 +857,24 @@ namespace OpenSim.Region.Framework.Scenes
826 { 857 {
827 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 858 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
828 pos.Y = crossedBorder.BorderLine.Z - 1; 859 pos.Y = crossedBorder.BorderLine.Z - 1;
860 }
861
862 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
863 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
864 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
865 if (KnownChildRegionHandles.Count == 0)
866 {
867 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
868 if (land != null)
869 {
870 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
871 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godlevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
872 {
873 pos = land.LandData.UserLocation;
874 }
875 }
829 } 876 }
830 877
831
832 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 878 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
833 { 879 {
834 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 880 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -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;
991 if (m_physicsActor != null)
992 isFlying = m_physicsActor.Flying;
993 1037
1038 if (m_physicsActor != null)
1039 isFlying = m_physicsActor.Flying;
1040
994 RemoveFromPhysicalScene(); 1041 RemoveFromPhysicalScene();
995 Velocity = Vector3.Zero; 1042 Velocity = Vector3.Zero;
996 AbsolutePosition = pos; 1043 AbsolutePosition = pos;
@@ -1001,7 +1048,8 @@ namespace OpenSim.Region.Framework.Scenes
1001 SetHeight(m_appearance.AvatarHeight); 1048 SetHeight(m_appearance.AvatarHeight);
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 {
@@ -1453,6 +1494,9 @@ namespace OpenSim.Region.Framework.Scenes
1453 // Ignore z component of vector 1494 // Ignore z component of vector
1454 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1495 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1455 LocalVectorToTarget2D.Normalize(); 1496 LocalVectorToTarget2D.Normalize();
1497
1498 //We're not nudging
1499 Nudging = false;
1456 agent_control_v3 += LocalVectorToTarget2D; 1500 agent_control_v3 += LocalVectorToTarget2D;
1457 1501
1458 // update avatar movement flags. the avatar coordinate system is as follows: 1502 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1541,13 +1585,13 @@ namespace OpenSim.Region.Framework.Scenes
1541 // m_log.DebugFormat( 1585 // m_log.DebugFormat(
1542 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1586 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1543 1587
1544 AddNewMovement(agent_control_v3, q); 1588 AddNewMovement(agent_control_v3, q, Nudging);
1545 1589
1546 1590
1547 } 1591 }
1548 } 1592 }
1549 1593
1550 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1594 if (update_movementflag)
1551 Animator.UpdateMovementAnimations(); 1595 Animator.UpdateMovementAnimations();
1552 1596
1553 m_scene.EventManager.TriggerOnClientMovement(this); 1597 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1562,7 +1606,6 @@ namespace OpenSim.Region.Framework.Scenes
1562 m_sitAtAutoTarget = false; 1606 m_sitAtAutoTarget = false;
1563 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1607 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1564 //proxy.PCode = (byte)PCode.ParticleSystem; 1608 //proxy.PCode = (byte)PCode.ParticleSystem;
1565
1566 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1609 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1567 proxyObjectGroup.AttachToScene(m_scene); 1610 proxyObjectGroup.AttachToScene(m_scene);
1568 1611
@@ -1604,7 +1647,7 @@ namespace OpenSim.Region.Framework.Scenes
1604 } 1647 }
1605 m_moveToPositionInProgress = true; 1648 m_moveToPositionInProgress = true;
1606 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1649 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1607 } 1650 }
1608 catch (Exception ex) 1651 catch (Exception ex)
1609 { 1652 {
1610 //Why did I get this error? 1653 //Why did I get this error?
@@ -1626,7 +1669,7 @@ namespace OpenSim.Region.Framework.Scenes
1626 Velocity = Vector3.Zero; 1669 Velocity = Vector3.Zero;
1627 SendFullUpdateToAllClients(); 1670 SendFullUpdateToAllClients();
1628 1671
1629 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1672 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1630 } 1673 }
1631 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1674 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1632 m_requestedSitTargetUUID = UUID.Zero; 1675 m_requestedSitTargetUUID = UUID.Zero;
@@ -1659,55 +1702,84 @@ namespace OpenSim.Region.Framework.Scenes
1659 /// </summary> 1702 /// </summary>
1660 public void StandUp() 1703 public void StandUp()
1661 { 1704 {
1662 if (SitGround)
1663 SitGround = false;
1664
1665 if (m_parentID != 0) 1705 if (m_parentID != 0)
1666 { 1706 {
1667 m_log.Debug("StandupCode Executed");
1668 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1707 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1669 if (part != null) 1708 if (part != null)
1670 { 1709 {
1710 part.TaskInventory.LockItemsForRead(true);
1671 TaskInventoryDictionary taskIDict = part.TaskInventory; 1711 TaskInventoryDictionary taskIDict = part.TaskInventory;
1672 if (taskIDict != null) 1712 if (taskIDict != null)
1673 { 1713 {
1674 lock (taskIDict) 1714 foreach (UUID taskID in taskIDict.Keys)
1675 { 1715 {
1676 foreach (UUID taskID in taskIDict.Keys) 1716 UnRegisterControlEventsToScript(LocalId, taskID);
1677 { 1717 taskIDict[taskID].PermsMask &= ~(
1678 UnRegisterControlEventsToScript(LocalId, taskID); 1718 2048 | //PERMISSION_CONTROL_CAMERA
1679 taskIDict[taskID].PermsMask &= ~( 1719 4); // PERMISSION_TAKE_CONTROLS
1680 2048 | //PERMISSION_CONTROL_CAMERA
1681 4); // PERMISSION_TAKE_CONTROLS
1682 }
1683 } 1720 }
1684
1685 } 1721 }
1722 part.TaskInventory.LockItemsForRead(false);
1686 // Reset sit target. 1723 // Reset sit target.
1687 if (part.GetAvatarOnSitTarget() == UUID) 1724 if (part.GetAvatarOnSitTarget() == UUID)
1688 part.SetAvatarOnSitTarget(UUID.Zero); 1725 part.SetAvatarOnSitTarget(UUID.Zero);
1689
1690 m_parentPosition = part.GetWorldPosition(); 1726 m_parentPosition = part.GetWorldPosition();
1691 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1727 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1692 } 1728 }
1693 1729 // part.GetWorldRotation() is the rotation of the object being sat on
1694 if (m_physicsActor == null) 1730 // Rotation is the sittiing Av's rotation
1695 { 1731
1696 AddToPhysicalScene(false); 1732 Quaternion partRot;
1733// if (part.LinkNum == 1)
1734// { // Root prim of linkset
1735// partRot = part.ParentGroup.RootPart.RotationOffset;
1736// }
1737// else
1738// { // single or child prim
1739
1740// }
1741 if (part == null) //CW: Part may be gone. llDie() for example.
1742 {
1743 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1744 }
1745 else
1746 {
1747 partRot = part.GetWorldRotation();
1697 } 1748 }
1698 1749
1699 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1750 Quaternion partIRot = Quaternion.Inverse(partRot);
1700 m_parentPosition = Vector3.Zero;
1701 1751
1702 m_parentID = 0; 1752 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1753 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1754
1755
1756 if (m_physicsActor == null)
1757 {
1758 AddToPhysicalScene(false);
1759 }
1760 //CW: If the part isn't null then we can set the current position
1761 if (part != null)
1762 {
1763 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1764 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1765 part.IsOccupied = false;
1766 }
1767 else
1768 {
1769 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1770 AbsolutePosition = m_lastWorldPosition;
1771 }
1772
1773 m_parentPosition = Vector3.Zero;
1774 m_parentID = 0;
1703 SendFullUpdateToAllClients(); 1775 SendFullUpdateToAllClients();
1704 m_requestedSitTargetID = 0; 1776 m_requestedSitTargetID = 0;
1777
1705 if ((m_physicsActor != null) && (m_avHeight > 0)) 1778 if ((m_physicsActor != null) && (m_avHeight > 0))
1706 { 1779 {
1707 SetHeight(m_avHeight); 1780 SetHeight(m_avHeight);
1708 } 1781 }
1709 } 1782 }
1710
1711 Animator.TrySetMovementAnimation("STAND"); 1783 Animator.TrySetMovementAnimation("STAND");
1712 } 1784 }
1713 1785
@@ -1738,13 +1810,9 @@ namespace OpenSim.Region.Framework.Scenes
1738 Vector3 avSitOffSet = part.SitTargetPosition; 1810 Vector3 avSitOffSet = part.SitTargetPosition;
1739 Quaternion avSitOrientation = part.SitTargetOrientation; 1811 Quaternion avSitOrientation = part.SitTargetOrientation;
1740 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1812 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1741 1813 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1742 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1814 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1743 bool SitTargetisSet = 1815 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 { 1816 {
1749 //switch the target to this prim 1817 //switch the target to this prim
1750 return part; 1818 return part;
@@ -1758,84 +1826,152 @@ namespace OpenSim.Region.Framework.Scenes
1758 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1826 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1759 { 1827 {
1760 bool autopilot = true; 1828 bool autopilot = true;
1829 Vector3 autopilotTarget = new Vector3();
1830 Quaternion sitOrientation = Quaternion.Identity;
1761 Vector3 pos = new Vector3(); 1831 Vector3 pos = new Vector3();
1762 Quaternion sitOrientation = pSitOrientation;
1763 Vector3 cameraEyeOffset = Vector3.Zero; 1832 Vector3 cameraEyeOffset = Vector3.Zero;
1764 Vector3 cameraAtOffset = Vector3.Zero; 1833 Vector3 cameraAtOffset = Vector3.Zero;
1765 bool forceMouselook = false; 1834 bool forceMouselook = false;
1766 1835
1767 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1836 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1768 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1837 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1769 if (part != null) 1838 if (part == null) return;
1770 { 1839
1771 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1840 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1772 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1841 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1773 1842
1774 // Is a sit target available? 1843 // part is the prim to sit on
1775 Vector3 avSitOffSet = part.SitTargetPosition; 1844 // offset is the world-ref vector distance from that prim center to the click-spot
1776 Quaternion avSitOrientation = part.SitTargetOrientation; 1845 // UUID is the UUID of the Avatar doing the clicking
1777 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1846
1778 1847 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1779 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1848
1780 bool SitTargetisSet = 1849 // Is a sit target available?
1781 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1850 Vector3 avSitOffSet = part.SitTargetPosition;
1782 ( 1851 Quaternion avSitOrientation = part.SitTargetOrientation;
1783 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1852
1784 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1853 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1785 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1854 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1786 ) 1855 Quaternion partRot;
1787 )); 1856// if (part.LinkNum == 1)
1788 1857// { // Root prim of linkset
1789 if (SitTargetisSet && SitTargetUnOccupied) 1858// partRot = part.ParentGroup.RootPart.RotationOffset;
1790 { 1859// }
1791 part.SetAvatarOnSitTarget(UUID); 1860// else
1792 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1861// { // single or child prim
1793 sitOrientation = avSitOrientation; 1862 partRot = part.GetWorldRotation();
1794 autopilot = false; 1863// }
1795 } 1864 Quaternion partIRot = Quaternion.Inverse(partRot);
1796 1865//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1797 pos = part.AbsolutePosition + offset; 1866 // Sit analysis rewritten by KF 091125
1798 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1867 if (SitTargetisSet) // scipted sit
1799 //{ 1868 {
1800 // offset = pos; 1869 if (!part.IsOccupied)
1801 //autopilot = false; 1870 {
1802 //} 1871//Console.WriteLine("Scripted, unoccupied");
1803 if (m_physicsActor != null) 1872 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1804 { 1873 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 1874 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1806 // We can remove the physicsActor until they stand up. 1875 autopilot = false; // Jump direct to scripted llSitPos()
1807 m_sitAvatarHeight = m_physicsActor.Size.Z; 1876 }
1808 1877 else
1809 if (autopilot) 1878 {
1810 { 1879//Console.WriteLine("Scripted, occupied");
1811 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1880 return;
1812 { 1881 }
1813 autopilot = false; 1882 }
1883 else // Not Scripted
1884 {
1885 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1886 {
1887 // large prim & offset, ignore if other Avs sitting
1888// offset.Z -= 0.05f;
1889 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1890 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1891
1892//Console.WriteLine(" offset ={0}", offset);
1893//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1894//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1895
1896 }
1897 else // small offset
1898 {
1899//Console.WriteLine("Small offset");
1900 if (!part.IsOccupied)
1901 {
1902 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1903 autopilotTarget = part.AbsolutePosition;
1904 }
1905 else return; // occupied small
1906 } // end large/small
1907 } // end Scripted/not
1908 cameraAtOffset = part.GetCameraAtOffset();
1909 cameraEyeOffset = part.GetCameraEyeOffset();
1910 forceMouselook = part.GetForceMouselook();
1911 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1912 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1814 1913
1815 RemoveFromPhysicalScene(); 1914 if (m_physicsActor != null)
1816 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1915 {
1817 } 1916 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1818 } 1917 // We can remove the physicsActor until they stand up.
1819 else 1918 m_sitAvatarHeight = m_physicsActor.Size.Z;
1919 if (autopilot)
1920 { // its not a scripted sit
1921// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1922 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1820 { 1923 {
1924 autopilot = false; // close enough
1925 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1926 Not using the part's position because returning the AV to the last known standing
1927 position is likely to be more friendly, isn't it? */
1821 RemoveFromPhysicalScene(); 1928 RemoveFromPhysicalScene();
1822 } 1929 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1930 } // else the autopilot will get us close
1931 }
1932 else
1933 { // its a scripted sit
1934 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1935 I *am* using the part's position this time because we have no real idea how far away
1936 the avatar is from the sit target. */
1937 RemoveFromPhysicalScene();
1823 } 1938 }
1824
1825 cameraAtOffset = part.GetCameraAtOffset();
1826 cameraEyeOffset = part.GetCameraEyeOffset();
1827 forceMouselook = part.GetForceMouselook();
1828 } 1939 }
1829 1940 else return; // physactor is null!
1830 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1941
1831 m_requestedSitTargetUUID = targetID; 1942 Vector3 offsetr; // = offset * partIRot;
1943 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1944 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1945 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1946 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1947 offsetr = offset * partIRot;
1948//
1949 // else
1950 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1951 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1952 // (offset * partRot);
1953 // }
1954
1955//Console.WriteLine(" ");
1956//Console.WriteLine("link number ={0}", part.LinkNum);
1957//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1958//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1959//Console.WriteLine("Click offst ={0}", offset);
1960//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1961//Console.WriteLine("offsetr ={0}", offsetr);
1962//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1963//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1964
1965 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1966 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1832 // This calls HandleAgentSit twice, once from here, and the client calls 1967 // This calls HandleAgentSit twice, once from here, and the client calls
1833 // HandleAgentSit itself after it gets to the location 1968 // HandleAgentSit itself after it gets to the location
1834 // It doesn't get to the location until we've moved them there though 1969 // It doesn't get to the location until we've moved them there though
1835 // which happens in HandleAgentSit :P 1970 // which happens in HandleAgentSit :P
1836 m_autopilotMoving = autopilot; 1971 m_autopilotMoving = autopilot;
1837 m_autoPilotTarget = pos; 1972 m_autoPilotTarget = autopilotTarget;
1838 m_sitAtAutoTarget = autopilot; 1973 m_sitAtAutoTarget = autopilot;
1974 m_initialSitTarget = autopilotTarget;
1839 if (!autopilot) 1975 if (!autopilot)
1840 HandleAgentSit(remoteClient, UUID); 1976 HandleAgentSit(remoteClient, UUID);
1841 } 1977 }
@@ -2130,31 +2266,65 @@ namespace OpenSim.Region.Framework.Scenes
2130 { 2266 {
2131 if (part != null) 2267 if (part != null)
2132 { 2268 {
2269//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2133 if (part.GetAvatarOnSitTarget() == UUID) 2270 if (part.GetAvatarOnSitTarget() == UUID)
2134 { 2271 {
2272//Console.WriteLine("Scripted Sit");
2273 // Scripted sit
2135 Vector3 sitTargetPos = part.SitTargetPosition; 2274 Vector3 sitTargetPos = part.SitTargetPosition;
2136 Quaternion sitTargetOrient = part.SitTargetOrientation; 2275 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); 2276 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2144 m_pos += SIT_TARGET_ADJUSTMENT; 2277 m_pos += SIT_TARGET_ADJUSTMENT;
2145 m_bodyRot = sitTargetOrient; 2278 m_bodyRot = sitTargetOrient;
2146 //Rotation = sitTargetOrient;
2147 m_parentPosition = part.AbsolutePosition; 2279 m_parentPosition = part.AbsolutePosition;
2148 2280 part.IsOccupied = true;
2149 //SendTerseUpdateToAllClients();
2150 } 2281 }
2151 else 2282 else
2152 { 2283 {
2153 m_pos -= part.AbsolutePosition; 2284 // if m_avUnscriptedSitPos is zero then Av sits above center
2285 // Else Av sits at m_avUnscriptedSitPos
2286
2287 // Non-scripted sit by Kitto Flora 21Nov09
2288 // Calculate angle of line from prim to Av
2289 Quaternion partIRot;
2290// if (part.LinkNum == 1)
2291// { // Root prim of linkset
2292// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2293// }
2294// else
2295// { // single or child prim
2296 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2297// }
2298 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2299 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2300 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2301 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2302 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2303 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2304 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2305 // Av sits at world euler <0,0, z>, translated by part rotation
2306 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2307
2154 m_parentPosition = part.AbsolutePosition; 2308 m_parentPosition = part.AbsolutePosition;
2155 } 2309 part.IsOccupied = true;
2310 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2311 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2312 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2313 m_avUnscriptedSitPos; // adds click offset, if any
2314 //Set up raytrace to find top surface of prim
2315 Vector3 size = part.Scale;
2316 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2317 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2318 Vector3 down = new Vector3(0f, 0f, -1f);
2319//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2320 m_scene.PhysicsScene.RaycastWorld(
2321 start, // Vector3 position,
2322 down, // Vector3 direction,
2323 mag, // float length,
2324 SitAltitudeCallback); // retMethod
2325 } // end scripted/not
2156 } 2326 }
2157 else 2327 else // no Av
2158 { 2328 {
2159 return; 2329 return;
2160 } 2330 }
@@ -2166,11 +2336,36 @@ namespace OpenSim.Region.Framework.Scenes
2166 2336
2167 Animator.TrySetMovementAnimation(sitAnimation); 2337 Animator.TrySetMovementAnimation(sitAnimation);
2168 SendFullUpdateToAllClients(); 2338 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 } 2339 }
2340
2341 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2342 {
2343 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2344 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2345 if(hitYN)
2346 {
2347 // m_pos = Av offset from prim center to make look like on center
2348 // m_parentPosition = Actual center pos of prim
2349 // collisionPoint = spot on prim where we want to sit
2350 // collisionPoint.Z = global sit surface height
2351 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2352 Quaternion partIRot;
2353// if (part.LinkNum == 1)
2354/// { // Root prim of linkset
2355// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2356// }
2357// else
2358// { // single or child prim
2359 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2360// }
2361 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2362 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2363//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2364 m_pos += offset;
2365// ControllingClient.SendClearFollowCamProperties(part.UUID);
2366
2367 }
2368 } // End SitAltitudeCallback KF.
2174 2369
2175 /// <summary> 2370 /// <summary>
2176 /// Event handler for the 'Always run' setting on the client 2371 /// Event handler for the 'Always run' setting on the client
@@ -2200,7 +2395,7 @@ namespace OpenSim.Region.Framework.Scenes
2200 /// </summary> 2395 /// </summary>
2201 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2396 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2202 /// <param name="rotation">The direction in which this avatar should now face. 2397 /// <param name="rotation">The direction in which this avatar should now face.
2203 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2398 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2204 { 2399 {
2205 if (m_isChildAgent) 2400 if (m_isChildAgent)
2206 { 2401 {
@@ -2274,7 +2469,7 @@ namespace OpenSim.Region.Framework.Scenes
2274 2469
2275 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2470 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2276 m_forceToApply = direc; 2471 m_forceToApply = direc;
2277 2472 m_isNudging = Nudging;
2278 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2473 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2279 } 2474 }
2280 2475
@@ -2289,7 +2484,7 @@ namespace OpenSim.Region.Framework.Scenes
2289 const float POSITION_TOLERANCE = 0.05f; 2484 const float POSITION_TOLERANCE = 0.05f;
2290 //const int TIME_MS_TOLERANCE = 3000; 2485 //const int TIME_MS_TOLERANCE = 3000;
2291 2486
2292 SendPrimUpdates(); 2487
2293 2488
2294 if (m_newCoarseLocations) 2489 if (m_newCoarseLocations)
2295 { 2490 {
@@ -2325,6 +2520,9 @@ namespace OpenSim.Region.Framework.Scenes
2325 CheckForBorderCrossing(); 2520 CheckForBorderCrossing();
2326 CheckForSignificantMovement(); // sends update to the modules. 2521 CheckForSignificantMovement(); // sends update to the modules.
2327 } 2522 }
2523
2524 //Sending prim updates AFTER the avatar terse updates are sent
2525 SendPrimUpdates();
2328 } 2526 }
2329 2527
2330 #endregion 2528 #endregion
@@ -3225,14 +3423,25 @@ namespace OpenSim.Region.Framework.Scenes
3225 { 3423 {
3226 if (m_forceToApply.HasValue) 3424 if (m_forceToApply.HasValue)
3227 { 3425 {
3228 Vector3 force = m_forceToApply.Value;
3229 3426
3427 Vector3 force = m_forceToApply.Value;
3230 m_updateflag = true; 3428 m_updateflag = true;
3231// movementvector = force;
3232 Velocity = force; 3429 Velocity = force;
3233 3430
3234 m_forceToApply = null; 3431 m_forceToApply = null;
3235 } 3432 }
3433 else
3434 {
3435 if (m_isNudging)
3436 {
3437 Vector3 force = Vector3.Zero;
3438
3439 m_updateflag = true;
3440 Velocity = force;
3441 m_isNudging = false;
3442 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3443 }
3444 }
3236 } 3445 }
3237 3446
3238 public override void SetText(string text, Vector3 color, double alpha) 3447 public override void SetText(string text, Vector3 color, double alpha)
@@ -3283,18 +3492,29 @@ namespace OpenSim.Region.Framework.Scenes
3283 { 3492 {
3284 if (e == null) 3493 if (e == null)
3285 return; 3494 return;
3286 3495
3287 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3496 // 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 3497 // as of this comment the interval is set in AddToPhysicalScene
3290 if (Animator!=null) 3498 if (Animator!=null)
3291 Animator.UpdateMovementAnimations(); 3499 {
3500 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3501 { // else its will lock out other animation changes, like ground sit.
3502 Animator.UpdateMovementAnimations();
3503 m_updateCount--;
3504 }
3505 }
3292 3506
3293 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3507 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3294 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3508 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3295 3509
3296 CollisionPlane = Vector4.UnitW; 3510 CollisionPlane = Vector4.UnitW;
3297 3511
3512 if (m_lastColCount != coldata.Count)
3513 {
3514 m_updateCount = UPDATE_COUNT;
3515 m_lastColCount = coldata.Count;
3516 }
3517
3298 if (coldata.Count != 0 && Animator != null) 3518 if (coldata.Count != 0 && Animator != null)
3299 { 3519 {
3300 switch (Animator.CurrentMovementAnimation) 3520 switch (Animator.CurrentMovementAnimation)
@@ -3931,5 +4151,16 @@ namespace OpenSim.Region.Framework.Scenes
3931 m_reprioritization_called = false; 4151 m_reprioritization_called = false;
3932 } 4152 }
3933 } 4153 }
4154
4155 private Vector3 Quat2Euler(Quaternion rot){
4156 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4157 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4158 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4159 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4160 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4161 return(new Vector3(x,y,z));
4162 }
4163
4164
3934 } 4165 }
3935} 4166}