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.cs580
1 files changed, 408 insertions, 172 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index b5f6217..5c54616 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
@@ -157,7 +161,6 @@ namespace OpenSim.Region.Framework.Scenes
157 private int m_perfMonMS; 161 private int m_perfMonMS;
158 162
159 private bool m_setAlwaysRun; 163 private bool m_setAlwaysRun;
160
161 private bool m_forceFly; 164 private bool m_forceFly;
162 private bool m_flyDisabled; 165 private bool m_flyDisabled;
163 166
@@ -183,7 +186,8 @@ namespace OpenSim.Region.Framework.Scenes
183 protected RegionInfo m_regionInfo; 186 protected RegionInfo m_regionInfo;
184 protected ulong crossingFromRegion; 187 protected ulong crossingFromRegion;
185 188
186 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 189 private readonly Vector3[] Dir_Vectors = new Vector3[11];
190 private bool m_isNudging = false;
187 191
188 // Position of agent's camera in world (region cordinates) 192 // Position of agent's camera in world (region cordinates)
189 protected Vector3 m_CameraCenter; 193 protected Vector3 m_CameraCenter;
@@ -208,6 +212,7 @@ namespace OpenSim.Region.Framework.Scenes
208 private bool m_autopilotMoving; 212 private bool m_autopilotMoving;
209 private Vector3 m_autoPilotTarget; 213 private Vector3 m_autoPilotTarget;
210 private bool m_sitAtAutoTarget; 214 private bool m_sitAtAutoTarget;
215 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
211 216
212 private string m_nextSitAnimation = String.Empty; 217 private string m_nextSitAnimation = String.Empty;
213 218
@@ -218,6 +223,9 @@ namespace OpenSim.Region.Framework.Scenes
218 private bool m_followCamAuto; 223 private bool m_followCamAuto;
219 224
220 private int m_movementUpdateCount; 225 private int m_movementUpdateCount;
226 private int m_lastColCount = -1; //KF: Look for Collision chnages
227 private int m_updateCount = 0; //KF: Update Anims for a while
228 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
221 229
222 private const int NumMovementsBetweenRayCast = 5; 230 private const int NumMovementsBetweenRayCast = 5;
223 231
@@ -246,7 +254,9 @@ namespace OpenSim.Region.Framework.Scenes
246 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 254 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
247 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 255 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
248 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 256 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
249 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 257 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
258 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
259 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
250 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 260 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
251 } 261 }
252 262
@@ -453,7 +463,8 @@ namespace OpenSim.Region.Framework.Scenes
453 get 463 get
454 { 464 {
455 PhysicsActor actor = m_physicsActor; 465 PhysicsActor actor = m_physicsActor;
456 if (actor != null) 466// if (actor != null)
467 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
457 m_pos = actor.Position; 468 m_pos = actor.Position;
458 469
459 return m_parentPosition + m_pos; 470 return m_parentPosition + m_pos;
@@ -474,7 +485,8 @@ namespace OpenSim.Region.Framework.Scenes
474 } 485 }
475 } 486 }
476 487
477 m_pos = value; 488 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
489 m_pos = value;
478 m_parentPosition = Vector3.Zero; 490 m_parentPosition = Vector3.Zero;
479 } 491 }
480 } 492 }
@@ -693,10 +705,7 @@ namespace OpenSim.Region.Framework.Scenes
693 m_reprioritization_timer.AutoReset = false; 705 m_reprioritization_timer.AutoReset = false;
694 706
695 AdjustKnownSeeds(); 707 AdjustKnownSeeds();
696
697 // TODO: I think, this won't send anything, as we are still a child here...
698 Animator.TrySetMovementAnimation("STAND"); 708 Animator.TrySetMovementAnimation("STAND");
699
700 // we created a new ScenePresence (a new child agent) in a fresh region. 709 // we created a new ScenePresence (a new child agent) in a fresh region.
701 // Request info about all the (root) agents in this region 710 // Request info about all the (root) agents in this region
702 // Note: This won't send data *to* other clients in that region (children don't send) 711 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -752,25 +761,47 @@ namespace OpenSim.Region.Framework.Scenes
752 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 761 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
753 Dir_Vectors[4] = Vector3.UnitZ; //UP 762 Dir_Vectors[4] = Vector3.UnitZ; //UP
754 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 763 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
755 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 764 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
756 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 765 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
757 Dir_Vectors[7] = -Vector3.UnitX; //BACK 766 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
767 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
768 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
758 } 769 }
759 770
760 private Vector3[] GetWalkDirectionVectors() 771 private Vector3[] GetWalkDirectionVectors()
761 { 772 {
762 Vector3[] vector = new Vector3[9]; 773 Vector3[] vector = new Vector3[11];
763 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 774 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
764 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 775 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
765 vector[2] = Vector3.UnitY; //LEFT 776 vector[2] = Vector3.UnitY; //LEFT
766 vector[3] = -Vector3.UnitY; //RIGHT 777 vector[3] = -Vector3.UnitY; //RIGHT
767 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 778 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
768 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 779 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
769 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 780 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
770 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 781 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
771 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 782 vector[8] = Vector3.UnitY; //LEFT_NUDGE
783 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
784 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
772 return vector; 785 return vector;
773 } 786 }
787
788 private bool[] GetDirectionIsNudge()
789 {
790 bool[] isNudge = new bool[11];
791 isNudge[0] = false; //FORWARD
792 isNudge[1] = false; //BACK
793 isNudge[2] = false; //LEFT
794 isNudge[3] = false; //RIGHT
795 isNudge[4] = false; //UP
796 isNudge[5] = false; //DOWN
797 isNudge[6] = true; //FORWARD_NUDGE
798 isNudge[7] = true; //BACK_NUDGE
799 isNudge[8] = true; //LEFT_NUDGE
800 isNudge[9] = true; //RIGHT_NUDGE
801 isNudge[10] = true; //DOWN_Nudge
802 return isNudge;
803 }
804
774 805
775 #endregion 806 #endregion
776 807
@@ -839,6 +870,22 @@ namespace OpenSim.Region.Framework.Scenes
839 { 870 {
840 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 871 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
841 pos.Y = crossedBorder.BorderLine.Z - 1; 872 pos.Y = crossedBorder.BorderLine.Z - 1;
873 }
874
875 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
876 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
877 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
878 if (KnownChildRegionHandles.Count == 0)
879 {
880 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
881 if (land != null)
882 {
883 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
884 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_userLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
885 {
886 pos = land.LandData.UserLocation;
887 }
888 }
842 } 889 }
843 890
844 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 891 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
@@ -972,9 +1019,10 @@ namespace OpenSim.Region.Framework.Scenes
972 public void Teleport(Vector3 pos) 1019 public void Teleport(Vector3 pos)
973 { 1020 {
974 bool isFlying = false; 1021 bool isFlying = false;
975 if (m_physicsActor != null)
976 isFlying = m_physicsActor.Flying;
977 1022
1023 if (m_physicsActor != null)
1024 isFlying = m_physicsActor.Flying;
1025
978 RemoveFromPhysicalScene(); 1026 RemoveFromPhysicalScene();
979 Velocity = Vector3.Zero; 1027 Velocity = Vector3.Zero;
980 AbsolutePosition = pos; 1028 AbsolutePosition = pos;
@@ -985,7 +1033,8 @@ namespace OpenSim.Region.Framework.Scenes
985 SetHeight(m_appearance.AvatarHeight); 1033 SetHeight(m_appearance.AvatarHeight);
986 } 1034 }
987 1035
988 SendTerseUpdateToAllClients(); 1036 SendTerseUpdateToAllClients();
1037
989 } 1038 }
990 1039
991 public void TeleportWithMomentum(Vector3 pos) 1040 public void TeleportWithMomentum(Vector3 pos)
@@ -1030,7 +1079,9 @@ namespace OpenSim.Region.Framework.Scenes
1030 { 1079 {
1031 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1080 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1032 } 1081 }
1033 1082
1083 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1084
1034 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1085 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1035 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1086 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1036 } 1087 }
@@ -1215,6 +1266,7 @@ namespace OpenSim.Region.Framework.Scenes
1215 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1266 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1216 1267
1217 m_pos = m_LastFinitePos; 1268 m_pos = m_LastFinitePos;
1269
1218 if (!m_pos.IsFinite()) 1270 if (!m_pos.IsFinite())
1219 { 1271 {
1220 m_pos.X = 127f; 1272 m_pos.X = 127f;
@@ -1281,7 +1333,6 @@ namespace OpenSim.Region.Framework.Scenes
1281 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1333 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1282 } 1334 }
1283 } 1335 }
1284
1285 lock (scriptedcontrols) 1336 lock (scriptedcontrols)
1286 { 1337 {
1287 if (scriptedcontrols.Count > 0) 1338 if (scriptedcontrols.Count > 0)
@@ -1296,12 +1347,8 @@ namespace OpenSim.Region.Framework.Scenes
1296 1347
1297 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1348 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1298 { 1349 {
1299 // TODO: This doesn't prevent the user from walking yet. 1350 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1300 // Setting parent ID would fix this, if we knew what value 1351 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1301 // to use. Or we could add a m_isSitting variable.
1302 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1303 SitGround = true;
1304
1305 } 1352 }
1306 1353
1307 // In the future, these values might need to go global. 1354 // In the future, these values might need to go global.
@@ -1351,6 +1398,11 @@ namespace OpenSim.Region.Framework.Scenes
1351 update_rotation = true; 1398 update_rotation = true;
1352 } 1399 }
1353 1400
1401 //guilty until proven innocent..
1402 bool Nudging = true;
1403 //Basically, if there is at least one non-nudge control then we don't need
1404 //to worry about stopping the avatar
1405
1354 if (m_parentID == 0) 1406 if (m_parentID == 0)
1355 { 1407 {
1356 bool bAllowUpdateMoveToPosition = false; 1408 bool bAllowUpdateMoveToPosition = false;
@@ -1365,9 +1417,12 @@ namespace OpenSim.Region.Framework.Scenes
1365 else 1417 else
1366 dirVectors = Dir_Vectors; 1418 dirVectors = Dir_Vectors;
1367 1419
1368 // The fact that m_movementflag is a byte needs to be fixed 1420 bool[] isNudge = GetDirectionIsNudge();
1369 // it really should be a uint 1421
1370 uint nudgehack = 250; 1422
1423
1424
1425
1371 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1426 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1372 { 1427 {
1373 if (((uint)flags & (uint)DCF) != 0) 1428 if (((uint)flags & (uint)DCF) != 0)
@@ -1377,40 +1432,28 @@ namespace OpenSim.Region.Framework.Scenes
1377 try 1432 try
1378 { 1433 {
1379 agent_control_v3 += dirVectors[i]; 1434 agent_control_v3 += dirVectors[i];
1380 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1435 if (isNudge[i] == false)
1436 {
1437 Nudging = false;
1438 }
1381 } 1439 }
1382 catch (IndexOutOfRangeException) 1440 catch (IndexOutOfRangeException)
1383 { 1441 {
1384 // Why did I get this? 1442 // Why did I get this?
1385 } 1443 }
1386 1444
1387 if ((m_movementflag & (byte)(uint)DCF) == 0) 1445 if ((m_movementflag & (uint)DCF) == 0)
1388 { 1446 {
1389 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1390 {
1391 m_movementflag |= (byte)nudgehack;
1392 }
1393 m_movementflag += (byte)(uint)DCF; 1447 m_movementflag += (byte)(uint)DCF;
1394 update_movementflag = true; 1448 update_movementflag = true;
1395 } 1449 }
1396 } 1450 }
1397 else 1451 else
1398 { 1452 {
1399 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1453 if ((m_movementflag & (uint)DCF) != 0)
1400 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1401 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1402 ) // This or is for Nudge forward
1403 { 1454 {
1404 m_movementflag -= ((byte)(uint)DCF); 1455 m_movementflag -= (byte)(uint)DCF;
1405
1406 update_movementflag = true; 1456 update_movementflag = true;
1407 /*
1408 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1409 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1410 {
1411 m_log.Debug("Removed Hack flag");
1412 }
1413 */
1414 } 1457 }
1415 else 1458 else
1416 { 1459 {
@@ -1454,6 +1497,9 @@ namespace OpenSim.Region.Framework.Scenes
1454 // Ignore z component of vector 1497 // Ignore z component of vector
1455 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1498 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1456 LocalVectorToTarget2D.Normalize(); 1499 LocalVectorToTarget2D.Normalize();
1500
1501 //We're not nudging
1502 Nudging = false;
1457 agent_control_v3 += LocalVectorToTarget2D; 1503 agent_control_v3 += LocalVectorToTarget2D;
1458 1504
1459 // update avatar movement flags. the avatar coordinate system is as follows: 1505 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1542,13 +1588,13 @@ namespace OpenSim.Region.Framework.Scenes
1542 // m_log.DebugFormat( 1588 // m_log.DebugFormat(
1543 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1589 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1544 1590
1545 AddNewMovement(agent_control_v3, q); 1591 AddNewMovement(agent_control_v3, q, Nudging);
1546 1592
1547 1593
1548 } 1594 }
1549 } 1595 }
1550 1596
1551 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1597 if (update_movementflag)
1552 Animator.UpdateMovementAnimations(); 1598 Animator.UpdateMovementAnimations();
1553 1599
1554 m_scene.EventManager.TriggerOnClientMovement(this); 1600 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1563,7 +1609,6 @@ namespace OpenSim.Region.Framework.Scenes
1563 m_sitAtAutoTarget = false; 1609 m_sitAtAutoTarget = false;
1564 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1610 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1565 //proxy.PCode = (byte)PCode.ParticleSystem; 1611 //proxy.PCode = (byte)PCode.ParticleSystem;
1566
1567 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1612 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1568 proxyObjectGroup.AttachToScene(m_scene); 1613 proxyObjectGroup.AttachToScene(m_scene);
1569 1614
@@ -1605,7 +1650,7 @@ namespace OpenSim.Region.Framework.Scenes
1605 } 1650 }
1606 m_moveToPositionInProgress = true; 1651 m_moveToPositionInProgress = true;
1607 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1652 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1608 } 1653 }
1609 catch (Exception ex) 1654 catch (Exception ex)
1610 { 1655 {
1611 //Why did I get this error? 1656 //Why did I get this error?
@@ -1627,7 +1672,7 @@ namespace OpenSim.Region.Framework.Scenes
1627 Velocity = Vector3.Zero; 1672 Velocity = Vector3.Zero;
1628 SendFullUpdateToAllClients(); 1673 SendFullUpdateToAllClients();
1629 1674
1630 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1675 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1631 } 1676 }
1632 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1677 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1633 m_requestedSitTargetUUID = UUID.Zero; 1678 m_requestedSitTargetUUID = UUID.Zero;
@@ -1660,55 +1705,84 @@ namespace OpenSim.Region.Framework.Scenes
1660 /// </summary> 1705 /// </summary>
1661 public void StandUp() 1706 public void StandUp()
1662 { 1707 {
1663 if (SitGround)
1664 SitGround = false;
1665
1666 if (m_parentID != 0) 1708 if (m_parentID != 0)
1667 { 1709 {
1668 m_log.Debug("StandupCode Executed");
1669 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1710 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1670 if (part != null) 1711 if (part != null)
1671 { 1712 {
1713 part.TaskInventory.LockItemsForRead(true);
1672 TaskInventoryDictionary taskIDict = part.TaskInventory; 1714 TaskInventoryDictionary taskIDict = part.TaskInventory;
1673 if (taskIDict != null) 1715 if (taskIDict != null)
1674 { 1716 {
1675 lock (taskIDict) 1717 foreach (UUID taskID in taskIDict.Keys)
1676 { 1718 {
1677 foreach (UUID taskID in taskIDict.Keys) 1719 UnRegisterControlEventsToScript(LocalId, taskID);
1678 { 1720 taskIDict[taskID].PermsMask &= ~(
1679 UnRegisterControlEventsToScript(LocalId, taskID); 1721 2048 | //PERMISSION_CONTROL_CAMERA
1680 taskIDict[taskID].PermsMask &= ~( 1722 4); // PERMISSION_TAKE_CONTROLS
1681 2048 | //PERMISSION_CONTROL_CAMERA
1682 4); // PERMISSION_TAKE_CONTROLS
1683 }
1684 } 1723 }
1685
1686 } 1724 }
1725 part.TaskInventory.LockItemsForRead(false);
1687 // Reset sit target. 1726 // Reset sit target.
1688 if (part.GetAvatarOnSitTarget() == UUID) 1727 if (part.GetAvatarOnSitTarget() == UUID)
1689 part.SetAvatarOnSitTarget(UUID.Zero); 1728 part.SetAvatarOnSitTarget(UUID.Zero);
1690
1691 m_parentPosition = part.GetWorldPosition(); 1729 m_parentPosition = part.GetWorldPosition();
1692 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1730 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1693 } 1731 }
1694 1732 // part.GetWorldRotation() is the rotation of the object being sat on
1695 if (m_physicsActor == null) 1733 // Rotation is the sittiing Av's rotation
1696 { 1734
1697 AddToPhysicalScene(false); 1735 Quaternion partRot;
1736// if (part.LinkNum == 1)
1737// { // Root prim of linkset
1738// partRot = part.ParentGroup.RootPart.RotationOffset;
1739// }
1740// else
1741// { // single or child prim
1742
1743// }
1744 if (part == null) //CW: Part may be gone. llDie() for example.
1745 {
1746 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1747 }
1748 else
1749 {
1750 partRot = part.GetWorldRotation();
1698 } 1751 }
1699 1752
1700 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1753 Quaternion partIRot = Quaternion.Inverse(partRot);
1701 m_parentPosition = Vector3.Zero; 1754
1755 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1756 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1702 1757
1703 m_parentID = 0; 1758
1759 if (m_physicsActor == null)
1760 {
1761 AddToPhysicalScene(false);
1762 }
1763 //CW: If the part isn't null then we can set the current position
1764 if (part != null)
1765 {
1766 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1767 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1768 part.IsOccupied = false;
1769 }
1770 else
1771 {
1772 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1773 AbsolutePosition = m_lastWorldPosition;
1774 }
1775
1776 m_parentPosition = Vector3.Zero;
1777 m_parentID = 0;
1704 SendFullUpdateToAllClients(); 1778 SendFullUpdateToAllClients();
1705 m_requestedSitTargetID = 0; 1779 m_requestedSitTargetID = 0;
1780
1706 if ((m_physicsActor != null) && (m_avHeight > 0)) 1781 if ((m_physicsActor != null) && (m_avHeight > 0))
1707 { 1782 {
1708 SetHeight(m_avHeight); 1783 SetHeight(m_avHeight);
1709 } 1784 }
1710 } 1785 }
1711
1712 Animator.TrySetMovementAnimation("STAND"); 1786 Animator.TrySetMovementAnimation("STAND");
1713 } 1787 }
1714 1788
@@ -1739,13 +1813,9 @@ namespace OpenSim.Region.Framework.Scenes
1739 Vector3 avSitOffSet = part.SitTargetPosition; 1813 Vector3 avSitOffSet = part.SitTargetPosition;
1740 Quaternion avSitOrientation = part.SitTargetOrientation; 1814 Quaternion avSitOrientation = part.SitTargetOrientation;
1741 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1815 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1742 1816 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1743 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1817 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1744 bool SitTargetisSet = 1818 if (SitTargetisSet && !SitTargetOccupied)
1745 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1746 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1747
1748 if (SitTargetisSet && SitTargetUnOccupied)
1749 { 1819 {
1750 //switch the target to this prim 1820 //switch the target to this prim
1751 return part; 1821 return part;
@@ -1759,84 +1829,153 @@ namespace OpenSim.Region.Framework.Scenes
1759 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1829 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1760 { 1830 {
1761 bool autopilot = true; 1831 bool autopilot = true;
1832 Vector3 autopilotTarget = new Vector3();
1833 Quaternion sitOrientation = Quaternion.Identity;
1762 Vector3 pos = new Vector3(); 1834 Vector3 pos = new Vector3();
1763 Quaternion sitOrientation = pSitOrientation;
1764 Vector3 cameraEyeOffset = Vector3.Zero; 1835 Vector3 cameraEyeOffset = Vector3.Zero;
1765 Vector3 cameraAtOffset = Vector3.Zero; 1836 Vector3 cameraAtOffset = Vector3.Zero;
1766 bool forceMouselook = false; 1837 bool forceMouselook = false;
1767 1838
1768 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1839 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1769 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1840 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1770 if (part != null) 1841 if (part == null) return;
1771 { 1842
1772 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1843 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1773 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1844 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1774 1845
1775 // Is a sit target available? 1846 // part is the prim to sit on
1776 Vector3 avSitOffSet = part.SitTargetPosition; 1847 // offset is the world-ref vector distance from that prim center to the click-spot
1777 Quaternion avSitOrientation = part.SitTargetOrientation; 1848 // UUID is the UUID of the Avatar doing the clicking
1778 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1849
1779 1850 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1780 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1851
1781 bool SitTargetisSet = 1852 // Is a sit target available?
1782 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1853 Vector3 avSitOffSet = part.SitTargetPosition;
1783 ( 1854 Quaternion avSitOrientation = part.SitTargetOrientation;
1784 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1855
1785 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1856 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1786 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1857 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1787 ) 1858 Quaternion partRot;
1788 )); 1859// if (part.LinkNum == 1)
1789 1860// { // Root prim of linkset
1790 if (SitTargetisSet && SitTargetUnOccupied) 1861// partRot = part.ParentGroup.RootPart.RotationOffset;
1791 { 1862// }
1792 part.SetAvatarOnSitTarget(UUID); 1863// else
1793 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1864// { // single or child prim
1794 sitOrientation = avSitOrientation; 1865 partRot = part.GetWorldRotation();
1795 autopilot = false; 1866// }
1796 } 1867 Quaternion partIRot = Quaternion.Inverse(partRot);
1797 1868//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1798 pos = part.AbsolutePosition + offset; 1869 // Sit analysis rewritten by KF 091125
1799 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1870 if (SitTargetisSet) // scipted sit
1800 //{ 1871 {
1801 // offset = pos; 1872 if (!part.IsOccupied)
1802 //autopilot = false; 1873 {
1803 //} 1874//Console.WriteLine("Scripted, unoccupied");
1804 if (m_physicsActor != null) 1875 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1805 { 1876 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1806 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1877 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1807 // We can remove the physicsActor until they stand up. 1878 autopilot = false; // Jump direct to scripted llSitPos()
1808 m_sitAvatarHeight = m_physicsActor.Size.Z; 1879 }
1809 1880 else
1810 if (autopilot) 1881 {
1811 { 1882//Console.WriteLine("Scripted, occupied");
1812 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1883 return;
1813 { 1884 }
1814 autopilot = false; 1885 }
1886 else // Not Scripted
1887 {
1888 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1889 {
1890 // large prim & offset, ignore if other Avs sitting
1891// offset.Z -= 0.05f;
1892 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1893 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1894
1895//Console.WriteLine(" offset ={0}", offset);
1896//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1897//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1898
1899 }
1900 else // small offset
1901 {
1902//Console.WriteLine("Small offset");
1903 if (!part.IsOccupied)
1904 {
1905 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1906 autopilotTarget = part.AbsolutePosition;
1907//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1908 }
1909 else return; // occupied small
1910 } // end large/small
1911 } // end Scripted/not
1912 cameraAtOffset = part.GetCameraAtOffset();
1913 cameraEyeOffset = part.GetCameraEyeOffset();
1914 forceMouselook = part.GetForceMouselook();
1915 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1916 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1815 1917
1816 RemoveFromPhysicalScene(); 1918 if (m_physicsActor != null)
1817 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1919 {
1818 } 1920 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1819 } 1921 // We can remove the physicsActor until they stand up.
1820 else 1922 m_sitAvatarHeight = m_physicsActor.Size.Z;
1923 if (autopilot)
1924 { // its not a scripted sit
1925// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1926 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1821 { 1927 {
1928 autopilot = false; // close enough
1929 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1930 Not using the part's position because returning the AV to the last known standing
1931 position is likely to be more friendly, isn't it? */
1822 RemoveFromPhysicalScene(); 1932 RemoveFromPhysicalScene();
1823 } 1933 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1934 } // else the autopilot will get us close
1935 }
1936 else
1937 { // its a scripted sit
1938 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1939 I *am* using the part's position this time because we have no real idea how far away
1940 the avatar is from the sit target. */
1941 RemoveFromPhysicalScene();
1824 } 1942 }
1825
1826 cameraAtOffset = part.GetCameraAtOffset();
1827 cameraEyeOffset = part.GetCameraEyeOffset();
1828 forceMouselook = part.GetForceMouselook();
1829 } 1943 }
1830 1944 else return; // physactor is null!
1831 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1945
1832 m_requestedSitTargetUUID = targetID; 1946 Vector3 offsetr; // = offset * partIRot;
1947 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1948 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1949 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1950 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1951 offsetr = offset * partIRot;
1952//
1953 // else
1954 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1955 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1956 // (offset * partRot);
1957 // }
1958
1959//Console.WriteLine(" ");
1960//Console.WriteLine("link number ={0}", part.LinkNum);
1961//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1962//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1963//Console.WriteLine("Click offst ={0}", offset);
1964//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1965//Console.WriteLine("offsetr ={0}", offsetr);
1966//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1967//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1968
1969 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1970 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1833 // This calls HandleAgentSit twice, once from here, and the client calls 1971 // This calls HandleAgentSit twice, once from here, and the client calls
1834 // HandleAgentSit itself after it gets to the location 1972 // HandleAgentSit itself after it gets to the location
1835 // It doesn't get to the location until we've moved them there though 1973 // It doesn't get to the location until we've moved them there though
1836 // which happens in HandleAgentSit :P 1974 // which happens in HandleAgentSit :P
1837 m_autopilotMoving = autopilot; 1975 m_autopilotMoving = autopilot;
1838 m_autoPilotTarget = pos; 1976 m_autoPilotTarget = autopilotTarget;
1839 m_sitAtAutoTarget = autopilot; 1977 m_sitAtAutoTarget = autopilot;
1978 m_initialSitTarget = autopilotTarget;
1840 if (!autopilot) 1979 if (!autopilot)
1841 HandleAgentSit(remoteClient, UUID); 1980 HandleAgentSit(remoteClient, UUID);
1842 } 1981 }
@@ -2131,31 +2270,66 @@ namespace OpenSim.Region.Framework.Scenes
2131 { 2270 {
2132 if (part != null) 2271 if (part != null)
2133 { 2272 {
2273//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2134 if (part.GetAvatarOnSitTarget() == UUID) 2274 if (part.GetAvatarOnSitTarget() == UUID)
2135 { 2275 {
2276//Console.WriteLine("Scripted Sit");
2277 // Scripted sit
2136 Vector3 sitTargetPos = part.SitTargetPosition; 2278 Vector3 sitTargetPos = part.SitTargetPosition;
2137 Quaternion sitTargetOrient = part.SitTargetOrientation; 2279 Quaternion sitTargetOrient = part.SitTargetOrientation;
2138
2139 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2140 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2141
2142 //Quaternion result = (sitTargetOrient * vq) * nq;
2143
2144 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2280 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2145 m_pos += SIT_TARGET_ADJUSTMENT; 2281 m_pos += SIT_TARGET_ADJUSTMENT;
2146 m_bodyRot = sitTargetOrient; 2282 m_bodyRot = sitTargetOrient;
2147 //Rotation = sitTargetOrient;
2148 m_parentPosition = part.AbsolutePosition; 2283 m_parentPosition = part.AbsolutePosition;
2149 2284 part.IsOccupied = true;
2150 //SendTerseUpdateToAllClients(); 2285Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2151 } 2286 }
2152 else 2287 else
2153 { 2288 {
2154 m_pos -= part.AbsolutePosition; 2289 // if m_avUnscriptedSitPos is zero then Av sits above center
2290 // Else Av sits at m_avUnscriptedSitPos
2291
2292 // Non-scripted sit by Kitto Flora 21Nov09
2293 // Calculate angle of line from prim to Av
2294 Quaternion partIRot;
2295// if (part.LinkNum == 1)
2296// { // Root prim of linkset
2297// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2298// }
2299// else
2300// { // single or child prim
2301 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2302// }
2303 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2304 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2305 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2306 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2307 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2308 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2309 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2310 // Av sits at world euler <0,0, z>, translated by part rotation
2311 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2312
2155 m_parentPosition = part.AbsolutePosition; 2313 m_parentPosition = part.AbsolutePosition;
2156 } 2314 part.IsOccupied = true;
2315 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2316 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2317 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2318 m_avUnscriptedSitPos; // adds click offset, if any
2319 //Set up raytrace to find top surface of prim
2320 Vector3 size = part.Scale;
2321 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2322 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2323 Vector3 down = new Vector3(0f, 0f, -1f);
2324//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2325 m_scene.PhysicsScene.RaycastWorld(
2326 start, // Vector3 position,
2327 down, // Vector3 direction,
2328 mag, // float length,
2329 SitAltitudeCallback); // retMethod
2330 } // end scripted/not
2157 } 2331 }
2158 else 2332 else // no Av
2159 { 2333 {
2160 return; 2334 return;
2161 } 2335 }
@@ -2167,11 +2341,36 @@ namespace OpenSim.Region.Framework.Scenes
2167 2341
2168 Animator.TrySetMovementAnimation(sitAnimation); 2342 Animator.TrySetMovementAnimation(sitAnimation);
2169 SendFullUpdateToAllClients(); 2343 SendFullUpdateToAllClients();
2170 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2171 // So we're also sending a terse update (which has avatar rotation)
2172 // [Update] We do now.
2173 //SendTerseUpdateToAllClients();
2174 } 2344 }
2345
2346 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2347 {
2348 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2349 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2350 if(hitYN)
2351 {
2352 // m_pos = Av offset from prim center to make look like on center
2353 // m_parentPosition = Actual center pos of prim
2354 // collisionPoint = spot on prim where we want to sit
2355 // collisionPoint.Z = global sit surface height
2356 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2357 Quaternion partIRot;
2358// if (part.LinkNum == 1)
2359/// { // Root prim of linkset
2360// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2361// }
2362// else
2363// { // single or child prim
2364 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2365// }
2366 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2367 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2368//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2369 m_pos += offset;
2370// ControllingClient.SendClearFollowCamProperties(part.UUID);
2371
2372 }
2373 } // End SitAltitudeCallback KF.
2175 2374
2176 /// <summary> 2375 /// <summary>
2177 /// Event handler for the 'Always run' setting on the client 2376 /// Event handler for the 'Always run' setting on the client
@@ -2201,7 +2400,7 @@ namespace OpenSim.Region.Framework.Scenes
2201 /// </summary> 2400 /// </summary>
2202 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2401 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2203 /// <param name="rotation">The direction in which this avatar should now face. 2402 /// <param name="rotation">The direction in which this avatar should now face.
2204 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2403 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2205 { 2404 {
2206 if (m_isChildAgent) 2405 if (m_isChildAgent)
2207 { 2406 {
@@ -2278,7 +2477,7 @@ namespace OpenSim.Region.Framework.Scenes
2278 2477
2279 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2478 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2280 m_forceToApply = direc; 2479 m_forceToApply = direc;
2281 2480 m_isNudging = Nudging;
2282 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2481 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2283 } 2482 }
2284 2483
@@ -2293,7 +2492,7 @@ namespace OpenSim.Region.Framework.Scenes
2293 const float POSITION_TOLERANCE = 0.05f; 2492 const float POSITION_TOLERANCE = 0.05f;
2294 //const int TIME_MS_TOLERANCE = 3000; 2493 //const int TIME_MS_TOLERANCE = 3000;
2295 2494
2296 SendPrimUpdates(); 2495
2297 2496
2298 if (m_newCoarseLocations) 2497 if (m_newCoarseLocations)
2299 { 2498 {
@@ -2329,6 +2528,9 @@ namespace OpenSim.Region.Framework.Scenes
2329 CheckForBorderCrossing(); 2528 CheckForBorderCrossing();
2330 CheckForSignificantMovement(); // sends update to the modules. 2529 CheckForSignificantMovement(); // sends update to the modules.
2331 } 2530 }
2531
2532 //Sending prim updates AFTER the avatar terse updates are sent
2533 SendPrimUpdates();
2332 } 2534 }
2333 2535
2334 #endregion 2536 #endregion
@@ -3145,6 +3347,7 @@ namespace OpenSim.Region.Framework.Scenes
3145 m_callbackURI = cAgent.CallbackURI; 3347 m_callbackURI = cAgent.CallbackURI;
3146 3348
3147 m_pos = cAgent.Position; 3349 m_pos = cAgent.Position;
3350
3148 m_velocity = cAgent.Velocity; 3351 m_velocity = cAgent.Velocity;
3149 m_CameraCenter = cAgent.Center; 3352 m_CameraCenter = cAgent.Center;
3150 //m_avHeight = cAgent.Size.Z; 3353 //m_avHeight = cAgent.Size.Z;
@@ -3233,14 +3436,25 @@ namespace OpenSim.Region.Framework.Scenes
3233 { 3436 {
3234 if (m_forceToApply.HasValue) 3437 if (m_forceToApply.HasValue)
3235 { 3438 {
3236 Vector3 force = m_forceToApply.Value;
3237 3439
3440 Vector3 force = m_forceToApply.Value;
3238 m_updateflag = true; 3441 m_updateflag = true;
3239// movementvector = force;
3240 Velocity = force; 3442 Velocity = force;
3241 3443
3242 m_forceToApply = null; 3444 m_forceToApply = null;
3243 } 3445 }
3446 else
3447 {
3448 if (m_isNudging)
3449 {
3450 Vector3 force = Vector3.Zero;
3451
3452 m_updateflag = true;
3453 Velocity = force;
3454 m_isNudging = false;
3455 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3456 }
3457 }
3244 } 3458 }
3245 3459
3246 public override void SetText(string text, Vector3 color, double alpha) 3460 public override void SetText(string text, Vector3 color, double alpha)
@@ -3291,18 +3505,29 @@ namespace OpenSim.Region.Framework.Scenes
3291 { 3505 {
3292 if (e == null) 3506 if (e == null)
3293 return; 3507 return;
3294 3508
3295 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3509 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3296 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3297 // as of this comment the interval is set in AddToPhysicalScene 3510 // as of this comment the interval is set in AddToPhysicalScene
3298 if (Animator!=null) 3511 if (Animator!=null)
3299 Animator.UpdateMovementAnimations(); 3512 {
3513 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3514 { // else its will lock out other animation changes, like ground sit.
3515 Animator.UpdateMovementAnimations();
3516 m_updateCount--;
3517 }
3518 }
3300 3519
3301 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3520 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3302 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3521 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3303 3522
3304 CollisionPlane = Vector4.UnitW; 3523 CollisionPlane = Vector4.UnitW;
3305 3524
3525 if (m_lastColCount != coldata.Count)
3526 {
3527 m_updateCount = UPDATE_COUNT;
3528 m_lastColCount = coldata.Count;
3529 }
3530
3306 if (coldata.Count != 0 && Animator != null) 3531 if (coldata.Count != 0 && Animator != null)
3307 { 3532 {
3308 switch (Animator.CurrentMovementAnimation) 3533 switch (Animator.CurrentMovementAnimation)
@@ -3909,5 +4134,16 @@ namespace OpenSim.Region.Framework.Scenes
3909 m_reprioritization_called = false; 4134 m_reprioritization_called = false;
3910 } 4135 }
3911 } 4136 }
4137
4138 private Vector3 Quat2Euler(Quaternion rot){
4139 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4140 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4141 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4142 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4143 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4144 return(new Vector3(x,y,z));
4145 }
4146
4147
3912 } 4148 }
3913} 4149}