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.cs975
1 files changed, 788 insertions, 187 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 30c9365..6ad6522 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,25 +1818,22 @@ 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.SitTargetAvatar = UUID.Zero; 1839 part.SitTargetAvatar = UUID.Zero;
@@ -1710,16 +1843,55 @@ namespace OpenSim.Region.Framework.Scenes
1710 m_parentPosition = part.GetWorldPosition(); 1843 m_parentPosition = part.GetWorldPosition();
1711 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1844 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1712 } 1845 }
1846 // part.GetWorldRotation() is the rotation of the object being sat on
1847 // Rotation is the sittiing Av's rotation
1848
1849 Quaternion partRot;
1850// if (part.LinkNum == 1)
1851// { // Root prim of linkset
1852// partRot = part.ParentGroup.RootPart.RotationOffset;
1853// }
1854// else
1855// { // single or child prim
1856
1857// }
1858 if (part == null) //CW: Part may be gone. llDie() for example.
1859 {
1860 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1861 }
1862 else
1863 {
1864 partRot = part.GetWorldRotation();
1865 }
1866
1867 Quaternion partIRot = Quaternion.Inverse(partRot);
1713 1868
1869 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1870 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1871
1872
1714 if (m_physicsActor == null) 1873 if (m_physicsActor == null)
1715 { 1874 {
1716 AddToPhysicalScene(false); 1875 AddToPhysicalScene(false);
1717 } 1876 }
1718 1877 //CW: If the part isn't null then we can set the current position
1719 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1878 if (part != null)
1720 m_parentPosition = Vector3.Zero; 1879 {
1721 1880 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1722 m_parentID = 0; 1881 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1882 part.IsOccupied = false;
1883 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1884 }
1885 else
1886 {
1887 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1888 AbsolutePosition = m_lastWorldPosition;
1889 }
1890
1891 m_parentPosition = Vector3.Zero;
1892 m_parentID = 0;
1893 m_linkedPrim = UUID.Zero;
1894 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1723 SendAvatarDataToAllAgents(); 1895 SendAvatarDataToAllAgents();
1724 m_requestedSitTargetID = 0; 1896 m_requestedSitTargetID = 0;
1725 if (m_physicsActor != null && m_appearance != null) 1897 if (m_physicsActor != null && m_appearance != null)
@@ -1728,7 +1900,6 @@ namespace OpenSim.Region.Framework.Scenes
1728 SetHeight(m_appearance.AvatarHeight); 1900 SetHeight(m_appearance.AvatarHeight);
1729 } 1901 }
1730 } 1902 }
1731
1732 Animator.TrySetMovementAnimation("STAND"); 1903 Animator.TrySetMovementAnimation("STAND");
1733 } 1904 }
1734 1905
@@ -1759,13 +1930,9 @@ namespace OpenSim.Region.Framework.Scenes
1759 Vector3 avSitOffSet = part.SitTargetPosition; 1930 Vector3 avSitOffSet = part.SitTargetPosition;
1760 Quaternion avSitOrientation = part.SitTargetOrientation; 1931 Quaternion avSitOrientation = part.SitTargetOrientation;
1761 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1932 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1762 1933 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1763 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1934 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1764 bool SitTargetisSet = 1935 if (SitTargetisSet && !SitTargetOccupied)
1765 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1766 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1767
1768 if (SitTargetisSet && SitTargetUnOccupied)
1769 { 1936 {
1770 //switch the target to this prim 1937 //switch the target to this prim
1771 return part; 1938 return part;
@@ -1779,86 +1946,164 @@ namespace OpenSim.Region.Framework.Scenes
1779 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1946 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1780 { 1947 {
1781 bool autopilot = true; 1948 bool autopilot = true;
1949 Vector3 autopilotTarget = new Vector3();
1950 Quaternion sitOrientation = Quaternion.Identity;
1782 Vector3 pos = new Vector3(); 1951 Vector3 pos = new Vector3();
1783 Quaternion sitOrientation = pSitOrientation;
1784 Vector3 cameraEyeOffset = Vector3.Zero; 1952 Vector3 cameraEyeOffset = Vector3.Zero;
1785 Vector3 cameraAtOffset = Vector3.Zero; 1953 Vector3 cameraAtOffset = Vector3.Zero;
1786 bool forceMouselook = false; 1954 bool forceMouselook = false;
1787 1955
1788 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1956 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1789 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1957 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1790 if (part != null) 1958 if (part == null) return;
1791 { 1959
1792 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1960 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1793 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1961 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1794 1962
1795 // Is a sit target available? 1963 // part is the prim to sit on
1796 Vector3 avSitOffSet = part.SitTargetPosition; 1964 // offset is the world-ref vector distance from that prim center to the click-spot
1797 Quaternion avSitOrientation = part.SitTargetOrientation; 1965 // UUID is the UUID of the Avatar doing the clicking
1798 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1966
1799 1967 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1800 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1968
1801 bool SitTargetisSet = 1969 // Is a sit target available?
1802 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1970 Vector3 avSitOffSet = part.SitTargetPosition;
1803 ( 1971 Quaternion avSitOrientation = part.SitTargetOrientation;
1804 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1972
1805 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1973 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1806 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1974 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1807 ) 1975 Quaternion partRot;
1808 )); 1976// if (part.LinkNum == 1)
1809 1977// { // Root prim of linkset
1810 if (SitTargetisSet && SitTargetUnOccupied) 1978// partRot = part.ParentGroup.RootPart.RotationOffset;
1811 { 1979// }
1812 part.SitTargetAvatar = UUID; 1980// else
1813 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1981// { // single or child prim
1814 sitOrientation = avSitOrientation; 1982 partRot = part.GetWorldRotation();
1815 autopilot = false; 1983// }
1816 } 1984 Quaternion partIRot = Quaternion.Inverse(partRot);
1817 if (part.ParentGroup != null) 1985//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1818 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 1986 // Sit analysis rewritten by KF 091125
1819 1987 if (SitTargetisSet) // scipted sit
1820 pos = part.AbsolutePosition + offset; 1988 {
1821 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1989 if (!part.IsOccupied)
1822 //{ 1990 {
1823 // offset = pos; 1991//Console.WriteLine("Scripted, unoccupied");
1824 //autopilot = false; 1992 part.SitTargetAvatar = UUID; // set that Av will be on it
1825 //} 1993 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1826 if (m_physicsActor != null) 1994
1827 { 1995 Quaternion nrot = avSitOrientation;
1828 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1996 if (!part.IsRoot)
1829 // We can remove the physicsActor until they stand up.
1830 m_sitAvatarHeight = m_physicsActor.Size.Z;
1831
1832 if (autopilot)
1833 { 1997 {
1834 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1998 nrot = part.RotationOffset * avSitOrientation;
1835 {
1836 autopilot = false;
1837
1838 RemoveFromPhysicalScene();
1839 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1840 }
1841 } 1999 }
1842 else 2000 sitOrientation = nrot; // Change rotatione to the scripted one
2001 OffsetRotation = nrot;
2002 autopilot = false; // Jump direct to scripted llSitPos()
2003 }
2004 else
2005 {
2006//Console.WriteLine("Scripted, occupied");
2007 return;
2008 }
2009 }
2010 else // Not Scripted
2011 {
2012 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
2013 {
2014 // large prim & offset, ignore if other Avs sitting
2015// offset.Z -= 0.05f;
2016 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2017 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2018
2019//Console.WriteLine(" offset ={0}", offset);
2020//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2021//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2022
2023 }
2024 else // small offset
2025 {
2026//Console.WriteLine("Small offset");
2027 if (!part.IsOccupied)
2028 {
2029 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2030 autopilotTarget = part.AbsolutePosition;
2031//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2032 }
2033 else return; // occupied small
2034 } // end large/small
2035 } // end Scripted/not
2036 cameraAtOffset = part.GetCameraAtOffset();
2037 cameraEyeOffset = part.GetCameraEyeOffset();
2038 forceMouselook = part.GetForceMouselook();
2039 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2040 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2041
2042 if (m_physicsActor != null)
2043 {
2044 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2045 // We can remove the physicsActor until they stand up.
2046 m_sitAvatarHeight = m_physicsActor.Size.Z;
2047 if (autopilot)
2048 { // its not a scripted sit
2049// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2050 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1843 { 2051 {
2052 autopilot = false; // close enough
2053 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2054 Not using the part's position because returning the AV to the last known standing
2055 position is likely to be more friendly, isn't it? */
1844 RemoveFromPhysicalScene(); 2056 RemoveFromPhysicalScene();
1845 } 2057 Velocity = Vector3.Zero;
2058 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2059 } // else the autopilot will get us close
2060 }
2061 else
2062 { // its a scripted sit
2063 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2064 I *am* using the part's position this time because we have no real idea how far away
2065 the avatar is from the sit target. */
2066 RemoveFromPhysicalScene();
2067 Velocity = Vector3.Zero;
1846 } 2068 }
1847
1848 cameraAtOffset = part.GetCameraAtOffset();
1849 cameraEyeOffset = part.GetCameraEyeOffset();
1850 forceMouselook = part.GetForceMouselook();
1851 } 2069 }
1852 2070 else return; // physactor is null!
1853 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2071
1854 m_requestedSitTargetUUID = targetID; 2072 Vector3 offsetr; // = offset * partIRot;
2073 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2074 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2075 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2076 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2077 //offsetr = offset * partIRot;
2078//
2079 // else
2080 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2081 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2082 // (offset * partRot);
2083 // }
2084
2085//Console.WriteLine(" ");
2086//Console.WriteLine("link number ={0}", part.LinkNum);
2087//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2088//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2089//Console.WriteLine("Click offst ={0}", offset);
2090//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2091//Console.WriteLine("offsetr ={0}", offsetr);
2092//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2093//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2094
2095 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2096 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2097
2098 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1855 // This calls HandleAgentSit twice, once from here, and the client calls 2099 // This calls HandleAgentSit twice, once from here, and the client calls
1856 // HandleAgentSit itself after it gets to the location 2100 // HandleAgentSit itself after it gets to the location
1857 // It doesn't get to the location until we've moved them there though 2101 // It doesn't get to the location until we've moved them there though
1858 // which happens in HandleAgentSit :P 2102 // which happens in HandleAgentSit :P
1859 m_autopilotMoving = autopilot; 2103 m_autopilotMoving = autopilot;
1860 m_autoPilotTarget = pos; 2104 m_autoPilotTarget = autopilotTarget;
1861 m_sitAtAutoTarget = autopilot; 2105 m_sitAtAutoTarget = autopilot;
2106 m_initialSitTarget = autopilotTarget;
1862 if (!autopilot) 2107 if (!autopilot)
1863 HandleAgentSit(remoteClient, UUID); 2108 HandleAgentSit(remoteClient, UUID);
1864 } 2109 }
@@ -2153,47 +2398,130 @@ namespace OpenSim.Region.Framework.Scenes
2153 { 2398 {
2154 if (part != null) 2399 if (part != null)
2155 { 2400 {
2401//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2156 if (part.GetAvatarOnSitTarget() == UUID) 2402 if (part.GetAvatarOnSitTarget() == UUID)
2157 { 2403 {
2404//Console.WriteLine("Scripted Sit");
2405 // Scripted sit
2158 Vector3 sitTargetPos = part.SitTargetPosition; 2406 Vector3 sitTargetPos = part.SitTargetPosition;
2159 Quaternion sitTargetOrient = part.SitTargetOrientation; 2407 Quaternion sitTargetOrient = part.SitTargetOrientation;
2160
2161 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2162 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2163
2164 //Quaternion result = (sitTargetOrient * vq) * nq;
2165
2166 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2408 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2167 m_pos += SIT_TARGET_ADJUSTMENT; 2409 m_pos += SIT_TARGET_ADJUSTMENT;
2410 if (!part.IsRoot)
2411 {
2412 m_pos *= part.RotationOffset;
2413 }
2168 m_bodyRot = sitTargetOrient; 2414 m_bodyRot = sitTargetOrient;
2169 //Rotation = sitTargetOrient;
2170 m_parentPosition = part.AbsolutePosition; 2415 m_parentPosition = part.AbsolutePosition;
2171 2416 part.IsOccupied = true;
2172 //SendTerseUpdateToAllClients(); 2417 part.ParentGroup.AddAvatar(agentID);
2173 } 2418 }
2174 else 2419 else
2175 { 2420 {
2176 m_pos -= part.AbsolutePosition; 2421 // if m_avUnscriptedSitPos is zero then Av sits above center
2422 // Else Av sits at m_avUnscriptedSitPos
2423
2424 // Non-scripted sit by Kitto Flora 21Nov09
2425 // Calculate angle of line from prim to Av
2426 Quaternion partIRot;
2427// if (part.LinkNum == 1)
2428// { // Root prim of linkset
2429// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2430// }
2431// else
2432// { // single or child prim
2433 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2434// }
2435 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2436 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2437 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2438 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2439 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2440 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2441 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2442 // Av sits at world euler <0,0, z>, translated by part rotation
2443 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2444
2177 m_parentPosition = part.AbsolutePosition; 2445 m_parentPosition = part.AbsolutePosition;
2178 } 2446 part.IsOccupied = true;
2447 part.ParentGroup.AddAvatar(agentID);
2448 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2449 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2450 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2451 m_avUnscriptedSitPos; // adds click offset, if any
2452 //Set up raytrace to find top surface of prim
2453 Vector3 size = part.Scale;
2454 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2455 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2456 Vector3 down = new Vector3(0f, 0f, -1f);
2457//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2458 m_scene.PhysicsScene.RaycastWorld(
2459 start, // Vector3 position,
2460 down, // Vector3 direction,
2461 mag, // float length,
2462 SitAltitudeCallback); // retMethod
2463 } // end scripted/not
2179 } 2464 }
2180 else 2465 else // no Av
2181 { 2466 {
2182 return; 2467 return;
2183 } 2468 }
2184 } 2469 }
2185 m_parentID = m_requestedSitTargetID;
2186 2470
2471 //We want our offsets to reference the root prim, not the child we may have sat on
2472 if (!part.IsRoot)
2473 {
2474 m_parentID = part.ParentGroup.RootPart.LocalId;
2475 m_pos += part.OffsetPosition;
2476 }
2477 else
2478 {
2479 m_parentID = m_requestedSitTargetID;
2480 }
2481
2482 m_linkedPrim = part.UUID;
2483 if (part.GetAvatarOnSitTarget() != UUID)
2484 {
2485 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2486 }
2187 Velocity = Vector3.Zero; 2487 Velocity = Vector3.Zero;
2188 RemoveFromPhysicalScene(); 2488 RemoveFromPhysicalScene();
2189
2190 Animator.TrySetMovementAnimation(sitAnimation); 2489 Animator.TrySetMovementAnimation(sitAnimation);
2191 SendAvatarDataToAllAgents(); 2490 SendAvatarDataToAllAgents();
2192 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2193 // So we're also sending a terse update (which has avatar rotation)
2194 // [Update] We do now.
2195 //SendTerseUpdateToAllClients(); 2491 //SendTerseUpdateToAllClients();
2196 } 2492 }
2493
2494 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2495 {
2496 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2497 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2498 if(hitYN)
2499 {
2500 // m_pos = Av offset from prim center to make look like on center
2501 // m_parentPosition = Actual center pos of prim
2502 // collisionPoint = spot on prim where we want to sit
2503 // collisionPoint.Z = global sit surface height
2504 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2505 Quaternion partIRot;
2506// if (part.LinkNum == 1)
2507/// { // Root prim of linkset
2508// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2509// }
2510// else
2511// { // single or child prim
2512 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2513// }
2514 if (m_initialSitTarget != null)
2515 {
2516 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2517 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2518 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2519 m_pos += offset;
2520 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2521 }
2522
2523 }
2524 } // End SitAltitudeCallback KF.
2197 2525
2198 /// <summary> 2526 /// <summary>
2199 /// Event handler for the 'Always run' setting on the client 2527 /// Event handler for the 'Always run' setting on the client
@@ -2223,12 +2551,13 @@ namespace OpenSim.Region.Framework.Scenes
2223 /// </summary> 2551 /// </summary>
2224 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2552 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2225 /// <param name="rotation">The direction in which this avatar should now face. 2553 /// <param name="rotation">The direction in which this avatar should now face.
2226 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2554 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2227 { 2555 {
2228 if (m_isChildAgent) 2556 if (m_isChildAgent)
2229 { 2557 {
2230 // WHAT??? 2558 // WHAT???
2231 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); 2559 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent");
2560
2232 return; 2561 return;
2233 } 2562 }
2234 2563
@@ -2237,15 +2566,26 @@ namespace OpenSim.Region.Framework.Scenes
2237 Rotation = rotation; 2566 Rotation = rotation;
2238 Vector3 direc = vec * rotation; 2567 Vector3 direc = vec * rotation;
2239 direc.Normalize(); 2568 direc.Normalize();
2569 PhysicsActor actor = m_physicsActor;
2570
2571 if (actor.Flying != m_flyingOld) // add for fly velocity control
2572 {
2573 m_flyingOld = actor.Flying; // add for fly velocity control
2574 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2575 }
2576
2577 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2578
2579 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2240 2580
2241 direc *= 0.03f * 128f * m_speedModifier; 2581 direc *= 0.03f * 128f * m_speedModifier;
2242 2582
2243 PhysicsActor actor = m_physicsActor;
2244 if (actor != null) 2583 if (actor != null)
2245 { 2584 {
2246 if (actor.Flying) 2585 if (actor.Flying)
2247 { 2586 {
2248 direc *= 4.0f; 2587// rm speed mod direc *= 4.0f;
2588 direc *= 5.2f; // for speed mod
2249 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2589 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2250 //bool colliding = (m_physicsActor.IsColliding==true); 2590 //bool colliding = (m_physicsActor.IsColliding==true);
2251 //if (controlland) 2591 //if (controlland)
@@ -2258,22 +2598,34 @@ namespace OpenSim.Region.Framework.Scenes
2258 // m_log.Info("[AGENT]: Stop FLying"); 2598 // m_log.Info("[AGENT]: Stop FLying");
2259 //} 2599 //}
2260 } 2600 }
2601 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2602 {
2603 direc *= 0.0f;
2604 }
2605 /* This jumping section removed to SPA
2261 else if (!actor.Flying && actor.IsColliding) 2606 else if (!actor.Flying && actor.IsColliding)
2262 { 2607 {
2263 if (direc.Z > 2.0f) 2608 if (direc.Z > 2.0f)
2264 { 2609 {
2265 direc.Z *= 3.0f; 2610 if(m_animator.m_animTickJump == -1)
2266 2611 {
2267 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2612 direc.Z *= 3.0f; // jump
2268 Animator.TrySetMovementAnimation("PREJUMP"); 2613 }
2269 Animator.TrySetMovementAnimation("JUMP"); 2614 else
2615 {
2616 direc.Z *= 0.1f; // prejump
2617 }
2618 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2619 Animator.TrySetMovementAnimation("PREJUMP");
2620 Animator.TrySetMovementAnimation("JUMP");
2621 * /
2270 } 2622 }
2271 } 2623 } */
2272 } 2624 }
2273 2625
2274 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2626 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2275 m_forceToApply = direc; 2627 m_forceToApply = direc;
2276 2628 m_isNudging = Nudging;
2277 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2629 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2278 } 2630 }
2279 2631
@@ -2288,7 +2640,7 @@ namespace OpenSim.Region.Framework.Scenes
2288 const float POSITION_TOLERANCE = 0.05f; 2640 const float POSITION_TOLERANCE = 0.05f;
2289 //const int TIME_MS_TOLERANCE = 3000; 2641 //const int TIME_MS_TOLERANCE = 3000;
2290 2642
2291 SendPrimUpdates(); 2643
2292 2644
2293 if (m_isChildAgent == false) 2645 if (m_isChildAgent == false)
2294 { 2646 {
@@ -2318,6 +2670,9 @@ namespace OpenSim.Region.Framework.Scenes
2318 CheckForBorderCrossing(); 2670 CheckForBorderCrossing();
2319 CheckForSignificantMovement(); // sends update to the modules. 2671 CheckForSignificantMovement(); // sends update to the modules.
2320 } 2672 }
2673
2674 //Sending prim updates AFTER the avatar terse updates are sent
2675 SendPrimUpdates();
2321 } 2676 }
2322 2677
2323 #endregion 2678 #endregion
@@ -3080,6 +3435,7 @@ namespace OpenSim.Region.Framework.Scenes
3080 m_callbackURI = cAgent.CallbackURI; 3435 m_callbackURI = cAgent.CallbackURI;
3081 3436
3082 m_pos = cAgent.Position; 3437 m_pos = cAgent.Position;
3438
3083 m_velocity = cAgent.Velocity; 3439 m_velocity = cAgent.Velocity;
3084 m_CameraCenter = cAgent.Center; 3440 m_CameraCenter = cAgent.Center;
3085 m_CameraAtAxis = cAgent.AtAxis; 3441 m_CameraAtAxis = cAgent.AtAxis;
@@ -3198,17 +3554,46 @@ namespace OpenSim.Region.Framework.Scenes
3198 /// </summary> 3554 /// </summary>
3199 public override void UpdateMovement() 3555 public override void UpdateMovement()
3200 { 3556 {
3201 if (m_forceToApply.HasValue) 3557 if (Animator!=null) // add for jumping
3202 { 3558 { // add for jumping
3203 Vector3 force = m_forceToApply.Value; 3559 // if (!m_animator.m_jumping) // add for jumping
3560 // { // add for jumping
3204 3561
3205 m_updateflag = true; 3562 if (m_forceToApply.HasValue) // this section realigned
3206// movementvector = force; 3563 {
3207 Velocity = force;
3208 3564
3209 m_forceToApply = null; 3565 Vector3 force = m_forceToApply.Value;
3210 } 3566 m_updateflag = true;
3211 } 3567if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3568 Velocity = force;
3569//Console.WriteLine("UM1 {0}", Velocity);
3570 m_forceToApply = null;
3571 }
3572 else
3573 {
3574 if (m_isNudging)
3575 {
3576 Vector3 force = Vector3.Zero;
3577
3578 m_updateflag = true;
3579if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3580 Velocity = force;
3581//Console.WriteLine("UM2 {0}", Velocity);
3582 m_isNudging = false;
3583 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3584 }
3585 else // add for jumping
3586 { // add for jumping
3587 Vector3 force = Vector3.Zero; // add for jumping
3588if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3589//Console.WriteLine("UM3 {0}", Velocity);
3590 Velocity = force; // add for jumping
3591 }
3592
3593 }
3594 // } // end realign
3595 } // add for jumping
3596 } // add for jumping
3212 3597
3213 /// <summary> 3598 /// <summary>
3214 /// Adds a physical representation of the avatar to the Physics plugin 3599 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3222,10 +3607,8 @@ namespace OpenSim.Region.Framework.Scenes
3222 3607
3223 Vector3 pVec = AbsolutePosition; 3608 Vector3 pVec = AbsolutePosition;
3224 3609
3225 // Old bug where the height was in centimeters instead of meters
3226 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3610 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3227 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3611 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3228
3229 scene.AddPhysicsActorTaint(m_physicsActor); 3612 scene.AddPhysicsActorTaint(m_physicsActor);
3230 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3613 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3231 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3614 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3249,18 +3632,29 @@ namespace OpenSim.Region.Framework.Scenes
3249 { 3632 {
3250 if (e == null) 3633 if (e == null)
3251 return; 3634 return;
3252 3635
3253 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3636 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3254 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3255 // as of this comment the interval is set in AddToPhysicalScene 3637 // as of this comment the interval is set in AddToPhysicalScene
3256 if (Animator!=null) 3638 if (Animator!=null)
3257 Animator.UpdateMovementAnimations(); 3639 {
3640 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3641 { // else its will lock out other animation changes, like ground sit.
3642 Animator.UpdateMovementAnimations();
3643 m_updateCount--;
3644 }
3645 }
3258 3646
3259 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3647 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3260 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3648 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3261 3649
3262 CollisionPlane = Vector4.UnitW; 3650 CollisionPlane = Vector4.UnitW;
3263 3651
3652 if (m_lastColCount != coldata.Count)
3653 {
3654 m_updateCount = UPDATE_COUNT;
3655 m_lastColCount = coldata.Count;
3656 }
3657
3264 if (coldata.Count != 0 && Animator != null) 3658 if (coldata.Count != 0 && Animator != null)
3265 { 3659 {
3266 switch (Animator.CurrentMovementAnimation) 3660 switch (Animator.CurrentMovementAnimation)
@@ -3290,6 +3684,148 @@ namespace OpenSim.Region.Framework.Scenes
3290 } 3684 }
3291 } 3685 }
3292 3686
3687 List<uint> thisHitColliders = new List<uint>();
3688 List<uint> endedColliders = new List<uint>();
3689 List<uint> startedColliders = new List<uint>();
3690
3691 foreach (uint localid in coldata.Keys)
3692 {
3693 thisHitColliders.Add(localid);
3694 if (!m_lastColliders.Contains(localid))
3695 {
3696 startedColliders.Add(localid);
3697 }
3698 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3699 }
3700
3701 // calculate things that ended colliding
3702 foreach (uint localID in m_lastColliders)
3703 {
3704 if (!thisHitColliders.Contains(localID))
3705 {
3706 endedColliders.Add(localID);
3707 }
3708 }
3709 //add the items that started colliding this time to the last colliders list.
3710 foreach (uint localID in startedColliders)
3711 {
3712 m_lastColliders.Add(localID);
3713 }
3714 // remove things that ended colliding from the last colliders list
3715 foreach (uint localID in endedColliders)
3716 {
3717 m_lastColliders.Remove(localID);
3718 }
3719
3720 // do event notification
3721 if (startedColliders.Count > 0)
3722 {
3723 ColliderArgs StartCollidingMessage = new ColliderArgs();
3724 List<DetectedObject> colliding = new List<DetectedObject>();
3725 foreach (uint localId in startedColliders)
3726 {
3727 if (localId == 0)
3728 continue;
3729
3730 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3731 string data = "";
3732 if (obj != null)
3733 {
3734 DetectedObject detobj = new DetectedObject();
3735 detobj.keyUUID = obj.UUID;
3736 detobj.nameStr = obj.Name;
3737 detobj.ownerUUID = obj.OwnerID;
3738 detobj.posVector = obj.AbsolutePosition;
3739 detobj.rotQuat = obj.GetWorldRotation();
3740 detobj.velVector = obj.Velocity;
3741 detobj.colliderType = 0;
3742 detobj.groupUUID = obj.GroupID;
3743 colliding.Add(detobj);
3744 }
3745 }
3746
3747 if (colliding.Count > 0)
3748 {
3749 StartCollidingMessage.Colliders = colliding;
3750
3751 foreach (SceneObjectGroup att in Attachments)
3752 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3753 }
3754 }
3755
3756 if (endedColliders.Count > 0)
3757 {
3758 ColliderArgs EndCollidingMessage = new ColliderArgs();
3759 List<DetectedObject> colliding = new List<DetectedObject>();
3760 foreach (uint localId in endedColliders)
3761 {
3762 if (localId == 0)
3763 continue;
3764
3765 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3766 string data = "";
3767 if (obj != null)
3768 {
3769 DetectedObject detobj = new DetectedObject();
3770 detobj.keyUUID = obj.UUID;
3771 detobj.nameStr = obj.Name;
3772 detobj.ownerUUID = obj.OwnerID;
3773 detobj.posVector = obj.AbsolutePosition;
3774 detobj.rotQuat = obj.GetWorldRotation();
3775 detobj.velVector = obj.Velocity;
3776 detobj.colliderType = 0;
3777 detobj.groupUUID = obj.GroupID;
3778 colliding.Add(detobj);
3779 }
3780 }
3781
3782 if (colliding.Count > 0)
3783 {
3784 EndCollidingMessage.Colliders = colliding;
3785
3786 foreach (SceneObjectGroup att in Attachments)
3787 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3788 }
3789 }
3790
3791 if (thisHitColliders.Count > 0)
3792 {
3793 ColliderArgs CollidingMessage = new ColliderArgs();
3794 List<DetectedObject> colliding = new List<DetectedObject>();
3795 foreach (uint localId in thisHitColliders)
3796 {
3797 if (localId == 0)
3798 continue;
3799
3800 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3801 string data = "";
3802 if (obj != null)
3803 {
3804 DetectedObject detobj = new DetectedObject();
3805 detobj.keyUUID = obj.UUID;
3806 detobj.nameStr = obj.Name;
3807 detobj.ownerUUID = obj.OwnerID;
3808 detobj.posVector = obj.AbsolutePosition;
3809 detobj.rotQuat = obj.GetWorldRotation();
3810 detobj.velVector = obj.Velocity;
3811 detobj.colliderType = 0;
3812 detobj.groupUUID = obj.GroupID;
3813 colliding.Add(detobj);
3814 }
3815 }
3816
3817 if (colliding.Count > 0)
3818 {
3819 CollidingMessage.Colliders = colliding;
3820
3821 lock (m_attachments)
3822 {
3823 foreach (SceneObjectGroup att in m_attachments)
3824 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3825 }
3826 }
3827 }
3828
3293 if (m_invulnerable) 3829 if (m_invulnerable)
3294 return; 3830 return;
3295 3831
@@ -3715,6 +4251,39 @@ namespace OpenSim.Region.Framework.Scenes
3715 return; 4251 return;
3716 } 4252 }
3717 4253
4254 XmlDocument doc = new XmlDocument();
4255 string stateData = String.Empty;
4256
4257 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4258 if (attServ != null)
4259 {
4260 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4261 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4262 if (stateData != String.Empty)
4263 {
4264 try
4265 {
4266 doc.LoadXml(stateData);
4267 }
4268 catch { }
4269 }
4270 }
4271
4272 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4273
4274 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4275 if (nodes.Count > 0)
4276 {
4277 foreach (XmlNode n in nodes)
4278 {
4279 XmlElement elem = (XmlElement)n;
4280 string itemID = elem.GetAttribute("ItemID");
4281 string xml = elem.InnerXml;
4282
4283 itemData[new UUID(itemID)] = xml;
4284 }
4285 }
4286
3718 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4287 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3719 foreach (AvatarAttachment attach in attachments) 4288 foreach (AvatarAttachment attach in attachments)
3720 { 4289 {
@@ -3735,7 +4304,30 @@ namespace OpenSim.Region.Framework.Scenes
3735 4304
3736 try 4305 try
3737 { 4306 {
3738 m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4307 string xmlData;
4308 XmlDocument d = new XmlDocument();
4309 UUID asset;
4310 if (itemData.TryGetValue(itemID, out xmlData))
4311 {
4312 d.LoadXml(xmlData);
4313 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4314
4315 // Rez from inventory
4316 asset
4317 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4318
4319 }
4320 else
4321 {
4322 // Rez from inventory (with a null doc to let
4323 // CHANGED_OWNER happen)
4324 asset
4325 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4326 }
4327
4328 m_log.InfoFormat(
4329 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4330 p, itemID, asset);
3739 } 4331 }
3740 catch (Exception e) 4332 catch (Exception e)
3741 { 4333 {
@@ -3768,6 +4360,15 @@ namespace OpenSim.Region.Framework.Scenes
3768 m_reprioritization_called = false; 4360 m_reprioritization_called = false;
3769 } 4361 }
3770 } 4362 }
4363
4364 private Vector3 Quat2Euler(Quaternion rot){
4365 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4366 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4367 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4368 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4369 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4370 return(new Vector3(x,y,z));
4371 }
3771 4372
3772 public void SaveChangedAttachments() 4373 public void SaveChangedAttachments()
3773 { 4374 {