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.cs979
1 files changed, 790 insertions, 189 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fa2c7b5..6a3983f 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(
@@ -980,12 +1106,17 @@ namespace OpenSim.Region.Framework.Scenes
980 { 1106 {
981 if (PhysicsActor != null) 1107 if (PhysicsActor != null)
982 { 1108 {
983 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1109 try
984 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1110 {
985 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1111 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
986 m_physicsActor.UnSubscribeEvents(); 1112 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
987 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1113 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
988 PhysicsActor = null; 1114 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1115 m_physicsActor.UnSubscribeEvents();
1116 PhysicsActor = null;
1117 }
1118 catch
1119 { }
989 } 1120 }
990 } 1121 }
991 1122
@@ -996,9 +1127,10 @@ namespace OpenSim.Region.Framework.Scenes
996 public void Teleport(Vector3 pos) 1127 public void Teleport(Vector3 pos)
997 { 1128 {
998 bool isFlying = false; 1129 bool isFlying = false;
1130
999 if (m_physicsActor != null) 1131 if (m_physicsActor != null)
1000 isFlying = m_physicsActor.Flying; 1132 isFlying = m_physicsActor.Flying;
1001 1133
1002 RemoveFromPhysicalScene(); 1134 RemoveFromPhysicalScene();
1003 Velocity = Vector3.Zero; 1135 Velocity = Vector3.Zero;
1004 AbsolutePosition = pos; 1136 AbsolutePosition = pos;
@@ -1010,6 +1142,7 @@ namespace OpenSim.Region.Framework.Scenes
1010 } 1142 }
1011 1143
1012 SendTerseUpdateToAllClients(); 1144 SendTerseUpdateToAllClients();
1145
1013 } 1146 }
1014 1147
1015 public void TeleportWithMomentum(Vector3 pos) 1148 public void TeleportWithMomentum(Vector3 pos)
@@ -1228,6 +1361,7 @@ namespace OpenSim.Region.Framework.Scenes
1228 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1361 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1229 1362
1230 m_pos = m_LastFinitePos; 1363 m_pos = m_LastFinitePos;
1364
1231 if (!m_pos.IsFinite()) 1365 if (!m_pos.IsFinite())
1232 { 1366 {
1233 m_pos.X = 127f; 1367 m_pos.X = 127f;
@@ -1294,7 +1428,6 @@ namespace OpenSim.Region.Framework.Scenes
1294 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1428 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1295 } 1429 }
1296 } 1430 }
1297
1298 lock (scriptedcontrols) 1431 lock (scriptedcontrols)
1299 { 1432 {
1300 if (scriptedcontrols.Count > 0) 1433 if (scriptedcontrols.Count > 0)
@@ -1309,6 +1442,9 @@ namespace OpenSim.Region.Framework.Scenes
1309 1442
1310 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1443 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1311 { 1444 {
1445 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1446 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1447
1312 // TODO: This doesn't prevent the user from walking yet. 1448 // TODO: This doesn't prevent the user from walking yet.
1313 // Setting parent ID would fix this, if we knew what value 1449 // Setting parent ID would fix this, if we knew what value
1314 // to use. Or we could add a m_isSitting variable. 1450 // to use. Or we could add a m_isSitting variable.
@@ -1357,12 +1493,20 @@ namespace OpenSim.Region.Framework.Scenes
1357 if (actor.Flying != oldflying) 1493 if (actor.Flying != oldflying)
1358 update_movementflag = true; 1494 update_movementflag = true;
1359 1495
1496 if (m_animator.m_jumping) // add for jumping
1497 update_movementflag = true;
1498
1360 if (q != m_bodyRot) 1499 if (q != m_bodyRot)
1361 { 1500 {
1362 m_bodyRot = q; 1501 m_bodyRot = q;
1363 update_rotation = true; 1502 update_rotation = true;
1364 } 1503 }
1365 1504
1505 //guilty until proven innocent..
1506 bool Nudging = true;
1507 //Basically, if there is at least one non-nudge control then we don't need
1508 //to worry about stopping the avatar
1509
1366 if (m_parentID == 0) 1510 if (m_parentID == 0)
1367 { 1511 {
1368 bool bAllowUpdateMoveToPosition = false; 1512 bool bAllowUpdateMoveToPosition = false;
@@ -1377,9 +1521,12 @@ namespace OpenSim.Region.Framework.Scenes
1377 else 1521 else
1378 dirVectors = Dir_Vectors; 1522 dirVectors = Dir_Vectors;
1379 1523
1380 // The fact that m_movementflag is a byte needs to be fixed 1524 bool[] isNudge = GetDirectionIsNudge();
1381 // it really should be a uint 1525
1382 uint nudgehack = 250; 1526
1527
1528
1529
1383 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1530 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1384 { 1531 {
1385 if (((uint)flags & (uint)DCF) != 0) 1532 if (((uint)flags & (uint)DCF) != 0)
@@ -1389,40 +1536,28 @@ namespace OpenSim.Region.Framework.Scenes
1389 try 1536 try
1390 { 1537 {
1391 agent_control_v3 += dirVectors[i]; 1538 agent_control_v3 += dirVectors[i];
1392 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1539 if (isNudge[i] == false)
1540 {
1541 Nudging = false;
1542 }
1393 } 1543 }
1394 catch (IndexOutOfRangeException) 1544 catch (IndexOutOfRangeException)
1395 { 1545 {
1396 // Why did I get this? 1546 // Why did I get this?
1397 } 1547 }
1398 1548
1399 if ((m_movementflag & (byte)(uint)DCF) == 0) 1549 if ((m_movementflag & (uint)DCF) == 0)
1400 { 1550 {
1401 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1402 {
1403 m_movementflag |= (byte)nudgehack;
1404 }
1405 m_movementflag += (byte)(uint)DCF; 1551 m_movementflag += (byte)(uint)DCF;
1406 update_movementflag = true; 1552 update_movementflag = true;
1407 } 1553 }
1408 } 1554 }
1409 else 1555 else
1410 { 1556 {
1411 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1557 if ((m_movementflag & (uint)DCF) != 0)
1412 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1413 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1414 ) // This or is for Nudge forward
1415 { 1558 {
1416 m_movementflag -= ((byte)(uint)DCF); 1559 m_movementflag -= (byte)(uint)DCF;
1417
1418 update_movementflag = true; 1560 update_movementflag = true;
1419 /*
1420 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1421 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1422 {
1423 m_log.Debug("Removed Hack flag");
1424 }
1425 */
1426 } 1561 }
1427 else 1562 else
1428 { 1563 {
@@ -1431,7 +1566,6 @@ namespace OpenSim.Region.Framework.Scenes
1431 } 1566 }
1432 i++; 1567 i++;
1433 } 1568 }
1434
1435 //Paupaw:Do Proper PID for Autopilot here 1569 //Paupaw:Do Proper PID for Autopilot here
1436 if (bResetMoveToPosition) 1570 if (bResetMoveToPosition)
1437 { 1571 {
@@ -1466,6 +1600,9 @@ namespace OpenSim.Region.Framework.Scenes
1466 // Ignore z component of vector 1600 // Ignore z component of vector
1467 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1601 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1468 LocalVectorToTarget2D.Normalize(); 1602 LocalVectorToTarget2D.Normalize();
1603
1604 //We're not nudging
1605 Nudging = false;
1469 agent_control_v3 += LocalVectorToTarget2D; 1606 agent_control_v3 += LocalVectorToTarget2D;
1470 1607
1471 // update avatar movement flags. the avatar coordinate system is as follows: 1608 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1556,13 +1693,13 @@ namespace OpenSim.Region.Framework.Scenes
1556 // m_log.DebugFormat( 1693 // m_log.DebugFormat(
1557 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1694 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1558 1695
1559 AddNewMovement(agent_control_v3, q); 1696 AddNewMovement(agent_control_v3, q, Nudging);
1560 1697
1561 1698
1562 } 1699 }
1563 } 1700 }
1564 1701
1565 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1702 if (update_movementflag && !SitGround)
1566 Animator.UpdateMovementAnimations(); 1703 Animator.UpdateMovementAnimations();
1567 1704
1568 m_scene.EventManager.TriggerOnClientMovement(this); 1705 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1577,7 +1714,6 @@ namespace OpenSim.Region.Framework.Scenes
1577 m_sitAtAutoTarget = false; 1714 m_sitAtAutoTarget = false;
1578 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1715 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1579 //proxy.PCode = (byte)PCode.ParticleSystem; 1716 //proxy.PCode = (byte)PCode.ParticleSystem;
1580
1581 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1717 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1582 proxyObjectGroup.AttachToScene(m_scene); 1718 proxyObjectGroup.AttachToScene(m_scene);
1583 1719
@@ -1618,8 +1754,8 @@ namespace OpenSim.Region.Framework.Scenes
1618 return; 1754 return;
1619 } 1755 }
1620 m_moveToPositionInProgress = true; 1756 m_moveToPositionInProgress = true;
1621 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1757 m_moveToPositionTarget = new Vector3(locx, locy, locz + (m_appearance.AvatarHeight / 2.0f));
1622 } 1758 }
1623 catch (Exception ex) 1759 catch (Exception ex)
1624 { 1760 {
1625 //Why did I get this error? 1761 //Why did I get this error?
@@ -1641,7 +1777,7 @@ namespace OpenSim.Region.Framework.Scenes
1641 Velocity = Vector3.Zero; 1777 Velocity = Vector3.Zero;
1642 SendAvatarDataToAllAgents(); 1778 SendAvatarDataToAllAgents();
1643 1779
1644 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1780 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1645 } 1781 }
1646 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1782 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1647 m_requestedSitTargetUUID = UUID.Zero; 1783 m_requestedSitTargetUUID = UUID.Zero;
@@ -1678,25 +1814,22 @@ namespace OpenSim.Region.Framework.Scenes
1678 1814
1679 if (m_parentID != 0) 1815 if (m_parentID != 0)
1680 { 1816 {
1681 m_log.Debug("StandupCode Executed"); 1817 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1682 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1683 if (part != null) 1818 if (part != null)
1684 { 1819 {
1820 part.TaskInventory.LockItemsForRead(true);
1685 TaskInventoryDictionary taskIDict = part.TaskInventory; 1821 TaskInventoryDictionary taskIDict = part.TaskInventory;
1686 if (taskIDict != null) 1822 if (taskIDict != null)
1687 { 1823 {
1688 lock (taskIDict) 1824 foreach (UUID taskID in taskIDict.Keys)
1689 { 1825 {
1690 foreach (UUID taskID in taskIDict.Keys) 1826 UnRegisterControlEventsToScript(LocalId, taskID);
1691 { 1827 taskIDict[taskID].PermsMask &= ~(
1692 UnRegisterControlEventsToScript(LocalId, taskID); 1828 2048 | //PERMISSION_CONTROL_CAMERA
1693 taskIDict[taskID].PermsMask &= ~( 1829 4); // PERMISSION_TAKE_CONTROLS
1694 2048 | //PERMISSION_CONTROL_CAMERA
1695 4); // PERMISSION_TAKE_CONTROLS
1696 }
1697 } 1830 }
1698
1699 } 1831 }
1832 part.TaskInventory.LockItemsForRead(false);
1700 // Reset sit target. 1833 // Reset sit target.
1701 if (part.GetAvatarOnSitTarget() == UUID) 1834 if (part.GetAvatarOnSitTarget() == UUID)
1702 part.SitTargetAvatar = UUID.Zero; 1835 part.SitTargetAvatar = UUID.Zero;
@@ -1705,16 +1838,55 @@ namespace OpenSim.Region.Framework.Scenes
1705 m_parentPosition = part.GetWorldPosition(); 1838 m_parentPosition = part.GetWorldPosition();
1706 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1839 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1707 } 1840 }
1841 // part.GetWorldRotation() is the rotation of the object being sat on
1842 // Rotation is the sittiing Av's rotation
1843
1844 Quaternion partRot;
1845// if (part.LinkNum == 1)
1846// { // Root prim of linkset
1847// partRot = part.ParentGroup.RootPart.RotationOffset;
1848// }
1849// else
1850// { // single or child prim
1851
1852// }
1853 if (part == null) //CW: Part may be gone. llDie() for example.
1854 {
1855 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1856 }
1857 else
1858 {
1859 partRot = part.GetWorldRotation();
1860 }
1861
1862 Quaternion partIRot = Quaternion.Inverse(partRot);
1708 1863
1864 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1865 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1866
1867
1709 if (m_physicsActor == null) 1868 if (m_physicsActor == null)
1710 { 1869 {
1711 AddToPhysicalScene(false); 1870 AddToPhysicalScene(false);
1712 } 1871 }
1713 1872 //CW: If the part isn't null then we can set the current position
1714 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1873 if (part != null)
1715 m_parentPosition = Vector3.Zero; 1874 {
1716 1875 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1717 m_parentID = 0; 1876 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1877 part.IsOccupied = false;
1878 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1879 }
1880 else
1881 {
1882 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1883 AbsolutePosition = m_lastWorldPosition;
1884 }
1885
1886 m_parentPosition = Vector3.Zero;
1887 m_parentID = 0;
1888 m_linkedPrim = UUID.Zero;
1889 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1718 SendAvatarDataToAllAgents(); 1890 SendAvatarDataToAllAgents();
1719 m_requestedSitTargetID = 0; 1891 m_requestedSitTargetID = 0;
1720 if (m_physicsActor != null && m_appearance != null) 1892 if (m_physicsActor != null && m_appearance != null)
@@ -1723,7 +1895,6 @@ namespace OpenSim.Region.Framework.Scenes
1723 SetHeight(m_appearance.AvatarHeight); 1895 SetHeight(m_appearance.AvatarHeight);
1724 } 1896 }
1725 } 1897 }
1726
1727 Animator.TrySetMovementAnimation("STAND"); 1898 Animator.TrySetMovementAnimation("STAND");
1728 } 1899 }
1729 1900
@@ -1754,13 +1925,9 @@ namespace OpenSim.Region.Framework.Scenes
1754 Vector3 avSitOffSet = part.SitTargetPosition; 1925 Vector3 avSitOffSet = part.SitTargetPosition;
1755 Quaternion avSitOrientation = part.SitTargetOrientation; 1926 Quaternion avSitOrientation = part.SitTargetOrientation;
1756 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1927 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1757 1928 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1758 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1929 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1759 bool SitTargetisSet = 1930 if (SitTargetisSet && !SitTargetOccupied)
1760 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1761 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1762
1763 if (SitTargetisSet && SitTargetUnOccupied)
1764 { 1931 {
1765 //switch the target to this prim 1932 //switch the target to this prim
1766 return part; 1933 return part;
@@ -1774,85 +1941,167 @@ namespace OpenSim.Region.Framework.Scenes
1774 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1941 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1775 { 1942 {
1776 bool autopilot = true; 1943 bool autopilot = true;
1944 Vector3 autopilotTarget = new Vector3();
1945 Quaternion sitOrientation = Quaternion.Identity;
1777 Vector3 pos = new Vector3(); 1946 Vector3 pos = new Vector3();
1778 Quaternion sitOrientation = pSitOrientation;
1779 Vector3 cameraEyeOffset = Vector3.Zero; 1947 Vector3 cameraEyeOffset = Vector3.Zero;
1780 Vector3 cameraAtOffset = Vector3.Zero; 1948 Vector3 cameraAtOffset = Vector3.Zero;
1781 bool forceMouselook = false; 1949 bool forceMouselook = false;
1782 1950
1783 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1951 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1784 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1952 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1785 if (part != null) 1953 if (part == null) return;
1786 { 1954
1787 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1955 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1788 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1956 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1789 1957
1790 // Is a sit target available? 1958 // part is the prim to sit on
1791 Vector3 avSitOffSet = part.SitTargetPosition; 1959 // offset is the world-ref vector distance from that prim center to the click-spot
1792 Quaternion avSitOrientation = part.SitTargetOrientation; 1960 // UUID is the UUID of the Avatar doing the clicking
1793 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1961
1794 1962 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1795 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1963
1796 bool SitTargetisSet = 1964 // Is a sit target available?
1797 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1965 Vector3 avSitOffSet = part.SitTargetPosition;
1798 ( 1966 Quaternion avSitOrientation = part.SitTargetOrientation;
1799 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1967
1800 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1968 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1801 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1969 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1802 ) 1970 Quaternion partRot;
1803 )); 1971// if (part.LinkNum == 1)
1804 1972// { // Root prim of linkset
1805 if (SitTargetisSet && SitTargetUnOccupied) 1973// partRot = part.ParentGroup.RootPart.RotationOffset;
1806 { 1974// }
1807 part.SitTargetAvatar = UUID; 1975// else
1808 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1976// { // single or child prim
1809 sitOrientation = avSitOrientation; 1977 partRot = part.GetWorldRotation();
1810 autopilot = false; 1978// }
1811 } 1979 Quaternion partIRot = Quaternion.Inverse(partRot);
1812 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 1980//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1813 1981 // Sit analysis rewritten by KF 091125
1814 pos = part.AbsolutePosition + offset; 1982 if (SitTargetisSet) // scipted sit
1815 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1983 {
1816 //{ 1984 if (!part.IsOccupied)
1817 // offset = pos; 1985 {
1818 //autopilot = false; 1986//Console.WriteLine("Scripted, unoccupied");
1819 //} 1987 part.SitTargetAvatar = UUID; // set that Av will be on it
1820 if (m_physicsActor != null) 1988 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1821 { 1989
1822 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1990 Quaternion nrot = avSitOrientation;
1823 // We can remove the physicsActor until they stand up. 1991 if (!part.IsRoot)
1824 m_sitAvatarHeight = m_physicsActor.Size.Z;
1825
1826 if (autopilot)
1827 { 1992 {
1828 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1993 nrot = part.RotationOffset * avSitOrientation;
1829 {
1830 autopilot = false;
1831
1832 RemoveFromPhysicalScene();
1833 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1834 }
1835 } 1994 }
1836 else 1995 sitOrientation = nrot; // Change rotatione to the scripted one
1996 OffsetRotation = nrot;
1997 autopilot = false; // Jump direct to scripted llSitPos()
1998 }
1999 else
2000 {
2001//Console.WriteLine("Scripted, occupied");
2002 return;
2003 }
2004 }
2005 else // Not Scripted
2006 {
2007 if ( (Math.Abs(offset.X) > 0.1f) || (Math.Abs(offset.Y) > 0.1f) ) // Changed 0.5M to 0.1M as they want to be able to sit close together
2008 {
2009 // large prim & offset, ignore if other Avs sitting
2010// offset.Z -= 0.05f;
2011 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2012 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2013
2014//Console.WriteLine(" offset ={0}", offset);
2015//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2016//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2017
2018 }
2019 else // small offset
2020 {
2021//Console.WriteLine("Small offset");
2022 if (!part.IsOccupied)
2023 {
2024 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2025 autopilotTarget = part.AbsolutePosition;
2026//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2027 }
2028 else return; // occupied small
2029 } // end large/small
2030 } // end Scripted/not
2031
2032 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2033
2034 cameraAtOffset = part.GetCameraAtOffset();
2035 cameraEyeOffset = part.GetCameraEyeOffset();
2036 forceMouselook = part.GetForceMouselook();
2037 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2038 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2039
2040 if (m_physicsActor != null)
2041 {
2042 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2043 // We can remove the physicsActor until they stand up.
2044 m_sitAvatarHeight = m_physicsActor.Size.Z;
2045 if (autopilot)
2046 { // its not a scripted sit
2047// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2048 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1837 { 2049 {
2050 autopilot = false; // close enough
2051 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2052 Not using the part's position because returning the AV to the last known standing
2053 position is likely to be more friendly, isn't it? */
1838 RemoveFromPhysicalScene(); 2054 RemoveFromPhysicalScene();
1839 } 2055 Velocity = Vector3.Zero;
2056 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2057 } // else the autopilot will get us close
2058 }
2059 else
2060 { // its a scripted sit
2061 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2062 I *am* using the part's position this time because we have no real idea how far away
2063 the avatar is from the sit target. */
2064 RemoveFromPhysicalScene();
2065 Velocity = Vector3.Zero;
1840 } 2066 }
1841
1842 cameraAtOffset = part.GetCameraAtOffset();
1843 cameraEyeOffset = part.GetCameraEyeOffset();
1844 forceMouselook = part.GetForceMouselook();
1845 } 2067 }
1846 2068 else return; // physactor is null!
1847 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2069
1848 m_requestedSitTargetUUID = targetID; 2070 Vector3 offsetr; // = offset * partIRot;
2071 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2072 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2073 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2074 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2075 //offsetr = offset * partIRot;
2076//
2077 // else
2078 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2079 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2080 // (offset * partRot);
2081 // }
2082
2083//Console.WriteLine(" ");
2084//Console.WriteLine("link number ={0}", part.LinkNum);
2085//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2086//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2087//Console.WriteLine("Click offst ={0}", offset);
2088//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2089//Console.WriteLine("offsetr ={0}", offsetr);
2090//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2091//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2092
2093 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2094 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2095
2096 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1849 // This calls HandleAgentSit twice, once from here, and the client calls 2097 // This calls HandleAgentSit twice, once from here, and the client calls
1850 // HandleAgentSit itself after it gets to the location 2098 // HandleAgentSit itself after it gets to the location
1851 // It doesn't get to the location until we've moved them there though 2099 // It doesn't get to the location until we've moved them there though
1852 // which happens in HandleAgentSit :P 2100 // which happens in HandleAgentSit :P
1853 m_autopilotMoving = autopilot; 2101 m_autopilotMoving = autopilot;
1854 m_autoPilotTarget = pos; 2102 m_autoPilotTarget = autopilotTarget;
1855 m_sitAtAutoTarget = autopilot; 2103 m_sitAtAutoTarget = autopilot;
2104 m_initialSitTarget = autopilotTarget;
1856 if (!autopilot) 2105 if (!autopilot)
1857 HandleAgentSit(remoteClient, UUID); 2106 HandleAgentSit(remoteClient, UUID);
1858 } 2107 }
@@ -2147,47 +2396,130 @@ namespace OpenSim.Region.Framework.Scenes
2147 { 2396 {
2148 if (part != null) 2397 if (part != null)
2149 { 2398 {
2399//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2150 if (part.GetAvatarOnSitTarget() == UUID) 2400 if (part.GetAvatarOnSitTarget() == UUID)
2151 { 2401 {
2402//Console.WriteLine("Scripted Sit");
2403 // Scripted sit
2152 Vector3 sitTargetPos = part.SitTargetPosition; 2404 Vector3 sitTargetPos = part.SitTargetPosition;
2153 Quaternion sitTargetOrient = part.SitTargetOrientation; 2405 Quaternion sitTargetOrient = part.SitTargetOrientation;
2154
2155 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2156 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2157
2158 //Quaternion result = (sitTargetOrient * vq) * nq;
2159
2160 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2406 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2161 m_pos += SIT_TARGET_ADJUSTMENT; 2407 m_pos += SIT_TARGET_ADJUSTMENT;
2408 if (!part.IsRoot)
2409 {
2410 m_pos *= part.RotationOffset;
2411 }
2162 m_bodyRot = sitTargetOrient; 2412 m_bodyRot = sitTargetOrient;
2163 //Rotation = sitTargetOrient;
2164 m_parentPosition = part.AbsolutePosition; 2413 m_parentPosition = part.AbsolutePosition;
2165 2414 part.IsOccupied = true;
2166 //SendTerseUpdateToAllClients(); 2415 part.ParentGroup.AddAvatar(agentID);
2167 } 2416 }
2168 else 2417 else
2169 { 2418 {
2170 m_pos -= part.AbsolutePosition; 2419 // if m_avUnscriptedSitPos is zero then Av sits above center
2420 // Else Av sits at m_avUnscriptedSitPos
2421
2422 // Non-scripted sit by Kitto Flora 21Nov09
2423 // Calculate angle of line from prim to Av
2424 Quaternion partIRot;
2425// if (part.LinkNum == 1)
2426// { // Root prim of linkset
2427// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2428// }
2429// else
2430// { // single or child prim
2431 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2432// }
2433 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2434 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2435 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2436 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2437 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2438 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2439 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2440 // Av sits at world euler <0,0, z>, translated by part rotation
2441 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2442
2171 m_parentPosition = part.AbsolutePosition; 2443 m_parentPosition = part.AbsolutePosition;
2172 } 2444 part.IsOccupied = true;
2445 part.ParentGroup.AddAvatar(agentID);
2446 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2447 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2448 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2449 m_avUnscriptedSitPos; // adds click offset, if any
2450 //Set up raytrace to find top surface of prim
2451 Vector3 size = part.Scale;
2452 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2453 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2454 Vector3 down = new Vector3(0f, 0f, -1f);
2455//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2456 m_scene.PhysicsScene.RaycastWorld(
2457 start, // Vector3 position,
2458 down, // Vector3 direction,
2459 mag, // float length,
2460 SitAltitudeCallback); // retMethod
2461 } // end scripted/not
2173 } 2462 }
2174 else 2463 else // no Av
2175 { 2464 {
2176 return; 2465 return;
2177 } 2466 }
2178 } 2467 }
2179 m_parentID = m_requestedSitTargetID;
2180 2468
2469 //We want our offsets to reference the root prim, not the child we may have sat on
2470 if (!part.IsRoot)
2471 {
2472 m_parentID = part.ParentGroup.RootPart.LocalId;
2473 m_pos += part.OffsetPosition;
2474 }
2475 else
2476 {
2477 m_parentID = m_requestedSitTargetID;
2478 }
2479
2480 m_linkedPrim = part.UUID;
2481 if (part.GetAvatarOnSitTarget() != UUID)
2482 {
2483 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2484 }
2181 Velocity = Vector3.Zero; 2485 Velocity = Vector3.Zero;
2182 RemoveFromPhysicalScene(); 2486 RemoveFromPhysicalScene();
2183
2184 Animator.TrySetMovementAnimation(sitAnimation); 2487 Animator.TrySetMovementAnimation(sitAnimation);
2185 SendAvatarDataToAllAgents(); 2488 SendAvatarDataToAllAgents();
2186 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2187 // So we're also sending a terse update (which has avatar rotation)
2188 // [Update] We do now.
2189 //SendTerseUpdateToAllClients(); 2489 //SendTerseUpdateToAllClients();
2190 } 2490 }
2491
2492 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2493 {
2494 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2495 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2496 if(hitYN)
2497 {
2498 // m_pos = Av offset from prim center to make look like on center
2499 // m_parentPosition = Actual center pos of prim
2500 // collisionPoint = spot on prim where we want to sit
2501 // collisionPoint.Z = global sit surface height
2502 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2503 Quaternion partIRot;
2504// if (part.LinkNum == 1)
2505/// { // Root prim of linkset
2506// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2507// }
2508// else
2509// { // single or child prim
2510 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2511// }
2512 if (m_initialSitTarget != null)
2513 {
2514 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2515 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2516 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2517 m_pos += offset;
2518 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2519 }
2520
2521 }
2522 } // End SitAltitudeCallback KF.
2191 2523
2192 /// <summary> 2524 /// <summary>
2193 /// Event handler for the 'Always run' setting on the client 2525 /// Event handler for the 'Always run' setting on the client
@@ -2217,12 +2549,13 @@ namespace OpenSim.Region.Framework.Scenes
2217 /// </summary> 2549 /// </summary>
2218 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2550 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2219 /// <param name="rotation">The direction in which this avatar should now face. 2551 /// <param name="rotation">The direction in which this avatar should now face.
2220 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2552 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2221 { 2553 {
2222 if (m_isChildAgent) 2554 if (m_isChildAgent)
2223 { 2555 {
2224 // WHAT??? 2556 // WHAT???
2225 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); 2557 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent");
2558
2226 return; 2559 return;
2227 } 2560 }
2228 2561
@@ -2231,15 +2564,26 @@ namespace OpenSim.Region.Framework.Scenes
2231 Rotation = rotation; 2564 Rotation = rotation;
2232 Vector3 direc = vec * rotation; 2565 Vector3 direc = vec * rotation;
2233 direc.Normalize(); 2566 direc.Normalize();
2567 PhysicsActor actor = m_physicsActor;
2568
2569 if (actor.Flying != m_flyingOld) // add for fly velocity control
2570 {
2571 m_flyingOld = actor.Flying; // add for fly velocity control
2572 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2573 }
2574
2575 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2576
2577 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2234 2578
2235 direc *= 0.03f * 128f * m_speedModifier; 2579 direc *= 0.03f * 128f * m_speedModifier;
2236 2580
2237 PhysicsActor actor = m_physicsActor;
2238 if (actor != null) 2581 if (actor != null)
2239 { 2582 {
2240 if (actor.Flying) 2583 if (actor.Flying)
2241 { 2584 {
2242 direc *= 4.0f; 2585// rm speed mod direc *= 4.0f;
2586 direc *= 5.2f; // for speed mod
2243 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2587 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2244 //bool colliding = (m_physicsActor.IsColliding==true); 2588 //bool colliding = (m_physicsActor.IsColliding==true);
2245 //if (controlland) 2589 //if (controlland)
@@ -2252,22 +2596,34 @@ namespace OpenSim.Region.Framework.Scenes
2252 // m_log.Info("[AGENT]: Stop FLying"); 2596 // m_log.Info("[AGENT]: Stop FLying");
2253 //} 2597 //}
2254 } 2598 }
2599 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2600 {
2601 direc *= 0.0f;
2602 }
2603 /* This jumping section removed to SPA
2255 else if (!actor.Flying && actor.IsColliding) 2604 else if (!actor.Flying && actor.IsColliding)
2256 { 2605 {
2257 if (direc.Z > 2.0f) 2606 if (direc.Z > 2.0f)
2258 { 2607 {
2259 direc.Z *= 3.0f; 2608 if(m_animator.m_animTickJump == -1)
2260 2609 {
2261 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2610 direc.Z *= 3.0f; // jump
2262 Animator.TrySetMovementAnimation("PREJUMP"); 2611 }
2263 Animator.TrySetMovementAnimation("JUMP"); 2612 else
2613 {
2614 direc.Z *= 0.1f; // prejump
2615 }
2616 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2617 Animator.TrySetMovementAnimation("PREJUMP");
2618 Animator.TrySetMovementAnimation("JUMP");
2619 * /
2264 } 2620 }
2265 } 2621 } */
2266 } 2622 }
2267 2623
2268 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2624 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2269 m_forceToApply = direc; 2625 m_forceToApply = direc;
2270 2626 m_isNudging = Nudging;
2271 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2627 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2272 } 2628 }
2273 2629
@@ -2316,6 +2672,9 @@ namespace OpenSim.Region.Framework.Scenes
2316 2672
2317 CheckForSignificantMovement(); // sends update to the modules. 2673 CheckForSignificantMovement(); // sends update to the modules.
2318 } 2674 }
2675
2676 //Sending prim updates AFTER the avatar terse updates are sent
2677 SendPrimUpdates();
2319 } 2678 }
2320 2679
2321 #endregion 2680 #endregion
@@ -3075,6 +3434,7 @@ namespace OpenSim.Region.Framework.Scenes
3075 m_callbackURI = cAgent.CallbackURI; 3434 m_callbackURI = cAgent.CallbackURI;
3076 3435
3077 m_pos = cAgent.Position; 3436 m_pos = cAgent.Position;
3437
3078 m_velocity = cAgent.Velocity; 3438 m_velocity = cAgent.Velocity;
3079 m_CameraCenter = cAgent.Center; 3439 m_CameraCenter = cAgent.Center;
3080 m_CameraAtAxis = cAgent.AtAxis; 3440 m_CameraAtAxis = cAgent.AtAxis;
@@ -3193,20 +3553,45 @@ namespace OpenSim.Region.Framework.Scenes
3193 /// </summary> 3553 /// </summary>
3194 public override void UpdateMovement() 3554 public override void UpdateMovement()
3195 { 3555 {
3196 if (m_forceToApply.HasValue) 3556 if (Animator!=null) // add for jumping
3197 { 3557 { // add for jumping
3198 Vector3 force = m_forceToApply.Value; 3558 // if (!m_animator.m_jumping) // add for jumping
3559 // { // add for jumping
3199 3560
3200 m_updateflag = true; 3561 if (m_forceToApply.HasValue) // this section realigned
3201 3562 {
3202 // The magic constant 0.95f seems to make walking feel less jerky,
3203 // probably because it hackishly accounts for the overall latency of
3204 // these Velocity updates -- Diva
3205 Velocity = force * .95F;
3206 3563
3207 m_forceToApply = null; 3564 Vector3 force = m_forceToApply.Value;
3208 } 3565 m_updateflag = true;
3209 } 3566if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3567 Velocity = force;
3568//Console.WriteLine("UM1 {0}", Velocity);
3569 m_forceToApply = null;
3570 }
3571 else
3572 {
3573 if (m_isNudging)
3574 {
3575 Vector3 force = Vector3.Zero;
3576
3577 m_updateflag = true;
3578if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3579 Velocity = force;
3580//Console.WriteLine("UM2 {0}", Velocity);
3581 m_isNudging = false;
3582 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3583 }
3584 else // add for jumping
3585 { // add for jumping
3586 Vector3 force = Vector3.Zero; // add for jumping
3587if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3588//Console.WriteLine("UM3 {0}", Velocity);
3589 Velocity = force; // add for jumping
3590 }
3591 }
3592 // } // end realign
3593 } // add for jumping
3594 } // add for jumping
3210 3595
3211 /// <summary> 3596 /// <summary>
3212 /// Adds a physical representation of the avatar to the Physics plugin 3597 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3220,10 +3605,8 @@ namespace OpenSim.Region.Framework.Scenes
3220 3605
3221 Vector3 pVec = AbsolutePosition; 3606 Vector3 pVec = AbsolutePosition;
3222 3607
3223 // Old bug where the height was in centimeters instead of meters
3224 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3608 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3225 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3609 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3226
3227 scene.AddPhysicsActorTaint(m_physicsActor); 3610 scene.AddPhysicsActorTaint(m_physicsActor);
3228 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3611 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3229 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3612 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3247,18 +3630,29 @@ namespace OpenSim.Region.Framework.Scenes
3247 { 3630 {
3248 if (e == null) 3631 if (e == null)
3249 return; 3632 return;
3250 3633
3251 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3634 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3252 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3253 // as of this comment the interval is set in AddToPhysicalScene 3635 // as of this comment the interval is set in AddToPhysicalScene
3254 if (Animator!=null) 3636 if (Animator!=null)
3255 Animator.UpdateMovementAnimations(); 3637 {
3638 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3639 { // else its will lock out other animation changes, like ground sit.
3640 Animator.UpdateMovementAnimations();
3641 m_updateCount--;
3642 }
3643 }
3256 3644
3257 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3645 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3258 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3646 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3259 3647
3260 CollisionPlane = Vector4.UnitW; 3648 CollisionPlane = Vector4.UnitW;
3261 3649
3650 if (m_lastColCount != coldata.Count)
3651 {
3652 m_updateCount = UPDATE_COUNT;
3653 m_lastColCount = coldata.Count;
3654 }
3655
3262 if (coldata.Count != 0 && Animator != null) 3656 if (coldata.Count != 0 && Animator != null)
3263 { 3657 {
3264 switch (Animator.CurrentMovementAnimation) 3658 switch (Animator.CurrentMovementAnimation)
@@ -3288,6 +3682,148 @@ namespace OpenSim.Region.Framework.Scenes
3288 } 3682 }
3289 } 3683 }
3290 3684
3685 List<uint> thisHitColliders = new List<uint>();
3686 List<uint> endedColliders = new List<uint>();
3687 List<uint> startedColliders = new List<uint>();
3688
3689 foreach (uint localid in coldata.Keys)
3690 {
3691 thisHitColliders.Add(localid);
3692 if (!m_lastColliders.Contains(localid))
3693 {
3694 startedColliders.Add(localid);
3695 }
3696 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3697 }
3698
3699 // calculate things that ended colliding
3700 foreach (uint localID in m_lastColliders)
3701 {
3702 if (!thisHitColliders.Contains(localID))
3703 {
3704 endedColliders.Add(localID);
3705 }
3706 }
3707 //add the items that started colliding this time to the last colliders list.
3708 foreach (uint localID in startedColliders)
3709 {
3710 m_lastColliders.Add(localID);
3711 }
3712 // remove things that ended colliding from the last colliders list
3713 foreach (uint localID in endedColliders)
3714 {
3715 m_lastColliders.Remove(localID);
3716 }
3717
3718 // do event notification
3719 if (startedColliders.Count > 0)
3720 {
3721 ColliderArgs StartCollidingMessage = new ColliderArgs();
3722 List<DetectedObject> colliding = new List<DetectedObject>();
3723 foreach (uint localId in startedColliders)
3724 {
3725 if (localId == 0)
3726 continue;
3727
3728 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3729 string data = "";
3730 if (obj != null)
3731 {
3732 DetectedObject detobj = new DetectedObject();
3733 detobj.keyUUID = obj.UUID;
3734 detobj.nameStr = obj.Name;
3735 detobj.ownerUUID = obj.OwnerID;
3736 detobj.posVector = obj.AbsolutePosition;
3737 detobj.rotQuat = obj.GetWorldRotation();
3738 detobj.velVector = obj.Velocity;
3739 detobj.colliderType = 0;
3740 detobj.groupUUID = obj.GroupID;
3741 colliding.Add(detobj);
3742 }
3743 }
3744
3745 if (colliding.Count > 0)
3746 {
3747 StartCollidingMessage.Colliders = colliding;
3748
3749 foreach (SceneObjectGroup att in Attachments)
3750 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3751 }
3752 }
3753
3754 if (endedColliders.Count > 0)
3755 {
3756 ColliderArgs EndCollidingMessage = new ColliderArgs();
3757 List<DetectedObject> colliding = new List<DetectedObject>();
3758 foreach (uint localId in endedColliders)
3759 {
3760 if (localId == 0)
3761 continue;
3762
3763 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3764 string data = "";
3765 if (obj != null)
3766 {
3767 DetectedObject detobj = new DetectedObject();
3768 detobj.keyUUID = obj.UUID;
3769 detobj.nameStr = obj.Name;
3770 detobj.ownerUUID = obj.OwnerID;
3771 detobj.posVector = obj.AbsolutePosition;
3772 detobj.rotQuat = obj.GetWorldRotation();
3773 detobj.velVector = obj.Velocity;
3774 detobj.colliderType = 0;
3775 detobj.groupUUID = obj.GroupID;
3776 colliding.Add(detobj);
3777 }
3778 }
3779
3780 if (colliding.Count > 0)
3781 {
3782 EndCollidingMessage.Colliders = colliding;
3783
3784 foreach (SceneObjectGroup att in Attachments)
3785 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3786 }
3787 }
3788
3789 if (thisHitColliders.Count > 0)
3790 {
3791 ColliderArgs CollidingMessage = new ColliderArgs();
3792 List<DetectedObject> colliding = new List<DetectedObject>();
3793 foreach (uint localId in thisHitColliders)
3794 {
3795 if (localId == 0)
3796 continue;
3797
3798 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3799 string data = "";
3800 if (obj != null)
3801 {
3802 DetectedObject detobj = new DetectedObject();
3803 detobj.keyUUID = obj.UUID;
3804 detobj.nameStr = obj.Name;
3805 detobj.ownerUUID = obj.OwnerID;
3806 detobj.posVector = obj.AbsolutePosition;
3807 detobj.rotQuat = obj.GetWorldRotation();
3808 detobj.velVector = obj.Velocity;
3809 detobj.colliderType = 0;
3810 detobj.groupUUID = obj.GroupID;
3811 colliding.Add(detobj);
3812 }
3813 }
3814
3815 if (colliding.Count > 0)
3816 {
3817 CollidingMessage.Colliders = colliding;
3818
3819 lock (m_attachments)
3820 {
3821 foreach (SceneObjectGroup att in m_attachments)
3822 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3823 }
3824 }
3825 }
3826
3291 if (m_invulnerable) 3827 if (m_invulnerable)
3292 return; 3828 return;
3293 3829
@@ -3713,6 +4249,39 @@ namespace OpenSim.Region.Framework.Scenes
3713 return; 4249 return;
3714 } 4250 }
3715 4251
4252 XmlDocument doc = new XmlDocument();
4253 string stateData = String.Empty;
4254
4255 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4256 if (attServ != null)
4257 {
4258 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4259 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4260 if (stateData != String.Empty)
4261 {
4262 try
4263 {
4264 doc.LoadXml(stateData);
4265 }
4266 catch { }
4267 }
4268 }
4269
4270 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4271
4272 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4273 if (nodes.Count > 0)
4274 {
4275 foreach (XmlNode n in nodes)
4276 {
4277 XmlElement elem = (XmlElement)n;
4278 string itemID = elem.GetAttribute("ItemID");
4279 string xml = elem.InnerXml;
4280
4281 itemData[new UUID(itemID)] = xml;
4282 }
4283 }
4284
3716 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4285 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3717 foreach (AvatarAttachment attach in attachments) 4286 foreach (AvatarAttachment attach in attachments)
3718 { 4287 {
@@ -3733,7 +4302,30 @@ namespace OpenSim.Region.Framework.Scenes
3733 4302
3734 try 4303 try
3735 { 4304 {
3736 m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4305 string xmlData;
4306 XmlDocument d = new XmlDocument();
4307 UUID asset;
4308 if (itemData.TryGetValue(itemID, out xmlData))
4309 {
4310 d.LoadXml(xmlData);
4311 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4312
4313 // Rez from inventory
4314 asset
4315 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4316
4317 }
4318 else
4319 {
4320 // Rez from inventory (with a null doc to let
4321 // CHANGED_OWNER happen)
4322 asset
4323 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4324 }
4325
4326 m_log.InfoFormat(
4327 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4328 p, itemID, asset);
3737 } 4329 }
3738 catch (Exception e) 4330 catch (Exception e)
3739 { 4331 {
@@ -3766,6 +4358,15 @@ namespace OpenSim.Region.Framework.Scenes
3766 m_reprioritization_called = false; 4358 m_reprioritization_called = false;
3767 } 4359 }
3768 } 4360 }
4361
4362 private Vector3 Quat2Euler(Quaternion rot){
4363 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4364 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4365 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4366 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4367 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4368 return(new Vector3(x,y,z));
4369 }
3769 4370
3770 public void SaveChangedAttachments() 4371 public void SaveChangedAttachments()
3771 { 4372 {