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.cs571
1 files changed, 400 insertions, 171 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 4973663..123d6f3 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
@@ -680,10 +690,7 @@ namespace OpenSim.Region.Framework.Scenes
680 m_reprioritization_timer.AutoReset = false; 690 m_reprioritization_timer.AutoReset = false;
681 691
682 AdjustKnownSeeds(); 692 AdjustKnownSeeds();
683
684 // TODO: I think, this won't send anything, as we are still a child here...
685 Animator.TrySetMovementAnimation("STAND"); 693 Animator.TrySetMovementAnimation("STAND");
686
687 // we created a new ScenePresence (a new child agent) in a fresh region. 694 // we created a new ScenePresence (a new child agent) in a fresh region.
688 // Request info about all the (root) agents in this region 695 // 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) 696 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -739,25 +746,47 @@ namespace OpenSim.Region.Framework.Scenes
739 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 746 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
740 Dir_Vectors[4] = Vector3.UnitZ; //UP 747 Dir_Vectors[4] = Vector3.UnitZ; //UP
741 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 748 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
742 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 749 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
743 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 750 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
744 Dir_Vectors[7] = -Vector3.UnitX; //BACK 751 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
752 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
753 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
745 } 754 }
746 755
747 private Vector3[] GetWalkDirectionVectors() 756 private Vector3[] GetWalkDirectionVectors()
748 { 757 {
749 Vector3[] vector = new Vector3[9]; 758 Vector3[] vector = new Vector3[11];
750 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 759 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 760 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
752 vector[2] = Vector3.UnitY; //LEFT 761 vector[2] = Vector3.UnitY; //LEFT
753 vector[3] = -Vector3.UnitY; //RIGHT 762 vector[3] = -Vector3.UnitY; //RIGHT
754 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 763 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 764 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 765 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 766 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 767 vector[8] = Vector3.UnitY; //LEFT_NUDGE
768 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
769 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
759 return vector; 770 return vector;
760 } 771 }
772
773 private bool[] GetDirectionIsNudge()
774 {
775 bool[] isNudge = new bool[11];
776 isNudge[0] = false; //FORWARD
777 isNudge[1] = false; //BACK
778 isNudge[2] = false; //LEFT
779 isNudge[3] = false; //RIGHT
780 isNudge[4] = false; //UP
781 isNudge[5] = false; //DOWN
782 isNudge[6] = true; //FORWARD_NUDGE
783 isNudge[7] = true; //BACK_NUDGE
784 isNudge[8] = true; //LEFT_NUDGE
785 isNudge[9] = true; //RIGHT_NUDGE
786 isNudge[10] = true; //DOWN_Nudge
787 return isNudge;
788 }
789
761 790
762 #endregion 791 #endregion
763 792
@@ -826,9 +855,24 @@ namespace OpenSim.Region.Framework.Scenes
826 { 855 {
827 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 856 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
828 pos.Y = crossedBorder.BorderLine.Z - 1; 857 pos.Y = crossedBorder.BorderLine.Z - 1;
858 }
859
860 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
861 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
862 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
863 if (KnownChildRegionHandles.Count == 0)
864 {
865 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
866 if (land != null)
867 {
868 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
869 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)
870 {
871 pos = land.LandData.UserLocation;
872 }
873 }
829 } 874 }
830 875
831
832 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 876 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
833 { 877 {
834 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); 878 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
@@ -988,9 +1032,10 @@ namespace OpenSim.Region.Framework.Scenes
988 public void Teleport(Vector3 pos) 1032 public void Teleport(Vector3 pos)
989 { 1033 {
990 bool isFlying = false; 1034 bool isFlying = false;
991 if (m_physicsActor != null)
992 isFlying = m_physicsActor.Flying;
993 1035
1036 if (m_physicsActor != null)
1037 isFlying = m_physicsActor.Flying;
1038
994 RemoveFromPhysicalScene(); 1039 RemoveFromPhysicalScene();
995 Velocity = Vector3.Zero; 1040 Velocity = Vector3.Zero;
996 AbsolutePosition = pos; 1041 AbsolutePosition = pos;
@@ -1001,7 +1046,8 @@ namespace OpenSim.Region.Framework.Scenes
1001 SetHeight(m_appearance.AvatarHeight); 1046 SetHeight(m_appearance.AvatarHeight);
1002 } 1047 }
1003 1048
1004 SendTerseUpdateToAllClients(); 1049 SendTerseUpdateToAllClients();
1050
1005 } 1051 }
1006 1052
1007 public void TeleportWithMomentum(Vector3 pos) 1053 public void TeleportWithMomentum(Vector3 pos)
@@ -1046,7 +1092,9 @@ namespace OpenSim.Region.Framework.Scenes
1046 { 1092 {
1047 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1093 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1048 } 1094 }
1049 1095
1096 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1097
1050 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1098 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))); 1099 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1052 } 1100 }
@@ -1280,7 +1328,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); 1328 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1281 } 1329 }
1282 } 1330 }
1283
1284 lock (scriptedcontrols) 1331 lock (scriptedcontrols)
1285 { 1332 {
1286 if (scriptedcontrols.Count > 0) 1333 if (scriptedcontrols.Count > 0)
@@ -1295,12 +1342,8 @@ namespace OpenSim.Region.Framework.Scenes
1295 1342
1296 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1343 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1297 { 1344 {
1298 // TODO: This doesn't prevent the user from walking yet. 1345 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 1346 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 } 1347 }
1305 1348
1306 // In the future, these values might need to go global. 1349 // In the future, these values might need to go global.
@@ -1350,6 +1393,11 @@ namespace OpenSim.Region.Framework.Scenes
1350 update_rotation = true; 1393 update_rotation = true;
1351 } 1394 }
1352 1395
1396 //guilty until proven innocent..
1397 bool Nudging = true;
1398 //Basically, if there is at least one non-nudge control then we don't need
1399 //to worry about stopping the avatar
1400
1353 if (m_parentID == 0) 1401 if (m_parentID == 0)
1354 { 1402 {
1355 bool bAllowUpdateMoveToPosition = false; 1403 bool bAllowUpdateMoveToPosition = false;
@@ -1364,9 +1412,12 @@ namespace OpenSim.Region.Framework.Scenes
1364 else 1412 else
1365 dirVectors = Dir_Vectors; 1413 dirVectors = Dir_Vectors;
1366 1414
1367 // The fact that m_movementflag is a byte needs to be fixed 1415 bool[] isNudge = GetDirectionIsNudge();
1368 // it really should be a uint 1416
1369 uint nudgehack = 250; 1417
1418
1419
1420
1370 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1421 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1371 { 1422 {
1372 if (((uint)flags & (uint)DCF) != 0) 1423 if (((uint)flags & (uint)DCF) != 0)
@@ -1376,40 +1427,28 @@ namespace OpenSim.Region.Framework.Scenes
1376 try 1427 try
1377 { 1428 {
1378 agent_control_v3 += dirVectors[i]; 1429 agent_control_v3 += dirVectors[i];
1379 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1430 if (isNudge[i] == false)
1431 {
1432 Nudging = false;
1433 }
1380 } 1434 }
1381 catch (IndexOutOfRangeException) 1435 catch (IndexOutOfRangeException)
1382 { 1436 {
1383 // Why did I get this? 1437 // Why did I get this?
1384 } 1438 }
1385 1439
1386 if ((m_movementflag & (byte)(uint)DCF) == 0) 1440 if ((m_movementflag & (uint)DCF) == 0)
1387 { 1441 {
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; 1442 m_movementflag += (byte)(uint)DCF;
1393 update_movementflag = true; 1443 update_movementflag = true;
1394 } 1444 }
1395 } 1445 }
1396 else 1446 else
1397 { 1447 {
1398 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1448 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 { 1449 {
1403 m_movementflag -= ((byte)(uint)DCF); 1450 m_movementflag -= (byte)(uint)DCF;
1404
1405 update_movementflag = true; 1451 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 } 1452 }
1414 else 1453 else
1415 { 1454 {
@@ -1453,6 +1492,9 @@ namespace OpenSim.Region.Framework.Scenes
1453 // Ignore z component of vector 1492 // Ignore z component of vector
1454 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1493 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1455 LocalVectorToTarget2D.Normalize(); 1494 LocalVectorToTarget2D.Normalize();
1495
1496 //We're not nudging
1497 Nudging = false;
1456 agent_control_v3 += LocalVectorToTarget2D; 1498 agent_control_v3 += LocalVectorToTarget2D;
1457 1499
1458 // update avatar movement flags. the avatar coordinate system is as follows: 1500 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1541,13 +1583,13 @@ namespace OpenSim.Region.Framework.Scenes
1541 // m_log.DebugFormat( 1583 // m_log.DebugFormat(
1542 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1584 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1543 1585
1544 AddNewMovement(agent_control_v3, q); 1586 AddNewMovement(agent_control_v3, q, Nudging);
1545 1587
1546 1588
1547 } 1589 }
1548 } 1590 }
1549 1591
1550 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1592 if (update_movementflag)
1551 Animator.UpdateMovementAnimations(); 1593 Animator.UpdateMovementAnimations();
1552 1594
1553 m_scene.EventManager.TriggerOnClientMovement(this); 1595 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1562,7 +1604,6 @@ namespace OpenSim.Region.Framework.Scenes
1562 m_sitAtAutoTarget = false; 1604 m_sitAtAutoTarget = false;
1563 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1605 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1564 //proxy.PCode = (byte)PCode.ParticleSystem; 1606 //proxy.PCode = (byte)PCode.ParticleSystem;
1565
1566 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1607 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1567 proxyObjectGroup.AttachToScene(m_scene); 1608 proxyObjectGroup.AttachToScene(m_scene);
1568 1609
@@ -1604,7 +1645,7 @@ namespace OpenSim.Region.Framework.Scenes
1604 } 1645 }
1605 m_moveToPositionInProgress = true; 1646 m_moveToPositionInProgress = true;
1606 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1647 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1607 } 1648 }
1608 catch (Exception ex) 1649 catch (Exception ex)
1609 { 1650 {
1610 //Why did I get this error? 1651 //Why did I get this error?
@@ -1626,7 +1667,7 @@ namespace OpenSim.Region.Framework.Scenes
1626 Velocity = Vector3.Zero; 1667 Velocity = Vector3.Zero;
1627 SendFullUpdateToAllClients(); 1668 SendFullUpdateToAllClients();
1628 1669
1629 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1670 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1630 } 1671 }
1631 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1672 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1632 m_requestedSitTargetUUID = UUID.Zero; 1673 m_requestedSitTargetUUID = UUID.Zero;
@@ -1659,55 +1700,84 @@ namespace OpenSim.Region.Framework.Scenes
1659 /// </summary> 1700 /// </summary>
1660 public void StandUp() 1701 public void StandUp()
1661 { 1702 {
1662 if (SitGround)
1663 SitGround = false;
1664
1665 if (m_parentID != 0) 1703 if (m_parentID != 0)
1666 { 1704 {
1667 m_log.Debug("StandupCode Executed");
1668 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1705 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1669 if (part != null) 1706 if (part != null)
1670 { 1707 {
1708 part.TaskInventory.LockItemsForRead(true);
1671 TaskInventoryDictionary taskIDict = part.TaskInventory; 1709 TaskInventoryDictionary taskIDict = part.TaskInventory;
1672 if (taskIDict != null) 1710 if (taskIDict != null)
1673 { 1711 {
1674 lock (taskIDict) 1712 foreach (UUID taskID in taskIDict.Keys)
1675 { 1713 {
1676 foreach (UUID taskID in taskIDict.Keys) 1714 UnRegisterControlEventsToScript(LocalId, taskID);
1677 { 1715 taskIDict[taskID].PermsMask &= ~(
1678 UnRegisterControlEventsToScript(LocalId, taskID); 1716 2048 | //PERMISSION_CONTROL_CAMERA
1679 taskIDict[taskID].PermsMask &= ~( 1717 4); // PERMISSION_TAKE_CONTROLS
1680 2048 | //PERMISSION_CONTROL_CAMERA
1681 4); // PERMISSION_TAKE_CONTROLS
1682 }
1683 } 1718 }
1684
1685 } 1719 }
1720 part.TaskInventory.LockItemsForRead(false);
1686 // Reset sit target. 1721 // Reset sit target.
1687 if (part.GetAvatarOnSitTarget() == UUID) 1722 if (part.GetAvatarOnSitTarget() == UUID)
1688 part.SetAvatarOnSitTarget(UUID.Zero); 1723 part.SetAvatarOnSitTarget(UUID.Zero);
1689
1690 m_parentPosition = part.GetWorldPosition(); 1724 m_parentPosition = part.GetWorldPosition();
1691 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1725 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1692 } 1726 }
1693 1727 // part.GetWorldRotation() is the rotation of the object being sat on
1694 if (m_physicsActor == null) 1728 // Rotation is the sittiing Av's rotation
1695 { 1729
1696 AddToPhysicalScene(false); 1730 Quaternion partRot;
1731// if (part.LinkNum == 1)
1732// { // Root prim of linkset
1733// partRot = part.ParentGroup.RootPart.RotationOffset;
1734// }
1735// else
1736// { // single or child prim
1737
1738// }
1739 if (part == null) //CW: Part may be gone. llDie() for example.
1740 {
1741 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1742 }
1743 else
1744 {
1745 partRot = part.GetWorldRotation();
1697 } 1746 }
1698 1747
1699 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1748 Quaternion partIRot = Quaternion.Inverse(partRot);
1700 m_parentPosition = Vector3.Zero; 1749
1750 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1751 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1701 1752
1702 m_parentID = 0; 1753
1754 if (m_physicsActor == null)
1755 {
1756 AddToPhysicalScene(false);
1757 }
1758 //CW: If the part isn't null then we can set the current position
1759 if (part != null)
1760 {
1761 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1762 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1763 part.IsOccupied = false;
1764 }
1765 else
1766 {
1767 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1768 AbsolutePosition = m_lastWorldPosition;
1769 }
1770
1771 m_parentPosition = Vector3.Zero;
1772 m_parentID = 0;
1703 SendFullUpdateToAllClients(); 1773 SendFullUpdateToAllClients();
1704 m_requestedSitTargetID = 0; 1774 m_requestedSitTargetID = 0;
1775
1705 if ((m_physicsActor != null) && (m_avHeight > 0)) 1776 if ((m_physicsActor != null) && (m_avHeight > 0))
1706 { 1777 {
1707 SetHeight(m_avHeight); 1778 SetHeight(m_avHeight);
1708 } 1779 }
1709 } 1780 }
1710
1711 Animator.TrySetMovementAnimation("STAND"); 1781 Animator.TrySetMovementAnimation("STAND");
1712 } 1782 }
1713 1783
@@ -1738,13 +1808,9 @@ namespace OpenSim.Region.Framework.Scenes
1738 Vector3 avSitOffSet = part.SitTargetPosition; 1808 Vector3 avSitOffSet = part.SitTargetPosition;
1739 Quaternion avSitOrientation = part.SitTargetOrientation; 1809 Quaternion avSitOrientation = part.SitTargetOrientation;
1740 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1810 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1741 1811 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1742 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1812 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1743 bool SitTargetisSet = 1813 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 { 1814 {
1749 //switch the target to this prim 1815 //switch the target to this prim
1750 return part; 1816 return part;
@@ -1758,84 +1824,152 @@ namespace OpenSim.Region.Framework.Scenes
1758 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1824 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1759 { 1825 {
1760 bool autopilot = true; 1826 bool autopilot = true;
1827 Vector3 autopilotTarget = new Vector3();
1828 Quaternion sitOrientation = Quaternion.Identity;
1761 Vector3 pos = new Vector3(); 1829 Vector3 pos = new Vector3();
1762 Quaternion sitOrientation = pSitOrientation;
1763 Vector3 cameraEyeOffset = Vector3.Zero; 1830 Vector3 cameraEyeOffset = Vector3.Zero;
1764 Vector3 cameraAtOffset = Vector3.Zero; 1831 Vector3 cameraAtOffset = Vector3.Zero;
1765 bool forceMouselook = false; 1832 bool forceMouselook = false;
1766 1833
1767 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1834 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1768 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1835 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1769 if (part != null) 1836 if (part == null) return;
1770 { 1837
1771 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1838 // 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 1839 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1773 1840
1774 // Is a sit target available? 1841 // part is the prim to sit on
1775 Vector3 avSitOffSet = part.SitTargetPosition; 1842 // offset is the world-ref vector distance from that prim center to the click-spot
1776 Quaternion avSitOrientation = part.SitTargetOrientation; 1843 // UUID is the UUID of the Avatar doing the clicking
1777 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1844
1778 1845 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1779 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1846
1780 bool SitTargetisSet = 1847 // Is a sit target available?
1781 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1848 Vector3 avSitOffSet = part.SitTargetPosition;
1782 ( 1849 Quaternion avSitOrientation = part.SitTargetOrientation;
1783 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1850
1784 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1851 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 1852 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1786 ) 1853 Quaternion partRot;
1787 )); 1854// if (part.LinkNum == 1)
1788 1855// { // Root prim of linkset
1789 if (SitTargetisSet && SitTargetUnOccupied) 1856// partRot = part.ParentGroup.RootPart.RotationOffset;
1790 { 1857// }
1791 part.SetAvatarOnSitTarget(UUID); 1858// else
1792 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1859// { // single or child prim
1793 sitOrientation = avSitOrientation; 1860 partRot = part.GetWorldRotation();
1794 autopilot = false; 1861// }
1795 } 1862 Quaternion partIRot = Quaternion.Inverse(partRot);
1796 1863//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1797 pos = part.AbsolutePosition + offset; 1864 // Sit analysis rewritten by KF 091125
1798 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1865 if (SitTargetisSet) // scipted sit
1799 //{ 1866 {
1800 // offset = pos; 1867 if (!part.IsOccupied)
1801 //autopilot = false; 1868 {
1802 //} 1869//Console.WriteLine("Scripted, unoccupied");
1803 if (m_physicsActor != null) 1870 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1804 { 1871 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 1872 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1806 // We can remove the physicsActor until they stand up. 1873 autopilot = false; // Jump direct to scripted llSitPos()
1807 m_sitAvatarHeight = m_physicsActor.Size.Z; 1874 }
1808 1875 else
1809 if (autopilot) 1876 {
1810 { 1877//Console.WriteLine("Scripted, occupied");
1811 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1878 return;
1812 { 1879 }
1813 autopilot = false; 1880 }
1881 else // Not Scripted
1882 {
1883 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1884 {
1885 // large prim & offset, ignore if other Avs sitting
1886// offset.Z -= 0.05f;
1887 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1888 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1889
1890//Console.WriteLine(" offset ={0}", offset);
1891//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1892//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1893
1894 }
1895 else // small offset
1896 {
1897//Console.WriteLine("Small offset");
1898 if (!part.IsOccupied)
1899 {
1900 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1901 autopilotTarget = part.AbsolutePosition;
1902 }
1903 else return; // occupied small
1904 } // end large/small
1905 } // end Scripted/not
1906 cameraAtOffset = part.GetCameraAtOffset();
1907 cameraEyeOffset = part.GetCameraEyeOffset();
1908 forceMouselook = part.GetForceMouselook();
1909 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1910 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1814 1911
1815 RemoveFromPhysicalScene(); 1912 if (m_physicsActor != null)
1816 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1913 {
1817 } 1914 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1818 } 1915 // We can remove the physicsActor until they stand up.
1819 else 1916 m_sitAvatarHeight = m_physicsActor.Size.Z;
1917 if (autopilot)
1918 { // its not a scripted sit
1919// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1920 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1820 { 1921 {
1922 autopilot = false; // close enough
1923 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1924 Not using the part's position because returning the AV to the last known standing
1925 position is likely to be more friendly, isn't it? */
1821 RemoveFromPhysicalScene(); 1926 RemoveFromPhysicalScene();
1822 } 1927 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1928 } // else the autopilot will get us close
1929 }
1930 else
1931 { // its a scripted sit
1932 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1933 I *am* using the part's position this time because we have no real idea how far away
1934 the avatar is from the sit target. */
1935 RemoveFromPhysicalScene();
1823 } 1936 }
1824
1825 cameraAtOffset = part.GetCameraAtOffset();
1826 cameraEyeOffset = part.GetCameraEyeOffset();
1827 forceMouselook = part.GetForceMouselook();
1828 } 1937 }
1829 1938 else return; // physactor is null!
1830 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1939
1831 m_requestedSitTargetUUID = targetID; 1940 Vector3 offsetr; // = offset * partIRot;
1941 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1942 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1943 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1944 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1945 offsetr = offset * partIRot;
1946//
1947 // else
1948 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1949 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1950 // (offset * partRot);
1951 // }
1952
1953//Console.WriteLine(" ");
1954//Console.WriteLine("link number ={0}", part.LinkNum);
1955//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1956//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1957//Console.WriteLine("Click offst ={0}", offset);
1958//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1959//Console.WriteLine("offsetr ={0}", offsetr);
1960//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1961//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1962
1963 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1964 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1832 // This calls HandleAgentSit twice, once from here, and the client calls 1965 // This calls HandleAgentSit twice, once from here, and the client calls
1833 // HandleAgentSit itself after it gets to the location 1966 // HandleAgentSit itself after it gets to the location
1834 // It doesn't get to the location until we've moved them there though 1967 // It doesn't get to the location until we've moved them there though
1835 // which happens in HandleAgentSit :P 1968 // which happens in HandleAgentSit :P
1836 m_autopilotMoving = autopilot; 1969 m_autopilotMoving = autopilot;
1837 m_autoPilotTarget = pos; 1970 m_autoPilotTarget = autopilotTarget;
1838 m_sitAtAutoTarget = autopilot; 1971 m_sitAtAutoTarget = autopilot;
1972 m_initialSitTarget = autopilotTarget;
1839 if (!autopilot) 1973 if (!autopilot)
1840 HandleAgentSit(remoteClient, UUID); 1974 HandleAgentSit(remoteClient, UUID);
1841 } 1975 }
@@ -2130,31 +2264,65 @@ namespace OpenSim.Region.Framework.Scenes
2130 { 2264 {
2131 if (part != null) 2265 if (part != null)
2132 { 2266 {
2267//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2133 if (part.GetAvatarOnSitTarget() == UUID) 2268 if (part.GetAvatarOnSitTarget() == UUID)
2134 { 2269 {
2270//Console.WriteLine("Scripted Sit");
2271 // Scripted sit
2135 Vector3 sitTargetPos = part.SitTargetPosition; 2272 Vector3 sitTargetPos = part.SitTargetPosition;
2136 Quaternion sitTargetOrient = part.SitTargetOrientation; 2273 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); 2274 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2144 m_pos += SIT_TARGET_ADJUSTMENT; 2275 m_pos += SIT_TARGET_ADJUSTMENT;
2145 m_bodyRot = sitTargetOrient; 2276 m_bodyRot = sitTargetOrient;
2146 //Rotation = sitTargetOrient;
2147 m_parentPosition = part.AbsolutePosition; 2277 m_parentPosition = part.AbsolutePosition;
2148 2278 part.IsOccupied = true;
2149 //SendTerseUpdateToAllClients();
2150 } 2279 }
2151 else 2280 else
2152 { 2281 {
2153 m_pos -= part.AbsolutePosition; 2282 // if m_avUnscriptedSitPos is zero then Av sits above center
2283 // Else Av sits at m_avUnscriptedSitPos
2284
2285 // Non-scripted sit by Kitto Flora 21Nov09
2286 // Calculate angle of line from prim to Av
2287 Quaternion partIRot;
2288// if (part.LinkNum == 1)
2289// { // Root prim of linkset
2290// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2291// }
2292// else
2293// { // single or child prim
2294 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2295// }
2296 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2297 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2298 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2299 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2300 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2301 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2302 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2303 // Av sits at world euler <0,0, z>, translated by part rotation
2304 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2305
2154 m_parentPosition = part.AbsolutePosition; 2306 m_parentPosition = part.AbsolutePosition;
2155 } 2307 part.IsOccupied = true;
2308 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2309 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2310 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2311 m_avUnscriptedSitPos; // adds click offset, if any
2312 //Set up raytrace to find top surface of prim
2313 Vector3 size = part.Scale;
2314 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2315 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2316 Vector3 down = new Vector3(0f, 0f, -1f);
2317//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2318 m_scene.PhysicsScene.RaycastWorld(
2319 start, // Vector3 position,
2320 down, // Vector3 direction,
2321 mag, // float length,
2322 SitAltitudeCallback); // retMethod
2323 } // end scripted/not
2156 } 2324 }
2157 else 2325 else // no Av
2158 { 2326 {
2159 return; 2327 return;
2160 } 2328 }
@@ -2166,11 +2334,36 @@ namespace OpenSim.Region.Framework.Scenes
2166 2334
2167 Animator.TrySetMovementAnimation(sitAnimation); 2335 Animator.TrySetMovementAnimation(sitAnimation);
2168 SendFullUpdateToAllClients(); 2336 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 } 2337 }
2338
2339 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2340 {
2341 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2342 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2343 if(hitYN)
2344 {
2345 // m_pos = Av offset from prim center to make look like on center
2346 // m_parentPosition = Actual center pos of prim
2347 // collisionPoint = spot on prim where we want to sit
2348 // collisionPoint.Z = global sit surface height
2349 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2350 Quaternion partIRot;
2351// if (part.LinkNum == 1)
2352/// { // Root prim of linkset
2353// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2354// }
2355// else
2356// { // single or child prim
2357 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2358// }
2359 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2360 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2361//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2362 m_pos += offset;
2363// ControllingClient.SendClearFollowCamProperties(part.UUID);
2364
2365 }
2366 } // End SitAltitudeCallback KF.
2174 2367
2175 /// <summary> 2368 /// <summary>
2176 /// Event handler for the 'Always run' setting on the client 2369 /// Event handler for the 'Always run' setting on the client
@@ -2200,7 +2393,7 @@ namespace OpenSim.Region.Framework.Scenes
2200 /// </summary> 2393 /// </summary>
2201 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2394 /// <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. 2395 /// <param name="rotation">The direction in which this avatar should now face.
2203 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2396 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2204 { 2397 {
2205 if (m_isChildAgent) 2398 if (m_isChildAgent)
2206 { 2399 {
@@ -2274,7 +2467,7 @@ namespace OpenSim.Region.Framework.Scenes
2274 2467
2275 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2468 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2276 m_forceToApply = direc; 2469 m_forceToApply = direc;
2277 2470 m_isNudging = Nudging;
2278 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2471 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2279 } 2472 }
2280 2473
@@ -2289,7 +2482,7 @@ namespace OpenSim.Region.Framework.Scenes
2289 const float POSITION_TOLERANCE = 0.05f; 2482 const float POSITION_TOLERANCE = 0.05f;
2290 //const int TIME_MS_TOLERANCE = 3000; 2483 //const int TIME_MS_TOLERANCE = 3000;
2291 2484
2292 SendPrimUpdates(); 2485
2293 2486
2294 if (m_newCoarseLocations) 2487 if (m_newCoarseLocations)
2295 { 2488 {
@@ -2325,6 +2518,9 @@ namespace OpenSim.Region.Framework.Scenes
2325 CheckForBorderCrossing(); 2518 CheckForBorderCrossing();
2326 CheckForSignificantMovement(); // sends update to the modules. 2519 CheckForSignificantMovement(); // sends update to the modules.
2327 } 2520 }
2521
2522 //Sending prim updates AFTER the avatar terse updates are sent
2523 SendPrimUpdates();
2328 } 2524 }
2329 2525
2330 #endregion 2526 #endregion
@@ -3225,14 +3421,25 @@ namespace OpenSim.Region.Framework.Scenes
3225 { 3421 {
3226 if (m_forceToApply.HasValue) 3422 if (m_forceToApply.HasValue)
3227 { 3423 {
3228 Vector3 force = m_forceToApply.Value;
3229 3424
3425 Vector3 force = m_forceToApply.Value;
3230 m_updateflag = true; 3426 m_updateflag = true;
3231// movementvector = force;
3232 Velocity = force; 3427 Velocity = force;
3233 3428
3234 m_forceToApply = null; 3429 m_forceToApply = null;
3235 } 3430 }
3431 else
3432 {
3433 if (m_isNudging)
3434 {
3435 Vector3 force = Vector3.Zero;
3436
3437 m_updateflag = true;
3438 Velocity = force;
3439 m_isNudging = false;
3440 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3441 }
3442 }
3236 } 3443 }
3237 3444
3238 public override void SetText(string text, Vector3 color, double alpha) 3445 public override void SetText(string text, Vector3 color, double alpha)
@@ -3283,18 +3490,29 @@ namespace OpenSim.Region.Framework.Scenes
3283 { 3490 {
3284 if (e == null) 3491 if (e == null)
3285 return; 3492 return;
3286 3493
3287 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3494 // 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 3495 // as of this comment the interval is set in AddToPhysicalScene
3290 if (Animator!=null) 3496 if (Animator!=null)
3291 Animator.UpdateMovementAnimations(); 3497 {
3498 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3499 { // else its will lock out other animation changes, like ground sit.
3500 Animator.UpdateMovementAnimations();
3501 m_updateCount--;
3502 }
3503 }
3292 3504
3293 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3505 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3294 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3506 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3295 3507
3296 CollisionPlane = Vector4.UnitW; 3508 CollisionPlane = Vector4.UnitW;
3297 3509
3510 if (m_lastColCount != coldata.Count)
3511 {
3512 m_updateCount = UPDATE_COUNT;
3513 m_lastColCount = coldata.Count;
3514 }
3515
3298 if (coldata.Count != 0 && Animator != null) 3516 if (coldata.Count != 0 && Animator != null)
3299 { 3517 {
3300 switch (Animator.CurrentMovementAnimation) 3518 switch (Animator.CurrentMovementAnimation)
@@ -3931,5 +4149,16 @@ namespace OpenSim.Region.Framework.Scenes
3931 m_reprioritization_called = false; 4149 m_reprioritization_called = false;
3932 } 4150 }
3933 } 4151 }
4152
4153 private Vector3 Quat2Euler(Quaternion rot){
4154 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4155 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4156 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4157 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4158 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4159 return(new Vector3(x,y,z));
4160 }
4161
4162
3934 } 4163 }
3935} 4164}