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.cs888
1 files changed, 713 insertions, 175 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 1e8ce22..efe3365 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;
@@ -72,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
72// { 73// {
73// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
74// } 75// }
75 76
76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 78
78 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 };
@@ -88,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
88 /// 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
89 /// issue #1716 90 /// issue #1716
90 /// </summary> 91 /// </summary>
91 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);
92 95
93 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
94 97
@@ -122,8 +125,11 @@ namespace OpenSim.Region.Framework.Scenes
122 public Vector3 lastKnownAllowedPosition; 125 public Vector3 lastKnownAllowedPosition;
123 public bool sentMessageAboutRestrictedParcelFlyingDown; 126 public bool sentMessageAboutRestrictedParcelFlyingDown;
124 public Vector4 CollisionPlane = Vector4.UnitW; 127 public Vector4 CollisionPlane = Vector4.UnitW;
125 128
129 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
130 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
126 private Vector3 m_lastPosition; 131 private Vector3 m_lastPosition;
132 private Vector3 m_lastWorldPosition;
127 private Quaternion m_lastRotation; 133 private Quaternion m_lastRotation;
128 private Vector3 m_lastVelocity; 134 private Vector3 m_lastVelocity;
129 //private int m_lastTerseSent; 135 //private int m_lastTerseSent;
@@ -156,7 +162,6 @@ namespace OpenSim.Region.Framework.Scenes
156 private int m_perfMonMS; 162 private int m_perfMonMS;
157 163
158 private bool m_setAlwaysRun; 164 private bool m_setAlwaysRun;
159
160 private bool m_forceFly; 165 private bool m_forceFly;
161 private bool m_flyDisabled; 166 private bool m_flyDisabled;
162 167
@@ -180,7 +185,8 @@ namespace OpenSim.Region.Framework.Scenes
180 protected RegionInfo m_regionInfo; 185 protected RegionInfo m_regionInfo;
181 protected ulong crossingFromRegion; 186 protected ulong crossingFromRegion;
182 187
183 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 188 private readonly Vector3[] Dir_Vectors = new Vector3[11];
189 private bool m_isNudging = false;
184 190
185 // Position of agent's camera in world (region cordinates) 191 // Position of agent's camera in world (region cordinates)
186 protected Vector3 m_CameraCenter; 192 protected Vector3 m_CameraCenter;
@@ -205,17 +211,23 @@ namespace OpenSim.Region.Framework.Scenes
205 private bool m_autopilotMoving; 211 private bool m_autopilotMoving;
206 private Vector3 m_autoPilotTarget; 212 private Vector3 m_autoPilotTarget;
207 private bool m_sitAtAutoTarget; 213 private bool m_sitAtAutoTarget;
214 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
208 215
209 private string m_nextSitAnimation = String.Empty; 216 private string m_nextSitAnimation = String.Empty;
210 217
211 //PauPaw:Proper PID Controler for autopilot************ 218 //PauPaw:Proper PID Controler for autopilot************
212 private bool m_moveToPositionInProgress; 219 private bool m_moveToPositionInProgress;
213 private Vector3 m_moveToPositionTarget; 220 private Vector3 m_moveToPositionTarget;
221 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
214 222
215 private bool m_followCamAuto; 223 private bool m_followCamAuto;
216 224
217 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
218 private const int NumMovementsBetweenRayCast = 5; 229 private const int NumMovementsBetweenRayCast = 5;
230 private List<uint> m_lastColliders = new List<uint>();
219 231
220 private bool CameraConstraintActive; 232 private bool CameraConstraintActive;
221 //private int m_moveToPositionStateStatus; 233 //private int m_moveToPositionStateStatus;
@@ -242,7 +254,9 @@ namespace OpenSim.Region.Framework.Scenes
242 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 254 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
243 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 255 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
244 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,
245 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,
246 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
247 } 261 }
248 262
@@ -449,9 +463,18 @@ namespace OpenSim.Region.Framework.Scenes
449 get 463 get
450 { 464 {
451 PhysicsActor actor = m_physicsActor; 465 PhysicsActor actor = m_physicsActor;
452 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!
453 m_pos = actor.Position; 468 m_pos = actor.Position;
454 469
470 // If we're sitting, we need to update our position
471 if (m_parentID != 0)
472 {
473 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
474 if (part != null)
475 m_parentPosition = part.AbsolutePosition;
476 }
477
455 return m_parentPosition + m_pos; 478 return m_parentPosition + m_pos;
456 } 479 }
457 set 480 set
@@ -470,7 +493,8 @@ namespace OpenSim.Region.Framework.Scenes
470 } 493 }
471 } 494 }
472 495
473 m_pos = value; 496 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
497 m_pos = value;
474 m_parentPosition = Vector3.Zero; 498 m_parentPosition = Vector3.Zero;
475 } 499 }
476 } 500 }
@@ -514,10 +538,39 @@ namespace OpenSim.Region.Framework.Scenes
514 } 538 }
515 } 539 }
516 540
541 public Quaternion OffsetRotation
542 {
543 get { return m_offsetRotation; }
544 set { m_offsetRotation = value; }
545 }
546
517 public Quaternion Rotation 547 public Quaternion Rotation
518 { 548 {
519 get { return m_bodyRot; } 549 get {
520 set { m_bodyRot = value; } 550 if (m_parentID != 0)
551 {
552 if (m_offsetRotation != null)
553 {
554 return m_offsetRotation;
555 }
556 else
557 {
558 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
559 }
560
561 }
562 else
563 {
564 return m_bodyRot;
565 }
566 }
567 set {
568 m_bodyRot = value;
569 if (m_parentID != 0)
570 {
571 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
572 }
573 }
521 } 574 }
522 575
523 public Quaternion PreviousRotation 576 public Quaternion PreviousRotation
@@ -668,7 +721,7 @@ namespace OpenSim.Region.Framework.Scenes
668 CreateSceneViewer(); 721 CreateSceneViewer();
669 m_animator = new ScenePresenceAnimator(this); 722 m_animator = new ScenePresenceAnimator(this);
670 } 723 }
671 724
672 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 725 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
673 { 726 {
674 m_rootRegionHandle = reginfo.RegionHandle; 727 m_rootRegionHandle = reginfo.RegionHandle;
@@ -700,16 +753,16 @@ namespace OpenSim.Region.Framework.Scenes
700 m_reprioritization_timer.AutoReset = false; 753 m_reprioritization_timer.AutoReset = false;
701 754
702 AdjustKnownSeeds(); 755 AdjustKnownSeeds();
703
704 // TODO: I think, this won't send anything, as we are still a child here...
705 Animator.TrySetMovementAnimation("STAND"); 756 Animator.TrySetMovementAnimation("STAND");
706
707 // we created a new ScenePresence (a new child agent) in a fresh region. 757 // we created a new ScenePresence (a new child agent) in a fresh region.
708 // Request info about all the (root) agents in this region 758 // Request info about all the (root) agents in this region
709 // Note: This won't send data *to* other clients in that region (children don't send) 759 // Note: This won't send data *to* other clients in that region (children don't send)
710 SendInitialFullUpdateToAllClients(); 760 SendInitialFullUpdateToAllClients();
711
712 RegisterToEvents(); 761 RegisterToEvents();
762 if (m_controllingClient != null)
763 {
764 m_controllingClient.ProcessPendingPackets();
765 }
713 SetDirectionVectors(); 766 SetDirectionVectors();
714 } 767 }
715 768
@@ -759,25 +812,47 @@ namespace OpenSim.Region.Framework.Scenes
759 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 812 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
760 Dir_Vectors[4] = Vector3.UnitZ; //UP 813 Dir_Vectors[4] = Vector3.UnitZ; //UP
761 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 814 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
762 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 815 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
763 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 816 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
764 Dir_Vectors[7] = -Vector3.UnitX; //BACK 817 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
818 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
819 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
765 } 820 }
766 821
767 private Vector3[] GetWalkDirectionVectors() 822 private Vector3[] GetWalkDirectionVectors()
768 { 823 {
769 Vector3[] vector = new Vector3[9]; 824 Vector3[] vector = new Vector3[11];
770 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 825 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
771 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 826 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
772 vector[2] = Vector3.UnitY; //LEFT 827 vector[2] = Vector3.UnitY; //LEFT
773 vector[3] = -Vector3.UnitY; //RIGHT 828 vector[3] = -Vector3.UnitY; //RIGHT
774 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 829 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
775 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 830 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
776 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 831 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
777 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 832 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
778 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 833 vector[8] = Vector3.UnitY; //LEFT_NUDGE
834 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
835 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
779 return vector; 836 return vector;
780 } 837 }
838
839 private bool[] GetDirectionIsNudge()
840 {
841 bool[] isNudge = new bool[11];
842 isNudge[0] = false; //FORWARD
843 isNudge[1] = false; //BACK
844 isNudge[2] = false; //LEFT
845 isNudge[3] = false; //RIGHT
846 isNudge[4] = false; //UP
847 isNudge[5] = false; //DOWN
848 isNudge[6] = true; //FORWARD_NUDGE
849 isNudge[7] = true; //BACK_NUDGE
850 isNudge[8] = true; //LEFT_NUDGE
851 isNudge[9] = true; //RIGHT_NUDGE
852 isNudge[10] = true; //DOWN_Nudge
853 return isNudge;
854 }
855
781 856
782 #endregion 857 #endregion
783 858
@@ -820,7 +895,6 @@ namespace OpenSim.Region.Framework.Scenes
820 m_grouptitle = gm.GetGroupTitle(m_uuid); 895 m_grouptitle = gm.GetGroupTitle(m_uuid);
821 896
822 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; 897 m_rootRegionHandle = m_scene.RegionInfo.RegionHandle;
823
824 m_scene.SetRootAgentScene(m_uuid); 898 m_scene.SetRootAgentScene(m_uuid);
825 899
826 // Moved this from SendInitialData to ensure that m_appearance is initialized 900 // Moved this from SendInitialData to ensure that m_appearance is initialized
@@ -839,6 +913,52 @@ namespace OpenSim.Region.Framework.Scenes
839 pos.Y = crossedBorder.BorderLine.Z - 1; 913 pos.Y = crossedBorder.BorderLine.Z - 1;
840 } 914 }
841 915
916 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
917 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
918 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
919 if (KnownChildRegionHandles.Count == 0)
920 {
921 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
922 if (land != null)
923 {
924 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
925 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && UserLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
926 {
927 pos = land.LandData.UserLocation;
928 }
929 }
930 }
931
932 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
933 {
934 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
935
936 if (pos.X < 0)
937 {
938 emergencyPos.X = (int)Constants.RegionSize + pos.X;
939 if (!(pos.Y < 0))
940 emergencyPos.Y = pos.Y;
941 if (!(pos.Z < 0))
942 emergencyPos.Z = pos.Z;
943 }
944 if (pos.Y < 0)
945 {
946 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
947 if (!(pos.X < 0))
948 emergencyPos.X = pos.X;
949 if (!(pos.Z < 0))
950 emergencyPos.Z = pos.Z;
951 }
952 if (pos.Z < 0)
953 {
954 emergencyPos.Z = 128;
955 if (!(pos.Y < 0))
956 emergencyPos.Y = pos.Y;
957 if (!(pos.X < 0))
958 emergencyPos.X = pos.X;
959 }
960 }
961
842 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 962 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
843 { 963 {
844 m_log.WarnFormat( 964 m_log.WarnFormat(
@@ -971,9 +1091,10 @@ namespace OpenSim.Region.Framework.Scenes
971 public void Teleport(Vector3 pos) 1091 public void Teleport(Vector3 pos)
972 { 1092 {
973 bool isFlying = false; 1093 bool isFlying = false;
1094
974 if (m_physicsActor != null) 1095 if (m_physicsActor != null)
975 isFlying = m_physicsActor.Flying; 1096 isFlying = m_physicsActor.Flying;
976 1097
977 RemoveFromPhysicalScene(); 1098 RemoveFromPhysicalScene();
978 Velocity = Vector3.Zero; 1099 Velocity = Vector3.Zero;
979 AbsolutePosition = pos; 1100 AbsolutePosition = pos;
@@ -985,6 +1106,7 @@ namespace OpenSim.Region.Framework.Scenes
985 } 1106 }
986 1107
987 SendTerseUpdateToAllClients(); 1108 SendTerseUpdateToAllClients();
1109
988 } 1110 }
989 1111
990 public void TeleportWithMomentum(Vector3 pos) 1112 public void TeleportWithMomentum(Vector3 pos)
@@ -1098,7 +1220,6 @@ namespace OpenSim.Region.Framework.Scenes
1098 pos.Z = ground + 1.5f; 1220 pos.Z = ground + 1.5f;
1099 AbsolutePosition = pos; 1221 AbsolutePosition = pos;
1100 } 1222 }
1101
1102 m_isChildAgent = false; 1223 m_isChildAgent = false;
1103 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1224 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1104 MakeRootAgent(AbsolutePosition, m_flying); 1225 MakeRootAgent(AbsolutePosition, m_flying);
@@ -1197,6 +1318,7 @@ namespace OpenSim.Region.Framework.Scenes
1197 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1318 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1198 1319
1199 m_pos = m_LastFinitePos; 1320 m_pos = m_LastFinitePos;
1321
1200 if (!m_pos.IsFinite()) 1322 if (!m_pos.IsFinite())
1201 { 1323 {
1202 m_pos.X = 127f; 1324 m_pos.X = 127f;
@@ -1263,7 +1385,6 @@ namespace OpenSim.Region.Framework.Scenes
1263 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1385 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1264 } 1386 }
1265 } 1387 }
1266
1267 lock (scriptedcontrols) 1388 lock (scriptedcontrols)
1268 { 1389 {
1269 if (scriptedcontrols.Count > 0) 1390 if (scriptedcontrols.Count > 0)
@@ -1278,6 +1399,9 @@ namespace OpenSim.Region.Framework.Scenes
1278 1399
1279 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1400 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1280 { 1401 {
1402 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1403 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1404
1281 // TODO: This doesn't prevent the user from walking yet. 1405 // TODO: This doesn't prevent the user from walking yet.
1282 // Setting parent ID would fix this, if we knew what value 1406 // Setting parent ID would fix this, if we knew what value
1283 // to use. Or we could add a m_isSitting variable. 1407 // to use. Or we could add a m_isSitting variable.
@@ -1332,6 +1456,11 @@ namespace OpenSim.Region.Framework.Scenes
1332 update_rotation = true; 1456 update_rotation = true;
1333 } 1457 }
1334 1458
1459 //guilty until proven innocent..
1460 bool Nudging = true;
1461 //Basically, if there is at least one non-nudge control then we don't need
1462 //to worry about stopping the avatar
1463
1335 if (m_parentID == 0) 1464 if (m_parentID == 0)
1336 { 1465 {
1337 bool bAllowUpdateMoveToPosition = false; 1466 bool bAllowUpdateMoveToPosition = false;
@@ -1346,9 +1475,12 @@ namespace OpenSim.Region.Framework.Scenes
1346 else 1475 else
1347 dirVectors = Dir_Vectors; 1476 dirVectors = Dir_Vectors;
1348 1477
1349 // The fact that m_movementflag is a byte needs to be fixed 1478 bool[] isNudge = GetDirectionIsNudge();
1350 // it really should be a uint 1479
1351 uint nudgehack = 250; 1480
1481
1482
1483
1352 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1484 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1353 { 1485 {
1354 if (((uint)flags & (uint)DCF) != 0) 1486 if (((uint)flags & (uint)DCF) != 0)
@@ -1358,40 +1490,28 @@ namespace OpenSim.Region.Framework.Scenes
1358 try 1490 try
1359 { 1491 {
1360 agent_control_v3 += dirVectors[i]; 1492 agent_control_v3 += dirVectors[i];
1361 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1493 if (isNudge[i] == false)
1494 {
1495 Nudging = false;
1496 }
1362 } 1497 }
1363 catch (IndexOutOfRangeException) 1498 catch (IndexOutOfRangeException)
1364 { 1499 {
1365 // Why did I get this? 1500 // Why did I get this?
1366 } 1501 }
1367 1502
1368 if ((m_movementflag & (byte)(uint)DCF) == 0) 1503 if ((m_movementflag & (uint)DCF) == 0)
1369 { 1504 {
1370 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1371 {
1372 m_movementflag |= (byte)nudgehack;
1373 }
1374 m_movementflag += (byte)(uint)DCF; 1505 m_movementflag += (byte)(uint)DCF;
1375 update_movementflag = true; 1506 update_movementflag = true;
1376 } 1507 }
1377 } 1508 }
1378 else 1509 else
1379 { 1510 {
1380 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1511 if ((m_movementflag & (uint)DCF) != 0)
1381 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1382 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1383 ) // This or is for Nudge forward
1384 { 1512 {
1385 m_movementflag -= ((byte)(uint)DCF); 1513 m_movementflag -= (byte)(uint)DCF;
1386
1387 update_movementflag = true; 1514 update_movementflag = true;
1388 /*
1389 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1390 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1391 {
1392 m_log.Debug("Removed Hack flag");
1393 }
1394 */
1395 } 1515 }
1396 else 1516 else
1397 { 1517 {
@@ -1400,7 +1520,6 @@ namespace OpenSim.Region.Framework.Scenes
1400 } 1520 }
1401 i++; 1521 i++;
1402 } 1522 }
1403
1404 //Paupaw:Do Proper PID for Autopilot here 1523 //Paupaw:Do Proper PID for Autopilot here
1405 if (bResetMoveToPosition) 1524 if (bResetMoveToPosition)
1406 { 1525 {
@@ -1435,6 +1554,9 @@ namespace OpenSim.Region.Framework.Scenes
1435 // Ignore z component of vector 1554 // Ignore z component of vector
1436 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1555 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1437 LocalVectorToTarget2D.Normalize(); 1556 LocalVectorToTarget2D.Normalize();
1557
1558 //We're not nudging
1559 Nudging = false;
1438 agent_control_v3 += LocalVectorToTarget2D; 1560 agent_control_v3 += LocalVectorToTarget2D;
1439 1561
1440 // update avatar movement flags. the avatar coordinate system is as follows: 1562 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1523,13 +1645,13 @@ namespace OpenSim.Region.Framework.Scenes
1523 // m_log.DebugFormat( 1645 // m_log.DebugFormat(
1524 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1646 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1525 1647
1526 AddNewMovement(agent_control_v3, q); 1648 AddNewMovement(agent_control_v3, q, Nudging);
1527 1649
1528 1650
1529 } 1651 }
1530 } 1652 }
1531 1653
1532 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1654 if (update_movementflag && !SitGround)
1533 Animator.UpdateMovementAnimations(); 1655 Animator.UpdateMovementAnimations();
1534 1656
1535 m_scene.EventManager.TriggerOnClientMovement(this); 1657 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1544,7 +1666,6 @@ namespace OpenSim.Region.Framework.Scenes
1544 m_sitAtAutoTarget = false; 1666 m_sitAtAutoTarget = false;
1545 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1667 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1546 //proxy.PCode = (byte)PCode.ParticleSystem; 1668 //proxy.PCode = (byte)PCode.ParticleSystem;
1547
1548 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1669 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1549 proxyObjectGroup.AttachToScene(m_scene); 1670 proxyObjectGroup.AttachToScene(m_scene);
1550 1671
@@ -1586,7 +1707,7 @@ namespace OpenSim.Region.Framework.Scenes
1586 } 1707 }
1587 m_moveToPositionInProgress = true; 1708 m_moveToPositionInProgress = true;
1588 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1709 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1589 } 1710 }
1590 catch (Exception ex) 1711 catch (Exception ex)
1591 { 1712 {
1592 //Why did I get this error? 1713 //Why did I get this error?
@@ -1608,7 +1729,7 @@ namespace OpenSim.Region.Framework.Scenes
1608 Velocity = Vector3.Zero; 1729 Velocity = Vector3.Zero;
1609 SendFullUpdateToAllClients(); 1730 SendFullUpdateToAllClients();
1610 1731
1611 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1732 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1612 } 1733 }
1613 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1734 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1614 m_requestedSitTargetUUID = UUID.Zero; 1735 m_requestedSitTargetUUID = UUID.Zero;
@@ -1645,50 +1766,84 @@ namespace OpenSim.Region.Framework.Scenes
1645 1766
1646 if (m_parentID != 0) 1767 if (m_parentID != 0)
1647 { 1768 {
1648 m_log.Debug("StandupCode Executed"); 1769 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1649 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1650 if (part != null) 1770 if (part != null)
1651 { 1771 {
1772 part.TaskInventory.LockItemsForRead(true);
1652 TaskInventoryDictionary taskIDict = part.TaskInventory; 1773 TaskInventoryDictionary taskIDict = part.TaskInventory;
1653 if (taskIDict != null) 1774 if (taskIDict != null)
1654 { 1775 {
1655 lock (taskIDict) 1776 foreach (UUID taskID in taskIDict.Keys)
1656 { 1777 {
1657 foreach (UUID taskID in taskIDict.Keys) 1778 UnRegisterControlEventsToScript(LocalId, taskID);
1658 { 1779 taskIDict[taskID].PermsMask &= ~(
1659 UnRegisterControlEventsToScript(LocalId, taskID); 1780 2048 | //PERMISSION_CONTROL_CAMERA
1660 taskIDict[taskID].PermsMask &= ~( 1781 4); // PERMISSION_TAKE_CONTROLS
1661 2048 | //PERMISSION_CONTROL_CAMERA
1662 4); // PERMISSION_TAKE_CONTROLS
1663 }
1664 } 1782 }
1665
1666 } 1783 }
1784 part.TaskInventory.LockItemsForRead(false);
1667 // Reset sit target. 1785 // Reset sit target.
1668 if (part.GetAvatarOnSitTarget() == UUID) 1786 if (part.GetAvatarOnSitTarget() == UUID)
1669 part.SetAvatarOnSitTarget(UUID.Zero); 1787 part.SetAvatarOnSitTarget(UUID.Zero);
1670
1671 m_parentPosition = part.GetWorldPosition(); 1788 m_parentPosition = part.GetWorldPosition();
1672 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1789 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1673 } 1790 }
1791 // part.GetWorldRotation() is the rotation of the object being sat on
1792 // Rotation is the sittiing Av's rotation
1793
1794 Quaternion partRot;
1795// if (part.LinkNum == 1)
1796// { // Root prim of linkset
1797// partRot = part.ParentGroup.RootPart.RotationOffset;
1798// }
1799// else
1800// { // single or child prim
1801
1802// }
1803 if (part == null) //CW: Part may be gone. llDie() for example.
1804 {
1805 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1806 }
1807 else
1808 {
1809 partRot = part.GetWorldRotation();
1810 }
1811
1812 Quaternion partIRot = Quaternion.Inverse(partRot);
1674 1813
1814 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1815 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1816
1817
1675 if (m_physicsActor == null) 1818 if (m_physicsActor == null)
1676 { 1819 {
1677 AddToPhysicalScene(false); 1820 AddToPhysicalScene(false);
1678 } 1821 }
1679 1822 //CW: If the part isn't null then we can set the current position
1680 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1823 if (part != null)
1681 m_parentPosition = Vector3.Zero; 1824 {
1682 1825 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1683 m_parentID = 0; 1826 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1827 part.IsOccupied = false;
1828 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1829 }
1830 else
1831 {
1832 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1833 AbsolutePosition = m_lastWorldPosition;
1834 }
1835
1836 m_parentPosition = Vector3.Zero;
1837 m_parentID = 0;
1838 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1684 SendFullUpdateToAllClients(); 1839 SendFullUpdateToAllClients();
1685 m_requestedSitTargetID = 0; 1840 m_requestedSitTargetID = 0;
1841
1686 if ((m_physicsActor != null) && (m_avHeight > 0)) 1842 if ((m_physicsActor != null) && (m_avHeight > 0))
1687 { 1843 {
1688 SetHeight(m_avHeight); 1844 SetHeight(m_avHeight);
1689 } 1845 }
1690 } 1846 }
1691
1692 Animator.TrySetMovementAnimation("STAND"); 1847 Animator.TrySetMovementAnimation("STAND");
1693 } 1848 }
1694 1849
@@ -1719,13 +1874,9 @@ namespace OpenSim.Region.Framework.Scenes
1719 Vector3 avSitOffSet = part.SitTargetPosition; 1874 Vector3 avSitOffSet = part.SitTargetPosition;
1720 Quaternion avSitOrientation = part.SitTargetOrientation; 1875 Quaternion avSitOrientation = part.SitTargetOrientation;
1721 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1876 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1722 1877 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1723 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1878 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1724 bool SitTargetisSet = 1879 if (SitTargetisSet && !SitTargetOccupied)
1725 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1726 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1727
1728 if (SitTargetisSet && SitTargetUnOccupied)
1729 { 1880 {
1730 //switch the target to this prim 1881 //switch the target to this prim
1731 return part; 1882 return part;
@@ -1739,84 +1890,156 @@ namespace OpenSim.Region.Framework.Scenes
1739 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1890 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1740 { 1891 {
1741 bool autopilot = true; 1892 bool autopilot = true;
1893 Vector3 autopilotTarget = new Vector3();
1894 Quaternion sitOrientation = Quaternion.Identity;
1742 Vector3 pos = new Vector3(); 1895 Vector3 pos = new Vector3();
1743 Quaternion sitOrientation = pSitOrientation;
1744 Vector3 cameraEyeOffset = Vector3.Zero; 1896 Vector3 cameraEyeOffset = Vector3.Zero;
1745 Vector3 cameraAtOffset = Vector3.Zero; 1897 Vector3 cameraAtOffset = Vector3.Zero;
1746 bool forceMouselook = false; 1898 bool forceMouselook = false;
1747 1899
1748 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1900 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1749 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1901 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1750 if (part != null) 1902 if (part == null) return;
1751 { 1903
1752 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1904 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1753 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1905 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1754 1906
1755 // Is a sit target available? 1907 // part is the prim to sit on
1756 Vector3 avSitOffSet = part.SitTargetPosition; 1908 // offset is the world-ref vector distance from that prim center to the click-spot
1757 Quaternion avSitOrientation = part.SitTargetOrientation; 1909 // UUID is the UUID of the Avatar doing the clicking
1758 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1910
1759 1911 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1760 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1912
1761 bool SitTargetisSet = 1913 // Is a sit target available?
1762 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1914 Vector3 avSitOffSet = part.SitTargetPosition;
1763 ( 1915 Quaternion avSitOrientation = part.SitTargetOrientation;
1764 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1916
1765 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1917 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1766 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1918 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1767 ) 1919 Quaternion partRot;
1768 )); 1920// if (part.LinkNum == 1)
1769 1921// { // Root prim of linkset
1770 if (SitTargetisSet && SitTargetUnOccupied) 1922// partRot = part.ParentGroup.RootPart.RotationOffset;
1771 { 1923// }
1772 part.SetAvatarOnSitTarget(UUID); 1924// else
1773 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1925// { // single or child prim
1774 sitOrientation = avSitOrientation; 1926 partRot = part.GetWorldRotation();
1775 autopilot = false; 1927// }
1776 } 1928 Quaternion partIRot = Quaternion.Inverse(partRot);
1777 1929//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1778 pos = part.AbsolutePosition + offset; 1930 // Sit analysis rewritten by KF 091125
1779 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1931 if (SitTargetisSet) // scipted sit
1780 //{ 1932 {
1781 // offset = pos; 1933 if (!part.IsOccupied)
1782 //autopilot = false; 1934 {
1783 //} 1935//Console.WriteLine("Scripted, unoccupied");
1784 if (m_physicsActor != null) 1936 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1785 { 1937 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1786 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1938 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1787 // We can remove the physicsActor until they stand up. 1939 OffsetRotation = avSitOrientation;
1788 m_sitAvatarHeight = m_physicsActor.Size.Z; 1940 autopilot = false; // Jump direct to scripted llSitPos()
1789 1941 }
1790 if (autopilot) 1942 else
1791 { 1943 {
1792 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1944//Console.WriteLine("Scripted, occupied");
1793 { 1945 return;
1794 autopilot = false; 1946 }
1947 }
1948 else // Not Scripted
1949 {
1950 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1951 {
1952 // large prim & offset, ignore if other Avs sitting
1953// offset.Z -= 0.05f;
1954 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1955 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1956
1957//Console.WriteLine(" offset ={0}", offset);
1958//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1959//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1960
1961 }
1962 else // small offset
1963 {
1964//Console.WriteLine("Small offset");
1965 if (!part.IsOccupied)
1966 {
1967 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1968 autopilotTarget = part.AbsolutePosition;
1969//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
1970 }
1971 else return; // occupied small
1972 } // end large/small
1973 } // end Scripted/not
1974 cameraAtOffset = part.GetCameraAtOffset();
1975 cameraEyeOffset = part.GetCameraEyeOffset();
1976 forceMouselook = part.GetForceMouselook();
1977 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1978 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1795 1979
1796 RemoveFromPhysicalScene(); 1980 if (m_physicsActor != null)
1797 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1981 {
1798 } 1982 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1799 } 1983 // We can remove the physicsActor until they stand up.
1800 else 1984 m_sitAvatarHeight = m_physicsActor.Size.Z;
1985 if (autopilot)
1986 { // its not a scripted sit
1987// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1988 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1801 { 1989 {
1990 autopilot = false; // close enough
1991 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1992 Not using the part's position because returning the AV to the last known standing
1993 position is likely to be more friendly, isn't it? */
1802 RemoveFromPhysicalScene(); 1994 RemoveFromPhysicalScene();
1803 } 1995 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1996 } // else the autopilot will get us close
1997 }
1998 else
1999 { // its a scripted sit
2000 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2001 I *am* using the part's position this time because we have no real idea how far away
2002 the avatar is from the sit target. */
2003 RemoveFromPhysicalScene();
1804 } 2004 }
1805
1806 cameraAtOffset = part.GetCameraAtOffset();
1807 cameraEyeOffset = part.GetCameraEyeOffset();
1808 forceMouselook = part.GetForceMouselook();
1809 } 2005 }
1810 2006 else return; // physactor is null!
1811 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2007
1812 m_requestedSitTargetUUID = targetID; 2008 Vector3 offsetr; // = offset * partIRot;
2009 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2010 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2011 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2012 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2013 offsetr = offset * partIRot;
2014//
2015 // else
2016 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2017 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2018 // (offset * partRot);
2019 // }
2020
2021//Console.WriteLine(" ");
2022//Console.WriteLine("link number ={0}", part.LinkNum);
2023//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2024//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2025//Console.WriteLine("Click offst ={0}", offset);
2026//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2027//Console.WriteLine("offsetr ={0}", offsetr);
2028//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2029//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2030
2031 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2032 ControllingClient.SendSitResponse(part.ParentGroup.UUID, offsetr + part.OffsetPosition, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2033
2034 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1813 // This calls HandleAgentSit twice, once from here, and the client calls 2035 // This calls HandleAgentSit twice, once from here, and the client calls
1814 // HandleAgentSit itself after it gets to the location 2036 // HandleAgentSit itself after it gets to the location
1815 // It doesn't get to the location until we've moved them there though 2037 // It doesn't get to the location until we've moved them there though
1816 // which happens in HandleAgentSit :P 2038 // which happens in HandleAgentSit :P
1817 m_autopilotMoving = autopilot; 2039 m_autopilotMoving = autopilot;
1818 m_autoPilotTarget = pos; 2040 m_autoPilotTarget = autopilotTarget;
1819 m_sitAtAutoTarget = autopilot; 2041 m_sitAtAutoTarget = autopilot;
2042 m_initialSitTarget = autopilotTarget;
1820 if (!autopilot) 2043 if (!autopilot)
1821 HandleAgentSit(remoteClient, UUID); 2044 HandleAgentSit(remoteClient, UUID);
1822 } 2045 }
@@ -2111,47 +2334,122 @@ namespace OpenSim.Region.Framework.Scenes
2111 { 2334 {
2112 if (part != null) 2335 if (part != null)
2113 { 2336 {
2337//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2114 if (part.GetAvatarOnSitTarget() == UUID) 2338 if (part.GetAvatarOnSitTarget() == UUID)
2115 { 2339 {
2340//Console.WriteLine("Scripted Sit");
2341 // Scripted sit
2116 Vector3 sitTargetPos = part.SitTargetPosition; 2342 Vector3 sitTargetPos = part.SitTargetPosition;
2117 Quaternion sitTargetOrient = part.SitTargetOrientation; 2343 Quaternion sitTargetOrient = part.SitTargetOrientation;
2118
2119 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2120 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2121
2122 //Quaternion result = (sitTargetOrient * vq) * nq;
2123
2124 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2344 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2125 m_pos += SIT_TARGET_ADJUSTMENT; 2345 m_pos += SIT_TARGET_ADJUSTMENT;
2126 m_bodyRot = sitTargetOrient; 2346 m_bodyRot = sitTargetOrient;
2127 //Rotation = sitTargetOrient;
2128 m_parentPosition = part.AbsolutePosition; 2347 m_parentPosition = part.AbsolutePosition;
2129 2348 part.IsOccupied = true;
2130 //SendTerseUpdateToAllClients(); 2349 part.ParentGroup.AddAvatar(agentID);
2350Console.WriteLine("Scripted Sit ofset {0}", m_pos);
2131 } 2351 }
2132 else 2352 else
2133 { 2353 {
2134 m_pos -= part.AbsolutePosition; 2354 // if m_avUnscriptedSitPos is zero then Av sits above center
2355 // Else Av sits at m_avUnscriptedSitPos
2356
2357 // Non-scripted sit by Kitto Flora 21Nov09
2358 // Calculate angle of line from prim to Av
2359 Quaternion partIRot;
2360// if (part.LinkNum == 1)
2361// { // Root prim of linkset
2362// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2363// }
2364// else
2365// { // single or child prim
2366 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2367// }
2368 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2369 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2370 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2371 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2372 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2373 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2374 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2375 // Av sits at world euler <0,0, z>, translated by part rotation
2376 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2377
2135 m_parentPosition = part.AbsolutePosition; 2378 m_parentPosition = part.AbsolutePosition;
2136 } 2379 part.IsOccupied = true;
2380 part.ParentGroup.AddAvatar(agentID);
2381 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2382 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2383 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2384 m_avUnscriptedSitPos; // adds click offset, if any
2385 //Set up raytrace to find top surface of prim
2386 Vector3 size = part.Scale;
2387 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2388 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2389 Vector3 down = new Vector3(0f, 0f, -1f);
2390//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2391 m_scene.PhysicsScene.RaycastWorld(
2392 start, // Vector3 position,
2393 down, // Vector3 direction,
2394 mag, // float length,
2395 SitAltitudeCallback); // retMethod
2396 } // end scripted/not
2137 } 2397 }
2138 else 2398 else // no Av
2139 { 2399 {
2140 return; 2400 return;
2141 } 2401 }
2142 } 2402 }
2143 m_parentID = m_requestedSitTargetID; 2403
2404 //We want our offsets to reference the root prim, not the child we may have sat on
2405 if (!part.IsRoot)
2406 {
2407 m_parentID = part.ParentGroup.RootPart.LocalId;
2408 m_pos += part.OffsetPosition;
2409 }
2410 else
2411 {
2412 m_parentID = m_requestedSitTargetID;
2413 }
2144 2414
2145 Velocity = Vector3.Zero; 2415 Velocity = Vector3.Zero;
2146 RemoveFromPhysicalScene(); 2416 RemoveFromPhysicalScene();
2147 2417
2148 Animator.TrySetMovementAnimation(sitAnimation); 2418 Animator.TrySetMovementAnimation(sitAnimation);
2149 SendFullUpdateToAllClients(); 2419 SendFullUpdateToAllClients();
2150 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2151 // So we're also sending a terse update (which has avatar rotation)
2152 // [Update] We do now.
2153 //SendTerseUpdateToAllClients();
2154 } 2420 }
2421
2422 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2423 {
2424 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2425 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2426 if(hitYN)
2427 {
2428 // m_pos = Av offset from prim center to make look like on center
2429 // m_parentPosition = Actual center pos of prim
2430 // collisionPoint = spot on prim where we want to sit
2431 // collisionPoint.Z = global sit surface height
2432 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2433 Quaternion partIRot;
2434// if (part.LinkNum == 1)
2435/// { // Root prim of linkset
2436// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2437// }
2438// else
2439// { // single or child prim
2440 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2441// }
2442 if (m_initialSitTarget != null)
2443 {
2444 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2445 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2446 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2447 m_pos += offset;
2448 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2449 }
2450
2451 }
2452 } // End SitAltitudeCallback KF.
2155 2453
2156 /// <summary> 2454 /// <summary>
2157 /// Event handler for the 'Always run' setting on the client 2455 /// Event handler for the 'Always run' setting on the client
@@ -2181,7 +2479,7 @@ namespace OpenSim.Region.Framework.Scenes
2181 /// </summary> 2479 /// </summary>
2182 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2480 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2183 /// <param name="rotation">The direction in which this avatar should now face. 2481 /// <param name="rotation">The direction in which this avatar should now face.
2184 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2482 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2185 { 2483 {
2186 if (m_isChildAgent) 2484 if (m_isChildAgent)
2187 { 2485 {
@@ -2222,10 +2520,11 @@ namespace OpenSim.Region.Framework.Scenes
2222 Rotation = rotation; 2520 Rotation = rotation;
2223 Vector3 direc = vec * rotation; 2521 Vector3 direc = vec * rotation;
2224 direc.Normalize(); 2522 direc.Normalize();
2523 PhysicsActor actor = m_physicsActor;
2524 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2225 2525
2226 direc *= 0.03f * 128f * m_speedModifier; 2526 direc *= 0.03f * 128f * m_speedModifier;
2227 2527
2228 PhysicsActor actor = m_physicsActor;
2229 if (actor != null) 2528 if (actor != null)
2230 { 2529 {
2231 if (actor.Flying) 2530 if (actor.Flying)
@@ -2247,18 +2546,25 @@ namespace OpenSim.Region.Framework.Scenes
2247 { 2546 {
2248 if (direc.Z > 2.0f) 2547 if (direc.Z > 2.0f)
2249 { 2548 {
2250 direc.Z *= 3.0f; 2549 if(m_animator.m_animTickJump == -1)
2251 2550 {
2252 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2551 direc.Z *= 3.0f; // jump
2253 Animator.TrySetMovementAnimation("PREJUMP"); 2552 }
2254 Animator.TrySetMovementAnimation("JUMP"); 2553 else
2554 {
2555 direc.Z *= 0.1f; // prejump
2556 }
2557 /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2558 Animator.TrySetMovementAnimation("PREJUMP");
2559 Animator.TrySetMovementAnimation("JUMP");
2560 */
2255 } 2561 }
2256 } 2562 }
2257 } 2563 }
2258 2564
2259 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2565 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2260 m_forceToApply = direc; 2566 m_forceToApply = direc;
2261 2567 m_isNudging = Nudging;
2262 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2568 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2263 } 2569 }
2264 2570
@@ -2273,7 +2579,7 @@ namespace OpenSim.Region.Framework.Scenes
2273 const float POSITION_TOLERANCE = 0.05f; 2579 const float POSITION_TOLERANCE = 0.05f;
2274 //const int TIME_MS_TOLERANCE = 3000; 2580 //const int TIME_MS_TOLERANCE = 3000;
2275 2581
2276 SendPrimUpdates(); 2582
2277 2583
2278 if (m_isChildAgent == false) 2584 if (m_isChildAgent == false)
2279 { 2585 {
@@ -2303,6 +2609,9 @@ namespace OpenSim.Region.Framework.Scenes
2303 CheckForBorderCrossing(); 2609 CheckForBorderCrossing();
2304 CheckForSignificantMovement(); // sends update to the modules. 2610 CheckForSignificantMovement(); // sends update to the modules.
2305 } 2611 }
2612
2613 //Sending prim updates AFTER the avatar terse updates are sent
2614 SendPrimUpdates();
2306 } 2615 }
2307 2616
2308 #endregion 2617 #endregion
@@ -3087,6 +3396,7 @@ namespace OpenSim.Region.Framework.Scenes
3087 m_callbackURI = cAgent.CallbackURI; 3396 m_callbackURI = cAgent.CallbackURI;
3088 3397
3089 m_pos = cAgent.Position; 3398 m_pos = cAgent.Position;
3399
3090 m_velocity = cAgent.Velocity; 3400 m_velocity = cAgent.Velocity;
3091 m_CameraCenter = cAgent.Center; 3401 m_CameraCenter = cAgent.Center;
3092 //m_avHeight = cAgent.Size.Z; 3402 //m_avHeight = cAgent.Size.Z;
@@ -3197,14 +3507,25 @@ namespace OpenSim.Region.Framework.Scenes
3197 { 3507 {
3198 if (m_forceToApply.HasValue) 3508 if (m_forceToApply.HasValue)
3199 { 3509 {
3200 Vector3 force = m_forceToApply.Value;
3201 3510
3511 Vector3 force = m_forceToApply.Value;
3202 m_updateflag = true; 3512 m_updateflag = true;
3203// movementvector = force;
3204 Velocity = force; 3513 Velocity = force;
3205 3514
3206 m_forceToApply = null; 3515 m_forceToApply = null;
3207 } 3516 }
3517 else
3518 {
3519 if (m_isNudging)
3520 {
3521 Vector3 force = Vector3.Zero;
3522
3523 m_updateflag = true;
3524 Velocity = force;
3525 m_isNudging = false;
3526 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3527 }
3528 }
3208 } 3529 }
3209 3530
3210 public override void SetText(string text, Vector3 color, double alpha) 3531 public override void SetText(string text, Vector3 color, double alpha)
@@ -3255,18 +3576,29 @@ namespace OpenSim.Region.Framework.Scenes
3255 { 3576 {
3256 if (e == null) 3577 if (e == null)
3257 return; 3578 return;
3258 3579
3259 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3580 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3260 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3261 // as of this comment the interval is set in AddToPhysicalScene 3581 // as of this comment the interval is set in AddToPhysicalScene
3262 if (Animator!=null) 3582 if (Animator!=null)
3263 Animator.UpdateMovementAnimations(); 3583 {
3584 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3585 { // else its will lock out other animation changes, like ground sit.
3586 Animator.UpdateMovementAnimations();
3587 m_updateCount--;
3588 }
3589 }
3264 3590
3265 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3591 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3266 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3592 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3267 3593
3268 CollisionPlane = Vector4.UnitW; 3594 CollisionPlane = Vector4.UnitW;
3269 3595
3596 if (m_lastColCount != coldata.Count)
3597 {
3598 m_updateCount = UPDATE_COUNT;
3599 m_lastColCount = coldata.Count;
3600 }
3601
3270 if (coldata.Count != 0 && Animator != null) 3602 if (coldata.Count != 0 && Animator != null)
3271 { 3603 {
3272 switch (Animator.CurrentMovementAnimation) 3604 switch (Animator.CurrentMovementAnimation)
@@ -3296,6 +3628,148 @@ namespace OpenSim.Region.Framework.Scenes
3296 } 3628 }
3297 } 3629 }
3298 3630
3631 List<uint> thisHitColliders = new List<uint>();
3632 List<uint> endedColliders = new List<uint>();
3633 List<uint> startedColliders = new List<uint>();
3634
3635 foreach (uint localid in coldata.Keys)
3636 {
3637 thisHitColliders.Add(localid);
3638 if (!m_lastColliders.Contains(localid))
3639 {
3640 startedColliders.Add(localid);
3641 }
3642 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3643 }
3644
3645 // calculate things that ended colliding
3646 foreach (uint localID in m_lastColliders)
3647 {
3648 if (!thisHitColliders.Contains(localID))
3649 {
3650 endedColliders.Add(localID);
3651 }
3652 }
3653 //add the items that started colliding this time to the last colliders list.
3654 foreach (uint localID in startedColliders)
3655 {
3656 m_lastColliders.Add(localID);
3657 }
3658 // remove things that ended colliding from the last colliders list
3659 foreach (uint localID in endedColliders)
3660 {
3661 m_lastColliders.Remove(localID);
3662 }
3663
3664 // do event notification
3665 if (startedColliders.Count > 0)
3666 {
3667 ColliderArgs StartCollidingMessage = new ColliderArgs();
3668 List<DetectedObject> colliding = new List<DetectedObject>();
3669 foreach (uint localId in startedColliders)
3670 {
3671 if (localId == 0)
3672 continue;
3673
3674 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3675 string data = "";
3676 if (obj != null)
3677 {
3678 DetectedObject detobj = new DetectedObject();
3679 detobj.keyUUID = obj.UUID;
3680 detobj.nameStr = obj.Name;
3681 detobj.ownerUUID = obj.OwnerID;
3682 detobj.posVector = obj.AbsolutePosition;
3683 detobj.rotQuat = obj.GetWorldRotation();
3684 detobj.velVector = obj.Velocity;
3685 detobj.colliderType = 0;
3686 detobj.groupUUID = obj.GroupID;
3687 colliding.Add(detobj);
3688 }
3689 }
3690
3691 if (colliding.Count > 0)
3692 {
3693 StartCollidingMessage.Colliders = colliding;
3694
3695 foreach (SceneObjectGroup att in Attachments)
3696 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3697 }
3698 }
3699
3700 if (endedColliders.Count > 0)
3701 {
3702 ColliderArgs EndCollidingMessage = new ColliderArgs();
3703 List<DetectedObject> colliding = new List<DetectedObject>();
3704 foreach (uint localId in endedColliders)
3705 {
3706 if (localId == 0)
3707 continue;
3708
3709 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3710 string data = "";
3711 if (obj != null)
3712 {
3713 DetectedObject detobj = new DetectedObject();
3714 detobj.keyUUID = obj.UUID;
3715 detobj.nameStr = obj.Name;
3716 detobj.ownerUUID = obj.OwnerID;
3717 detobj.posVector = obj.AbsolutePosition;
3718 detobj.rotQuat = obj.GetWorldRotation();
3719 detobj.velVector = obj.Velocity;
3720 detobj.colliderType = 0;
3721 detobj.groupUUID = obj.GroupID;
3722 colliding.Add(detobj);
3723 }
3724 }
3725
3726 if (colliding.Count > 0)
3727 {
3728 EndCollidingMessage.Colliders = colliding;
3729
3730 foreach (SceneObjectGroup att in Attachments)
3731 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3732 }
3733 }
3734
3735 if (thisHitColliders.Count > 0)
3736 {
3737 ColliderArgs CollidingMessage = new ColliderArgs();
3738 List<DetectedObject> colliding = new List<DetectedObject>();
3739 foreach (uint localId in thisHitColliders)
3740 {
3741 if (localId == 0)
3742 continue;
3743
3744 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3745 string data = "";
3746 if (obj != null)
3747 {
3748 DetectedObject detobj = new DetectedObject();
3749 detobj.keyUUID = obj.UUID;
3750 detobj.nameStr = obj.Name;
3751 detobj.ownerUUID = obj.OwnerID;
3752 detobj.posVector = obj.AbsolutePosition;
3753 detobj.rotQuat = obj.GetWorldRotation();
3754 detobj.velVector = obj.Velocity;
3755 detobj.colliderType = 0;
3756 detobj.groupUUID = obj.GroupID;
3757 colliding.Add(detobj);
3758 }
3759 }
3760
3761 if (colliding.Count > 0)
3762 {
3763 CollidingMessage.Colliders = colliding;
3764
3765 lock (m_attachments)
3766 {
3767 foreach (SceneObjectGroup att in m_attachments)
3768 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3769 }
3770 }
3771 }
3772
3299 if (m_invulnerable) 3773 if (m_invulnerable)
3300 return; 3774 return;
3301 3775
@@ -3470,7 +3944,10 @@ namespace OpenSim.Region.Framework.Scenes
3470 m_scene = scene; 3944 m_scene = scene;
3471 3945
3472 RegisterToEvents(); 3946 RegisterToEvents();
3473 3947 if (m_controllingClient != null)
3948 {
3949 m_controllingClient.ProcessPendingPackets();
3950 }
3474 /* 3951 /*
3475 AbsolutePosition = client.StartPos; 3952 AbsolutePosition = client.StartPos;
3476 3953
@@ -3700,6 +4177,39 @@ namespace OpenSim.Region.Framework.Scenes
3700 return; 4177 return;
3701 } 4178 }
3702 4179
4180 XmlDocument doc = new XmlDocument();
4181 string stateData = String.Empty;
4182
4183 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4184 if (attServ != null)
4185 {
4186 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4187 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4188 if (stateData != String.Empty)
4189 {
4190 try
4191 {
4192 doc.LoadXml(stateData);
4193 }
4194 catch { }
4195 }
4196 }
4197
4198 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4199
4200 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4201 if (nodes.Count > 0)
4202 {
4203 foreach (XmlNode n in nodes)
4204 {
4205 XmlElement elem = (XmlElement)n;
4206 string itemID = elem.GetAttribute("ItemID");
4207 string xml = elem.InnerXml;
4208
4209 itemData[new UUID(itemID)] = xml;
4210 }
4211 }
4212
3703 List<int> attPoints = m_appearance.GetAttachedPoints(); 4213 List<int> attPoints = m_appearance.GetAttachedPoints();
3704 foreach (int p in attPoints) 4214 foreach (int p in attPoints)
3705 { 4215 {
@@ -3719,9 +4229,26 @@ namespace OpenSim.Region.Framework.Scenes
3719 4229
3720 try 4230 try
3721 { 4231 {
3722 // Rez from inventory 4232 string xmlData;
3723 UUID asset 4233 XmlDocument d = new XmlDocument();
3724 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4234 UUID asset;
4235 if (itemData.TryGetValue(itemID, out xmlData))
4236 {
4237 d.LoadXml(xmlData);
4238 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4239
4240 // Rez from inventory
4241 asset
4242 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4243
4244 }
4245 else
4246 {
4247 // Rez from inventory (with a null doc to let
4248 // CHANGED_OWNER happen)
4249 asset
4250 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4251 }
3725 4252
3726 m_log.InfoFormat( 4253 m_log.InfoFormat(
3727 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", 4254 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
@@ -3758,5 +4285,16 @@ namespace OpenSim.Region.Framework.Scenes
3758 m_reprioritization_called = false; 4285 m_reprioritization_called = false;
3759 } 4286 }
3760 } 4287 }
4288
4289 private Vector3 Quat2Euler(Quaternion rot){
4290 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4291 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4292 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4293 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4294 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4295 return(new Vector3(x,y,z));
4296 }
4297
4298
3761 } 4299 }
3762} 4300}