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.cs630
1 files changed, 455 insertions, 175 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 30eafd7..cb24784 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Xml;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using System.Timers; 32using System.Timers;
@@ -73,7 +74,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 74// {
74// m_log.Debug("[ScenePresence] Destructor called"); 75// m_log.Debug("[ScenePresence] Destructor called");
75// } 76// }
76 77
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 78 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 79
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 80 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +90,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 90 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 91 /// issue #1716
91 /// </summary> 92 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 93// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
94 // Value revised by KF 091121 by comparison with SL.
95 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 96
94 public UUID currentParcelUUID = UUID.Zero; 97 public UUID currentParcelUUID = UUID.Zero;
95 98
@@ -123,8 +126,11 @@ namespace OpenSim.Region.Framework.Scenes
123 public Vector3 lastKnownAllowedPosition; 126 public Vector3 lastKnownAllowedPosition;
124 public bool sentMessageAboutRestrictedParcelFlyingDown; 127 public bool sentMessageAboutRestrictedParcelFlyingDown;
125 public Vector4 CollisionPlane = Vector4.UnitW; 128 public Vector4 CollisionPlane = Vector4.UnitW;
126 129
127 private Vector3 m_lastPosition; 130 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
131 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
132 private Vector3 m_lastPosition;
133 private Vector3 m_lastWorldPosition;
128 private Quaternion m_lastRotation; 134 private Quaternion m_lastRotation;
129 private Vector3 m_lastVelocity; 135 private Vector3 m_lastVelocity;
130 //private int m_lastTerseSent; 136 //private int m_lastTerseSent;
@@ -134,7 +140,6 @@ namespace OpenSim.Region.Framework.Scenes
134 private Vector3? m_forceToApply; 140 private Vector3? m_forceToApply;
135 private uint m_requestedSitTargetID; 141 private uint m_requestedSitTargetID;
136 private UUID m_requestedSitTargetUUID; 142 private UUID m_requestedSitTargetUUID;
137 public bool SitGround = false;
138 143
139 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 144 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
140 145
@@ -157,7 +162,6 @@ namespace OpenSim.Region.Framework.Scenes
157 private int m_perfMonMS; 162 private int m_perfMonMS;
158 163
159 private bool m_setAlwaysRun; 164 private bool m_setAlwaysRun;
160
161 private bool m_forceFly; 165 private bool m_forceFly;
162 private bool m_flyDisabled; 166 private bool m_flyDisabled;
163 167
@@ -183,7 +187,8 @@ namespace OpenSim.Region.Framework.Scenes
183 protected RegionInfo m_regionInfo; 187 protected RegionInfo m_regionInfo;
184 protected ulong crossingFromRegion; 188 protected ulong crossingFromRegion;
185 189
186 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 190 private readonly Vector3[] Dir_Vectors = new Vector3[11];
191 private bool m_isNudging = false;
187 192
188 // Position of agent's camera in world (region cordinates) 193 // Position of agent's camera in world (region cordinates)
189 protected Vector3 m_CameraCenter; 194 protected Vector3 m_CameraCenter;
@@ -208,6 +213,7 @@ namespace OpenSim.Region.Framework.Scenes
208 private bool m_autopilotMoving; 213 private bool m_autopilotMoving;
209 private Vector3 m_autoPilotTarget; 214 private Vector3 m_autoPilotTarget;
210 private bool m_sitAtAutoTarget; 215 private bool m_sitAtAutoTarget;
216 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
211 217
212 private string m_nextSitAnimation = String.Empty; 218 private string m_nextSitAnimation = String.Empty;
213 219
@@ -218,6 +224,9 @@ namespace OpenSim.Region.Framework.Scenes
218 private bool m_followCamAuto; 224 private bool m_followCamAuto;
219 225
220 private int m_movementUpdateCount; 226 private int m_movementUpdateCount;
227 private int m_lastColCount = -1; //KF: Look for Collision chnages
228 private int m_updateCount = 0; //KF: Update Anims for a while
229 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
221 private const int NumMovementsBetweenRayCast = 5; 230 private const int NumMovementsBetweenRayCast = 5;
222 231
223 private bool CameraConstraintActive; 232 private bool CameraConstraintActive;
@@ -245,7 +254,9 @@ namespace OpenSim.Region.Framework.Scenes
245 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 254 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
246 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 255 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
247 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,
248 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,
249 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
250 } 261 }
251 262
@@ -452,7 +463,8 @@ namespace OpenSim.Region.Framework.Scenes
452 get 463 get
453 { 464 {
454 PhysicsActor actor = m_physicsActor; 465 PhysicsActor actor = m_physicsActor;
455 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!
456 m_pos = actor.Position; 468 m_pos = actor.Position;
457 469
458 return m_parentPosition + m_pos; 470 return m_parentPosition + m_pos;
@@ -473,7 +485,8 @@ namespace OpenSim.Region.Framework.Scenes
473 } 485 }
474 } 486 }
475 487
476 m_pos = value; 488 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
489 m_pos = value;
477 m_parentPosition = Vector3.Zero; 490 m_parentPosition = Vector3.Zero;
478 } 491 }
479 } 492 }
@@ -697,10 +710,7 @@ namespace OpenSim.Region.Framework.Scenes
697 m_reprioritization_timer.AutoReset = false; 710 m_reprioritization_timer.AutoReset = false;
698 711
699 AdjustKnownSeeds(); 712 AdjustKnownSeeds();
700
701 // TODO: I think, this won't send anything, as we are still a child here...
702 Animator.TrySetMovementAnimation("STAND"); 713 Animator.TrySetMovementAnimation("STAND");
703
704 // we created a new ScenePresence (a new child agent) in a fresh region. 714 // we created a new ScenePresence (a new child agent) in a fresh region.
705 // Request info about all the (root) agents in this region 715 // Request info about all the (root) agents in this region
706 // Note: This won't send data *to* other clients in that region (children don't send) 716 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -756,25 +766,47 @@ namespace OpenSim.Region.Framework.Scenes
756 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 766 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
757 Dir_Vectors[4] = Vector3.UnitZ; //UP 767 Dir_Vectors[4] = Vector3.UnitZ; //UP
758 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 768 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
759 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 769 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
760 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 770 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
761 Dir_Vectors[7] = -Vector3.UnitX; //BACK 771 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
772 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
773 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
762 } 774 }
763 775
764 private Vector3[] GetWalkDirectionVectors() 776 private Vector3[] GetWalkDirectionVectors()
765 { 777 {
766 Vector3[] vector = new Vector3[9]; 778 Vector3[] vector = new Vector3[11];
767 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 779 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
768 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 780 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
769 vector[2] = Vector3.UnitY; //LEFT 781 vector[2] = Vector3.UnitY; //LEFT
770 vector[3] = -Vector3.UnitY; //RIGHT 782 vector[3] = -Vector3.UnitY; //RIGHT
771 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 783 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
772 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 784 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
773 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 785 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
774 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 786 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
775 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 787 vector[8] = Vector3.UnitY; //LEFT_NUDGE
788 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
789 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
776 return vector; 790 return vector;
777 } 791 }
792
793 private bool[] GetDirectionIsNudge()
794 {
795 bool[] isNudge = new bool[11];
796 isNudge[0] = false; //FORWARD
797 isNudge[1] = false; //BACK
798 isNudge[2] = false; //LEFT
799 isNudge[3] = false; //RIGHT
800 isNudge[4] = false; //UP
801 isNudge[5] = false; //DOWN
802 isNudge[6] = true; //FORWARD_NUDGE
803 isNudge[7] = true; //BACK_NUDGE
804 isNudge[8] = true; //LEFT_NUDGE
805 isNudge[9] = true; //RIGHT_NUDGE
806 isNudge[10] = true; //DOWN_Nudge
807 return isNudge;
808 }
809
778 810
779 #endregion 811 #endregion
780 812
@@ -843,6 +875,22 @@ namespace OpenSim.Region.Framework.Scenes
843 { 875 {
844 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 876 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
845 pos.Y = crossedBorder.BorderLine.Z - 1; 877 pos.Y = crossedBorder.BorderLine.Z - 1;
878 }
879
880 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
881 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
882 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
883 if (KnownChildRegionHandles.Count == 0)
884 {
885 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
886 if (land != null)
887 {
888 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
889 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)
890 {
891 pos = land.LandData.UserLocation;
892 }
893 }
846 } 894 }
847 895
848 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 896 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
@@ -977,9 +1025,10 @@ namespace OpenSim.Region.Framework.Scenes
977 public void Teleport(Vector3 pos) 1025 public void Teleport(Vector3 pos)
978 { 1026 {
979 bool isFlying = false; 1027 bool isFlying = false;
980 if (m_physicsActor != null)
981 isFlying = m_physicsActor.Flying;
982 1028
1029 if (m_physicsActor != null)
1030 isFlying = m_physicsActor.Flying;
1031
983 RemoveFromPhysicalScene(); 1032 RemoveFromPhysicalScene();
984 Velocity = Vector3.Zero; 1033 Velocity = Vector3.Zero;
985 AbsolutePosition = pos; 1034 AbsolutePosition = pos;
@@ -990,7 +1039,8 @@ namespace OpenSim.Region.Framework.Scenes
990 SetHeight(m_appearance.AvatarHeight); 1039 SetHeight(m_appearance.AvatarHeight);
991 } 1040 }
992 1041
993 SendTerseUpdateToAllClients(); 1042 SendTerseUpdateToAllClients();
1043
994 } 1044 }
995 1045
996 public void TeleportWithMomentum(Vector3 pos) 1046 public void TeleportWithMomentum(Vector3 pos)
@@ -1035,7 +1085,9 @@ namespace OpenSim.Region.Framework.Scenes
1035 { 1085 {
1036 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1086 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1037 } 1087 }
1038 1088
1089 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1090
1039 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1091 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1040 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1092 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1041 } 1093 }
@@ -1220,6 +1272,7 @@ namespace OpenSim.Region.Framework.Scenes
1220 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1272 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1221 1273
1222 m_pos = m_LastFinitePos; 1274 m_pos = m_LastFinitePos;
1275
1223 if (!m_pos.IsFinite()) 1276 if (!m_pos.IsFinite())
1224 { 1277 {
1225 m_pos.X = 127f; 1278 m_pos.X = 127f;
@@ -1286,7 +1339,6 @@ namespace OpenSim.Region.Framework.Scenes
1286 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1339 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1287 } 1340 }
1288 } 1341 }
1289
1290 lock (scriptedcontrols) 1342 lock (scriptedcontrols)
1291 { 1343 {
1292 if (scriptedcontrols.Count > 0) 1344 if (scriptedcontrols.Count > 0)
@@ -1301,12 +1353,8 @@ namespace OpenSim.Region.Framework.Scenes
1301 1353
1302 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1354 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1303 { 1355 {
1304 // TODO: This doesn't prevent the user from walking yet. 1356 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1305 // Setting parent ID would fix this, if we knew what value 1357 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1306 // to use. Or we could add a m_isSitting variable.
1307 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1308 SitGround = true;
1309
1310 } 1358 }
1311 1359
1312 // In the future, these values might need to go global. 1360 // In the future, these values might need to go global.
@@ -1356,6 +1404,11 @@ namespace OpenSim.Region.Framework.Scenes
1356 update_rotation = true; 1404 update_rotation = true;
1357 } 1405 }
1358 1406
1407 //guilty until proven innocent..
1408 bool Nudging = true;
1409 //Basically, if there is at least one non-nudge control then we don't need
1410 //to worry about stopping the avatar
1411
1359 if (m_parentID == 0) 1412 if (m_parentID == 0)
1360 { 1413 {
1361 bool bAllowUpdateMoveToPosition = false; 1414 bool bAllowUpdateMoveToPosition = false;
@@ -1370,9 +1423,12 @@ namespace OpenSim.Region.Framework.Scenes
1370 else 1423 else
1371 dirVectors = Dir_Vectors; 1424 dirVectors = Dir_Vectors;
1372 1425
1373 // The fact that m_movementflag is a byte needs to be fixed 1426 bool[] isNudge = GetDirectionIsNudge();
1374 // it really should be a uint 1427
1375 uint nudgehack = 250; 1428
1429
1430
1431
1376 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1432 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1377 { 1433 {
1378 if (((uint)flags & (uint)DCF) != 0) 1434 if (((uint)flags & (uint)DCF) != 0)
@@ -1382,40 +1438,28 @@ namespace OpenSim.Region.Framework.Scenes
1382 try 1438 try
1383 { 1439 {
1384 agent_control_v3 += dirVectors[i]; 1440 agent_control_v3 += dirVectors[i];
1385 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1441 if (isNudge[i] == false)
1442 {
1443 Nudging = false;
1444 }
1386 } 1445 }
1387 catch (IndexOutOfRangeException) 1446 catch (IndexOutOfRangeException)
1388 { 1447 {
1389 // Why did I get this? 1448 // Why did I get this?
1390 } 1449 }
1391 1450
1392 if ((m_movementflag & (byte)(uint)DCF) == 0) 1451 if ((m_movementflag & (uint)DCF) == 0)
1393 { 1452 {
1394 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1395 {
1396 m_movementflag |= (byte)nudgehack;
1397 }
1398 m_movementflag += (byte)(uint)DCF; 1453 m_movementflag += (byte)(uint)DCF;
1399 update_movementflag = true; 1454 update_movementflag = true;
1400 } 1455 }
1401 } 1456 }
1402 else 1457 else
1403 { 1458 {
1404 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1459 if ((m_movementflag & (uint)DCF) != 0)
1405 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1406 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1407 ) // This or is for Nudge forward
1408 { 1460 {
1409 m_movementflag -= ((byte)(uint)DCF); 1461 m_movementflag -= (byte)(uint)DCF;
1410
1411 update_movementflag = true; 1462 update_movementflag = true;
1412 /*
1413 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1414 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1415 {
1416 m_log.Debug("Removed Hack flag");
1417 }
1418 */
1419 } 1463 }
1420 else 1464 else
1421 { 1465 {
@@ -1459,6 +1503,9 @@ namespace OpenSim.Region.Framework.Scenes
1459 // Ignore z component of vector 1503 // Ignore z component of vector
1460 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1504 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1461 LocalVectorToTarget2D.Normalize(); 1505 LocalVectorToTarget2D.Normalize();
1506
1507 //We're not nudging
1508 Nudging = false;
1462 agent_control_v3 += LocalVectorToTarget2D; 1509 agent_control_v3 += LocalVectorToTarget2D;
1463 1510
1464 // update avatar movement flags. the avatar coordinate system is as follows: 1511 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1547,13 +1594,13 @@ namespace OpenSim.Region.Framework.Scenes
1547 // m_log.DebugFormat( 1594 // m_log.DebugFormat(
1548 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1595 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1549 1596
1550 AddNewMovement(agent_control_v3, q); 1597 AddNewMovement(agent_control_v3, q, Nudging);
1551 1598
1552 1599
1553 } 1600 }
1554 } 1601 }
1555 1602
1556 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1603 if (update_movementflag)
1557 Animator.UpdateMovementAnimations(); 1604 Animator.UpdateMovementAnimations();
1558 1605
1559 m_scene.EventManager.TriggerOnClientMovement(this); 1606 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1568,7 +1615,6 @@ namespace OpenSim.Region.Framework.Scenes
1568 m_sitAtAutoTarget = false; 1615 m_sitAtAutoTarget = false;
1569 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1616 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1570 //proxy.PCode = (byte)PCode.ParticleSystem; 1617 //proxy.PCode = (byte)PCode.ParticleSystem;
1571
1572 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1618 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1573 proxyObjectGroup.AttachToScene(m_scene); 1619 proxyObjectGroup.AttachToScene(m_scene);
1574 1620
@@ -1610,7 +1656,7 @@ namespace OpenSim.Region.Framework.Scenes
1610 } 1656 }
1611 m_moveToPositionInProgress = true; 1657 m_moveToPositionInProgress = true;
1612 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1658 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1613 } 1659 }
1614 catch (Exception ex) 1660 catch (Exception ex)
1615 { 1661 {
1616 //Why did I get this error? 1662 //Why did I get this error?
@@ -1632,7 +1678,7 @@ namespace OpenSim.Region.Framework.Scenes
1632 Velocity = Vector3.Zero; 1678 Velocity = Vector3.Zero;
1633 SendFullUpdateToAllClients(); 1679 SendFullUpdateToAllClients();
1634 1680
1635 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1681 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1636 } 1682 }
1637 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1683 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1638 m_requestedSitTargetUUID = UUID.Zero; 1684 m_requestedSitTargetUUID = UUID.Zero;
@@ -1665,55 +1711,84 @@ namespace OpenSim.Region.Framework.Scenes
1665 /// </summary> 1711 /// </summary>
1666 public void StandUp() 1712 public void StandUp()
1667 { 1713 {
1668 if (SitGround)
1669 SitGround = false;
1670
1671 if (m_parentID != 0) 1714 if (m_parentID != 0)
1672 { 1715 {
1673 m_log.Debug("StandupCode Executed");
1674 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1716 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1675 if (part != null) 1717 if (part != null)
1676 { 1718 {
1719 part.TaskInventory.LockItemsForRead(true);
1677 TaskInventoryDictionary taskIDict = part.TaskInventory; 1720 TaskInventoryDictionary taskIDict = part.TaskInventory;
1678 if (taskIDict != null) 1721 if (taskIDict != null)
1679 { 1722 {
1680 lock (taskIDict) 1723 foreach (UUID taskID in taskIDict.Keys)
1681 { 1724 {
1682 foreach (UUID taskID in taskIDict.Keys) 1725 UnRegisterControlEventsToScript(LocalId, taskID);
1683 { 1726 taskIDict[taskID].PermsMask &= ~(
1684 UnRegisterControlEventsToScript(LocalId, taskID); 1727 2048 | //PERMISSION_CONTROL_CAMERA
1685 taskIDict[taskID].PermsMask &= ~( 1728 4); // PERMISSION_TAKE_CONTROLS
1686 2048 | //PERMISSION_CONTROL_CAMERA
1687 4); // PERMISSION_TAKE_CONTROLS
1688 }
1689 } 1729 }
1690
1691 } 1730 }
1731 part.TaskInventory.LockItemsForRead(false);
1692 // Reset sit target. 1732 // Reset sit target.
1693 if (part.GetAvatarOnSitTarget() == UUID) 1733 if (part.GetAvatarOnSitTarget() == UUID)
1694 part.SetAvatarOnSitTarget(UUID.Zero); 1734 part.SetAvatarOnSitTarget(UUID.Zero);
1695
1696 m_parentPosition = part.GetWorldPosition(); 1735 m_parentPosition = part.GetWorldPosition();
1697 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1736 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1698 } 1737 }
1699 1738 // part.GetWorldRotation() is the rotation of the object being sat on
1700 if (m_physicsActor == null) 1739 // Rotation is the sittiing Av's rotation
1701 { 1740
1702 AddToPhysicalScene(false); 1741 Quaternion partRot;
1742// if (part.LinkNum == 1)
1743// { // Root prim of linkset
1744// partRot = part.ParentGroup.RootPart.RotationOffset;
1745// }
1746// else
1747// { // single or child prim
1748
1749// }
1750 if (part == null) //CW: Part may be gone. llDie() for example.
1751 {
1752 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1753 }
1754 else
1755 {
1756 partRot = part.GetWorldRotation();
1703 } 1757 }
1704 1758
1705 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1759 Quaternion partIRot = Quaternion.Inverse(partRot);
1706 m_parentPosition = Vector3.Zero;
1707 1760
1708 m_parentID = 0; 1761 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1762 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1763
1764
1765 if (m_physicsActor == null)
1766 {
1767 AddToPhysicalScene(false);
1768 }
1769 //CW: If the part isn't null then we can set the current position
1770 if (part != null)
1771 {
1772 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1773 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1774 part.IsOccupied = false;
1775 }
1776 else
1777 {
1778 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1779 AbsolutePosition = m_lastWorldPosition;
1780 }
1781
1782 m_parentPosition = Vector3.Zero;
1783 m_parentID = 0;
1709 SendFullUpdateToAllClients(); 1784 SendFullUpdateToAllClients();
1710 m_requestedSitTargetID = 0; 1785 m_requestedSitTargetID = 0;
1786
1711 if ((m_physicsActor != null) && (m_avHeight > 0)) 1787 if ((m_physicsActor != null) && (m_avHeight > 0))
1712 { 1788 {
1713 SetHeight(m_avHeight); 1789 SetHeight(m_avHeight);
1714 } 1790 }
1715 } 1791 }
1716
1717 Animator.TrySetMovementAnimation("STAND"); 1792 Animator.TrySetMovementAnimation("STAND");
1718 } 1793 }
1719 1794
@@ -1744,13 +1819,9 @@ namespace OpenSim.Region.Framework.Scenes
1744 Vector3 avSitOffSet = part.SitTargetPosition; 1819 Vector3 avSitOffSet = part.SitTargetPosition;
1745 Quaternion avSitOrientation = part.SitTargetOrientation; 1820 Quaternion avSitOrientation = part.SitTargetOrientation;
1746 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1821 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1747 1822 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1748 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1823 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1749 bool SitTargetisSet = 1824 if (SitTargetisSet && !SitTargetOccupied)
1750 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1751 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1752
1753 if (SitTargetisSet && SitTargetUnOccupied)
1754 { 1825 {
1755 //switch the target to this prim 1826 //switch the target to this prim
1756 return part; 1827 return part;
@@ -1764,84 +1835,153 @@ namespace OpenSim.Region.Framework.Scenes
1764 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1835 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1765 { 1836 {
1766 bool autopilot = true; 1837 bool autopilot = true;
1838 Vector3 autopilotTarget = new Vector3();
1839 Quaternion sitOrientation = Quaternion.Identity;
1767 Vector3 pos = new Vector3(); 1840 Vector3 pos = new Vector3();
1768 Quaternion sitOrientation = pSitOrientation;
1769 Vector3 cameraEyeOffset = Vector3.Zero; 1841 Vector3 cameraEyeOffset = Vector3.Zero;
1770 Vector3 cameraAtOffset = Vector3.Zero; 1842 Vector3 cameraAtOffset = Vector3.Zero;
1771 bool forceMouselook = false; 1843 bool forceMouselook = false;
1772 1844
1773 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1845 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1774 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1846 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1775 if (part != null) 1847 if (part == null) return;
1776 { 1848
1777 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1849 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1778 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1850 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1779 1851
1780 // Is a sit target available? 1852 // part is the prim to sit on
1781 Vector3 avSitOffSet = part.SitTargetPosition; 1853 // offset is the world-ref vector distance from that prim center to the click-spot
1782 Quaternion avSitOrientation = part.SitTargetOrientation; 1854 // UUID is the UUID of the Avatar doing the clicking
1783 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1855
1784 1856 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1785 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1857
1786 bool SitTargetisSet = 1858 // Is a sit target available?
1787 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1859 Vector3 avSitOffSet = part.SitTargetPosition;
1788 ( 1860 Quaternion avSitOrientation = part.SitTargetOrientation;
1789 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1861
1790 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1862 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1791 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1863 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1792 ) 1864 Quaternion partRot;
1793 )); 1865// if (part.LinkNum == 1)
1794 1866// { // Root prim of linkset
1795 if (SitTargetisSet && SitTargetUnOccupied) 1867// partRot = part.ParentGroup.RootPart.RotationOffset;
1796 { 1868// }
1797 part.SetAvatarOnSitTarget(UUID); 1869// else
1798 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1870// { // single or child prim
1799 sitOrientation = avSitOrientation; 1871 partRot = part.GetWorldRotation();
1800 autopilot = false; 1872// }
1801 } 1873 Quaternion partIRot = Quaternion.Inverse(partRot);
1802 1874//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1803 pos = part.AbsolutePosition + offset; 1875 // Sit analysis rewritten by KF 091125
1804 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1876 if (SitTargetisSet) // scipted sit
1805 //{ 1877 {
1806 // offset = pos; 1878 if (!part.IsOccupied)
1807 //autopilot = false; 1879 {
1808 //} 1880//Console.WriteLine("Scripted, unoccupied");
1809 if (m_physicsActor != null) 1881 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1810 { 1882 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1811 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1883 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1812 // We can remove the physicsActor until they stand up. 1884 autopilot = false; // Jump direct to scripted llSitPos()
1813 m_sitAvatarHeight = m_physicsActor.Size.Z; 1885 }
1814 1886 else
1815 if (autopilot) 1887 {
1816 { 1888//Console.WriteLine("Scripted, occupied");
1817 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1889 return;
1818 { 1890 }
1819 autopilot = false; 1891 }
1892 else // Not Scripted
1893 {
1894 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1895 {
1896 // large prim & offset, ignore if other Avs sitting
1897// offset.Z -= 0.05f;
1898 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1899 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1900
1901//Console.WriteLine(" offset ={0}", offset);
1902//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1903//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1904
1905 }
1906 else // small offset
1907 {
1908//Console.WriteLine("Small offset");
1909 if (!part.IsOccupied)
1910 {
1911 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1912 autopilotTarget = part.AbsolutePosition;
1913//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1914 }
1915 else return; // occupied small
1916 } // end large/small
1917 } // end Scripted/not
1918 cameraAtOffset = part.GetCameraAtOffset();
1919 cameraEyeOffset = part.GetCameraEyeOffset();
1920 forceMouselook = part.GetForceMouselook();
1921 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1922 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1820 1923
1821 RemoveFromPhysicalScene(); 1924 if (m_physicsActor != null)
1822 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1925 {
1823 } 1926 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1824 } 1927 // We can remove the physicsActor until they stand up.
1825 else 1928 m_sitAvatarHeight = m_physicsActor.Size.Z;
1929 if (autopilot)
1930 { // its not a scripted sit
1931// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1932 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1826 { 1933 {
1934 autopilot = false; // close enough
1935 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1936 Not using the part's position because returning the AV to the last known standing
1937 position is likely to be more friendly, isn't it? */
1827 RemoveFromPhysicalScene(); 1938 RemoveFromPhysicalScene();
1828 } 1939 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1940 } // else the autopilot will get us close
1941 }
1942 else
1943 { // its a scripted sit
1944 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1945 I *am* using the part's position this time because we have no real idea how far away
1946 the avatar is from the sit target. */
1947 RemoveFromPhysicalScene();
1829 } 1948 }
1830
1831 cameraAtOffset = part.GetCameraAtOffset();
1832 cameraEyeOffset = part.GetCameraEyeOffset();
1833 forceMouselook = part.GetForceMouselook();
1834 } 1949 }
1835 1950 else return; // physactor is null!
1836 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1951
1837 m_requestedSitTargetUUID = targetID; 1952 Vector3 offsetr; // = offset * partIRot;
1953 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1954 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1955 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1956 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1957 offsetr = offset * partIRot;
1958//
1959 // else
1960 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1961 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1962 // (offset * partRot);
1963 // }
1964
1965//Console.WriteLine(" ");
1966//Console.WriteLine("link number ={0}", part.LinkNum);
1967//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1968//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1969//Console.WriteLine("Click offst ={0}", offset);
1970//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1971//Console.WriteLine("offsetr ={0}", offsetr);
1972//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1973//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1974
1975 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1976 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1838 // This calls HandleAgentSit twice, once from here, and the client calls 1977 // This calls HandleAgentSit twice, once from here, and the client calls
1839 // HandleAgentSit itself after it gets to the location 1978 // HandleAgentSit itself after it gets to the location
1840 // It doesn't get to the location until we've moved them there though 1979 // It doesn't get to the location until we've moved them there though
1841 // which happens in HandleAgentSit :P 1980 // which happens in HandleAgentSit :P
1842 m_autopilotMoving = autopilot; 1981 m_autopilotMoving = autopilot;
1843 m_autoPilotTarget = pos; 1982 m_autoPilotTarget = autopilotTarget;
1844 m_sitAtAutoTarget = autopilot; 1983 m_sitAtAutoTarget = autopilot;
1984 m_initialSitTarget = autopilotTarget;
1845 if (!autopilot) 1985 if (!autopilot)
1846 HandleAgentSit(remoteClient, UUID); 1986 HandleAgentSit(remoteClient, UUID);
1847 } 1987 }
@@ -2136,31 +2276,66 @@ namespace OpenSim.Region.Framework.Scenes
2136 { 2276 {
2137 if (part != null) 2277 if (part != null)
2138 { 2278 {
2279//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2139 if (part.GetAvatarOnSitTarget() == UUID) 2280 if (part.GetAvatarOnSitTarget() == UUID)
2140 { 2281 {
2282//Console.WriteLine("Scripted Sit");
2283 // Scripted sit
2141 Vector3 sitTargetPos = part.SitTargetPosition; 2284 Vector3 sitTargetPos = part.SitTargetPosition;
2142 Quaternion sitTargetOrient = part.SitTargetOrientation; 2285 Quaternion sitTargetOrient = part.SitTargetOrientation;
2143
2144 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2145 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2146
2147 //Quaternion result = (sitTargetOrient * vq) * nq;
2148
2149 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2286 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2150 m_pos += SIT_TARGET_ADJUSTMENT; 2287 m_pos += SIT_TARGET_ADJUSTMENT;
2151 m_bodyRot = sitTargetOrient; 2288 m_bodyRot = sitTargetOrient;
2152 //Rotation = sitTargetOrient;
2153 m_parentPosition = part.AbsolutePosition; 2289 m_parentPosition = part.AbsolutePosition;
2154 2290 part.IsOccupied = true;
2155 //SendTerseUpdateToAllClients(); 2291Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2156 } 2292 }
2157 else 2293 else
2158 { 2294 {
2159 m_pos -= part.AbsolutePosition; 2295 // if m_avUnscriptedSitPos is zero then Av sits above center
2296 // Else Av sits at m_avUnscriptedSitPos
2297
2298 // Non-scripted sit by Kitto Flora 21Nov09
2299 // Calculate angle of line from prim to Av
2300 Quaternion partIRot;
2301// if (part.LinkNum == 1)
2302// { // Root prim of linkset
2303// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2304// }
2305// else
2306// { // single or child prim
2307 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2308// }
2309 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2310 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2311 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2312 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2313 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2314 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2315 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2316 // Av sits at world euler <0,0, z>, translated by part rotation
2317 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2318
2160 m_parentPosition = part.AbsolutePosition; 2319 m_parentPosition = part.AbsolutePosition;
2161 } 2320 part.IsOccupied = true;
2321 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2322 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2323 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2324 m_avUnscriptedSitPos; // adds click offset, if any
2325 //Set up raytrace to find top surface of prim
2326 Vector3 size = part.Scale;
2327 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2328 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2329 Vector3 down = new Vector3(0f, 0f, -1f);
2330//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2331 m_scene.PhysicsScene.RaycastWorld(
2332 start, // Vector3 position,
2333 down, // Vector3 direction,
2334 mag, // float length,
2335 SitAltitudeCallback); // retMethod
2336 } // end scripted/not
2162 } 2337 }
2163 else 2338 else // no Av
2164 { 2339 {
2165 return; 2340 return;
2166 } 2341 }
@@ -2172,11 +2347,36 @@ namespace OpenSim.Region.Framework.Scenes
2172 2347
2173 Animator.TrySetMovementAnimation(sitAnimation); 2348 Animator.TrySetMovementAnimation(sitAnimation);
2174 SendFullUpdateToAllClients(); 2349 SendFullUpdateToAllClients();
2175 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2176 // So we're also sending a terse update (which has avatar rotation)
2177 // [Update] We do now.
2178 //SendTerseUpdateToAllClients();
2179 } 2350 }
2351
2352 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2353 {
2354 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2355 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2356 if(hitYN)
2357 {
2358 // m_pos = Av offset from prim center to make look like on center
2359 // m_parentPosition = Actual center pos of prim
2360 // collisionPoint = spot on prim where we want to sit
2361 // collisionPoint.Z = global sit surface height
2362 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2363 Quaternion partIRot;
2364// if (part.LinkNum == 1)
2365/// { // Root prim of linkset
2366// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2367// }
2368// else
2369// { // single or child prim
2370 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2371// }
2372 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2373 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2374//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2375 m_pos += offset;
2376// ControllingClient.SendClearFollowCamProperties(part.UUID);
2377
2378 }
2379 } // End SitAltitudeCallback KF.
2180 2380
2181 /// <summary> 2381 /// <summary>
2182 /// Event handler for the 'Always run' setting on the client 2382 /// Event handler for the 'Always run' setting on the client
@@ -2206,7 +2406,7 @@ namespace OpenSim.Region.Framework.Scenes
2206 /// </summary> 2406 /// </summary>
2207 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2407 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2208 /// <param name="rotation">The direction in which this avatar should now face. 2408 /// <param name="rotation">The direction in which this avatar should now face.
2209 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2409 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2210 { 2410 {
2211 if (m_isChildAgent) 2411 if (m_isChildAgent)
2212 { 2412 {
@@ -2283,7 +2483,7 @@ namespace OpenSim.Region.Framework.Scenes
2283 2483
2284 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2484 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2285 m_forceToApply = direc; 2485 m_forceToApply = direc;
2286 2486 m_isNudging = Nudging;
2287 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2487 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2288 } 2488 }
2289 2489
@@ -2298,7 +2498,7 @@ namespace OpenSim.Region.Framework.Scenes
2298 const float POSITION_TOLERANCE = 0.05f; 2498 const float POSITION_TOLERANCE = 0.05f;
2299 //const int TIME_MS_TOLERANCE = 3000; 2499 //const int TIME_MS_TOLERANCE = 3000;
2300 2500
2301 SendPrimUpdates(); 2501
2302 2502
2303 if (m_newCoarseLocations) 2503 if (m_newCoarseLocations)
2304 { 2504 {
@@ -2334,6 +2534,9 @@ namespace OpenSim.Region.Framework.Scenes
2334 CheckForBorderCrossing(); 2534 CheckForBorderCrossing();
2335 CheckForSignificantMovement(); // sends update to the modules. 2535 CheckForSignificantMovement(); // sends update to the modules.
2336 } 2536 }
2537
2538 //Sending prim updates AFTER the avatar terse updates are sent
2539 SendPrimUpdates();
2337 } 2540 }
2338 2541
2339 #endregion 2542 #endregion
@@ -3150,6 +3353,7 @@ namespace OpenSim.Region.Framework.Scenes
3150 m_callbackURI = cAgent.CallbackURI; 3353 m_callbackURI = cAgent.CallbackURI;
3151 3354
3152 m_pos = cAgent.Position; 3355 m_pos = cAgent.Position;
3356
3153 m_velocity = cAgent.Velocity; 3357 m_velocity = cAgent.Velocity;
3154 m_CameraCenter = cAgent.Center; 3358 m_CameraCenter = cAgent.Center;
3155 //m_avHeight = cAgent.Size.Z; 3359 //m_avHeight = cAgent.Size.Z;
@@ -3238,14 +3442,25 @@ namespace OpenSim.Region.Framework.Scenes
3238 { 3442 {
3239 if (m_forceToApply.HasValue) 3443 if (m_forceToApply.HasValue)
3240 { 3444 {
3241 Vector3 force = m_forceToApply.Value;
3242 3445
3446 Vector3 force = m_forceToApply.Value;
3243 m_updateflag = true; 3447 m_updateflag = true;
3244// movementvector = force;
3245 Velocity = force; 3448 Velocity = force;
3246 3449
3247 m_forceToApply = null; 3450 m_forceToApply = null;
3248 } 3451 }
3452 else
3453 {
3454 if (m_isNudging)
3455 {
3456 Vector3 force = Vector3.Zero;
3457
3458 m_updateflag = true;
3459 Velocity = force;
3460 m_isNudging = false;
3461 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3462 }
3463 }
3249 } 3464 }
3250 3465
3251 public override void SetText(string text, Vector3 color, double alpha) 3466 public override void SetText(string text, Vector3 color, double alpha)
@@ -3296,18 +3511,29 @@ namespace OpenSim.Region.Framework.Scenes
3296 { 3511 {
3297 if (e == null) 3512 if (e == null)
3298 return; 3513 return;
3299 3514
3300 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3515 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3301 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3302 // as of this comment the interval is set in AddToPhysicalScene 3516 // as of this comment the interval is set in AddToPhysicalScene
3303 if (Animator!=null) 3517 if (Animator!=null)
3304 Animator.UpdateMovementAnimations(); 3518 {
3519 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3520 { // else its will lock out other animation changes, like ground sit.
3521 Animator.UpdateMovementAnimations();
3522 m_updateCount--;
3523 }
3524 }
3305 3525
3306 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3526 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3307 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3527 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3308 3528
3309 CollisionPlane = Vector4.UnitW; 3529 CollisionPlane = Vector4.UnitW;
3310 3530
3531 if (m_lastColCount != coldata.Count)
3532 {
3533 m_updateCount = UPDATE_COUNT;
3534 m_lastColCount = coldata.Count;
3535 }
3536
3311 if (coldata.Count != 0 && Animator != null) 3537 if (coldata.Count != 0 && Animator != null)
3312 { 3538 {
3313 switch (Animator.CurrentMovementAnimation) 3539 switch (Animator.CurrentMovementAnimation)
@@ -3742,6 +3968,32 @@ namespace OpenSim.Region.Framework.Scenes
3742 return; 3968 return;
3743 } 3969 }
3744 3970
3971 XmlDocument doc = new XmlDocument();
3972 string stateData = String.Empty;
3973
3974 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
3975 if (attServ != null)
3976 {
3977 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
3978 stateData = attServ.Get(ControllingClient.AgentId.ToString());
3979 doc.LoadXml(stateData);
3980 }
3981
3982 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
3983
3984 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
3985 if (nodes.Count > 0)
3986 {
3987 foreach (XmlNode n in nodes)
3988 {
3989 XmlElement elem = (XmlElement)n;
3990 string itemID = elem.GetAttribute("ItemID");
3991 string xml = elem.InnerXml;
3992
3993 itemData[new UUID(itemID)] = xml;
3994 }
3995 }
3996
3745 List<int> attPoints = m_appearance.GetAttachedPoints(); 3997 List<int> attPoints = m_appearance.GetAttachedPoints();
3746 foreach (int p in attPoints) 3998 foreach (int p in attPoints)
3747 { 3999 {
@@ -3761,9 +4013,26 @@ namespace OpenSim.Region.Framework.Scenes
3761 4013
3762 try 4014 try
3763 { 4015 {
3764 // Rez from inventory 4016 string xmlData;
3765 UUID asset 4017 XmlDocument d = new XmlDocument();
3766 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4018 UUID asset;
4019 if (itemData.TryGetValue(itemID, out xmlData))
4020 {
4021 d.LoadXml(xmlData);
4022 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4023
4024 // Rez from inventory
4025 asset
4026 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4027
4028 }
4029 else
4030 {
4031 // Rez from inventory (with a null doc to let
4032 // CHANGED_OWNER happen)
4033 asset
4034 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4035 }
3767 4036
3768 m_log.InfoFormat( 4037 m_log.InfoFormat(
3769 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", 4038 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
@@ -3914,5 +4183,16 @@ namespace OpenSim.Region.Framework.Scenes
3914 m_reprioritization_called = false; 4183 m_reprioritization_called = false;
3915 } 4184 }
3916 } 4185 }
4186
4187 private Vector3 Quat2Euler(Quaternion rot){
4188 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4189 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4190 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4191 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4192 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4193 return(new Vector3(x,y,z));
4194 }
4195
4196
3917 } 4197 }
3918} 4198}