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.cs971
1 files changed, 786 insertions, 185 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 82214bf..24c809b 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,9 +159,10 @@ 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;
164 private bool m_flyingOld; // add for fly velocity control
165 public bool m_wasFlying; // add for fly velocity control
159 166
160 private float m_speedModifier = 1.0f; 167 private float m_speedModifier = 1.0f;
161 168
@@ -174,7 +181,8 @@ namespace OpenSim.Region.Framework.Scenes
174 protected RegionInfo m_regionInfo; 181 protected RegionInfo m_regionInfo;
175 protected ulong crossingFromRegion; 182 protected ulong crossingFromRegion;
176 183
177 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 184 private readonly Vector3[] Dir_Vectors = new Vector3[11];
185 private bool m_isNudging = false;
178 186
179 // Position of agent's camera in world (region cordinates) 187 // Position of agent's camera in world (region cordinates)
180 protected Vector3 m_CameraCenter; 188 protected Vector3 m_CameraCenter;
@@ -199,17 +207,25 @@ namespace OpenSim.Region.Framework.Scenes
199 private bool m_autopilotMoving; 207 private bool m_autopilotMoving;
200 private Vector3 m_autoPilotTarget; 208 private Vector3 m_autoPilotTarget;
201 private bool m_sitAtAutoTarget; 209 private bool m_sitAtAutoTarget;
210 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
202 211
203 private string m_nextSitAnimation = String.Empty; 212 private string m_nextSitAnimation = String.Empty;
204 213
205 //PauPaw:Proper PID Controler for autopilot************ 214 //PauPaw:Proper PID Controler for autopilot************
206 private bool m_moveToPositionInProgress; 215 private bool m_moveToPositionInProgress;
207 private Vector3 m_moveToPositionTarget; 216 private Vector3 m_moveToPositionTarget;
217 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
208 218
209 private bool m_followCamAuto; 219 private bool m_followCamAuto;
210 220
211 private int m_movementUpdateCount; 221 private int m_movementUpdateCount;
222 private int m_lastColCount = -1; //KF: Look for Collision chnages
223 private int m_updateCount = 0; //KF: Update Anims for a while
224 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
212 private const int NumMovementsBetweenRayCast = 5; 225 private const int NumMovementsBetweenRayCast = 5;
226 private List<uint> m_lastColliders = new List<uint>();
227
228 private object m_syncRoot = new Object();
213 229
214 private bool CameraConstraintActive; 230 private bool CameraConstraintActive;
215 //private int m_moveToPositionStateStatus; 231 //private int m_moveToPositionStateStatus;
@@ -236,7 +252,9 @@ namespace OpenSim.Region.Framework.Scenes
236 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 252 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
237 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 253 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
238 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 254 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, 255 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
256 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
257 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 258 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
241 } 259 }
242 260
@@ -443,7 +461,8 @@ namespace OpenSim.Region.Framework.Scenes
443 get 461 get
444 { 462 {
445 PhysicsActor actor = m_physicsActor; 463 PhysicsActor actor = m_physicsActor;
446 if (actor != null) 464// if (actor != null)
465 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
447 m_pos = actor.Position; 466 m_pos = actor.Position;
448 else 467 else
449 { 468 {
@@ -492,7 +511,8 @@ namespace OpenSim.Region.Framework.Scenes
492 } 511 }
493 } 512 }
494 513
495 m_pos = value; 514 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
515 m_pos = value;
496 m_parentPosition = Vector3.Zero; 516 m_parentPosition = Vector3.Zero;
497 } 517 }
498 } 518 }
@@ -536,10 +556,39 @@ namespace OpenSim.Region.Framework.Scenes
536 } 556 }
537 } 557 }
538 558
559 public Quaternion OffsetRotation
560 {
561 get { return m_offsetRotation; }
562 set { m_offsetRotation = value; }
563 }
564
539 public Quaternion Rotation 565 public Quaternion Rotation
540 { 566 {
541 get { return m_bodyRot; } 567 get {
542 set { m_bodyRot = value; } 568 if (m_parentID != 0)
569 {
570 if (m_offsetRotation != null)
571 {
572 return m_offsetRotation;
573 }
574 else
575 {
576 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
577 }
578
579 }
580 else
581 {
582 return m_bodyRot;
583 }
584 }
585 set {
586 m_bodyRot = value;
587 if (m_parentID != 0)
588 {
589 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
590 }
591 }
543 } 592 }
544 593
545 public Quaternion PreviousRotation 594 public Quaternion PreviousRotation
@@ -564,11 +613,21 @@ namespace OpenSim.Region.Framework.Scenes
564 613
565 private uint m_parentID; 614 private uint m_parentID;
566 615
616
617 private UUID m_linkedPrim;
618
567 public uint ParentID 619 public uint ParentID
568 { 620 {
569 get { return m_parentID; } 621 get { return m_parentID; }
570 set { m_parentID = value; } 622 set { m_parentID = value; }
571 } 623 }
624
625 public UUID LinkedPrim
626 {
627 get { return m_linkedPrim; }
628 set { m_linkedPrim = value; }
629 }
630
572 public float Health 631 public float Health
573 { 632 {
574 get { return m_health; } 633 get { return m_health; }
@@ -690,7 +749,7 @@ namespace OpenSim.Region.Framework.Scenes
690 CreateSceneViewer(); 749 CreateSceneViewer();
691 m_animator = new ScenePresenceAnimator(this); 750 m_animator = new ScenePresenceAnimator(this);
692 } 751 }
693 752
694 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 753 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
695 { 754 {
696 m_rootRegionHandle = reginfo.RegionHandle; 755 m_rootRegionHandle = reginfo.RegionHandle;
@@ -722,10 +781,7 @@ namespace OpenSim.Region.Framework.Scenes
722 m_reprioritization_timer.AutoReset = false; 781 m_reprioritization_timer.AutoReset = false;
723 782
724 AdjustKnownSeeds(); 783 AdjustKnownSeeds();
725
726 // TODO: I think, this won't send anything, as we are still a child here...
727 Animator.TrySetMovementAnimation("STAND"); 784 Animator.TrySetMovementAnimation("STAND");
728
729 // we created a new ScenePresence (a new child agent) in a fresh region. 785 // we created a new ScenePresence (a new child agent) in a fresh region.
730 // Request info about all the (root) agents in this region 786 // Request info about all the (root) agents in this region
731 // Note: This won't send data *to* other clients in that region (children don't send) 787 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -776,25 +832,47 @@ namespace OpenSim.Region.Framework.Scenes
776 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 832 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
777 Dir_Vectors[4] = Vector3.UnitZ; //UP 833 Dir_Vectors[4] = Vector3.UnitZ; //UP
778 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 834 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
779 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 835 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
780 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 836 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
781 Dir_Vectors[7] = -Vector3.UnitX; //BACK 837 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
838 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
839 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
782 } 840 }
783 841
784 private Vector3[] GetWalkDirectionVectors() 842 private Vector3[] GetWalkDirectionVectors()
785 { 843 {
786 Vector3[] vector = new Vector3[9]; 844 Vector3[] vector = new Vector3[11];
787 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 845 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
788 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 846 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
789 vector[2] = Vector3.UnitY; //LEFT 847 vector[2] = Vector3.UnitY; //LEFT
790 vector[3] = -Vector3.UnitY; //RIGHT 848 vector[3] = -Vector3.UnitY; //RIGHT
791 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 849 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
792 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 850 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
793 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 851 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
794 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 852 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
795 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 853 vector[8] = Vector3.UnitY; //LEFT_NUDGE
854 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
855 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
796 return vector; 856 return vector;
797 } 857 }
858
859 private bool[] GetDirectionIsNudge()
860 {
861 bool[] isNudge = new bool[11];
862 isNudge[0] = false; //FORWARD
863 isNudge[1] = false; //BACK
864 isNudge[2] = false; //LEFT
865 isNudge[3] = false; //RIGHT
866 isNudge[4] = false; //UP
867 isNudge[5] = false; //DOWN
868 isNudge[6] = true; //FORWARD_NUDGE
869 isNudge[7] = true; //BACK_NUDGE
870 isNudge[8] = true; //LEFT_NUDGE
871 isNudge[9] = true; //RIGHT_NUDGE
872 isNudge[10] = true; //DOWN_Nudge
873 return isNudge;
874 }
875
798 876
799 #endregion 877 #endregion
800 878
@@ -856,6 +934,54 @@ namespace OpenSim.Region.Framework.Scenes
856 pos.Y = crossedBorder.BorderLine.Z - 1; 934 pos.Y = crossedBorder.BorderLine.Z - 1;
857 } 935 }
858 936
937 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
938 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
939 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
940 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
941 if (land != null)
942 {
943 if (KnownChildRegionHandles.Count == 0)
944 {
945 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
946 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)
947 {
948 pos = land.LandData.UserLocation;
949 }
950 }
951
952 land.SendLandUpdateToClient(ControllingClient);
953 }
954
955 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
956 {
957 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
958
959 if (pos.X < 0)
960 {
961 emergencyPos.X = (int)Constants.RegionSize + pos.X;
962 if (!(pos.Y < 0))
963 emergencyPos.Y = pos.Y;
964 if (!(pos.Z < 0))
965 emergencyPos.Z = pos.Z;
966 }
967 if (pos.Y < 0)
968 {
969 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
970 if (!(pos.X < 0))
971 emergencyPos.X = pos.X;
972 if (!(pos.Z < 0))
973 emergencyPos.Z = pos.Z;
974 }
975 if (pos.Z < 0)
976 {
977 emergencyPos.Z = 128;
978 if (!(pos.Y < 0))
979 emergencyPos.Y = pos.Y;
980 if (!(pos.X < 0))
981 emergencyPos.X = pos.X;
982 }
983 }
984
859 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 985 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
860 { 986 {
861 m_log.WarnFormat( 987 m_log.WarnFormat(
@@ -984,12 +1110,17 @@ namespace OpenSim.Region.Framework.Scenes
984 { 1110 {
985 if (PhysicsActor != null) 1111 if (PhysicsActor != null)
986 { 1112 {
987 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1113 try
988 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1114 {
989 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1115 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
990 m_physicsActor.UnSubscribeEvents(); 1116 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
991 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1117 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
992 PhysicsActor = null; 1118 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1119 m_physicsActor.UnSubscribeEvents();
1120 PhysicsActor = null;
1121 }
1122 catch
1123 { }
993 } 1124 }
994 } 1125 }
995 1126
@@ -1000,9 +1131,10 @@ namespace OpenSim.Region.Framework.Scenes
1000 public void Teleport(Vector3 pos) 1131 public void Teleport(Vector3 pos)
1001 { 1132 {
1002 bool isFlying = false; 1133 bool isFlying = false;
1134
1003 if (m_physicsActor != null) 1135 if (m_physicsActor != null)
1004 isFlying = m_physicsActor.Flying; 1136 isFlying = m_physicsActor.Flying;
1005 1137
1006 RemoveFromPhysicalScene(); 1138 RemoveFromPhysicalScene();
1007 Velocity = Vector3.Zero; 1139 Velocity = Vector3.Zero;
1008 AbsolutePosition = pos; 1140 AbsolutePosition = pos;
@@ -1014,6 +1146,7 @@ namespace OpenSim.Region.Framework.Scenes
1014 } 1146 }
1015 1147
1016 SendTerseUpdateToAllClients(); 1148 SendTerseUpdateToAllClients();
1149
1017 } 1150 }
1018 1151
1019 public void TeleportWithMomentum(Vector3 pos) 1152 public void TeleportWithMomentum(Vector3 pos)
@@ -1232,6 +1365,7 @@ namespace OpenSim.Region.Framework.Scenes
1232 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1365 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1233 1366
1234 m_pos = m_LastFinitePos; 1367 m_pos = m_LastFinitePos;
1368
1235 if (!m_pos.IsFinite()) 1369 if (!m_pos.IsFinite())
1236 { 1370 {
1237 m_pos.X = 127f; 1371 m_pos.X = 127f;
@@ -1298,7 +1432,6 @@ namespace OpenSim.Region.Framework.Scenes
1298 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1432 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1299 } 1433 }
1300 } 1434 }
1301
1302 lock (scriptedcontrols) 1435 lock (scriptedcontrols)
1303 { 1436 {
1304 if (scriptedcontrols.Count > 0) 1437 if (scriptedcontrols.Count > 0)
@@ -1313,6 +1446,9 @@ namespace OpenSim.Region.Framework.Scenes
1313 1446
1314 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1447 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1315 { 1448 {
1449 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1450 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1451
1316 // TODO: This doesn't prevent the user from walking yet. 1452 // TODO: This doesn't prevent the user from walking yet.
1317 // Setting parent ID would fix this, if we knew what value 1453 // Setting parent ID would fix this, if we knew what value
1318 // to use. Or we could add a m_isSitting variable. 1454 // to use. Or we could add a m_isSitting variable.
@@ -1361,12 +1497,20 @@ namespace OpenSim.Region.Framework.Scenes
1361 if (actor.Flying != oldflying) 1497 if (actor.Flying != oldflying)
1362 update_movementflag = true; 1498 update_movementflag = true;
1363 1499
1500 if (m_animator.m_jumping) // add for jumping
1501 update_movementflag = true;
1502
1364 if (q != m_bodyRot) 1503 if (q != m_bodyRot)
1365 { 1504 {
1366 m_bodyRot = q; 1505 m_bodyRot = q;
1367 update_rotation = true; 1506 update_rotation = true;
1368 } 1507 }
1369 1508
1509 //guilty until proven innocent..
1510 bool Nudging = true;
1511 //Basically, if there is at least one non-nudge control then we don't need
1512 //to worry about stopping the avatar
1513
1370 if (m_parentID == 0) 1514 if (m_parentID == 0)
1371 { 1515 {
1372 bool bAllowUpdateMoveToPosition = false; 1516 bool bAllowUpdateMoveToPosition = false;
@@ -1381,9 +1525,12 @@ namespace OpenSim.Region.Framework.Scenes
1381 else 1525 else
1382 dirVectors = Dir_Vectors; 1526 dirVectors = Dir_Vectors;
1383 1527
1384 // The fact that m_movementflag is a byte needs to be fixed 1528 bool[] isNudge = GetDirectionIsNudge();
1385 // it really should be a uint 1529
1386 uint nudgehack = 250; 1530
1531
1532
1533
1387 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1534 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1388 { 1535 {
1389 if (((uint)flags & (uint)DCF) != 0) 1536 if (((uint)flags & (uint)DCF) != 0)
@@ -1393,40 +1540,28 @@ namespace OpenSim.Region.Framework.Scenes
1393 try 1540 try
1394 { 1541 {
1395 agent_control_v3 += dirVectors[i]; 1542 agent_control_v3 += dirVectors[i];
1396 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1543 if (isNudge[i] == false)
1544 {
1545 Nudging = false;
1546 }
1397 } 1547 }
1398 catch (IndexOutOfRangeException) 1548 catch (IndexOutOfRangeException)
1399 { 1549 {
1400 // Why did I get this? 1550 // Why did I get this?
1401 } 1551 }
1402 1552
1403 if ((m_movementflag & (byte)(uint)DCF) == 0) 1553 if ((m_movementflag & (uint)DCF) == 0)
1404 { 1554 {
1405 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1406 {
1407 m_movementflag |= (byte)nudgehack;
1408 }
1409 m_movementflag += (byte)(uint)DCF; 1555 m_movementflag += (byte)(uint)DCF;
1410 update_movementflag = true; 1556 update_movementflag = true;
1411 } 1557 }
1412 } 1558 }
1413 else 1559 else
1414 { 1560 {
1415 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1561 if ((m_movementflag & (uint)DCF) != 0)
1416 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1417 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1418 ) // This or is for Nudge forward
1419 { 1562 {
1420 m_movementflag -= ((byte)(uint)DCF); 1563 m_movementflag -= (byte)(uint)DCF;
1421
1422 update_movementflag = true; 1564 update_movementflag = true;
1423 /*
1424 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1425 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1426 {
1427 m_log.Debug("Removed Hack flag");
1428 }
1429 */
1430 } 1565 }
1431 else 1566 else
1432 { 1567 {
@@ -1435,7 +1570,6 @@ namespace OpenSim.Region.Framework.Scenes
1435 } 1570 }
1436 i++; 1571 i++;
1437 } 1572 }
1438
1439 //Paupaw:Do Proper PID for Autopilot here 1573 //Paupaw:Do Proper PID for Autopilot here
1440 if (bResetMoveToPosition) 1574 if (bResetMoveToPosition)
1441 { 1575 {
@@ -1470,6 +1604,9 @@ namespace OpenSim.Region.Framework.Scenes
1470 // Ignore z component of vector 1604 // Ignore z component of vector
1471 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1605 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1472 LocalVectorToTarget2D.Normalize(); 1606 LocalVectorToTarget2D.Normalize();
1607
1608 //We're not nudging
1609 Nudging = false;
1473 agent_control_v3 += LocalVectorToTarget2D; 1610 agent_control_v3 += LocalVectorToTarget2D;
1474 1611
1475 // update avatar movement flags. the avatar coordinate system is as follows: 1612 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1560,13 +1697,13 @@ namespace OpenSim.Region.Framework.Scenes
1560 // m_log.DebugFormat( 1697 // m_log.DebugFormat(
1561 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1698 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1562 1699
1563 AddNewMovement(agent_control_v3, q); 1700 AddNewMovement(agent_control_v3, q, Nudging);
1564 1701
1565 1702
1566 } 1703 }
1567 } 1704 }
1568 1705
1569 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1706 if (update_movementflag && !SitGround)
1570 Animator.UpdateMovementAnimations(); 1707 Animator.UpdateMovementAnimations();
1571 1708
1572 m_scene.EventManager.TriggerOnClientMovement(this); 1709 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1581,7 +1718,6 @@ namespace OpenSim.Region.Framework.Scenes
1581 m_sitAtAutoTarget = false; 1718 m_sitAtAutoTarget = false;
1582 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1719 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1583 //proxy.PCode = (byte)PCode.ParticleSystem; 1720 //proxy.PCode = (byte)PCode.ParticleSystem;
1584
1585 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1721 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1586 proxyObjectGroup.AttachToScene(m_scene); 1722 proxyObjectGroup.AttachToScene(m_scene);
1587 1723
@@ -1623,7 +1759,7 @@ namespace OpenSim.Region.Framework.Scenes
1623 } 1759 }
1624 m_moveToPositionInProgress = true; 1760 m_moveToPositionInProgress = true;
1625 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1761 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1626 } 1762 }
1627 catch (Exception ex) 1763 catch (Exception ex)
1628 { 1764 {
1629 //Why did I get this error? 1765 //Why did I get this error?
@@ -1645,7 +1781,7 @@ namespace OpenSim.Region.Framework.Scenes
1645 Velocity = Vector3.Zero; 1781 Velocity = Vector3.Zero;
1646 SendAvatarDataToAllAgents(); 1782 SendAvatarDataToAllAgents();
1647 1783
1648 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1784 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1649 } 1785 }
1650 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1786 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1651 m_requestedSitTargetUUID = UUID.Zero; 1787 m_requestedSitTargetUUID = UUID.Zero;
@@ -1682,42 +1818,77 @@ namespace OpenSim.Region.Framework.Scenes
1682 1818
1683 if (m_parentID != 0) 1819 if (m_parentID != 0)
1684 { 1820 {
1685 m_log.Debug("StandupCode Executed"); 1821 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1686 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1687 if (part != null) 1822 if (part != null)
1688 { 1823 {
1824 part.TaskInventory.LockItemsForRead(true);
1689 TaskInventoryDictionary taskIDict = part.TaskInventory; 1825 TaskInventoryDictionary taskIDict = part.TaskInventory;
1690 if (taskIDict != null) 1826 if (taskIDict != null)
1691 { 1827 {
1692 lock (taskIDict) 1828 foreach (UUID taskID in taskIDict.Keys)
1693 { 1829 {
1694 foreach (UUID taskID in taskIDict.Keys) 1830 UnRegisterControlEventsToScript(LocalId, taskID);
1695 { 1831 taskIDict[taskID].PermsMask &= ~(
1696 UnRegisterControlEventsToScript(LocalId, taskID); 1832 2048 | //PERMISSION_CONTROL_CAMERA
1697 taskIDict[taskID].PermsMask &= ~( 1833 4); // PERMISSION_TAKE_CONTROLS
1698 2048 | //PERMISSION_CONTROL_CAMERA
1699 4); // PERMISSION_TAKE_CONTROLS
1700 }
1701 } 1834 }
1702
1703 } 1835 }
1836 part.TaskInventory.LockItemsForRead(false);
1704 // Reset sit target. 1837 // Reset sit target.
1705 if (part.GetAvatarOnSitTarget() == UUID) 1838 if (part.GetAvatarOnSitTarget() == UUID)
1706 part.SetAvatarOnSitTarget(UUID.Zero); 1839 part.SetAvatarOnSitTarget(UUID.Zero);
1707
1708 m_parentPosition = part.GetWorldPosition(); 1840 m_parentPosition = part.GetWorldPosition();
1709 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1841 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1710 } 1842 }
1843 // part.GetWorldRotation() is the rotation of the object being sat on
1844 // Rotation is the sittiing Av's rotation
1845
1846 Quaternion partRot;
1847// if (part.LinkNum == 1)
1848// { // Root prim of linkset
1849// partRot = part.ParentGroup.RootPart.RotationOffset;
1850// }
1851// else
1852// { // single or child prim
1853
1854// }
1855 if (part == null) //CW: Part may be gone. llDie() for example.
1856 {
1857 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1858 }
1859 else
1860 {
1861 partRot = part.GetWorldRotation();
1862 }
1711 1863
1864 Quaternion partIRot = Quaternion.Inverse(partRot);
1865
1866 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1867 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1868
1869
1712 if (m_physicsActor == null) 1870 if (m_physicsActor == null)
1713 { 1871 {
1714 AddToPhysicalScene(false); 1872 AddToPhysicalScene(false);
1715 } 1873 }
1716 1874 //CW: If the part isn't null then we can set the current position
1717 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1875 if (part != null)
1718 m_parentPosition = Vector3.Zero; 1876 {
1719 1877 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1720 m_parentID = 0; 1878 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1879 part.IsOccupied = false;
1880 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1881 }
1882 else
1883 {
1884 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1885 AbsolutePosition = m_lastWorldPosition;
1886 }
1887
1888 m_parentPosition = Vector3.Zero;
1889 m_parentID = 0;
1890 m_linkedPrim = UUID.Zero;
1891 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1721 SendAvatarDataToAllAgents(); 1892 SendAvatarDataToAllAgents();
1722 m_requestedSitTargetID = 0; 1893 m_requestedSitTargetID = 0;
1723 if (m_physicsActor != null && m_appearance != null) 1894 if (m_physicsActor != null && m_appearance != null)
@@ -1726,7 +1897,6 @@ namespace OpenSim.Region.Framework.Scenes
1726 SetHeight(m_appearance.AvatarHeight); 1897 SetHeight(m_appearance.AvatarHeight);
1727 } 1898 }
1728 } 1899 }
1729
1730 Animator.TrySetMovementAnimation("STAND"); 1900 Animator.TrySetMovementAnimation("STAND");
1731 } 1901 }
1732 1902
@@ -1757,13 +1927,9 @@ namespace OpenSim.Region.Framework.Scenes
1757 Vector3 avSitOffSet = part.SitTargetPosition; 1927 Vector3 avSitOffSet = part.SitTargetPosition;
1758 Quaternion avSitOrientation = part.SitTargetOrientation; 1928 Quaternion avSitOrientation = part.SitTargetOrientation;
1759 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1929 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1760 1930 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1761 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1931 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1762 bool SitTargetisSet = 1932 if (SitTargetisSet && !SitTargetOccupied)
1763 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1764 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1765
1766 if (SitTargetisSet && SitTargetUnOccupied)
1767 { 1933 {
1768 //switch the target to this prim 1934 //switch the target to this prim
1769 return part; 1935 return part;
@@ -1777,84 +1943,164 @@ namespace OpenSim.Region.Framework.Scenes
1777 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1943 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1778 { 1944 {
1779 bool autopilot = true; 1945 bool autopilot = true;
1946 Vector3 autopilotTarget = new Vector3();
1947 Quaternion sitOrientation = Quaternion.Identity;
1780 Vector3 pos = new Vector3(); 1948 Vector3 pos = new Vector3();
1781 Quaternion sitOrientation = pSitOrientation;
1782 Vector3 cameraEyeOffset = Vector3.Zero; 1949 Vector3 cameraEyeOffset = Vector3.Zero;
1783 Vector3 cameraAtOffset = Vector3.Zero; 1950 Vector3 cameraAtOffset = Vector3.Zero;
1784 bool forceMouselook = false; 1951 bool forceMouselook = false;
1785 1952
1786 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1953 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1787 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1954 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1788 if (part != null) 1955 if (part == null) return;
1789 { 1956
1790 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1957 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1791 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1958 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1792 1959
1793 // Is a sit target available? 1960 // part is the prim to sit on
1794 Vector3 avSitOffSet = part.SitTargetPosition; 1961 // offset is the world-ref vector distance from that prim center to the click-spot
1795 Quaternion avSitOrientation = part.SitTargetOrientation; 1962 // UUID is the UUID of the Avatar doing the clicking
1796 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1963
1797 1964 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1798 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1965
1799 bool SitTargetisSet = 1966 // Is a sit target available?
1800 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1967 Vector3 avSitOffSet = part.SitTargetPosition;
1801 ( 1968 Quaternion avSitOrientation = part.SitTargetOrientation;
1802 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1969
1803 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1970 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1804 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1971 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1805 ) 1972 Quaternion partRot;
1806 )); 1973// if (part.LinkNum == 1)
1807 1974// { // Root prim of linkset
1808 if (SitTargetisSet && SitTargetUnOccupied) 1975// partRot = part.ParentGroup.RootPart.RotationOffset;
1809 { 1976// }
1810 part.SetAvatarOnSitTarget(UUID); 1977// else
1811 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1978// { // single or child prim
1812 sitOrientation = avSitOrientation; 1979 partRot = part.GetWorldRotation();
1813 autopilot = false; 1980// }
1814 } 1981 Quaternion partIRot = Quaternion.Inverse(partRot);
1815 1982//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1816 pos = part.AbsolutePosition + offset; 1983 // Sit analysis rewritten by KF 091125
1817 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1984 if (SitTargetisSet) // scipted sit
1818 //{ 1985 {
1819 // offset = pos; 1986 if (!part.IsOccupied)
1820 //autopilot = false; 1987 {
1821 //} 1988//Console.WriteLine("Scripted, unoccupied");
1822 if (m_physicsActor != null) 1989 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1823 { 1990 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1824 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1991
1825 // We can remove the physicsActor until they stand up. 1992 Quaternion nrot = avSitOrientation;
1826 m_sitAvatarHeight = m_physicsActor.Size.Z; 1993 if (!part.IsRoot)
1827
1828 if (autopilot)
1829 { 1994 {
1830 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1995 nrot = part.RotationOffset * avSitOrientation;
1831 {
1832 autopilot = false;
1833
1834 RemoveFromPhysicalScene();
1835 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1836 }
1837 } 1996 }
1838 else 1997 sitOrientation = nrot; // Change rotatione to the scripted one
1998 OffsetRotation = nrot;
1999 autopilot = false; // Jump direct to scripted llSitPos()
2000 }
2001 else
2002 {
2003//Console.WriteLine("Scripted, occupied");
2004 return;
2005 }
2006 }
2007 else // Not Scripted
2008 {
2009 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
2010 {
2011 // large prim & offset, ignore if other Avs sitting
2012// offset.Z -= 0.05f;
2013 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2014 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2015
2016//Console.WriteLine(" offset ={0}", offset);
2017//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2018//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2019
2020 }
2021 else // small offset
2022 {
2023//Console.WriteLine("Small offset");
2024 if (!part.IsOccupied)
2025 {
2026 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2027 autopilotTarget = part.AbsolutePosition;
2028//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2029 }
2030 else return; // occupied small
2031 } // end large/small
2032 } // end Scripted/not
2033 cameraAtOffset = part.GetCameraAtOffset();
2034 cameraEyeOffset = part.GetCameraEyeOffset();
2035 forceMouselook = part.GetForceMouselook();
2036 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2037 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2038
2039 if (m_physicsActor != null)
2040 {
2041 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2042 // We can remove the physicsActor until they stand up.
2043 m_sitAvatarHeight = m_physicsActor.Size.Z;
2044 if (autopilot)
2045 { // its not a scripted sit
2046// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2047 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1839 { 2048 {
2049 autopilot = false; // close enough
2050 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2051 Not using the part's position because returning the AV to the last known standing
2052 position is likely to be more friendly, isn't it? */
1840 RemoveFromPhysicalScene(); 2053 RemoveFromPhysicalScene();
1841 } 2054 Velocity = Vector3.Zero;
2055 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2056 } // else the autopilot will get us close
2057 }
2058 else
2059 { // its a scripted sit
2060 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2061 I *am* using the part's position this time because we have no real idea how far away
2062 the avatar is from the sit target. */
2063 RemoveFromPhysicalScene();
2064 Velocity = Vector3.Zero;
1842 } 2065 }
1843
1844 cameraAtOffset = part.GetCameraAtOffset();
1845 cameraEyeOffset = part.GetCameraEyeOffset();
1846 forceMouselook = part.GetForceMouselook();
1847 } 2066 }
1848 2067 else return; // physactor is null!
1849 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2068
1850 m_requestedSitTargetUUID = targetID; 2069 Vector3 offsetr; // = offset * partIRot;
2070 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2071 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2072 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2073 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2074 //offsetr = offset * partIRot;
2075//
2076 // else
2077 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2078 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2079 // (offset * partRot);
2080 // }
2081
2082//Console.WriteLine(" ");
2083//Console.WriteLine("link number ={0}", part.LinkNum);
2084//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2085//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2086//Console.WriteLine("Click offst ={0}", offset);
2087//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2088//Console.WriteLine("offsetr ={0}", offsetr);
2089//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2090//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2091
2092 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2093 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2094
2095 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1851 // This calls HandleAgentSit twice, once from here, and the client calls 2096 // This calls HandleAgentSit twice, once from here, and the client calls
1852 // HandleAgentSit itself after it gets to the location 2097 // HandleAgentSit itself after it gets to the location
1853 // It doesn't get to the location until we've moved them there though 2098 // It doesn't get to the location until we've moved them there though
1854 // which happens in HandleAgentSit :P 2099 // which happens in HandleAgentSit :P
1855 m_autopilotMoving = autopilot; 2100 m_autopilotMoving = autopilot;
1856 m_autoPilotTarget = pos; 2101 m_autoPilotTarget = autopilotTarget;
1857 m_sitAtAutoTarget = autopilot; 2102 m_sitAtAutoTarget = autopilot;
2103 m_initialSitTarget = autopilotTarget;
1858 if (!autopilot) 2104 if (!autopilot)
1859 HandleAgentSit(remoteClient, UUID); 2105 HandleAgentSit(remoteClient, UUID);
1860 } 2106 }
@@ -2149,47 +2395,130 @@ namespace OpenSim.Region.Framework.Scenes
2149 { 2395 {
2150 if (part != null) 2396 if (part != null)
2151 { 2397 {
2398//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2152 if (part.GetAvatarOnSitTarget() == UUID) 2399 if (part.GetAvatarOnSitTarget() == UUID)
2153 { 2400 {
2401//Console.WriteLine("Scripted Sit");
2402 // Scripted sit
2154 Vector3 sitTargetPos = part.SitTargetPosition; 2403 Vector3 sitTargetPos = part.SitTargetPosition;
2155 Quaternion sitTargetOrient = part.SitTargetOrientation; 2404 Quaternion sitTargetOrient = part.SitTargetOrientation;
2156
2157 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2158 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2159
2160 //Quaternion result = (sitTargetOrient * vq) * nq;
2161
2162 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2405 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2163 m_pos += SIT_TARGET_ADJUSTMENT; 2406 m_pos += SIT_TARGET_ADJUSTMENT;
2407 if (!part.IsRoot)
2408 {
2409 m_pos *= part.RotationOffset;
2410 }
2164 m_bodyRot = sitTargetOrient; 2411 m_bodyRot = sitTargetOrient;
2165 //Rotation = sitTargetOrient;
2166 m_parentPosition = part.AbsolutePosition; 2412 m_parentPosition = part.AbsolutePosition;
2167 2413 part.IsOccupied = true;
2168 //SendTerseUpdateToAllClients(); 2414 part.ParentGroup.AddAvatar(agentID);
2169 } 2415 }
2170 else 2416 else
2171 { 2417 {
2172 m_pos -= part.AbsolutePosition; 2418 // if m_avUnscriptedSitPos is zero then Av sits above center
2419 // Else Av sits at m_avUnscriptedSitPos
2420
2421 // Non-scripted sit by Kitto Flora 21Nov09
2422 // Calculate angle of line from prim to Av
2423 Quaternion partIRot;
2424// if (part.LinkNum == 1)
2425// { // Root prim of linkset
2426// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2427// }
2428// else
2429// { // single or child prim
2430 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2431// }
2432 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2433 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2434 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2435 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2436 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2437 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2438 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2439 // Av sits at world euler <0,0, z>, translated by part rotation
2440 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2441
2173 m_parentPosition = part.AbsolutePosition; 2442 m_parentPosition = part.AbsolutePosition;
2174 } 2443 part.IsOccupied = true;
2444 part.ParentGroup.AddAvatar(agentID);
2445 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2446 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2447 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2448 m_avUnscriptedSitPos; // adds click offset, if any
2449 //Set up raytrace to find top surface of prim
2450 Vector3 size = part.Scale;
2451 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2452 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2453 Vector3 down = new Vector3(0f, 0f, -1f);
2454//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2455 m_scene.PhysicsScene.RaycastWorld(
2456 start, // Vector3 position,
2457 down, // Vector3 direction,
2458 mag, // float length,
2459 SitAltitudeCallback); // retMethod
2460 } // end scripted/not
2175 } 2461 }
2176 else 2462 else // no Av
2177 { 2463 {
2178 return; 2464 return;
2179 } 2465 }
2180 } 2466 }
2181 m_parentID = m_requestedSitTargetID;
2182 2467
2468 //We want our offsets to reference the root prim, not the child we may have sat on
2469 if (!part.IsRoot)
2470 {
2471 m_parentID = part.ParentGroup.RootPart.LocalId;
2472 m_pos += part.OffsetPosition;
2473 }
2474 else
2475 {
2476 m_parentID = m_requestedSitTargetID;
2477 }
2478
2479 m_linkedPrim = part.UUID;
2480 if (part.GetAvatarOnSitTarget() != UUID)
2481 {
2482 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2483 }
2183 Velocity = Vector3.Zero; 2484 Velocity = Vector3.Zero;
2184 RemoveFromPhysicalScene(); 2485 RemoveFromPhysicalScene();
2185
2186 Animator.TrySetMovementAnimation(sitAnimation); 2486 Animator.TrySetMovementAnimation(sitAnimation);
2187 SendAvatarDataToAllAgents(); 2487 SendAvatarDataToAllAgents();
2188 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2189 // So we're also sending a terse update (which has avatar rotation)
2190 // [Update] We do now.
2191 //SendTerseUpdateToAllClients(); 2488 //SendTerseUpdateToAllClients();
2192 } 2489 }
2490
2491 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2492 {
2493 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2494 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2495 if(hitYN)
2496 {
2497 // m_pos = Av offset from prim center to make look like on center
2498 // m_parentPosition = Actual center pos of prim
2499 // collisionPoint = spot on prim where we want to sit
2500 // collisionPoint.Z = global sit surface height
2501 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2502 Quaternion partIRot;
2503// if (part.LinkNum == 1)
2504/// { // Root prim of linkset
2505// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2506// }
2507// else
2508// { // single or child prim
2509 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2510// }
2511 if (m_initialSitTarget != null)
2512 {
2513 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2514 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2515 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2516 m_pos += offset;
2517 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2518 }
2519
2520 }
2521 } // End SitAltitudeCallback KF.
2193 2522
2194 /// <summary> 2523 /// <summary>
2195 /// Event handler for the 'Always run' setting on the client 2524 /// Event handler for the 'Always run' setting on the client
@@ -2219,7 +2548,7 @@ namespace OpenSim.Region.Framework.Scenes
2219 /// </summary> 2548 /// </summary>
2220 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2549 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2221 /// <param name="rotation">The direction in which this avatar should now face. 2550 /// <param name="rotation">The direction in which this avatar should now face.
2222 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2551 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2223 { 2552 {
2224 if (m_isChildAgent) 2553 if (m_isChildAgent)
2225 { 2554 {
@@ -2260,15 +2589,26 @@ namespace OpenSim.Region.Framework.Scenes
2260 Rotation = rotation; 2589 Rotation = rotation;
2261 Vector3 direc = vec * rotation; 2590 Vector3 direc = vec * rotation;
2262 direc.Normalize(); 2591 direc.Normalize();
2592 PhysicsActor actor = m_physicsActor;
2593
2594 if (actor.Flying != m_flyingOld) // add for fly velocity control
2595 {
2596 m_flyingOld = actor.Flying; // add for fly velocity control
2597 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2598 }
2599
2600 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2601
2602 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2263 2603
2264 direc *= 0.03f * 128f * m_speedModifier; 2604 direc *= 0.03f * 128f * m_speedModifier;
2265 2605
2266 PhysicsActor actor = m_physicsActor;
2267 if (actor != null) 2606 if (actor != null)
2268 { 2607 {
2269 if (actor.Flying) 2608 if (actor.Flying)
2270 { 2609 {
2271 direc *= 4.0f; 2610// rm speed mod direc *= 4.0f;
2611 direc *= 5.2f; // for speed mod
2272 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2612 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2273 //bool colliding = (m_physicsActor.IsColliding==true); 2613 //bool colliding = (m_physicsActor.IsColliding==true);
2274 //if (controlland) 2614 //if (controlland)
@@ -2281,22 +2621,34 @@ namespace OpenSim.Region.Framework.Scenes
2281 // m_log.Info("[AGENT]: Stop FLying"); 2621 // m_log.Info("[AGENT]: Stop FLying");
2282 //} 2622 //}
2283 } 2623 }
2624 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2625 {
2626 direc *= 0.0f;
2627 }
2628 /* This jumping section removed to SPA
2284 else if (!actor.Flying && actor.IsColliding) 2629 else if (!actor.Flying && actor.IsColliding)
2285 { 2630 {
2286 if (direc.Z > 2.0f) 2631 if (direc.Z > 2.0f)
2287 { 2632 {
2288 direc.Z *= 3.0f; 2633 if(m_animator.m_animTickJump == -1)
2289 2634 {
2290 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2635 direc.Z *= 3.0f; // jump
2291 Animator.TrySetMovementAnimation("PREJUMP"); 2636 }
2292 Animator.TrySetMovementAnimation("JUMP"); 2637 else
2638 {
2639 direc.Z *= 0.1f; // prejump
2640 }
2641 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2642 Animator.TrySetMovementAnimation("PREJUMP");
2643 Animator.TrySetMovementAnimation("JUMP");
2644 * /
2293 } 2645 }
2294 } 2646 } */
2295 } 2647 }
2296 2648
2297 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2649 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2298 m_forceToApply = direc; 2650 m_forceToApply = direc;
2299 2651 m_isNudging = Nudging;
2300 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2652 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2301 } 2653 }
2302 2654
@@ -2311,7 +2663,7 @@ namespace OpenSim.Region.Framework.Scenes
2311 const float POSITION_TOLERANCE = 0.05f; 2663 const float POSITION_TOLERANCE = 0.05f;
2312 //const int TIME_MS_TOLERANCE = 3000; 2664 //const int TIME_MS_TOLERANCE = 3000;
2313 2665
2314 SendPrimUpdates(); 2666
2315 2667
2316 if (m_isChildAgent == false) 2668 if (m_isChildAgent == false)
2317 { 2669 {
@@ -2341,6 +2693,9 @@ namespace OpenSim.Region.Framework.Scenes
2341 CheckForBorderCrossing(); 2693 CheckForBorderCrossing();
2342 CheckForSignificantMovement(); // sends update to the modules. 2694 CheckForSignificantMovement(); // sends update to the modules.
2343 } 2695 }
2696
2697 //Sending prim updates AFTER the avatar terse updates are sent
2698 SendPrimUpdates();
2344 } 2699 }
2345 2700
2346 #endregion 2701 #endregion
@@ -3089,6 +3444,7 @@ namespace OpenSim.Region.Framework.Scenes
3089 m_callbackURI = cAgent.CallbackURI; 3444 m_callbackURI = cAgent.CallbackURI;
3090 3445
3091 m_pos = cAgent.Position; 3446 m_pos = cAgent.Position;
3447
3092 m_velocity = cAgent.Velocity; 3448 m_velocity = cAgent.Velocity;
3093 m_CameraCenter = cAgent.Center; 3449 m_CameraCenter = cAgent.Center;
3094 m_CameraAtAxis = cAgent.AtAxis; 3450 m_CameraAtAxis = cAgent.AtAxis;
@@ -3207,17 +3563,46 @@ namespace OpenSim.Region.Framework.Scenes
3207 /// </summary> 3563 /// </summary>
3208 public override void UpdateMovement() 3564 public override void UpdateMovement()
3209 { 3565 {
3210 if (m_forceToApply.HasValue) 3566 if (Animator!=null) // add for jumping
3211 { 3567 { // add for jumping
3212 Vector3 force = m_forceToApply.Value; 3568 // if (!m_animator.m_jumping) // add for jumping
3569 // { // add for jumping
3213 3570
3214 m_updateflag = true; 3571 if (m_forceToApply.HasValue) // this section realigned
3215// movementvector = force; 3572 {
3216 Velocity = force;
3217 3573
3218 m_forceToApply = null; 3574 Vector3 force = m_forceToApply.Value;
3219 } 3575 m_updateflag = true;
3220 } 3576if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3577 Velocity = force;
3578//Console.WriteLine("UM1 {0}", Velocity);
3579 m_forceToApply = null;
3580 }
3581 else
3582 {
3583 if (m_isNudging)
3584 {
3585 Vector3 force = Vector3.Zero;
3586
3587 m_updateflag = true;
3588if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3589 Velocity = force;
3590//Console.WriteLine("UM2 {0}", Velocity);
3591 m_isNudging = false;
3592 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3593 }
3594 else // add for jumping
3595 { // add for jumping
3596 Vector3 force = Vector3.Zero; // add for jumping
3597if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3598//Console.WriteLine("UM3 {0}", Velocity);
3599 Velocity = force; // add for jumping
3600 }
3601
3602 }
3603 // } // end realign
3604 } // add for jumping
3605 } // add for jumping
3221 3606
3222 /// <summary> 3607 /// <summary>
3223 /// Adds a physical representation of the avatar to the Physics plugin 3608 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3231,10 +3616,8 @@ namespace OpenSim.Region.Framework.Scenes
3231 3616
3232 Vector3 pVec = AbsolutePosition; 3617 Vector3 pVec = AbsolutePosition;
3233 3618
3234 // Old bug where the height was in centimeters instead of meters
3235 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3619 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3236 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3620 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3237
3238 scene.AddPhysicsActorTaint(m_physicsActor); 3621 scene.AddPhysicsActorTaint(m_physicsActor);
3239 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3622 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3240 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3623 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3258,18 +3641,29 @@ namespace OpenSim.Region.Framework.Scenes
3258 { 3641 {
3259 if (e == null) 3642 if (e == null)
3260 return; 3643 return;
3261 3644
3262 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3645 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3263 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3264 // as of this comment the interval is set in AddToPhysicalScene 3646 // as of this comment the interval is set in AddToPhysicalScene
3265 if (Animator!=null) 3647 if (Animator!=null)
3266 Animator.UpdateMovementAnimations(); 3648 {
3649 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3650 { // else its will lock out other animation changes, like ground sit.
3651 Animator.UpdateMovementAnimations();
3652 m_updateCount--;
3653 }
3654 }
3267 3655
3268 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3656 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3269 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3657 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3270 3658
3271 CollisionPlane = Vector4.UnitW; 3659 CollisionPlane = Vector4.UnitW;
3272 3660
3661 if (m_lastColCount != coldata.Count)
3662 {
3663 m_updateCount = UPDATE_COUNT;
3664 m_lastColCount = coldata.Count;
3665 }
3666
3273 if (coldata.Count != 0 && Animator != null) 3667 if (coldata.Count != 0 && Animator != null)
3274 { 3668 {
3275 switch (Animator.CurrentMovementAnimation) 3669 switch (Animator.CurrentMovementAnimation)
@@ -3299,6 +3693,148 @@ namespace OpenSim.Region.Framework.Scenes
3299 } 3693 }
3300 } 3694 }
3301 3695
3696 List<uint> thisHitColliders = new List<uint>();
3697 List<uint> endedColliders = new List<uint>();
3698 List<uint> startedColliders = new List<uint>();
3699
3700 foreach (uint localid in coldata.Keys)
3701 {
3702 thisHitColliders.Add(localid);
3703 if (!m_lastColliders.Contains(localid))
3704 {
3705 startedColliders.Add(localid);
3706 }
3707 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3708 }
3709
3710 // calculate things that ended colliding
3711 foreach (uint localID in m_lastColliders)
3712 {
3713 if (!thisHitColliders.Contains(localID))
3714 {
3715 endedColliders.Add(localID);
3716 }
3717 }
3718 //add the items that started colliding this time to the last colliders list.
3719 foreach (uint localID in startedColliders)
3720 {
3721 m_lastColliders.Add(localID);
3722 }
3723 // remove things that ended colliding from the last colliders list
3724 foreach (uint localID in endedColliders)
3725 {
3726 m_lastColliders.Remove(localID);
3727 }
3728
3729 // do event notification
3730 if (startedColliders.Count > 0)
3731 {
3732 ColliderArgs StartCollidingMessage = new ColliderArgs();
3733 List<DetectedObject> colliding = new List<DetectedObject>();
3734 foreach (uint localId in startedColliders)
3735 {
3736 if (localId == 0)
3737 continue;
3738
3739 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3740 string data = "";
3741 if (obj != null)
3742 {
3743 DetectedObject detobj = new DetectedObject();
3744 detobj.keyUUID = obj.UUID;
3745 detobj.nameStr = obj.Name;
3746 detobj.ownerUUID = obj.OwnerID;
3747 detobj.posVector = obj.AbsolutePosition;
3748 detobj.rotQuat = obj.GetWorldRotation();
3749 detobj.velVector = obj.Velocity;
3750 detobj.colliderType = 0;
3751 detobj.groupUUID = obj.GroupID;
3752 colliding.Add(detobj);
3753 }
3754 }
3755
3756 if (colliding.Count > 0)
3757 {
3758 StartCollidingMessage.Colliders = colliding;
3759
3760 foreach (SceneObjectGroup att in Attachments)
3761 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3762 }
3763 }
3764
3765 if (endedColliders.Count > 0)
3766 {
3767 ColliderArgs EndCollidingMessage = new ColliderArgs();
3768 List<DetectedObject> colliding = new List<DetectedObject>();
3769 foreach (uint localId in endedColliders)
3770 {
3771 if (localId == 0)
3772 continue;
3773
3774 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3775 string data = "";
3776 if (obj != null)
3777 {
3778 DetectedObject detobj = new DetectedObject();
3779 detobj.keyUUID = obj.UUID;
3780 detobj.nameStr = obj.Name;
3781 detobj.ownerUUID = obj.OwnerID;
3782 detobj.posVector = obj.AbsolutePosition;
3783 detobj.rotQuat = obj.GetWorldRotation();
3784 detobj.velVector = obj.Velocity;
3785 detobj.colliderType = 0;
3786 detobj.groupUUID = obj.GroupID;
3787 colliding.Add(detobj);
3788 }
3789 }
3790
3791 if (colliding.Count > 0)
3792 {
3793 EndCollidingMessage.Colliders = colliding;
3794
3795 foreach (SceneObjectGroup att in Attachments)
3796 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3797 }
3798 }
3799
3800 if (thisHitColliders.Count > 0)
3801 {
3802 ColliderArgs CollidingMessage = new ColliderArgs();
3803 List<DetectedObject> colliding = new List<DetectedObject>();
3804 foreach (uint localId in thisHitColliders)
3805 {
3806 if (localId == 0)
3807 continue;
3808
3809 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3810 string data = "";
3811 if (obj != null)
3812 {
3813 DetectedObject detobj = new DetectedObject();
3814 detobj.keyUUID = obj.UUID;
3815 detobj.nameStr = obj.Name;
3816 detobj.ownerUUID = obj.OwnerID;
3817 detobj.posVector = obj.AbsolutePosition;
3818 detobj.rotQuat = obj.GetWorldRotation();
3819 detobj.velVector = obj.Velocity;
3820 detobj.colliderType = 0;
3821 detobj.groupUUID = obj.GroupID;
3822 colliding.Add(detobj);
3823 }
3824 }
3825
3826 if (colliding.Count > 0)
3827 {
3828 CollidingMessage.Colliders = colliding;
3829
3830 lock (m_attachments)
3831 {
3832 foreach (SceneObjectGroup att in m_attachments)
3833 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3834 }
3835 }
3836 }
3837
3302 if (m_invulnerable) 3838 if (m_invulnerable)
3303 return; 3839 return;
3304 3840
@@ -3724,6 +4260,39 @@ namespace OpenSim.Region.Framework.Scenes
3724 return; 4260 return;
3725 } 4261 }
3726 4262
4263 XmlDocument doc = new XmlDocument();
4264 string stateData = String.Empty;
4265
4266 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4267 if (attServ != null)
4268 {
4269 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4270 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4271 if (stateData != String.Empty)
4272 {
4273 try
4274 {
4275 doc.LoadXml(stateData);
4276 }
4277 catch { }
4278 }
4279 }
4280
4281 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4282
4283 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4284 if (nodes.Count > 0)
4285 {
4286 foreach (XmlNode n in nodes)
4287 {
4288 XmlElement elem = (XmlElement)n;
4289 string itemID = elem.GetAttribute("ItemID");
4290 string xml = elem.InnerXml;
4291
4292 itemData[new UUID(itemID)] = xml;
4293 }
4294 }
4295
3727 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4296 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3728 foreach (AvatarAttachment attach in attachments) 4297 foreach (AvatarAttachment attach in attachments)
3729 { 4298 {
@@ -3744,7 +4313,30 @@ namespace OpenSim.Region.Framework.Scenes
3744 4313
3745 try 4314 try
3746 { 4315 {
3747 m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4316 string xmlData;
4317 XmlDocument d = new XmlDocument();
4318 UUID asset;
4319 if (itemData.TryGetValue(itemID, out xmlData))
4320 {
4321 d.LoadXml(xmlData);
4322 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4323
4324 // Rez from inventory
4325 asset
4326 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4327
4328 }
4329 else
4330 {
4331 // Rez from inventory (with a null doc to let
4332 // CHANGED_OWNER happen)
4333 asset
4334 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4335 }
4336
4337 m_log.InfoFormat(
4338 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4339 p, itemID, asset);
3748 } 4340 }
3749 catch (Exception e) 4341 catch (Exception e)
3750 { 4342 {
@@ -3777,6 +4369,15 @@ namespace OpenSim.Region.Framework.Scenes
3777 m_reprioritization_called = false; 4369 m_reprioritization_called = false;
3778 } 4370 }
3779 } 4371 }
4372
4373 private Vector3 Quat2Euler(Quaternion rot){
4374 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4375 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4376 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4377 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4378 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4379 return(new Vector3(x,y,z));
4380 }
3780 4381
3781 public void SaveChangedAttachments() 4382 public void SaveChangedAttachments()
3782 { 4383 {