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.cs967
1 files changed, 781 insertions, 186 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 964f8cb..b637317 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[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 79// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
@@ -87,7 +88,9 @@ namespace OpenSim.Region.Framework.Scenes
87 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 88 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
88 /// issue #1716 89 /// issue #1716
89 /// </summary> 90 /// </summary>
90 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 91// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
92 // Value revised by KF 091121 by comparison with SL.
93 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
91 94
92 public UUID currentParcelUUID = UUID.Zero; 95 public UUID currentParcelUUID = UUID.Zero;
93 96
@@ -121,8 +124,11 @@ namespace OpenSim.Region.Framework.Scenes
121 public Vector3 lastKnownAllowedPosition; 124 public Vector3 lastKnownAllowedPosition;
122 public bool sentMessageAboutRestrictedParcelFlyingDown; 125 public bool sentMessageAboutRestrictedParcelFlyingDown;
123 public Vector4 CollisionPlane = Vector4.UnitW; 126 public Vector4 CollisionPlane = Vector4.UnitW;
124 127
128 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
129 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
125 private Vector3 m_lastPosition; 130 private Vector3 m_lastPosition;
131 private Vector3 m_lastWorldPosition;
126 private Quaternion m_lastRotation; 132 private Quaternion m_lastRotation;
127 private Vector3 m_lastVelocity; 133 private Vector3 m_lastVelocity;
128 //private int m_lastTerseSent; 134 //private int m_lastTerseSent;
@@ -153,7 +159,6 @@ namespace OpenSim.Region.Framework.Scenes
153 private int m_perfMonMS; 159 private int m_perfMonMS;
154 160
155 private bool m_setAlwaysRun; 161 private bool m_setAlwaysRun;
156
157 private bool m_forceFly; 162 private bool m_forceFly;
158 private bool m_flyDisabled; 163 private bool m_flyDisabled;
159 164
@@ -174,7 +179,8 @@ namespace OpenSim.Region.Framework.Scenes
174 protected RegionInfo m_regionInfo; 179 protected RegionInfo m_regionInfo;
175 protected ulong crossingFromRegion; 180 protected ulong crossingFromRegion;
176 181
177 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 182 private readonly Vector3[] Dir_Vectors = new Vector3[11];
183 private bool m_isNudging = false;
178 184
179 // Position of agent's camera in world (region cordinates) 185 // Position of agent's camera in world (region cordinates)
180 protected Vector3 m_CameraCenter; 186 protected Vector3 m_CameraCenter;
@@ -199,17 +205,25 @@ namespace OpenSim.Region.Framework.Scenes
199 private bool m_autopilotMoving; 205 private bool m_autopilotMoving;
200 private Vector3 m_autoPilotTarget; 206 private Vector3 m_autoPilotTarget;
201 private bool m_sitAtAutoTarget; 207 private bool m_sitAtAutoTarget;
208 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
202 209
203 private string m_nextSitAnimation = String.Empty; 210 private string m_nextSitAnimation = String.Empty;
204 211
205 //PauPaw:Proper PID Controler for autopilot************ 212 //PauPaw:Proper PID Controler for autopilot************
206 private bool m_moveToPositionInProgress; 213 private bool m_moveToPositionInProgress;
207 private Vector3 m_moveToPositionTarget; 214 private Vector3 m_moveToPositionTarget;
215 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
208 216
209 private bool m_followCamAuto; 217 private bool m_followCamAuto;
210 218
211 private int m_movementUpdateCount; 219 private int m_movementUpdateCount;
220 private int m_lastColCount = -1; //KF: Look for Collision chnages
221 private int m_updateCount = 0; //KF: Update Anims for a while
222 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
212 private const int NumMovementsBetweenRayCast = 5; 223 private const int NumMovementsBetweenRayCast = 5;
224 private List<uint> m_lastColliders = new List<uint>();
225
226 private object m_syncRoot = new Object();
213 227
214 private bool CameraConstraintActive; 228 private bool CameraConstraintActive;
215 //private int m_moveToPositionStateStatus; 229 //private int m_moveToPositionStateStatus;
@@ -236,7 +250,9 @@ namespace OpenSim.Region.Framework.Scenes
236 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 250 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
237 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 251 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
238 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 252 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
239 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 253 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
254 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
255 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
240 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 256 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
241 } 257 }
242 258
@@ -443,9 +459,18 @@ namespace OpenSim.Region.Framework.Scenes
443 get 459 get
444 { 460 {
445 PhysicsActor actor = m_physicsActor; 461 PhysicsActor actor = m_physicsActor;
446 if (actor != null) 462// if (actor != null)
463 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
447 m_pos = actor.Position; 464 m_pos = actor.Position;
448 465
466 // If we're sitting, we need to update our position
467 if (m_parentID != 0)
468 {
469 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
470 if (part != null)
471 m_parentPosition = part.AbsolutePosition;
472 }
473
449 return m_parentPosition + m_pos; 474 return m_parentPosition + m_pos;
450 } 475 }
451 set 476 set
@@ -464,7 +489,8 @@ namespace OpenSim.Region.Framework.Scenes
464 } 489 }
465 } 490 }
466 491
467 m_pos = value; 492 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
493 m_pos = value;
468 m_parentPosition = Vector3.Zero; 494 m_parentPosition = Vector3.Zero;
469 } 495 }
470 } 496 }
@@ -508,10 +534,39 @@ namespace OpenSim.Region.Framework.Scenes
508 } 534 }
509 } 535 }
510 536
537 public Quaternion OffsetRotation
538 {
539 get { return m_offsetRotation; }
540 set { m_offsetRotation = value; }
541 }
542
511 public Quaternion Rotation 543 public Quaternion Rotation
512 { 544 {
513 get { return m_bodyRot; } 545 get {
514 set { m_bodyRot = value; } 546 if (m_parentID != 0)
547 {
548 if (m_offsetRotation != null)
549 {
550 return m_offsetRotation;
551 }
552 else
553 {
554 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
555 }
556
557 }
558 else
559 {
560 return m_bodyRot;
561 }
562 }
563 set {
564 m_bodyRot = value;
565 if (m_parentID != 0)
566 {
567 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
568 }
569 }
515 } 570 }
516 571
517 public Quaternion PreviousRotation 572 public Quaternion PreviousRotation
@@ -536,11 +591,21 @@ namespace OpenSim.Region.Framework.Scenes
536 591
537 private uint m_parentID; 592 private uint m_parentID;
538 593
594
595 private UUID m_linkedPrim;
596
539 public uint ParentID 597 public uint ParentID
540 { 598 {
541 get { return m_parentID; } 599 get { return m_parentID; }
542 set { m_parentID = value; } 600 set { m_parentID = value; }
543 } 601 }
602
603 public UUID LinkedPrim
604 {
605 get { return m_linkedPrim; }
606 set { m_linkedPrim = value; }
607 }
608
544 public float Health 609 public float Health
545 { 610 {
546 get { return m_health; } 611 get { return m_health; }
@@ -662,7 +727,7 @@ namespace OpenSim.Region.Framework.Scenes
662 CreateSceneViewer(); 727 CreateSceneViewer();
663 m_animator = new ScenePresenceAnimator(this); 728 m_animator = new ScenePresenceAnimator(this);
664 } 729 }
665 730
666 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 731 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
667 { 732 {
668 m_rootRegionHandle = reginfo.RegionHandle; 733 m_rootRegionHandle = reginfo.RegionHandle;
@@ -694,10 +759,7 @@ namespace OpenSim.Region.Framework.Scenes
694 m_reprioritization_timer.AutoReset = false; 759 m_reprioritization_timer.AutoReset = false;
695 760
696 AdjustKnownSeeds(); 761 AdjustKnownSeeds();
697
698 // TODO: I think, this won't send anything, as we are still a child here...
699 Animator.TrySetMovementAnimation("STAND"); 762 Animator.TrySetMovementAnimation("STAND");
700
701 // we created a new ScenePresence (a new child agent) in a fresh region. 763 // we created a new ScenePresence (a new child agent) in a fresh region.
702 // Request info about all the (root) agents in this region 764 // Request info about all the (root) agents in this region
703 // Note: This won't send data *to* other clients in that region (children don't send) 765 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -746,25 +808,47 @@ namespace OpenSim.Region.Framework.Scenes
746 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 808 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
747 Dir_Vectors[4] = Vector3.UnitZ; //UP 809 Dir_Vectors[4] = Vector3.UnitZ; //UP
748 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 810 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
749 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 811 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
750 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 812 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
751 Dir_Vectors[7] = -Vector3.UnitX; //BACK 813 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
814 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
815 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
752 } 816 }
753 817
754 private Vector3[] GetWalkDirectionVectors() 818 private Vector3[] GetWalkDirectionVectors()
755 { 819 {
756 Vector3[] vector = new Vector3[9]; 820 Vector3[] vector = new Vector3[11];
757 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 821 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
758 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 822 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
759 vector[2] = Vector3.UnitY; //LEFT 823 vector[2] = Vector3.UnitY; //LEFT
760 vector[3] = -Vector3.UnitY; //RIGHT 824 vector[3] = -Vector3.UnitY; //RIGHT
761 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 825 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
762 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 826 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
763 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 827 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
764 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 828 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
765 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 829 vector[8] = Vector3.UnitY; //LEFT_NUDGE
830 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
831 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
766 return vector; 832 return vector;
767 } 833 }
834
835 private bool[] GetDirectionIsNudge()
836 {
837 bool[] isNudge = new bool[11];
838 isNudge[0] = false; //FORWARD
839 isNudge[1] = false; //BACK
840 isNudge[2] = false; //LEFT
841 isNudge[3] = false; //RIGHT
842 isNudge[4] = false; //UP
843 isNudge[5] = false; //DOWN
844 isNudge[6] = true; //FORWARD_NUDGE
845 isNudge[7] = true; //BACK_NUDGE
846 isNudge[8] = true; //LEFT_NUDGE
847 isNudge[9] = true; //RIGHT_NUDGE
848 isNudge[10] = true; //DOWN_Nudge
849 return isNudge;
850 }
851
768 852
769 #endregion 853 #endregion
770 854
@@ -826,6 +910,52 @@ namespace OpenSim.Region.Framework.Scenes
826 pos.Y = crossedBorder.BorderLine.Z - 1; 910 pos.Y = crossedBorder.BorderLine.Z - 1;
827 } 911 }
828 912
913 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
914 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
915 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
916 if (KnownChildRegionHandles.Count == 0)
917 {
918 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
919 if (land != null)
920 {
921 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
922 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)
923 {
924 pos = land.LandData.UserLocation;
925 }
926 }
927 }
928
929 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
930 {
931 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
932
933 if (pos.X < 0)
934 {
935 emergencyPos.X = (int)Constants.RegionSize + pos.X;
936 if (!(pos.Y < 0))
937 emergencyPos.Y = pos.Y;
938 if (!(pos.Z < 0))
939 emergencyPos.Z = pos.Z;
940 }
941 if (pos.Y < 0)
942 {
943 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
944 if (!(pos.X < 0))
945 emergencyPos.X = pos.X;
946 if (!(pos.Z < 0))
947 emergencyPos.Z = pos.Z;
948 }
949 if (pos.Z < 0)
950 {
951 emergencyPos.Z = 128;
952 if (!(pos.Y < 0))
953 emergencyPos.Y = pos.Y;
954 if (!(pos.X < 0))
955 emergencyPos.X = pos.X;
956 }
957 }
958
829 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 959 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
830 { 960 {
831 m_log.WarnFormat( 961 m_log.WarnFormat(
@@ -954,12 +1084,17 @@ namespace OpenSim.Region.Framework.Scenes
954 { 1084 {
955 if (PhysicsActor != null) 1085 if (PhysicsActor != null)
956 { 1086 {
957 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1087 try
958 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1088 {
959 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1089 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
960 m_physicsActor.UnSubscribeEvents(); 1090 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
961 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1091 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
962 PhysicsActor = null; 1092 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1093 m_physicsActor.UnSubscribeEvents();
1094 PhysicsActor = null;
1095 }
1096 catch
1097 { }
963 } 1098 }
964 } 1099 }
965 1100
@@ -970,9 +1105,10 @@ namespace OpenSim.Region.Framework.Scenes
970 public void Teleport(Vector3 pos) 1105 public void Teleport(Vector3 pos)
971 { 1106 {
972 bool isFlying = false; 1107 bool isFlying = false;
1108
973 if (m_physicsActor != null) 1109 if (m_physicsActor != null)
974 isFlying = m_physicsActor.Flying; 1110 isFlying = m_physicsActor.Flying;
975 1111
976 RemoveFromPhysicalScene(); 1112 RemoveFromPhysicalScene();
977 Velocity = Vector3.Zero; 1113 Velocity = Vector3.Zero;
978 AbsolutePosition = pos; 1114 AbsolutePosition = pos;
@@ -984,6 +1120,7 @@ namespace OpenSim.Region.Framework.Scenes
984 } 1120 }
985 1121
986 SendTerseUpdateToAllClients(); 1122 SendTerseUpdateToAllClients();
1123
987 } 1124 }
988 1125
989 public void TeleportWithMomentum(Vector3 pos) 1126 public void TeleportWithMomentum(Vector3 pos)
@@ -1202,6 +1339,7 @@ namespace OpenSim.Region.Framework.Scenes
1202 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1339 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1203 1340
1204 m_pos = m_LastFinitePos; 1341 m_pos = m_LastFinitePos;
1342
1205 if (!m_pos.IsFinite()) 1343 if (!m_pos.IsFinite())
1206 { 1344 {
1207 m_pos.X = 127f; 1345 m_pos.X = 127f;
@@ -1268,7 +1406,6 @@ namespace OpenSim.Region.Framework.Scenes
1268 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1406 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1269 } 1407 }
1270 } 1408 }
1271
1272 lock (scriptedcontrols) 1409 lock (scriptedcontrols)
1273 { 1410 {
1274 if (scriptedcontrols.Count > 0) 1411 if (scriptedcontrols.Count > 0)
@@ -1283,6 +1420,9 @@ namespace OpenSim.Region.Framework.Scenes
1283 1420
1284 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1421 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1285 { 1422 {
1423 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1424 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1425
1286 // TODO: This doesn't prevent the user from walking yet. 1426 // TODO: This doesn't prevent the user from walking yet.
1287 // Setting parent ID would fix this, if we knew what value 1427 // Setting parent ID would fix this, if we knew what value
1288 // to use. Or we could add a m_isSitting variable. 1428 // to use. Or we could add a m_isSitting variable.
@@ -1331,12 +1471,20 @@ namespace OpenSim.Region.Framework.Scenes
1331 if (actor.Flying != oldflying) 1471 if (actor.Flying != oldflying)
1332 update_movementflag = true; 1472 update_movementflag = true;
1333 1473
1474 if (m_animator.m_jumping) // add for jumping
1475 update_movementflag = true;
1476
1334 if (q != m_bodyRot) 1477 if (q != m_bodyRot)
1335 { 1478 {
1336 m_bodyRot = q; 1479 m_bodyRot = q;
1337 update_rotation = true; 1480 update_rotation = true;
1338 } 1481 }
1339 1482
1483 //guilty until proven innocent..
1484 bool Nudging = true;
1485 //Basically, if there is at least one non-nudge control then we don't need
1486 //to worry about stopping the avatar
1487
1340 if (m_parentID == 0) 1488 if (m_parentID == 0)
1341 { 1489 {
1342 bool bAllowUpdateMoveToPosition = false; 1490 bool bAllowUpdateMoveToPosition = false;
@@ -1351,9 +1499,12 @@ namespace OpenSim.Region.Framework.Scenes
1351 else 1499 else
1352 dirVectors = Dir_Vectors; 1500 dirVectors = Dir_Vectors;
1353 1501
1354 // The fact that m_movementflag is a byte needs to be fixed 1502 bool[] isNudge = GetDirectionIsNudge();
1355 // it really should be a uint 1503
1356 uint nudgehack = 250; 1504
1505
1506
1507
1357 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1508 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1358 { 1509 {
1359 if (((uint)flags & (uint)DCF) != 0) 1510 if (((uint)flags & (uint)DCF) != 0)
@@ -1363,40 +1514,28 @@ namespace OpenSim.Region.Framework.Scenes
1363 try 1514 try
1364 { 1515 {
1365 agent_control_v3 += dirVectors[i]; 1516 agent_control_v3 += dirVectors[i];
1366 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1517 if (isNudge[i] == false)
1518 {
1519 Nudging = false;
1520 }
1367 } 1521 }
1368 catch (IndexOutOfRangeException) 1522 catch (IndexOutOfRangeException)
1369 { 1523 {
1370 // Why did I get this? 1524 // Why did I get this?
1371 } 1525 }
1372 1526
1373 if ((m_movementflag & (byte)(uint)DCF) == 0) 1527 if ((m_movementflag & (uint)DCF) == 0)
1374 { 1528 {
1375 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1376 {
1377 m_movementflag |= (byte)nudgehack;
1378 }
1379 m_movementflag += (byte)(uint)DCF; 1529 m_movementflag += (byte)(uint)DCF;
1380 update_movementflag = true; 1530 update_movementflag = true;
1381 } 1531 }
1382 } 1532 }
1383 else 1533 else
1384 { 1534 {
1385 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1535 if ((m_movementflag & (uint)DCF) != 0)
1386 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1387 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1388 ) // This or is for Nudge forward
1389 { 1536 {
1390 m_movementflag -= ((byte)(uint)DCF); 1537 m_movementflag -= (byte)(uint)DCF;
1391
1392 update_movementflag = true; 1538 update_movementflag = true;
1393 /*
1394 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1395 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1396 {
1397 m_log.Debug("Removed Hack flag");
1398 }
1399 */
1400 } 1539 }
1401 else 1540 else
1402 { 1541 {
@@ -1405,7 +1544,6 @@ namespace OpenSim.Region.Framework.Scenes
1405 } 1544 }
1406 i++; 1545 i++;
1407 } 1546 }
1408
1409 //Paupaw:Do Proper PID for Autopilot here 1547 //Paupaw:Do Proper PID for Autopilot here
1410 if (bResetMoveToPosition) 1548 if (bResetMoveToPosition)
1411 { 1549 {
@@ -1440,6 +1578,9 @@ namespace OpenSim.Region.Framework.Scenes
1440 // Ignore z component of vector 1578 // Ignore z component of vector
1441 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1579 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1442 LocalVectorToTarget2D.Normalize(); 1580 LocalVectorToTarget2D.Normalize();
1581
1582 //We're not nudging
1583 Nudging = false;
1443 agent_control_v3 += LocalVectorToTarget2D; 1584 agent_control_v3 += LocalVectorToTarget2D;
1444 1585
1445 // update avatar movement flags. the avatar coordinate system is as follows: 1586 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1530,13 +1671,13 @@ namespace OpenSim.Region.Framework.Scenes
1530 // m_log.DebugFormat( 1671 // m_log.DebugFormat(
1531 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1672 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1532 1673
1533 AddNewMovement(agent_control_v3, q); 1674 AddNewMovement(agent_control_v3, q, Nudging);
1534 1675
1535 1676
1536 } 1677 }
1537 } 1678 }
1538 1679
1539 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1680 if (update_movementflag && !SitGround)
1540 Animator.UpdateMovementAnimations(); 1681 Animator.UpdateMovementAnimations();
1541 1682
1542 m_scene.EventManager.TriggerOnClientMovement(this); 1683 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1551,7 +1692,6 @@ namespace OpenSim.Region.Framework.Scenes
1551 m_sitAtAutoTarget = false; 1692 m_sitAtAutoTarget = false;
1552 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1693 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1553 //proxy.PCode = (byte)PCode.ParticleSystem; 1694 //proxy.PCode = (byte)PCode.ParticleSystem;
1554
1555 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1695 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1556 proxyObjectGroup.AttachToScene(m_scene); 1696 proxyObjectGroup.AttachToScene(m_scene);
1557 1697
@@ -1593,7 +1733,7 @@ namespace OpenSim.Region.Framework.Scenes
1593 } 1733 }
1594 m_moveToPositionInProgress = true; 1734 m_moveToPositionInProgress = true;
1595 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1735 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1596 } 1736 }
1597 catch (Exception ex) 1737 catch (Exception ex)
1598 { 1738 {
1599 //Why did I get this error? 1739 //Why did I get this error?
@@ -1615,7 +1755,7 @@ namespace OpenSim.Region.Framework.Scenes
1615 Velocity = Vector3.Zero; 1755 Velocity = Vector3.Zero;
1616 SendFullUpdateToAllClients(); 1756 SendFullUpdateToAllClients();
1617 1757
1618 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1758 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1619 } 1759 }
1620 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1760 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1621 m_requestedSitTargetUUID = UUID.Zero; 1761 m_requestedSitTargetUUID = UUID.Zero;
@@ -1652,42 +1792,77 @@ namespace OpenSim.Region.Framework.Scenes
1652 1792
1653 if (m_parentID != 0) 1793 if (m_parentID != 0)
1654 { 1794 {
1655 m_log.Debug("StandupCode Executed"); 1795 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1656 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1657 if (part != null) 1796 if (part != null)
1658 { 1797 {
1798 part.TaskInventory.LockItemsForRead(true);
1659 TaskInventoryDictionary taskIDict = part.TaskInventory; 1799 TaskInventoryDictionary taskIDict = part.TaskInventory;
1660 if (taskIDict != null) 1800 if (taskIDict != null)
1661 { 1801 {
1662 lock (taskIDict) 1802 foreach (UUID taskID in taskIDict.Keys)
1663 { 1803 {
1664 foreach (UUID taskID in taskIDict.Keys) 1804 UnRegisterControlEventsToScript(LocalId, taskID);
1665 { 1805 taskIDict[taskID].PermsMask &= ~(
1666 UnRegisterControlEventsToScript(LocalId, taskID); 1806 2048 | //PERMISSION_CONTROL_CAMERA
1667 taskIDict[taskID].PermsMask &= ~( 1807 4); // PERMISSION_TAKE_CONTROLS
1668 2048 | //PERMISSION_CONTROL_CAMERA
1669 4); // PERMISSION_TAKE_CONTROLS
1670 }
1671 } 1808 }
1672
1673 } 1809 }
1810 part.TaskInventory.LockItemsForRead(false);
1674 // Reset sit target. 1811 // Reset sit target.
1675 if (part.GetAvatarOnSitTarget() == UUID) 1812 if (part.GetAvatarOnSitTarget() == UUID)
1676 part.SetAvatarOnSitTarget(UUID.Zero); 1813 part.SetAvatarOnSitTarget(UUID.Zero);
1677
1678 m_parentPosition = part.GetWorldPosition(); 1814 m_parentPosition = part.GetWorldPosition();
1679 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1815 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1680 } 1816 }
1817 // part.GetWorldRotation() is the rotation of the object being sat on
1818 // Rotation is the sittiing Av's rotation
1819
1820 Quaternion partRot;
1821// if (part.LinkNum == 1)
1822// { // Root prim of linkset
1823// partRot = part.ParentGroup.RootPart.RotationOffset;
1824// }
1825// else
1826// { // single or child prim
1827
1828// }
1829 if (part == null) //CW: Part may be gone. llDie() for example.
1830 {
1831 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1832 }
1833 else
1834 {
1835 partRot = part.GetWorldRotation();
1836 }
1681 1837
1838 Quaternion partIRot = Quaternion.Inverse(partRot);
1839
1840 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1841 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1842
1843
1682 if (m_physicsActor == null) 1844 if (m_physicsActor == null)
1683 { 1845 {
1684 AddToPhysicalScene(false); 1846 AddToPhysicalScene(false);
1685 } 1847 }
1686 1848 //CW: If the part isn't null then we can set the current position
1687 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1849 if (part != null)
1688 m_parentPosition = Vector3.Zero; 1850 {
1689 1851 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1690 m_parentID = 0; 1852 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1853 part.IsOccupied = false;
1854 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1855 }
1856 else
1857 {
1858 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1859 AbsolutePosition = m_lastWorldPosition;
1860 }
1861
1862 m_parentPosition = Vector3.Zero;
1863 m_parentID = 0;
1864 m_linkedPrim = UUID.Zero;
1865 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1691 SendFullUpdateToAllClients(); 1866 SendFullUpdateToAllClients();
1692 m_requestedSitTargetID = 0; 1867 m_requestedSitTargetID = 0;
1693 if (m_physicsActor != null && m_appearance != null) 1868 if (m_physicsActor != null && m_appearance != null)
@@ -1696,7 +1871,6 @@ namespace OpenSim.Region.Framework.Scenes
1696 SetHeight(m_appearance.AvatarHeight); 1871 SetHeight(m_appearance.AvatarHeight);
1697 } 1872 }
1698 } 1873 }
1699
1700 Animator.TrySetMovementAnimation("STAND"); 1874 Animator.TrySetMovementAnimation("STAND");
1701 } 1875 }
1702 1876
@@ -1727,13 +1901,9 @@ namespace OpenSim.Region.Framework.Scenes
1727 Vector3 avSitOffSet = part.SitTargetPosition; 1901 Vector3 avSitOffSet = part.SitTargetPosition;
1728 Quaternion avSitOrientation = part.SitTargetOrientation; 1902 Quaternion avSitOrientation = part.SitTargetOrientation;
1729 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1903 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1730 1904 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1731 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1905 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1732 bool SitTargetisSet = 1906 if (SitTargetisSet && !SitTargetOccupied)
1733 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1734 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1735
1736 if (SitTargetisSet && SitTargetUnOccupied)
1737 { 1907 {
1738 //switch the target to this prim 1908 //switch the target to this prim
1739 return part; 1909 return part;
@@ -1747,84 +1917,164 @@ namespace OpenSim.Region.Framework.Scenes
1747 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1917 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1748 { 1918 {
1749 bool autopilot = true; 1919 bool autopilot = true;
1920 Vector3 autopilotTarget = new Vector3();
1921 Quaternion sitOrientation = Quaternion.Identity;
1750 Vector3 pos = new Vector3(); 1922 Vector3 pos = new Vector3();
1751 Quaternion sitOrientation = pSitOrientation;
1752 Vector3 cameraEyeOffset = Vector3.Zero; 1923 Vector3 cameraEyeOffset = Vector3.Zero;
1753 Vector3 cameraAtOffset = Vector3.Zero; 1924 Vector3 cameraAtOffset = Vector3.Zero;
1754 bool forceMouselook = false; 1925 bool forceMouselook = false;
1755 1926
1756 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1927 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1757 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1928 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1758 if (part != null) 1929 if (part == null) return;
1759 { 1930
1760 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1931 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1761 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1932 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1762 1933
1763 // Is a sit target available? 1934 // part is the prim to sit on
1764 Vector3 avSitOffSet = part.SitTargetPosition; 1935 // offset is the world-ref vector distance from that prim center to the click-spot
1765 Quaternion avSitOrientation = part.SitTargetOrientation; 1936 // UUID is the UUID of the Avatar doing the clicking
1766 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1937
1767 1938 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1768 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1939
1769 bool SitTargetisSet = 1940 // Is a sit target available?
1770 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1941 Vector3 avSitOffSet = part.SitTargetPosition;
1771 ( 1942 Quaternion avSitOrientation = part.SitTargetOrientation;
1772 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1943
1773 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1944 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1774 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1945 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1775 ) 1946 Quaternion partRot;
1776 )); 1947// if (part.LinkNum == 1)
1777 1948// { // Root prim of linkset
1778 if (SitTargetisSet && SitTargetUnOccupied) 1949// partRot = part.ParentGroup.RootPart.RotationOffset;
1779 { 1950// }
1780 part.SetAvatarOnSitTarget(UUID); 1951// else
1781 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1952// { // single or child prim
1782 sitOrientation = avSitOrientation; 1953 partRot = part.GetWorldRotation();
1783 autopilot = false; 1954// }
1784 } 1955 Quaternion partIRot = Quaternion.Inverse(partRot);
1785 1956//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1786 pos = part.AbsolutePosition + offset; 1957 // Sit analysis rewritten by KF 091125
1787 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1958 if (SitTargetisSet) // scipted sit
1788 //{ 1959 {
1789 // offset = pos; 1960 if (!part.IsOccupied)
1790 //autopilot = false; 1961 {
1791 //} 1962//Console.WriteLine("Scripted, unoccupied");
1792 if (m_physicsActor != null) 1963 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1793 { 1964 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1794 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1965
1795 // We can remove the physicsActor until they stand up. 1966 Quaternion nrot = avSitOrientation;
1796 m_sitAvatarHeight = m_physicsActor.Size.Z; 1967 if (!part.IsRoot)
1797
1798 if (autopilot)
1799 { 1968 {
1800 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1969 nrot = part.RotationOffset * avSitOrientation;
1801 {
1802 autopilot = false;
1803
1804 RemoveFromPhysicalScene();
1805 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1806 }
1807 } 1970 }
1808 else 1971 sitOrientation = nrot; // Change rotatione to the scripted one
1972 OffsetRotation = nrot;
1973 autopilot = false; // Jump direct to scripted llSitPos()
1974 }
1975 else
1976 {
1977//Console.WriteLine("Scripted, occupied");
1978 return;
1979 }
1980 }
1981 else // Not Scripted
1982 {
1983 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1984 {
1985 // large prim & offset, ignore if other Avs sitting
1986// offset.Z -= 0.05f;
1987 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1988 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1989
1990//Console.WriteLine(" offset ={0}", offset);
1991//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1992//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1993
1994 }
1995 else // small offset
1996 {
1997//Console.WriteLine("Small offset");
1998 if (!part.IsOccupied)
1999 {
2000 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2001 autopilotTarget = part.AbsolutePosition;
2002//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2003 }
2004 else return; // occupied small
2005 } // end large/small
2006 } // end Scripted/not
2007 cameraAtOffset = part.GetCameraAtOffset();
2008 cameraEyeOffset = part.GetCameraEyeOffset();
2009 forceMouselook = part.GetForceMouselook();
2010 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2011 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2012
2013 if (m_physicsActor != null)
2014 {
2015 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2016 // We can remove the physicsActor until they stand up.
2017 m_sitAvatarHeight = m_physicsActor.Size.Z;
2018 if (autopilot)
2019 { // its not a scripted sit
2020// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2021 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1809 { 2022 {
2023 autopilot = false; // close enough
2024 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2025 Not using the part's position because returning the AV to the last known standing
2026 position is likely to be more friendly, isn't it? */
1810 RemoveFromPhysicalScene(); 2027 RemoveFromPhysicalScene();
1811 } 2028 Velocity = Vector3.Zero;
2029 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2030 } // else the autopilot will get us close
2031 }
2032 else
2033 { // its a scripted sit
2034 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2035 I *am* using the part's position this time because we have no real idea how far away
2036 the avatar is from the sit target. */
2037 RemoveFromPhysicalScene();
2038 Velocity = Vector3.Zero;
1812 } 2039 }
1813
1814 cameraAtOffset = part.GetCameraAtOffset();
1815 cameraEyeOffset = part.GetCameraEyeOffset();
1816 forceMouselook = part.GetForceMouselook();
1817 } 2040 }
2041 else return; // physactor is null!
1818 2042
1819 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2043 Vector3 offsetr; // = offset * partIRot;
1820 m_requestedSitTargetUUID = targetID; 2044 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2045 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2046 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2047 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2048 //offsetr = offset * partIRot;
2049//
2050 // else
2051 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2052 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2053 // (offset * partRot);
2054 // }
2055
2056//Console.WriteLine(" ");
2057//Console.WriteLine("link number ={0}", part.LinkNum);
2058//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2059//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2060//Console.WriteLine("Click offst ={0}", offset);
2061//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2062//Console.WriteLine("offsetr ={0}", offsetr);
2063//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2064//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2065
2066 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2067 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2068
2069 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1821 // This calls HandleAgentSit twice, once from here, and the client calls 2070 // This calls HandleAgentSit twice, once from here, and the client calls
1822 // HandleAgentSit itself after it gets to the location 2071 // HandleAgentSit itself after it gets to the location
1823 // It doesn't get to the location until we've moved them there though 2072 // It doesn't get to the location until we've moved them there though
1824 // which happens in HandleAgentSit :P 2073 // which happens in HandleAgentSit :P
1825 m_autopilotMoving = autopilot; 2074 m_autopilotMoving = autopilot;
1826 m_autoPilotTarget = pos; 2075 m_autoPilotTarget = autopilotTarget;
1827 m_sitAtAutoTarget = autopilot; 2076 m_sitAtAutoTarget = autopilot;
2077 m_initialSitTarget = autopilotTarget;
1828 if (!autopilot) 2078 if (!autopilot)
1829 HandleAgentSit(remoteClient, UUID); 2079 HandleAgentSit(remoteClient, UUID);
1830 } 2080 }
@@ -2119,47 +2369,130 @@ namespace OpenSim.Region.Framework.Scenes
2119 { 2369 {
2120 if (part != null) 2370 if (part != null)
2121 { 2371 {
2372//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2122 if (part.GetAvatarOnSitTarget() == UUID) 2373 if (part.GetAvatarOnSitTarget() == UUID)
2123 { 2374 {
2375//Console.WriteLine("Scripted Sit");
2376 // Scripted sit
2124 Vector3 sitTargetPos = part.SitTargetPosition; 2377 Vector3 sitTargetPos = part.SitTargetPosition;
2125 Quaternion sitTargetOrient = part.SitTargetOrientation; 2378 Quaternion sitTargetOrient = part.SitTargetOrientation;
2126
2127 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2128 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2129
2130 //Quaternion result = (sitTargetOrient * vq) * nq;
2131
2132 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2379 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2133 m_pos += SIT_TARGET_ADJUSTMENT; 2380 m_pos += SIT_TARGET_ADJUSTMENT;
2381 if (!part.IsRoot)
2382 {
2383 m_pos *= part.RotationOffset;
2384 }
2134 m_bodyRot = sitTargetOrient; 2385 m_bodyRot = sitTargetOrient;
2135 //Rotation = sitTargetOrient;
2136 m_parentPosition = part.AbsolutePosition; 2386 m_parentPosition = part.AbsolutePosition;
2137 2387 part.IsOccupied = true;
2138 //SendTerseUpdateToAllClients(); 2388 part.ParentGroup.AddAvatar(agentID);
2139 } 2389 }
2140 else 2390 else
2141 { 2391 {
2142 m_pos -= part.AbsolutePosition; 2392 // if m_avUnscriptedSitPos is zero then Av sits above center
2393 // Else Av sits at m_avUnscriptedSitPos
2394
2395 // Non-scripted sit by Kitto Flora 21Nov09
2396 // Calculate angle of line from prim to Av
2397 Quaternion partIRot;
2398// if (part.LinkNum == 1)
2399// { // Root prim of linkset
2400// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2401// }
2402// else
2403// { // single or child prim
2404 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2405// }
2406 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2407 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2408 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2409 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2410 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2411 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2412 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2413 // Av sits at world euler <0,0, z>, translated by part rotation
2414 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2415
2143 m_parentPosition = part.AbsolutePosition; 2416 m_parentPosition = part.AbsolutePosition;
2144 } 2417 part.IsOccupied = true;
2418 part.ParentGroup.AddAvatar(agentID);
2419 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2420 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2421 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2422 m_avUnscriptedSitPos; // adds click offset, if any
2423 //Set up raytrace to find top surface of prim
2424 Vector3 size = part.Scale;
2425 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2426 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2427 Vector3 down = new Vector3(0f, 0f, -1f);
2428//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2429 m_scene.PhysicsScene.RaycastWorld(
2430 start, // Vector3 position,
2431 down, // Vector3 direction,
2432 mag, // float length,
2433 SitAltitudeCallback); // retMethod
2434 } // end scripted/not
2145 } 2435 }
2146 else 2436 else // no Av
2147 { 2437 {
2148 return; 2438 return;
2149 } 2439 }
2150 } 2440 }
2151 m_parentID = m_requestedSitTargetID;
2152 2441
2442 //We want our offsets to reference the root prim, not the child we may have sat on
2443 if (!part.IsRoot)
2444 {
2445 m_parentID = part.ParentGroup.RootPart.LocalId;
2446 m_pos += part.OffsetPosition;
2447 }
2448 else
2449 {
2450 m_parentID = m_requestedSitTargetID;
2451 }
2452
2453 m_linkedPrim = part.UUID;
2454 if (part.GetAvatarOnSitTarget() != UUID)
2455 {
2456 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2457 }
2153 Velocity = Vector3.Zero; 2458 Velocity = Vector3.Zero;
2154 RemoveFromPhysicalScene(); 2459 RemoveFromPhysicalScene();
2155
2156 Animator.TrySetMovementAnimation(sitAnimation); 2460 Animator.TrySetMovementAnimation(sitAnimation);
2157 SendFullUpdateToAllClients(); 2461 SendFullUpdateToAllClients();
2158 // This may seem stupid, but Our Full updates don't send avatar rotation :P 2462 SendTerseUpdateToAllClients();
2159 // So we're also sending a terse update (which has avatar rotation)
2160 // [Update] We do now.
2161 //SendTerseUpdateToAllClients();
2162 } 2463 }
2464
2465 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2466 {
2467 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2468 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2469 if(hitYN)
2470 {
2471 // m_pos = Av offset from prim center to make look like on center
2472 // m_parentPosition = Actual center pos of prim
2473 // collisionPoint = spot on prim where we want to sit
2474 // collisionPoint.Z = global sit surface height
2475 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2476 Quaternion partIRot;
2477// if (part.LinkNum == 1)
2478/// { // Root prim of linkset
2479// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2480// }
2481// else
2482// { // single or child prim
2483 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2484// }
2485 if (m_initialSitTarget != null)
2486 {
2487 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2488 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2489 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2490 m_pos += offset;
2491 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2492 }
2493
2494 }
2495 } // End SitAltitudeCallback KF.
2163 2496
2164 /// <summary> 2497 /// <summary>
2165 /// Event handler for the 'Always run' setting on the client 2498 /// Event handler for the 'Always run' setting on the client
@@ -2189,7 +2522,7 @@ namespace OpenSim.Region.Framework.Scenes
2189 /// </summary> 2522 /// </summary>
2190 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2523 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2191 /// <param name="rotation">The direction in which this avatar should now face. 2524 /// <param name="rotation">The direction in which this avatar should now face.
2192 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2525 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2193 { 2526 {
2194 if (m_isChildAgent) 2527 if (m_isChildAgent)
2195 { 2528 {
@@ -2230,15 +2563,18 @@ namespace OpenSim.Region.Framework.Scenes
2230 Rotation = rotation; 2563 Rotation = rotation;
2231 Vector3 direc = vec * rotation; 2564 Vector3 direc = vec * rotation;
2232 direc.Normalize(); 2565 direc.Normalize();
2566 PhysicsActor actor = m_physicsActor;
2567 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2233 2568
2234 direc *= 0.03f * 128f * m_speedModifier; 2569 direc *= 0.03f * 128f * m_speedModifier;
2235 2570
2236 PhysicsActor actor = m_physicsActor;
2237 if (actor != null) 2571 if (actor != null)
2238 { 2572 {
2239 if (actor.Flying) 2573// rm falling if (actor.Flying)
2574 if ((actor.Flying) || Animator.m_falling) // add for falling lateral speed
2240 { 2575 {
2241 direc *= 4.0f; 2576// rm speed mod direc *= 4.0f;
2577 direc *= 5.2f; // for speed mod
2242 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2578 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2243 //bool colliding = (m_physicsActor.IsColliding==true); 2579 //bool colliding = (m_physicsActor.IsColliding==true);
2244 //if (controlland) 2580 //if (controlland)
@@ -2251,22 +2587,30 @@ namespace OpenSim.Region.Framework.Scenes
2251 // m_log.Info("[AGENT]: Stop FLying"); 2587 // m_log.Info("[AGENT]: Stop FLying");
2252 //} 2588 //}
2253 } 2589 }
2590 /* This jumping section removed to SPA
2254 else if (!actor.Flying && actor.IsColliding) 2591 else if (!actor.Flying && actor.IsColliding)
2255 { 2592 {
2256 if (direc.Z > 2.0f) 2593 if (direc.Z > 2.0f)
2257 { 2594 {
2258 direc.Z *= 3.0f; 2595 if(m_animator.m_animTickJump == -1)
2259 2596 {
2260 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2597 direc.Z *= 3.0f; // jump
2261 Animator.TrySetMovementAnimation("PREJUMP"); 2598 }
2262 Animator.TrySetMovementAnimation("JUMP"); 2599 else
2600 {
2601 direc.Z *= 0.1f; // prejump
2602 }
2603 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2604 Animator.TrySetMovementAnimation("PREJUMP");
2605 Animator.TrySetMovementAnimation("JUMP");
2606 * /
2263 } 2607 }
2264 } 2608 } */
2265 } 2609 }
2266 2610
2267 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2611 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2268 m_forceToApply = direc; 2612 m_forceToApply = direc;
2269 2613 m_isNudging = Nudging;
2270 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2614 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2271 } 2615 }
2272 2616
@@ -2281,7 +2625,7 @@ namespace OpenSim.Region.Framework.Scenes
2281 const float POSITION_TOLERANCE = 0.05f; 2625 const float POSITION_TOLERANCE = 0.05f;
2282 //const int TIME_MS_TOLERANCE = 3000; 2626 //const int TIME_MS_TOLERANCE = 3000;
2283 2627
2284 SendPrimUpdates(); 2628
2285 2629
2286 if (m_isChildAgent == false) 2630 if (m_isChildAgent == false)
2287 { 2631 {
@@ -2311,6 +2655,9 @@ namespace OpenSim.Region.Framework.Scenes
2311 CheckForBorderCrossing(); 2655 CheckForBorderCrossing();
2312 CheckForSignificantMovement(); // sends update to the modules. 2656 CheckForSignificantMovement(); // sends update to the modules.
2313 } 2657 }
2658
2659 //Sending prim updates AFTER the avatar terse updates are sent
2660 SendPrimUpdates();
2314 } 2661 }
2315 2662
2316 #endregion 2663 #endregion
@@ -3058,6 +3405,7 @@ namespace OpenSim.Region.Framework.Scenes
3058 m_callbackURI = cAgent.CallbackURI; 3405 m_callbackURI = cAgent.CallbackURI;
3059 3406
3060 m_pos = cAgent.Position; 3407 m_pos = cAgent.Position;
3408
3061 m_velocity = cAgent.Velocity; 3409 m_velocity = cAgent.Velocity;
3062 m_CameraCenter = cAgent.Center; 3410 m_CameraCenter = cAgent.Center;
3063 m_CameraAtAxis = cAgent.AtAxis; 3411 m_CameraAtAxis = cAgent.AtAxis;
@@ -3176,17 +3524,46 @@ namespace OpenSim.Region.Framework.Scenes
3176 /// </summary> 3524 /// </summary>
3177 public override void UpdateMovement() 3525 public override void UpdateMovement()
3178 { 3526 {
3179 if (m_forceToApply.HasValue) 3527 if (Animator!=null) // add for jumping
3180 { 3528 { // add for jumping
3181 Vector3 force = m_forceToApply.Value; 3529 // if (!m_animator.m_jumping) // add for jumping
3530 // { // add for jumping
3182 3531
3183 m_updateflag = true; 3532 if (m_forceToApply.HasValue) // this section realigned
3184// movementvector = force; 3533 {
3185 Velocity = force;
3186 3534
3187 m_forceToApply = null; 3535 Vector3 force = m_forceToApply.Value;
3188 } 3536 m_updateflag = true;
3189 } 3537if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3538 Velocity = force;
3539//Console.WriteLine("UM1 {0}", Velocity);
3540 m_forceToApply = null;
3541 }
3542 else
3543 {
3544 if (m_isNudging)
3545 {
3546 Vector3 force = Vector3.Zero;
3547
3548 m_updateflag = true;
3549if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3550 Velocity = force;
3551//Console.WriteLine("UM2 {0}", Velocity);
3552 m_isNudging = false;
3553 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3554 }
3555 else // add for jumping
3556 { // add for jumping
3557 Vector3 force = Vector3.Zero; // add for jumping
3558if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3559//Console.WriteLine("UM3 {0}", Velocity);
3560 Velocity = force; // add for jumping
3561 }
3562
3563 }
3564 // } // end realign
3565 } // add for jumping
3566 } // add for jumping
3190 3567
3191 /// <summary> 3568 /// <summary>
3192 /// Adds a physical representation of the avatar to the Physics plugin 3569 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3200,10 +3577,8 @@ namespace OpenSim.Region.Framework.Scenes
3200 3577
3201 Vector3 pVec = AbsolutePosition; 3578 Vector3 pVec = AbsolutePosition;
3202 3579
3203 // Old bug where the height was in centimeters instead of meters
3204 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3580 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3205 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3581 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3206
3207 scene.AddPhysicsActorTaint(m_physicsActor); 3582 scene.AddPhysicsActorTaint(m_physicsActor);
3208 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3583 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3209 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3584 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3227,18 +3602,29 @@ namespace OpenSim.Region.Framework.Scenes
3227 { 3602 {
3228 if (e == null) 3603 if (e == null)
3229 return; 3604 return;
3230 3605
3231 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3606 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3232 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3233 // as of this comment the interval is set in AddToPhysicalScene 3607 // as of this comment the interval is set in AddToPhysicalScene
3234 if (Animator!=null) 3608 if (Animator!=null)
3235 Animator.UpdateMovementAnimations(); 3609 {
3610 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3611 { // else its will lock out other animation changes, like ground sit.
3612 Animator.UpdateMovementAnimations();
3613 m_updateCount--;
3614 }
3615 }
3236 3616
3237 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3617 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3238 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3618 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3239 3619
3240 CollisionPlane = Vector4.UnitW; 3620 CollisionPlane = Vector4.UnitW;
3241 3621
3622 if (m_lastColCount != coldata.Count)
3623 {
3624 m_updateCount = UPDATE_COUNT;
3625 m_lastColCount = coldata.Count;
3626 }
3627
3242 if (coldata.Count != 0 && Animator != null) 3628 if (coldata.Count != 0 && Animator != null)
3243 { 3629 {
3244 switch (Animator.CurrentMovementAnimation) 3630 switch (Animator.CurrentMovementAnimation)
@@ -3268,6 +3654,148 @@ namespace OpenSim.Region.Framework.Scenes
3268 } 3654 }
3269 } 3655 }
3270 3656
3657 List<uint> thisHitColliders = new List<uint>();
3658 List<uint> endedColliders = new List<uint>();
3659 List<uint> startedColliders = new List<uint>();
3660
3661 foreach (uint localid in coldata.Keys)
3662 {
3663 thisHitColliders.Add(localid);
3664 if (!m_lastColliders.Contains(localid))
3665 {
3666 startedColliders.Add(localid);
3667 }
3668 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3669 }
3670
3671 // calculate things that ended colliding
3672 foreach (uint localID in m_lastColliders)
3673 {
3674 if (!thisHitColliders.Contains(localID))
3675 {
3676 endedColliders.Add(localID);
3677 }
3678 }
3679 //add the items that started colliding this time to the last colliders list.
3680 foreach (uint localID in startedColliders)
3681 {
3682 m_lastColliders.Add(localID);
3683 }
3684 // remove things that ended colliding from the last colliders list
3685 foreach (uint localID in endedColliders)
3686 {
3687 m_lastColliders.Remove(localID);
3688 }
3689
3690 // do event notification
3691 if (startedColliders.Count > 0)
3692 {
3693 ColliderArgs StartCollidingMessage = new ColliderArgs();
3694 List<DetectedObject> colliding = new List<DetectedObject>();
3695 foreach (uint localId in startedColliders)
3696 {
3697 if (localId == 0)
3698 continue;
3699
3700 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3701 string data = "";
3702 if (obj != null)
3703 {
3704 DetectedObject detobj = new DetectedObject();
3705 detobj.keyUUID = obj.UUID;
3706 detobj.nameStr = obj.Name;
3707 detobj.ownerUUID = obj.OwnerID;
3708 detobj.posVector = obj.AbsolutePosition;
3709 detobj.rotQuat = obj.GetWorldRotation();
3710 detobj.velVector = obj.Velocity;
3711 detobj.colliderType = 0;
3712 detobj.groupUUID = obj.GroupID;
3713 colliding.Add(detobj);
3714 }
3715 }
3716
3717 if (colliding.Count > 0)
3718 {
3719 StartCollidingMessage.Colliders = colliding;
3720
3721 foreach (SceneObjectGroup att in Attachments)
3722 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3723 }
3724 }
3725
3726 if (endedColliders.Count > 0)
3727 {
3728 ColliderArgs EndCollidingMessage = new ColliderArgs();
3729 List<DetectedObject> colliding = new List<DetectedObject>();
3730 foreach (uint localId in endedColliders)
3731 {
3732 if (localId == 0)
3733 continue;
3734
3735 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3736 string data = "";
3737 if (obj != null)
3738 {
3739 DetectedObject detobj = new DetectedObject();
3740 detobj.keyUUID = obj.UUID;
3741 detobj.nameStr = obj.Name;
3742 detobj.ownerUUID = obj.OwnerID;
3743 detobj.posVector = obj.AbsolutePosition;
3744 detobj.rotQuat = obj.GetWorldRotation();
3745 detobj.velVector = obj.Velocity;
3746 detobj.colliderType = 0;
3747 detobj.groupUUID = obj.GroupID;
3748 colliding.Add(detobj);
3749 }
3750 }
3751
3752 if (colliding.Count > 0)
3753 {
3754 EndCollidingMessage.Colliders = colliding;
3755
3756 foreach (SceneObjectGroup att in Attachments)
3757 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3758 }
3759 }
3760
3761 if (thisHitColliders.Count > 0)
3762 {
3763 ColliderArgs CollidingMessage = new ColliderArgs();
3764 List<DetectedObject> colliding = new List<DetectedObject>();
3765 foreach (uint localId in thisHitColliders)
3766 {
3767 if (localId == 0)
3768 continue;
3769
3770 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3771 string data = "";
3772 if (obj != null)
3773 {
3774 DetectedObject detobj = new DetectedObject();
3775 detobj.keyUUID = obj.UUID;
3776 detobj.nameStr = obj.Name;
3777 detobj.ownerUUID = obj.OwnerID;
3778 detobj.posVector = obj.AbsolutePosition;
3779 detobj.rotQuat = obj.GetWorldRotation();
3780 detobj.velVector = obj.Velocity;
3781 detobj.colliderType = 0;
3782 detobj.groupUUID = obj.GroupID;
3783 colliding.Add(detobj);
3784 }
3785 }
3786
3787 if (colliding.Count > 0)
3788 {
3789 CollidingMessage.Colliders = colliding;
3790
3791 lock (m_attachments)
3792 {
3793 foreach (SceneObjectGroup att in m_attachments)
3794 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3795 }
3796 }
3797 }
3798
3271 if (m_invulnerable) 3799 if (m_invulnerable)
3272 return; 3800 return;
3273 3801
@@ -3693,6 +4221,39 @@ namespace OpenSim.Region.Framework.Scenes
3693 return; 4221 return;
3694 } 4222 }
3695 4223
4224 XmlDocument doc = new XmlDocument();
4225 string stateData = String.Empty;
4226
4227 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4228 if (attServ != null)
4229 {
4230 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4231 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4232 if (stateData != String.Empty)
4233 {
4234 try
4235 {
4236 doc.LoadXml(stateData);
4237 }
4238 catch { }
4239 }
4240 }
4241
4242 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4243
4244 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4245 if (nodes.Count > 0)
4246 {
4247 foreach (XmlNode n in nodes)
4248 {
4249 XmlElement elem = (XmlElement)n;
4250 string itemID = elem.GetAttribute("ItemID");
4251 string xml = elem.InnerXml;
4252
4253 itemData[new UUID(itemID)] = xml;
4254 }
4255 }
4256
3696 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4257 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3697 foreach (AvatarAttachment attach in attachments) 4258 foreach (AvatarAttachment attach in attachments)
3698 { 4259 {
@@ -3713,7 +4274,30 @@ namespace OpenSim.Region.Framework.Scenes
3713 4274
3714 try 4275 try
3715 { 4276 {
3716 m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4277 string xmlData;
4278 XmlDocument d = new XmlDocument();
4279 UUID asset;
4280 if (itemData.TryGetValue(itemID, out xmlData))
4281 {
4282 d.LoadXml(xmlData);
4283 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4284
4285 // Rez from inventory
4286 asset
4287 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4288
4289 }
4290 else
4291 {
4292 // Rez from inventory (with a null doc to let
4293 // CHANGED_OWNER happen)
4294 asset
4295 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4296 }
4297
4298 m_log.InfoFormat(
4299 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4300 p, itemID, asset);
3717 } 4301 }
3718 catch (Exception e) 4302 catch (Exception e)
3719 { 4303 {
@@ -3746,5 +4330,16 @@ namespace OpenSim.Region.Framework.Scenes
3746 m_reprioritization_called = false; 4330 m_reprioritization_called = false;
3747 } 4331 }
3748 } 4332 }
4333
4334 private Vector3 Quat2Euler(Quaternion rot){
4335 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4336 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4337 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4338 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4339 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4340 return(new Vector3(x,y,z));
4341 }
4342
4343
3749 } 4344 }
3750} 4345}