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